RTSP,

ExoPlayer obsługuje RTSP na żywo i na żądanie. Obsługiwane formaty próbek i typy sieci znajdziesz poniżej.

Obsługiwane formaty próbek

  • H.264 (opis multimediów SDP musi zawierać dane SPS/PPS w atrybucie fmtp na potrzeby inicjalizacji dekodera).
  • AAC (z strumieniem bitów ADTS).
  • AC3.

Obsługiwane typy sieci

  • RTP przez UDP unicast (multicast nie jest obsługiwany).
  • Przeplatane RTSP, RTP przez RTSP za pomocą TCP.

Korzystanie z MediaItem

Aby odtworzyć strumień RTSP, musisz polegać na module RTSP.

Kotlin

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

Groovy

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

Następnie możesz utworzyć MediaItem dla 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 odtwarzać chronione treści RTSP, identyfikator URI MediaItem musi być skonfigurowany z informacjami uwierzytelniania. Identyfikator URI powinien mieć postać rtsp://<username>:<password>@<host address>.

Korzystanie z RtspMediaSource

Aby uzyskać więcej opcji dostosowywania, możesz utworzyć RtspMediaSource i przekazać go bezpośrednio odtwarzaczowi zamiast 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 za NAT (obsługa RTP/TCP)

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

Podczas przesyłania strumieniowego RTSP za warstwą NAT może się zdarzyć, że NAT nie będzie w stanie przekazać przychodzących pakietów RTP/UDP do urządzenia. Dzieje się tak, gdy NAT nie ma mapowania potrzebnego portu UDP. Jeśli ExoPlayer wykryje, że przez jakiś czas nie było przychodzących pakietów RTP, a odtwarzanie jeszcze się nie rozpoczęło, ExoPlayer przerywa bieżącą sesję odtwarzania RTSP i próbuje ponownie odtworzyć materiał za pomocą RTP-over-RTSP (przesyłając pakiety RTP za pomocą połączenia TCP otwartego dla RTSP).

Czas oczekiwania na ponowne próby z TCP można dostosować, wywołując metodę RtspMediaSource.Factory.setTimeoutMs(). Jeśli na przykład ustawisz limit czasu na 4 sekundy, odtwarzacz spróbuje ponownie użyć protokołu TCP po 4 sekundach braku aktywności w przypadku protokołu UDP.

Ustawienie limitu czasu wpływa też na logikę wykrywania końca strumienia. Oznacza to, że ExoPlayer zgłosi, że odtwarzanie zostało zakończone, jeśli w czasie ustawionego limitu czasu nie zostanie odebrana żadna transmisja. Ustawienie zbyt małej wartości może spowodować przedwczesne zakończenie strumienia w przypadku słabego połączenia z internetem.

RTP/TCP zapewnia lepszą kompatybilność w przypadku niektórych konfiguracji sieci. Za pomocą RtspMediaSource.Factory.setForceUseRtpTcp() możesz skonfigurować ExoPlayera tak, aby domyślnie używał protokołu RTP/TCP.

Przekazywanie niestandardowego SocketFactory

Niestandardowe instancje SocketFactory mogą być przydatne, gdy wymagane jest określone kierowanie (np. gdy ruch RTSP musi przechodzić przez określony interfejs lub gdy gniazdo potrzebuje dodatkowych flag połączeń).

Domyślnie RtspMediaSource używa standardowej fabryki gniazd (SocketFactory.getDefault()) w języku Java do tworzenia połączeń z odległymi punktami końcowymi. To zachowanie można zastąpić za pomocą elementu 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));