Часто задаваемые вопросы о Web Audio

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

Вопрос. У меня не воспроизводится звук. Что делать?

Если вы только начали работать с Web Audio API, ознакомьтесь с руководством для начинающих или рецептом Эрика по воспроизведению аудио на основе действий пользователя.

В. Сколько аудиоконтекстов должно быть?

Обычно на странице размещается один элемент AudioContext, а один аудиоконтекст может поддерживать множество связанных с ним узлов. На одной странице можно разместить несколько объектов AudioContext, но это может снизить производительность.

У меня есть AudioBufferSourceNode, который я только что воспроизвел с помощью noteOn(), и я хочу воспроизвести его снова, но noteOn() ничего не делает! Что делать?

О: После того как исходный узел закончит воспроизведение, он не сможет воспроизвести что-либо ещё. Чтобы снова воспроизвести буфер, создайте новый объект AudioBufferSourceNode и вызовите метод noteOn().

Хотя повторное создание исходного узла может показаться неэффективным, исходные узлы сильно оптимизированы для такого использования. Кроме того, если вы сохраните дескриптор AudioBuffer, вам не придется снова запрашивать у объекта воспроизведение того же звука. Если вам часто приходится повторять этот код, создайте простую вспомогательную функцию, например playSound(buffer).

Вопрос: почему при воспроизведении звука каждый раз нужно создавать новый узел источника?

А. Идея этой архитектуры заключается в том, чтобы отделить аудиообъект от состояния воспроизведения. Если провести аналогию с проигрывателем, буферы – это пластинки, а источники – головки звукоснимателя. Поскольку во многих приложениях одновременно воспроизводятся несколько версий одного и того же буфера, этот шаблон имеет важное значение.

Как обрабатывать звук из тегов audio и video?

Ответ. MediaElementAudioSourceNode находится в разработке. Если он доступен, то работает примерно так (добавляет эффект фильтра к образцу, воспроизводимому с помощью тега audio):

<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);

Информация об этой функции приведена в этой ошибке. Обратите внимание, что в этой конфигурации нет необходимости вызывать mediaSourceNode.noteOn(), поскольку воспроизведением управляет аудиотег.

Когда можно получить звук с микрофона?

А. Вход аудио будет реализован как часть WebRTC с помощью getUserMedia и будет доступен как специальный исходный узел в Web Audio API. Он будет работать вместе с createMediaElementSource.

Как узнать, когда закончится воспроизведение AudioSourceNode?

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

// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
    console.log('playback finished');
}, buffer.duration * 1000);

В Web Audio API есть ошибка, из-за которой обратный вызов выполняется неточно.

Вопрос. Загрузка звуков приводит к блокировке всего потока UI, и интерфейс перестает реагировать на действия пользователя. Помогите!**

Ответ. Используйте API decodeAudioData для асинхронной загрузки, чтобы избежать блокировки основного потока. Пример

Можно ли с помощью Web Audio API обрабатывать звуки быстрее, чем в реальном времени?

Ответ. Да, мы работаем над решением этой проблемы. Следите за новостями.

Я создал отличное приложение с использованием Web Audio API, но когда вкладка, на которой оно запущено, переходит в фоновый режим, звук начинает воспроизводиться неправильно.

Ответ: Скорее всего, вы используете setTimeouts, которые по-разному работают, если страница находится в фоновом режиме. В будущем Web Audio API сможет вызывать функции обратного вызова в определенное время, используя внутренний таймер Web Audio (атрибут context.currentTime). Дополнительную информацию вы найдете в запросе на добавление функции.

Как правило, при переходе приложения в фоновый режим воспроизведение лучше останавливать. Чтобы определить, когда страница переходит в фоновый режим, можно использовать Page Visibility API.

Как изменить высоту звука с помощью Web Audio API?

А. Измените playbackRate на исходном узле.

Можно ли изменить высоту тона, не меняя скорость воспроизведения?

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

  • Алгоритмы временной области, которые вызывают повторные эхо-артефакты сегментов.
  • Методы частотной области, которые вызывают артефакты реверберации.

Хотя для этого нет встроенного узла, вы можете использовать узел JavaScriptAudioNode. В качестве отправной точки можно использовать фрагмент кода.

Как создать AudioContext с нужной частотой дискретизации?

Нет, пока эта функция не поддерживается, но мы работаем над этим. Подробнее о запросе на добавление этой функции…

Если у вас есть вопросы, задайте их на сайте Stack Overflow, используя тег web-audio.