Come eseguire l'integrazione con i tasti multimediali hardware, personalizzare le notifiche multimediali e altro ancora.
Per consentire agli utenti di sapere cosa è in riproduzione nel browser e controllarlo senza tornare alla pagina che lo ha avviato, è stata introdotta l'API Media Session. Consente agli sviluppatori web di personalizzare questa esperienza tramite metadati nelle notifiche multimediali personalizzate, eventi multimediali come riproduzione, messa in pausa, ricerca, cambio di traccia ed eventi di videoconferenza come attivazione/disattivazione del microfono, attivazione/disattivazione della videocamera e riaggancio. Queste personalizzazioni sono disponibili in diversi contesti, tra cui hub multimediali per computer, notifiche multimediali su dispositivi mobili e persino su dispositivi indossabili. Descriverò queste personalizzazioni in questo articolo.
Informazioni sull'API Media Session
L'API Media session offre diversi vantaggi e funzionalità:
- Le tasti multimediali hardware sono supportate.
- Le notifiche multimediali sono personalizzate su dispositivi mobili, computer e dispositivi indossabili accoppiati.
- L'hub multimediale è disponibile su computer.
- I controlli multimediali della schermata di blocco sono disponibili su ChromeOS e dispositivi mobili.
- I controlli della finestra Picture-in-Picture sono disponibili per la riproduzione audio, le videoconferenze e le presentazioni di slide.
- L'integrazione con l'assistente è disponibile sui dispositivi mobili.
Di seguito sono riportati alcuni esempi che illustrano alcuni di questi punti.
Esempio 1: se gli utenti premono il tasto multimediale "Brano successivo" della tastiera, gli sviluppatori web possono gestire questa azione dell'utente indipendentemente dal fatto che il browser sia in primo piano o in background.
Esempio 2: se gli utenti ascoltano un podcast sul web mentre lo schermo del dispositivo è bloccato, possono comunque premere l'icona "avanza indietro" dai controlli multimediali della schermata di blocco in modo che gli sviluppatori web spostino il tempo di riproduzione indietro di alcuni secondi.
Esempio 3: se gli utenti hanno schede che riproducono audio, possono interrompere facilmente la riproduzione dall'hub multimediale sul computer in modo che gli sviluppatori web abbiano la possibilità di cancellare il proprio stato.
Esempio 4: se gli utenti sono in videochiamata, possono premere il controllo "attiva/disattiva microfono" nella finestra Picture-in-Picture per impedire al sito web di ricevere i dati del microfono.
Tutto questo viene eseguito tramite due interfacce diverse: l'interfaccia MediaSession
e l'interfaccia MediaMetadata
. La prima consente agli utenti
di controllare qualsiasi cosa stia riproducendo. Il secondo è come dire a MediaSession
cosa deve essere controllato.
A titolo esemplificativo, l'immagine seguente mostra come queste interfacce si riferiscono a controlli multimediali specifici, in questo caso una notifica multimediale su dispositivo mobile.
Fai sapere agli utenti cosa c'è in riproduzione
Quando un sito web riproduce contenuti audio o video, gli utenti ricevono automaticamente notifiche multimediali nella barra delle notifiche sui dispositivi mobili o nell'hub multimediale su computer. Il browser fa del suo meglio per mostrare le informazioni appropriate utilizzando il titolo del documento e l'immagine dell'icona più grande che riesce a trovare. Con l'API Media Session, è possibile personalizzare le notifiche relative ai contenuti multimediali con alcuni metadati multimediali più avanzati, come il titolo, il nome dell'artista, il nome dell'album e la copertina, come mostrato di seguito.
Chrome richiede l'attenzione audio "completa" per mostrare le notifiche multimediali solo quando la durata del contenuto multimediale è di almeno 5 secondi. In questo modo, gli suoni accidentali come i bip non mostrano notifiche.
// 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.
}
Al termine della riproduzione, non è necessario "rilasciare" la sessione multimediale perché la notifica scompare automaticamente. Tieni presente che l'elemento navigator.mediaSession.metadata
verrà utilizzato all'avvio della successiva riproduzione. Per questo motivo, è importante aggiornarlo quando cambia la fonte di riproduzione dei contenuti multimediali per assicurarti che nella notifica multimediale vengano mostrate informazioni pertinenti.
Esistono alcuni aspetti da tenere in considerazione in merito ai metadati dei contenuti multimediali.
- L'array di artwork delle notifiche supporta URL BLOB e URL di dati.
- Se non è definito alcun artwork e esiste un'immagine dell'icona (specificata utilizzando
<link rel=icon>
) di dimensioni adeguate, le notifiche multimediali la utilizzeranno. - Le dimensioni target dell'artwork di notifica in Chrome per Android sono
512x512
. Per i dispositivi di fascia bassa, è256x256
. - L'attributo
title
dell'elemento HTML multimediale viene utilizzato nel widget macOS "Now Playing". - Se la risorsa multimediale è incorporata (ad esempio in un iframe), le informazioni sull'API Media Session devono essere impostate dal contesto incorporato. Guarda lo snippet di seguito.
<iframe id="iframe">
<video>...</video>
</iframe>
<script>
iframe.contentWindow.navigator.mediaSession.metadata = new MediaMetadata({
title: 'Never Gonna Give You Up',
...
});
</script>
Puoi anche aggiungere ai metadati dei contenuti multimediali informazioni sui singoli capitoli, come il titolo della sezione, il timestamp e un'immagine dello screenshot. In questo modo gli utenti possono navigare tra i contenuti dei contenuti multimediali.
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' },
]
}]
});
Consentire agli utenti di controllare i contenuti in riproduzione
Un'azione di sessione multimediale è un'azione (ad esempio "Riproduci" o "Metti in pausa") che un sito web può gestire per gli utenti quando interagiscono con la riproduzione multimediale in corso. Le azioni sono simili agli eventi e funzionano in modo molto simile. Come per gli eventi, le azioni vengono implementate impostando i gestori su un oggetto appropriato, in questo caso un'istanza di MediaSession
. Alcune azioni vengono attivate quando gli utenti premono pulsanti su cuffie, un altro dispositivo remoto, una tastiera o interagiscono con una notifica multimediale.
Poiché alcune azioni di sessione multimediale potrebbero non essere supportate, è consigliabile
utilizzare un blocco try…catch
per impostarle.
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.`);
}
}
Per annullare un gestore di azioni della sessione multimediale è sufficiente impostarlo su 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.`);
}
Una volta impostati, i gestori delle azioni delle sessioni multimediali verranno mantenuti durante le riproduzioni multimediali. È simile al pattern di listener di eventi, tranne per il fatto che la gestione di un evento significa che il browser interrompe qualsiasi comportamento predefinito e lo utilizza come segnale che il sito web supporta l'azione multimediale. Di conseguenza, i controlli delle azioni multimediali non verranno mostrati se non viene impostato il gestore delle azioni appropriato.
Riprodurre / mettere in pausa
L'azione "play"
indica che l'utente vuole riprendere la riproduzione dei contenuti multimediali, mentre "pause"
indica la volontà di interromperla temporaneamente.
L'icona "Riproduci/Metti in pausa" viene sempre visualizzata in una notifica multimediale e gli eventi multimediali correlati vengono gestiti automaticamente dal browser. Per sostituire il loro comportamento predefinito, gestisci le azioni multimediali "Riproduci" e "Metti in pausa" come mostrato di seguito.
Ad esempio, il browser potrebbe considerare che un sito web non riproduca contenuti multimediali durante la ricerca o il caricamento. In questo caso, sostituisci questo comportamento impostando navigator.mediaSession.playbackState
su "playing"
o "paused"
per assicurarti che l'interfaccia utente del sito web rimanga sincronizzata con i controlli delle notifiche multimediali.
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';
});
Traccia precedente
L'azione "previoustrack"
indica che l'utente vuole avviare la riproduzione dei contenuti multimediali correnti dall'inizio se la riproduzione dei contenuti multimediali ha un concetto di inizio oppure passare all'elemento precedente della playlist se la riproduzione dei contenuti multimediali ha un concetto di playlist.
navigator.mediaSession.setActionHandler('previoustrack', () => {
// Play previous track.
});
Traccia successiva
L'azione "nexttrack"
indica che l'utente vuole passare la riproduzione di contenuti multimediali
all'elemento successivo nella playlist se la riproduzione di contenuti multimediali ha una nozione di playlist.
navigator.mediaSession.setActionHandler('nexttrack', () => {
// Play next track.
});
Interrompi
L'azione "stop"
indica che l'utente vuole interrompere la riproduzione dei contenuti multimediali e
cancellare lo stato, se appropriato.
navigator.mediaSession.setActionHandler('stop', () => {
// Stop playback and clear state if appropriate.
});
Andare avanti/indietro
L'azione "seekbackward"
indica che l'utente vuole spostare il tempo di riproduzione dei contenuti multimediali indietro di un breve periodo, mentre "seekforward"
indica il desiderio di spostare il tempo di riproduzione dei contenuti multimediali in avanti di un breve periodo. In entrambi i casi, un periodo breve indica alcuni secondi.
Il valore seekOffset
fornito nel gestore dell'azione è il tempo in secondi di scorrimento del tempo di riproduzione dei contenuti multimediali. Se non viene fornito (ad esempio undefined
),
devi utilizzare un tempo ragionevole (ad esempio 10-30 secondi).
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.
});
Eseguire la ricerca fino a un momento specifico
L'azione "seekto"
indica che l'utente vuole spostare il tempo di riproduzione dei contenuti multimediali su un momento specifico.
Il valore seekTime
fornito nel gestore dell'azione è il tempo in secondi a cui spostare il tempo di riproduzione dei contenuti multimediali.
Il valore booleano fastSeek
fornito nel gestore dell'azione è true se l'azione viene chiamata più volte nell'ambito di una sequenza e non è l'ultima chiamata nella sequenza.
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.
});
Impostare la posizione di riproduzione
Mostrare con precisione la posizione di riproduzione dei contenuti multimediali in una notifica è semplice come impostare lo stato della posizione in un momento opportuno, come mostrato di seguito. Lo stato della posizione è una combinazione della velocità di riproduzione dei contenuti multimediali, della durata e dell'ora corrente.
La durata deve essere specificata e positiva. La posizione deve essere positiva e inferiore alla durata. La frequenza di riproduzione deve essere maggiore di 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();
});
Reimpostare lo stato della posizione è facile come impostarlo su null
.
// Reset position state when media is reset.
navigator.mediaSession.setPositionState(null);
Azioni di videoconferenza
Quando l'utente inserisce la videochiamata in una finestra Picture in picture, il browser potrebbe mostrare i controlli per il microfono e la videocamera e per riagganciare. Quando l'utente fa clic su questi elementi, il sito web li gestisce tramite le azioni di videoconferenza riportate di seguito. Per un esempio, consulta l'esempio di videoconferenza.
Attiva/disattiva microfono
L'azione "togglemicrophone"
indica che l'utente vuole attivare o disattivare il microfono. Il metodo setMicrophoneActive(isActive)
indica al browser se il sito web considera attualmente attivo il microfono.
let isMicrophoneActive = false;
navigator.mediaSession.setActionHandler('togglemicrophone', () => {
if (isMicrophoneActive) {
// Mute the microphone.
} else {
// Unmute the microphone.
}
isMicrophoneActive = !isMicrophoneActive;
navigator.mediaSession.setMicrophoneActive(isMicrophoneActive);
});
Attiva/Disattiva fotocamera
L'azione "togglecamera"
indica che l'utente vuole attivare o disattivare la
camera attiva. Il metodo setCameraActive(isActive)
indica se il browser considera attivo il sito web.
let isCameraActive = false;
navigator.mediaSession.setActionHandler('togglecamera', () => {
if (isCameraActive) {
// Disable the camera.
} else {
// Enable the camera.
}
isCameraActive = !isCameraActive;
navigator.mediaSession.setCameraActive(isCameraActive);
});
Riagganciare
L'azione "hangup"
indica che l'utente vuole terminare una chiamata.
navigator.mediaSession.setActionHandler('hangup', () => {
// End the call.
});
Azioni di presentazione delle diapositive
Quando l'utente inserisce la presentazione delle diapositive in una finestra Picture-in-Picture, il browser potrebbe mostrare i controlli per scorrere le diapositive. Quando l'utente fa clic su questi elementi, il sito web li gestisce tramite l'API Media Session. Per un esempio, consulta l'esempio di presentazione di Presentazioni.
Diapositiva precedente
L'azione "previousslide"
indica che l'utente vuole tornare alla slide precedente durante la presentazione.
navigator.mediaSession.setActionHandler('previousslide', () => {
// Show previous slide.
});
Supporto dei browser
Diapositiva successiva
L'azione "nextslide"
indica che l'utente vuole passare alla slide successiva
durante la presentazione di slide.
navigator.mediaSession.setActionHandler('nextslide', () => {
// Show next slide.
});
Supporto dei browser
Esempi
Dai un'occhiata ad alcuni Sample di Media Session che includono Blender Foundation e il lavoro di Jan Morgenstern.
Risorse
- Specifiche della sessione multimediale: wicg.github.io/mediasession
- Problemi relativi alle specifiche: github.com/WICG/mediasession/issues
- Bug di Chrome: crbug.com