Signatur
Beschreibung
Mit createMediaStreamSource() bindest du einen Live-Medienstrom als Quelle in einen AudioContext ein. Typischerweise stammt der Strom von navigator.mediaDevices.getUserMedia() (Mikrofon), von getDisplayMedia() oder von einer entfernten WebRTC-Verbindung (RTCPeerConnection). Der zurückgegebene Knoten hat keine Eingänge und genau einen Ausgang.
Einsatzgebiete sind unter anderem Pegelanzeigen und Visualisierungen (zusammen mit einem AnalyserNode), Live-Effekte wie Filter, Hall oder Verzerrung, Spracherkennung und Stille-Erkennung oder die Aufnahme eines bearbeiteten Signals über createMediaStreamDestination() und MediaRecorder.
Enthält der Strom mehrere Audiospuren, wird laut Spezifikation die Spur verwendet, deren id lexikografisch zuerst kommt. Brauchst du gezielt eine bestimmte Spur, nutze stattdessen createMediaStreamTrackSource() bzw. erzeuge einen neuen MediaStream mit nur dieser Spur. Alternativ zur Fabrikmethode kannst du auch den Konstruktor new MediaStreamAudioSourceNode(context, { mediaStream }) verwenden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $mediaStream Pflicht | MediaStream | Der Medienstrom, dessen Audiospur als Quelle dienen soll. Er muss mindestens eine MediaStreamTrack vom Typ audio enthalten. |
Rückgabewert
connect() verbunden werden kann.Beispiele
Mikrofon-Pegel mit AnalyserNode messen
const startMeter = async () => {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const ctx = new AudioContext();
const source = ctx.createMediaStreamSource(stream);
const analyser = ctx.createAnalyser();
analyser.fftSize = 256;
source.connect(analyser); // nicht mit destination verbinden -> keine Rückkopplung
const data = new Uint8Array(analyser.frequencyBinCount);
const tick = () => {
analyser.getByteFrequencyData(data);
const avg = data.reduce((a, b) => a + b, 0) / data.length;
console.log('Pegel:', Math.round(avg));
requestAnimationFrame(tick);
};
tick();
};
document.querySelector('#start').addEventListener('click', startMeter);
Live-Tiefpassfilter auf das Mikrofon anwenden
const ctx = new AudioContext();
const stream = await navigator.mediaDevices.getUserMedia({
audio: { echoCancellation: true }
});
const source = ctx.createMediaStreamSource(stream);
const filter = ctx.createBiquadFilter();
filter.type = 'lowpass';
filter.frequency.value = 800;
source.connect(filter).connect(ctx.destination);
// Hinweis: Kopfhörer verwenden, sonst droht Rückkopplung
Bearbeitetes Signal mit MediaRecorder aufnehmen
const ctx = new AudioContext();
const mic = await navigator.mediaDevices.getUserMedia({ audio: true });
const source = ctx.createMediaStreamSource(mic);
const gain = ctx.createGain();
gain.gain.value = 1.5;
const dest = ctx.createMediaStreamDestination();
source.connect(gain).connect(dest);
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 });
console.log('Aufnahme fertig:', blob.size, 'Bytes');
mic.getTracks().forEach((t) => t.stop());
ctx.close();
};
recorder.start();
setTimeout(() => recorder.stop(), 3000);
Entfernten WebRTC-Audiostrom analysieren
const pc = new RTCPeerConnection();
const ctx = new AudioContext();
pc.addEventListener('track', ({ track, streams }) => {
if (track.kind !== 'audio') return;
const source = ctx.createMediaStreamSource(streams[0] ?? new MediaStream([track]));
const analyser = ctx.createAnalyser();
source.connect(analyser);
console.log('Remote-Audio angebunden');
});
// Wichtig · Fallstricke
- Autoplay-Richtlinie: Ein
AudioContext, der ohne Nutzerinteraktion erzeugt wird, startet oft im Zustandsuspended. Rufectx.resume()in einem Klick-Handler auf oder erzeuge den Kontext erst dort. - Keine Audiospur: Enthält der Strom keine Audiospur, wird eine
InvalidStateError-DOMExceptiongeworfen. - Rückkopplung: Mikrofon direkt mit
ctx.destinationzu verbinden, erzeugt über Lautsprecher schnell Pfeifen. Nur für Analysen reicht die Verbindung zu einemAnalyserNode. - Abtastrate: Firefox warf früher einen Fehler, wenn die Abtastrate von Kontext und Stream nicht übereinstimmte. Im Zweifel
new AudioContext()ohne festesampleRateerzeugen. - Remote-Streams: In Chrome liefert ein WebRTC-Stream teilweise nur dann Audio im Graphen, wenn er zusätzlich einem (ggf. stummgeschalteten)
<audio>-Element alssrcObjectzugewiesen ist. - Datenschutz/Sicherheit:
getUserMedia()funktioniert nur in sicheren Kontexten (HTTPS oderlocalhost) und erfordert die Zustimmung des Nutzers. Beende nach Gebrauch alle Spuren mittrack.stop(), damit die Mikrofonanzeige erlischt. - Nur
AudioContext: Auf einemOfflineAudioContextsteht die Methode nicht zur Verfügung.