Personnalisez les notifications multimédias et les commandes de lecture avec l'API Media Session

Intégrer les clés multimédias matérielles, personnaliser les notifications multimédias, etc.

François Beaufort
François Beaufort

L'API Media Session a été introduite pour permettre aux utilisateurs de savoir ce qui est en cours de lecture dans leur navigateur et de le contrôler sans revenir à la page qui l'a lancé. Il permet aux développeurs Web de personnaliser cette expérience via des métadonnées dans les notifications multimédias personnalisées, des événements multimédias tels que la lecture, la mise en pause, la recherche et le changement de titre, ainsi que des événements de visioconférence tels que la désactivation/réactivation du micro, l'activation et la désactivation de la caméra et raccrocher. Ces personnalisations sont disponibles dans plusieurs contextes, y compris sur les hubs multimédias pour ordinateur, les notifications multimédias sur mobile et même sur les accessoires connectés. Je décrirai ces personnalisations dans cet article.

Captures d'écran des contextes de sessions multimédias.
Media Hub sur ordinateur, notifications multimédias sur mobile et accessoire connecté.

À propos de l'API Media Session

L'API de session multimédia offre plusieurs avantages et fonctionnalités:

  • Les clés multimédias matérielles sont compatibles.
  • Les notifications multimédias sont personnalisées sur les mobiles, les ordinateurs et les accessoires connectés associés.
  • Le hub multimédia est disponible sur ordinateur.
  • Les commandes multimédias de l'écran de verrouillage sont disponibles sur ChromeOS et sur mobile.
  • Les commandes de fenêtre Picture-in-picture sont disponibles pour la lecture audio, la visioconférence et la présentation de diapositives.
  • L'intégration de l'Assistant sur mobile est disponible.

Navigateurs pris en charge

  • 73
  • 79
  • 82
  • 15

Source

Voici quelques exemples pour illustrer certains de ces points.

Exemple 1:Si les utilisateurs appuient sur la touche multimédia "Voie suivante" de leur clavier, les développeurs Web peuvent gérer cette action utilisateur, que le navigateur soit au premier plan ou en arrière-plan.

Exemple 2:Si les utilisateurs écoutent un podcast sur le Web alors que l'écran de leur appareil est verrouillé, ils peuvent toujours appuyer sur l'icône de retour arrière dans les commandes multimédias de l'écran de verrouillage, afin que les développeurs Web reculent la durée de lecture de quelques secondes.

Exemple 3:Si les utilisateurs disposent d'onglets qui lisent du contenu audio, ils peuvent facilement arrêter la lecture à partir du Media Hub sur ordinateur afin que les développeurs Web aient la possibilité d'effacer leur état.

Exemple 4:Si les utilisateurs participent à un appel vidéo, ils peuvent appuyer sur la commande d'activation du micro dans la fenêtre Picture-in-picture pour empêcher le site Web de recevoir les données du micro.

Tout cela se fait via deux interfaces différentes: l'interface MediaSession et l'interface MediaMetadata. Le premier permet aux utilisateurs de contrôler ce qui se passe. La seconde permet d'indiquer à MediaSession ce qui doit être contrôlé.

L'image ci-dessous illustre la relation entre ces interfaces et des commandes multimédias spécifiques, dans ce cas une notification multimédia sur mobile.

Illustration des interfaces de sessions multimédias.
Anatomie d'une notification multimédia sur mobile.

Indiquer aux utilisateurs quel est le titre en cours de lecture

Lorsqu'un site Web lit du contenu audio ou vidéo, les utilisateurs reçoivent automatiquement des notifications multimédias dans la barre de notifications sur mobile ou via le hub multimédia sur un ordinateur. Le navigateur s'efforce d'afficher les informations appropriées en utilisant le titre du document et la plus grande image d'icône disponible. Avec l'API Media Session, il est possible de personnaliser la notification multimédia avec des métadonnées multimédias plus riches telles que le titre, le nom de l'artiste, le nom de l'album et la pochette, comme illustré ci-dessous.

Chrome demande la sélection audio "complète" pour n'afficher les notifications multimédias que si ces dernières durent au moins cinq secondes. Cela garantit que les sons accessoires, comme les notifications, n'affichent pas de notifications.

// After media (video or audio) starts playing
await document.querySelector("video").play();

