ExoPlayer 同時支援直播和隨選 RTSP。以下列出支援的樣本格式和網路類型。
支援的範例格式
- H264 (SDP 媒體描述必須在 fmtp 屬性中加入 SPS/PPS 資料,以便解碼器初始化)。
- AAC (含 ADTS 位元串流)。
- AC3。
支援的網路類型
- 透過 UDP 傳送 RTP 的單播 (不支援多播)。
- 交錯的 RTSP、透過 TCP 的 RTP。
使用 MediaItem
如要播放 RTSP 串流,您需要依附 RTSP 模組。
Kotlin
implementation("androidx.media3:media3-exoplayer-rtsp:1.4.1")
Groovy
implementation "androidx.media3:media3-exoplayer-rtsp:1.4.1"
接著,您可以為 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 的相容性會更好。您可以設定 ExoPlayer 預設使用 RtspMediaSource.Factory.setForceUseRtpTcp()
的 RTP/TCP。
傳遞自訂 SocketFactory
在需要特定路由的情況下,自訂 SocketFactory
例項可能會很實用 (例如,當 RTSP 流量需要傳送至特定介面,或 Socket 需要額外的連線旗標時)。
根據預設,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));