Guide de migration AndroidX Media3

Applications qui utilisent actuellement la version autonome de com.google.android.exoplayer2 bibliothèque et androidx.media doivent migrer vers androidx.media3. Utilisez le script de migration permettant de migrer les fichiers de compilation Gradle, Java et Fichiers sources Kotlin et fichiers de mise en page XML d'ExoPlayer 2.19.1 vers AndroidX Media3 1.1.1.

Présentation

Avant d'effectuer la migration, consultez les sections suivantes pour en savoir plus sur les avantages des nouvelles API et les API à migrer, ainsi que les prérequis que le projet de votre application doit satisfaire.

Pourquoi migrer vers Jetpack Media3

  • Il s'agit du nouvel environnement d'ExoPlayer, tandis que com.google.android.exoplayer2 fin de journée.
  • Accédez à l'API Player pour l'ensemble des composants/processus avec MediaBrowser/MediaController.
  • Utilisez les fonctionnalités étendues de MediaSession et MediaController.
  • Annoncez les fonctionnalités de lecture avec un contrôle des accès précis.
  • Simplifiez votre application en supprimant les MediaSessionConnector et PlayerNotificationManager
  • Rétrocompatibilité avec les API clientes de compatibilité multimédia (MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)

API multimédias pour migrer vers AndroidX Media3

  • ExoPlayer et ses extensions
    Cela inclut tous les modules de l'ancien projet ExoPlayer, à l'exception du Le module mediasession a été arrêté. Applications ou modules en fonction les packages dans com.google.android.exoplayer2 peuvent être migrés avec script de migration.
  • MediaSessionConnector (selon le androidx.media.* packages de androidx.media:media:1.4.3+)
    Supprimez le MediaSessionConnector et utilisez la androidx.media3.session.MediaSession à la place.
  • MediaBrowserServiceCompat (selon le androidx.media.* packages de androidx.media:media:1.4.3+)
    Migrer les sous-classes de androidx.media.MediaBrowserServiceCompat vers androidx.media3.session.MediaLibraryService et le code en utilisant Du MediaBrowserCompat.MediaItem au androidx.media3.common.MediaItem.
  • MediaBrowserCompat (selon le android.support.v4.media.* packages de androidx.media:media:1.4.3+)
    Migrez le code client à l'aide des commandes MediaBrowserCompat ou MediaControllerCompat pour utiliser la androidx.media3.session.MediaBrowser avec androidx.media3.common.MediaItem.

Prérequis

  1. S'assurer que votre projet est soumis au contrôle du code source

    Assurez-vous de pouvoir facilement annuler les modifications appliquées par les outils de migration à l'aide de scripts. Si votre projet n'est pas encore sous contrôle des sources, c'est le bon moment pour commencer. Si, pour une raison quelconque, vous ne voulez pas le faire, une copie de sauvegarde de votre projet avant de lancer la migration.

  2. Mettre à jour votre application

    • Nous vous recommandons de mettre à jour votre projet afin d'utiliser version la plus récente de la bibliothèque ExoPlayer et supprimez les à des méthodes obsolètes. Si vous avez l'intention de utilisez le script pour la migration, vous devez faire correspondre les la version vers laquelle vous effectuez la mise à jour avec la version gérée par le script.

    • Augmentez la valeur de compileSdkVersion de votre application à au moins 32.

    • Mettez à niveau Gradle et le plug-in Android Studio Gradle vers une version récente. qui fonctionne avec les dépendances mises à jour ci-dessus. Pour instance:

      • Version du plug-in Android Gradle: 7.1.0
      • Version de Gradle: 7.4
    • Remplacer toutes les instructions d'importation avec des caractères génériques qui utilisent un astérisque (*) et utiliser des instructions d'importation complètes: supprimez le caractère générique les instructions d'importation et utilisez Android Studio pour importer les (F2 - Alt/Entrée, F2 - Alt/Entrée, ...).

    • Migrer de com.google.android.exoplayer2.PlayerView vers com.google.android.exoplayer2.StyledPlayerView C'est nécessaire car il n'existe pas d'équivalent com.google.android.exoplayer2.PlayerView dans AndroidX Media3.

