在JavaScript / HTML5中的声音效果

我使用HTML5来编写游戏; 我现在碰到的障碍是如何播放音效。

具体要求很less:

  • 播放和混合多种声音,
  • 多次播放相同的样本,可能会重叠播放,
  • 在任何时候中断播放样本,
  • 最好播放包含(低质量)原始PCM的WAV文件,但我当然可以转换这些文件。

我的第一个方法是使用HTML5 <audio>元素,并在我的页面中定义所有的声音效果。 Firefox播放WAV文件只是桃色,但多次调用#play不会真正播放样本多次。 从我对HTML5规范的理解中, <audio>元素也跟踪回放状态,所以这就解释了原因。

我的直接想法是克隆audio元素,所以我创build了下面的小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>元素实际上更像是一个stream媒体function,而不是播放音效的东西。

有没有一种巧妙的方法来实现这一点,我错过了,最好只使用HTML5和JavaScript?

我还应该提到,我的testing环境是Ubuntu 9.10上的Firefox 3.5。 我试过的其他浏览器 – Opera,Midori,Chromium,Epiphany – 产生了不同的结果。 有些不玩什么,有的则抛出exception。

HTML5 Audio对象

你不需要打扰<audio>元素。 HTML 5可让您直接访问Audio对象 :

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

在当前版本的规范中不支持混合。

要多次播放相同的声音,请创buildAudio对象的多个实例。 完成播放后,您也可以在对象上设置snd.currentTime=0


由于JS构造函数不支持后备<source>元素,所以应该使用

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

来testing浏览器是否支持Ogg Vorbis。


如果您正在编写游戏或音乐应用程序(不仅仅是玩家),则需要使用更高级的Web Audio API ,现在大多数浏览器都支持该API 。

W3C的WebAudio API

截至2012年7月, ChromeAudio现在支持WebAudio API ,至less在Firefox中得到部分支持,并预计在版本6中添加到IOS。

尽pipe它足够强大,可以用于基本任务的编程使用,但Audio元素从来不是为了为游戏等提供完整的audio支持。它的目的是允许将单个媒体内容embedded到页面中,类似于img标签。 尝试为游戏使用audio标签有很多问题:

  • 计时单与audio元素很常见
  • 每个声音实例都需要一个Audio元素
  • 加载事件并不完全可靠
  • 没有共同的音量控制,没有褪色,没有filter/效果

我使用WebAudio这篇入门文章开始使用WebAudio API。 FieldRunners WebAudio案例研究也是一个很好的阅读。

howler.js

对于游戏创作来说,最好的解决scheme之一就是使用一个库来解决我们在编写web代码时所面临的诸多问题,比如howler.js 。 howler.js将伟大的(但低级的) Web Audio API抽象为一个易于使用的框架。 如果Web Audio API不可用,它将尝试回退到HTML5audio元素 。

 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 ,它对于制作合成audio(例如音乐和效果)特别有用。 例如:

 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:

 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?] ); } 

概要

无论您需要播放单个声音文件,还是创build自己的基于html的音乐编辑器,效果生成器或video游戏,这些库都值得一看。

在某些情况下,您可能还想使用它来检测HTML 5audio:

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

HTML 5 JS检测function

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

这里有一种方法可以同时发挥同样的声音。 结合preloader,你就全部设置。 这至less与Firefox 17.0.1一起工作,还没有testing过。

 // 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个频道(比如在真正的老16位游戏上),我还没有开始使用HTML5audiofunction,但是你不需要4个<audio>元素,而使用循环发挥下一个音效? 你尝试过吗? 怎么了? 如果有效:要同时播放更多声音,只需添加更多<audio>元素。

我之前没有使用HTML5 <audio>元素,使用http://flash-mp3-player.net/中的一个Flash对象; – 我写了一个音乐测验( http://webdeavour.appspot.com/ )和当用户点击问题的button时,用它来播放音乐剪辑。 最初我每个问题有一个玩家,而且有可能把它们放在另一个的顶部,所以我改变了它,所以只有一个玩家,我指出了不同的音乐片段。

