ExoPlayer поддерживает RTSP как для трансляций, так и для видео по запросу. Ниже перечислены поддерживаемые форматы образцов и типы сетей.
Поддерживаемые форматы образцов
- H264 (описание медиаконтента в SDP должно включать данные SPS/PPS в атрибуте fmtp для инициализации декодера).
- AAC (с битовым потоком ADTS).
- AC3.
Поддерживаемые типы сетей
- RTP через одноадресную передачу UDP (многоадресная передача не поддерживается).
- Чередующийся RTSP, RTP поверх RTSP с использованием TCP.
Как использовать MediaItem
Чтобы воспроизвести поток RTSP, вам понадобится модуль RTSP.
Kotlin
implementation("androidx.media3:media3-exoplayer-rtsp:1.11.1")
Яркий
implementation "androidx.media3:media3-exoplayer-rtsp:1.11.1"
Затем вы можете создать MediaItem для URI RTSP и передать его проигрывателю.
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();
Аутентификация
ExoPlayer поддерживает воспроизведение с аутентификацией RTSP BASIC и DIGEST. Чтобы воспроизводить защищенный контент RTSP, URI MediaItem должен быть настроен с информацией об аутентификации. В частности, URI должен иметь форму rtsp://<username>:<password>@<host address>.
Использование RtspMediaSource
Чтобы получить больше возможностей для настройки, вы можете создать RtspMediaSource и передать его непосредственно проигрывателю вместо 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();
Использование RTSP за NAT (поддержка RTP/TCP)
ExoPlayer использует UDP в качестве протокола по умолчанию для передачи RTP.
При потоковой передаче RTSP за уровнем NAT может оказаться, что NAT не сможет пересылать входящие пакеты RTP/UDP на устройство. Это происходит, если в NAT отсутствует необходимое сопоставление UDP-портов. Если ExoPlayer обнаруживает, что в течение некоторого времени не поступали пакеты RTP и воспроизведение ещё не началось, ExoPlayer завершает текущий сеанс воспроизведения RTSP и пытается воспроизвести контент с помощью RTP через RTSP (передает пакеты RTP с помощью TCP-подключения, открытого для RTSP).
Время ожидания для повторной попытки с использованием TCP можно настроить, вызвав метод RtspMediaSource.Factory.setTimeoutMs(). Например, если время ожидания составляет четыре секунды, проигрыватель повторит попытку с использованием TCP после четырех секунд бездействия UDP.
Установка тайм-аута также влияет на логику обнаружения конца потока. То есть ExoPlayer сообщит, что воспроизведение завершено, если в течение заданного времени ожидания не будет получено никаких данных. Если задать слишком маленькое значение, при плохом качестве связи может преждевременно поступить сигнал о завершении потока.
RTP/TCP обеспечивает лучшую совместимость при некоторых настройках сети. Вы можете настроить ExoPlayer на использование RTP/TCP по умолчанию с помощью RtspMediaSource.Factory.setForceUseRtpTcp().
Передача пользовательского класса SocketFactory
Настраиваемые экземпляры SocketFactory могут быть полезны, когда требуется определенная маршрутизация (например, когда трафик RTSP должен проходить через определенный интерфейс или сокету нужны дополнительные флаги подключения).
По умолчанию RtspMediaSource использует стандартную фабрику сокетов Java (SocketFactory.getDefault()) для создания подключений к удаленным конечным точкам.
Это поведение можно переопределить с помощью параметра 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(socketFactory) .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(socketFactory) .createMediaSource(MediaItem.fromUri(rtspUri));