Приложения, которые в настоящее время используют автономную библиотеку com.google.android.exoplayer2 и androidx.media должны перейти на androidx.media3 . Используйте скрипт миграции для переноса файлов сборки Gradle, исходных файлов Java и Kotlin, а также файлов XML-разметки с ExoPlayer 2.19.1 на AndroidX Media3 1.1.1 .
Обзор
Перед миграцией ознакомьтесь со следующими разделами, чтобы узнать больше о преимуществах новых API, API для миграции и предварительных требованиях, которым должен соответствовать проект вашего приложения.
Почему стоит перейти на Jetpack Media3?
- Это новый адрес для ExoPlayer , в то время как
com.google.android.exoplayer2больше не поддерживается. - Доступ к API проигрывателя осуществляется между компонентами/процессами с помощью
MediaBrowser/MediaController. - Воспользуйтесь расширенными возможностями API
MediaSessionиMediaController. - Рекламируйте возможности воспроизведения с детальным контролем доступа .
- Упростите свое приложение , удалив
MediaSessionConnectorиPlayerNotificationManager. - Обратная совместимость с API-интерфейсами клиентов, совместимыми с мультимедиа (
MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat).
API для работы с медиафайлами будут переведены на AndroidX Media3.
- ExoPlayer и его расширения
Это включает в себя все модули устаревшего проекта ExoPlayer, за исключением модуля mediasession , разработка которого прекращена. Приложения или модули, зависящие от пакетов вcom.google.android.exoplayer2могут быть перенесены с помощью скрипта миграции. - MediaSessionConnector (в зависимости от пакетов
androidx.media.*изandroidx.media:media:1.4.3+)
УдалитеMediaSessionConnectorи используйте вместо негоandroidx.media3.session.MediaSession. - MediaBrowserServiceCompat (в зависимости от пакетов
androidx.media.*изandroidx.media:media:1.4.3+)
Перенесите подклассыandroidx.media.MediaBrowserServiceCompatвandroidx.media3.session.MediaLibraryServiceи используйте код, в которомMediaBrowserCompat.MediaItemперенесен вandroidx.media3.common.MediaItem. - MediaBrowserCompat (в зависимости от пакетов
android.support.v4.media.*изandroidx.media:media:1.4.3+)
Перенесите клиентский код, использующийMediaBrowserCompatилиMediaControllerCompat, чтобы использоватьandroidx.media3.session.MediaBrowserсandroidx.media3.common.MediaItem.
Предварительные требования
Убедитесь, что ваш проект находится под контролем версий.
Убедитесь, что вы можете легко отменить изменения, внесенные с помощью скриптовых инструментов миграции. Если ваш проект еще не находится под контролем версий, сейчас самое время начать это делать. Если по какой-либо причине вы не хотите этого делать, создайте резервную копию проекта перед началом миграции.
Обновите приложение
Мы рекомендуем обновить ваш проект, используя самую последнюю версию библиотеки ExoPlayer , и удалить все вызовы устаревших методов. Если вы планируете использовать скрипт для миграции, необходимо согласовать версию, на которую вы обновляете проект, с версией, обрабатываемой скриптом.
Увеличьте значение параметра compileSdkVersion вашего приложения как минимум до 32 .
Обновите Gradle и плагин Gradle для Android Studio до последней версии, которая работает с обновленными зависимостями, указанными выше. Например:
- Версия плагина Android Gradle: 7.1.0
- Версия Gradle: 7.4
Замените все операторы импорта с подстановочными знаками (*) на операторы импорта с полными квалифицированными значениями: удалите операторы импорта с подстановочными знаками и используйте Android Studio для импорта операторов с полными квалифицированными значениями (F2 - Alt/Enter, F2 - Alt/Enter, ...).
Необходимо перейти с
com.google.android.exoplayer2.PlayerViewнаcom.google.android.exoplayer2.StyledPlayerView. Это необходимо, поскольку в AndroidX Media3 нет эквивалентаcom.google.android.exoplayer2.PlayerView.
Миграция ExoPlayer с поддержкой скриптов.
Этот скрипт упрощает переход от com.google.android.exoplayer2 к новой структуре пакетов и модулей в androidx.media3 . Скрипт выполняет некоторые проверки валидации в вашем проекте и выводит предупреждения, если проверка не пройдена. В противном случае он применяет сопоставления переименованных классов и пакетов в ресурсах проекта Android Gradle, написанного на Java или Kotlin.
usage: ./media3-migration.sh [-p|-c|-d|-v]|[-m|-l [-x <path>] [-f] PROJECT_ROOT]
PROJECT_ROOT: path to your project root (location of 'gradlew')
-p: list package mappings and then exit
-c: list class mappings (precedence over package mappings) and then exit
-d: list dependency mappings and then exit
-l: list files that will be considered for rewrite and then exit
-x: exclude the path from the list of file to be changed: 'app/src/test'
-m: migrate packages, classes and dependencies to AndroidX Media3
-f: force the action even when validation fails
-v: print the exoplayer2/media3 version strings of this script
-h, --help: show this help text
Использование скрипта миграции
Загрузите скрипт миграции из тега проекта ExoPlayer на GitHub, соответствующего версии, до которой вы обновили свое приложение:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"Сделайте скрипт исполняемым:
chmod 744 media3-migration.shЗапустите скрипт с
--help, чтобы узнать о доступных параметрах.Запустите скрипт с параметром
-l, чтобы вывести список файлов, выбранных для миграции (используйте-f, чтобы принудительно вывести список без предупреждений):./media3-migration.sh -l -f /path/to/gradle/project/rootЗапустите скрипт с
-m, чтобы сопоставить пакеты, классы и модули с Media3. Запуск скрипта с параметром-mприменит изменения к выбранным файлам.- Остановить работу при ошибке проверки без внесения изменений.
./media3-migration.sh -m /path/to/gradle/project/root- Принудительное исполнение
Если скрипт обнаружит нарушение предварительных условий, миграцию можно принудительно запустить с помощью флага
-f:./media3-migration.sh -m -f /path/to/gradle/project/root
# list files selected for migration when excluding paths
./media3-migration.sh -l -x "app/src/test/" -x "service/" /path/to/project/root
# migrate the selected files
./media3-migration.sh -m -x "app/src/test/" -x "service/" /path/to/project/root
После запуска скрипта с опцией -m выполните следующие действия вручную:
- Проверьте, как скрипт изменил ваш код : используйте инструмент сравнения файлов и исправьте потенциальные проблемы (если вы считаете, что в скрипте есть общая проблема, возникшая без передачи параметра
-fподумайте о том, чтобы сообщить об ошибке ). - Соберите проект : используйте команду
./gradlew clean buildили в Android Studio выберите `File > Sync Project with Gradle Files` , затем `Build > Clean project` , а затем `Build > Rebuild project` (отслеживайте процесс сборки на вкладке `Build - Build Output` в Android Studio ).
Рекомендуемые дальнейшие действия:
- Устранить ошибки, связанные с согласием на использование нестабильных API .
- Замените устаревшие вызовы API : используйте предложенный API-интерфейс замены. Наведите указатель мыши на предупреждение в Android Studio и обратитесь к документации JavaDoc для устаревшего символа, чтобы узнать, что использовать вместо данного вызова.
- Отсортируйте операторы импорта : откройте проект в Android Studio, затем щелкните правой кнопкой мыши на узле папки пакета в окне просмотра проекта и выберите «Оптимизировать импорт для пакетов, содержащих измененные исходные файлы».
Замените MediaSessionConnector на androidx.media3.session.MediaSession
В устаревшей среде MediaSessionCompat за синхронизацию состояния проигрывателя с состоянием сессии и получение команд от контроллеров, которые требовали делегирования соответствующим методам проигрывателя, отвечал MediaSessionConnector . В AndroidX Media3 это делается непосредственно MediaSession без необходимости использования коннектора.
Удалите все ссылки и использование MediaSessionConnector: если вы использовали автоматический скрипт для миграции классов и пакетов ExoPlayer, то, вероятно, скрипт оставил ваш код в некомпилируемом состоянии, связанном с
MediaSessionConnector, которое невозможно разрешить. Android Studio покажет вам неработающий код при попытке сборки или запуска приложения.В файле
build.gradle, где хранятся ваши зависимости, добавьте зависимость реализации к модулю сессии AndroidX Media3 и удалите устаревшую зависимость:implementation "androidx.media3:media3-session:1.9.0"Замените
MediaSessionCompatнаandroidx.media3.session.MediaSession.В том месте кода, где вы создали устаревший класс
MediaSessionCompat, используйтеandroidx.media3.session.MediaSession.Builderдля создания объектаMediaSession. Передайте плеер в конструктор сессии.val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player) .setSessionCallback(MySessionCallback()) .build()Реализуйте
MySessionCallbackв соответствии с требованиями вашего приложения. Это необязательно. Если вы хотите разрешить контроллерам добавлять медиафайлы в плеер, реализуйтеMediaSession.Callback.onAddMediaItems(). Он предоставляет доступ к различным текущим и устаревшим методам API, которые добавляют медиафайлы в плеер для воспроизведения, обеспечивая обратную совместимость. Это включает методыMediaController.set/addMediaItems()контроллера Media3, а также методыTransportControls.prepareFrom*/playFrom*устаревшего API. Пример реализации методаonAddMediaItemsможно найти в классеPlaybackServiceдемонстрационного приложения для работы с сессиями .Освободите медиа-сессию в том месте кода, где вы уничтожили свою сессию перед миграцией:
mediaSession?.run { player.release() release() mediaSession = null }
Функциональность MediaSessionConnector в Media3
В таблице ниже показаны API Media3, которые обрабатывают функциональность, ранее реализованную в MediaSessionConnector .
| MediaSessionConnector | AndroidX Media3 |
|---|---|
CustomActionProvider | MediaSession.Callback.onCustomCommand()/ MediaSession.setMediaButtonPreferences() |
PlaybackPreparer | MediaSession.Callback.onAddMediaItems() (функция prepare() вызывается внутри системы) |
QueueNavigator | ForwardingSimpleBasePlayer |
QueueEditor | MediaSession.Callback.onAddMediaItems() |
RatingCallback | MediaSession.Callback.onSetRating() |
PlayerNotificationManager | DefaultMediaNotificationProvider/ MediaNotification.Provider |
Миграция MediaBrowserService в MediaLibraryService
В AndroidX Media3 представлен MediaLibraryService , заменяющий MediaBrowserServiceCompat . Документация JavaDoc для MediaLibraryService и его суперкласса MediaSessionService дает хорошее представление об API и асинхронной модели программирования сервиса.
Сервис MediaLibraryService обратно совместим с MediaBrowserService . Клиентское приложение, использующее MediaBrowserCompat или MediaControllerCompat , продолжает работать без изменений в коде при подключении к MediaLibraryService . Для клиента не имеет значения, использует ли его приложение MediaLibraryService или устаревший MediaBrowserServiceCompat .

