The Media Session API enables web apps to provide a way to interact with media elements (audio, video) without actively being on the web page playing the media.

All you need to achieve this is to provide some metadata, event handlers, plug them to a media element and have rich media experience.

This allows users to know what is playing and gives them the control to manipulate media from other places.

In this article, we’ll explore the API and how it can be used on a website. The current status of the API is draft which means it isn’t a web standard yet so it should be used with caution.

Using the Media Session API

Support for the Media Session API is quite low:

As can be seen from the support table above, only Chrome (Desktop and Mobile), Firefox and Samsung Internet mobile browser has full support so the first thing you should do is a feature detection:

if ('mediaSession' in navigator) { ... }

Once we are sure of support, we can start using it. First, we add some metadata:

navigator.mediaSession.metadata = new MediaMetadata({ title: 'Sample Audio', artist: 'John Doe', album: 'Sample Album', 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' }, ] });

This code creates a new MediaMetadata object. Then we add details of the media like title , artist , album , and artwork which is an array of objects that contains the images that will be displayed in notifications and on the lock screen, in the case of mobile devices.

Once that is set, we can set handlers for different actions the user may want to perform. For example, to play or pause audio:

navigator.mediaSession.setActionHandler("play", function() { … }); navigator.mediaSession.setActionHandler("pause", function() { … });

setActionHandler receives two arguments: a user control eg play, pause, and a function that runs when that control is interacted with by the user.

A Small Music Website

Let’s create a small website. All that we’ll have is one audio element and a button to play the audio. We’ll also have a progress bar that will update as the audio plays. Create a file index.html and add the following:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Media Session</title> <style>p { margin-bottom: 5px; }</style> </head> <body> <h3>Music Player</h3> <p>Sample Music.mp3</p> <progress value="0" max="100"></progress> <br> <audio> <source src="sample.mp3" type="audio/mpeg"> Your browser does not support the audio element </audio> <button id="playBtn">Play song</button> </body> </html>

In our script main.js , we get a reference to the audio and the button. Then add an event listener to the button, where we’ll set up the media session.

playBtn.addEventListener('click', function(e) { // User interacted with the page. Let's play audio... audio.play() .then(_ => { if ('mediaSession' in navigator) { navigator.mediaSession.metadata = new MediaMetadata({ title: 'Sample Audio', artist: 'John Doe', album: 'Sample Album', 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() { audio.play(); }); navigator.mediaSession.setActionHandler(pause, function() { audio.pause(); }); }) .catch(error => { console.log(error) }); // update progress bar audio.addEventListener('timeupdate', function(e) { progress.value = (audio.currentTime / audio.duration) * 100; }); });

Here we use the code explained in the previous section. To update the progress bar, we set an event listener on the audio element for timeupdate . The event is triggered when the playback position changes. We do some maths to get the percentage and update the progress bar’s value.

screenshot of music website

lock screen on mobile

Conclusion

In this tutorial, we looked at the Media Session API and it can be used to deliver a native media experience. Even though still in draft, the Media Session API looks promising and it’s another step towards bringing the web closer to native.