Signatur
Beschreibung
MediaStreamAudioDestinationNode ist ein Zielknoten der Web Audio API. Er verbindet den Audiograph eines AudioContext mit der Media-Capture-and-Streams-API. Alles, was an diesen Knoten angeschlossen wird, erscheint in seiner Eigenschaft stream. Das ist ein MediaStream mit genau einer MediaStreamTrack der Art "audio".
Typische Einsatzfälle:
- Den Mix mehrerer Quellen aufnehmen, z. B. Mikrofon, Musik und Effekte, mit
MediaRecorder. - Bearbeitetes Audio mit Filtern, Hall oder Stimmverzerrung per WebRTC übertragen, über
RTCPeerConnection.addTrack(). - Eine Audiospur mit einer Videospur, z. B. von
canvas.captureStream(), zu einem gemeinsamen Stream zusammenführen.
Du erzeugst den Knoten mit audioContext.createMediaStreamDestination() oder mit dem Konstruktor new MediaStreamAudioDestinationNode(context, options). Der Knoten hat einen Eingang und keinen Ausgang (numberOfInputs = 1, numberOfOutputs = 0). Standardmäßig ist channelCount auf 2 gesetzt und channelCountMode auf "explicit".
Wichtig: Der Knoten ersetzt nicht audioContext.destination. Wenn du das Signal gleichzeitig hören willst, musst du die Quelle zusätzlich mit audioContext.destination verbinden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $context Pflicht | AudioContext | Der AudioContext, zu dem der Knoten gehört. Ein OfflineAudioContext wird nicht unterstützt. |
|
| $options | AudioNodeOptions | {} | Optionales Objekt mit channelCount (Standard 2), channelCountMode (Standard "explicit") und channelInterpretation (Standard "speakers"). |
Rückgabewert
stream vom Typ MediaStream. Sie enthält eine Audiospur mit dem Signal, das am Knoten ankommt.Beispiele
Instanziierung und Zugriff auf den Stream
const ctx = new AudioContext();
// Variante 1: Fabrikmethode
const dest1 = ctx.createMediaStreamDestination();
// Variante 2: Konstruktor mit Optionen (Mono)
const dest2 = new MediaStreamAudioDestinationNode(ctx, { channelCount: 1 });
console.log(dest1.stream instanceof MediaStream);
console.log(dest1.stream.getAudioTracks().length);
console.log(dest2.channelCount, dest1.numberOfOutputs);
Oszillator-Ton mit MediaRecorder aufnehmen
const recordTone = async (durationMs = 2000) => {
const ctx = new AudioContext();
const osc = new OscillatorNode(ctx, { frequency: 440 });
const dest = ctx.createMediaStreamDestination();
osc.connect(dest); // in den Stream
osc.connect(ctx.destination); // optional: mithören
const recorder = new MediaRecorder(dest.stream);
const chunks = [];
recorder.ondataavailable = (e) => chunks.push(e.data);
const stopped = new Promise((resolve) => (recorder.onstop = resolve));
recorder.start();
osc.start();
await new Promise((r) => setTimeout(r, durationMs));
osc.stop();
recorder.stop();
await stopped;
const blob = new Blob(chunks, { type: recorder.mimeType });
console.log('Aufnahme:', blob.type, blob.size > 0);
return URL.createObjectURL(blob);
};
document.querySelector('#rec').addEventListener('click', recordTone);
Mikrofon mit Filter bearbeiten und per WebRTC senden
const sendFilteredMic = async (peerConnection) => {
const mic = await navigator.mediaDevices.getUserMedia({ audio: true });
const ctx = new AudioContext();
const source = ctx.createMediaStreamSource(mic);
const filter = new BiquadFilterNode(ctx, { type: 'highpass', frequency: 200 });
const dest = ctx.createMediaStreamDestination();
source.connect(filter).connect(dest);
const [track] = dest.stream.getAudioTracks();
peerConnection.addTrack(track, dest.stream);
console.log('Gesendete Spur:', track.kind, track.readyState);
};
sendFilteredMic(new RTCPeerConnection());
Canvas-Video und Web-Audio zu einem Stream zusammenführen
const canvas = document.querySelector('canvas');
const ctx = new AudioContext();
const dest = ctx.createMediaStreamDestination();
const audioEl = document.querySelector('audio');
ctx.createMediaElementSource(audioEl).connect(dest);
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));
// Wichtig · Fallstricke
- Autoplay-Sperre: Ein
AudioContextstartet oft im Zustand"suspended". Solange er nicht läuft, enthält der Stream nur Stille. Rufectx.resume()nach einer Nutzeraktion auf. - Nicht hörbar: Ein Signal, das nur an den
MediaStreamAudioDestinationNodegeht, ist nicht über die Lautsprecher zu hören. Verbinde die Quelle bei Bedarf zusätzlich mitctx.destination. - Kein
OfflineAudioContext: Die Erzeugung in einem Offline-Kontext wirft einenNotSupportedError. - Nur eine Spur: Der Stream enthält immer genau eine Audiospur. Mehrere Quellen werden im Knoten zusammengemischt (mit Auf- oder Abmischung gemäß
channelCount). - Ressourcen: Nach dem Gebrauch
track.stop()aufrufen undctx.close()ausführen, sonst bleibt das Audio-Rendering aktiv. - Kompatibilität: Wird in Chrome, Edge, Firefox und Safari (ab 14.1) unterstützt. Den Konstruktor unterstützen ältere Browser teils nicht. Die Fabrikmethode
createMediaStreamDestination()ist die sicherste Variante. Welches FormatMediaRecordererzeugt, hängt vom Browser ab (Safari: meistaudio/mp4).