Web Audio API: создание аудиоредактора в браузере

Сегодня решил расказать вам о создании аудиоредактора прямо в браузере с использованием Web Audio API. Мы разберем ключевые аспекты: обработку звука, визуализацию и добавление эффектов. В статье вы найдете примеры кода, сравнительные тесты и рекомендации, которые помогут вам избежать типичных ошибок.

Почему Web Audio API?

Web Audio API это мощный инструмент, который превращает браузер в полноценную аудиостудию. В отличие от нативных приложений, решения на основе этого API:

  • Не требуют установки — работают прямо в браузере.
  • Кросс-платформенны — одинаково функционируют на Windows, macOS, Android и iOS.
  • Интегрируются с веб-технологиями — легко сочетаются с Canvas, WebGL и другими API.

Но главное — Web Audio API предоставляет низкоуровневый контроль над аудиопотоком. Давайте начнем с основ.

Обработка звука

Загрузка и воспроизведение аудио

Для работы с аудио нужен AudioContextцентральный объект API.

javascript
// Создаем контекст  
const audioContext = new (window.AudioContext || window.webkitAudioContext)();  

// Загружаем аудиофайл  
async function loadAudio(url) {  
  const response = await fetch(url);  
  const arrayBuffer = await response.arrayBuffer();  
  const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);  
  return audioBuffer;  
}  

// Воспроизведение  
const audioBuffer = await loadAudio('track.mp3');  
const source = audioContext.createBufferSource();  
source.buffer = audioBuffer;  
source.connect(audioContext.destination);  
source.start();

Редактирование аудиобуфера

Допустим, мы хотим обрезать трек или изменить громкость. Для этого манипулируем данными в AudioBuffer:

javascript
// Обрезка аудио с 5-й по 10-ю секунду  
const startOffset = 5 * audioBuffer.sampleRate;  
const endOffset = 10 * audioBuffer.sampleRate;  
const newBuffer = audioContext.createBuffer(  
  audioBuffer.numberOfChannels,  
  endOffset - startOffset,  
  audioBuffer.sampleRate  
);  

// Копируем данные  
for (let channel = 0; channel < audioBuffer.numberOfChannels; channel++) {  
  const channelData = audioBuffer.getChannelData(channel);  
  newBuffer.copyToChannel(channelData.subarray(startOffset, endOffset), channel);  
}

Визуализация

Анализ частот и волновой формы

Для визуализации используется AnalyserNode. Подключим его к источнику:

javascript
const analyser = audioContext.createAnalyser();  
source.connect(analyser);  
analyser.connect(audioContext.destination);  

// Настройки  
analyser.fftSize = 2048;  
const bufferLength = analyser.frequencyBinCount;  
const dataArray = new Uint8Array(bufferLength);

Отрисовка на Canvas

Получаем данные и рисуем волновую форму:

javascript
const canvas = document.getElementById('waveform');  
const ctx = canvas.getContext('2d');  

function drawWaveform() {  
  analyser.getByteTimeDomainData(dataArray);  
  ctx.clearRect(0, 0, canvas.width, canvas.height);  
  ctx.beginPath();  
  const sliceWidth = canvas.width / bufferLength;  
  let x = 0;  

  for (let i = 0; i < bufferLength; i++) {  
    const v = dataArray[i] / 128.0;  
    const y = v * canvas.height / 2;  
    ctx.lineTo(x, y);  
    x += sliceWidth;  
  }  

  ctx.stroke();  
  requestAnimationFrame(drawWaveform);  
}  

drawWaveform();

Эффекты: от дилея до дисторшна

Создание эффекта эха (Delay)

Используем DelayNode и GainNode для обратной связи:

javascript
const delay = audioContext.createDelay();  
const feedbackGain = audioContext.createGain();  

delay.delayTime.value = 0.3; // 300 мс  
feedbackGain.gain.value = 0.5; // Уровень обратной связи  

source.connect(delay);  
delay.connect(feedbackGain);  
feedbackGain.connect(delay); // Создаем петлю  
delay.connect(audioContext.destination);

Дисторшн через волновое шейпирование

Модифицируем форму волны с помощью WaveShaperNode:

javascript
const distortion = audioContext.createWaveShaper();  

// Функция для создания кривой дисторшна  
function makeDistortionCurve(amount) {  
  const curve = new Float32Array(44100);  
  for (let i = 0; i < curve.length; i++) {  
    const x = (i * 2) / curve.length - 1;  
    curve[i] = Math.tanh(amount * x); // Гиперболический тангенс для "мягкого" клиппинга  
  }  
  return curve;  
}  

distortion.curve = makeDistortionCurve(400);  
source.connect(distortion);  
distortion.connect(audioContext.destination);

Советы для разработчиков

  1. Оптимизируйте AudioContext
    Создавайте один экземпляр AudioContext на страницу.
  2. Управляйте памятью
    Вызывайте source.stop() и node.disconnect() для завершенных узлов.
  3. Тестируйте на реальных устройствах
    Задержки и производительность сильно зависят от железа.
  4. Используйте WebAssembly
    Для сложных DSP-операций (например FFT) подключайте оптимизированные модули.

Web Audio API открывает безграничные возможности для аудиообработки в браузере. Создавайте редакторы, синтезаторы или интерактивные инсталляции, все ограничивается только вашей фантазией. Попробуйте загрузить трек, нарисуйте его волну и добавьте эхо.

Поделиться статьей:
Поддержать автора блога

Поддержка автора осуществляется с помощью специальной формы ниже, предоставленной сервисом «ЮMoney». Все платёжные операции выполняются на защищённой странице сервиса, что обеспечивает их корректность и полную безопасность.

Персональные рекомендации
Оставить комментарий