Apps que actualmente usan com.google.android.exoplayer2
independiente
y androidx.media
deberían migrar a androidx.media3
. Usa
la secuencia de comandos de migración para migrar archivos de compilación de Gradle, Java y
Archivos de origen de Kotlin y archivos de diseño XML de ExoPlayer
2.19.1
a AndroidX Media3 1.1.1
.
Descripción general
Antes de realizar la migración, revisa las siguientes secciones para obtener más información sobre los beneficios de las nuevas APIs, las APIs para migrar y los requisitos previos que debe cumplir el proyecto de tu aplicación.
Por qué migrar a Jetpack Media3
- Es la nueva página principal de ExoPlayer, mientras que
com.google.android.exoplayer2
es descontinuados. - Accede a la API del reproductor en todos los componentes y procesos con
MediaBrowser
/MediaController
- Utiliza las capacidades extendidas de
MediaSession
y API deMediaController
. - Anuncia las capacidades de reproducción con el control de acceso detallado.
- Simplifica tu app quitando
MediaSessionConnector
yPlayerNotificationManager
- Son retrocompatibles con las APIs cliente de media-compat.
(
MediaBrowserCompat
/MediaControllerCompat
/MediaMetadataCompat
)
APIs de contenido multimedia para migrar a AndroidX Media3
- ExoPlayer y sus extensiones
Esto incluye todos los módulos del proyecto ExoPlayer heredado, excepto los módulo mediasession que está descontinuado. Las apps o los módulos que dependen de paquetes decom.google.android.exoplayer2
se pueden migrar con el secuencia de comandos de migración. - MediaSessionConnector (según la
androidx.media.*
paquetes deandroidx.media:media:1.4.3+
)
Quita laMediaSessionConnector
y usa laandroidx.media3.session.MediaSession
en su lugar. - MediaBrowserServiceCompat (según la
androidx.media.*
paquetes deandroidx.media:media:1.4.3+
)
Migra las subclases deandroidx.media.MediaBrowserServiceCompat
aandroidx.media3.session.MediaLibraryService
y el código que usaMediaBrowserCompat.MediaItem
aandroidx.media3.common.MediaItem
. - MediaBrowserCompat (según la clase
android.support.v4.media.*
paquetes deandroidx.media:media:1.4.3+
)
Migra el código de cliente con el métodoMediaBrowserCompat
MediaControllerCompat
para usarandroidx.media3.session.MediaBrowser
conandroidx.media3.common.MediaItem
.
Requisitos previos
Asegúrate de que tu proyecto esté bajo el control del código fuente
Asegúrate de poder revertir con facilidad los cambios aplicados por las herramientas de migración con secuencia de comandos. Si aún no tienes el proyecto bajo control del código fuente, ahora es un buen momento para comenzar. Si por alguna razón no quieres hacerlo, crea un copia de seguridad de tu proyecto antes de comenzar la migración.
Actualiza tu app
Te recomendamos actualizar tu proyecto para usar la versión más reciente de la biblioteca de ExoPlayer y quita llamadas a métodos obsoletos. Si tienes la intención de utilizar la secuencia de comandos para la migración, debes hacer coincidir el a la que estás actualizando con la versión controlada por la secuencia de comandos.
Aumenta la compileSdkVersion de tu app a, al menos, 32.
Actualiza Gradle y el complemento de Gradle para Android Studio a una versión reciente que funcione con las dependencias actualizadas. Para instancia:
- Versión del complemento de Android para Gradle: 7.1.0
- Versión de Gradle: 7.4
Reemplaza todas las sentencias de importación de comodines que usan un asterisco (*) y usar sentencias de importación completamente calificadas: borrar el comodín de configuración y usar Android Studio para importar apps (F2: Alt/Intro, F2: Alt/Intro, ...).
Migra de
com.google.android.exoplayer2.PlayerView
acom.google.android.exoplayer2.StyledPlayerView
Esto es necesario porque no hay equivalente acom.google.android.exoplayer2.PlayerView
en AndroidX Media3.
Cómo migrar ExoPlayer con compatibilidad para secuencias de comandos
La secuencia de comandos facilita el paso de com.google.android.exoplayer2
a la nueva
estructura del paquete y del módulo en androidx.media3
. La secuencia de comandos se aplica
algunas comprobaciones de validación en tu proyecto e imprime advertencias si falla la validación.
De lo contrario, aplica las asignaciones de clases y paquetes con nombres nuevos en la
recursos de un proyecto de Gradle para Android escritos en Java o 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
Usa la secuencia de comandos de migración
Descarga la secuencia de comandos de migración de la etiqueta del proyecto de ExoPlayer en GitHub correspondiente a la versión a la que actualizaste tu app:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
Haz que la secuencia de comandos sea ejecutable:
chmod 744 media3-migration.sh
Ejecuta la secuencia de comandos con
--help
para conocer las opciones.Ejecuta la secuencia de comandos con
-l
para enumerar el conjunto de archivos seleccionados. Migración (usa-f
para forzar la ficha sin advertencias):./media3-migration.sh -l -f /path/to/gradle/project/root
Ejecuta la secuencia de comandos con
-m
para asignar paquetes, clases y módulos a Media3. Si ejecutas la secuencia de comandos con la opción-m
, se aplicarán los cambios en la secuencia seleccionada archivos.- Detener el error de validación sin realizar cambios
./media3-migration.sh -m /path/to/gradle/project/root
- Ejecución forzada
Si la secuencia de comandos encuentra un incumplimiento de los requisitos previos, se puede forzado con la marca
-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
Completa estos pasos manuales después de ejecutar la secuencia de comandos con la opción -m
:
- Comprueba cómo la secuencia de comandos cambió tu código: Usa una herramienta de diferencias y corrige el problema.
problemas potenciales (considera informar un error si crees que la secuencia de comandos tiene
un problema general que se introdujo sin pasar la opción
-f
). - Compila el proyecto: Usa
./gradlew clean build
o en Android. Selecciona File > Sync Project with Gradle Files, luego Build > Limpiar proyecto y, luego, Compilar > Vuelve a compilar el proyecto (supervisa tu compilación en la “Compilación: Resultado de la compilación” de Android Studio.
Pasos de seguimiento recomendados:
- Resolver la aceptación de errores relacionados con el uso de APIs inestables
- Reemplazar las llamadas a la API obsoletas: Usa la API de reemplazo sugerida. Mantén el puntero sobre la advertencia en Android Studio y consulta el JavaDoc del símbolo obsoleto para averiguar qué usar en lugar de una llamada determinada.
- Ordena las sentencias de importación: Abre el proyecto en Android Studio y, luego, haz clic con el botón derecho en un nodo de la carpeta del paquete en el visor de proyectos y elige Optimiza las importaciones en los paquetes que contienen los archivos fuente modificados.
Reemplaza MediaSessionConnector
con androidx.media3.session.MediaSession
.
En el mundo heredado de MediaSessionCompat
, la MediaSessionConnector
era
Es responsable de sincronizar el estado del reproductor con el estado de la sesión.
y recibir comandos de controladores que necesitaban delegación para los
los métodos del reproductor. Con AndroidX Media3, MediaSession
lo hace directamente
sin requerir un conector.
Quita todas las referencias y el uso de MediaSessionConnector: Si usaste la secuencia de comandos automatizada para migrar clases y paquetes de ExoPlayer, y luego secuencia de comandos haya dejado a tu código en un estado no compilable relacionado con la
MediaSessionConnector
que no se puede resolver. Android Studio hará lo siguiente: te mostrará el código dañado cuando intentas compilar o iniciar la app.En el archivo
build.gradle
en el que mantienes tus dependencias, agrega una implementación de la dependencia al módulo de sesión de AndroidX Media3 y quita la dependencia heredada:implementation "androidx.media3:media3-session:1.4.0"
Reemplaza
MediaSessionCompat
porandroidx.media3.session.MediaSession
En el sitio de código donde creaste el
MediaSessionCompat
heredado, usaandroidx.media3.session.MediaSession.Builder
para crear unMediaSession
Pasa el jugador para construir el compilador de sesiones.val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player) .setSessionCallback(MySessionCallback()) .build()
Implementa
MySessionCallback
según lo requiera tu app. Esto es opcional. Si para permitir que los controladores agreguen elementos multimedia al reproductor, implementaMediaSession.Callback.onAddMediaItems()
Sirve para varios servicios actuales y actuales métodos de API heredados que agregan elementos multimedia al reproductor para reproducirlos en una retrocompatible. Esto incluye lasMediaController.set/addMediaItems()
del controlador de Media3, como así como laTransportControls.prepareFrom*/playFrom*
de la API heredada. Una implementación de muestra deonAddMediaItems
puede se encuentra en laPlaybackService
de la app de demostración de la sesión.Libera la sesión multimedia en el sitio del código donde destruiste tu sesión antes de la migración.
mediaSession?.run { player.release() release() mediaSession = null }
Funcionalidad MediaSessionConnector
en Media3
En la siguiente tabla, se muestran las APIs de Media3 que controlan la funcionalidad
implementado previamente en MediaSessionConnector
.
MediaSessionConnector | AndroidX Media3 |
---|---|
CustomActionProvider |
MediaSession.Callback.onCustomCommand()/
MediaSession.setCustomLayout() |
PlaybackPreparer |
MediaSession.Callback.onAddMediaItems()
(Se llama a prepare() de forma interna).
|
QueueNavigator |
ForwardingPlayer |
QueueEditor |
MediaSession.Callback.onAddMediaItems() |
RatingCallback |
MediaSession.Callback.onSetRating() |
PlayerNotificationManager |
DefaultMediaNotificationProvider/
MediaNotification.Provider |
Migra MediaBrowserService
a MediaLibraryService
AndroidX Media3 presenta MediaLibraryService
, que reemplaza la
MediaBrowserServiceCompat
El JavaDoc de MediaLibraryService
y su super
la clase MediaSessionService
proporcionan una buena introducción a la API y al
de programación asíncrono del servicio.
MediaLibraryService
es retrocompatible con
MediaBrowserService
Una app cliente que usa MediaBrowserCompat
o
MediaControllerCompat
, continúa funcionando sin cambios de código cuando se conecta
a un MediaLibraryService
. Para un cliente, es transparente si tu app está
con un objeto MediaLibraryService
o un MediaBrowserServiceCompat
heredado.
![Diagrama de componentes de la app con el servicio, la actividad y las apps externas.](https://developer.android.google.cn/static/media/images/overview.png?authuser=19&hl=es)
Para que la retrocompatibilidad funcione, debes registrar ambos servicios interfaces con tu servicio en
AndroidManifest.xml
. De esta manera, cliente encuentra tu servicio mediante la interfaz de servicio requerida:<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>
En el archivo
build.gradle
en el que mantienes tus dependencias, agrega una la dependencia de implementación al módulo de sesión de AndroidX Media3 y quita la dependencia heredada:implementation "androidx.media3:media3-session:1.4.0"
Cambia tu servicio para que herede de un
MediaLibraryService
en lugar deMediaBrowserService
Como se mencionó anteriormente,MediaLibraryService
es compatible con la versión heredada.MediaBrowserService
Por lo tanto, a la API más amplia con la que se a los clientes sigue siendo la misma. Por lo tanto, es probable que una aplicación pueda mantener la mayor parte de la lógica que se requiere para implementarMediaBrowserService
y adáptala para el nuevoMediaLibraryService
.Las principales diferencias en comparación con la versión heredada
MediaBrowserServiceCompat
son las siguientes:Implementar los métodos de ciclo de vida del servicio: Son los métodos que deben anulada en el servicio son
onCreate/onDestroy
, en las que un La app asigna o lanza la sesión de la biblioteca, el reproductor y otras de Google Cloud. Además de los métodos de ciclo de vida de servicio estándar, una app debe anularonGetSession(MediaSession.ControllerInfo)
para que se muestre elMediaLibrarySession
que se compiló enonCreate
.Implementa MediaLibraryService.MediaLibrarySessionCallback: compilación una sesión requiere
MediaLibraryService.MediaLibrarySessionCallback
que implementa los métodos de API del dominio real. En lugar de anular los métodos de la API del servicio heredado, anularás los métodos delMediaLibrarySession.Callback
en su lugar.Luego, se usa la devolución de llamada para compilar el
MediaLibrarySession
:mediaLibrarySession = MediaLibrarySession.Builder(this, player, MySessionCallback()) .build()
Encuentra la API completa de MediaLibrarySessionCallback en la API. en la documentación de Google Cloud.
Implementa
MediaSession.Callback.onAddMediaItems()
: La devolución de llamadaonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)
porción varios métodos actuales y heredados de la API que agregan elementos multimedia al reproductor para la reproducción de una manera compatible con versiones anteriores. Esto incluye las métodosMediaController.set/addMediaItems()
del controlador de Media3 así como laTransportControls.prepareFrom*/playFrom*
de la API heredada. Un ejemplo de implementación de la devolución de llamada se encuentra en elPlaybackService
de la app de demostración de la sesión.En su lugar, AndroidX Media3 usa
androidx.media3.common.MediaItem
. de MediaBrowserCompat.MediaItem y MediaMetadataCompat. Piezas de tu código vinculado a las clases heredadas, debes cambiar lo que corresponda o asignarla aMediaItem
de Media3.El modelo de programación asíncrona general cambió a
Futures
en contrastan con el enfoque deResult
desmontable delMediaBrowserServiceCompat
Tu implementación del servicio puede mostrar unListenableFuture
asíncrono en lugar de desvincular un resultado o muestra un Future inmediato para mostrar directamente un valor.
Quitar PlayerNotificationManager
El MediaLibraryService
admite notificaciones multimedia automáticamente y el
Se puede quitar PlayerNotificationManager
cuando se usa un MediaLibraryService
o
MediaSessionService
La app puede personalizar la notificación estableciendo una
MediaNotification.Provider
en onCreate()
que reemplaza al
DefaultMediaNotificationProvider
Luego, MediaLibraryService
se encarga de
iniciar el servicio en primer plano según sea necesario.
Cuando se anula MediaLibraryService.updateNotification()
, una app puede tardar más
propiedad absoluta de la publicación de una notificación e iniciar/detener el servicio en
en primer plano según sea necesario.
Cómo migrar el código del cliente con un MediaBrowser
Con AndroidX Media3, un MediaBrowser
implementa MediaController/Player
y se pueden usar para controlar la reproducción de contenido multimedia, además de explorar
biblioteca. Si tuvieras que crear un MediaBrowserCompat
y un
MediaControllerCompat
en el mundo heredado, puedes hacer lo mismo usando solo
el MediaBrowser
en Media3.
Se puede compilar un MediaBrowser
y esperar la conexión al
servicio que se está estableciendo:
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)
}
Echa un vistazo a
Cómo controlar la reproducción en la sesión multimedia
Aprende a crear un objeto MediaController
para controlar la reproducción en la
en segundo plano.
Pasos adicionales y limpieza
Errores de API inestables
Después de migrar a Media3, es posible que veas errores de lint sobre usos inestables de la API.
Estas APIs son seguras de usar y los errores de lint son un subproducto de nuestra nueva
y garantías de compatibilidad binaria. Si no necesitas objetos binarios estrictos
compatibilidad, estos errores se pueden suprimir de forma segura con un @OptIn
.
Información general
Ni ExoPlayer v1 ni v2 proporcionaron garantías estrictas sobre la compatibilidad con objetos binarios. de la biblioteca entre versiones posteriores. La superficie de la API de ExoPlayer es muy son grandes por diseño, para permitir que las apps personalicen casi todos los aspectos de reproducción. En las versiones posteriores de ExoPlayer, en ocasiones, se ingresarían símbolos cambios de nombre y otros cambios rotundos (p.ej., nuevos métodos requeridos en las interfaces). En En la mayoría de los casos, estas fallas se mitigaron mediante la incorporación del nuevo símbolo. además de dar de baja el símbolo anterior para algunas versiones, para que los desarrolladores para migrar sus usos, pero no siempre fue posible.
Estos cambios rotundos generaron dos problemas para los usuarios de ExoPlayer v1. y bibliotecas v2:
- Una actualización a la versión de ExoPlayer podría hacer que el código deje de compilarse.
- Una app que dependía de ExoPlayer de forma directa y a través de un elemento intermedio tuvo que asegurarse de que ambas dependencias fueran la misma versión, De lo contrario, las incompatibilidades binarias podrían provocar fallas en el tiempo de ejecución.
Mejoras en Media3
Media3 garantiza la compatibilidad binaria para un subconjunto de la plataforma de la API. El
las partes que no garantizan la compatibilidad binaria se marcan con
@UnstableApi
Para dejar en claro esta distinción, los usos de
Los símbolos de API generan un error de lint, a menos que tengan anotaciones con @OptIn
.
Después de migrar de ExoPlayer v2 a Media3, es posible que veas mucha API inestable errores de lint. Esto puede hacer que parezca que Media3 es “menos estable”. que ExoPlayer versión 2. Este no es el caso. La situación "inestable" de la API de Media3 tienen la misma nivel de estabilidad completa de la superficie de la API de ExoPlayer v2 y el garantías de la superficie estable de la API de Media3 no están disponibles en ExoPlayer v2 en todos. La diferencia es que un error de lint ahora te alerta sobre los diferentes niveles de estabilidad.
Cómo controlar errores inestables de lint de API
Para obtener información sobre cómo hacerlo, consulta la sección de solución de problemas de estos errores de lint.
anotar los usos de Java y Kotlin de APIs inestables con @OptIn
APIs obsoletas
Quizás notes que las llamadas a las APIs obsoletas están tachadas en Android a Looker Studio. Te recomendamos reemplazar esas llamadas por la alternativa adecuada. Coloca el cursor sobre el símbolo para ver el JavaDoc que indica qué API usar en su lugar.
![Captura de pantalla: Cómo mostrar JavaDoc con una alternativa al método obsoleto](https://developer.android.google.cn/static/media/media3/exoplayer/images/deprecation.png?authuser=19&hl=es)
Muestras de código y apps de demostración
- App de demostración de la sesión de AndroidX Media3 (para dispositivos móviles y Wear OS)
- Acciones personalizadas
- Notificación de IU del sistema, MediaButton/BT
- Control de reproducción de Asistente de Google
- UAMP: Android Media Player (rama media3) (dispositivos móviles y AutomotiveOS)
- Notificación de la IU del sistema, MediaButton/BT, reanudación de la reproducción
- Control de reproducción de Asistente de Google y Wear OS
- AutomotiveOS: Comando y acceso personalizados