Звуковые эффекты в JavaScript/HTML5

Я использую HTML5 для программирования игр; препятствие, с которым я столкнулся сейчас, - это как воспроизвести звуковые эффекты.

Конкретные требования немногочисленны:

  • Воспроизведение и смешивание нескольких звуков,
  • Воспроизведение одного и того же образца несколько раз, возможно перекрытие воспроизведения,
  • Прерывание воспроизведения образца в любой точке,
  • Желательно воспроизводить файлы WAV, содержащие (низкокачественные) raw PCM, но я могу их преобразовать, конечно.

Мой первый подход состоял в том, чтобы использовать элемент HTML5 <audio> и определять все звуковые эффекты на моей странице. Firefox воспроизводит файлы WAV просто персиковые, но вызов #play несколько раз не воспроизводит образец несколько раз. Из моего понимания спецификации HTML5 элемент <audio> также отслеживает состояние воспроизведения, поэтому это объясняет.

Я сразу подумал, что нужно клонировать аудио элементы, поэтому я создал следующую крошечную библиотеку JavaScript, чтобы сделать это для меня (зависит от jQuery):

var Snd = {
  init: function() {
    $("audio").each(function() {
      var src = this.getAttribute('src');
      if (src.substring(0, 4) !== "snd/") { return; }
      // Cut out the basename (strip directory and extension)
      var name = src.substring(4, src.length - 4);
      // Create the helper function, which clones the audio object and plays it
      var Constructor = function() {};
      Constructor.prototype = this;
      Snd[name] = function() {
        var clone = new Constructor();
        clone.play();
        // Return the cloned element, so the caller can interrupt the sound effect
        return clone;
      };
    });
  }
};

Итак, теперь я могу сделать Snd.boom(); с консоли Firebug и воспроизвести snd/boom.wav, но я все еще не могу воспроизвести один и тот же образец несколько раз. Похоже, что элемент <audio> - это скорее больше потоковая функция, чем нечто, для воспроизведения звуковых эффектов.

Есть ли умный способ сделать это, что я пропал без вести, желательно используя только HTML5 и JavaScript?

Я также должен отметить, что моя тестовая среда - Firefox 3.5 на Ubuntu 9.10. Другие браузеры, которые я пробовал - Opera, Midori, Chromium, Epiphany - произвели разные результаты. Некоторые не играют ничего, а некоторые бросают исключения.

Ответ 1

HTML5 Audio объекты

Вам не нужно беспокоиться о элементах <audio>. HTML 5 позволяет напрямую обращаться к Audio objects:

var snd = new Audio("file.wav"); // buffers automatically when created
snd.play();

Нет поддержки для смешивания в текущей версии спецификации.

Чтобы воспроизвести один и тот же звук несколько раз, создайте несколько экземпляров объекта Audio. Вы также можете установить snd.currentTime=0 на объект после завершения воспроизведения.


Поскольку конструктор JS не поддерживает резервные элементы <source>, вы должны использовать

(new Audio()).canPlayType("audio/ogg; codecs=vorbis")

чтобы проверить, поддерживает ли браузер Ogg Vorbis.


Если вы пишете игру или музыкальное приложение (больше, чем просто плеер), вы захотите использовать более продвинутый API веб-аудио, который теперь поддерживается большинством браузеров.

Ответ 2

API WebAudio по W3C

По состоянию на июль 2012 года API WebAudio теперь поддерживается в Chrome и, по крайней мере, частично поддерживается в Firefox, и предполагается, что он будет добавлен в IOS с версии 6.

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

  • Временные пропуски являются общими для аудиоэлементов.
  • Для каждого экземпляра звука вам нужен элемент Audio
  • События загрузки не являются полностью надежными, но
  • Нет общих регуляторов громкости, без затухания, нет фильтров/эффектов

Я использовал эту Начало работы с WebAudio, чтобы начать работу с API WebAudio. FieldRunners WebAudio Case Study также хорошо читается.

Ответ 3

howler.js

Для разработки игр одним из лучших решений является использование библиотеки, которая решает многие проблемы, с которыми мы сталкиваемся при написании кода для Интернета, например howler.js., howler.js абстрагирует большой (но низкоуровневый) Web Audio API в простой в использовании фреймворк. Он попытается вернуться к HTML5 Audio Element, если API веб-аудио недоступен.

var sound = new Howl({
  urls: ['sound.mp3', 'sound.ogg']
}).play();
// it also provides calls for spatial/3d audio effects (most browsers)
sound.pos3d(0.1,0.3,0.5);