if ("mediaSession" in navigator) {
  navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    artist: 'Rick Astley',
    album: 'Whenever You Need Somebody',
    artwork: [
      { src: 'https://via.placeholder.com/96',   sizes: '96x96',   type: 'image/png' },
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/192', sizes: '192x192', type: 'image/png' },
      { src: 'https://via.placeholder.com/256', sizes: '256x256', type: 'image/png' },
      { src: 'https://via.placeholder.com/384', sizes: '384x384', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  });

  // TODO: Update playback state.
}

À la fin de la lecture, il n'est pas nécessaire de "libérer" la session multimédia, car la notification disparaîtra automatiquement. N'oubliez pas que navigator.mediaSession.metadata sera utilisé au début de la lecture suivante. C'est pourquoi il est important de la mettre à jour lorsque la source de lecture multimédia change pour vous assurer que les informations pertinentes sont affichées dans la notification multimédia.

Voici quelques points à retenir concernant les métadonnées multimédias.

  • Le tableau d'illustrations de notification accepte les URL blob et les URL de données.
  • Si aucune illustration n'est définie et qu'il existe une icône (spécifiée à l'aide de <link rel=icon>) à une taille souhaitée, les notifications des médias l'utiliseront.
  • La taille de la cible de l'illustration de notification dans Chrome pour Android est de 512x512. Pour les appareils bas de gamme, il s'agit de 256x256.
  • L'attribut title de l'élément HTML multimédia est utilisé dans le widget macOS "En écoute".
  • Si la ressource multimédia est intégrée (par exemple, dans un iFrame), les informations de l'API Media Session doivent être définies à partir du contexte intégré. Voir l'extrait ci-dessous.
<iframe id="iframe">
  <video>...</video>
</iframe>
<script>
  iframe.contentWindow.navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    ...
  });
</script>

Contrôler la lecture d'un contenu pour les utilisateurs

Une action de session multimédia est une action (par exemple, "lecture" ou "pause") qu'un site Web peut gérer pour les utilisateurs lorsqu'ils interagissent avec la lecture du contenu multimédia en cours. Les actions sont analogues aux événements et fonctionnent à peu près de la même manière. Comme les événements, les actions sont mises en œuvre en définissant des gestionnaires sur un objet approprié, une instance de MediaSession dans ce cas. Certaines actions sont déclenchées lorsque l'utilisateur appuie sur les boutons d'un casque, d'un autre appareil distant ou d'un clavier, ou lorsqu'il interagit avec une notification multimédia.

Capture d&#39;écran d&#39;une notification multimédia sous Windows 10.
Notifications multimédias personnalisées sous Windows 10.

Étant donné que certaines actions de session multimédia peuvent ne pas être compatibles, nous vous recommandons d'utiliser un bloc try…catch lorsque vous les définissez.

const actionHandlers = [
  ['play',          () => { /* ... */ }],
  ['pause',         () => { /* ... */ }],
  ['previoustrack', () => { /* ... */ }],
  ['nexttrack',     () => { /* ... */ }],
  ['stop',          () => { /* ... */ }],
  ['seekbackward',  (details) => { /* ... */ }],
  ['seekforward',   (details) => { /* ... */ }],
  ['seekto',        (details) => { /* ... */ }],
  /* Video conferencing actions */
  ['togglemicrophone', () => { /* ... */ }],
  ['togglecamera',     () => { /* ... */ }],
  ['hangup',           () => { /* ... */ }],
  /* Presenting slides actions */
  ['previousslide', () => { /* ... */ }],
  ['nextslide',     () => { /* ... */ }],
];

for (const [action, handler] of actionHandlers) {
  try {
    navigator.mediaSession.setActionHandler(action, handler);
  } catch (error) {
    console.log(`The media session action "${action}" is not supported yet.`);
  }
}

Pour désactiver un gestionnaire d'actions de session multimédia, il suffit de le définir sur null.

try {
  // Unset the "nexttrack" action handler at the end of a playlist.
  navigator.mediaSession.setActionHandler('nexttrack', null);
} catch (error) {
  console.log(`The media session action "nexttrack" is not supported yet.`);
}

Une fois définis, les gestionnaires d'actions de session multimédia sont conservés pendant la lecture des contenus multimédias. Ce modèle est semblable au modèle d'écouteur d'événements, à la différence que la gestion d'un événement signifie que le navigateur cesse de suivre le comportement par défaut et l'utilise comme signal indiquant que le site Web prend en charge l'action multimédia. Par conséquent, les commandes des actions multimédias ne s'affichent que si le gestionnaire d'actions approprié est défini.

