diff --git a/android/build.gradle b/android/build.gradle index a17296a1..ba304056 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -164,6 +164,8 @@ dependencies { implementation "androidx.media3:media3-exoplayer-dash:$media3_version" // For HLS playback support with ExoPlayer 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 if (useExoplayerIMA) { implementation "androidx.media3:media3-exoplayer-ima:$media3_version" diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index eee80fef..c4000f1d 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -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_HLS; 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.TIME_END_OF_SOURCE; @@ -68,6 +69,7 @@ import androidx.media3.exoplayer.hls.HlsMediaSource; import androidx.media3.exoplayer.ima.ImaAdsLoader; import androidx.media3.exoplayer.mediacodec.MediaCodecInfo; import androidx.media3.exoplayer.mediacodec.MediaCodecUtil; +import androidx.media3.exoplayer.rtsp.RtspMediaSource; import androidx.media3.exoplayer.smoothstreaming.DefaultSsChunkSource; import androidx.media3.exoplayer.smoothstreaming.SsMediaSource; import androidx.media3.exoplayer.source.ClippingMediaSource; @@ -792,8 +794,13 @@ public class ReactExoplayerView extends FrameLayout implements if (uri == null) { throw new IllegalStateException("Invalid video uri"); } - int type = Util.inferContentType(!TextUtils.isEmpty(overrideExtension) ? "." + overrideExtension - : uri.getLastPathSegment()); + int type; + if ("rtsp".equals(overrideExtension)) { + type = C.TYPE_RTSP; + } else { + type = Util.inferContentType(!TextUtils.isEmpty(overrideExtension) ? "." + overrideExtension + : uri.getLastPathSegment()); + } config.setDisableDisconnectError(this.disableDisconnectError); MediaItem.Builder mediaItemBuilder = new MediaItem.Builder().setUri(uri); @@ -836,6 +843,9 @@ public class ReactExoplayerView extends FrameLayout implements mediaDataSourceFactory ); break; + case CONTENT_TYPE_RTSP: + mediaSourceFactory = new RtspMediaSource.Factory(); + break; default: { throw new IllegalStateException("Unsupported type: " + type); } diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java index 0a2adbc5..e3482cda 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java @@ -442,6 +442,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager( if (!uri) { console.log('Trying to load empty source'); } - const isNetwork = !!(uri && uri.match(/^https?:/)); + const isNetwork = !!(uri && uri.match(/^(rtp|rtsp|http|https):/)); const isAsset = !!( uri && uri.match(