wad.js

Другая отличная библиотека wad.js, которая особенно полезна для создания синтезаторного звука, такого как музыка и эффекты. Например:

var saw = new Wad({source : 'sawtooth'})
saw.play({
    volume  : 0.8,
    wait    : 0,     // Time in seconds between calling play() and actually triggering the note.
    loop    : false, // This overrides the value for loop on the constructor, if it was set. 
    pitch   : 'A4',  // A4 is 440 hertz.
    label   : 'A',   // A label that identifies this note.
    env     : {hold : 9001},
    panning : [1, -1, 10],
    filter  : {frequency : 900},
    delay   : {delayTime : .8}
})

Звук для игр

Другая библиотека, похожая на Wad.js, это "Звук для игр ", она больше ориентирована на производство эффектов, предоставляя аналогичный набор функций через относительно разные (и, возможно, более сжатые ощущения) API:

function shootSound() {
  soundEffect(
    1046.5,           //frequency
    0,                //attack
    0.3,              //decay
    "sawtooth",       //waveform
    1,                //Volume
    -0.8,             //pan
    0,                //wait before playing
    1200,             //pitch bend amount
    false,            //reverse bend
    0,                //random pitch range
    25,               //dissonance
    [0.2, 0.2, 2000], //echo array: [delay, feedback, filter]
    undefined         //reverb array: [duration, decay, reverse?]
  );
}

Резюме

Каждая из этих библиотек стоит посмотреть, нужно ли воспроизводить один звуковой файл или создать собственный HTML-редактор, генератор эффектов или видеоигру.

Ответ 4

Вы также можете использовать это для обнаружения аудио HTML 5 в некоторых случаях:

http://diveintohtml5.ep.io/everything.html

HTML 5 Функция обнаружения JS

function supportsAudio()
{
    var a = document.createElement('audio'); 
    return !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
}

Ответ 5

Здесь один из способов, позволяющих одновременно воспроизводить один и тот же звук. Комбинируйте с предварительным загрузчиком, и все готово. Это, по крайней мере, работает с Firefox 17.0.1, еще не проверил его ни с чем.

// collection of sounds that are playing
var playing={};
// collection of sounds
var sounds={step:"knock.ogg",throw:"swing.ogg"};

// function that is used to play sounds
function player(x)
{
    var a,b;
    b=new Date();
    a=x+b.getTime();
    playing[a]=new Audio(sounds[x]);
    // with this we prevent playing-object from becoming a memory-monster:
    playing[a].onended=function(){delete playing[a]};
    playing[a].play();
}

Привяжите это к клавише клавиатуры и наслаждайтесь:

player("step");

Ответ 6

Посмотрите jai (- > mirror) (javascript audio interface). От взгляда на их источник они, как представляется, многократно звонят play(), и они отмечают, что их библиотека может быть подходящей для использования в играх на базе HTML5.

Вы можете запускать несколько звуковых событий одновременно, которые могут быть использованы для создания Javascript-игр или имея голос, говорящий над некоторыми фоновая музыка

Ответ 7

Похоже, что вы хотите многоканальные звуки. Предположим, что у вас есть 4 канала (например, в действительно старых 16-разрядных играх), пока я еще не играл с аудиофункцией HTML5, но вам просто не нужно 4 <audio> элементы и цикл, который используется для воспроизведения следующего звукового эффекта? Вы пробовали это? Что происходит? Если это работает: Чтобы воспроизводить больше звуков одновременно, просто добавьте больше <audio> элементы.

Я сделал это раньше без HTML5 <audio> элемент, используя небольшой Flash-объект из http://flash-mp3-player.net/ - я написал музыкальную викторину (http://webdeavour.appspot.com/) и использовал его для воспроизведения клипов музыки, когда пользователь нажал кнопку для вопроса. Первоначально у меня был один игрок на вопрос, и можно было сыграть их поверх всех друг друга, поэтому я изменил его, так что был только один игрок, который я указал на разные клипы.

Ответ 8

Чтобы воспроизвести один и тот же образец несколько раз, не было бы возможным сделать что-то вроде этого:

e.pause(); // Perhaps optional
e.currentTime = 0;
e.play();

(e - это аудио-элемент)

Возможно, я полностью неправильно понял вашу проблему, вы хотите, чтобы звуковой эффект воспроизводился несколько раз в одно и то же время? Тогда это совершенно неправильно.

Ответ 9

