Как настроить Media3 для аудио/видео и перейти со старого ExoPlayer

Заменять ExoPlayer “на что-то другое” обычно не нужно: ExoPlayer стал частью Jetpack и используется через AndroidX Media3. На практике это означает замену зависимостей и импортов (com.google.android.exoplayer2androidx.media3.*) плюс более правильную схему для фонового воспроизведения.

Оглавление

Что такое AndroidX Media3 и чем он лучше для замены ExoPlayer

AndroidX Media3 — это набор библиотек для проигрывания и управления медиа. Внутри него есть реализация Player на базе ExoPlayer, а также модули для UI и интеграции с системой (шторка, гарнитура, авто, lock screen).

Когда говорят “заменить ExoPlayer”, в 99% случаев речь о переходе на:

  • androidx.media3:media3-exoplayer (движок)
  • androidx.media3:media3-ui (готовый PlayerView)
  • androidx.media3:media3-session (фон, системные контролы)

Быстрый старт: зависимости, PlayerView и запуск воспроизведения

Подключите модули (версию держите одной переменной, чтобы обновлять централизованно):

dependencies {
    implementation "androidx.media3:media3-exoplayer:$media3Version"
    implementation "androidx.media3:media3-ui:$media3Version"
}

Разметка:

<androidx.media3.ui.PlayerView
    android:id="@+id/playerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:show_buffering="when_playing" />

Минимальный Kotlin-код для видео/аудио:

private var player: ExoPlayer? = null

override fun onStart() {
    super.onStart()
    player = ExoPlayer.Builder(this).build().also { exo ->
        findViewById<PlayerView>(R.id.playerView).player = exo
        exo.setMediaItem(MediaItem.fromUri(mediaUrl))
        exo.prepare()
        exo.playWhenReady = true
    }
}

override fun onStop() {
    super.onStop()
    findViewById<PlayerView>(R.id.playerView).player = null
    player?.release()
    player = null
}

Если это аудио без видео, PlayerView не обязателен: вы можете управлять ExoPlayer напрямую и выводить свой UI (кнопки/таймер/прогресс).

Фоновое воспроизведение: MediaSessionService и системные кнопки

Если нужно воспроизведение в фоне (шторка, lock screen, кнопки гарнитуры), хранить плеер в Activity недостаточно. Типовая схема в Media3:

  1. MediaSessionService создаёт ExoPlayer
  2. поверх него создаётся MediaSession
  3. экран управляет через MediaController (подключается к сессии)

Добавьте модуль:

implementation "androidx.media3:media3-session:$media3Version"

Частая ошибка — пытаться “дотянуть” фон через один Activity и не выводить сервис в foreground при воспроизведении. В итоге звук обрывается, а контролов в системе нет или они нестабильны.

Минимальный ориентир по ответственности:

  • Service: живёт дольше UI, держит плеер/очередь/состояние
  • UI: показывает экран и отправляет команды (play/pause/seek/next)

Миграция со старого ExoPlayer: что чаще всего ломается

План миграции без боли:

  1. Замените зависимости com.google.android.exoplayer2:* на androidx.media3:*.
  2. Исправьте импорты и названия классов:
    • SimpleExoPlayerExoPlayer
    • com.google.android.exoplayer2.MediaItemandroidx.media3.common.MediaItem
    • StyledPlayerViewandroidx.media3.ui.PlayerView
  3. Если появились предупреждения про нестабильные API — добавляйте @OptIn(UnstableApi::class) точечно (не “на весь проект” без необходимости).
  4. Отдельным шагом переносите фон и системные контроли на MediaSessionService (если раньше использовали устаревшие связки и менеджеры уведомлений).

Частые ошибки

  • Чёрный экран при видео: не назначили playerView.player, перепутали PlayerView не из androidx.media3.ui, не вызвали prepare().
  • Утечки/двойной звук: не вызываете release() и создаёте новый плеер при каждом повороте/возврате на экран.
  • В фоне всё “умирает”: плеер живёт в UI вместо MediaSessionService, нет корректного перехода в foreground во время проигрывания.
  • После миграции “не найден класс”: это нормально — пакеты переехали, нужно обновить импорты и UI-компоненты.

FAQ

ExoPlayer устарел?
Устарели старые артефакты и пакеты com.google.android.exoplayer2. Сам ExoPlayer продолжает развиваться внутри Media3.

Можно ли оставить старый ExoPlayer и не мигрировать?
Можно, но вы зафиксируете проект на старых зависимостях: будет сложнее получать исправления, новые возможности и совместимость с современными требованиями Android.

Что делать, если нужно “просто проиграть mp3/mp4”?
Подключите media3-exoplayer (+ media3-ui при необходимости) и используйте минимальный пример выше. Фон подключайте только если он реально нужен.