Migrer ExoPlayer avec prise en charge des scripts

Le script facilite le passage de com.google.android.exoplayer2 au nouveau des packages et des modules sous androidx.media3. Le script s'applique des contrôles de validation sur votre projet et affiche des avertissements en cas d'échec de la validation. Sinon, il applique les mappages de classes et de packages renommés dans le les ressources d'un projet Gradle Android écrit en Java ou 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

Utiliser le script de migration

  1. Téléchargez le script de migration à partir du tag du projet ExoPlayer sur GitHub correspondant à la version vers laquelle vous avez mis à jour votre application:

    curl -o media3-migration.sh \
      "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
    
  2. Rendez le script exécutable:

    chmod 744 media3-migration.sh
    
  3. Exécutez le script avec --help pour en savoir plus sur les options.

  4. Exécutez le script avec -l afin de lister l'ensemble des fichiers sélectionnés pour Migration (utilisez -f pour forcer l'affichage de la liste sans avertissement):

    ./media3-migration.sh -l -f /path/to/gradle/project/root
    
  5. Exécutez le script avec -m pour mapper les packages, les classes et les modules à Media3. Exécuter le script avec l'option -m appliquera les modifications à la partie sélectionnée .

    • Arrêter à l'erreur de validation sans apporter de modifications
    ./media3-migration.sh -m /path/to/gradle/project/root
    
    • Exécution forcée

    Si le script détecte un cas de non-respect des conditions préalables, la migration peut être forcé avec l'indicateur -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

