Start · Sprachen · JavaScript · Referenz · MediaStreamAudioSourceNode

MediaStreamAudioSourceNode

Schnittstelle

Ein <code>AudioNode</code> ohne Eingänge, der die erste Audiospur eines <code>MediaStream</code> (z. B. Mikrofon oder WebRTC) als Quelle in einen Audio-Graphen einspeist.

seit JavaScript Baseline: alle modernen Browser (seit ca. 2015) Kategorie: webapi

Signatur

interface MediaStreamAudioSourceNode extends AudioNode

Beschreibung

MediaStreamAudioSourceNode verbindet Live-Audio aus einem MediaStream mit der Web Audio API. Typische Quellen sind das Mikrofon über navigator.mediaDevices.getUserMedia(), eine Bildschirmfreigabe über getDisplayMedia() oder ein entfernter Teilnehmer einer WebRTC-Verbindung (RTCPeerConnection). Der Knoten hat keine Eingänge und genau einen Ausgang. Die Kanalanzahl des Ausgangs richtet sich nach der Audiospur.

Erzeugt wird der Knoten entweder über die Fabrikmethode AudioContext.prototype.createMediaStreamSource(stream) oder den Konstruktor new MediaStreamAudioSourceNode(context, { mediaStream }). Danach lässt er sich mit anderen Knoten verbinden, z. B. mit einem AnalyserNode für Pegelanzeigen und Visualisierungen, einem GainNode für die Lautstärke, Filtern für Effekte oder einem MediaStreamAudioDestinationNode, um das bearbeitete Audio wieder als Stream auszugeben (etwa für MediaRecorder oder WebRTC).

Der Knoten übernimmt nur die erste Audiospur des Streams. Welche das ist, bestimmt der Browser durch lexikografische Sortierung der Spur-IDs, nicht die Reihenfolge der Spuren im Stream. Brauchst du eine bestimmte Spur, nimm MediaStreamTrackAudioSourceNode bzw. createMediaStreamTrackSource().

Die einzige eigene Eigenschaft ist mediaStream (nur lesbar). Sie liefert den MediaStream, der beim Erzeugen übergeben wurde. Alle weiteren Eigenschaften und Methoden (connect(), disconnect(), channelCount …) erbt der Knoten von AudioNode.

Parameter

Name Typ Default Beschreibung
$context Pflicht AudioContext Der AudioContext, zu dem der Knoten gehört (Konstruktor-Parameter). Ein OfflineAudioContext ist nicht erlaubt.
$options Pflicht { mediaStream: MediaStream } Optionsobjekt mit der Pflicht-Eigenschaft mediaStream: der Stream, dessen erste Audiospur als Quelle dient.

Rückgabewert

Typ
MediaStreamAudioSourceNode
Beschreibung
Ein neuer Quellknoten. Seine Eigenschaft mediaStream verweist auf den übergebenen Stream.

Beispiele

Mikrofon abhören und Lautstärke regeln

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

  // Fabrikmethode – gleichwertig zum Konstruktor
  const source = ctx.createMediaStreamSource(stream);
  const gain = ctx.createGain();
  gain.gain.value = 0.5;

  source.connect(gain).connect(ctx.destination);
  console.log(source.mediaStream === stream);
  return { ctx, stream };
};

document.querySelector('#start').addEventListener('click', startMic);
true

Pegelanzeige mit AnalyserNode (Konstruktor-Variante)

const showLevel = async () => {
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
  const ctx = new AudioContext();
  const source = new MediaStreamAudioSourceNode(ctx, { mediaStream: stream });
  const analyser = new AnalyserNode(ctx, { fftSize: 256 });
  source.connect(analyser); // nicht mit destination verbinden -> keine Rückkopplung

  const data = new Uint8Array(analyser.fftSize);
  const tick = () => {
    analyser.getByteTimeDomainData(data);
    const peak = Math.max(...data.map((v) => Math.abs(v - 128))) / 128;
    document.querySelector('#meter').value = peak;
    requestAnimationFrame(tick);
  };
  tick();
};

document.querySelector('#meter-start').addEventListener('click', showLevel);

WebRTC-Gegenstelle filtern und aufnehmen

const pc = new RTCPeerConnection();
const ctx = new AudioContext();

pc.addEventListener('track', ({ streams: [remoteStream] }) => {
  const source = ctx.createMediaStreamSource(remoteStream);
  const highpass = new BiquadFilterNode(ctx, { type: 'highpass', frequency: 120 });
  const dest = ctx.createMediaStreamDestination();

  source.connect(highpass).connect(dest);

  const recorder = new MediaRecorder(dest.stream);
  recorder.addEventListener('dataavailable', (e) => console.log('Chunk:', e.data.size, 'Bytes'));
  recorder.start(1000);
});
Chunk: 16384 Bytes (Beispielwert, jede Sekunde)

Aufräumen: Stream und Kontext beenden

const stopMic = async ({ ctx, stream }) => {
  stream.getTracks().forEach((track) => track.stop()); // Mikrofon-Anzeige erlischt
  await ctx.close();
  console.log(ctx.state);
};
closed

// Wichtig · Fallstricke

  • Autoplay-Richtlinie: Ein AudioContext, der ohne Nutzerinteraktion entsteht, startet oft im Zustand suspended. Erzeuge ihn in einem Klick-Handler oder rufe ctx.resume() auf.
  • Keine Audiospur: Enthält der Stream keine Audiospur, werfen der Konstruktor und createMediaStreamSource() einen InvalidStateError.
  • Nur erste Spur: Bei mehreren Audiospuren wird nur eine verwendet, sortiert nach ID. Für eine gezielte Auswahl nimm MediaStreamTrackAudioSourceNode. Firefox unterstützt diesen Knoten; bei Chromium und Safari ist die Unterstützung eingeschränkt, deshalb vorher prüfen.
  • Rückkopplung: Wird ein Mikrofon direkt mit ctx.destination verbunden, kann es über Lautsprecher pfeifen. Nutze Kopfhörer oder verbinde nur mit einem Analyser.
  • Sicherheit/Datenschutz: getUserMedia() funktioniert nur in sicheren Kontexten (HTTPS oder localhost) und braucht die Zustimmung der Nutzer. Beende die Spuren mit track.stop(), wenn du sie nicht mehr brauchst.
  • Cross-Origin: Stammt der Stream aus Medien einer anderen Herkunft ohne CORS-Freigabe, liefert der Knoten nur Stille.
  • Abtastrate: Firefox hat früher einen Fehler geworfen, wenn die Abtastrate von Kontext und Mikrofon nicht übereinstimmte. Lässt man die Abtastrate beim AudioContext weg, vermeidet man das Problem.
  • OfflineAudioContext wird nicht unterstützt.