Skip to content

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

TypeScript
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:

TypeScript
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:

TypeScript
{
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:

TypeScript
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):

TypeScript
// 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.