Signatur
Beschreibung
Das Ereignis durationchange wird an einem HTMLMediaElement (also <audio> oder <video>) ausgelöst, wenn die Eigenschaft duration einen neuen Wert bekommt. Das passiert typischerweise beim Laden der Metadaten, wenn der Wert von NaN auf die echte Länge in Sekunden wechselt. Das Ereignis lässt sich weder abbrechen noch steigt es im DOM nach oben (es „bubbelt“ nicht).
Sie können es mit addEventListener("durationchange", handler) abonnieren oder über die Eigenschaft ondurationchange einen Handler setzen. Der Handler bekommt ein gewöhnliches Event-Objekt. Die neue Dauer lesen Sie aus event.target.duration.
Typische Anwendungen sind die Anzeige der Gesamtlänge in eigenen Player-Steuerelementen, die Skalierung von Fortschrittsbalken und der Umgang mit Livestreams oder wachsenden Medien. Bei Streams (z. B. HLS oder MSE) kann sich duration während der Wiedergabe mehrmals ändern oder den Wert Infinity annehmen.
Beim Laden neuer Medien laufen die Ereignisse normalerweise in dieser Reihenfolge ab: loadstart → durationchange → loadedmetadata → loadeddata. Wenn Sie src ändern oder load() aufrufen, wird duration auf NaN zurückgesetzt, und auch das löst ein durationchange aus.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses: "durationchange". |
|
| $handler Pflicht | (event: Event) => void | Funktion, die bei jeder Änderung von duration aufgerufen wird. Sie bekommt ein einfaches Event-Objekt. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, signal oder capture. Das Ereignis bubbelt nicht, deshalb ist capture nur für Handler auf übergeordneten Elementen sinnvoll. |
Beispiele
Gesamtdauer im eigenen Player anzeigen
const video = document.querySelector('video');
const durationLabel = document.querySelector('#duration');
const formatTime = (seconds) => {
if (!Number.isFinite(seconds)) return seconds === Infinity ? 'Live' : '--:--';
const m = Math.floor(seconds / 60);
const s = Math.floor(seconds % 60).toString().padStart(2, '0');
return `${m}:${s}`;
};
video.addEventListener('durationchange', (event) => {
const { duration } = event.target;
durationLabel.textContent = formatTime(duration);
console.log('Neue Dauer:', duration);
});
video.src = 'trailer.mp4';
Fortschrittsbalken an die Dauer anpassen (ondurationchange)
const audio = document.querySelector('audio');
const progress = document.querySelector('input[type=range]');
audio.ondurationchange = () => {
// Bei Livestreams (Infinity) oder unbekannter Dauer (NaN) Slider sperren
const known = Number.isFinite(audio.duration);
progress.disabled = !known;
if (known) progress.max = audio.duration;
};
audio.addEventListener('timeupdate', () => {
progress.value = audio.currentTime;
});
progress.addEventListener('input', () => {
audio.currentTime = Number(progress.value);
});
Listener wieder entfernen
const video = document.querySelector('video');
const logDuration = () => {
console.log(`Dauer: ${video.duration.toFixed(1)} s`);
};
video.addEventListener('durationchange', logDuration);
// Später, z. B. beim Abbau der Player-Komponente:
video.removeEventListener('durationchange', logDuration);
// Alternative: mit AbortController mehrere Listener auf einmal entfernen
const controller = new AbortController();
video.addEventListener('durationchange', logDuration, { signal: controller.signal });
controller.abort();
Auf die Dauer warten (Promise)
const waitForDuration = (media) => new Promise((resolve) => {
if (Number.isFinite(media.duration)) return resolve(media.duration);
const onChange = () => {
if (Number.isFinite(media.duration)) {
media.removeEventListener('durationchange', onChange);
resolve(media.duration);
}
};
media.addEventListener('durationchange', onChange);
});
const audio = new Audio('podcast-folge-12.mp3');
const seconds = await waitForDuration(audio);
console.log(`Folge dauert ${Math.round(seconds / 60)} Minuten`);
// Wichtig · Fallstricke
NaNundInfinity: Bevor die Metadaten geladen sind, istdurationgleichNaN. Bei Livestreams ist der WertInfinity. Prüfen Sie deshalb immer mitNumber.isFinite(), bevor Sie mit dem Wert rechnen.- Mehrfaches Auslösen: Das Ereignis kann mehrmals kommen, zum Beispiel beim Zurücksetzen durch
load()oder einen neuensrc(dann ist der Wert wiederNaN), bei Media Source Extensions überMediaSource.durationoder wenn der Browser die Dauer von VBR-MP3-Dateien nachträglich korrigiert. - Handler zu spät registriert: Wenn das Medium schon geladen ist, bevor der Listener existiert, kommt kein Ereignis mehr an. Lesen Sie daher zusätzlich direkt
media.durationaus oder registrieren Sie den Listener vor dem Setzen vonsrc. - Kein Bubbling: Das Ereignis steigt nicht im DOM nach oben. Eine Delegation über ein Elternelement funktioniert nur mit
{ capture: true }. - WebM/MediaRecorder: Aufnahmen mit
MediaRecorderhaben in Chromium oft keine Dauer in den Metadaten (Infinity). Der echte Wert wird erst nach einem Sprung ans Ende gemeldet, dann ebenfalls perdurationchange. - Kompatibilität: Wird von allen modernen Browsern unterstützt, auch mobil. Die Eigenschaft
ondurationchangegehört zuGlobalEventHandlers.