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

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

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

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

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

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

Компонент Описание и заметки о поведении
ExoPlayer API медиаплеера и реализация интерфейса Player по умолчанию.
MediaController Взаимодействует с MediaSession для отправки команд воспроизведения. Если ваш Player и MediaSession находятся в Service , отдельной от Activity или Fragment , где расположен пользовательский интерфейс плеера, вы можете назначить ваш MediaController в качестве плеера для вашего PlayerView UI. Вызовы методов воспроизведения и создания плейлистов отправляются вашему 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 по событиям плеера .

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

Котлин

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

Java

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

Java

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 . Подробнее см. руководство на странице «Настройка» .