Приложения, которые в настоящее время используют автономную библиотеку 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 Player через компоненты/процессы осуществляется с помощью
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 и плагин Android Studio Gradle до последней версии, работающей с обновлёнными зависимостями, указанными выше. Например:
- Версия плагина 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 выберите Файл > Синхронизировать проект с файлами Gradle , затем Сборка > Очистить проект , а затем Сборка > Пересобрать проект (отслеживайте сборку на вкладке «Сборка — Выходные данные сборки» в 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.8.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.8.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, ни ExoPlayer v2 не предоставляли строгих гарантий двоичной совместимости библиотеки между последующими версиями. API ExoPlayer изначально очень обширен, чтобы приложения могли настраивать практически каждый аспект воспроизведения. В последующих версиях ExoPlayer периодически вносились изменения в символы или другие критические изменения (например, новые обязательные методы в интерфейсах). В большинстве случаев эти проблемы решались путём добавления нового символа и одновременного прекращения поддержки старого в нескольких версиях, что давало разработчикам время на миграцию своих практик, но это было возможно не всегда.
Эти критические изменения привели к двум проблемам для пользователей библиотек ExoPlayer v1 и v2:
- Обновление до версии ExoPlayer может привести к остановке компиляции кода.
- Приложение, которое зависело от ExoPlayer как напрямую, так и через промежуточную библиотеку, должно было гарантировать, что обе зависимости имеют одинаковую версию, в противном случае двоичная несовместимость могла привести к сбоям во время выполнения.
Улучшения в Media3
Media3 гарантирует двоичную совместимость для части API. Части, не гарантирующие двоичную совместимость, отмечены аннотацией @UnstableApi . Чтобы подчеркнуть это различие, использование нестабильных символов API приводит к ошибке lint, если только они не аннотированы аннотацией @OptIn .
После миграции с ExoPlayer v2 на Media3 вы можете столкнуться с множеством ошибок линтинга нестабильного API. Из-за этого может показаться, что Media3 «менее стабилен», чем ExoPlayer v2. Это не так. «Нестабильные» части API Media3 имеют тот же уровень стабильности, что и весь API ExoPlayer v2, а гарантии стабильного API Media3 в ExoPlayer v2 вообще отсутствуют. Разница лишь в том, что ошибка линтинга теперь предупреждает о разных уровнях стабильности.
Обработка нестабильных ошибок API lint
Подробную информацию о том, как аннотировать использование нестабильных API Java и Kotlin с помощью @OptIn , см. в разделе по устранению неполадок, связанных с этими ошибками lint.
Устаревшие API
Вы можете заметить, что вызовы устаревших API в Android Studio зачёркнуты. Мы рекомендуем заменить такие вызовы подходящими альтернативами. Наведите указатель мыши на символ, чтобы увидеть документацию JavaDoc с подсказками о том, какой API следует использовать.

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