JavaScript / HTML5音效

我使用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;
};
});
}
};

所以现在我可以从Firebug控制台执行Snd.boom();并播放snd/boom.wav,但我仍然不能多次播放相同的示例。<audio>元素似乎更像是一个流特性,而不是用来播放声音效果的东西。

有什么聪明的方法可以做到这一点,最好只使用HTML5和JavaScript?

我还应该提一下,我的测试环境是Ubuntu 9.10上的Firefox 3.5。我尝试过的其他浏览器——Opera、Midori、Chromium、Epiphany——产生了不同的结果。有些不播放任何内容,有些则抛出异常。

301776 次浏览

为了多次播放相同的样本,是不是可以这样做:

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

(e是audio元素)

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

看看> <罢工胜利> < /罢工 (-> 镜子罢工< > < / >罢工) (javascript音频接口)网站。从它们的源代码来看,它们似乎反复调用play(),并且它们提到他们的库可能适用于基于html5的游戏。

你可以触发多个音频事件 同时,这是可以使用的 用于创建Javascript游戏,或者 有一个声音在说话 背景音乐< / p >

听起来你想要的是多声道的声音。让我们假设你有4个频道(就像在非常老的16位游戏中),我还没有时间玩HTML5音频功能,但你不需要4 <audio>元素和循环是用来播放下一个音效的?你试过吗?会发生什么呢?如果有效:要同时播放更多声音,只需添加更多<audio>元素。

我以前在没有HTML5 <audio>元素,使用一个小Flash对象从http://flash-mp3-player.net/ -我写了一个音乐测试(http://webdeavour.appspot.com/),并使用它来播放音乐剪辑当用户点击按钮的问题。一开始,每个问题都有一个播放器,而且可以互相播放,所以我改变了它,只有一个播放器,我指向不同的音乐片段。

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音频API,它现在是大多数浏览器支持

不可能用一个<audio>元素进行多镜头播放。为此需要使用多个元素。

在某些情况下,你可能也想用它来检测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/, ''));
}

我有个主意。将某一类声音的所有音频加载到一个单独的音频元素中,其中src数据是连续音频文件中的所有样本(可能需要一些静默,这样你就可以在超时时捕捉和剪切样本,从而减少下一个样本的风险)。然后,寻找样本,并在需要时播放它。

如果你需要多个音频元素来播放,你可以用相同的src创建一个额外的音频元素,这样它就会被缓存。现在,你有效地拥有多个“轨道”。你可以利用你最喜欢的资源分配方案(如轮询等)来利用轨道组。

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

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 (); 后来 < / p > sound.pause ();

Web音频API

截至2021年12月,Web Audio API在Chrome, Firefox, Safari和所有其他主要浏览器(当然不包括IE)中基本上都是支持

截至2012年7月,Web Audio API现在在Chrome中得到支持,至少在Firefox中得到部分支持,并计划在版本6时添加到IOS中。

尽管Audio元素足够健壮,可以以编程方式用于基本任务,但它从未为游戏和其他复杂应用程序提供完整的音频支持。它被设计为允许在页面中嵌入一个媒体片段,类似于img标记。在游戏中使用it存在很多问题:

  • 定时卡瓦在Audio元素中很常见
  • 每个声音实例都需要Audio元素
  • 加载事件还不是完全可靠的
  • 没有常用的音量控制,没有淡出,没有过滤器/效果

这里有一些很好的资源来开始使用Web Audio API:

这里有一种方法可以同时播放相同的声音。结合预加载器,你就万事俱备了。这至少适用于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");

我知道这是一个完全的黑客,但我认为我应该添加这个样本开源音频库我放在github上一段时间…

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

点击下面的链接后,在主行键上键入蓝调riff(也可以同时键入多个键等)。

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

它的基本工作原理是通过创建不可见的<iframe>元素来加载播放onReady()声音的页面。

这当然不理想,但你可以+1这个解决方案基于创造力(事实上,它是开源的,在我尝试过的任何浏览器中都可以工作),我希望这至少能给其他人一些搜索的想法。

:)

我建议使用SoundJS,这是我帮助开发的一个库。它允许你编写一个适用于任何地方的代码库,使用SoundJS选择web音频、html音频或flash音频。

它将允许你做所有你想做的事情:

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

希望这能有所帮助。

< a href = " http://goldfirestudios.com/blog/104/howler.js-Modern-Web-Audio-Javascript-Library " > howler.js < / >

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

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

< a href = " https://github.com/rserota/wad " > 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的音乐编辑器、效果生成器或视频游戏,这些库都值得一看。

我在编程一个音乐盒卡片生成器时遇到了这个问题。从不同的库开始,但每次都有某种程度的故障。正常音频执行的延迟很糟糕,没有多次播放……最终使用低延迟库+ soundmanager:

http://lowlag.alienbill.com/ 而且 http://www.schillmania.com/projects/soundmanager2/ < / p >

你可以在这里查看实现: http://musicbox.grit.it/ < / p >

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

所选答案将在除IE之外的所有程序中工作。我写了一个教程关于如何使它跨浏览器工作。下面是我写的函数:

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

你可以尝试AudioContext,它的支持有限,但它是Web音频API工作草案的一部分。如果你打算在未来发布一些东西,这可能是值得的。如果你只会为chrome和Firefox编程,那你就太棒了。

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>

Web音频API是这项工作的正确工具。在加载声音文件和播放它的过程中涉及到一些工作。幸运的是,有很多库可以简化这项工作。由于对声音感兴趣,我还创建了一个名为musquito的库,你也可以查看。

目前它只支持衰落的声音效果,我正在做其他的事情,比如3D空间化。