Использование API Web Audio
Давайте рассмотрим начало работы с API Web Audio. Мы кратко рассмотрим некоторые концепции, а затем изучим простой пример бумбокса, который позволяет нам загрузить аудиодорожку, воспроизвести и приостановить её, а также изменить громкость и стереопанорамирование.
API Web Audio не заменяет элемент медиа <audio>, а скорее дополняет его, так же как <canvas> существует вместе с элементом <img>. Ваш случай использования определит, какие инструменты вы используете для реализации аудио. Если вы хотите управлять воспроизведением аудиодорожки, элемент медиа <audio> предоставляет более простое и быстрое решение, чем API Web Audio. Если вы хотите выполнить более сложную обработку аудио, а также воспроизведение, API Web Audio предоставляет гораздо больше мощности и контроля.
Мощной функцией API Web Audio является отсутствие строгого «ограничения вызовов звука». Например, нет предела в 32 или 64 одновременных вызова звука. Некоторые процессоры могут воспроизводить более 1000 одновременных звуков без заиканий.
Пример кода
Наш бумбокс выглядит так:
Обратите внимание на ретро-кассетную деку с кнопкой воспроизведения и ползунками громкости и панорамирования, которые позволяют изменять громкость и стереопанорамирование. Мы могли бы сделать это гораздо сложнее, но на данном этапе это идеально подходит для простого обучения.
Посмотрите финальную демонстрацию здесь на CodePen или посмотрите исходный код на GitHub.
Аудиографы
Всё внутри API Web Audio основано на концепции аудиографа, который состоит из узлов.
API Web Audio обрабатывает аудиооперации внутри **контекста аудио** и разработан для **модульного маршрутизирования**. Основные аудиооперации выполняются с **аудиоузлами**, которые связаны вместе, чтобы образовать **аудио маршрутизируемый граф**. У вас есть входные узлы, которые являются источником звуков, которые вы изменяете, узлы модификации, которые изменяют эти звуки по мере необходимости, и выходные узлы (назначения), которые позволяют вам сохранить или услышать эти звуки.
Поддерживается несколько источников аудио с различной компоновкой каналов, даже в рамках одного контекста. Благодаря этой модульной структуре вы можете создавать сложные аудиофункции с динамическими эффектами.
Контекст аудио
Чтобы что-то сделать с API Web Audio, нам нужно создать экземпляр контекста аудио. Это даёт нам доступ ко всем функциям и возможностям API.
const audioContext = new AudioContext();
Так что происходит, когда мы это делаем? Для нас автоматически создаётся BaseAudioContext и расширяется до контекста аудио онлайн. Нам это понадобится, так как мы хотим воспроизводить звук в реальном времени.
Примечание: Если вы хотите просто обработать данные аудио, например, буферизовать и транслировать их, но не воспроизводить, вы можете захотеть создать OfflineAudioContext.
Загрузка звука
Теперь контекст аудио, который мы создали, нуждается в звуке, который должен воспроизводиться через него. Есть несколько способов сделать это с помощью API. Давайте начнём с простого метода — так как у нас бумбокс, мы, скорее всего, хотим воспроизвести всю песню. Кроме того, для доступности полезно экспонировать эту дорожку в DOM. Мы будем экспонировать песню на странице с помощью элемента <audio>.
<audio src="myCoolTrack.mp3"></audio>
Примечание: Если звуковой файл, который вы загружаете, находится на другом домене, вам нужно будет использовать атрибут crossorigin; для получения дополнительной информации см. Cross Origin Resource Sharing (CORS).
Чтобы использовать все хорошие вещи, которые мы получаем с помощью API Web Audio, нам нужно извлечь источник из этого элемента и **направить** его в созданный нами контекст. К счастью, есть метод, который позволяет нам сделать именно это — AudioContext.createMediaElementSource:
// get the audio element
const audioElement = document.querySelector("audio");
// pass it into the audio context
const track = audioContext.createMediaElementSource(audioElement);
Примечание: Элемент <audio> выше представлен в DOM объектом типа HTMLMediaElement, который поставляется со своим набором функций. Всё это осталось неизменным; мы просто позволяем звуку стать доступным для API Web Audio.
Управление звуком
При воспроизведении звука в веб-приложении важно предоставить пользователю возможность управлять им. В зависимости от варианта использования существует множество вариантов, но мы предоставим функциональность для воспроизведения/приостановки звука, изменения громкости дорожки и панорамирования её слева направо.
Управление звуком программно из кода JavaScript регулируется политиками браузера по поддержке автовоспроизведения, и, таким образом, скорее всего будет заблокировано без предоставления разрешения пользователем (или списка разрешённых). Политики автовоспроизведения обычно требуют либо явного разрешения, либо взаимодействия пользователя со страницей перед тем, как скрипты смогут начать воспроизведение аудио.
Эти специальные требования существуют в основном потому, что неожиданные звуки могут быть раздражающими и навязчивыми, а также могут вызывать проблемы с доступностью. Вы можете узнать больше об этом в нашей статье Руководство по автовоспроизведению для медиа и API Web Audio.
Поскольку наши скрипты воспроизводят аудио в ответ на событие ввода пользователя (например, нажатие на кнопку воспроизведения), у нас всё в порядке, и проблем с блокировкой автовоспроизведения не должно быть. Итак, давайте начнём с рассмотрения функциональности воспроизведения и приостановки. У нас есть кнопка воспроизведения, которая меняется на кнопку паузы, когда трек воспроизводится:
<button data-playing="false" role="switch" aria-checked="false"> <span>Play/Pause</span> </button>
Прежде чем мы сможем воспроизвести наш трек, нам нужно подключить наш аудиограф от аудиоисточника/входного узла к выходу.
Мы уже создали входной узел, передав наш аудиоэлемент в API. В основном, вам не нужно создавать выходной узел, вы можете просто подключить свои другие узлы к BaseAudioContext.destination, который обрабатывает ситуацию за вас:
track.connect(audioContext.destination);
Хороший способ визуализировать эти узлы — нарисовать аудиограф, чтобы вы могли визуализировать его. Вот как выглядит наш текущий аудиограф:
Теперь мы можем добавить функциональность воспроизведения и приостановки.
// Select our play button
const playButton = document.querySelector("button");
playButton.addEventListener(
"click",
() => {
// Check if context is in suspended state (autoplay policy)
if (audioContext.state === "suspended") {
audioContext.resume();
}
// Play or pause track depending on state
if (playButton.dataset.playing === "false") {
audioElement.play();
playButton.dataset.playing = "true";
} else if (playButton.dataset.playing === "true") {
audioElement.pause();
playButton.dataset.playing = "false";
}
},
false,
);
Нам также нужно учесть, что делать, когда трек завершит воспроизведение. Наш HTMLMediaElement запускает событие ended после завершения воспроизведения, поэтому мы можем прослушивать его и выполнять код соответствующим образом:
audioElement.addEventListener(
"ended",
() => {
playButton.dataset.playing = "false";
},
false,
);
Изменение звука
Давайте углубимся в некоторые основные узлы модификации, чтобы изменить звук, который у нас есть. Именно здесь API Web Audio действительно начинает пригождаться. Прежде всего, давайте изменим громкость. Это можно сделать с помощью GainNode, который представляет, насколько большой у нас звуковая волна.
Есть два способа создать узлы с помощью API Web Audio. Вы можете использовать фабричный метод самого контекста (например, audioContext.createGain()) или через конструктор узла (например, new GainNode()). Мы будем использовать фабричный метод в нашем коде:
const gainNode = audioContext.createGain();
Теперь нам нужно обновить наш аудиограф, чтобы вход был подключён к усилению, а затем узел усиления был подключён к выходу:
track.connect(gainNode).connect(audioContext.destination);
Это сделает наш аудиограф таким:
Значение по умолчанию для усиления равно 1; это сохраняет текущую громкость такой же. Усиление может быть установлено в минимальное значение около -3.4028235E38 и максимальное значение около 3.4028235E38 (диапазон чисел с плавающей точкой в JavaScript). Здесь мы разрешим бумбоксу увеличить усиление до 2 (удвоить исходную громкость) и уменьшить до 0 (это фактически выключит наш звук).
Давайте предоставим пользователю возможность сделать это — мы будем использовать элемент ввода range input:
<input type="range" id="volume" min="0" max="2" value="1" step="0.01" />
Примечание: Элементы ввода типа range очень удобны для обновления значений в аудиоузлах. Вы можете указать диапазоны значений и использовать их непосредственно с параметрами аудиоузла.
Итак, давайте получим значение этого элемента ввода и обновим значение усиления, когда значение входного узла изменяется пользователем:
const volumeControl = document.querySelector("#volume");
volumeControl.addEventListener(
"input",
() => {
gainNode.gain.value = volumeControl.value;
},
false,
);
Примечание: Значения объектов узлов (например, GainNode.gain) — не простые значения; они фактически являются объектами типа AudioParam — эти так называемые параметры. Вот почему нам нужно установить свойство GainNode.gain value, а не просто установить значение на gain напрямую. Это делает их гораздо более гибкими, позволяя, например, передавать параметру определённый набор значений для изменения в течение заданного периода времени.
Отлично, теперь пользователь может обновлять громкость трека! Узел усиления идеально подходит для добавления функции выключения звука.
Добавление стереопанорамирования в наше приложение
Давайте добавим ещё один узел модификации, чтобы потренироваться в том, чему мы только что научились.
Существует узел StereoPannerNode, который изменяет баланс звука между левым и правым динамиками, если у пользователя есть стереовозможности.
Примечание: Узел StereoPannerNode предназначен для простых случаев, когда вам нужно просто стереопанорамирование слева направо. Также есть PannerNode, который позволяет в значительной степени управлять 3D-пространством или звуковой пространственной локализацией для создания более сложных эффектов. Он используется в играх и 3D-приложениях для создания, например, изображений птиц, летящих сверху, или звука, идущего сзади пользователя.
Для визуализации мы сделаем нашу звуковую схему такой:
Давайте в этот раз воспользуемся методом конструктора для создания узла. В этом случае нам нужно передать контекст и любые параметры, которые может принимать конкретный узел:
const pannerOptions = { pan: 0 };
const panner = new StereoPannerNode(audioContext, pannerOptions);
Примечание: Метод конструктора для создания узлов в настоящее время не поддерживается всеми браузерами. Более старые методы фабрики поддерживаются шире.
Здесь наши значения варьируются от -1 (крайне слева) до 1 (крайне справа). Опять же, давайте воспользуемся типом ввода диапазона для изменения этого параметра:
<input type="range" id="panner" min="-1" max="1" value="0" step="0.01" />
Мы используем значения из этого ввода для корректировки значений панорамирования аналогичным образом, как мы делали раньше:
const pannerControl = document.querySelector("#panner");
pannerControl.addEventListener(
"input",
() => {
panner.pan.value = pannerControl.value;
},
false,
);
Давайте снова скорректируем нашу звуковую схему, чтобы соединить все узлы вместе:
track.connect(gainNode).connect(panner).connect(audioContext.destination);
Осталось только попробовать приложение: Посмотрите финальную демонстрацию на CodePen.
Краткое описание
Отлично! У нас есть бумбокс, воспроизводящий нашу «ленту», и мы можем регулировать громкость и стереопанорамирование, что даёт нам довольно простую работающую звуковую схему.
Это охватывает достаточно базовых элементов, которые вам понадобятся, чтобы начать добавлять звук на свой веб-сайт или веб-приложение. API Web Audio имеет гораздо больше функциональности, но после того, как вы освоите концепцию узлов и сборки вашей звуковой схемы, мы можем перейти к рассмотрению более сложной функциональности.
Дополнительные примеры
Существуют другие примеры, которые помогут узнать больше об API Web Audio.
«Voice-change-O-matic» — это забавное приложение для изменения голоса и визуализации звука, которое позволяет выбрать различные эффекты и визуализации. Приложение довольно примитивное, но оно демонстрирует одновременное использование нескольких функций API Web Audio. (Запустите Voice-change-O-matic прямо сейчас).
Ещё одно приложение, разработанное специально для демонстрации API Web Audio, — это «Violent Theremin», простое веб-приложение, которое позволяет изменять высоту тона и громкость, перемещая указатель мыши. Оно также предоставляет психоделическое световое шоу (посмотрите исходный код Violent Theremin).
Также ознакомьтесь с нашим репозиторием webaudio-examples для получения дополнительных примеров.
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Using_Web_Audio_API