The setActionHandler()
method of the MediaSession
interface sets a handler for a media session action. These actions let a web app receive notifications when the user engages a device's built-in physical or onscreen media controls, such as play, stop, or seek buttons.
setActionHandler(type, callback)
To remove a previously-established action handler, call setActionHandler()
again, specifying null
as the callback
.
The action handler receives as input a single parameter: an object which provides both the action type (so the same function can handle multiple action types), as well as data needed in order to perform the action.
This example creates a new media session and assigns action handlers (which don't do anything) to it.
if ('mediaSession' in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: 'Unforgettable',
artist: 'Nat King Cole',
album: 'The Ultimate Collection (Remastered)',
artwork: [
{ src: 'https://dummyimage.com/96x96', sizes: '96x96', type: 'image/png' },
{ src: 'https://dummyimage.com/128x128', sizes: '128x128', type: 'image/png' },
{ src: 'https://dummyimage.com/192x192', sizes: '192x192', type: 'image/png' },
{ src: 'https://dummyimage.com/256x256', sizes: '256x256', type: 'image/png' },
{ src: 'https://dummyimage.com/384x384', sizes: '384x384', type: 'image/png' },
{ src: 'https://dummyimage.com/512x512', sizes: '512x512', type: 'image/png' },
]
});
navigator.mediaSession.setActionHandler('play', function() { });
navigator.mediaSession.setActionHandler('pause', function() { });
navigator.mediaSession.setActionHandler('stop', function() { });
navigator.mediaSession.setActionHandler('seekbackward', function() { });
navigator.mediaSession.setActionHandler('seekforward', function() { });
navigator.mediaSession.setActionHandler('seekto', function() { });
navigator.mediaSession.setActionHandler('previoustrack', function() { });
navigator.mediaSession.setActionHandler('nexttrack', function() { });
navigator.mediaSession.setActionHandler('skipad', function() { });
}
The following example sets up two functions for playing and pausing, then uses them as callbacks with the relevant action handlers.
const actionHandlers = [
[
'play',
async function() {
await audioEl.play();
navigator.mediaSession.playbackState = "playing";
updateStatus(allMeta[index], 'Action: play | Track is playing...')
}
],
[
'pause',
() => {
audioEl.pause();
navigator.mediaSession.playbackState = "paused";
updateStatus(allMeta[index], 'Action: pause | Track has been paused...');
}
],
]
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.`);
}
}
This example uses appropriate action handlers to allow seeking in either direction through the playing media.
let skipTime = 10;
navigator.mediaSession.setActionHandler('seekbackward', evt => {
audio.currentTime = Math.max(audio.currentTime - skipTime, 0);
});
navigator.mediaSession.setActionHandler('seekforward', evt => {
audio.currentTime = Math.min(audio.currentTime + skipTime,
audio.duration);
});
To remove a media action handler, assign it to null.
navigator.mediaSession.setActionHandler('nexttrack', null);
You can also, if you prefer, use a single function to handle multiple action types, by checking the value of the action
property:
let skipTime = 7;
navigator.mediaSession.setActionHandler("seekforward", handleSeek);
navigator.mediaSession.setActionHandler("seekbackward", handleSeek);
function handleSeek(details) {
switch(details.action) {
case "seekforward":
audio.currentTime = Math.min(audio.currentTime + skipTime,
audio.duration);
break;
case "seekbackward":
audio.currentTime = Math.max(audio.currentTime - skipTime, 0);
break;
}
}
Here, the handleSeek()
function handles both seekbackward
and seekforward
actions.