Signatur
Beschreibung
Das Interface MediaStream der Media Capture and Streams API bündelt mehrere MediaStreamTrack-Objekte, typischerweise eine Video- und eine oder mehrere Audiospuren. Einen MediaStream bekommt man meist von navigator.mediaDevices.getUserMedia() (Kamera/Mikrofon), getDisplayMedia() (Bildschirmfreigabe), HTMLCanvasElement.captureStream(), HTMLMediaElement.captureStream() oder über WebRTC (RTCPeerConnection, Ereignis track).
Mit dem Konstruktor new MediaStream() lassen sich auch eigene Streams bauen, z. B. um Spuren aus verschiedenen Quellen zu kombinieren (Bildschirm-Video und Mikrofon-Audio). Einen Stream zeigt man an, indem man ihn der Eigenschaft srcObject eines <video>- oder <audio>-Elements zuweist. Mit MediaRecorder kann man ihn aufzeichnen und mit RTCPeerConnection an Gegenstellen senden.
Wichtige Mitglieder:
- Eigenschaften:
id(eindeutige Kennung als UUID-Zeichenkette),active(true, solange mindestens eine Spur nicht beendet ist). - Methoden:
getTracks(),getAudioTracks(),getVideoTracks(),getTrackById(id),addTrack(track),removeTrack(track),clone(). - Ereignisse:
addtrackundremovetrack(MediaStreamTrackEvent). Sie werden nur ausgelöst, wenn der Browser selbst Spuren ändert (z. B. bei WebRTC), nicht bei eigenen Aufrufen vonaddTrack()/removeTrack().
Einen Stream stoppt man nicht direkt, sondern indem man stop() auf allen Spuren aufruft. Erst danach geben Kamera und Mikrofon die Hardware frei und die Aufnahmeanzeige des Browsers erlischt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $streamOrTracks | MediaStream | MediaStreamTrack[] | Nur für den Konstruktor new MediaStream(). Ohne Argument entsteht ein leerer Stream. Bei einem MediaStream teilt sich der neue Stream dessen Spuren; die Spuren werden nicht geklont. Bei einem Array von MediaStreamTrack-Objekten werden genau diese Spuren übernommen. |
Rückgabewert
MediaStream-Objekt mit einer neuen id. Es enthält die übergebenen Spuren oder ist leer.Beispiele
Kamera und Mikrofon anzeigen und sauber beenden
const video = document.querySelector('video');
const startCamera = async () => {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: { width: 1280, height: 720 },
audio: true
});
video.srcObject = stream;
await video.play();
console.log('Stream-ID:', stream.id, 'aktiv:', stream.active);
console.log('Spuren:', stream.getTracks().map(t => `${t.kind}: ${t.label}`));
return stream;
} catch (err) {
console.error('Zugriff verweigert oder kein Gerät:', err.name);
}
};
const stopCamera = (stream) => {
// Hardware erst frei, wenn ALLE Spuren gestoppt sind
stream.getTracks().forEach(track => track.stop());
video.srcObject = null;
};
const stream = await startCamera();
setTimeout(() => stopCamera(stream), 10000);
Bildschirmfreigabe mit Mikrofon-Audio kombinieren (Konstruktor)
const buildRecordingStream = async () => {
const screen = await navigator.mediaDevices.getDisplayMedia({ video: true });
const mic = await navigator.mediaDevices.getUserMedia({ audio: true });
// Neuen Stream aus Spuren beider Quellen zusammensetzen
const combined = new MediaStream([
...screen.getVideoTracks(),
...mic.getAudioTracks()
]);
console.log('Video:', combined.getVideoTracks().length,
'Audio:', combined.getAudioTracks().length);
return combined;
};
const combined = await buildRecordingStream();
const recorder = new MediaRecorder(combined, { mimeType: 'video/webm' });
const chunks = [];
recorder.ondataavailable = (e) => chunks.push(e.data);
recorder.onstop = () => {
const blob = new Blob(chunks, { type: 'video/webm' });
console.log('Aufnahme fertig:', blob.size, 'Bytes');
};
recorder.start();
setTimeout(() => recorder.stop(), 5000);
Mikrofon stummschalten und Spuren verwalten
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
// Stummschalten ohne Stoppen: enabled = false sendet Stille bzw. Schwarzbild
const toggleMute = () => {
const [audio] = stream.getAudioTracks();
audio.enabled = !audio.enabled;
console.log('Mikrofon an:', audio.enabled);
};
toggleMute();
// Videospur entfernen; der Stream bleibt mit der Audiospur aktiv
const [videoTrack] = stream.getVideoTracks();
stream.removeTrack(videoTrack);
videoTrack.stop();
console.log('Verbleibende Spuren:', stream.getTracks().length, 'aktiv:', stream.active);
// Spur per ID wiederfinden
const audioId = stream.getAudioTracks()[0].id;
console.log(stream.getTrackById(audioId)?.kind);
Remote-Stream in WebRTC empfangen
const pc = new RTCPeerConnection();
const remoteVideo = document.querySelector('#remote');
pc.addEventListener('track', (event) => {
const [remoteStream] = event.streams;
if (remoteVideo.srcObject !== remoteStream) {
remoteVideo.srcObject = remoteStream;
}
// Der Browser ergänzt oder entfernt hier Spuren selbst, daher feuern diese Ereignisse
remoteStream.addEventListener('addtrack', (e) => console.log('Neue Spur:', e.track.kind));
remoteStream.addEventListener('removetrack', (e) => console.log('Spur entfernt:', e.track.kind));
});