Вот идея. Загрузите весь свой звук для определенного класса звуков в один отдельный аудиоэлемент, где данные src - все ваши образцы в непрерывном звуковом файле (возможно, требуется некоторое молчание между ними, чтобы вы могли поймать и вырезать образцы с тайм-аутом с меньшим риск кровотечения к следующему образцу). Затем ищите образец и воспроизводите его, когда это необходимо.

Если вам нужно больше одного из них, вы можете создать дополнительный аудиоэлемент с тем же src, чтобы он был кэширован. Теперь у вас есть несколько "треков". Вы можете использовать группы треков с вашей любимой схемой выделения ресурсов, например Round Robin и т.д.

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

Ответ 11

Я бы рекомендовал использовать SoundJS, библиотеку, с которой я помогаю. Это позволяет вам писать единую базу кода, которая работает повсеместно, с использованием SoundJS для веб-аудио, html-аудио или флеш-аудио.

Это позволит вам сделать все, что вам нужно:

  • Воспроизведение и смешивание нескольких звуков,
  • Воспроизведение одного и того же образца несколько раз, возможно перекрытие воспроизведения
  • Прерывание воспроизведения образца в любой точке
  • воспроизводить WAV файлы, содержащие (в зависимости от поддержки браузера)

Надеюсь, что это поможет.

Ответ 12

Невозможно выполнить многократное воспроизведение с помощью одного элемента <audio>. Для этого вам нужно использовать несколько элементов.

Ответ 13

Я столкнулся с этим при программировании генератора карт музыкальных карт. Начались с разных библиотек, но каждый раз возникал сбой. Задержка в нормальной реализации звука была плохая, не было многократных игр... в конечном итоге закончилась использование библиотеки lowlag + soundmanager:

http://lowlag.alienbill.com/ а также http://www.schillmania.com/projects/soundmanager2/

Вы можете проверить реализацию здесь: http://musicbox.grit.it/

Я создал wav + ogg файлы для нескольких браузеров. Этот проигрыватель музыки работает с учетом ipad, iphone, Nexus, mac, pc,... работает для меня.

Ответ 14

Для самой широкой совместимости я бы рекомендовал использовать небольшой FLASH-объект, который может взаимодействовать с Javascript. Это намного проще, чем пытаться использовать элемент audio в HTML5 из-за текущей (и не будущей) поддержки.

проверьте этот проект в качестве примера: http://www.schillmania.com/projects/soundmanager/ текущая и расширенная версия: http://www.schillmania.com/projects/soundmanager2/

Ответ 15

Я знаю, что это полный взлом, но я подумал, что должен добавить эту тестовую библиотеку с открытым исходным кодом, которую я поставил на github некоторое время назад...

https://github.com/run-time/jThump

После нажатия ссылки ниже введите в главные строки строки, чтобы воспроизвести блюзовый рифф (также введите несколько ключей одновременно и т.д.).

Пример с использованием библиотеки jThump → http://davealger.com/apps/jthump/

В основном он работает, создавая невидимые элементы <iframe>, которые загружают страницу, воспроизводящую звук onReady().

Это, безусловно, не идеальный, но вы могли бы использовать это решение на основе только творчества (и того факта, что он работает с открытым исходным кодом и работает в любом браузере, который я пробовал) Я надеюсь это дает кому-то еще хотя бы некоторые идеи.

:)

Ответ 16

Выбранный ответ будет работать во всем, кроме IE. Я написал учебник о том, как заставить его работать cross browser = http://www.andy-howard.com/how-to-play-sounds-cross-browser-including-ie/index.html

Вот функция, которую я написал:

function playSomeSounds(soundPath)
 {

 var trident = !!navigator.userAgent.match(/Trident\/7.0/);
 var net = !!navigator.userAgent.match(/.NET4.0E/);
 var IE11 = trident && net
 var IEold = ( navigator.userAgent.match(/MSIE/i) ? true : false );
 if(IE11 || IEold){
 document.all.sound.src = soundPath;
 }
 else
 {
 var snd = new Audio(soundPath); // buffers automatically when created
 snd.play();
 }
 };

Вам также нужно добавить следующий тег на страницу html:

<bgsound id="sound">

Наконец, вы можете вызвать функцию и просто пройти по пути здесь:

playSomeSounds("sounds/welcome.wav");

Ответ 17

Вы всегда можете попробовать AudioContext, у него ограниченная поддержка, но это часть веб-аудио api рабочий проект. Возможно, это будет стоить того, если вы планируете выпускать что-то в будущем. И если вы только программируете на Chrome и Firefox, вы золотые.