Media Session
Lock-screen controls, browser media notification widgets, and hardware media key support.
Both the video and music players support this via MediaSessionPlugin.
The Media Session API is a browser standard that exposes playback controls to the OS: Android lock screen, iOS Control Center, Windows system tray, desktop browser toolbars, and hardware media keys (keyboards, headsets, remotes).
Basic setup
import { nmMPlayer } from '@nomercy-entertainment/nomercy-music-player';
import { MediaSessionPlugin } from '@nomercy-entertainment/nomercy-player-core/plugins/media-session';
const player = nmMPlayer('main').setup({
baseUrl: 'https://raw.githubusercontent.com/NoMercy-Entertainment/nomercy-media/master/Music',
playlist: [
{
id: '1',
name: 'Thaw You Out',
artist: 'Derek Clegg',
album: 'KJC',
url: '/D/Derek%20Clegg/%5B2010%5D%20KJC/01%20Thaw%20You%20Out.mp3',
},
],
});
// MediaSessionPlugin wires all transport actions and metadata automatically
player.addPlugin(MediaSessionPlugin);
await player.ready();
await player.play();
That is all that is needed.
The plugin reads title, artist, album, and artwork (image / poster / thumbnail / cover) from the current queue item and writes them to navigator.mediaSession.metadata (the music library maps its name field to title at the library layer).
It wires play, pause, previoustrack, nexttrack, seekbackward, seekforward, seekto, and stop action handlers.
Video player
The setup is identical for the video player:
import { nmplayer } from '@nomercy-entertainment/nomercy-video-player';
import { MediaSessionPlugin } from '@nomercy-entertainment/nomercy-player-core/plugins/media-session';
const player = nmplayer('main').setup({
baseUrl: 'https://raw.githubusercontent.com/NoMercy-Entertainment/nomercy-media/master/Films',
playlist: [
{
id: '1',
title: 'Episode 1',
url: '/Sintel.(2010)/Sintel.(2010).NoMercy.m3u8',
poster: 'https://image.tmdb.org/t/p/w780/q2bVM5z90tCGbmXYtq2J38T5hSX.jpg',
},
],
});
player.addPlugin(MediaSessionPlugin);
For video, the plugin reads title and poster from the item.
Multiple artwork sizes
Browsers prefer the largest artwork that fits the display. Provide multiple sizes for the best result:
{
id: '1',
name: 'Track One',
artwork: [
{ src: '/art/1-96.jpg', sizes: '96x96', type: 'image/jpeg' },
{ src: '/art/1-256.jpg', sizes: '256x256', type: 'image/jpeg' },
{ src: '/art/1-512.jpg', sizes: '512x512', type: 'image/jpeg' },
],
}
When artwork is a string (single URL), the plugin wraps it in a single-entry array with sizes: '512x512'.
Customizing metadata
Override how the plugin builds MediaMetadata by subclassing:
import { MediaSessionPlugin } from '@nomercy-entertainment/nomercy-player-core/plugins/media-session';
import type { MediaSessionMetadata } from '@nomercy-entertainment/nomercy-player-core/plugins/media-session';
import type { MusicPlaylistItem } from '@nomercy-entertainment/nomercy-music-player';
// year is a consumer-defined field — extend MusicPlaylistItem with your own fields.
interface MyTrack extends MusicPlaylistItem {
year?: number;
}
class MyMediaSession extends MediaSessionPlugin {
static readonly id = 'media-session'; // same id = replaces built-in
protected getMetadata(item: MyTrack): MediaSessionMetadata {
return {
title: item.name,
artist: item.artist ?? 'Unknown Artist',
// Add the year to the album field
album: item.album ? `${item.album} (${item.year ?? ''})` : '',
};
}
}
player.addPlugin(MyMediaSession);
Observing media key actions
If you need to respond to media key presses independently (e.g. for analytics):
// MediaSessionPlugin routes OS media-key handlers straight to transport
// methods; observe the resulting player events rather than a plugin event:
player.on('play', () => analytics.track('media-key', { action: 'play' }));
player.on('pause', () => analytics.track('media-key', { action: 'pause' }));
player.on('next', () => analytics.track('media-key', { action: 'next' }));
Browser support
The Media Session API is available in Chrome 73+, Firefox 82+, Safari 15+, and Edge 79+.
On unsupported browsers, MediaSessionPlugin detects the absence of navigator.mediaSession at use() time and self-disables gracefully, no errors thrown.
What to read next
- Recipes: Keyboard Shortcuts, pairing media key handling with custom keyboard bindings
- Recipes: Persistence, saving playback position so resuming from lock screen continues from the right point
- Music: API Methods,
current(),peekNext(),artworkfield reference