ExoPlayer admite RTSP en vivo y on demand. A continuación, se indican los formatos de muestra y los tipos de redes admitidos.
Formatos de muestras admitidos
- H264 (la descripción de medios del SDP debe incluir datos de SPS/PPS en el atributo fmtp para la inicialización del decodificador).
- AAC (con flujo de bits ADTS)
- AC3.
Tipos de redes admitidos
- RTP a través de UDP unicast (no se admite la multidifusión).
- RTSP intercalado, RTP a través de RTSP con TCP.
Cómo usar MediaItem
Para reproducir una transmisión de RTSP, debes depender del módulo de RTSP.
Kotlin
implementation("androidx.media3:media3-exoplayer-rtsp:1.7.1")
Groovy
implementation "androidx.media3:media3-exoplayer-rtsp:1.7.1"
Luego, puedes crear un MediaItem
para un URI de RTSP y pasarlo al reproductor.
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 BASIC y DIGEST de RTSP. 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();
Uso de RTSP detrás de una NAT (compatibilidad con RTP/TCP)
ExoPlayer usa UDP como protocolo predeterminado para el transporte de RTP.
Cuando se transmite RTSP detrás de una capa de NAT, es posible que la NAT no pueda reenviar los paquetes RTP/UDP entrantes al dispositivo. Esto ocurre si la NAT no tiene la asignación de puertos UDP necesaria. Si ExoPlayer detecta que no se recibieron paquetes RTP durante un tiempo y que aún no se inició la reproducción, ExoPlayer cierra la sesión de reproducción RTSP actual y vuelve a intentar la reproducción con RTP a través de RTSP (transmite paquetes RTP con la conexión TCP abierta para RTSP).
El tiempo de espera para reintentar con TCP se puede personalizar llamando al método RtspMediaSource.Factory.setTimeoutMs()
. Por ejemplo, si el tiempo de espera se establece en cuatro segundos, el reproductor volverá a intentar la conexión con TCP después de cuatro segundos de inactividad de UDP.
Establecer 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 se establece 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 algunos parámetros de configuración de red. Puedes configurar ExoPlayer para que use RTP/TCP de forma predeterminada con RtspMediaSource.Factory.setForceUseRtpTcp()
.
Cómo pasar un SocketFactory personalizado
Las instancias SocketFactory
personalizadas pueden ser útiles cuando se requiere un enrutamiento particular (por ejemplo, cuando el tráfico RTSP necesita pasar una interfaz específica o el socket necesita marcas de conectividad adicionales).
De forma predeterminada, RtspMediaSource
usará el socket factory estándar de Java (SocketFactory.getDefault()
) para crear conexiones a 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));