O ExoPlayer oferece suporte a RTSP ao vivo e on demand. Confira abaixo os formatos e tipos de rede de exemplo compatíveis.
Formatos de amostra aceitos
- H264 (a descrição de mídia do SDP precisa incluir dados SPS/PPS no atributo fmtp para inicialização do decodificador).
- AAC (com bitstream ADTS).
- AC3.
Tipos de rede aceitos
- RTP sobre unicast UDP (não há suporte para multicast).
- RTSP intercalado, RTP sobre RTSP usando TCP.
Como usar o MediaItem
Para reproduzir um stream RTSP, você precisa depender do módulo RTSP.
Kotlin
implementation("androidx.media3:media3-exoplayer-rtsp:1.4.1")
Groovy
implementation "androidx.media3:media3-exoplayer-rtsp:1.4.1"
Em seguida, crie um MediaItem
para um URI RTSP e transmita-o para o 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, crie uma RtspMediaSource
e transmita-a
diretamente ao player em vez de uma 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();
Como usar o RTSP por trás de uma NAT (suporte a RTP/TCP)
O ExoPlayer usa UDP como o protocolo padrão para transporte RTP.
Ao fazer streaming do RTSP por trás de uma camada NAT, o NAT pode não conseguir 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 um tempo e a reprodução ainda não tiver sido iniciada, o ExoPlayer desmonta a sessão de reprodução do RTSP atual e tenta a reprodução usando o RTP-sobre-RTSP (transmitindo pacotes RTP usando a conexão TCP aberta para o 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 vai tentar novamente com o TCP após quatro segundos de inatividade
do UDP.
Definir o tempo limite também afeta a lógica de detecção do fim da transmissão. Ou seja, o ExoPlayer vai informar que a reprodução foi encerrada se nada for recebido durante o tempo limite definido. Definir esse valor muito pequeno pode levar a um sinal de fim de transmissão 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 uma SocketFactory personalizada
As instâncias personalizadas de SocketFactory
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
socket precisa de flags de conectividade adicionais.
Por padrão, RtspMediaSource
usará a fábrica de soquete 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));