Приложения, которые в настоящее время используют автономную библиотеку 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.7.1"
Замените
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.7.1"
Измените свой сервис так, чтобы он наследовался от
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: пользовательские команды и вход в систему