Signatur
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()undgetCapabilities()lesen die aktuellen Einstellungen, Vorgaben und Gerätefähigkeiten aus.applyConstraints(constraints)ändert Auflösung, Bildrate oder Audio-Verarbeitung zur Laufzeit und gibt einPromise<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
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`);
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);
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);
}
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);
// Wichtig · Fallstricke
enabledundstop()machen verschiedene Dinge: Mitenabled = falsebleibt das Gerät belegt und die Kamera-LED leuchtet weiter. Erststop()gibt das Gerät frei. Ein gestoppter Track lässt sich nicht wieder starten, dafür braucht es einen neuengetUserMedia()-Aufruf.- Kein
endedbei eigenemstop(): 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. mutedist nichtenabled:mutedist nur lesbar und wird vom Browser oder System gesetzt, etwa bei einem Hardware-Stummschalter oder Netzwerkproblemen in WebRTC.- Datenschutz:
labelund Geräte-IDs sind erst nach erteilter Berechtigung sinnvoll gefüllt.getUserMedia()funktioniert nur in sicheren Kontexten (HTTPS oderlocalhost) und braucht in iframes die Berechtigungsrichtlinieallow="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 mitnavigator.mediaDevices.getSupportedConstraints()prüfen. applyConstraints()weist sein Promise mitOverconstrainedErrorzurück, wennexact- odermin/max-Vorgaben nicht erfüllbar sind.ideal-Werte führen nie zu einem Fehler.