Feat/add rtsp support (#3677)

* feat(android) : add rtsp support
This commit is contained in:
Olivier Bouillet 2024-04-16 10:41:39 +02:00 committed by GitHub
parent 336b9f0220
commit 2285eba8f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 34 additions and 4 deletions

View File

@ -164,6 +164,8 @@ dependencies {
implementation "androidx.media3:media3-exoplayer-dash:$media3_version" implementation "androidx.media3:media3-exoplayer-dash:$media3_version"
// For HLS playback support with ExoPlayer // For HLS playback support with ExoPlayer
implementation "androidx.media3:media3-exoplayer-hls:$media3_version" implementation "androidx.media3:media3-exoplayer-hls:$media3_version"
implementation "androidx.media3:media3-exoplayer-rtsp:$media3_version"
// For ad insertion using the Interactive Media Ads SDK with ExoPlayer // For ad insertion using the Interactive Media Ads SDK with ExoPlayer
if (useExoplayerIMA) { if (useExoplayerIMA) {
implementation "androidx.media3:media3-exoplayer-ima:$media3_version" implementation "androidx.media3:media3-exoplayer-ima:$media3_version"

View File

@ -3,6 +3,7 @@ package com.brentvatne.exoplayer;
import static androidx.media3.common.C.CONTENT_TYPE_DASH; import static androidx.media3.common.C.CONTENT_TYPE_DASH;
import static androidx.media3.common.C.CONTENT_TYPE_HLS; import static androidx.media3.common.C.CONTENT_TYPE_HLS;
import static androidx.media3.common.C.CONTENT_TYPE_OTHER; import static androidx.media3.common.C.CONTENT_TYPE_OTHER;
import static androidx.media3.common.C.CONTENT_TYPE_RTSP;
import static androidx.media3.common.C.CONTENT_TYPE_SS; import static androidx.media3.common.C.CONTENT_TYPE_SS;
import static androidx.media3.common.C.TIME_END_OF_SOURCE; import static androidx.media3.common.C.TIME_END_OF_SOURCE;
@ -68,6 +69,7 @@ import androidx.media3.exoplayer.hls.HlsMediaSource;
import androidx.media3.exoplayer.ima.ImaAdsLoader; import androidx.media3.exoplayer.ima.ImaAdsLoader;
import androidx.media3.exoplayer.mediacodec.MediaCodecInfo; import androidx.media3.exoplayer.mediacodec.MediaCodecInfo;
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil; import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
import androidx.media3.exoplayer.rtsp.RtspMediaSource;
import androidx.media3.exoplayer.smoothstreaming.DefaultSsChunkSource; import androidx.media3.exoplayer.smoothstreaming.DefaultSsChunkSource;
import androidx.media3.exoplayer.smoothstreaming.SsMediaSource; import androidx.media3.exoplayer.smoothstreaming.SsMediaSource;
import androidx.media3.exoplayer.source.ClippingMediaSource; import androidx.media3.exoplayer.source.ClippingMediaSource;
@ -792,8 +794,13 @@ public class ReactExoplayerView extends FrameLayout implements
if (uri == null) { if (uri == null) {
throw new IllegalStateException("Invalid video uri"); throw new IllegalStateException("Invalid video uri");
} }
int type = Util.inferContentType(!TextUtils.isEmpty(overrideExtension) ? "." + overrideExtension int type;
if ("rtsp".equals(overrideExtension)) {
type = C.TYPE_RTSP;
} else {
type = Util.inferContentType(!TextUtils.isEmpty(overrideExtension) ? "." + overrideExtension
: uri.getLastPathSegment()); : uri.getLastPathSegment());
}
config.setDisableDisconnectError(this.disableDisconnectError); config.setDisableDisconnectError(this.disableDisconnectError);
MediaItem.Builder mediaItemBuilder = new MediaItem.Builder().setUri(uri); MediaItem.Builder mediaItemBuilder = new MediaItem.Builder().setUri(uri);
@ -836,6 +843,9 @@ public class ReactExoplayerView extends FrameLayout implements
mediaDataSourceFactory mediaDataSourceFactory
); );
break; break;
case CONTENT_TYPE_RTSP:
mediaSourceFactory = new RtspMediaSource.Factory();
break;
default: { default: {
throw new IllegalStateException("Unsupported type: " + type); throw new IllegalStateException("Unsupported type: " + type);
} }

View File

@ -442,6 +442,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
|| lowerCaseUri.startsWith("https://") || lowerCaseUri.startsWith("https://")
|| lowerCaseUri.startsWith("content://") || lowerCaseUri.startsWith("content://")
|| lowerCaseUri.startsWith("file://") || lowerCaseUri.startsWith("file://")
|| lowerCaseUri.startsWith("rtsp://")
|| lowerCaseUri.startsWith("asset://"); || lowerCaseUri.startsWith("asset://");
} }
} }

View File

@ -106,6 +106,18 @@ android {
configurations.all { configurations.all {
resolutionStrategy { force 'androidx.core:core:1.9.0' } resolutionStrategy { force 'androidx.core:core:1.9.0' }
} }
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
exclude("META-INF/*.kotlin_module")
}
} }

View File

@ -10,7 +10,7 @@
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512m
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit

View File

@ -191,6 +191,11 @@ class VideoPlayer extends Component {
'https://proxy.uat.widevine.com/proxy?provider=widevine_test', 'https://proxy.uat.widevine.com/proxy?provider=widevine_test',
}, },
}, },
{
description: 'rtsp big bug bunny',
uri: 'rtsp://rtspstream:3cfa3c36a9c00f4aa38f3cd35816b287@zephyr.rtsp.stream/movie',
type: 'rtsp',
}
]; ];
// poster which can be displayed // poster which can be displayed

View File

@ -146,7 +146,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
if (!uri) { if (!uri) {
console.log('Trying to load empty source'); console.log('Trying to load empty source');
} }
const isNetwork = !!(uri && uri.match(/^https?:/)); const isNetwork = !!(uri && uri.match(/^(rtp|rtsp|http|https):/));
const isAsset = !!( const isAsset = !!(
uri && uri &&
uri.match( uri.match(