Signatur
Beschreibung
Die Methode clone() gibt ein neues MediaStream-Objekt zurück, das eine eigene, eindeutige id bekommt. Alle Spuren des Originals werden dabei mit MediaStreamTrack.clone() kopiert. Der neue Stream enthält also eigene Track-Objekte und nicht dieselben Referenzen.
Das ist nützlich, wenn du dieselbe Kamera- oder Mikrofonquelle unabhängig voneinander nutzen willst, zum Beispiel für eine lokale Vorschau und eine WebRTC-Übertragung oder eine Aufnahme mit MediaRecorder. Jeder Klon lässt sich einzeln stummschalten (track.enabled = false), beenden (track.stop()) oder mit applyConstraints() anpassen, ohne dass sich das auf das Original auswirkt.
Die zugrunde liegende Hardwarequelle wird erst dann freigegeben, wenn alle Tracks beendet sind, die auf sie zugreifen, also auch die geklonten. Wer die Kamera ausschalten will, muss deshalb die Tracks aller Klone stoppen.
Rückgabewert
MediaStream mit neuer id, der geklonte Kopien aller Audio- und Videospuren des Originals enthält.Beispiele
Stream klonen und IDs vergleichen
const original = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
const kopie = original.clone();
console.log(original.id === kopie.id);
console.log(original.getVideoTracks()[0] === kopie.getVideoTracks()[0]);
console.log(kopie.getTracks().length);
Vorschau stumm, Aufnahme mit Ton
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
// Lokale Vorschau: ohne Ton, damit es keine Rückkopplung gibt
const vorschau = stream.clone();
vorschau.getAudioTracks().forEach((t) => { t.enabled = false; });
document.querySelector('video').srcObject = vorschau;
// Aufnahme mit dem Original-Stream (inklusive Ton)
const recorder = new MediaRecorder(stream);
const chunks = [];
recorder.ondataavailable = (e) => chunks.push(e.data);
recorder.start();
Klon herunterskalieren, ohne das Original zu verändern
const stream = await navigator.mediaDevices.getUserMedia({ video: { width: 1280, height: 720 } });
const klein = stream.clone();
await klein.getVideoTracks()[0].applyConstraints({ width: 320, height: 180 });
console.log(stream.getVideoTracks()[0].getSettings().width);
console.log(klein.getVideoTracks()[0].getSettings().width);
Kamera vollständig freigeben
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const klon = stream.clone();
const alleStoppen = (...streams) =>
streams.forEach((s) => s.getTracks().forEach((t) => t.stop()));
// Kamera-LED geht erst aus, wenn alle Tracks gestoppt sind
alleStoppen(stream, klon);
console.log(klon.getTracks()[0].readyState);
// Wichtig · Fallstricke
- Hardware bleibt aktiv: Wenn du nur die Tracks des Originals stoppst, bleibt die Kamera oder das Mikrofon an, solange ein geklonter Track noch läuft. Stoppe immer alle Klone.
- Schon beendete Tracks: Tracks mit
readyState === "ended"werden als beendete Tracks mitkopiert und liefern keine Daten mehr. - Späteres Hinzufügen: Tracks, die du nach dem Klonen mit
addTrack()zum Original hinzufügst, erscheinen nicht im Klon und umgekehrt. - Ressourcen: Jeder Klon kann zusätzliche Verarbeitung auslösen, etwa unterschiedliche Auflösungen per
applyConstraints(). Lege Klone deshalb nicht unnötig an. - Kompatibilität: Wird von allen modernen Browsern unterstützt (Chrome, Edge, Firefox, Safari).
getUserMediafunktioniert nur in einem sicheren Kontext (HTTPS oder localhost).