Start · Sprachen · JavaScript · Referenz · MediaSource.duration

MediaSource.duration

Eigenschaft

Liest oder setzt die Gesamtdauer (in Sekunden) des Mediums, das über eine <code>MediaSource</code> an ein <code>&lt;video&gt;</code>- oder <code>&lt;audio&gt;</code>-Element geliefert wird.

seit JavaScript Baseline: alle modernen Desktop-Browser (auf dem i Kategorie: webapi

Signatur

MediaSource.duration

Beschreibung

Die Eigenschaft duration einer MediaSource gibt die Dauer der Präsentation als Gleitkommazahl in Sekunden an. Sie gehört zu den Media Source Extensions (MSE), mit denen sich Mediendaten in einzelnen Stücken per JavaScript in einen Player einspeisen lassen. Das ist z. B. bei adaptivem Streaming (DASH, HLS über hls.js) oder bei selbst gebauten Playern nötig.

Das Setzen von duration ist sinnvoll, wenn die Gesamtlänge schon bekannt ist, bevor alle Segmente geladen sind, etwa aus einem Manifest. Dann zeigt die Fortschrittsleiste des Players sofort die richtige Länge an. Bei Livestreams setzt man den Wert auf Infinity. Jede Änderung wird an HTMLMediaElement.duration weitergegeben und löst am Medienelement das Ereignis durationchange aus.

Lesen ist jederzeit möglich. Solange readyState den Wert "closed" hat, also keine Verbindung zu einem Medienelement besteht, ist das Ergebnis aber NaN. Setzen ist nur erlaubt, wenn readyState auf "open" steht und gerade kein SourceBuffer ein Update verarbeitet (updating === false).

Parameter

Name Typ Default Beschreibung
$value Pflicht number Nur beim Setzen: neue Dauer in Sekunden. Muss eine nicht-negative Zahl sein; Infinity ist erlaubt (Livestream), NaN nicht.

Rückgabewert

Typ
number
Beschreibung
Die aktuelle Dauer in Sekunden als Gleitkommazahl (double). NaN, wenn noch keine Dauer bekannt ist oder die MediaSource geschlossen ist; Infinity bei unbegrenzten Streams.

Beispiele

Dauer nach dem Öffnen der MediaSource setzen

const video = document.querySelector('video');
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);

console.log(mediaSource.duration); // noch geschlossen

mediaSource.addEventListener('sourceopen', () => {
  // Gesamtlänge z. B. aus dem Manifest bekannt
  mediaSource.duration = 596.48;
  console.log('Dauer:', mediaSource.duration);
}, { once: true });

video.addEventListener('durationchange', () => {
  console.log('Player-Dauer:', video.duration);
});
NaN Dauer: 596.48 Player-Dauer: 596.48

Erst auf das Ende eines SourceBuffer-Updates warten

const video = document.querySelector('video');
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);

mediaSource.addEventListener('sourceopen', async () => {
  const mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
  const sb = mediaSource.addSourceBuffer(mime);

  const initSegment = await (await fetch('/media/init.mp4')).arrayBuffer();
  sb.appendBuffer(initSegment);

  // Während sb.updating === true würde das Setzen einen InvalidStateError werfen
  await new Promise((resolve) => sb.addEventListener('updateend', resolve, { once: true }));

  mediaSource.duration = 120;
  console.log(mediaSource.duration);
}, { once: true });
120

Livestream mit unbegrenzter Dauer

const video = document.querySelector('video');
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);

mediaSource.addEventListener('sourceopen', () => {
  mediaSource.duration = Infinity;
  console.log(mediaSource.duration, video.duration);
}, { once: true });
Infinity Infinity

Sicheres Setzen mit Fehlerbehandlung

const setDuration = (mediaSource, seconds) => {
  const busy = [...mediaSource.sourceBuffers].some((sb) => sb.updating);
  if (mediaSource.readyState !== 'open' || busy) {
    console.warn('Dauer kann gerade nicht gesetzt werden');
    return false;
  }
  try {
    mediaSource.duration = seconds;
    return true;
  } catch (err) {
    console.error(err.name, err.message);
    return false;
  }
};

const ms = new MediaSource();
console.log(setDuration(ms, 60)); // readyState ist noch 'closed'
Dauer kann gerade nicht gesetzt werden false

// Wichtig · Fallstricke

  • InvalidStateError: Das Setzen wirft diesen Fehler, wenn readyState nicht "open" ist oder ein SourceBuffer gerade updating === true hat. Warte vorher auf sourceopen bzw. updateend.
  • TypeError: Negative Werte und NaN werden abgelehnt.
  • Kürzen unter bereits gepufferte Daten: Nach der aktuellen Spezifikation wirft das Setzen einen InvalidStateError, wenn der neue Wert kleiner ist als der höchste Präsentationszeitstempel der gepufferten Frames. Solche Daten müssen vorher mit SourceBuffer.remove() entfernt werden. Ältere Browser haben die Daten stattdessen stillschweigend abgeschnitten.
  • MediaSource.endOfStream() passt die Dauer automatisch an das Ende der gepufferten Daten an. Ein manuell gesetzter Wert kann dadurch überschrieben werden.
  • Für Livestreams mit verschiebbarem Suchbereich ist setLiveSeekableRange() meist besser geeignet als eine feste Dauer.
  • Kompatibilität: MSE wird in allen modernen Desktop-Browsern und in Android-Browsern unterstützt. Auf dem iPhone steht MSE erst ab iOS 17.1 zur Verfügung, und zwar als ManagedMediaSource. Prüfe die Unterstützung vorher mit 'MediaSource' in window bzw. MediaSource.isTypeSupported(). In Dedicated Workers ist MSE nur in neueren Browsern nutzbar (z. B. Chrome 108+).