Comment intégrer les touches multimédias matérielles, personnaliser les notifications multimédias et plus encore.
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 des notifications multimédias personnalisées, des événements multimédias tels que la lecture, la mise en pause, la recherche, le changement de piste et 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 les hubs multimédias pour ordinateur, les notifications multimédias sur mobile et même sur les accessoires connectés. Je vais décrire ces personnalisations dans cet article.
![Captures d'écran des contextes de sessions multimédias.](https://web.dev/static/articles/media-session/image/screenshots-media-sessio-f4629fe9ea633.jpg?authuser=6&hl=fr)
À propos de l'API Media Session
L'API Media Session offre plusieurs avantages et fonctionnalités:
- Les clés multimédias matérielles sont acceptées.
- 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.
Voici quelques exemples pour illustrer certains de ces points.
Exemple 1:Si les utilisateurs appuient sur la touche multimédia "track Next" 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 lorsque l'écran de leur appareil est verrouillé, ils peuvent toujours appuyer sur l'icône de recherche en arrière dans les commandes multimédias de l'écran de verrouillage, ce qui permet aux développeurs Web de reculer de quelques secondes le temps de lecture.
Exemple 3:Si les utilisateurs ont des 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 via deux interfaces différentes: MediaSession
et MediaMetadata
. Le premier permet aux utilisateurs
de contrôler ce qui est diffusé. La seconde permet d'indiquer à MediaSession
ce qui doit être contrôlé.
Pour illustrer cela, l'image ci-dessous montre 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 la session multimédia.](https://web.dev/static/articles/media-session/image/media-session-interfaces-c7bc0962a921c.jpg?authuser=6&hl=fr)
Indiquer aux utilisateurs ce qui est 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 notification sur mobile ou dans le hub multimédia sur ordinateur. Le navigateur affiche au mieux 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 enrichies telles que le titre, le nom de l'artiste, le nom de l'album et la pochette, comme illustré ci-dessous.
Chrome demande le focus audio "complet" pour n'afficher les notifications multimédias que si la durée du contenu multimédia est d'au moins cinq secondes. Cela garantit que les sons indirects tels que les bruits 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 "relâcher" la session multimédia, car la notification disparaît automatiquement. N'oubliez pas que navigator.mediaSession.metadata
sera utilisé au démarrage de la lecture suivante. C'est pourquoi il est important de le 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.
Vous devez tenir compte des points suivants concernant les métadonnées multimédias.
- Le tableau d'illustrations de notification accepte les URL d'objets blob et les URL de données.
- Si aucune illustration n'est définie et qu'une image d'icône (spécifiée à l'aide de
<link rel=icon>
) est à une taille souhaitée, les notifications multimédias l'utiliseront. - La taille de la cible de l'illustration de la notification dans Chrome pour Android est de
512x512
. Pour les appareils bas de gamme, il s'agit de256x256
. - 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>
Vous pouvez également ajouter aux métadonnées multimédias des informations sur des chapitres individuels, comme le titre de la section, son code temporel et une capture d'écran. Cela permet aux utilisateurs de naviguer dans le contenu du média.
navigator.mediaSession.metadata = new MediaMetadata({
// title, artist, album, artwork, ...
chapterInfo: [{
title: 'Chapter 1',
startTime: 0,
artwork: [
{ src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
{ src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
]
}, {
title: 'Chapter 2',
startTime: 42,
artwork: [
{ src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
{ src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
]
}]
});
![Informations sur les chapitres affichées dans une notification multimédia ChromeOS.](https://web.dev/static/articles/media-session/image/screenshot-notification-chapter.jpg?authuser=6&hl=fr)
Autoriser les utilisateurs à contrôler la lecture
Une action de session multimédia est une action (par exemple, "lire" ou "mettre en pause") qu'un site Web peut gérer pour les utilisateurs lorsqu'ils interagissent avec le contenu multimédia en cours de lecture. 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 le cas présent). Certaines actions sont déclenchées lorsque les utilisateurs appuient sur les boutons d'un casque, d'un autre appareil distant ou d'un clavier, ou lorsqu'ils interagissent avec une notification multimédia.
![Capture d'écran d'une notification multimédia sous Windows 10.](https://web.dev/static/articles/media-session/image/screenshot-a-media-notif-0b640cbe50bb1.jpg?authuser=6&hl=fr)
É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 sessions multimédias sont conservés lors de la lecture de contenus multimédias. Ce modèle d'écouteur d'événements 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 d'effectuer tout 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'écran du widget En écoute dans macOS Big Sur.](https://web.dev/static/articles/media-session/image/screenshot-the-playing-178373d8aea09.jpg?authuser=6&hl=fr)
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 "Lire" et "Mettre en pause" comme indiqué ci-dessous.
Le navigateur peut considérer qu'un site Web ne lit pas de contenu multimédia, par exemple lors de la recherche ou du chargement. 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 du contenu multimédia a une notion de début, ou passer à l'élément précédent dans la playlist si la lecture multimédia a 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 d'un contenu multimédia vers l'élément suivant de la playlist si la lecture contient 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 brièvement la durée de lecture du contenu multimédia, tandis que "seekforward"
indique qu'il souhaite avancer d'un court laps de temps. Dans les deux cas, une courte période correspond à quelques secondes.
La valeur seekOffset
fournie dans le gestionnaire d'actions correspond à la durée en secondes de déplacement de la durée de lecture multimédia. 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.
});
Rechercher une heure spécifique
L'action "seekto"
indique que l'utilisateur souhaite décaler la durée de lecture du contenu multimédia vers une heure spécifique.
La valeur seekTime
fournie dans le gestionnaire d'actions correspond à la durée de lecture du contenu multimédia, exprimée en secondes.
La valeur booléenne fastSeek
fournie dans le gestionnaire d'actions est "true" si l'action est appelée plusieurs fois dans le cadre d'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 lecture du 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'écran des commandes multimédias de l'écran de verrouillage dans ChromeOS.](https://web.dev/static/articles/media-session/image/screenshot-lock-screen-m-e71582de5ca3d.jpg?authuser=6&hl=fr)
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();
});
Pour réinitialiser l'état de la position, il suffit 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'écran des commandes de visioconférence dans une fenêtre Picture-in-picture.](https://web.dev/static/articles/media-session/image/screenshot-video-confere-7e82acef00cdb.jpg?authuser=6&hl=fr)
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.
});
Actions pour la présentation des diapositives
Lorsque l'utilisateur place sa présentation Slides dans une fenêtre Picture-in-picture, le navigateur peut afficher des commandes permettant de naviguer 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 de présentation de diapositives.
Diapositive précédente
L'action "previousslide"
indique que l'utilisateur souhaite revenir à la diapositive précédente lors de la présentation 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
Exemples
Consultez des exemples de sessions multimédias dans lesquelles la Blender Foundation et le travail de Jan Morgenstern sont présentés.
Ressources
- Spécification de la session multimédia : wicg.github.io/mediasession
- Problèmes de spécifications : github.com/WICG/mediasession/issues
- Bugs Chrome : crbug.com