Effectuez ces étapes manuelles après avoir exécuté le script avec l'option -m:

  1. Vérifiez comment le script a modifié votre code: utilisez un outil de vérification des différences et corrigez le problème. les problèmes potentiels (vous pouvez signaler un bug si vous pensez que le script a un problème général qui a été introduit sans transmettre l'option -f).
  2. Compilez le projet: utilisez ./gradlew clean build ou Android. Sélectionnez Fichier > Synchroniser le projet avec les fichiers Gradle, puis Build > Clean project (Nettoyer le projet), puis Build > Recompilez le projet (surveillez votre compilation dans le 'Build - Build Output' (Compilation - Sortie de compilation) d'Android Studio.

Étapes de suivi recommandées:

  1. Résolvez les erreurs d'activation concernant l'utilisation d'API instables.
  2. Remplacer les appels d'API obsolètes: utilisez l'API de remplacement suggérée. Pointez sur l'avertissement dans Android Studio et consultez le JavaDoc du symbole obsolète pour savoir quoi utiliser à la place d'un appel donné.
  3. Trier les instructions d'importation: ouvrez le projet dans Android Studio, puis faites un clic droit sur un nœud de dossier de package dans la visionneuse de projet et choisissez Optimisez les importations sur les packages contenant les fichiers sources modifiés.

Remplacez MediaSessionConnector par androidx.media3.session.MediaSession.

Dans l'ancien monde de MediaSessionCompat, MediaSessionConnector était qui synchronise l'état du lecteur avec l'état de la session. et la réception des commandes des contrôleurs nécessitant la délégation aux méthodes de lecteur. Avec AndroidX Media3, cette opération est effectuée directement par MediaSession. sans avoir besoin d'un connecteur.

  1. Remove all reference and usage of MediaSessionConnector (Supprimer toutes les références et l'utilisation de MediaSessionConnector) : le script automatisé pour migrer les classes et les packages ExoPlayer, puis le a probablement laissé votre code dans un état incompilable concernant MediaSessionConnector qui ne peut pas être résolu. Android Studio va afficher le code défaillant lorsque vous essayez de compiler ou de démarrer l'application.

  2. Dans le fichier build.gradle où vous gérez vos dépendances, ajoutez une la dépendance d'implémentation au module de session AndroidX Media3 et à supprimer l'ancienne dépendance:

    implementation "androidx.media3:media3-session:1.4.1"
    
  3. Remplacez MediaSessionCompat par androidx.media3.session.MediaSession

  4. Sur le site de code où vous avez créé l'ancienne MediaSessionCompat, utilisez : androidx.media3.session.MediaSession.Builder pour créer un MediaSession Transmettez le joueur pour construire le générateur de session.

    val player = ExoPlayer.Builder(context).build()
    mediaSession = MediaSession.Builder(context, player)
        .setSessionCallback(MySessionCallback())
        .build()
    
  5. Implémentez MySessionCallback selon les exigences de votre application. Cette étape est facultative. Si que vous souhaitez autoriser les manettes à ajouter des éléments multimédias au lecteur, MediaSession.Callback.onAddMediaItems() Il sert diverses applications actuelles et d'anciennes méthodes d'API qui permettent d'ajouter des éléments multimédias au lecteur pour une lecture dans un rétrocompatible. Cela inclut les MediaController.set/addMediaItems() de la manette Media3, comme ainsi que TransportControls.prepareFrom*/playFrom* de l'ancienne API. Un exemple d'implémentation de onAddMediaItems peut se trouve dans le PlaybackService de l'application de démonstration de la session.

  6. Libérez la session multimédia sur le site de code où vous avez détruit votre session avant la migration:

    mediaSession?.run {
      player.release()
      release()
      mediaSession = null
    }
    

Fonctionnalité MediaSessionConnector dans Media3

Le tableau suivant présente les API Media3 qui gèrent les fonctionnalités précédemment implémentée dans MediaSessionConnector.

MediaSessionConnectorAndroidX Media3
CustomActionProvider MediaSession.Callback.onCustomCommand()/ MediaSession.setCustomLayout()
PlaybackPreparer MediaSession.Callback.onAddMediaItems() (prepare() est appelé en interne)
QueueNavigator ForwardingPlayer
QueueEditor MediaSession.Callback.onAddMediaItems()
RatingCallback MediaSession.Callback.onSetRating()
PlayerNotificationManager DefaultMediaNotificationProvider/ MediaNotification.Provider

Migrer MediaBrowserService vers MediaLibraryService

AndroidX Media3 introduit MediaLibraryService, qui remplace MediaBrowserServiceCompat Le JavaDoc de MediaLibraryService et ses super MediaSessionService constituent une bonne introduction à l'API. de programmation asynchrone du service.

Le MediaLibraryService est rétrocompatible avec le MediaBrowserService Une application cliente qui utilise MediaBrowserCompat ou MediaControllerCompat continue de fonctionner sans modification du code lors de la connexion. en MediaLibraryService. Pour un client, il est clair que votre application est à l'aide d'un MediaLibraryService ou d'un ancien MediaBrowserServiceCompat.

<ph type="x-smartling-placeholder">
</ph> Schéma des composants d&#39;application avec le service, l&#39;activité et les applications externes.
Figure 1: Présentation du composant d'application multimédia
    .
  1. Pour que la rétrocompatibilité fonctionne, vous devez enregistrer les deux services interfaces avec votre service dans le AndroidManifest.xml. De cette façon, client trouve votre service via l'interface de service requise:

    <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>
    
  2. Dans le fichier build.gradle où vous gérez vos dépendances, ajoutez une la dépendance d'implémentation au module de session AndroidX Media3 et Supprimez l'ancienne dépendance:

    implementation "androidx.media3:media3-session:1.4.1"
    
  3. Modifiez votre service pour qu'il hérite d'un MediaLibraryService au lieu de MediaBrowserService Comme indiqué précédemment, MediaLibraryService est compatible avec l'ancienne version MediaBrowserService Par conséquent, l'API dans laquelle le service est offre aux clients est toujours la même. Il est donc probable qu'une application la plupart de la logique requise pour implémenter MediaBrowserService. et de l'adapter au nouveau MediaLibraryService.

    Les principales différences par rapport à l'ancienne version Les MediaBrowserServiceCompat sont les suivantes:

    • Implémentez les méthodes du cycle de vie du service:les méthodes qui doivent sur le service lui-même sont onCreate/onDestroy, où alloue/libère la session de bibliothèque, le lecteur ressources. En plus des méthodes standards liées au cycle de vie des services, une application doit ignorer onGetSession(MediaSession.ControllerInfo) pour renvoyer le MediaLibrarySession créé dans onCreate.

    • Implement MediaLibraryService.MediaLibrarySessionCallback: bâtiment une session nécessite MediaLibraryService.MediaLibrarySessionCallback qui implémente les méthodes d'API du domaine. Au lieu de remplacer les méthodes API de l'ancien service, vous remplacerez les méthodes MediaLibrarySession.Callback à la place.

      Le rappel est ensuite utilisé pour créer MediaLibrarySession:

      mediaLibrarySession =
            MediaLibrarySession.Builder(this, player, MySessionCallback())
               .build()
      

      Rechercher l'API complète de MediaLibrarySessionCallback dans l'API dans la documentation Google Cloud.

    • Implémentation de MediaSession.Callback.onAddMediaItems(): le rappel onAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>) services Diverses méthodes d'API actuelles et anciennes qui ajoutent des éléments multimédias au lecteur pour une lecture rétrocompatible. Cela inclut les Méthodes MediaController.set/addMediaItems() de la manette Media3 ainsi que TransportControls.prepareFrom*/playFrom* de l'ancienne API. Un exemple d'implémentation du rappel peut se trouve dans le PlaybackService de l'application de démonstration de session.

    • AndroidX Media3 utilise androidx.media3.common.MediaItem à la place de MediaBrowserCompat.MediaItem et MediaMetadataCompat. Pièces de votre code lié aux anciennes classes doivent être modifiés en conséquence ou mapper vers le MediaItem Media3 à la place.

    • Le modèle de programmation asynchrone général est passé à Futures dans contraste avec l'approche Result détachable du MediaBrowserServiceCompat L'implémentation de votre service peut renvoyer une des ListenableFuture asynchrones au lieu de dissocier un résultat ou renvoie un objet Future immédiat pour renvoyer directement une valeur.

Suppression de PlayerNotificationManager

Le MediaLibraryService prend automatiquement en charge les notifications multimédias et la PlayerNotificationManager peut être supprimé lorsque vous utilisez un MediaLibraryService ou MediaSessionService

Une application peut personnaliser la notification en définissant MediaNotification.Provider dans onCreate() qui remplace DefaultMediaNotificationProvider MediaLibraryService s'occupe ensuite de en démarrant le service au premier plan si nécessaire.

En remplaçant MediaLibraryService.updateNotification(), une application peut prendre la publication de la notification et le démarrage/l'arrêt du service dans le premier plan selon les besoins.

Migrer le code client à l'aide d'un MediaBrowser

Avec AndroidX Media3, un MediaBrowser implémente MediaController/Player. et peuvent être utilisées pour contrôler la lecture des contenus multimédias, en plus de la navigation dans les bibliothèque. Si vous avez dû créer un MediaBrowserCompat et un MediaControllerCompat dans l'ancien système, vous pouvez le faire en n'utilisant MediaBrowser dans Media3.

Un MediaBrowser peut être créé et attendre la connexion à service en cours d'établissement:

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)
}

