Signatur
Beschreibung
Die Methode end() der Schnittstelle TimeRanges liefert den Zeitversatz in Sekunden, an dem ein bestimmtes Zeitintervall endet. TimeRanges-Objekte erhält man von Medienelementen (<audio>, <video>) über die Eigenschaften buffered, played und seekable, außerdem von SourceBuffer.buffered (Media Source Extensions).
Ein TimeRanges-Objekt enthält null oder mehr nicht überlappende, zeitlich sortierte Intervalle. Deren Anzahl steht in length; den Startzeitpunkt eines Intervalls liefert start(index), den Endzeitpunkt end(index). Typische Anwendungen sind Fortschrittsbalken für den Pufferstand, die Frage „bis wohin kann ohne Nachladen abgespielt werden?“ oder das Ermitteln des spätesten ansteuerbaren Zeitpunkts bei Livestreams.
Wichtig: Die Objekte sind Momentaufnahmen. Sie werden nicht automatisch aktualisiert. Man sollte video.buffered daher bei jedem Bedarf neu abfragen, etwa im progress- oder timeupdate-Event.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $index Pflicht | number | Nullbasierter Index des Zeitintervalls, dessen Endzeitpunkt zurückgegeben werden soll. Er muss im Bereich 0 bis length - 1 liegen. Der Wert wird zu einem vorzeichenlosen Ganzzahlwert (unsigned long) konvertiert. |
Rückgabewert
double) relativ zum Anfang der Medienzeitachse. Bei unbegrenzten Livestreams kann seekable.end() auch Infinity liefern.Beispiele
Alle gepufferten Bereiche eines Videos ausgeben
const video = document.querySelector('video');
video.addEventListener('progress', () => {
const { buffered } = video;
for (let i = 0; i < buffered.length; i++) {
console.log(`Bereich ${i}: ${buffered.start(i).toFixed(1)}s – ${buffered.end(i).toFixed(1)}s`);
}
});
Pufferstand relativ zur aktuellen Position für einen Fortschrittsbalken
const video = document.querySelector('video');
const bar = document.querySelector('#buffer-bar');
// Liefert das Ende des Bereichs, der die aktuelle Position enthält
const bufferedAhead = (media) => {
const { buffered, currentTime } = media;
for (let i = 0; i < buffered.length; i++) {
if (buffered.start(i) <= currentTime && currentTime <= buffered.end(i)) {
return buffered.end(i);
}
}
return currentTime;
};
video.addEventListener('progress', () => {
if (!Number.isFinite(video.duration)) return;
const percent = (bufferedAhead(video) / video.duration) * 100;
bar.style.width = `${percent}%`;
console.log(`Gepuffert bis ${percent.toFixed(0)} %`);
});
Zum Live-Rand eines Streams springen
const video = document.querySelector('video');
const jumpToLive = () => {
const { seekable } = video;
if (seekable.length === 0) return; // noch nichts ansteuerbar
const liveEdge = seekable.end(seekable.length - 1);
video.currentTime = Math.max(0, liveEdge - 2); // 2 s Sicherheitsabstand
console.log(`Springe zu ${video.currentTime.toFixed(1)}s`);
};
document.querySelector('#live-btn').addEventListener('click', jumpToLive);
Fehlerfall: ungültiger Index
const video = document.createElement('video');
try {
// Ohne geladene Quelle ist buffered.length === 0
video.buffered.end(0);
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Index prüfen: Ist
indexgrößer oder gleichlength, wirft die Methode eineDOMExceptionvom TypIndexSizeError. Vor dem Zugriff immerlength > 0prüfen, besonders direkt nach dem Laden, wenn noch nichts gepuffert ist. - Nicht zusammenhängend: Nach einem Sprung (Seek) können mehrere getrennte Bereiche entstehen.
buffered.end(0)ist also nicht unbedingt der für die aktuelle Position relevante Wert. Suche den Bereich, dercurrentTimeenthält. - Momentaufnahme: Ein gespeichertes
TimeRanges-Objekt ändert sich nicht. Frage die Eigenschaft bei Bedarf neu ab. - Livestreams:
durationkannInfinitysein. Bei Berechnungen in Prozent vorher mitNumber.isFinite()absichern. - Kompatibilität: Wird von allen modernen Browsern unterstützt. Bei MSE-Streams gibt es kleine Unterschiede in der Granularität von
SourceBuffer.buffered, weil die Browser Lücken unterschiedlich zusammenfassen.