ExoPlayer 支援即時和隨選 RTSP。支援的樣本格式和網路類型如下。
支援的樣本格式
- H264 (SDP 媒體說明必須在 fmtp 屬性中包含 SPS/PPS 資料,以初始化解碼器)。
- AAC (含 ADTS 位元串流)。
- AC3。
支援的網路類型
- 透過 UDP 單點傳播的 RTP (不支援多點傳播)。
- 交錯式 RTSP,透過 TCP 使用 RTSP 的 RTP。
使用 MediaItem
如要播放 RTSP 串流,您必須依附於 RTSP 模組。
Kotlin
implementation("androidx.media3:media3-exoplayer-rtsp:1.8.0")
Groovy
implementation "androidx.media3:media3-exoplayer-rtsp:1.8.0"
接著,您可以為 RTSP URI 建立 MediaItem,並傳遞至播放器。
Kotlin
// Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the media item to be played. player.setMediaItem(MediaItem.fromUri(rtspUri)) // Prepare the player. player.prepare()
Java
// Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the media item to be played. player.setMediaItem(MediaItem.fromUri(rtspUri)); // Prepare the player. player.prepare();
驗證
ExoPlayer 支援使用 RTSP BASIC 和 DIGEST 驗證播放內容。如要播放受保護的 RTSP 內容,必須使用驗證資訊設定 MediaItem 的 URI。具體來說,URI 應採用 rtsp://<username>:<password>@<host address> 格式。
使用 RtspMediaSource
如需更多自訂選項,您可以建立 RtspMediaSource,並直接傳遞至播放器,而非 MediaItem。
Kotlin
// Create an RTSP media source pointing to an RTSP uri. val mediaSource: MediaSource = RtspMediaSource.Factory().createMediaSource(MediaItem.fromUri(rtspUri)) // Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the media source to be played. player.setMediaSource(mediaSource) // Prepare the player. player.prepare()
Java
// Create an RTSP media source pointing to an RTSP uri. MediaSource mediaSource = new RtspMediaSource.Factory().createMediaSource(MediaItem.fromUri(rtspUri)); // Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the media source to be played. player.setMediaSource(mediaSource); // Prepare the player. player.prepare();
在 NAT 後方使用 RTSP (支援 RTP/TCP)
ExoPlayer 會將 UDP 設為 RTP 傳輸的預設通訊協定。
在 NAT 層後方串流 RTSP 時,NAT 可能無法將傳入的 RTP/UDP 封包轉送至裝置。如果 NAT 缺少必要的 UDP 通訊埠對應,就會發生這種情況。如果 ExoPlayer 偵測到一段時間沒有傳入 RTP 封包,且尚未開始播放,ExoPlayer 會終止目前的 RTSP 播放工作階段,並使用 RTP over RTSP (透過為 RTSP 開啟的 TCP 連線傳輸 RTP 封包) 重試播放。
您可以呼叫 RtspMediaSource.Factory.setTimeoutMs() 方法,自訂使用 TCP 重試的逾時時間。舉例來說,如果逾時時間設為四秒,玩家會在 UDP 閒置四秒後,以 TCP 重試。
設定逾時也會影響串流結束偵測邏輯。也就是說,如果 ExoPlayer 在設定的逾時時間內未收到任何內容,就會回報播放已結束。如果這個值設定得太小,在網路狀況不佳時,可能會導致串流提早結束。
在某些網路設定下,RTP/TCP 的相容性較佳。您可以透過 RtspMediaSource.Factory.setForceUseRtpTcp(),將 ExoPlayer 設為預設使用 RTP/TCP。
傳遞自訂 SocketFactory
如果需要特定路徑 (例如 RTSP 流量必須通過特定介面,或通訊端需要額外的連線旗標),自訂 SocketFactory 執行個體就非常實用。
根據預設,RtspMediaSource 會使用 Java 的標準通訊端工廠 (SocketFactory.getDefault()) 建立與遠端端點的連線。您可以使用 RtspMediaSource.Factory.setSocketFactory() 覆寫這項行為。
Kotlin
// Create an RTSP media source pointing to an RTSP uri and override the socket // factory. val mediaSource: MediaSource = RtspMediaSource.Factory() .setSocketFactory(...) .createMediaSource(MediaItem.fromUri(rtspUri))
Java
// Create an RTSP media source pointing to an RTSP uri and override the socket // factory. MediaSource mediaSource = new RtspMediaSource.Factory() .setSocketFactory(...) .createMediaSource(MediaItem.fromUri(rtspUri));