Jetez un coup d'œil à Contrôler la lecture dans la session multimédia pour découvrir comment créer un MediaController permettant de contrôler la lecture dans en arrière-plan.

Étapes supplémentaires et nettoyage

Erreurs d'API instables

Après la migration vers Media3, vous verrez peut-être des erreurs lint concernant des utilisations d'API instables. Ces API peuvent être utilisées sans risque, et les erreurs lint sont le résultat de notre nouvelle de compatibilité binaire. Si vous n'avez pas besoin d'un binaire strict la compatibilité, vous pouvez supprimer ces erreurs en toute sécurité à l'aide d'un @OptIn .

Arrière-plan

Ni ExoPlayer v1 ni version 2 n'offre de garanties strictes concernant la compatibilité binaire de la bibliothèque entre les versions ultérieures. La surface de l'API ExoPlayer de grande taille, pour permettre aux applications de personnaliser presque tous les aspects lecture. Les versions ultérieures d'ExoPlayer introduisent parfois des symboles renommages ou autres modifications destructives (par exemple, nouvelles méthodes requises sur les interfaces). Dans la plupart des cas, ces défaillances ont été atténuées par l'introduction du nouveau symbole et l'abandon de l'ancien symbole pour quelques versions, pour permettre aux développeurs le temps de migrer leurs utilisations, mais cela n'était pas toujours possible.

