Start · Sprachen · JavaScript · Referenz · VideoTrack

VideoTrack

Schnittstelle

Steht für eine einzelne Videospur eines <code>&lt;video&gt;</code>-Elements, etwa die Hauptansicht, einen anderen Kamerawinkel oder eine Gebärdensprach-Einblendung.

seit JavaScript Nicht Baseline: Safari 7+; Chrome/Edge nur mit Fla Kategorie: webapi

Signatur

interface VideoTrack

Beschreibung

Das Interface VideoTrack steht für eine einzelne Videospur in einer Mediendatei. Eine Datei (z. B. MP4 oder WebM) kann mehrere Videospuren enthalten, zum Beispiel die Hauptansicht, einen anderen Kamerawinkel oder eine Einblendung in Gebärdensprache. Du erzeugst VideoTrack-Objekte nicht selbst. Der Browser legt sie beim Laden der Metadaten an, und du erreichst sie über die Eigenschaft HTMLMediaElement.videoTracks. Sie liefert eine VideoTrackList.

Jede Spur hat nur lesbare Metadaten und eine schreibbare Eigenschaft:

  • id: eindeutige Kennung der Spur innerhalb des Mediums, für VideoTrackList.getTrackById().
  • kind: Art der Spur, z. B. "main", "alternative", "sign", "captions", "subtitles", "commentary" oder "".
  • label: für Menschen lesbarer Name, z. B. für ein Auswahlmenü. Kann leer sein.
  • language: Sprachkennung nach BCP 47 (z. B. "de"). Kann leer sein.
  • selected: true, wenn die Spur gerade angezeigt wird. Diese Eigenschaft kannst du setzen.
  • sourceBuffer: der SourceBuffer, der die Spur erzeugt hat (bei Media Source Extensions), sonst null.

Anders als bei Audiospuren ist immer höchstens eine Videospur ausgewählt. Wenn du selected = true auf eine Spur setzt, hebt der Browser die Auswahl aller anderen Spuren auf. Danach löst die VideoTrackList das Ereignis change aus. So kannst du einen Wechsel des Kamerawinkels ohne Neuladen und ohne Unterbrechung umsetzen.

Rückgabewert

Typ
VideoTrack
Beschreibung
Wird nicht direkt erzeugt. Du bekommst Instanzen über video.videoTracks[i], video.videoTracks.getTrackById(id) oder über event.track im Ereignis addtrack bzw. removetrack.

Beispiele

Videospuren auflisten (mit Funktionsprüfung)

const video = document.querySelector('video');

video.addEventListener('loadedmetadata', () => {
  if (!('videoTracks' in video)) {
    console.warn('VideoTrack-API wird von diesem Browser nicht unterstützt.');
    return;
  }

  for (const track of video.videoTracks) {
    console.log(`${track.id} | ${track.kind} | ${track.label || '(ohne Name)'} | ${track.language || '-'} | ausgewählt: ${track.selected}`);
  }
});
1 | main | Hauptkamera | de | ausgewählt: true 2 | alternative | Tribüne | de | ausgewählt: false

Kamerawinkel über ein Auswahlmenü wechseln

const video = document.querySelector('#match');
const select = document.querySelector('#angle');

video.addEventListener('loadedmetadata', () => {
  if (!video.videoTracks) return;

  for (const track of video.videoTracks) {
    const option = new Option(track.label || `Spur ${track.id}`, track.id, false, track.selected);
    select.append(option);
  }
});

select.addEventListener('change', () => {
  const track = video.videoTracks.getTrackById(select.value);
  // Setzt die Auswahl; alle anderen Spuren werden automatisch abgewählt
  if (track) track.selected = true;
});

video.videoTracks?.addEventListener('change', () => {
  const aktiv = video.videoTracks[video.videoTracks.selectedIndex];
  console.log('Aktive Spur:', aktiv?.label);
});
Aktive Spur: Tribüne

Gebärdensprach-Spur bevorzugen

const bevorzugeSpur = (video, kind) => {
  const tracks = video.videoTracks;
  if (!tracks) return false;

  const treffer = [...tracks].find((t) => t.kind === kind);
  if (treffer) {
    treffer.selected = true;
    return true;
  }
  return false;
};

const video = document.querySelector('video');
video.addEventListener('loadedmetadata', () => {
  const ok = bevorzugeSpur(video, 'sign');
  console.log(ok ? 'Gebärdensprach-Spur aktiv' : 'Keine Gebärdensprach-Spur vorhanden');
});
Gebärdensprach-Spur aktiv

Auf neue Spuren reagieren (addtrack / removetrack)

const video = document.querySelector('video');
const tracks = video.videoTracks;

if (tracks) {
  const onAdd = (event) => console.log('Neue Spur:', event.track.id, event.track.kind);
  tracks.addEventListener('addtrack', onAdd);

  // Alternativ über die on-Eigenschaft
  tracks.onremovetrack = (event) => console.log('Spur entfernt:', event.track.id);

  // Später aufräumen
  video.addEventListener('emptied', () => tracks.removeEventListener('addtrack', onAdd), { once: true });
}
Neue Spur: 1 main

// Wichtig · Fallstricke

Browser-Kompatibilität: Die API ist nicht Baseline. Nur Safari unterstützt sie ohne Einschränkung. In Chrome und Edge brauchst du das Flag „Experimental Web Platform features“, in Firefox die Einstellung media.track.enabled. Prüfe deshalb immer vorher mit 'videoTracks' in video und biete einen Ersatz an, z. B. mehrere Quelldateien oder Adaptive Streaming mit HLS oder DASH über eine Player-Bibliothek.

  • Die Spurliste ist erst nach dem Ereignis loadedmetadata gefüllt. Ein früherer Zugriff liefert meist eine leere Liste.
  • Es ist immer nur eine Videospur ausgewählt. Wenn du selected = false auf die aktive Spur setzt, ist danach keine Spur ausgewählt (selectedIndex === -1) und kein Bild zu sehen.
  • label und language sind oft leer, weil viele Encoder diese Metadaten nicht schreiben. Plane einen Ersatzwert für die Anzeige ein.
  • kind-Werte hängen vom Container-Format ab und werden je nach Browser unterschiedlich zugeordnet.
  • Untertitel gehören zu TextTrack, nicht zu VideoTrack. Nur eingebrannte Untertitel in einer eigenen Videospur tauchen hier auf.