JavaScript/HTML5中的音效

Sté*_*hen 314 javascript html5

我正在使用HTML5来编写游戏; 我现在遇到的障碍是如何播放声音效果.

具体要求很少:

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

我的第一种方法是使用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;
      };
    });
  }
};
Run Code Online (Sandbox Code Playgroud)

所以现在我可以Snd.boom();从Firebug控制台播放并播放snd/boom.wav,但我仍然无法多次播放相同的样本.看起来这个<audio>元素实际上更像是一个流媒体功能而不是播放音效的东西.

是否有一种聪明的方法可以实现这一点,我很想忘记,最好只使用HTML5和JavaScript?

我还要提一下,我的测试环境是Ubuntu 9.10上的Firefox 3.5.我尝试过的其他浏览器--Opera,Midori,Chromium,Epiphany--产生了不同的结果.有些人不玩任何东西,有些人抛出异常.

Kor*_*nel 445

HTML5 Audio对象

你不需要打扰<audio>元素.HTML 5允许您直接访问Audio对象:

var snd = new Audio("file.wav"); // buffers automatically when created
snd.play();
Run Code Online (Sandbox Code Playgroud)

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

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


由于JS构造函数不支持回退<source>元素,因此您应该使用

(new Audio()).canPlayType("audio/ogg; codecs=vorbis")
Run Code Online (Sandbox Code Playgroud)

测试浏览器是否支持Ogg Vorbis.


如果您正在编写游戏或音乐应用程序(不仅仅是一个播放器),您将需要使用更高级的Web Audio API,现在大多数浏览器都支持它.

  • `Audio`对象是自动缓冲的.它们的设计类似于`Image`对象,因此oldschool图像预加载技术也适用于音频. (18认同)
  • 这也适用于iOS.请注意,您*需要*使用某种用户操作(例如,单击按钮)来启动声音.你不能只在window.load()上做一个`snd.play()`. (5认同)
  • 如果不是因为<audio> html5元素允许多个源,我更喜欢这种方法,所以如果浏览器不支持mp3,你可以回退到ogg/wav.在javascript中需要一些技巧才能完成相同的操作. (2认同)
  • 在iOS 6上支持自动播放:您可以在window.load()上使用简单的snd.play()启动声音. (2认同)

Chr*_*nes 36

W3C的WebAudio API

截至2012年7月,Chrome现在支持WebAudio API,并且至少部分支持Firefox,并且将从版本6开始添加到IOS.

虽然它足够强大,可以编程方式用于基本任务,但Audio元素从未打算为游戏等提供完整的音频支持.它旨在允许将单个媒体嵌入到页面中,类似于img标签.尝试将音频标记用于游戏时存在很多问题:

  • 定时单对于Audio元素很常见
  • 每个声音实例都需要一个Audio元素
  • 负载事件尚不完全可靠
  • 没有常见的音量控制,没有褪色,没有滤镜/效果

我使用WebAudio入门文章开始使用WebAudio API.该炮塔防御WebAudio案例也很好看.

  • 这是一个比已接受的答案更好的答案,因为它侧重于问题的正确解决方案(WebAudio API),以及音频元素不是一个好的解决方案的原因,而不是试图将一个糟糕的解决方案与音频元素拼凑在一起 (3认同)

d13*_*d13 29

howler.js

对于游戏创作,最好的解决方案之一是使用一个库来解决我们在为Web编写代码时遇到的许多问题,例如howler.js.howler.js将伟大的(但是低级的)Web Audio 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);
Run Code Online (Sandbox Code Playgroud)

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}
})
Run Code Online (Sandbox Code Playgroud)

游戏的声音

另一个类似于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?]
  );
}
Run Code Online (Sandbox Code Playgroud)

摘要

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


Rob*_*Rob 9

在某些情况下,您可能还希望使用它来检测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/, ''));
}
Run Code Online (Sandbox Code Playgroud)


F-3*_*000 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();
}
Run Code Online (Sandbox Code Playgroud)

将其绑定到键盘键,然后享受:

player("step");
Run Code Online (Sandbox Code Playgroud)