1. Введение
Последнее обновление: 9 сентября 2020 г.
Каковы преимущества добавления MediaSession при воспроизведении видео?
Медиа-сессии являются неотъемлемой связью между платформой Android и медиа-приложениями. Он не только информирует Android о воспроизведении мультимедиа (чтобы он мог перенаправить медиа-действия в правильный сеанс), но также сообщает платформе, что воспроизводится и как этим можно управлять.
Открытие MediaSession через ваше приложение дает пользователям различные преимущества. Вот несколько замечательных примеров.
Google Ассистент
Пользователи могут легко взаимодействовать с медиафайлами в вашем приложении с помощью голосовых команд, таких как «Пауза», «Возобновить» и «Далее». Метаданные ваших медиафайлов также можно использовать для получения ответов о том, что сейчас воспроизводится.
Андроид ТВ
На большом экране ваше приложение Android TV может использовать обычные пульты дистанционного управления для пользователей телевизоров, поддерживающих HDMI-CEC. Команды, выданные кнопками воспроизведения/паузы, остановки, следующего и предыдущего, передаются в ваше приложение.
Экранные элементы управления мультимедиа
Начиная с Android 4.0 (уровень API 14), система может получить доступ к состоянию воспроизведения и метаданным мультимедийного сеанса. Эта функция позволяет на экране блокировки отображать элементы управления мультимедиа и изображения. Такое поведение зависит от версии Android.
Фоновые медиа
Медиафайлами можно управлять в любом из этих сценариев, даже если приложение, воспроизводящее мультимедиа, работает в фоновом режиме.
Окружающие вычисления
Предоставление вашим медиафайлам данных о том, что воспроизводится и как этим можно управлять, может стать мостом между устройствами, чтобы пользователи могли взаимодействовать с ним различными способами, которые им нравятся.
Что ты построишь
В этой кодовой лаборатории вы собираетесь расширить существующий образец Exoplayer, добавив поддержку мультимедийных сеансов. Ваше приложение будет:
- Правильно отражать активное состояние медиа-сессии
- Передача элементов управления мультимедиа в ExoPlayer
- Передавать метаданные элементов в очереди в медиа-сеанс.
Что вы узнаете
- Почему медиа-сессии предлагают пользователям более богатый опыт
- Как создать медиа-сессию и управлять ее состоянием
- Как подключить медиа-сессию к ExoPlayer
- Как включить метаданные элементов в очередь воспроизведения в медиасеансе
- Как добавить дополнительные (настраиваемые) действия
Эта лаборатория кода посвящена MediaSession SDK. Нерелевантные концепции и блоки кода, включая подробности реализации ExoPlayer, не обсуждаются, а предоставляются для простого копирования и вставки.
Что вам понадобится
- Последняя версия Android Studio (3.5 или новее).
- Базовые знания разработки Android-приложений.
2. Приступаем к настройке
Какова наша отправная точка?
Нашей отправной точкой является основная демо-версия ExoPlayer. Эта демонстрация содержит видео с экранными элементами управления воспроизведением, но не использует мультимедийные сеансы «из коробки». Это отличное место, где мы можем погрузиться и добавить их!
Получите образец ExoPlayer
Для начала давайте начнем с примера ExoPlayer. Клонируйте репозиторий GitHub, запустив приведенный ниже код.
git clone https://github.com/google/ExoPlayer.git
Открыть демо-версию
В Android Studio откройте основной демонстрационный проект, расположенный в папке demos/main
.
Android Studio предложит вам указать путь к SDK. Если у вас возникнут какие-либо проблемы, вы можете следовать рекомендациям по обновлению инструментов IDE и SDK .
Если вас попросят использовать последнюю версию Gradle, обновите ее.
Уделите немного времени, чтобы получить общее представление о том, как устроено приложение. Обратите внимание, что существует два действия: SampleChooserActivity и PlayerActivity. Оставшуюся часть работы с кодом мы проведем в PlayerActivity, где фактически воспроизводится медиафайл, поэтому откройте этот класс и переходите к следующему разделу.
3. Создайте медиа-сеанс и управляйте его состоянием.
Создать медиа-сессию
Откройте PlayerActivity.java
. Этот класс создает ExoPlayer и управляет его функциями, такими как рендеринг видео на экран. В этом упражнении мы подключим ExoPlayer к медиа-сеансу.
Объявите следующие два поля в верхней части класса. Мы будем использовать эти поля в этом разделе.
private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;
Вам нужно будет добавить зависимость проекта «extension-mediasession» в build.gradle
уровня модуля для «Модуль: демонстрация»:
implementation project(path: ':extension-mediasession')
Обратите внимание, что Android Studio может помочь вам автоматически добавить эту зависимость, если вы наведете указатель мыши на ошибку при разрешении MediaSessionConnector:
Наконец, разрешите импорт классов, добавив следующее:
import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
Когда действие будет создано, мы захотим создать медиа-сеанс и соединитель медиа-сеанса, который будет служить посредником между медиа-сеансом и ExoPlayer.
Идеальное место для вставки — это место, где также создается ExoPlayer. В нашем демонстрационном приложении мы можем добавить наш код в конец initializePlayer()
. Обязательно добавьте эту логику после создания экземпляра проигрывателя!
private void initializePlayer() {
if (player == null) {
...
player = ...
...
mediaSession = new MediaSessionCompat(this, "sample");
mediaSessionConnector = new MediaSessionConnector(mediaSession);
mediaSessionConnector.setPlayer(player);
}
...
}
Выпустить медиа-сессию
Освободите сеанс мультимедиа, когда он больше не нужен. Когда мы выпускаем ExoPlayer в releasePlayer()
, мы также можем включить для этого следующий код:
private void releasePlayer() {
if (mediaSession != null) {
mediaSession.release();
}
...
}
Управление состоянием медиа-сессии
Теперь, когда мы создали экземпляр медиа-сеанса, нам нужно убедиться, что его состояние правильно отражается при взаимодействии пользователя с действием.
Когда пользователь начинает действие, медиа-сеанс должен стать активным:
@Override
public void onStart() {
...
if (mediaSession != null) {
mediaSession.setActive(true);
}
}
Поскольку наше приложение не воспроизводит мультимедиа в фоновом режиме, важно убедиться, что медиа-сеанс становится неактивным, когда пользователь прекращает действие:
@Override
public void onStop() {
super.onStop();
if (mediaSession != null) {
mediaSession.setActive(false);
}
...
}
Давайте запустим демо
- Подключите Android-устройство или запустите эмулятор.
- Убедитесь, что выбрано «демо» для запуска с панели инструментов Android Studio.
- Нажмите с панели инструментов Android Studio.
- После запуска приложения на вашем устройстве выберите видеопоток для воспроизведения.
- После начала воспроизведения изучите возможность использования следующих команд
adb
для управления сеансом мультимедиа:
adb shell media dispatch pause
adb shell media dispatch play
adb shell media dispatch play-pause
adb shell media dispatch fast-forward
adb shell media dispatch rewind
- Также узнайте, как Android видит ваш медиа-сеанс. В частности, вы можете проверить, какие действия поддерживаются, просмотрев поле действия. Число, которое вы видите здесь, представляет собой комбинацию идентификаторов действий, объявленных в объекте PlaybackState . Чтобы увидеть запуск медиа-сеанса:
adb shell dumpsys media_session
- Если вы используете физическое устройство с микрофоном, попробуйте вызвать Google Ассистента и подать голосовые команды, например: «Пауза». "Резюме." «Перемотка вперед на 1 минуту».
Пример ExoPlayer, работающий на Android TV.
4. Включение метаданных элементов в очередь воспроизведения.
Теперь мы можем расширить поддерживаемые функции нашего медиа-сеанса, где мы ранее создали наш MediaSessionConnector в initializePlayer()
.
Добавление TimelineQueueNavigator
ExoPlayer представляет структуру мультимедиа в виде временной шкалы. Для получения подробной информации о том, как это работает, прочтите об объекте Timeline ExoPlayer. Подключаясь к этой структуре, мы можем получать информацию об изменении контента и предоставлять метаданные о том, что сейчас воспроизводится, когда нас об этом спросят.
Для этого мы определим TimelineQueueNavigator. Найдите экземпляр MediaSessionConnector в initializePlayer()
и добавьте реализацию TimelineQueueNavigator после инициализации mediaSession
.
mediaSessionConnector.setQueueNavigator(new TimelineQueueNavigator(mediaSession) {
@Override
public MediaDescriptionCompat getMediaDescription(Player player, int windowIndex) {
return new MediaDescriptionCompat.Builder()
.setTitle(player.getCurrentMediaItem().mediaMetadata.title)
.setDescription("MediaDescription description for " + windowIndex)
.setSubtitle("MediaDescription subtitle")
.build();
}
});
Разрешите импорт классов, добавив:
import android.support.v4.media.MediaDescriptionCompat;
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator;
Обратите внимание, что параметр windowIndex
соответствует элементу этого индекса в очереди воспроизведения.
Теперь, когда вы добавили метаданные, вы можете проверить, понимает ли Ассистент, что воспроизводится. Во время воспроизведения видео на Android TV вызовите Ассистента и спросите: «Что воспроизводится?»
5. Настройка действий
Возможно, ваш плеер не поддерживает некоторые действия или вы хотели бы включить поддержку большего? Давайте теперь углубимся в медиа-сеанс, где мы ранее создали наш MediaSessionConnector в initializePlayer()
.
Объявление поддерживаемых действий
Попробуйте использовать mediaSessionConnector.setEnabledPlaybackActions()
чтобы настроить, какие действия вы хотите поддерживать в мультимедийном сеансе.
Обратите внимание, что полный комплект:
mediaSessionConnector.setEnabledPlaybackActions(
PlaybackStateCompat.ACTION_PLAY_PAUSE
| PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_PAUSE
| PlaybackStateCompat.ACTION_SEEK_TO
| PlaybackStateCompat.ACTION_FAST_FORWARD
| PlaybackStateCompat.ACTION_REWIND
| PlaybackStateCompat.ACTION_STOP
| PlaybackStateCompat.ACTION_SET_REPEAT_MODE
| PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE
);
Давайте еще раз посмотрим, как эти данные предоставляются платформе:
- Как и раньше, запустите видео.
- Узнайте, как Android видит метаданные вашего медиа-сеанса, выполнив:
adb shell dumpsys media_session
- Найдите строку, содержащую метаданные, и обратите внимание, что заголовок и описание включены и связаны с
com.google.android.exoplayer2.demo/sample
.
Добавление дополнительных действий
Мы можем расширить нашу медиа-сессию некоторыми дополнительными действиями. В этом разделе мы добавим только поддержку подписей.
Поддержка подписей
Добавление поддержки подписей к медиа-сессиям позволяет пользователям переключать их голосом. Там, где вы инициализировали соединитель мультимедийного сеанса, добавьте следующее:
mediaSessionConnector.setCaptionCallback(new MediaSessionConnector.CaptionCallback() {
@Override
public void onSetCaptioningEnabled(Player player, boolean enabled) {
Log.d("MediaSession", "onSetCaptioningEnabled: enabled=" + enabled);
}
@Override
public boolean hasCaptions(Player player) {
return true;
}
@Override
public boolean onCommand(Player player, ControlDispatcher controlDispatcher, String command, Bundle extras, ResultReceiver cb) {
return false;
}
}
);
Наконец, устраните отсутствующий импорт.
Вы можете проверить это, вызвав Google Assistant на Android TV и сказав «Включить субтитры». Проверьте Logcat на наличие сообщений, чтобы увидеть, как это вызывается в вашем коде.
6. Поздравления
Поздравляем, вы успешно добавили медиа-сеансы в образец!
Вы получили огромный функционал благодаря:
- добавление медиа-сессии,
- подключение медиа-сессий к экземпляру ExoPlayer,
- добавление метаданных и дополнительных действий.
Теперь вы знаете ключевые шаги, необходимые для обогащения мультимедийного приложения и предоставления пользователям более универсального опыта!
Последнее замечание
Эта лаборатория кода была построена на основе образца исходного кода ExoPlayer. Нет необходимости использовать ExoPlayer из исходного кода, вместо этого рекомендуется использовать зависимости для ExoPlayer и MediaSessionConnector, чтобы было легче оставаться в курсе последних выпусков.
Для этого просто замените зависимости проекта, такие как:
implementation project(modulePrefix + 'library-core')
implementation project(path: ':extension-mediasession')
для извлечения из репозиториев Maven, например:
implementation 'com.google.android.exoplayer:exoplayer-core:2.+'
implementation 'com.google.android.exoplayer:extension-mediasession:2.+'