Проигрыватель — это компонент вашего приложения, который облегчает воспроизведение мультимедийных элементов. Интерфейс 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
, который работает как служба переднего плана. Если вы это сделаете, вы сможете отделить свой проигрыватель от действия в вашем приложении, которое содержит пользовательский интерфейс для управления воспроизведением. Это может потребовать использования медиа-контроллера.
Состояние игрока
Состояние медиаплеера, реализующего интерфейс Player
состоит в основном из 4 категорий информации:
- Состояние воспроизведения
- Получите с помощью
getPlaybackState()
. - Значение состояния, определенное интерфейсом, — это
STATE_IDLE
,STATE_BUFFERING
,STATE_READY
иSTATE_ENDED
.
- Получите с помощью
- Плейлист с медиа-материалами
- Последовательность экземпляров
MediaItem
для воспроизведения. - Получить с помощью
getCurrentTimeline()
- Экземпляры
Player
могут предоставлять методы работы со списком воспроизведения, такие как добавление или удалениеMediaItem
, а также удобные методы, такие какgetCurrentMediaItem()
.
- Последовательность экземпляров
- Свойства воспроизведения/паузы, такие как:
-
playWhenReady
: указывает, хочет ли пользователь, чтобы медиа воспроизводилось, когда это возможно, или оставалось на паузе. - Причина подавления воспроизведения : указание того, почему воспроизведение подавляется, если применимо, даже если
playWhenReady
имеетtrue
-
isPlaying
: указание того, играет ли проигрыватель в данный момент, что будетtrue
только в том случае, если состояние воспроизведения равноSTATE_READY
,playWhenReady
имеетtrue
и воспроизведение не подавляется.
-
- Позиция воспроизведения, включая:
- Индекс текущего медиа-элемента : индекс текущего
MediaItem
в списке воспроизведения. -
isPlayingAd
: индикатор того, воспроизводится ли вставленное объявление. - Текущая позиция воспроизведения : текущая позиция воспроизведения в текущем
MediaItem
или вставленном объявлении.
- Индекс текущего медиа-элемента : индекс текущего
Кроме того, интерфейс 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
предлагает множество способов манипулирования состоянием и управления воспроизведением:
- Основные элементы управления воспроизведением , такие как
play()
,pause()
,prepare()
иstop()
. - Операции со списками воспроизведения, такие как
addMediaItem()
илиremoveMediaItem()
. - Попытка изменить текущий элемент или позицию.
- Установите режимы повтора и режим случайного воспроизведения .
- Обновите настройки выбора трека .
- Установите скорость воспроизведения .
Пользовательские реализации 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
.