Signatur
Beschreibung
Über TextTrack.cues greifst du auf alle Cues eines Text-Tracks zu, also auf Untertitel, Kapitelmarken, Beschreibungen oder Metadaten. Der Wert ist eine TextTrackCueList. Sie verhält sich wie ein Array: Es gibt length, Zugriff per Index und getCueById(). Die Cues sind nach Startzeit sortiert.
Wichtig: Die Liste gibt es nur, wenn der Track nicht im Modus "disabled" ist. Solange track.mode === "disabled" gilt, liefert cues den Wert null. Willst du Cues auslesen, ohne dass etwas angezeigt wird, setze den Modus auf "hidden". Dann lädt der Browser die WebVTT-Datei und füllt die Liste.
Typische Einsatzfälle sind ein durchsuchbares Transkript, eine eigene Kapitelnavigation, eine eigene Darstellung der Untertitel oder die Auswertung von Metadaten-Tracks (kind="metadata"). Die Liste ist live: Cues, die du mit addCue() hinzufügst oder mit removeCue() entfernst, erscheinen dort sofort.
Für die Cues, die zur aktuellen Abspielposition gerade aktiv sind, gibt es die Schwester-Eigenschaft TextTrack.activeCues.
Rückgabewert
TextTrackCue-Objekte des Tracks (in der Praxis meist VTTCue), sortiert nach Startzeit. null, wenn der Track im Modus "disabled" ist.Beispiele
Alle Untertitel eines <track>-Elements auslesen
// HTML: <video id="vid" src="film.mp4"><track id="de" kind="subtitles" srclang="de" src="de.vtt"></video>
const trackEl = document.querySelector('#de');
const track = trackEl.track;
// "hidden" lädt die Cues, ohne sie anzuzeigen
track.mode = 'hidden';
trackEl.addEventListener('load', () => {
const cues = track.cues;
console.log(`Anzahl Cues: ${cues.length}`);
for (const cue of cues) {
console.log(`${cue.startTime.toFixed(1)}s – ${cue.endTime.toFixed(1)}s: ${cue.text}`);
}
});
Klickbares Transkript erzeugen
const video = document.querySelector('video');
const track = video.textTracks[0];
track.mode = 'hidden';
const renderTranscript = () => {
const list = document.querySelector('#transcript');
list.replaceChildren();
for (const cue of Array.from(track.cues ?? [])) {
const li = document.createElement('li');
li.textContent = cue.text; // textContent statt innerHTML → kein XSS
li.addEventListener('click', () => {
video.currentTime = cue.startTime;
video.play();
});
list.append(li);
}
};
document.querySelector('track').addEventListener('load', renderTranscript);
Cues per Skript hinzufügen und Live-Liste prüfen
const video = document.querySelector('video');
const track = video.addTextTrack('captions', 'Deutsch', 'de');
console.log(track.cues); // Modus ist anfangs "hidden" → leere Liste
track.addCue(new VTTCue(0, 3, 'Intro'));
track.addCue(new VTTCue(3, 6, 'Kapitel 1'));
console.log(track.cues.length);
track.mode = 'disabled';
console.log(track.cues);
Cue über seine ID finden
const track = document.querySelector('video').textTracks[0];
track.mode = 'hidden';
document.querySelector('track').addEventListener('load', () => {
// In WebVTT steht die ID in der Zeile vor dem Zeitstempel
const cue = track.cues.getCueById('kapitel-2');
if (cue) console.log(`Kapitel 2 beginnt bei ${cue.startTime}s`);
});
// Wichtig · Fallstricke
nullbei deaktiviertem Track: Tracks aus<track>-Elementen ohnedefault-Attribut stehen anfangs auf"disabled". Dann istcuesnull. Setze vorhermode = "hidden"oder"showing". Absichern kannst du dich mittrack.cues ?? [].- Asynchrones Laden: Direkt nach dem Umschalten des Modus ist die Liste oft noch leer. Warte auf das
load-Event des<track>-Elements oder prüfetrackElement.readyState === 2(LOADED). - Kein echtes Array:
TextTrackCueListist iterierbar, hat aber keinmapoderfilter. Wandle sie bei Bedarf mitArray.from()um. - Sicherheit: Der Text eines Cues kann Markup enthalten. Gib ihn per
textContentaus oder nutzeVTTCue.getCueAsHTML(), aber nichtinnerHTML, sonst droht XSS. Bei WebVTT-Dateien von anderen Domains muss am<video>das Attributcrossorigingesetzt sein und der Server CORS erlauben. Sonst lädt der Browser den Track nicht. - Kompatibilität: Wird von allen modernen Browsern unterstützt. Safari stellt Untertitel im nativen Vollbild eventuell selbst dar,
cuesbleibt aber lesbar.