Web Audio API
Низкоуровневый граф обработки звука: декодирование, синтез, эффекты, анализ спектра.
Что это
Граф из узлов (AudioNode), которые соединяются connect. Источники (AudioBufferSourceNode, MediaElementAudioSourceNode, OscillatorNode) → процессоры (GainNode, BiquadFilterNode, DelayNode) → анализатор/назначение (AudioDestinationNode). Всё работает через единый AudioContext.
Гораздо мощнее HTMLAudioElement: семплерная точность, синтез, эффекты, спектральный анализ для визуализаций.
Базовое использование
// 1. Контекст
const ctx = new AudioContext();
// 2. Загрузить и декодировать сэмпл
const res = await fetch('/sounds/clap.mp3');
const arrayBuf = await res.arrayBuffer();
const audioBuf = await ctx.decodeAudioData(arrayBuf);
// 3. Воспроизвести (одноразовый источник — нужно создавать каждый раз)
function play() {
const src = ctx.createBufferSource;
src.buffer = audioBuf;
src.connect(ctx.destination);
src.start();
}
// Связь с <audio>
const audioEl = document.querySelector('audio');
const source = ctx.createMediaElementSource(audioEl);
const gain = ctx.createGain;
gain.gain.value = 0.5;
source.connect(gain).connect(ctx.destination);
// Анализатор для визуализации (drum kit waveform)
const analyser = ctx.createAnalyser;
analyser.fftSize = 256;
source.connect(analyser);
const data = new Uint8Array(analyser.frequencyBinCount);
function draw() {
requestAnimationFrame(draw);
analyser.getByteFrequencyData(data);
// нарисовать data на canvas
}
draw;
Основные узлы
| Узел | Что делает |
|---|---|
AudioContext |
Корневой граф, sampleRate, currentTime |
AudioBufferSourceNode |
Источник из декодированного буфера (one-shot) |
MediaElementAudioSourceNode |
Источник из <audio>/<video> |
OscillatorNode |
Синтез: sine/square/sawtooth/triangle |
GainNode |
Громкость, fade in/out |
BiquadFilterNode |
Low/high/bandpass фильтры |
AnalyserNode |
FFT для визуализации |
DelayNode / ConvolverNode |
Эффекты echo/reverb |
Поддержка
Все современные браузеры. webkitAudioContext — legacy префикс для старых Safari.
Подводные камни
AudioContextсоздаётся в состоянииsuspended— нужен user gesture +ctx.resumeдля запускаAudioBufferSourceNode— одноразовый: послеstopсоздавай новыйdecodeAudioDataкопирует данные → большие файлы расходуют память; для стриминга лучше<audio>+MediaElementAudioSourceNode- Один и тот же
<audio>нельзя подключить к двумMediaElementAudioSourceNode - На iOS контекст блокирован до тапа
Используется в bootcamp
- JS30 — Drum Kit (#1) — простейший случай: можно ограничиться
audio.currentTime = 0; audio.play(). Но если хочется визуализацию спектра — берёмAnalyserNode.