Start · Sprachen · JavaScript · Referenz · MediaStream

MediaStream

Schnittstelle

Repräsentiert einen Stream von Medieninhalten, der aus einer oder mehreren Audio- und Videospuren (<code>MediaStreamTrack</code>) besteht.

seit JavaScript Baseline: alle modernen Browser (Chrome 55+, Firef Kategorie: webapi

Signatur

interface MediaStream extends EventTarget

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: addtrack und removetrack (MediaStreamTrackEvent). Sie werden nur ausgelöst, wenn der Browser selbst Spuren ändert (z. B. bei WebRTC), nicht bei eigenen Aufrufen von addTrack()/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

Typ
MediaStream
Beschreibung
Der Konstruktor liefert ein neues 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);
Stream-ID: 3f2a9c1e-... aktiv: true Spuren: ["audio: Internes Mikrofon", "video: FaceTime HD Camera"]

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);
Video: 1 Audio: 1 Aufnahme fertig: 842113 Bytes

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);
Mikrofon an: false Verbleibende Spuren: 1 aktiv: true audio

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));
});