RTSP.

O ExoPlayer oferece suporte a RTSP ao vivo e sob demanda. Confira abaixo os formatos de amostra e os tipos de rede compatíveis.

Formatos de amostra compatíveis

  • H264 (a descrição da mídia do SDP precisa incluir dados SPS/PPS no atributo fmtp para a inicialização do decodificador).
  • AAC (com bitstream ADTS).
  • CA3.

Tipos de rede compatíveis

  • RTP sobre unicast UDP (o multicast não é compatível).
  • RTSP intercalado, RTP sobre RTSP usando TCP.

Como usar MediaItem

Para reproduzir um stream RTSP, você precisa depender do módulo RTSP.

Kotlin

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

Groovy

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

Você pode criar um MediaItem para um URI RTSP e transmiti-lo ao player.

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

Autenticação

O ExoPlayer oferece suporte à reprodução com autenticação RTSP BASIC e DIGEST. Para reproduzir conteúdo RTSP protegido, o URI do MediaItem precisa ser configurado com as informações de autenticação. Especificamente, o URI precisa estar no formato rtsp://<username>:<password>@<host address>.

Como usar RtspMediaSource

Para mais opções de personalização, você pode criar um RtspMediaSource e transmiti-lo diretamente ao player em vez de 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();

Uso de RTSP atrás de um NAT (suporte a RTP/TCP)

O ExoPlayer usa o UDP como protocolo padrão para o transporte RTP.

Ao transmitir RTSP atrás de uma camada NAT, o NAT pode não ser capaz de encaminhar os pacotes RTP/UDP de entrada para o dispositivo. Isso ocorre se o NAT não tiver o mapeamento de porta UDP necessário. Se o ExoPlayer detectar que não há pacotes RTP de entrada por algum tempo e a reprodução ainda não tiver sido iniciada, o ExoPlayer vai desativar a sessão de reprodução do RTSP atual e repetir a reprodução usando o RTP sobre RTSP (transmissão de pacotes RTP usando a conexão TCP aberta para RTSP).

O tempo limite para novas tentativas com TCP pode ser personalizado chamando o método RtspMediaSource.Factory.setTimeoutMs(). Por exemplo, se o tempo limite for definido como quatro segundos, o player tentará novamente com TCP após quatro segundos de inatividade do UDP.

Definir o tempo limite também afeta a lógica de detecção de fim de stream. Ou seja, o ExoPlayer vai informar que a reprodução terminou se nada for recebido durante o tempo limite definido. Definir um valor muito baixo pode levar a um sinal de fim de stream antecipado em condições de rede ruins.

O RTP/TCP oferece melhor compatibilidade em algumas configurações de rede. É possível configurar o ExoPlayer para usar RTP/TCP por padrão com RtspMediaSource.Factory.setForceUseRtpTcp().

Como transmitir um SocketFactory personalizado

Instâncias SocketFactory personalizadas podem ser úteis quando um roteamento específico é necessário. Por exemplo, quando o tráfego RTSP precisa passar por uma interface específica ou o soquete precisa de outras flags de conectividade.

Por padrão, RtspMediaSource usará a fábrica de soquetes padrão do Java (SocketFactory.getDefault()) para criar conexões com os endpoints remotos. Esse comportamento pode ser substituído usando 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));