ExoPlayer поддерживает HLS с несколькими форматами контейнеров. Содержащиеся форматы образцов аудио и видео также должны поддерживаться (подробности см. в разделе «Форматы примеров» ). Мы настоятельно рекомендуем производителям контента HLS создавать высококачественные потоки HLS, как описано здесь .
Особенность | Поддерживается | Комментарии |
---|---|---|
Контейнеры | ||
MPEG-TS | ДА | |
ФМП4/КМАФ | ДА | |
АДТС (ААС) | ДА | |
МП3 | ДА | |
Скрытые субтитры/субтитры | ||
СЕА-608 | ДА | |
СЕА-708 | ДА | |
ВебВТТ | ДА | |
Метаданные | ||
ID3 | ДА | |
СКТЭ-35 | НЕТ | |
Защита контента | ||
АЭС-128 | ДА | |
Образец АЭС-128 | НЕТ | |
Широкая лоза | ДА | API 19+ (схема «cenc») и 25+ (схема «cbcs») |
PlayReady SL2000 | ДА | Только Android-ТВ |
Управление сервером | ||
Дельта-обновления | ДА | |
Блокировка перезагрузки плейлиста | ДА | |
Блокировка загрузки подсказок по предварительной загрузке | ДА | За исключением диапазонов байтов с неопределенной длиной. |
Живое воспроизведение | ||
Регулярное живое воспроизведение | ДА | |
HLS с низкой задержкой (Apple) | ДА | |
HLS с низкой задержкой (сообщество) | НЕТ | |
Общие данные медиаклиента (CMCD) | ДА | Руководство по интеграции |
Использование Медиаитем
Чтобы воспроизводить поток HLS, вам необходимо зависеть от модуля HLS.
Котлин
implementation("androidx.media3:media3-exoplayer-hls:1.4.1")
классный
implementation "androidx.media3:media3-exoplayer-hls:1.4.1"
Затем вы можете создать MediaItem
для URI плейлиста HLS и передать его проигрывателю.
Котлин
// Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the media item to be played. player.setMediaItem(MediaItem.fromUri(hlsUri)) // Prepare the player. player.prepare()
Ява
// Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the media item to be played. player.setMediaItem(MediaItem.fromUri(hlsUri)); // Prepare the player. player.prepare();
Если ваш URI не заканчивается на .m3u8
, вы можете передать MimeTypes.APPLICATION_M3U8
в setMimeType
MediaItem.Builder
, чтобы явно указать тип контента.
URI элемента мультимедиа может указывать либо на список воспроизведения мультимедиа, либо на многовариантный список воспроизведения. Если URI указывает на многовариантный список воспроизведения, в котором объявлено несколько тегов #EXT-X-STREAM-INF
, то ExoPlayer автоматически адаптируется между вариантами, принимая во внимание как доступную пропускную способность, так и возможности устройства.
Использование HlsMediaSource
Чтобы получить дополнительные возможности настройки, вы можете создать HlsMediaSource
и передать его непосредственно проигрывателю вместо MediaItem
.
Котлин
// Create a data source factory. val dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory() // Create a HLS media source pointing to a playlist uri. val hlsMediaSource = HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri)) // Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the HLS media source as the playlist with a single media item. player.setMediaSource(hlsMediaSource) // Prepare the player. player.prepare()
Ява
// Create a data source factory. DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory(); // Create a HLS media source pointing to a playlist uri. HlsMediaSource hlsMediaSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri)); // Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the HLS media source as the playlist with a single media item. player.setMediaSource(hlsMediaSource); // Prepare the player. player.prepare();
Доступ к манифесту
Вы можете получить текущий манифест, вызвав Player.getCurrentManifest
. Для HLS вам следует привести возвращаемый объект к HlsManifest
. Обратный вызов onTimelineChanged
Player.Listener
также вызывается при каждой загрузке манифеста. Это произойдет один раз для контента по запросу и, возможно, много раз для контента в реальном времени. В следующем фрагменте кода показано, как приложение может что-то делать при загрузке манифеста.
Котлин
player.addListener( object : Player.Listener { override fun onTimelineChanged(timeline: Timeline, @TimelineChangeReason reason: Int) { val manifest = player.currentManifest if (manifest is HlsManifest) { // Do something with the manifest. } } } )
Ява
player.addListener( new Player.Listener() { @Override public void onTimelineChanged( Timeline timeline, @Player.TimelineChangeReason int reason) { Object manifest = player.getCurrentManifest(); if (manifest != null) { HlsManifest hlsManifest = (HlsManifest) manifest; // Do something with the manifest. } } });
Настройка воспроизведения
ExoPlayer предоставляет вам несколько способов адаптировать воспроизведение к потребностям вашего приложения. Примеры см. на странице «Настройки» .
Отключение бескусковой подготовки
По умолчанию ExoPlayer будет использовать подготовку без кусков. Это означает, что ExoPlayer будет использовать информацию из многовариантного списка воспроизведения только для подготовки потока, что работает, если теги #EXT-X-STREAM-INF
содержат атрибут CODECS
.
Возможно, вам придется отключить эту функцию, если ваши медиасегменты содержат мультиплексированные дорожки со скрытыми субтитрами, которые не объявлены в многовариантном списке воспроизведения с помощью тега #EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS
. В противном случае эти треки со скрытыми субтитрами не будут обнаружены и воспроизведены. Вы можете отключить подготовку без фрагментов в HlsMediaSource.Factory
, как показано в следующем фрагменте кода. Обратите внимание, что это увеличит время запуска, поскольку ExoPlayer необходимо загрузить медиа-сегмент, чтобы обнаружить эти дополнительные треки, и вместо этого предпочтительно объявить треки со скрытыми субтитрами в многовариантном списке воспроизведения.
Котлин
val hlsMediaSource = HlsMediaSource.Factory(dataSourceFactory) .setAllowChunklessPreparation(false) .createMediaSource(MediaItem.fromUri(hlsUri))
Ява
HlsMediaSource hlsMediaSource = new HlsMediaSource.Factory(dataSourceFactory) .setAllowChunklessPreparation(false) .createMediaSource(MediaItem.fromUri(hlsUri));
Создание высококачественного HLS-контента
Чтобы получить максимальную отдачу от ExoPlayer, существует ряд рекомендаций, которым вы можете следовать, чтобы улучшить свой HLS-контент. Прочтите нашу публикацию на Medium о воспроизведении HLS в ExoPlayer для получения полного объяснения. Основные моменты:
- Используйте точную длительность сегментов.
- Используйте непрерывный медиапоток; избегать изменений в медиаструктуре между сегментами.
- Используйте тег
#EXT-X-INDEPENDENT-SEGMENTS
. - Отдавайте предпочтение демультиплексированным потокам, а не файлам, содержащим как видео, так и аудио.
- Включите всю возможную информацию в многовариантный плейлист.
Следующие правила применяются специально для прямых трансляций:
- Используйте тег
#EXT-X-PROGRAM-DATE-TIME
. - Используйте тег
#EXT-X-DISCONTINUITY-SEQUENCE
. - Обеспечьте окно долгой жизни. Одна минута или больше – это здорово.