Start · Sprachen · JavaScript · Referenz · MediaStreamTrack

MediaStreamTrack

Schnittstelle

Stellt eine einzelne Audio- oder Videospur innerhalb eines <code>MediaStream</code> dar, etwa das Mikrofon-Signal oder das Kamerabild.

seit JavaScript Baseline: alle modernen Browser (Chrome, Edge, Fir Kategorie: webapi

Signatur

interface MediaStreamTrack extends EventTarget

Beschreibung

MediaStreamTrack gehört zur Media Capture and Streams API und steht für genau eine Medienspur, also Audio oder Video. Tracks bekommt man meist über MediaStream.getTracks(), getAudioTracks() oder getVideoTracks(), nachdem man mit navigator.mediaDevices.getUserMedia() oder getDisplayMedia() einen Stream angefordert hat. Auch WebRTC (RTCPeerConnection) und HTMLCanvasElement.captureStream() liefern Tracks.

Wichtige Eigenschaften sind kind ("audio" oder "video"), id, label (Gerätename), enabled (Spur stumm oder schwarz schalten, ohne die Aufnahme zu beenden), muted (nur lesbar, Stummschaltung durch Quelle oder System), readyState ("live" oder "ended") und contentHint.

Die wichtigsten Methoden sind:

  • stop() beendet die Spur endgültig und gibt das Gerät frei. Danach erlischt die Kamera-LED.
  • clone() legt eine unabhängige Kopie der Spur an.
  • getSettings(), getConstraints() und getCapabilities() lesen die aktuellen Einstellungen, Vorgaben und Gerätefähigkeiten aus.
  • applyConstraints(constraints) ändert Auflösung, Bildrate oder Audio-Verarbeitung zur Laufzeit und gibt ein Promise<void> zurück.

Die Events sind ended, mute und unmute. Man kann sie per addEventListener() oder über onended, onmute und onunmute abonnieren. Einen öffentlichen Konstruktor gibt es nicht. Tracks entstehen immer über eine API, die Medien liefert.

Parameter

Name Typ Default Beschreibung
$constraints MediaTrackConstraints {} Nur für applyConstraints(). Objekt mit Vorgaben wie width, height, frameRate, facingMode, echoCancellation oder noiseSuppression. Möglich sind feste Werte, { ideal, min, max, exact } und advanced.

Rückgabewert

Typ
MediaStreamTrack
Beschreibung
Die Schnittstelle selbst hat keinen Konstruktor. Instanzen liefern z. B. MediaStream.getTracks(), RTCRtpReceiver.track oder clone().

Beispiele

Kamera starten und Tracks untersuchen

const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });

for (const track of stream.getTracks()) {
  console.log(track.kind, track.label, track.readyState);
}

const [videoTrack] = stream.getVideoTracks();
const { width, height, frameRate } = videoTrack.getSettings();
console.log(`Auflösung: ${width}x${height} @ ${frameRate} fps`);
video FaceTime HD Camera live audio MacBook Pro Mikrofon live Auflösung: 640x480 @ 30 fps

Mikrofon stummschalten und Kamera wirklich beenden

const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
const [audioTrack] = stream.getAudioTracks();

// Stummschalten: Gerät bleibt aktiv, liefert aber Stille
const toggleMute = () => {
  audioTrack.enabled = !audioTrack.enabled;
  console.log('Mikrofon aktiv:', audioTrack.enabled);
};
toggleMute();

// Anruf beenden: alle Geräte freigeben, die Kamera-LED erlischt
const hangUp = () => stream.getTracks().forEach((t) => t.stop());
hangUp();
console.log(audioTrack.readyState);
Mikrofon aktiv: false ended

Auflösung zur Laufzeit ändern (applyConstraints)

const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const [track] = stream.getVideoTracks();

const caps = track.getCapabilities?.() ?? {};
console.log('Max. Breite:', caps.width?.max);

try {
  await track.applyConstraints({ width: { ideal: 1280 }, height: { ideal: 720 }, frameRate: { max: 30 } });
  console.log('Neu:', track.getSettings().width, 'x', track.getSettings().height);
} catch (err) {
  // OverconstrainedError, wenn exact-/min-Werte nicht erfüllbar sind
  console.error(err.name, err.constraint);
}
Max. Breite: 1920 Neu: 1280 x 720

Auf Ende der Bildschirmfreigabe reagieren (ended-Event)

const stream = await navigator.mediaDevices.getDisplayMedia({ video: true });
const [screenTrack] = stream.getVideoTracks();

const onEnded = () => {
  console.log('Freigabe wurde vom Benutzer beendet');
  document.querySelector('#share-btn').disabled = false;
};

screenTrack.addEventListener('ended', onEnded, { once: true });
// Alternativ: screenTrack.onended = onEnded;

screenTrack.onmute = () => console.log('Quelle liefert vorübergehend keine Daten');
screenTrack.onunmute = () => console.log('Quelle liefert wieder Daten');

// Später Listener entfernen:
// screenTrack.removeEventListener('ended', onEnded);
Freigabe wurde vom Benutzer beendet

// Wichtig · Fallstricke

  • enabled und stop() machen verschiedene Dinge: Mit enabled = false bleibt das Gerät belegt und die Kamera-LED leuchtet weiter. Erst stop() gibt das Gerät frei. Ein gestoppter Track lässt sich nicht wieder starten, dafür braucht es einen neuen getUserMedia()-Aufruf.
  • Kein ended bei eigenem stop(): Das Event feuert nur, wenn die Quelle von außen endet, z. B. wenn das Gerät getrennt, die Berechtigung entzogen oder die Freigabe beendet wird.
  • muted ist nicht enabled: muted ist nur lesbar und wird vom Browser oder System gesetzt, etwa bei einem Hardware-Stummschalter oder Netzwerkproblemen in WebRTC.
  • Datenschutz: label und Geräte-IDs sind erst nach erteilter Berechtigung sinnvoll gefüllt. getUserMedia() funktioniert nur in sicheren Kontexten (HTTPS oder localhost) und braucht in iframes die Berechtigungsrichtlinie allow="camera; microphone".
  • Kompatibilität: getCapabilities() fehlte in Firefox lange und ist dort erst seit Version 132 verfügbar. Deshalb optional aufrufen (track.getCapabilities?.()). Nicht jeder Browser unterstützt jeden Constraint (z. B. zoom, torch). Das lässt sich mit navigator.mediaDevices.getSupportedConstraints() prüfen.
  • applyConstraints() weist sein Promise mit OverconstrainedError zurück, wenn exact- oder min/max-Vorgaben nicht erfüllbar sind. ideal-Werte führen nie zu einem Fehler.