Интерфейс игрока

Плеер — это компонент вашего приложения, обеспечивающий воспроизведение медиафайлов. Интерфейс Media3 Player определяет структуру функций, обычно реализуемых плеером. В число этих функций входят:

  • Влияние на управление воспроизведением, такое как воспроизведение, пауза и поиск
  • Запрос свойств текущего воспроизводимого медиафайла, таких как позиция воспроизведения
  • Управление плейлистом/очередью медиафайлов
  • Настройка свойств воспроизведения, таких как перемешивание, повтор, скорость и громкость
  • Вывод видео на экран

Media3 также предоставляет реализацию интерфейса Player , называемую ExoPlayer .

Общий интерфейс между компонентами

Несколько компонентов в Media3 реализуют интерфейс Player, например:

Компонент Описание и заметки о поведении
ExoPlayer API медиаплеера и реализация интерфейса Player по умолчанию.
MediaController Взаимодействует с MediaSession для отправки команд воспроизведения. Если ваш Player и MediaSession находятся в Service отдельном от Activity или Fragment , где находится пользовательский интерфейс вашего проигрывателя, вы можете назначить MediaController в качестве проигрывателя для пользовательского интерфейса PlayerView . Вызовы методов воспроизведения и списка воспроизведения отправляются в ваш Player через MediaSession .
MediaBrowser В дополнение к функциональным возможностям, предлагаемым MediaController , взаимодействует с MediaLibrarySession для просмотра доступного медиаконтента.
SimpleBasePlayer Реализация Player , которая сводит количество методов к минимуму. Полезно при использовании пользовательского плеера, который нужно подключить к MediaSession .
ForwardingSimpleBasePlayer Подкласс SimpleBasePlayer , предназначенный для переадресации операций воспроизведения другому Player , с возможностью такой же последовательной настройки поведения, как и SimpleBasePlayer . Используйте этот класс для подавления или изменения определенных операций воспроизведения.
CastPlayer Реализация Player , взаимодействующая с приложением-приёмником Cast. Поведение зависит от базового сеанса Cast.

Хотя MediaSession не реализует интерфейс Player , при его создании требуется Player . Его цель — обеспечить доступ к Player из других процессов или потоков.

Архитектура воспроизведения Media3

Если у вас есть доступ к Player , необходимо вызывать его методы напрямую для выдачи команд воспроизведения. Вы можете объявить о воспроизведении и предоставить управление внешним источникам, реализовав MediaSession . Эти внешние источники реализуют MediaController , который упрощает подключение к медиасеансу и выдачу запросов на команды воспроизведения.

При воспроизведении медиаконтента в фоновом режиме необходимо разместить медиасеанс и проигрыватель в службе MediaSessionService или MediaLibraryService , работающей в режиме переднего плана. В этом случае вы сможете отделить проигрыватель от Activity в приложении, содержащей пользовательский интерфейс для управления воспроизведением. Для этого может потребоваться использование медиаконтроллера.

Диаграмма, показывающая, как компоненты воспроизведения Media3 встраиваются в архитектуру медиа-приложения.
Рисунок 1 : Интерфейс Player играет ключевую роль в архитектуре Media3.

Состояние игрока

Состояние медиаплеера, реализующего интерфейс Player состоит в основном из 4 категорий информации:

  1. Состояние воспроизведения
  2. Плейлист медиа-элементов
    • Последовательность экземпляров MediaItem для воспроизведения.
    • Извлечь с помощью getCurrentTimeline()
    • Экземпляры Player могут предоставлять методы работы со списком воспроизведения, такие как добавление или удаление MediaItem , а также вспомогательные методы, такие как getCurrentMediaItem() .
  3. Свойства воспроизведения/паузы, такие как:
    • playWhenReady : указывает, хочет ли пользователь, чтобы медиафайл воспроизводился, когда это возможно, или оставался приостановленным.
    • Причина подавления воспроизведения : указание причины подавления воспроизведения, если применимо, даже если playWhenReady имеет true
    • isPlaying : индикатор того, воспроизводит ли проигрыватель в данный момент, что будет true только в том случае, если состояние воспроизведения STATE_READY , playWhenReady равно true , а воспроизведение не подавлено.
  4. Позиция воспроизведения, включая:

Кроме того, интерфейс Player позволяет получить доступ к доступным дорожкам , метаданным мультимедиа , скорости воспроизведения , громкости и другим вспомогательным свойствам воспроизведения.

Следите за изменениями

Используйте Player.Listener для отслеживания изменений в Player . Подробную информацию о создании и использовании прослушивателя см. в документации ExoPlayer, посвящённой событиям Player.

Обратите внимание, что интерфейс слушателя не включает обратные вызовы для отслеживания обычного хода воспроизведения. Для непрерывного отслеживания хода воспроизведения, например, для настройки пользовательского интерфейса с индикатором прогресса, необходимо запрашивать текущую позицию с определёнными интервалами.

Котлин

val handler = Handler(Looper.getMainLooper())
fun checkPlaybackPosition(delayMs: Long): Boolean =
  handler.postDelayed(
    {
      val currentPosition = player.currentPosition
      // Update UI based on currentPosition
      checkPlaybackPosition(delayMs)
    },
    delayMs)

Ява

Handler handler = new Handler(Looper.getMainLooper());
boolean checkPlaybackPosition(long delayMs) {
    return handler.postDelayed(() -> {
        long currentPosition = player.getCurrentPosition();
        // Update UI based on currentPosition
        checkPlaybackPosition(delayMs);
    }, delayMs);
}

Управление воспроизведением

Интерфейс Player предлагает множество способов управления состоянием и воспроизведением:

Пользовательские реализации Player

Чтобы создать собственный проигрыватель, можно расширить класс SimpleBasePlayer , входящий в состав Media3. Этот класс предоставляет базовую реализацию интерфейса Player , сводя к минимуму количество методов, которые необходимо реализовать.

Начните с переопределения метода getState() . При вызове этот метод должен заполнять текущее состояние игрока, включая:

  • Набор доступных команд
  • Свойства воспроизведения, такие как должен ли проигрыватель начинать воспроизведение, когда состояние воспроизведения равно STATE_READY , индекс текущего воспроизводимого элемента мультимедиа и позиция воспроизведения в текущем элементе.

Котлин

class CustomPlayer : SimpleBasePlayer(looper) {
  override fun getState(): State {
    return State.Builder()
      .setAvailableCommands(...) // Set which playback commands the player can handle
      // Configure additional playback properties
      .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
      .setCurrentMediaItemIndex(0)
      .setContentPositionMs(0)
      .build()
  }
}

Ява

public class CustomPlayer extends SimpleBasePlayer {
  public CustomPlayer(Looper looper) {
    super(looper);
  }

  @Override
  protected State getState() {
    return new State.Builder()
      .setAvailableCommands(...) // Set which playback commands the player can handle
      // Configure additional playback properties
      .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
      .setCurrentMediaItemIndex(0)
      .setContentPositionMs(0)
      .build();
  }
}

SimpleBasePlayer обеспечит создание State с допустимой комбинацией значений состояния. Он также будет обрабатывать прослушиватели и информировать их об изменениях состояния. Если вам нужно вручную запустить обновление состояния, вызовите invalidateState() .

Помимо метода getState() , вам нужно реализовать только методы, используемые для команд, которые ваш проигрыватель объявляет доступными. Найдите переопределяемый метод-обработчик, соответствующий функциональности, которую вы хотите реализовать. Например, переопределите метод handleSeek() для поддержки таких операций, как COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM и COMMAND_SEEK_TO_NEXT_MEDIA_ITEM .

Изменить реализации Player

Вместо создания полностью настраиваемого Player вы можете использовать ForwardingSimpleBasePlayer для изменения состояния и поведения существующего Player . Подробнее см. в руководстве на странице «Настройка» .