Ces modifications destructives ont entraîné deux problèmes pour les utilisateurs d'ExoPlayer v1. et v2:

  1. Une mise à niveau vers la version d'ExoPlayer peut entraîner l'arrêt de la compilation du code.
  2. Application qui dépendait d'ExoPlayer directement et via un outil intermédiaire devait s'assurer que les deux dépendances étaient la même version, sinon des incompatibilités binaires pourraient entraîner des plantages de l'exécution.

Améliorations dans Media3

Media3 garantit la compatibilité binaire pour un sous-ensemble de la surface de l'API. La les parties qui ne garantissent pas la compatibilité binaire sont marquées avec @UnstableApi Pour que cette distinction soit claire, les utilisations de fichiers instables Les symboles d'API génèrent une erreur lint, sauf s'ils sont annotés avec @OptIn.

Après avoir migré d'ExoPlayer v2 vers Media3, vous verrez peut-être de nombreuses API instables les erreurs lint. Media3 peut donc sembler "moins stable" qu'ExoPlayer version 2. Ce n'est pas le cas. L'état "unstable" de l'API Media3 ont le même rôle le niveau de stabilité de l'ensemble de la surface de l'API ExoPlayer v2 ; les garanties de stabilité de la surface d'API Media3 ne sont pas disponibles dans ExoPlayer v2 à l'adresse tout. La différence est simplement qu'une erreur lint vous alerte désormais différents niveaux de stabilité.

Gérer les erreurs lint de l'API instable

Consultez la section de dépannage sur ces erreurs lint pour savoir comment annoter les utilisations Java et Kotlin des API instables avec @OptIn.

API obsolètes

Vous remarquerez peut-être que les appels à des API obsolètes sont barrés dans Android. dans Google Marketing Platform Studio. Nous vous recommandons de remplacer ces appels par une autre méthode appropriée. Passez la souris sur le symbole pour afficher le document JavaDoc qui indique l'API à utiliser à la place.

<ph type="x-smartling-placeholder">
</ph> Capture d&#39;écran: Afficher JavaDoc avec une alternative à la méthode obsolète
Figure 3: L'info-bulle JavaDoc dans Android Studio suggère une alternative à tout symbole obsolète.

Exemples de code et applications de démonstration

  • Application de démonstration de la session AndroidX Media3 (mobile et Wear OS) <ph type="x-smartling-placeholder">
      </ph>
    • Actions personnalisées
    • Notification de l'interface utilisateur système, MediaButton/BT
    • Commande de lecture de l'Assistant Google
  • UAMP: Android Media Player (branch media3) (mobile, AutomotiveOS) <ph type="x-smartling-placeholder">
      </ph>
    • Notification de l'interface utilisateur système, MediaButton/BT, reprise de la lecture
    • Commandes de lecture de l'Assistant Google/WearOS
    • AutomotiveOS: commande et connexion personnalisées