Customizing Safari Playback with the Media Session API
This article explores how the Media Session API in the Safari web browser empowers web developers to customize media playback controls and metadata displayed directly on the iOS Lock Screen, Control Center, and macOS Now Playing widget. By utilizing this JavaScript API, websites can provide a native-like media experience, displaying rich track information such as titles, artists, and album artwork, while simultaneously mapping system-level hardware and software buttons to custom web-based playback actions.
Displaying Custom Metadata
When a user plays audio or video on a webpage in Safari, the operating system attempts to show basic information in the Lock Screen and Control Center. Without the Media Session API, Safari simply displays the webpage's title and URL.
To override this default behavior, websites use the
MediaMetadata interface. By instantiating a new
MediaMetadata object and assigning it to
navigator.mediaSession.metadata, developers can explicitly
define the title, artist, album name, and artwork for the currently
playing media.
if ('mediaSession' in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: 'Episode 1: The Web Audio Revolution',
artist: 'Tech Daily Podcast',
album: 'Season 4',
artwork: [
{ src: 'https://example.com/album-art-512x512.jpg', sizes: '512x512', type: 'image/jpeg' }
]
});
}Safari reads this object and immediately updates the Lock Screen and Control Center interfaces with the provided strings and fetches the specified image URL to display as the thumbnail artwork.
Customizing Playback Controls
Beyond displaying information, the Media Session API allows websites
to dictate which playback buttons appear in the system UI and how they
behave when tapped. This is achieved using the
setActionHandler method on the
navigator.mediaSession object.
Safari supports several action types, including:
playandpauseprevioustrackandnexttrackseekbackwardandseekforwardseekto
When a developer registers an action handler, Safari enables the
corresponding button on the Lock Screen and in the Control Center. If an
action handler is not set (or is set to null), Safari will
either hide that specific control or fall back to default browser
behavior.
Adding Next and Previous Track Buttons
For a music or playlist website, enabling track skipping requires mapping the system buttons to the website's internal playlist logic:
navigator.mediaSession.setActionHandler('previoustrack', () => {
// Custom logic to load and play the previous media file
playPreviousSong();
});
navigator.mediaSession.setActionHandler('nexttrack', () => {
// Custom logic to load and play the next media file
playNextSong();
});Enabling Skip Forward and Backward Buttons
Podcasts and audiobooks typically prefer 10- or 15-second skip
buttons instead of track-skipping buttons. If seekbackward
and seekforward handlers are defined instead of track
handlers, Safari automatically swaps the UI icons on the Lock Screen to
reflect time-skipping controls:
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
const skipTime = details.seekOffset || 15;
audioElement.currentTime = Math.max(audioElement.currentTime - skipTime, 0);
});
navigator.mediaSession.setActionHandler('seekforward', (details) => {
const skipTime = details.seekOffset || 15;
audioElement.currentTime = Math.min(audioElement.currentTime + skipTime, audioElement.duration);
});Synchronizing Timeline and Scrubbing
Safari displays a progress bar in the Lock Screen and Control Center
that allows users to scrub through the media. To ensure this progress
bar accurately reflects the web player's state—especially when playback
speed changes or when custom skipping occurs—developers use the
setPositionState method.
function updatePositionState() {
if ('setPositionState' in navigator.mediaSession) {
navigator.mediaSession.setPositionState({
duration: audioElement.duration,
playbackRate: audioElement.playbackRate,
position: audioElement.currentTime
});
}
}To allow the user to drag the playhead on the Lock Screen to a new
time, the seekto action handler must also be
implemented:
navigator.mediaSession.setActionHandler('seekto', (details) => {
if (details.fastSeek && 'fastSeek' in audioElement) {
audioElement.fastSeek(details.seekTime);
return;
}
audioElement.currentTime = details.seekTime;
updatePositionState();
});Safari-Specific Requirements
For the Media Session API to successfully take control of the Lock
Screen and Control Center in Safari, the webpage must actively be
playing media through a standard HTML <audio> or
<video> element, or via the Web Audio API. Safari
requires a user gesture (like a tap or click) to initiate the playback
first. Once the audio stream is active, Safari grants the webpage
permission to populate the system-level media controls with the defined
metadata and action handlers. Additionally, because the API integrates
directly with Apple's native "Now Playing" architecture, any
customizations made for the Lock Screen and Control Center automatically
extend to connected devices, including AirPods, CarPlay, and the Apple
Watch.