Звуковые эффекты в JavaScript / HTML5 - PullRequest
310 голосов
/ 19 декабря 2009

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

Особых требований немного:

  • Воспроизведение и смешивание нескольких звуков,
  • Воспроизведение одного и того же семпла несколько раз, возможно, с перекрывающимся воспроизведением
  • Прервать воспроизведение сэмпла в любой точке,
  • Предпочтительно воспроизводить файлы WAV, содержащие (низкое качество) необработанные 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 - дали разные результаты. Некоторые ничего не играют, а некоторые бросают исключения.

Ответы [ 18 ]

442 голосов
/ 20 декабря 2009

HTML5 Audio объекты

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

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.


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

36 голосов
/ 19 июля 2012

WebAudio API от W3C

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

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

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

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

28 голосов
/ 23 октября 2013

howler.js

Для разработки игр одним из лучших решений является использование библиотеки, которая решает многие проблемы, с которыми мы сталкиваемся при написании кода для Интернета, например howler.js . howler.js абстрагирует отличный (но низкоуровневый) Web Audio API в простой в использовании фреймворк. Он попытается вернуться к HTML5 Audio Element , если Web Audio 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, - это " Sound for Games ", она больше ориентирована на создание эффектов, обеспечивая при этом аналогичный набор функций с помощью относительно отличного (и, возможно, более лаконичного) 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, генератор эффектов или видеоигру.

9 голосов
/ 01 января 2011

Вы также можете использовать это для обнаружения звука 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 голосов
/ 24 декабря 2012

Вот один метод, позволяющий воспроизводить даже один и тот же звук одновременно. Объедините с preloader, и все готово. Это работает, по крайней мере, с 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");
4 голосов
/ 19 декабря 2009

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

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

4 голосов
/ 19 декабря 2009

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

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

3 голосов
/ 04 апреля 2011

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

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

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

3 голосов
/ 19 декабря 2009

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

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

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

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

2 голосов
/ 03 октября 2013

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

Это позволит вам делать все, что вы хотите:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...