RTSP,

ExoPlayer obsługuje zarówno protokół RTSP na żywo, jak i na żądanie. Poniżej znajdziesz obsługiwane przykładowe formaty i typy sieci.

Obsługiwane formaty próbek

  • H264 (opis mediów SDP musi zawierać dane SPS/PPS w atrybucie fmtp na potrzeby inicjowania dekodera).
  • AAC (ze strumieniem bitowym ADTS).
  • AC3.

Obsługiwane typy sieci

  • Transmisja pojedyncza RTP przez UDP (multicast nie jest obsługiwany).
  • Przeplatany RTSP, RTP przez RTSP przy użyciu TCP.

Korzystanie z elementu MediaItem

Aby odtwarzać strumień RTSP, musisz korzystać z modułu RTSP.

Kotlin

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

Odlotowe

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

Następnie możesz utworzyć identyfikator MediaItem dla identyfikatora URI RTSP i przekazać go do odtwarzacza.

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();

Uwierzytelnianie

ExoPlayer obsługuje odtwarzanie z uwierzytelnianiem RTSP BASIC i DIGEST. Aby można było odtwarzać chronione treści RTSP, identyfikator URI elementu MediaItem musi być skonfigurowany za pomocą danych uwierzytelniających. Identyfikator URI powinien mieć postać rtsp://<username>:<password>@<host address>.

Korzystanie z RtspMediaSource

Aby uzyskać więcej opcji dostosowywania, możesz utworzyć element RtspMediaSource i przekazać go bezpośrednio do odtwarzacza zamiast do 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();

Używanie RTSP z protokołem NAT (obsługa RTP/TCP)

ExoPlayer używa UDP jako domyślnego protokołu do przesyłania RTP.

Podczas strumieniowego przesyłania danych RTSP za warstwę NAT sieć NAT może nie być w stanie przekazać przychodzących pakietów RTP/UDP do urządzenia. Dzieje się tak, gdy NAT nie ma wymaganego mapowania portów UDP. Jeśli ExoPlayer wykryje, że przez jakiś czas nie ma przychodzących pakietów RTP, a odtwarzanie jeszcze się nie rozpoczęło, ExoPlayer przerwie bieżącą sesję odtwarzania RTSP i ponawia próbę odtworzenia przy użyciu protokołu RTP przez protokół RTSP (wysyłanie pakietów RTP przy użyciu połączenia TCP otwartego dla RTSP).

Limit czasu ponawiania próby za pomocą TCP można dostosować, wywołując metodę RtspMediaSource.Factory.setTimeoutMs(). Jeśli na przykład czas oczekiwania jest ustawiony na 4 sekundy, odtwarzacz ponawia próbę połączenia przez TCP po 4 sekundach braku aktywności UDP.

Ustawienie limitu czasu wpływa też na logikę wykrywania końca transmisji. Oznacza to, że jeśli przez ustawiony czas oczekiwania nie zostaną odebrane żadne treści, ExoPlayer zgłosi, że odtwarzanie się zakończyło. Zbyt mała wartość może spowodować, że w słabych warunkach połączenia sieciowego sygnał dobiegnie końca.

Protokół RTP/TCP zapewnia lepszą zgodność z niektórymi konfiguracjami sieci. Możesz skonfigurować ExoPlayer tak, aby domyślnie używał RTP/TCP z RtspMediaSource.Factory.setForceUseRtpTcp().

Przekazywanie niestandardowej wartości SocketFactory

Niestandardowe instancje SocketFactory mogą być przydatne, gdy wymagany jest określony routing (na przykład gdy ruch RTSP musi przechodzić przez określony interfejs lub gniazdo wymaga dodatkowych flag połączenia).

Domyślnie RtspMediaSource używa standardowego gniazda Javy (SocketFactory.getDefault()) do nawiązywania połączeń ze zdalnymi punktami końcowymi. To zachowanie można zastąpić za pomocą parametru 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));