Start · Sprachen · JavaScript · Referenz · MediaSession.setPositionState()

MediaSession.setPositionState()

Methode

Meldet dem Browser Dauer, aktuelle Position und Wiedergabegeschwindigkeit der Medien. Damit kann er Fortschrittsanzeigen in Sperrbildschirm, Benachrichtigungen und Mediensteuerungen darstellen.

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

Signatur

MediaSession.prototype.setPositionState(stateDict)

Beschreibung

Mit navigator.mediaSession.setPositionState() teilst du der Benutzerumgebung (Browser, Betriebssystem, Sperrbildschirm, Bluetooth-Geräte, Smartwatch) mit, wie lang das aktuelle Medium ist, an welcher Stelle die Wiedergabe gerade steht und wie schnell abgespielt wird. Aus diesen Angaben berechnet der Browser die Position laufend selbst weiter. Du musst die Methode also nicht bei jedem timeupdate aufrufen, sondern nur, wenn sich der Zustand sprunghaft ändert.

Sinnvolle Zeitpunkte für einen Aufruf sind:

  • Laden neuer Metadaten (loadedmetadata), also wenn die Dauer bekannt wird,
  • Springen in der Zeitleiste (seeked, Aktionen seekto, seekforward, seekbackward),
  • Änderung der Wiedergabegeschwindigkeit (ratechange),
  • Pause und Fortsetzen, wenn der Browser den Zustand über MediaSession.playbackState nicht selbst erkennt.

Rufst du die Methode ohne Argument auf, wird der gespeicherte Positionszustand gelöscht. Dann verschwindet zum Beispiel die Fortschrittsleiste in der Systembenachrichtigung. Das ist nützlich, wenn ein Medium entladen wird oder ein Livestream beginnt.

Besonders wichtig ist die Methode bei eigenen Playern, die nicht direkt auf einem <audio>- oder <video>-Element beruhen, etwa bei Wiedergabe über die Web Audio API oder Media Source Extensions mit eigener Logik. Hier kann der Browser die Position nicht selbst ermitteln.

Parameter

Name Typ Default Beschreibung
$stateDict MediaPositionState | undefined Objekt mit dem Positionszustand. Fehlt es, wird der Positionszustand gelöscht.
$stateDict.duration number Gesamtdauer des Mediums in Sekunden. Muss ≥ 0 sein. Für Livestreams ohne Ende ist Infinity erlaubt. Ohne Angabe von stateDict Pflicht, sonst entsteht ein TypeError.
$stateDict.playbackRate number 1.0 Wiedergabegeschwindigkeit. Darf nicht 0 sein. Negative Werte bedeuten Rückwärtswiedergabe. Bei Pause bleibt der Wert erhalten; die Pause wird über playbackState gemeldet.
$stateDict.position number 0 Aktuelle Wiedergabeposition in Sekunden. Muss zwischen 0 und duration liegen.

Rückgabewert

Typ
void
Beschreibung
Gibt undefined zurück. Bei ungültigen Werten wird ein TypeError ausgelöst.

Beispiele

Position eines Audio-Elements an die Mediensteuerung melden

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

const updatePositionState = () => {
  if (!('mediaSession' in navigator)) return;
  // Dauer ist erst nach loadedmetadata bekannt
  if (!Number.isFinite(audio.duration)) return;

  navigator.mediaSession.setPositionState({
    duration: audio.duration,
    playbackRate: audio.playbackRate,
    position: audio.currentTime,
  });
};

// Nur bei sprunghaften Änderungen aktualisieren, nicht bei timeupdate
audio.addEventListener('loadedmetadata', updatePositionState);
audio.addEventListener('seeked', updatePositionState);
audio.addEventListener('ratechange', updatePositionState);
audio.addEventListener('play', updatePositionState);
audio.addEventListener('pause', updatePositionState);

Spulen-Aktionen der Systemsteuerung behandeln

const video = document.querySelector('video');
const SKIP = 10; // Sekunden

const syncPosition = () => {
  navigator.mediaSession.setPositionState({
    duration: video.duration,
    playbackRate: video.playbackRate,
    position: video.currentTime,
  });
};

navigator.mediaSession.setActionHandler('seekbackward', (details) => {
  video.currentTime = Math.max(video.currentTime - (details.seekOffset ?? SKIP), 0);
  syncPosition();
});

navigator.mediaSession.setActionHandler('seekforward', (details) => {
  video.currentTime = Math.min(video.currentTime + (details.seekOffset ?? SKIP), video.duration);
  syncPosition();
});

navigator.mediaSession.setActionHandler('seekto', (details) => {
  if (details.fastSeek && 'fastSeek' in video) {
    video.fastSeek(details.seekTime);
  } else {
    video.currentTime = details.seekTime;
  }
  syncPosition();
});

Positionszustand beim Trackwechsel oder Livestream löschen

const startLivestream = async (audio, url) => {
  audio.src = url;
  await audio.play();

  // Ohne Argument aufgerufen: Die Fortschrittsleiste in der Systembenachrichtigung verschwindet
  navigator.mediaSession.setPositionState();

  navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Radio Live',
    artist: 'Sender XY',
  });
};

Ungültige Werte abfangen

try {
  navigator.mediaSession.setPositionState({
    duration: 120,
    position: 150, // größer als duration
  });
} catch (err) {
  console.log(err.name);
}
TypeError

// Wichtig · Fallstricke

Validierung: Es wird ein TypeError ausgelöst, wenn duration fehlt oder negativ bzw. NaN ist, wenn position negativ oder größer als duration ist oder wenn playbackRate gleich 0 ist. Vor dem Laden der Metadaten ist audio.duration gleich NaN. Prüfe den Wert deshalb vorher mit Number.isFinite() oder warte auf loadedmetadata.

Pause: Setze bei einer Pause nicht playbackRate: 0, denn das löst einen Fehler aus. Melde die Pause stattdessen mit navigator.mediaSession.playbackState = 'paused'.

Leistung: Rufe die Methode nicht im timeupdate-Handler auf. Der Browser schreibt die Position anhand von playbackRate selbst fort.

Kompatibilität: Die Methode wird von Chrome/Edge ab 81, Firefox ab 82 und Safari ab 15 unterstützt. Prüfe vorher mit 'mediaSession' in navigator && 'setPositionState' in navigator.mediaSession. Die Darstellung hängt vom Betriebssystem ab: Auf Desktop-Systemen wird die Position teils gar nicht angezeigt. Die API ist nur in sicheren Kontexten (HTTPS) verfügbar.