Часто задаваемые вопросы по веб-аудио

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

В: Помогите, я не могу издавать звуки!

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

Вопрос. Сколько аудиоконтекстов мне следует иметь?

О: Как правило, вам следует включать один AudioContext на страницу, а один аудиоконтекст может поддерживать множество подключенных к нему узлов. Хотя вы можете включить несколько AudioContexts на одну страницу, это может привести к снижению производительности.

Вопрос: У меня есть 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);

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

В: Когда я смогу услышать звук с микрофона?

О: Часть аудиовхода будет реализована как часть WebRTC с использованием getUserMedia и будет доступна как специальный узел источника в API веб-аудио. Он будет работать совместно с createMediaElementSource .

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

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

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

Существует открытая ошибка, позволяющая API веб-аудио реализовывать более точный обратный вызов.

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

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

Вопрос: Можно ли использовать API веб-аудио для обработки звука быстрее, чем в реальном времени?

О: Да, решение находится в разработке. Пожалуйста, следите за обновлениями!

Вопрос: Я создал потрясающее приложение API веб-аудио, но всякий раз, когда вкладка, на которой оно работает, работает в фоновом режиме, звуки становятся совершенно странными!

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

В общем, может быть хорошей идеей остановить воспроизведение, когда ваше приложение переходит в фоновый режим. Вы можете определить, когда страница переходит в фоновый режим, с помощью API видимости страницы .

Вопрос: Как изменить высоту звука с помощью API веб-аудио?

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

Вопрос: Могу ли я изменить высоту звука без изменения скорости?

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

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

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

Вопрос: Как создать AudioContext с выбранной мной частотой дискретизации?

О: В настоящее время эта поддержка не поддерживается, но мы над этим работаем. См. этот запрос функции .

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