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. Чтобы воспроизвести защищенный контент 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 и воспроизведение ещё не началось, он прерывает текущий сеанс воспроизведения RTSP и повторяет попытку воспроизведения с использованием RTP-over-RTSP (передача пакетов RTP с использованием TCP-соединения, открытого для RTSP).
Время ожидания для повторной попытки с TCP можно настроить, вызвав метод RtspMediaSource.Factory.setTimeoutMs(). Например, если время ожидания составляет четыре секунды, то после четырех секунд бездействия UDP проигрыватель повторит попытку с TCP.
Настройка времени ожидания также влияет на логику обнаружения конца потока. Это означает, что 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));