Signatur
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
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);
});
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 });
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 });
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'
// Wichtig · Fallstricke
- InvalidStateError: Das Setzen wirft diesen Fehler, wenn
readyStatenicht"open"ist oder einSourceBuffergeradeupdating === truehat. Warte vorher aufsourceopenbzw.updateend. - TypeError: Negative Werte und
NaNwerden 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 mitSourceBuffer.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 windowbzw.MediaSource.isTypeSupported(). In Dedicated Workers ist MSE nur in neueren Browsern nutzbar (z. B. Chrome 108+).