RTSP

ExoPlayer 同時支援直播與隨選 RTSP。以下列出支援的範例格式和網路類型。

支援的範例格式

  • H264 (SDP 媒體說明必須在解碼器初始化的 fmtp 屬性中包含 SPS/PPS 資料)。
  • AAC (含 ADTS 位元串流)。
  • AC3。

支援的網路類型

  • 透過 UDP 單點傳播的 RTP (不支援多點傳播)。
  • 交錯 RTSP、透過 RTSP 使用 TCP 的 RTP。

使用 MediaItem

如要播放 RTSP 串流,您需要依附於 RTSP 模組。

Kotlin

implementation("androidx.media3:media3-exoplayer-rtsp:1.3.1")

Groovy

implementation "androidx.media3:media3-exoplayer-rtsp:1.3.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 閒置 4 秒後使用 TCP 重試。

設定逾時也會影響串流結束偵測邏輯。也就是說,如果在設定的逾時期間未收到任何內容,ExoPlayer 會回報播放已結束。如果設定的值太小,可能會導致系統在網路狀況不佳的情況下,出現早期的串流訊號。

在部分網路設定下,RTP/TCP 可提供更好的相容性。您可以將 ExoPlayer 設為預設搭配 RtspMediaSource.Factory.setForceUseRtpTcp() 使用 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));