Signatur
Beschreibung
Die nur lesbare Eigenschaft seekable eines <audio>- oder <video>-Elements beschreibt, zu welchen Zeitpunkten (in Sekunden) der Browser per currentTime oder fastSeek() springen kann. Das Ergebnis ist ein TimeRanges-Objekt mit length sowie den Methoden start(index) und end(index).
Bei normalen Dateien, die der Server mit HTTP-Range-Requests ausliefert, umfasst seekable meist das ganze Medium von 0 bis duration. Bei Livestreams (HLS, DASH über Media Source Extensions) ist der Bereich dagegen ein „gleitendes Fenster“: Man kann nur innerhalb des DVR-Puffers springen. Deshalb eignet sich die Eigenschaft gut, um Fortschrittsleisten zu begrenzen, „Live“-Schaltflächen zu bauen oder Sprungziele zu prüfen.
Das Objekt ist statisch: Es ist eine Momentaufnahme und wird später nicht aktualisiert. Wer den aktuellen Stand braucht, muss seekable erneut lesen, zum Beispiel in den Events progress, durationchange oder loadedmetadata. Normalisiert bedeutet, dass die Bereiche sortiert sind, sich nicht überlappen und aneinandergrenzende Bereiche zusammengefasst werden.
Rückgabewert
TimeRanges-Objekt mit den Bereichen, zu denen man springen kann (Start- und Endzeit in Sekunden). Solange keine Metadaten geladen sind, ist length gleich 0.Beispiele
Springbare Bereiche ausgeben
const video = document.querySelector('video');
video.addEventListener('loadedmetadata', () => {
const ranges = video.seekable;
for (let i = 0; i < ranges.length; i++) {
console.log(`Bereich ${i}: ${ranges.start(i).toFixed(1)}s – ${ranges.end(i).toFixed(1)}s`);
}
});
Sicher springen: Ziel auf den erlaubten Bereich begrenzen
const seekSafely = (media, target) => {
const { seekable } = media;
if (seekable.length === 0) return false; // noch nichts springbar
const start = seekable.start(0);
const end = seekable.end(seekable.length - 1);
media.currentTime = Math.min(Math.max(target, start), end);
return true;
};
const audio = document.querySelector('audio');
audio.addEventListener('canplay', () => {
seekSafely(audio, 9999); // springt höchstens bis zum Ende
console.log(audio.currentTime);
}, { once: true });
„Zurück zu Live“-Schaltfläche für Livestreams
const video = document.querySelector('#live');
const liveBtn = document.querySelector('#go-live');
liveBtn.addEventListener('click', () => {
const { seekable } = video;
if (seekable.length > 0) {
// An den Rand des Live-Fensters springen, knapp vor dem Ende
const liveEdge = seekable.end(seekable.length - 1);
video.currentTime = liveEdge - 1;
video.play();
}
});
// Anzeigen, ob man hinter dem Live-Stand zurückliegt
video.addEventListener('timeupdate', () => {
const { seekable } = video;
if (!seekable.length) return;
const behind = seekable.end(seekable.length - 1) - video.currentTime;
liveBtn.hidden = behind < 5;
});
// Wichtig · Fallstricke
- Statische Momentaufnahme: Jeder Zugriff gibt ein neues Objekt zurück. Eine gespeicherte Referenz wird nicht aktualisiert, also
video.seekablejedes Mal neu lesen. Außerdem giltvideo.seekable !== video.seekable. - Indexfehler: Wenn
start(i)oderend(i)mit einem ungültigen Index aufgerufen wird, wirft das einenIndexSizeError(DOMException). Deshalb vorher immerlengthprüfen, besonders vorloadedmetadata. - Server-Unterstützung: Wenn der Server keine HTTP-Range-Requests unterstützt (
Accept-Ranges: bytes), kannseekableje nach Browser leer sein oder nur den bereits geladenen Teil enthalten. - Nicht mit
bufferedverwechseln:bufferedzeigt, was schon heruntergeladen wurde.seekablezeigt, wohin man springen kann, auch wenn die Daten erst noch geladen werden müssen. - Livestreams:
durationist dort oftInfinity. Für die Fortschrittsleiste sollte man deshalbseekable.start()undseekable.end()verwenden. - Die Eigenschaft wird von allen modernen Browsern unterstützt. In Safari auf iOS kann
seekablebei nativem HLS vom Verhalten anderer Browser abweichen.