Start · Sprachen · JavaScript · Referenz · MediaStreamAudioDestinationNode.stream

MediaStreamAudioDestinationNode.stream

Eigenschaft

Nur-Lese-Eigenschaft, die einen <code>MediaStream</code> mit genau einer Audiospur liefert. Die Spur enthält das Audiosignal, das im Web-Audio-Graphen an diesen Knoten geleitet wird.

seit JavaScript Baseline: alle modernen Browser (seit 2021) Kategorie: webapi

Signatur

MediaStreamAudioDestinationNode.stream

Beschreibung

Die Eigenschaft stream des Interfaces MediaStreamAudioDestinationNode (nicht AudioContext, wie es manchmal falsch heißt) gibt einen MediaStream zurück. Dieser enthält genau einen MediaStreamTrack vom Typ "audio". Die Spur hat so viele Kanäle wie der Knoten (channelCount, standardmäßig 2).

Über diese Eigenschaft verlässt ein bearbeitetes Audiosignal den Web-Audio-Graphen und geht an andere Medien-APIs weiter. Typische Einsatzfälle:

  • Aufnahme mit MediaRecorder, z. B. eines Synthesizers oder einer abgemischten Tonspur.
  • Versand über WebRTC mit RTCPeerConnection.addTrack(), z. B. ein Mikrofon mit Effekten oder Rauschunterdrückung.
  • Kombination mit einer Videospur aus canvas.captureStream() zu einem gemeinsamen Audio-Video-Stream.

Die Eigenschaft ist schreibgeschützt. Sie liefert bei jedem Zugriff dasselbe MediaStream-Objekt. Das Signal fließt nur, solange der zugehörige AudioContext läuft (state === "running").

Rückgabewert

Typ
MediaStream
Beschreibung
Ein MediaStream mit genau einem Audio-MediaStreamTrack. Er gibt in Echtzeit wieder, was an den Knoten geleitet wird.

Beispiele

Oszillator-Ton mit MediaRecorder aufnehmen

const ctx = new AudioContext();
const osc = ctx.createOscillator();
const dest = ctx.createMediaStreamDestination();

osc.frequency.value = 440;
osc.connect(dest);
osc.start();

const recorder = new MediaRecorder(dest.stream);
const chunks = [];
recorder.ondataavailable = (e) => chunks.push(e.data);
recorder.onstop = () => {
  const blob = new Blob(chunks, { type: recorder.mimeType });
  const audio = new Audio(URL.createObjectURL(blob));
  audio.controls = true;
  document.body.append(audio);
  console.log('Aufnahme fertig:', blob.size, 'Bytes');
};

recorder.start();
setTimeout(() => {
  recorder.stop();
  osc.stop();
}, 2000);
Aufnahme fertig: 16384 Bytes (Wert variiert)

Aufbau des Streams prüfen

const ctx = new AudioContext();
const dest = ctx.createMediaStreamDestination();

const tracks = dest.stream.getAudioTracks();
console.log(tracks.length);          // Anzahl der Audiospuren
console.log(tracks[0].kind);         // Art der Spur
console.log(dest.channelCount);      // Kanäle des Knotens
console.log(dest.stream === dest.stream); // immer dasselbe Objekt
1 audio 2 true

Mikrofon mit Effekt über WebRTC senden

const sendProcessedMic = async (peerConnection) => {
  const ctx = new AudioContext();
  const micStream = await navigator.mediaDevices.getUserMedia({ audio: true });

  const source = ctx.createMediaStreamSource(micStream);
  const filter = ctx.createBiquadFilter();
  filter.type = 'highpass';
  filter.frequency.value = 120; // Brummen unterdrücken

  const dest = ctx.createMediaStreamDestination();
  source.connect(filter).connect(dest);

  const [track] = dest.stream.getAudioTracks();
  peerConnection.addTrack(track, dest.stream);
  return track;
};

const pc = new RTCPeerConnection();
sendProcessedMic(pc).then((track) => console.log('Gesendet:', track.label));
Gesendet: MediaStreamAudioDestinationNode (Bezeichnung browserabhängig)

Canvas-Video und Web-Audio zusammenführen

const canvas = document.querySelector('canvas');
const ctx = new AudioContext();
const dest = ctx.createMediaStreamDestination();

const osc = ctx.createOscillator();
osc.connect(dest);
osc.start();

const combined = new MediaStream([
  ...canvas.captureStream(30).getVideoTracks(),
  ...dest.stream.getAudioTracks(),
]);

const recorder = new MediaRecorder(combined, { mimeType: 'video/webm' });
recorder.start();
console.log(combined.getTracks().map((t) => t.kind));
["video", "audio"]

// Wichtig · Fallstricke

  • Autoplay-Richtlinie: Ein AudioContext startet oft im Zustand "suspended". Solange er angehalten ist, enthält der Stream nur Stille. Rufe ctx.resume() deshalb nach einer Nutzeraktion auf, z. B. nach einem Klick.
  • Kein Lautsprecher-Ausgang: Was an diesen Knoten geleitet wird, ist nicht zu hören. Wer das Signal gleichzeitig abhören will, verbindet die Quelle zusätzlich mit ctx.destination.
  • Kanalanzahl: Die Spur übernimmt die Kanalanzahl des Knotens (channelCount, Standard 2). Um sie zu ändern, übergibst du die gewünschte Anzahl beim Erzeugen, z. B. new MediaStreamAudioDestinationNode(ctx, { channelCount: 1 }).
  • Kein OfflineAudioContext: Der Knoten funktioniert nur in einem Echtzeit-AudioContext. Beim Erzeugen in einem OfflineAudioContext wird ein Fehler ausgelöst.
  • Ressourcen freigeben: Beende nicht mehr benötigte Spuren mit track.stop() und schließe den Kontext mit ctx.close(). Sonst laufen Audioverarbeitung und gegebenenfalls das Mikrofon weiter.
  • Kompatibilität: Wird von Chrome, Edge, Firefox und Safari (ab 14.1) unterstützt. Das Aufnahmeformat von MediaRecorder unterscheidet sich je nach Browser: audio/webm oder audio/mp4. Prüfe es mit MediaRecorder.isTypeSupported().