Start · Sprachen · JavaScript · Referenz · HTMLMediaElement.seekable

HTMLMediaElement.seekable

Eigenschaft

Gibt ein neues, statisches und normalisiertes <code>TimeRanges</code>-Objekt mit den Zeitbereichen zurück, zu denen der Nutzer im Medium springen kann.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

get HTMLMediaElement.seekable

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

Typ
TimeRanges
Beschreibung
Ein neues 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`);
  }
});
Bereich 0: 0.0s – 596.5s

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 });
z. B. 245.3

„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.seekable jedes Mal neu lesen. Außerdem gilt video.seekable !== video.seekable.
  • Indexfehler: Wenn start(i) oder end(i) mit einem ungültigen Index aufgerufen wird, wirft das einen IndexSizeError (DOMException). Deshalb vorher immer length prüfen, besonders vor loadedmetadata.
  • Server-Unterstützung: Wenn der Server keine HTTP-Range-Requests unterstützt (Accept-Ranges: bytes), kann seekable je nach Browser leer sein oder nur den bereits geladenen Teil enthalten.
  • Nicht mit buffered verwechseln: buffered zeigt, was schon heruntergeladen wurde. seekable zeigt, wohin man springen kann, auch wenn die Daten erst noch geladen werden müssen.
  • Livestreams: duration ist dort oft Infinity. Für die Fortschrittsleiste sollte man deshalb seekable.start() und seekable.end() verwenden.
  • Die Eigenschaft wird von allen modernen Browsern unterstützt. In Safari auf iOS kann seekable bei nativem HLS vom Verhalten anderer Browser abweichen.