Звуковые эффекты в 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 ]

2 голосов
/ 12 января 2012

http://robert.ocallahan.org/2011/11/latency-of-html5-sounds.html

http://people.mozilla.org/~roc/audio-latency-repeating.html

Работает нормально в Firefox и Chrome для меня.

Чтобы остановить звук, который вы начали, сделайте var sound = document.getElementById ("shot"). cloneNode (true); sound.play (); и позже sound.pause ();

1 голос
/ 01 апреля 2014

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

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

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

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

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

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

0 голосов
/ 11 апреля 2019

Web Audio API - правильный инструмент для этой работы. Существует небольшая работа, связанная с загрузкой звуковых файлов и их воспроизведением. К счастью, существует множество библиотек, которые упрощают работу. Заинтересовавшись звуками, я также создал библиотеку под названием musquito , которую вы также можете проверить.

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

0 голосов
/ 29 марта 2019

var AudioContextFunc = window.AudioContext || window.webkitAudioContext;
var audioContext = new AudioContextFunc();
var player=new WebAudioFontPlayer();
var instrumVox,instrumApplause;
var drumClap,drumLowTom,drumHighTom,drumSnare,drumKick,drumCrash;
loadDrum(21,function(s){drumClap=s;});
loadDrum(30,function(s){drumLowTom=s;});
loadDrum(50,function(s){drumHighTom=s;});
loadDrum(15,function(s){drumSnare=s;});
loadDrum(5,function(s){drumKick=s;});
loadDrum(70,function(s){drumCrash=s;});
loadInstrument(594,function(s){instrumVox=s;});
loadInstrument(1367,function(s){instrumApplause=s;});
function loadDrum(n,callback){
  var info=player.loader.drumInfo(n);
  player.loader.startLoad(audioContext, info.url, info.variable);
  player.loader.waitLoad(function () {callback(window[info.variable])});
}
function loadInstrument(n,callback){
  var info=player.loader.instrumentInfo(n);
  player.loader.startLoad(audioContext, info.url, info.variable);
  player.loader.waitLoad(function () {callback(window[info.variable])});
}
function uhoh(){
  var when=audioContext.currentTime;
  var b=0.1;
  player.queueWaveTable(audioContext, audioContext.destination, instrumVox, when+b*0, 60, b*1);
  player.queueWaveTable(audioContext, audioContext.destination, instrumVox, when+b*3, 56, b*4);
}
function applause(){
  player.queueWaveTable(audioContext, audioContext.destination, instrumApplause, audioContext.currentTime, 54, 3);
}
function badumtss(){
  var when=audioContext.currentTime;
  var b=0.11;
  player.queueWaveTable(audioContext, audioContext.destination, drumSnare, when+b*0, drumSnare.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumLowTom, when+b*0, drumLowTom.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumSnare, when+b*1, drumSnare.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumHighTom, when+b*1, drumHighTom.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumSnare, when+b*3, drumSnare.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumKick, when+b*3, drumKick.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumCrash, when+b*3, drumCrash.zones[0].keyRangeLow, 3.5);
}
<script src='https://surikov.github.io/webaudiofont/npm/dist/WebAudioFontPlayer.js'></script>
<button onclick='badumtss();'>badumtss</button>
<button onclick='uhoh();'>uhoh</button>
<button onclick='applause();'>applause</button>
<br/><a href='https://github.com/surikov/webaudiofont'>More sounds</a>
0 голосов
/ 29 августа 2016

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

0 голосов
/ 13 мая 2014

Выбранный ответ будет работать во всем, кроме IE. Я написал учебник о том, как заставить его работать в разных браузерах = http://www.andy -howard.com / как проигрывать звуки-в разных браузерах, включая-т.е. / 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");
0 голосов
/ 29 марта 2013

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

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

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

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

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

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

:)

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