Signatur
Beschreibung
Das Ereignis cuechange wird an einem TextTrack-Objekt ausgelöst, sobald sich dessen Liste activeCues ändert. Das passiert, wenn während der Wiedergabe ein Cue aktiv wird (seine startTime ist erreicht), ein Cue endet (endTime ist überschritten) oder beim Springen (Seeking) ein anderer Satz von Cues gültig wird.
Registrieren lässt sich ein Handler über textTrack.addEventListener("cuechange", handler) oder über die Eigenschaft textTrack.oncuechange. Zusätzlich feuert das Ereignis auch am zugehörigen <track>-Element (HTMLTrackElement), sofern der Track über ein solches Element eingebunden wurde. Das Ereignis ist ein einfaches Event ohne zusätzliche Eigenschaften; es blubbert nicht und ist nicht abbrechbar.
Typische Einsatzzwecke: eigene Untertitel-Darstellung außerhalb des Videos, Transkripte mit Hervorhebung der aktuellen Zeile, Kapitelanzeigen oder synchronisierte Aktionen über metadata-Tracks (z. B. Einblenden von Zusatzinfos zu einem bestimmten Zeitpunkt).
Wichtig: Das Ereignis wird nur ausgelöst, wenn der Track im Modus "showing" oder "hidden" ist. Im Modus "disabled" (Standard für nicht-default Tracks) werden keine Cues aktiv und damit auch keine cuechange-Ereignisse gefeuert.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignistyp, hier immer "cuechange". |
|
| $handler Pflicht | (event: Event) => void | Callback, der bei jeder Änderung von activeCues aufgerufen wird. event.target ist der TextTrack (bzw. das <track>-Element). |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once oder signal (zum Entfernen per AbortController). |
Rückgabewert
addEventListener gibt nichts zurück. Die aktuellen Cues liest man im Handler über track.activeCues (TextTrackCueList oder null).Beispiele
Untertitel in eigenem Container anzeigen
const video = document.querySelector('video');
const box = document.querySelector('#untertitel');
const track = video.textTracks[0];
// 'hidden': Cues werden aktiv, aber nicht nativ gerendert
track.mode = 'hidden';
track.addEventListener('cuechange', () => {
const cues = track.activeCues;
box.textContent = cues && cues.length
? Array.from(cues, (cue) => cue.text).join('\n')
: '';
});
Handler über oncuechange setzen und wieder entfernen
const track = document.querySelector('video').textTracks[0];
track.mode = 'hidden';
track.oncuechange = (event) => {
const count = event.target.activeCues?.length ?? 0;
console.log(`Aktive Cues: ${count}`);
};
// Später: Handler wieder entfernen
setTimeout(() => {
track.oncuechange = null;
}, 30_000);
Metadaten-Track per Skript anlegen und mit AbortController abmelden
const video = document.querySelector('video');
const meta = video.addTextTrack('metadata', 'Ereignisse');
meta.mode = 'hidden';
meta.addCue(new VTTCue(5, 10, JSON.stringify({ produkt: 'Kamera X' })));
meta.addCue(new VTTCue(15, 20, JSON.stringify({ produkt: 'Objektiv Y' })));
const controller = new AbortController();
meta.addEventListener('cuechange', () => {
for (const cue of meta.activeCues ?? []) {
const daten = JSON.parse(cue.text);
console.log('Einblenden:', daten.produkt);
}
}, { signal: controller.signal });
// Listener entfernen, wenn das Video endet
video.addEventListener('ended', () => controller.abort(), { once: true });
Ereignis am <track>-Element abfangen
const trackEl = document.querySelector('track[kind="chapters"]');
trackEl.track.mode = 'hidden';
trackEl.addEventListener('cuechange', () => {
const kapitel = trackEl.track.activeCues?.[0];
if (kapitel) {
document.querySelector('#kapitel').textContent = kapitel.text;
}
});
// Wichtig · Fallstricke
- Modus beachten: Bei
track.mode === "disabled"wirdcuechangenie ausgelöst. Für eigene Darstellung"hidden"verwenden, sonst rendert der Browser die Untertitel zusätzlich nativ. - Das Ereignis enthält keine Information darüber, welche Cues hinzukamen oder wegfielen – man muss
activeCuesselbst auswerten oderenter/exitan einzelnenVTTCue-Objekten nutzen. activeCueskannnullsein (z. B. bei deaktiviertem Track) – immer absichern (?.,?? []).- Das Ereignis feuert auch, wenn keine Cues mehr aktiv sind; leere Listen also gezielt behandeln (z. B. Anzeige leeren).
- Die Auslösung ist an die Zeitaktualisierung der Wiedergabe gekoppelt und daher nicht millisekundengenau; für präzise Synchronisation nicht allein darauf verlassen.
- Externe
.vtt-Dateien von fremden Ursprüngen erfordern CORS und das Attributcrossoriginam<video>-Element, sonst lädt der Track nicht. - Cue-Texte beim Einfügen ins DOM über
textContentstattinnerHTMLsetzen, um XSS durch manipulierte Untertiteldateien zu vermeiden. - Browser-Unterstützung: in allen modernen Browsern (Chrome, Edge, Firefox, Safari) seit Langem verfügbar.