Start · Sprachen · JavaScript · Referenz · new MediaStreamAudioDestinationNode()

new MediaStreamAudioDestinationNode()

Methode

Erstellt einen <code>MediaStreamAudioDestinationNode</code>, der das Audiosignal eines Audio-Graphen als <code>MediaStream</code> bereitstellt, z. B. für Aufnahme oder WebRTC.

seit JavaScript Baseline: alle modernen Browser (Konstruktor-Form Kategorie: webapi

Signatur

new MediaStreamAudioDestinationNode(context, options)

Beschreibung

Der Konstruktor MediaStreamAudioDestinationNode() erzeugt einen Ausgabeknoten der Web Audio API. Anders als AudioContext.destination (die Lautsprecher) schreibt dieser Knoten das eingehende Audiosignal in einen MediaStream. Dieser Stream steht über die Eigenschaft stream zur Verfügung und enthält genau einen MediaStreamTrack der Art "audio".

Man braucht ihn immer dann, wenn bearbeitetes oder synthetisch erzeugtes Audio den Web-Audio-Graphen verlassen und an andere Media-APIs gehen soll: zum Aufnehmen mit MediaRecorder, zum Senden über RTCPeerConnection (WebRTC), zum Mischen mit einem Video-Stream aus canvas.captureStream() oder zum Abspielen über ein <audio>-Element per srcObject.

Funktional ist der Konstruktor gleichwertig zur Fabrikmethode AudioContext.createMediaStreamDestination(). Er hat aber den Vorteil, dass sich Kanal-Optionen gleich beim Erzeugen über das options-Objekt setzen lassen. Der Knoten hat einen Eingang und keinen Ausgang. Man verbindet also andere Knoten zu ihm hin, nicht von ihm weg.

Parameter

Name Typ Default Beschreibung
$context Pflicht AudioContext Der AudioContext, zu dem der Knoten gehören soll. Ein OfflineAudioContext ist nicht erlaubt.
$options object {} Optionales Objekt mit Kanal-Einstellungen (siehe folgende Einträge).
$options.channelCount number 2 Anzahl der Kanäle für das Herauf- und Heruntermischen am Eingang, z. B. 1 für Mono.
$options.channelCountMode "max" | "clamped-max" | "explicit" "explicit" Legt fest, wie die Kanalzahl des Eingangs bestimmt wird.
$options.channelInterpretation "speakers" | "discrete" "speakers" Legt fest, wie Kanäle beim Heraufmischen und Heruntermischen zugeordnet werden.

Rückgabewert

Typ
MediaStreamAudioDestinationNode
Beschreibung
Ein neuer Knoten. Seine Eigenschaft stream liefert den erzeugten MediaStream mit einer Audiospur.

Beispiele

Knoten erzeugen und Stream auslesen

const ctx = new AudioContext();
const dest = new MediaStreamAudioDestinationNode(ctx, { channelCount: 1 });

const osc = new OscillatorNode(ctx, { frequency: 440 });
osc.connect(dest);
osc.start();

console.log(dest.stream instanceof MediaStream);
console.log(dest.stream.getAudioTracks().length);
console.log(dest.channelCount);
true 1 1

Bearbeitetes Mikrofon-Audio mit MediaRecorder aufnehmen

const recordFiltered = async (durationMs = 5000) => {
  const ctx = new AudioContext();
  const mic = await navigator.mediaDevices.getUserMedia({ audio: true });
  const source = new MediaStreamAudioSourceNode(ctx, { mediaStream: mic });
  const filter = new BiquadFilterNode(ctx, { type: 'lowpass', frequency: 1200 });
  const dest = new MediaStreamAudioDestinationNode(ctx);

  source.connect(filter).connect(dest);

  const recorder = new MediaRecorder(dest.stream);
  const chunks = [];
  recorder.ondataavailable = (e) => chunks.push(e.data);

  const done = new Promise((resolve) => {
    recorder.onstop = () => resolve(new Blob(chunks, { type: recorder.mimeType }));
  });

  recorder.start();
  setTimeout(() => {
    recorder.stop();
    mic.getTracks().forEach((t) => t.stop());
  }, durationMs);

  const blob = await done;
  console.log('Aufnahme fertig:', blob.size, 'Bytes');
  return URL.createObjectURL(blob);
};

document.querySelector('#rec').addEventListener('click', async () => {
  const url = await recordFiltered();
  document.querySelector('audio').src = url;
});
Aufnahme fertig: 48213 Bytes

Synthetisches Audio über WebRTC senden

const ctx = new AudioContext();
const dest = new MediaStreamAudioDestinationNode(ctx);
const osc = new OscillatorNode(ctx, { type: 'sine', frequency: 880 });
const gain = new GainNode(ctx, { gain: 0.2 });
osc.connect(gain).connect(dest);
osc.start();

const pc = new RTCPeerConnection();
const [track] = dest.stream.getAudioTracks();
pc.addTrack(track, dest.stream);
console.log(pc.getSenders()[0].track.kind);
audio

Audio mit Canvas-Video zu einem Stream kombinieren

const canvas = document.querySelector('canvas');
const ctx = new AudioContext();
const dest = new MediaStreamAudioDestinationNode(ctx);
new OscillatorNode(ctx).connect(dest);

const combined = new MediaStream([
  ...canvas.captureStream(30).getVideoTracks(),
  ...dest.stream.getAudioTracks()
]);
console.log(combined.getTracks().map((t) => t.kind));
["video", "audio"]

// Wichtig · Fallstricke

  • Kein OfflineAudioContext: Der Knoten funktioniert nur mit einem echten AudioContext. Mit einem OfflineAudioContext wird ein Fehler geworfen. Offline gerendertes Audio gibt man stattdessen über den AudioBuffer aus startRendering() aus.
  • Autoplay-Richtlinie: Ein AudioContext, der ohne Nutzerinteraktion erzeugt wurde, startet oft im Zustand "suspended". Dann ist der Stream still. Rufe ctx.resume() in einem Klick-Handler auf.
  • Nicht hörbar: Was mit dem Knoten verbunden ist, geht nicht automatisch an die Lautsprecher. Wenn du mithören willst, verbinde die Quelle zusätzlich mit ctx.destination.
  • Nur eine Spur: stream enthält immer genau eine Audiospur. Mehrere Knoten ergeben mehrere unabhängige Streams.
  • Kompatibilität: Die Fabrikmethode createMediaStreamDestination() gibt es schon länger. Die Konstruktor-Form ist in allen aktuellen Browsern (Chrome, Edge, Firefox, Safari 14.1+) verfügbar. Für sehr alte Browser nimm die Fabrikmethode.
  • Das Aufnahmeformat von MediaRecorder (z. B. audio/webm oder audio/mp4) unterscheidet sich je nach Browser. Prüfe es mit MediaRecorder.isTypeSupported().