Start · Sprachen · JavaScript · Referenz · MediaSession

MediaSession

Schnittstelle

Über <code>MediaSession</code> meldet eine Webseite dem Betriebssystem Metadaten zur Wiedergabe und legt eigene Handler für Medientasten, Sperrbildschirm und Benachrichtigungen fest.

seit JavaScript Baseline 2023: Chrome 73+, Edge 79+, Firefox 82+, Kategorie: webapi

Signatur

interface MediaSession

Beschreibung

Die Schnittstelle MediaSession gehört zur Media Session API. Es gibt keinen Konstruktor, die einzige Instanz erreicht man über navigator.mediaSession. Damit teilt eine Webseite dem Browser und dem Betriebssystem mit, was gerade läuft (Titel, Künstler, Album, Cover) und wie die Seite auf Steuerbefehle reagieren soll. Solche Befehle kommen zum Beispiel von Hardware-Medientasten auf der Tastatur, von Bluetooth-Kopfhörern, vom Sperrbildschirm auf Mobilgeräten, von Smartwatches oder aus der Medienübersicht des Systems.

Die wichtigsten Mitglieder sind:

  • metadata: ein MediaMetadata-Objekt oder null. Enthält title, artist, album und artwork.
  • playbackState: "none", "paused" oder "playing". Damit zeigt die Systemoberfläche den richtigen Zustand an, auch wenn die Wiedergabe gar nicht über ein <audio>-Element läuft, sondern etwa über Web Audio.
  • setActionHandler(action, handler): registriert einen Handler für Aktionen wie play, pause, stop, seekbackward, seekforward, seekto, previoustrack, nexttrack und skipad. Für Videokonferenzen gibt es außerdem togglemicrophone, togglecamera, hangup und weitere.
  • setPositionState(state): übergibt Dauer, Wiedergaberate und aktuelle Position, damit das System einen passenden Fortschrittsbalken anzeigen kann.
  • setMicrophoneActive(active) / setCameraActive(active): melden den Zustand von Mikrofon und Kamera bei WebRTC-Anwendungen (bisher nur in Chromium).

Die API lohnt sich für Musik- und Podcast-Player, Videoplattformen, Hörbuch-Apps und Web-Konferenztools, also überall dort, wo sich Nutzer eine Steuerung außerhalb des Browserfensters wünschen. Wer keine Handler setzt, bekommt nur das Standardverhalten des Browsers. Das deckt meist Play und Pause ab, aber zum Beispiel nicht „Nächster Titel“.

Parameter

Name Typ Default Beschreibung
$action Pflicht "play"|"pause"|"stop"|"seekbackward"|"seekforward"|"seekto"|"previoustrack"|"nexttrack"|"skipad"|"togglemicrophone"|"togglecamera"|"hangup"|string Parameter von setActionHandler(): die Medienaktion, für die ein Handler registriert werden soll.
$handler Pflicht ((details: MediaSessionActionDetails) => void) | null Parameter von setActionHandler(): Callback, der ein Objekt mit action und je nach Aktion seekOffset, seekTime oder fastSeek bekommt. Mit null wird der Handler wieder entfernt.
$state { duration?: number, playbackRate?: number, position?: number } Parameter von setPositionState(): Dauer und Position in Sekunden sowie die Wiedergaberate. Ohne Argument wird der Positionszustand gelöscht.

Rückgabewert

Typ
MediaSession
Beschreibung
navigator.mediaSession liefert die einzige MediaSession-Instanz des Dokuments. setActionHandler() und setPositionState() geben undefined zurück.

Beispiele

Metadaten für den Sperrbildschirm setzen

const audio = document.querySelector('audio');

if ('mediaSession' in navigator) {
  navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Morgenroutine',
    artist: 'Podcast programmierung.net',
    album: 'Folge 42',
    artwork: [
      { src: '/cover-96.png', sizes: '96x96', type: 'image/png' },
      { src: '/cover-512.png', sizes: '512x512', type: 'image/png' }
    ]
  });
}

await audio.play();
console.log(navigator.mediaSession.metadata.title);
Morgenroutine

Action-Handler für eine Playlist registrieren

const audio = document.querySelector('audio');
const playlist = ['/a.mp3', '/b.mp3', '/c.mp3'];
let index = 0;

const loadTrack = async (i) => {
  index = (i + playlist.length) % playlist.length;
  audio.src = playlist[index];
  await audio.play();
};

const handlers = {
  play: () => audio.play(),
  pause: () => audio.pause(),
  previoustrack: () => loadTrack(index - 1),
  nexttrack: () => loadTrack(index + 1),
  seekbackward: (d) => { audio.currentTime = Math.max(audio.currentTime - (d.seekOffset ?? 10), 0); },
  seekforward: (d) => { audio.currentTime = Math.min(audio.currentTime + (d.seekOffset ?? 10), audio.duration); },
  seekto: (d) => {
    if (d.fastSeek && 'fastSeek' in audio) audio.fastSeek(d.seekTime);
    else audio.currentTime = d.seekTime;
  }
};

for (const [action, handler] of Object.entries(handlers)) {
  try {
    navigator.mediaSession.setActionHandler(action, handler);
  } catch {
    console.warn(`Aktion "${action}" wird nicht unterstützt.`);
  }
}

Wiedergabestatus und Fortschritt synchron halten

const audio = document.querySelector('audio');
const session = navigator.mediaSession;

const updatePosition = () => {
  if (!Number.isFinite(audio.duration)) return; // z. B. Livestream
  session.setPositionState({
    duration: audio.duration,
    playbackRate: audio.playbackRate,
    position: Math.min(audio.currentTime, audio.duration)
  });
};

audio.addEventListener('play', () => { session.playbackState = 'playing'; });
audio.addEventListener('pause', () => { session.playbackState = 'paused'; });
audio.addEventListener('loadedmetadata', updatePosition);
audio.addEventListener('ratechange', updatePosition);
audio.addEventListener('seeked', updatePosition);

Videokonferenz: Mikrofon über die Systemoberfläche umschalten

const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const [track] = stream.getAudioTracks();

try {
  navigator.mediaSession.setActionHandler('togglemicrophone', () => {
    track.enabled = !track.enabled;
    navigator.mediaSession.setMicrophoneActive(track.enabled);
    console.log('Mikrofon aktiv:', track.enabled);
  });
  navigator.mediaSession.setActionHandler('hangup', () => {
    stream.getTracks().forEach((t) => t.stop());
  });
} catch {
  console.warn('Konferenz-Aktionen werden nicht unterstützt.');
}
Mikrofon aktiv: false