Start · Sprachen · JavaScript · Referenz · RTCAudioSourceStats.audioLevel

RTCAudioSourceStats.audioLevel

Eigenschaft

Liefert den aktuellen Pegel der lokalen Audioquelle (z. B. Mikrofon) als linearen Wert zwischen <code>0</code> und <code>1</code>.

seit JavaScript WebRTC Statistics; Chromium-Browser, in anderen Br Kategorie: webapi

Signatur

RTCAudioSourceStats.audioLevel

Beschreibung

Die Eigenschaft audioLevel gehört zum Dictionary RTCAudioSourceStats. Dieses Dictionary steht in einem RTCStatsReport für Einträge mit type === "media-source" und kind === "audio". Es beschreibt die lokale Audioquelle, die an einen RTCRtpSender angehängt ist, also meistens das Mikrofon. Der Wert zeigt den Pegel des Signals, bevor es codiert und gesendet wird.

Der Wert ist eine Gleitkommazahl zwischen 0.0 und 1.0 auf einer linearen Skala. 1.0 entspricht 0 dBov, also dem maximal möglichen Pegel. 0.5 entspricht ungefähr 6 dB weniger Schalldruck als 1.0. Die Messung bezieht sich auf einen kurzen, zuletzt verarbeiteten Zeitraum. Es ist also ein Momentanwert und kein Durchschnitt.

Typische Anwendungen sind ein Pegelanzeiger für das eigene Mikrofon, die Erkennung eines stummen Mikrofons („Sie sprechen, sind aber stummgeschaltet“) und Diagnosen in Videokonferenzen. Einen Durchschnittspegel über ein bestimmtes Intervall berechnet man besser aus totalAudioEnergy und totalSamplesDuration.

Rückgabewert

Typ
number | undefined
Beschreibung
Linearer Pegel zwischen 0 und 1. Ist der Wert undefined, unterstützt der Browser das Feld nicht oder es liegen noch keine Audiodaten vor.

Beispiele

Mikrofonpegel einmalig auslesen

const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const pc = new RTCPeerConnection();
const [track] = stream.getAudioTracks();
const sender = pc.addTrack(track, stream);

// Kurz warten, damit Audiodaten verarbeitet wurden
await new Promise((r) => setTimeout(r, 500));

const report = await sender.getStats();
report.forEach((stats) => {
  if (stats.type === 'media-source' && stats.kind === 'audio') {
    console.log('Pegel:', stats.audioLevel?.toFixed(3));
  }
});
Pegel: 0.042

Live-Pegelanzeige mit Fortschrittsbalken

// <progress id="meter" max="1"></progress>
const meter = document.querySelector('#meter');

const startMeter = (sender) => {
  const id = setInterval(async () => {
    const report = await sender.getStats();
    for (const stats of report.values()) {
      if (stats.type === 'media-source' && stats.kind === 'audio') {
        meter.value = stats.audioLevel ?? 0;
      }
    }
  }, 200);
  return () => clearInterval(id); // Funktion zum Stoppen
};

const stopMeter = startMeter(sender);
// später: stopMeter();

Warnung: Sprechen trotz Stummschaltung

const checkMutedSpeaking = async (sender, track) => {
  const report = await sender.getStats();
  const source = [...report.values()].find(
    (s) => s.type === 'media-source' && s.kind === 'audio'
  );
  // track.enabled = false: Es werden nur Nullen gesendet,
  // der Quellpegel kann aber browserabhängig weiter gemessen werden
  if (!track.enabled && (source?.audioLevel ?? 0) > 0.1) {
    console.warn('Sie sprechen, aber Ihr Mikrofon ist stummgeschaltet.');
  }
};

setInterval(() => checkMutedSpeaking(sender, track), 1000);
Sie sprechen, aber Ihr Mikrofon ist stummgeschaltet.

Durchschnittspegel über ein Intervall berechnen

let prev = null;

const averageLevel = async (sender) => {
  const report = await sender.getStats();
  const s = [...report.values()].find(
    (x) => x.type === 'media-source' && x.kind === 'audio'
  );
  if (!s || s.totalAudioEnergy === undefined) return null;

  let avg = null;
  if (prev) {
    const dE = s.totalAudioEnergy - prev.totalAudioEnergy;
    const dT = s.totalSamplesDuration - prev.totalSamplesDuration;
    avg = dT > 0 ? Math.sqrt(dE / dT) : 0; // RMS-Pegel, vergleichbar mit audioLevel
  }
  prev = s;
  return avg;
};

// Wichtig · Fallstricke

  • Browser-Kompatibilität: RTCAudioSourceStats und damit audioLevel werden vor allem von Chromium-Browsern (Chrome, Edge, Opera) unterstützt. Firefox und Safari liefern das Feld teilweise nicht. Prüfen Sie deshalb immer auf undefined und sehen Sie einen Ersatz vor, z. B. einen AnalyserNode der Web Audio API.
  • Die Skala ist linear, nicht logarithmisch. Wenn die Anzeige in dB erfolgen soll, rechnen Sie mit 20 * Math.log10(audioLevel) um.
  • Der Wert ist ein kurzer Momentanwert. Wenn Sie nur selten abfragen, verpassen Sie Spitzen. Für stabile Aussagen verwenden Sie totalAudioEnergy und totalSamplesDuration.
  • Verwechseln Sie das Feld nicht mit RTCInboundRtpStreamStats.audioLevel, das den Pegel des empfangenen Audios der Gegenseite angibt.
  • Ist kein Track angehängt oder wurde der Track gestoppt, fehlt der media-source-Eintrag möglicherweise ganz.
  • getStats() ist asynchron und kostet etwas Rechenzeit. Intervalle unter etwa 100 ms bringen kaum Nutzen.