RTSP

ExoPlayer admite RTSP en vivo y on demand. A continuación, se enumeran los formatos de muestra y los tipos de red compatibles.

Formatos de muestra compatibles

  • H264 (la descripción del medio SDP debe incluir datos SPS/PPS en el atributo fmtp para la inicialización del decodificador).
  • AAC (con flujo de bits ADTS)
  • AC3.

Tipos de red admitidos

  • RTP sobre unicast UDP (no se admite la multidifusión).
  • RTSP intercalado, RTP sobre RTSP a través de TCP

Cómo usar MediaItem

Para reproducir una transmisión RTSP, debes depender del módulo RTSP.

Kotlin

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

Groovy

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

Luego, puedes crear un MediaItem para un URI de RTSP y pasarlo al jugador.

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

Autenticación

ExoPlayer admite la reproducción con autenticación RTSP BASIC y DIGEST. Para reproducir contenido RTSP protegido, el URI de MediaItem debe configurarse con la información de autenticación. Específicamente, el URI debe tener el formato rtsp://<username>:<password>@<host address>.

Cómo usar RtspMediaSource

Para obtener más opciones de personalización, puedes crear un RtspMediaSource y pasarlo directamente al reproductor en lugar de un 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();

Cómo usar RTSP detrás de una NAT (compatibilidad con RTP/TCP)

ExoPlayer usa UDP como el protocolo predeterminado para el transporte de RTP.

Cuando se transmite el RTSP detrás de una capa NAT, es posible que la NAT no pueda reenviar los paquetes RTP/UDP entrantes al dispositivo. Esto ocurre si la NAT carece de la asignación de puertos UDP necesaria. Si ExoPlayer detecta que no hay paquetes RTP entrantes durante un tiempo y la reproducción aún no se inició, ExoPlayer cierra la sesión de reproducción de RTSP actual y vuelve a intentar la reproducción con RTP sobre RTSP (transmite paquetes RTP con la conexión TCP abierta para RTSP).

Para personalizar el tiempo de espera para volver a intentarlo con TCP, llama al método RtspMediaSource.Factory.setTimeoutMs(). Por ejemplo, si el tiempo de espera se establece en cuatro segundos, el jugador volverá a intentarlo con TCP después de cuatro segundos de inactividad de UDP.

Configurar el tiempo de espera también afecta la lógica de detección del final de la transmisión. Es decir, ExoPlayer informará que la reproducción finalizó si no se recibe nada durante el tiempo de espera establecido. Si estableces un valor demasiado bajo, es posible que se envíe una señal de fin de transmisión anticipada en condiciones de red deficientes.

RTP/TCP ofrece una mejor compatibilidad en algunas configuraciones de red. Puedes configurar ExoPlayer para que use RTP/TCP de forma predeterminada con RtspMediaSource.Factory.setForceUseRtpTcp().

Pasa una SocketFactory personalizada

Las instancias personalizadas de SocketFactory pueden ser útiles cuando se requiere un enrutamiento particular (por ejemplo, cuando el tráfico RTSP debe pasar por una interfaz específica o el socket necesita marcas de conectividad adicionales).

De forma predeterminada, RtspMediaSource usará la fábrica de sockets estándar de Java (SocketFactory.getDefault()) para crear conexiones con los extremos remotos. Este comportamiento se puede anular con 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));