Для обеспечения обратной совместимости необходимо зарегистрировать оба интерфейса службы в файле
AndroidManifest.xml. Таким образом, клиент сможет найти вашу службу по требуемому интерфейсу:<service android:name=".MusicService" android:exported="true"> <intent-filter> <action android:name="androidx.media3.session.MediaLibraryService"/> <action android:name="android.media.browse.MediaBrowserService" /> </intent-filter> </service>В файле
build.gradle, где хранятся ваши зависимости, добавьте зависимость реализации к модулю сессии AndroidX Media3 и удалите устаревшую зависимость:implementation "androidx.media3:media3-session:1.9.0"Измените функциональность вашего сервиса, чтобы он наследовал от
MediaLibraryServiceвместоMediaBrowserServiceКак уже говорилось,MediaLibraryServiceсовместим с устаревшимMediaBrowserService. Соответственно, более широкий API, предлагаемый сервисом клиентам, остается тем же. Поэтому вполне вероятно, что приложение сможет сохранить большую часть логики, необходимой для реализацииMediaBrowserService, и адаптировать ее для новогоMediaLibraryService.Основные отличия от устаревшей версии
MediaBrowserServiceCompatзаключаются в следующем:Реализуйте методы жизненного цикла сервиса: методы, которые необходимо переопределить в самом сервисе, — это
onCreate/onDestroy, где приложение выделяет/освобождает сессию библиотеки, плеер и другие ресурсы. В дополнение к стандартным методам жизненного цикла сервиса, приложению необходимо переопределитьonGetSession(MediaSession.ControllerInfo), чтобы он возвращалMediaLibrarySession, созданный вonCreate.Реализуйте MediaLibraryService.MediaLibrarySessionCallback: для создания сессии требуется объект
MediaLibraryService.MediaLibrarySessionCallback, реализующий методы фактического API домена. Таким образом, вместо переопределения методов API устаревшего сервиса, вы будете переопределять методыMediaLibrarySession.Callback.Затем функция обратного вызова используется для создания объекта
MediaLibrarySession:mediaLibrarySession = MediaLibrarySession.Builder(this, player, MySessionCallback()) .build()Полное описание API класса MediaLibrarySessionCallback можно найти в документации по API.
Реализуйте
MediaSession.Callback.onAddMediaItems(): функция обратного вызоваonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)предоставляет доступ к различным текущим и устаревшим методам API, которые добавляют медиафайлы в плеер для воспроизведения, обеспечивая обратную совместимость. Это включает методыMediaController.set/addMediaItems()контроллера Media3, а также методыTransportControls.prepareFrom*/playFrom*устаревшего API. Пример реализации функции обратного вызова можно найти вPlaybackServiceдемонстрационного приложения сессии .В AndroidX Media3 используется
androidx.media3.common.MediaItemвместо MediaBrowserCompat.MediaItem и MediaMetadataCompat . Части вашего кода, связанные с устаревшими классами, необходимо соответствующим образом изменить или перенаправить на Media3MediaItem.В общей модели асинхронного программирования произошел переход к
Futuresв отличие от подхода с отсоединяемымResultвMediaBrowserServiceCompat. Ваша реализация сервиса может возвращать асинхронныйListenableFutureвместо отсоединения результата или возвращать немедленный Future для прямой передачи значения .
Удалить PlayerNotificationManager
Сервис MediaLibraryService поддерживает автоматическое оповещение о воспроизведении мультимедиа , а PlayerNotificationManager можно удалить при использовании MediaLibraryService или MediaSessionService .
Приложение может настроить уведомление, установив пользовательский MediaNotification.Provider в onCreate() , который заменит DefaultMediaNotificationProvider . Затем MediaLibraryService позаботится о запуске службы в фоновом режиме по мере необходимости.
Переопределив MediaLibraryService.updateNotification() приложение может получить полный контроль над отправкой уведомлений и запуском/остановкой службы в фоновом режиме по мере необходимости.
Перенос клиентского кода с использованием MediaBrowser
В AndroidX Media3 компонент MediaBrowser реализует интерфейсы MediaController/Player и может использоваться для управления воспроизведением мультимедиа, помимо просмотра медиатеки. Если в устаревшей среде вам приходилось создавать MediaBrowserCompat и MediaControllerCompat , то в Media3 вы можете сделать то же самое, используя только MediaBrowser .
Можно создать объект MediaBrowser и ожидать установления соединения со службой:
scope.launch {
val sessionToken =
SessionToken(context, ComponentName(context, MusicService::class.java)
browser =
MediaBrowser.Builder(context, sessionToken))
.setListener(BrowserListener())
.buildAsync()
.await()
// Get the library root to start browsing the library.
root = browser.getLibraryRoot(/* params= */ null).await();
// Add a MediaController.Listener to listen to player state events.
browser.addListener(playerListener)
playerView.setPlayer(browser)
}
Ознакомьтесь с разделом «Управление воспроизведением в сеансе мультимедиа», чтобы узнать, как создать MediaController для управления воспроизведением в фоновом режиме.
Дальнейшие шаги и уборка
Нестабильные ошибки API
После перехода на Media3 вы можете столкнуться с ошибками линтинга, связанными с нестабильным использованием API. Эти API безопасны для использования, а ошибки линтинга являются побочным продуктом наших новых гарантий бинарной совместимости. Если вам не требуется строгая бинарная совместимость, эти ошибки можно безопасно подавить с помощью аннотации @OptIn .
Фон
Ни ExoPlayer v1, ни v2 не предоставляли строгих гарантий бинарной совместимости библиотеки между последующими версиями. API ExoPlayer по своей сути очень обширен, чтобы позволить приложениям настраивать практически каждый аспект воспроизведения. В последующих версиях ExoPlayer иногда происходили переименования символов или другие критические изменения (например, новые обязательные методы в интерфейсах). В большинстве случаев эти проблемы решались путем введения нового символа и одновременного отказа от старого символа на несколько версий, чтобы дать разработчикам время на миграцию использования, но это было не всегда возможно.
Эти критические изменения привели к двум проблемам для пользователей библиотек ExoPlayer v1 и v2:
- Обновление до версии ExoPlayer может привести к тому, что код перестанет компилироваться.
- Приложение, зависящее от ExoPlayer как напрямую, так и через промежуточную библиотеку, должно было гарантировать, что обе зависимости имеют одинаковую версию, иначе несовместимость бинарных файлов могла привести к сбоям во время выполнения.
Улучшения в Media3
Media3 гарантирует бинарную совместимость для части API. Части, для которых бинарная совместимость не гарантируется, помечены аннотацией @UnstableApi . Чтобы это различие было очевидным, использование символов нестабильного API приводит к ошибке линтера, если они не помечены аннотацией @OptIn .
После перехода с ExoPlayer v2 на Media3 вы можете столкнуться с множеством ошибок проверки нестабильности API. Это может создать впечатление, что Media3 «менее стабилен», чем ExoPlayer v2. Это не так. «Нестабильные» части API Media3 обладают тем же уровнем стабильности, что и весь API ExoPlayer v2, и гарантии стабильного API Media3 в ExoPlayer v2 полностью отсутствуют. Разница заключается лишь в том, что теперь ошибка проверки API сообщает вам о разных уровнях стабильности.
Обработка нестабильных ошибок проверки синтаксиса API.
Подробную информацию о том, как аннотировать использование нестабильных API в Java и Kotlin с помощью @OptIn , см. в разделе устранения неполадок, связанных с этими ошибками линтинга.
Устаревшие API
В Android Studio вы можете заметить, что вызовы устаревших API перечеркнуты. Мы рекомендуем заменить такие вызовы соответствующими альтернативами. Наведите курсор на символ, чтобы увидеть документацию JavaDoc, указывающую, какой API следует использовать вместо него.

Примеры кода и демонстрационные приложения
- Демонстрационное приложение AndroidX Media3 для работы с различными устройствами (мобильная версия и WearOS)
- Пользовательские действия
- Уведомление системного интерфейса, MediaButton/BT
- управление воспроизведением Google Ассистента
- UAMP: Android Media Player (ветка media3) (mobile, AutomotiveOS)
- Уведомление системного интерфейса, кнопка MediaButton/BT, возобновление воспроизведения.
- Управление воспроизведением через Google Assistant/WearOS
- AutomotiveOS: пользовательские команды и вход в систему