Start · Sprachen · JavaScript · Referenz · TextTrack: cuechange

TextTrack: cuechange

Ereignis

Wird ausgelöst, wenn sich die Menge der aktiven Cues eines <code>TextTrack</code> ändert – also ein Untertitel, Kapitel oder Metadaten-Cue beginnt oder endet.

seit JavaScript Baseline: alle modernen Browser Kategorie: webapi

Signatur

textTrack.addEventListener("cuechange", handler)

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

Typ
void
Beschreibung
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);
Aktive Cues: 1 Aktive Cues: 0 Aktive Cues: 1

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 });
Einblenden: Kamera X Einblenden: Objektiv Y

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" wird cuechange nie 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 activeCues selbst auswerten oder enter/exit an einzelnen VTTCue-Objekten nutzen.
  • activeCues kann null sein (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 Attribut crossorigin am <video>-Element, sonst lädt der Track nicht.
  • Cue-Texte beim Einfügen ins DOM über textContent statt innerHTML setzen, um XSS durch manipulierte Untertiteldateien zu vermeiden.
  • Browser-Unterstützung: in allen modernen Browsern (Chrome, Edge, Firefox, Safari) seit Langem verfügbar.