ExoPlayer поддерживает большинство адаптивных трансляций без дополнительной настройки. Подробнее о поддерживаемых форматах…
Адаптивные трансляции предлагают окно доступного медиаконтента, которое регулярно обновляется, чтобы соответствовать текущему времени. Это означает, что позиция воспроизведения всегда будет находиться в этом окне, в большинстве случаев близко к текущему реальному времени, в котором создается трансляция. Разница между текущим временем и позицией воспроизведения называется смещением трансляции.
Обнаружение и отслеживание воспроизведения в реальном времени
При каждом обновлении окна трансляции зарегистрированные экземпляры Player.Listener будут получать событие onTimelineChanged. Чтобы получить информацию о текущем воспроизведении трансляции, можно использовать различные методы Player и Timeline.Window, перечисленные ниже и показанные на рисунке.

Player.isCurrentWindowLiveуказывает, является ли текущий медиаконтент трансляцией. Это значение остается истинным, даже если трансляция завершилась.Player.isCurrentWindowDynamicуказывает, обновляется ли сейчас воспроизводимый медиаконтент. Обычно это относится к трансляциям, которые ещё не завершены. Обратите внимание, что этот флаг также может быть установлен для обычных видео.Player.getCurrentLiveOffsetвозвращает смещение между текущим реальным временем и позицией воспроизведения (если доступно).Player.getDurationвозвращает длину текущего окна трансляции.Player.getCurrentPositionвозвращает позицию воспроизведения относительно начала окна трансляции.Player.getCurrentMediaItemвозвращает текущий медиаконтент, гдеMediaItem.liveConfigurationсодержит переопределения, предоставленные приложением для целевого смещения прямого эфира и параметров корректировки смещения прямого эфира.Player.getCurrentTimelineвозвращает текущую структуру медиаконтента в форматеTimeline. Текущий объектTimeline.Windowможно получить из объектаTimelineс помощью методовPlayer.getCurrentMediaItemIndexиTimeline.getWindow. В течениеWindow:Window.liveConfigurationсодержит целевое смещение трансляции и параметры корректировки смещения трансляции. Эти значения основаны на информации из медиаконтента и любых переопределений, заданных в приложении вMediaItem.liveConfiguration.Window.windowStartTimeMs– время начала окна трансляции в формате Unix Epoch.Window.getCurrentUnixTimeMs– время с начала эпохи Unix до текущего момента в реальном времени. Это значение может быть скорректировано с учетом известной разницы во времени между сервером и клиентом.Window.getDefaultPositionMs– позиция в окне трансляции, с которой проигрыватель начнет воспроизведение по умолчанию.
Перемотка в прямых трансляциях
Вы можете перейти к любому моменту в окне трансляции, используя Player.seekTo. Позиция, указанная в запросе seek, отсчитывается от начала окна трансляции. Например, команда "назад seekTo(0)" переведет вас в начало окна трансляции. После перехода к определенной позиции проигрыватель попытается сохранить смещение относительно начала трансляции.
У окна трансляции также есть позиция по умолчанию, с которой должно начинаться воспроизведение. Обычно она находится рядом с краем трансляции. Чтобы перейти к позиции по умолчанию, вызовите метод Player.seekToDefaultPosition.
Интерфейс воспроизведения трансляции
Стандартные компоненты интерфейса ExoPlayer показывают продолжительность окна трансляции и текущую позицию воспроизведения в нем. Это означает, что при каждом обновлении окна трансляции позиция будет как бы отматываться назад. Если вам нужно другое поведение, например отображение Unix-времени или текущего смещения трансляции, вы можете создать ответвление PlayerControlView и изменить его в соответствии со своими потребностями.
Как настроить параметры воспроизведения трансляции
ExoPlayer использует некоторые параметры, чтобы контролировать смещение позиции воспроизведения относительно начала трансляции и диапазон скоростей воспроизведения, которые можно использовать для корректировки этого смещения.
ExoPlayer получает значения этих параметров из трех источников в порядке убывания приоритета (используется первое найденное значение):
- Значения
MediaItem, переданные вMediaItem.Builder.setLiveConfiguration. - Глобальные значения по умолчанию, заданные в
DefaultMediaSourceFactory. - Значения, считанные непосредственно из медиаконтента.
Kotlin
// Global settings. val player = ExoPlayer.Builder(context) .setMediaSourceFactory(DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000)) .build() // Per MediaItem settings. val mediaItem = MediaItem.Builder() .setUri(mediaUri) .setLiveConfiguration( MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build() ) .build() player.setMediaItem(mediaItem)
Java
// Global settings. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000)) .build(); // Per MediaItem settings. MediaItem mediaItem = new MediaItem.Builder() .setUri(mediaUri) .setLiveConfiguration( new MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build()) .build(); player.setMediaItem(mediaItem);
Доступные значения конфигурации:
targetOffsetMs– целевое смещение трансляции. Проигрыватель попытается приблизиться к этому смещению во время воспроизведения, если это возможно.minOffsetMs– минимальное допустимое смещение трансляции. Даже если смещение будет скорректировано с учетом текущих условий сети, проигрыватель не будет пытаться уменьшить его во время воспроизведения.maxOffsetMs– максимальное допустимое смещение трансляции. Даже если смещение будет скорректировано с учетом текущих условий сети, проигрыватель не будет пытаться превысить это смещение во время воспроизведения.minPlaybackSpeed– минимальная скорость воспроизведения, которую может использовать проигрыватель, чтобы достичь целевого смещения трансляции.maxPlaybackSpeed– максимальная скорость воспроизведения, которую может использовать проигрыватель, чтобы догнать трансляцию и достичь целевого смещения.
Настройка скорости воспроизведения
При воспроизведении трансляции с низкой задержкой ExoPlayer корректирует смещение, немного изменяя скорость воспроизведения. Проигрыватель попытается сопоставить целевое смещение трансляции, предоставленное медиаконтентом или приложением, но также будет реагировать на изменения в сети. Например, если во время воспроизведения происходит буферизация, проигрыватель немного замедлит воспроизведение, чтобы увеличить задержку. Если сеть снова станет достаточно стабильной, чтобы поддерживать воспроизведение с меньшим отставанием, проигрыватель ускорит воспроизведение, чтобы вернуться к целевому смещению.
Если вы не хотите, чтобы скорость воспроизведения регулировалась автоматически, отключите эту функцию, задав для свойств minPlaybackSpeed и maxPlaybackSpeed значение 1.0f.
Аналогичным образом можно включить эту функцию для трансляций с обычной задержкой, задав для этих параметров значения, отличные от 1.0f. Подробнее о том, как задавать эти свойства, рассказывается в разделе о настройке.
Как настроить алгоритм изменения скорости воспроизведения
Если регулировка скорости включена, LivePlaybackSpeedControl определяет, какие корректировки будут внесены. Вы можете реализовать собственный LivePlaybackSpeedControl или настроить реализацию по умолчанию, которая представлена в виде DefaultLivePlaybackSpeedControl. В обоих случаях экземпляр можно задать при создании проигрывателя:
Kotlin
val player = ExoPlayer.Builder(context) .setLivePlaybackSpeedControl( DefaultLivePlaybackSpeedControl.Builder().setFallbackMaxPlaybackSpeed(1.04f).build() ) .build()
Java
ExoPlayer player = new ExoPlayer.Builder(context) .setLivePlaybackSpeedControl( new DefaultLivePlaybackSpeedControl.Builder() .setFallbackMaxPlaybackSpeed(1.04f) .build()) .build();
К параметрам настройки DefaultLivePlaybackSpeedControl относятся:
fallbackMinPlaybackSpeedиfallbackMaxPlaybackSpeed– минимальная и максимальная скорости воспроизведения, которые можно использовать для регулировки, если ни медиаконтент, ни предоставленный приложением параметрMediaItemне определяют ограничения.proportionalControlFactor– определяет, насколько плавно будет меняться скорость. Высокое значение делает изменения более резкими и заметными, но также более вероятными для восприятия на слух. Чем меньше значение, тем плавнее переход между скоростями, но тем медленнее будет выполняться задача.targetLiveOffsetIncrementOnRebufferMs– это значение добавляется к целевому смещению трансляции при каждой повторной буферизации, чтобы обеспечить более осторожную работу. Чтобы отключить эту функцию, задайте значение 0.minPossibleLiveOffsetSmoothingFactor: коэффициент экспоненциального сглаживания, который используется для отслеживания минимально возможного смещения трансляции на основе текущего буферизованного медиаконтента. Значение, близкое к 1, означает, что оценка более осторожная и может дольше адаптироваться к улучшению условий сети. Более низкое значение означает, что оценка будет быстрее адаптироваться, но при этом повышается риск повторной буферизации.
BehindLiveWindowException и ERROR_CODE_BEHIND_LIVE_WINDOW
Позиция воспроизведения может отставать от окна трансляции, например если проигрыватель был на паузе или буферизировался достаточно долго. В этом случае воспроизведение будет прервано, а исключение с кодом ошибки ERROR_CODE_BEHIND_LIVE_WINDOW будет передано через Player.Listener.onPlayerError. Код приложения может обрабатывать такие ошибки, возобновляя воспроизведение с позиции по умолчанию. В демонстрационном приложении этот подход реализован в PlayerActivity.
Kotlin
override fun onPlayerError(error: PlaybackException) { if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) { // Re-initialize player at the live edge. player.seekToDefaultPosition() player.prepare() } else { // Handle other errors } }
Java
@Override public void onPlayerError(PlaybackException error) { if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) { // Re-initialize player at the live edge. player.seekToDefaultPosition(); player.prepare(); } else { // Handle other errors } }