Capture d&#39;écran du widget En écoute dans macOS Big Sur.
Widget En écoute dans macOS Big Sur

Lecture / Pause

L'action "play" indique que l'utilisateur souhaite reprendre la lecture du contenu multimédia, tandis que "pause" indique qu'il souhaite l'interrompre temporairement.

L'icône lecture/pause s'affiche toujours dans une notification multimédia, et les événements multimédias associés sont gérés automatiquement par le navigateur. Pour ignorer leur comportement par défaut, gérez les actions multimédias "lecture" et "pause" comme indiqué ci-dessous.

Le navigateur peut considérer qu'un site Web ne lit pas de contenu multimédia lors de la recherche ou du chargement, par exemple. Dans ce cas, remplacez ce comportement en définissant navigator.mediaSession.playbackState sur "playing" ou "paused" pour vous assurer que l'UI du site Web reste synchronisée avec les commandes de notification multimédia.

const video = document.querySelector('video');

navigator.mediaSession.setActionHandler('play', async () => {
  // Resume playback
  await video.play();
});

navigator.mediaSession.setActionHandler('pause', () => {
  // Pause active playback
  video.pause();
});

video.addEventListener('play', () => {
  navigator.mediaSession.playbackState = 'playing';
});

video.addEventListener('pause', () => {
  navigator.mediaSession.playbackState = 'paused';
});

Titre précédent

L'action "previoustrack" indique que l'utilisateur souhaite lancer la lecture du contenu multimédia en cours depuis le début si la lecture a une notion de début, ou passer à l'élément précédent de la playlist si la lecture de contenus multimédias comporte une notion de playlist.

navigator.mediaSession.setActionHandler('previoustrack', () => {
  // Play previous track.
});

Titre suivant

L'action "nexttrack" indique que l'utilisateur souhaite déplacer la lecture du contenu multimédia vers l'élément suivant de la playlist s'il s'agit d'une notion de playlist.

navigator.mediaSession.setActionHandler('nexttrack', () => {
  // Play next track.
});

Arrêter

L'action "stop" indique que l'utilisateur souhaite arrêter la lecture du contenu multimédia et effacer l'état, le cas échéant.

navigator.mediaSession.setActionHandler('stop', () => {
  // Stop playback and clear state if appropriate.
});

Avancer / Reculer

L'action "seekbackward" indique que l'utilisateur souhaite reculer d'un court moment la durée de lecture, tandis que "seekforward" indique qu'il souhaite avancer brièvement la durée de lecture. Dans les deux cas, une courte période correspond à quelques secondes.

La valeur seekOffset fournie dans le gestionnaire d'actions correspond au délai de lecture du contenu multimédia en secondes. S'il n'est pas fourni (par exemple, undefined), vous devez utiliser un moment raisonnable (par exemple, 10 à 30 secondes).

const video = document.querySelector('video');
const defaultSkipTime = 10; /* Time to skip in seconds by default */

navigator.mediaSession.setActionHandler('seekbackward', (details) => {
  const skipTime = details.seekOffset || defaultSkipTime;
  video.currentTime = Math.max(video.currentTime - skipTime, 0);
  // TODO: Update playback state.
});

navigator.mediaSession.setActionHandler('seekforward', (details) => {
  const skipTime = details.seekOffset || defaultSkipTime;
  video.currentTime = Math.min(video.currentTime + skipTime, video.duration);
  // TODO: Update playback state.
});

Accéder à une heure spécifique

L'action "seekto" indique que l'utilisateur souhaite déplacer la durée de lecture des contenus multimédias vers un moment spécifique.

La valeur seekTime fournie dans le gestionnaire d'actions correspond à la durée (en secondes) de lecture du contenu multimédia.

La valeur booléenne fastSeek fournie dans le gestionnaire d'actions est "true" si l'action est appelée plusieurs fois dans une séquence et qu'il ne s'agit pas du dernier appel de cette séquence.

const video = document.querySelector('video');

navigator.mediaSession.setActionHandler('seekto', (details) => {
  if (details.fastSeek && 'fastSeek' in video) {
    // Only use fast seek if supported.
    video.fastSeek(details.seekTime);
    return;
  }
  video.currentTime = details.seekTime;
  // TODO: Update playback state.
});

Définir la position de lecture

Pour afficher avec précision la position de la lecture d'un contenu multimédia dans une notification, il suffit de définir l'état de la position au moment approprié, comme indiqué ci-dessous. L'état de position combine la vitesse de lecture du contenu multimédia, la durée et l'heure actuelle.

