Прямая трансляция

ExoPlayer воспроизводит большинство адаптивных прямых трансляций без какой-либо специальной настройки. Дополнительную информацию см. на странице «Поддерживаемые форматы» .

Адаптивные прямые трансляции предлагают окно доступных медиафайлов, которое регулярно обновляется в соответствии с текущим реальным временем. Это означает, что позиция воспроизведения всегда будет находиться где-то в этом окне, в большинстве случаев близко к текущему реальному времени, в которое создается поток. Разница между текущим реальным временем и позицией воспроизведения называется смещением в реальном времени (live offset) .

Обнаружение и мониторинг воспроизведения в реальном времени

При каждом обновлении окна воспроизведения зарегистрированные экземпляры 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, с которого запускается активное окно.
    • Window.getCurrentUnixTimeMs — это время, прошедшее с момента начала эпохи Unix для текущего реального времени. Это значение может быть скорректировано с учетом известной разницы во времени между сервером и клиентом.
    • Window.getDefaultPositionMs — это позиция в окне воспроизведения, с которой проигрыватель по умолчанию начнет воспроизведение.

Поиск в прямых трансляциях

С помощью Player.seekTo можно переместиться в любую точку внутри окна воспроизведения. Передаваемая позиция перемещения указывается относительно начала окна воспроизведения. Например, seekTo(0) переместит курсор в начало окна воспроизведения. После перемещения плеер будет стараться сохранить то же смещение относительно позиции перемещения.

В окне воспроизведения также есть позиция по умолчанию, с которой должно начинаться воспроизведение. Эта позиция обычно находится где-то близко к краю окна воспроизведения. Вы можете перейти к позиции по умолчанию, вызвав Player.seekToDefaultPosition .

Пользовательский интерфейс воспроизведения в реальном времени

Компоненты пользовательского интерфейса ExoPlayer по умолчанию отображают продолжительность окна воспроизведения и текущую позицию в нем. Это означает, что позиция будет как бы смещаться назад при каждом обновлении окна воспроизведения. Если вам нужно другое поведение, например, отображение времени Unix или текущего смещения в реальном времени, вы можете создать форк PlayerControlView и модифицировать его в соответствии со своими потребностями.

Настройка параметров воспроизведения в реальном времени

ExoPlayer использует ряд параметров для управления смещением позиции воспроизведения относительно края активного канала, а также диапазоном скоростей воспроизведения, которые можно использовать для регулировки этого смещения.

ExoPlayer получает значения этих параметров из трех источников в порядке убывания приоритета (используется первое найденное значение):

  • Значения для каждого MediaItem передаются в MediaItem.Builder.setLiveConfiguration .
  • Глобальные значения по умолчанию, установленные для DefaultMediaSourceFactory .
  • Ценности, почерпнутые непосредственно из средств массовой информации.

Котлин

// 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 . В обоих случаях экземпляр можно задать при создании проигрывателя:

Котлин

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 в демонстрационном приложении иллюстрирует этот подход.

Котлин

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
  }
}