看看jai ( – > 镜像 )(javascriptaudio界面)网站。 从看他们的源头,他们似乎反复地调用play() ,他们提到他们的库可能适用于基于HTML5的游戏。

您可以同时触发多个audio事件,这些事件可用于创buildJavascript游戏,或通过某些背景音乐进行发言

要多次播放同一个样本,是不是可以这样做:

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

e是audio元素)

也许我完全误解了你的问题,你想同时播放多个音效吗? 那么这是完全错误的。

这是一个想法。 将所有audio加载到一个单独的audio元素中,其中src数据是连续audio文件中的所有样本(可能需要一些静音,以便您可以用较less的时间捕捉和剪切样本下一个样本出血的风险)。 然后,寻找样品,并在需要时播放。

如果你需要多个这样的播放,你可以使用相同的src创build一个额外的audio元素,以便将其caching。 现在,你有多个“轨道”。 你可以利用你最喜欢的资源分配scheme,如循环赛等利用曲目组。

您还可以指定其他选项,例如将声音排队到音轨中以播放资源,或切割当前播放的样本。

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();

我会推荐使用SoundJS ,一个我帮助开发的库。 它允许你编写一个可以在任何地方工作的代码库,SoundJS可以根据需要selectnetworkingaudio,htmlaudio或者flashaudio。

它会让你做所有你想要的东西:

  • 播放和混合多种声音,
  • 多次播放相同的样本,可能会重叠播放
  • 在任何时候中断播放样本
  • 播放包含WAV文件(取决于浏览器的支持)

希望有所帮助。

使用单个<audio>元素进行多重播放是不可能的。 你需要为此使用多个元素。

我在编程音乐盒卡片发生器时遇到了这个问题。 开始与不同的图书馆,但每次都有一个小故障。 正常的audio实施的滞后是不好的,没有多个戏剧…最终结束了使用lowlag库+ soundmanager:

http://lowlag.alienbill.com/和http://www.schillmania.com/projects/soundmanager2/

你可以看看这里的实现: http : //musicbox.grit.it/

我为多个浏览器播放生成了wav + ogg文件。 这个音乐盒播放器响应ipad,iphone,Nexus,mac,pc,…为我工作。

对于最广泛的兼容性,我真的会推荐使用可以与Javascript交互的小FLASH对象。 由于目前(以及不会很快)的支持,这比在HTML5中尝试audio元素要容易得多。

检查这个项目为例: http : //www.schillmania.com/projects/soundmanager/目前和高级版本: http : //www.schillmania.com/projects/soundmanager2/

我知道这是一个彻头彻尾的黑客,但认为我应该添加这个样品开放源码audio库我放在github前一段时间…

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

点击下面的链接后,在首页键上键入播放蓝调即兴(同时键入多个键等)

使用jThump库的示例>> http://davealger.com/apps/jthump/

它基本上是通过加载一个播放声音onReady()的页面的隐形<iframe>元素。

这当然不是很理想,但是你可以仅仅基于创造力来devise这个解决scheme(事实上它是开源的,并且可以在我试过的任何浏览器中运行),我希望这能让别人至lesssearch一些想法。

🙂

所选的答案将在IE浏览器除外。 我写了一个关于如何使它跨浏览器的教程= http://www.andy-howard.com/how-to-play-sounds-cross-browser-including-ie/index.html

这是我写的function。

 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"> 

最后你可以调用这个函数,并简单地通过这里的path:

 playSomeSounds("sounds/welcome.wav"); 

你总是可以尝试AudioContext它有限的支持,但它是networkingaudioAPI工作草案的一部分。 如果你打算在将来发布一些东西,这可能是值得的。 如果你只是编程铬和Firefox,你是金。