Capture d&#39;écran des commandes multimédias de l&#39;écran de verrouillage dans ChromeOS.
Commandes multimédias sur l'écran de verrouillage dans ChromeOS

La durée doit être indiquée et positive. La position doit être positive et inférieure à la durée. La vitesse de lecture doit être supérieure à 0.

const video = document.querySelector('video');

function updatePositionState() {
  if ('setPositionState' in navigator.mediaSession) {
    navigator.mediaSession.setPositionState({
      duration: video.duration,
      playbackRate: video.playbackRate,
      position: video.currentTime,
    });
  }
}

// When video starts playing, update duration.
await video.play();
updatePositionState();

// When user wants to seek backward, update position.
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
  /* ... */
  updatePositionState();
});

// When user wants to seek forward, update position.
navigator.mediaSession.setActionHandler('seekforward', (details) => {
  /* ... */
  updatePositionState();
});

// When user wants to seek to a specific time, update position.
navigator.mediaSession.setActionHandler('seekto', (details) => {
  /* ... */
  updatePositionState();
});

// When video playback rate changes, update position state.
video.addEventListener('ratechange', (event) => {
  updatePositionState();
});

Réinitialiser l'état de la position est aussi simple que de le définir sur null.

// Reset position state when media is reset.
navigator.mediaSession.setPositionState(null);

Actions de visioconférence

Lorsque l'utilisateur place son appel vidéo dans une fenêtre Picture-in-picture, le navigateur peut afficher des commandes pour le micro et la caméra, ainsi que pour raccrocher. Lorsque l'utilisateur clique dessus, le site Web les gère via les actions de visioconférence ci-dessous. Pour obtenir un exemple, consultez l'exemple de visioconférence.

Capture d&#39;écran des commandes de visioconférence dans une fenêtre Picture-in-picture.
Commandes de visioconférence dans une fenêtre Picture-in-picture

Activer/Désactiver le micro

L'action "togglemicrophone" indique que l'utilisateur souhaite couper ou réactiver le micro. La méthode setMicrophoneActive(isActive) indique au navigateur si le site Web considère actuellement le micro comme actif.

let isMicrophoneActive = false;

navigator.mediaSession.setActionHandler('togglemicrophone', () => {
  if (isMicrophoneActive) {
    // Mute the microphone.
  } else {
    // Unmute the microphone.
  }
  isMicrophoneActive = !isMicrophoneActive;
  navigator.mediaSession.setMicrophoneActive(isMicrophoneActive);
});

Activer/Désactiver la caméra

L'action "togglecamera" indique que l'utilisateur souhaite activer ou désactiver la caméra active. La méthode setCameraActive(isActive) indique si le navigateur considère que le site Web est actif.

let isCameraActive = false;

navigator.mediaSession.setActionHandler('togglecamera', () => {
  if (isCameraActive) {
    // Disable the camera.
  } else {
    // Enable the camera.
  }
  isCameraActive = !isCameraActive;
  navigator.mediaSession.setCameraActive(isCameraActive);
});

Raccrocher

L'action "hangup" indique que l'utilisateur souhaite mettre fin à un appel.

navigator.mediaSession.setActionHandler('hangup', () => {
  // End the call.
});

Présenter des actions de diapositives

Lorsque l'utilisateur place sa présentation de diapositives dans une fenêtre Picture-in-picture, le navigateur peut afficher des commandes de navigation dans les diapositives. Lorsque l'utilisateur clique dessus, le site Web les gère via l'API Media Session. Pour obtenir un exemple, consultez l'exemple Présenter du contenu Slides.

Diapositive précédente

L'action "previousslide" indique que l'utilisateur souhaite revenir à la diapositive précédente lorsqu'il présente des diapositives.

navigator.mediaSession.setActionHandler('previousslide', () => {
  // Show previous slide.
});

Navigateurs pris en charge

  • 111
  • 111
  • x
  • x

Diapositive suivante

L'action "nextslide" indique que l'utilisateur souhaite passer à la diapositive suivante lors de la présentation de diapositives.

navigator.mediaSession.setActionHandler('nextslide', () => {
  // Show next slide.
});

Navigateurs pris en charge

  • 111
  • 111
  • x
  • x

Samples

Consultez des exemples de sessions multimédias présentant Blender Foundation et le travail de Jan Morgenstern.

Enregistrement d'écran illustrant l'API Media Session.

Ressources