ExoPlayer obsługuje RTSP zarówno w przypadku transmisji na żywo, jak i na żądanie. Obsługiwane formaty próbek i typy sieci są wymienione poniżej.
Obsługiwane formaty próbek
- H264 (opis multimediów SDP musi zawierać dane SPS/PPS w atrybucie fmtp na potrzeby inicjowania dekodera).
- AAC (ze strumieniem bitów ADTS).
- AC3.
Obsługiwane typy sieci
- RTP przez UDP unicast (multicast nie jest obsługiwany).
- Przeplatany RTSP, RTP przez RTSP z użyciem TCP.
Używanie elementu MediaItem
Aby odtworzyć strumień RTSP, musisz użyć modułu RTSP.
Kotlin
implementation("androidx.media3:media3-exoplayer-rtsp:1.7.1")
Groovy
implementation "androidx.media3:media3-exoplayer-rtsp:1.7.1"
Następnie możesz utworzyć 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 odtwarzać chronione treści RTSP, identyfikator URI MediaItem
musi być skonfigurowany z informacjami o uwierzytelnianiu. W szczególności 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 do odtwarzacza 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();
Korzystanie z RTSP za NAT (obsługa RTP/TCP)
ExoPlayer używa protokołu UDP jako domyślnego protokołu transportu RTP.
Podczas przesyłania strumieniowego RTSP za warstwą NAT może nie być możliwe przekazywanie przychodzących pakietów RTP/UDP do urządzenia. Dzieje się tak, gdy NAT nie ma odpowiedniego mapowania portów UDP. Jeśli ExoPlayer wykryje, że od dłuższego czasu nie ma przychodzących pakietów RTP, a odtwarzanie jeszcze się nie rozpoczęło, ExoPlayer zamyka bieżącą sesję odtwarzania RTSP i ponawia odtwarzanie za pomocą RTP-over-RTSP (przesyłanie pakietów RTP za pomocą połączenia TCP otwartego dla RTSP).
Czas oczekiwania na ponowienie próby z TCP można dostosować, wywołując metodę RtspMediaSource.Factory.setTimeoutMs()
. Jeśli na przykład limit czasu wynosi 4 sekundy, odtwarzacz ponowi próbę z protokołem TCP po 4 sekundach braku aktywności protokołu UDP.
Ustawienie czasu oczekiwania wpływa też na logikę wykrywania końca strumienia. Oznacza to, że jeśli przez ustawiony czas oczekiwania nie zostaną odebrane żadne dane, ExoPlayer zgłosi zakończenie odtwarzania. Ustawienie zbyt małej wartości może spowodować przedwczesne wysłanie sygnału końca strumienia w przypadku słabych warunków sieciowych.
RTP/TCP zapewnia lepszą zgodność w przypadku niektórych konfiguracji sieci. Możesz skonfigurować ExoPlayer tak, aby domyślnie używał protokołu RTP/TCP za pomocą RtspMediaSource.Factory.setForceUseRtpTcp()
.
Przekazywanie niestandardowego obiektu SocketFactory
Niestandardowe instancje SocketFactory
mogą być przydatne, gdy wymagane jest określone routowanie (np. gdy ruch RTSP musi przechodzić przez określony interfejs lub gniazdo wymaga dodatkowych flag łączności).
Domyślnie RtspMediaSource
używa standardowego fabrykatora gniazd Java (SocketFactory.getDefault()
) do tworzenia połączeń z odległymi punktami końcowymi.
To zachowanie można zastąpić za pomocą zasady 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));