Utiliser une session multimédia

Les sessions multimédias offrent un moyen universel d'interagir avec un lecteur audio ou vidéo. En informant Android que des contenus multimédias sont en cours de lecture dans une application, les commandes de lecture peuvent être déléguées à l'application. L'intégration à la session multimédia permet à une application d'annoncer la lecture multimédia en externe et de recevoir des commandes de lecture à partir de sources externes. Ces sources peuvent être des boutons physiques (comme le bouton de lecture d'un casque ou de la télécommande d'un téléviseur) ou des commandes indirectes (telles que l'instruction de "pause" à l'Assistant Google). La session multimédia délègue ensuite ces commandes à l'application qui les applique au lecteur multimédia dont l'origine est transparente.

Une session multimédia est également exécutée en même temps que le lecteur qu'elle gère. Vous devez créer et initialiser une session multimédia dans la méthode onCreate() de l'activité ou du service propriétaire de la session multimédia et du lecteur associé.

Initialiser la session multimédia

Une session multimédia nouvellement créée ne dispose d'aucune fonctionnalité. Vous devez initialiser la session en procédant comme suit:

  • Définissez des indicateurs afin que la session multimédia puisse recevoir des rappels des contrôleurs multimédias et des boutons multimédias.
  • Créez et initialisez une instance de PlaybackStateCompat, puis affectez-la à la session. L'état de la lecture change tout au long de la session. Nous vous recommandons donc de mettre en cache PlaybackStateCompat.Builder pour le réutiliser.
  • Créez une instance de MediaSessionCompat.Callback et affectez-la à la session (plus d'informations sur les rappels ci-dessous).

Vous devez créer et initialiser une session multimédia dans la méthode onCreate() de l'activité ou du service propriétaire de la session.

Pour que les boutons multimédias fonctionnent lorsque votre application est initialisée (ou arrêtée), son PlaybackState doit contenir une action de lecture correspondant à l'intent envoyé par le bouton multimédia. C'est pourquoi ACTION_PLAY est attribué à l'état de la session lors de l'initialisation. Pour en savoir plus, consultez la section Répondre aux boutons multimédias.

Gérer l'état de la lecture et les métadonnées

Deux classes représentent l'état d'une session multimédia.

La classe PlaybackStateCompat décrit l'état de fonctionnement actuel du lecteur. Par exemple :

  • État du transport (lecture, mise en pause ou mise en mémoire tampon du lecteur, etc. voir getState())
  • Un code d'erreur et un message d'erreur facultatif, le cas échéant. (Voir getErrorCode() et États et erreurs ci-dessous.)
  • La position du lecteur
  • Les actions valides du contrôleur pouvant être gérées à l'état actuel

La classe MediaMetadataCompat décrit le contenu en cours de lecture:

  • Le nom de l'artiste, de l'album et du titre
  • la durée du titre ;
  • Pochette d'album à afficher sur l'écran de verrouillage. L'image est un bitmap avec une taille maximale de 320 x 320 dp (si elle est plus grande, elle est réduite).
  • Instance de ContentUris qui pointe vers une version plus grande de l'illustration.

L'état du lecteur et les métadonnées peuvent changer au cours d'une session multimédia. Chaque fois que l'état ou les métadonnées changent, vous devez utiliser le compilateur correspondant pour chaque classe, PlaybackStateCompat.Builder() ou MediaMetadataCompat.Builder(), puis transmettre la nouvelle instance à la session multimédia en appelant setPlaybackState() ou setMetaData(). Pour réduire la consommation globale de mémoire de ces opérations fréquentes, il est recommandé de créer les compilateurs une seule fois et de les réutiliser tout au long de la durée de la session.

États et erreurs

Notez que PlaybackState est un objet qui contient des valeurs distinctes pour l'état de lecture de la session (getState()) et, si nécessaire, un code d'erreur associé (getErrorCode()). Les erreurs peuvent être fatales ou non:

Chaque fois que la lecture est interrompue, vous devez générer une erreur fatale: définissez l'état du transport sur STATE_ERROR et spécifiez une erreur associée avec setErrorMessage(int, CharSequence). Tant que la lecture est bloquée par l'erreur, PlaybackState doit continuer à signaler STATE_ERROR et l'erreur.

Une erreur non fatale se produit lorsque votre application ne peut pas gérer une requête, mais peut continuer à lire : le transport reste dans un état "normal" (par exemple, STATE_PLAYING), mais PlaybackState contient un code d'erreur. Par exemple, si le dernier titre est en cours de lecture et que l'utilisateur demande de passer au titre suivant, la lecture peut se poursuivre, mais vous devez créer un PlaybackState avec le code d'erreur ERROR_CODE_END_OF_QUEUE, puis appeler setPlaybackState(). Les contrôleurs multimédias associés à la session reçoivent le rappel onPlaybackStateChanged() et expliquent à l'utilisateur ce qui s'est passé. Une erreur non fatale ne doit être signalée qu'une seule fois au moment où elle se produit. Lors de la prochaine mise à jour de la session, ne redéfinissez pas la même erreur non fatale (sauf si l'erreur se produit en réponse à une nouvelle requête).PlaybackState

Écrans de verrouillage des sessions multimédias

À partir d'Android 4.0 (niveau d'API 14), le système peut accéder à l'état et aux métadonnées de lecture d'une session multimédia. C'est ainsi que l'écran de verrouillage peut afficher les commandes multimédias et les illustrations. Le comportement varie selon la version d'Android.

Pochettes d'album

Sous Android 4.0 (niveau d'API 14) à Android 10 (niveau d'API 29), l'arrière-plan de l'écran de verrouillage affiche la pochette de votre album, mais uniquement si les métadonnées de la session multimédia incluent un bitmap d'arrière-plan.

Commandes de transport

Dans Android 4.0 (niveau d'API 14) à Android 4.4 (niveau d'API 19), lorsqu'une session multimédia est active et que les métadonnées de la session multimédia incluent un bitmap d'arrière-plan, l'écran de verrouillage affiche automatiquement les commandes de transport.

Sous Android 5.0 (niveau d'API 21) ou version ultérieure, le système ne fournit pas de commandes de transport sur l'écran de verrouillage. Utilisez plutôt une notification MediaStyle pour afficher les commandes de transport.

Ajouter des actions personnalisées

Les applications multimédias peuvent définir des actions personnalisées, comme cliquer sur "J'aime" ou "J'aime" ou revenir en arrière de 30 secondes. Une action personnalisée doit implémenter un comportement entièrement nouveau. N'utilisez pas d'action personnalisée pour remplacer l'une des actions de commande de transport standards définies dans PlaybackStateCompat.

Ajoutez des actions personnalisées avec addCustomAction(). L'exemple suivant montre comment ajouter une commande pour une action "J'aime" :

Kotlin

stateBuilder.addCustomAction(
        PlaybackStateCompat.CustomAction.Builder(
                CUSTOM_ACTION_THUMBS_UP,
                resources.getString(R.string.thumbs_up),
                thumbsUpIcon
        ).run {
            setExtras(customActionExtras)
            build()
        }
)

Java

stateBuilder.addCustomAction(new PlaybackStateCompat.CustomAction.Builder(
    CUSTOM_ACTION_THUMBS_UP, resources.getString(R.string.thumbs_up), thumbsUpIcon)
    .setExtras(customActionExtras)
    .build());

Consultez Universal Music Player pour un exemple complet.

Vous répondez à l'action par onCustomAction().

Kotlin

override fun onCustomAction(action: String, extras: Bundle?) {
    when(action) {
        CUSTOM_ACTION_THUMBS_UP -> {
            ...
        }
    }
}

Java

@Override
public void onCustomAction(@NonNull String action, Bundle extras) {
    if (CUSTOM_ACTION_THUMBS_UP.equals(action)) {
        ...
    }
}

Consultez également Universal Music Player.

Rappels de session multimédia

Les principales méthodes de rappel de la session multimédia sont onPlay(), onPause() et onStop(). C'est ici que vous ajoutez le code qui contrôle votre lecteur.

Étant donné que vous instanciez et définissez le rappel de la session au moment de l'exécution (dans onCreate()), votre application peut définir d'autres rappels qui utilisent différents joueurs et choisir la combinaison rappel/lecteur appropriée en fonction de l'appareil et/ou du niveau du système. Vous pouvez changer de lecteur sans modifier le reste de l'application. Par exemple, vous pouvez utiliser ExoPlayer sur Android 4.1 (niveau d'API 16) ou une version ultérieure et MediaPlayer sur les anciens systèmes.

En plus de contrôler le lecteur et de gérer les transitions d'état des sessions multimédias, les rappels permettent d'activer et de désactiver les fonctionnalités de votre application, et de contrôler la façon dont elle interagit avec les autres applications et le matériel de l'appareil. (voir la section Contrôler la sortie audio).

L'implémentation des méthodes de rappel de session multimédia dépend de la structure de votre application. Consultez les pages distinctes qui décrivent l'utilisation des rappels dans les applications audio et les applications vidéo, ainsi que la manière dont les rappels doivent être implémentés pour chaque type d'application.