Signatur
Beschreibung
getByteFrequencyData() liefert eine Momentaufnahme des Frequenzspektrums des Audiosignals, das gerade durch den AnalyserNode läuft. Intern wird eine schnelle Fourier-Transformation (FFT) berechnet. Jeder Eintrag im Array steht für einen Frequenzbereich („Bin“), der Wert ist die Lautstärke in diesem Bereich, auf 0–255 abgebildet.
Typische Einsatzzwecke sind Audio-Visualisierungen (Balken-Equalizer, Spektrumanzeigen), Pegelanzeigen und einfache Klanganalysen, etwa ob Bässe oder Höhen gerade dominieren. Normalerweise ruft man die Methode in einer requestAnimationFrame-Schleife auf und zeichnet das Ergebnis auf ein <canvas>.
Das Array sollte analyser.frequencyBinCount Einträge haben (entspricht fftSize / 2). Bin i deckt ungefähr die Frequenz i * sampleRate / fftSize ab. Die Umrechnung der dB-Werte in Bytes hängt von minDecibels und maxDecibels ab: Werte unter minDecibels ergeben 0, Werte über maxDecibels ergeben 255. Mit smoothingTimeConstant werden die Werte zusätzlich über die Zeit geglättet.
Brauchst du mehr Genauigkeit, nimm getFloatFrequencyData(), das die Werte direkt in Dezibel als Float32Array liefert.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $array Pflicht | Uint8Array | Ziel-Array, in das die Frequenzdaten geschrieben werden. Ist es länger als frequencyBinCount, bleiben die überzähligen Einträge unverändert. Ist es kürzer, werden die überzähligen Bins verworfen. |
Rückgabewert
undefined). Die Daten werden direkt in das übergebene Array geschrieben.Beispiele
Einmalige Spektrum-Momentaufnahme eines Oszillators
const ctx = new AudioContext();
const osc = ctx.createOscillator();
const analyser = ctx.createAnalyser();
analyser.fftSize = 2048;
osc.frequency.value = 440; // Kammerton A
osc.connect(analyser).connect(ctx.destination);
osc.start();
const data = new Uint8Array(analyser.frequencyBinCount);
setTimeout(() => {
analyser.getByteFrequencyData(data);
// Bin mit dem höchsten Wert suchen
let maxIndex = 0;
data.forEach((v, i) => { if (v > data[maxIndex]) maxIndex = i; });
const hz = maxIndex * ctx.sampleRate / analyser.fftSize;
console.log(`Stärkste Frequenz: ca. ${Math.round(hz)} Hz`);
osc.stop();
}, 500);
Balken-Visualisierung auf einem Canvas
const canvas = document.querySelector('canvas');
const g = canvas.getContext('2d');
const audioEl = document.querySelector('audio');
const ctx = new AudioContext();
const source = ctx.createMediaElementSource(audioEl);
const analyser = ctx.createAnalyser();
analyser.fftSize = 256;
analyser.smoothingTimeConstant = 0.8;
source.connect(analyser).connect(ctx.destination);
const data = new Uint8Array(analyser.frequencyBinCount);
const draw = () => {
requestAnimationFrame(draw);
analyser.getByteFrequencyData(data);
g.fillStyle = '#111';
g.fillRect(0, 0, canvas.width, canvas.height);
const barWidth = canvas.width / data.length;
data.forEach((value, i) => {
const h = (value / 255) * canvas.height;
g.fillStyle = `hsl(${(i / data.length) * 300}, 80%, 50%)`;
g.fillRect(i * barWidth, canvas.height - h, barWidth - 1, h);
});
};
audioEl.addEventListener('play', async () => {
await ctx.resume(); // Autoplay-Richtlinie
draw();
});
Mikrofonpegel als einfacher Lautstärkewert
const startMeter = async () => {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const ctx = new AudioContext();
const analyser = ctx.createAnalyser();
analyser.fftSize = 512;
ctx.createMediaStreamSource(stream).connect(analyser);
const data = new Uint8Array(analyser.frequencyBinCount);
setInterval(() => {
analyser.getByteFrequencyData(data);
const avg = data.reduce((sum, v) => sum + v, 0) / data.length;
console.log(`Pegel: ${Math.round((avg / 255) * 100)} %`);
}, 250);
};
document.querySelector('#start').addEventListener('click', startMeter);
// Wichtig · Fallstricke
- Autoplay-Richtlinie: Ein
AudioContextstartet in vielen Browsern im Zustandsuspended. Solange er nicht per Nutzeraktion mitctx.resume()gestartet wurde, bestehen die Daten nur aus Nullen. - Array wiederverwenden: Lege das
Uint8Arrayeinmal an und nicht in jedem Frame neu. Sonst erzeugst du unnötige Arbeit für die Speicherbereinigung. - Nur Nullen trotz Ton? Prüfe, ob die Quelle wirklich mit dem Analyser verbunden ist. Bei
createMediaElementSourcemit Medien von fremden Servern ohne passende CORS-Header gibt der Browser aus Sicherheitsgründen nur Stille aus. Dann hilftcrossorigin="anonymous"am<audio>-Element zusammen mit korrekten CORS-Headern auf dem Server. - Auflösung: Byte-Werte sind grob (256 Stufen) und hängen von
minDecibelsundmaxDecibelsab. Für genaue Messungen istgetFloatFrequencyData()besser. - Folgen zwei Aufrufe innerhalb desselben Render-Quantums (128 Samples) aufeinander, liefern sie dieselben Daten.
- Die Frequenzachse ist linear. Für eine gehörrichtige Darstellung solltest du die Bins logarithmisch gruppieren.
- Kompatibilität: Wird von allen aktuellen Browsern unterstützt (Chrome, Firefox, Safari, Edge). Sehr alte Safari-Versionen brauchten
webkitAudioContext.