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", () => {
});
navigator.mediaSession.setActionHandler("pause", () => {
});
navigator.mediaSession.setActionHandler("stop", () => {
});
navigator.mediaSession.setActionHandler("seekbackward", () => {
});
navigator.mediaSession.setActionHandler("seekforward", () => {
});
navigator.mediaSession.setActionHandler("seekto", () => {
});
navigator.mediaSession.setActionHandler("previoustrack", () => {
});
navigator.mediaSession.setActionHandler("nexttrack", () => {
});
navigator.mediaSession.setActionHandler("skipad", () => {
});
}
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 () => {
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.
The "previousslide"
and "nextslide"
action handlers can be used to handle moving forward and backward through a slide presentation, for example when the user puts their presentation into a Picture-in-Picture window, and presses the browser-supplied controls for navigating through slides.
try {
navigator.mediaSession.setActionHandler("previousslide", () => {
log('> User clicked "Previous Slide" icon.');
if (slideNumber > 1) slideNumber--;
updateSlide();
});
} catch (error) {
log('Warning! The "previousslide" media session action is not supported.');
}
try {
navigator.mediaSession.setActionHandler("nextslide", () => {
log('> User clicked "Next Slide" icon.');
slideNumber++;
updateSlide();
});
} catch (error) {
log('Warning! The "nextslide" media session action is not supported.');
}
See Presenting Slides / Media Session Sample for a working example.