JavaScript / HTML5 中的音效

IT技术 javascript html html5-audio
2021-02-07 03:56:01

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

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

有没有一种聪明的方法来实现我所缺少的,最好只使用 HTML5 和 JavaScript?

我还应该提到,我的测试环境是 Ubuntu 9.10 上的 Firefox 3.5。我尝试过的其他浏览器——Opera、Midori、Chromium、Epiphany——产生了不同的结果。有些什么都不玩,有些抛出异常。

6个回答

HTML5Audio对象

你不需要理会<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,现在大多数浏览器都支持API

如果不是因为 <audio> html5 元素允许多个来源,我更喜欢这种方法,所以如果浏览器不支持 mp3,你可以回退到 ogg/wav。它需要在 javascript 中使用一些技巧才能完成相同的操作。
2021-03-13 03:56:01
在 iOS 6 上支持自动播放:您可以在 window.load() 上使用简单的 snd.play() 启动声音。
2021-03-18 03:56:01
这也适用于 iOS。但请注意,您需要使用某种用户操作(例如,单击按钮)来启动声音。你不能只snd.play()在 window.load() 上做一个
2021-03-20 03:56:01
Audio对象是自动缓冲的。它们的设计类似于Image对象,因此老式图像预加载技术也适用于音频。
2021-03-26 03:56:01
我还在使用这个<audio>标签,因为它更可控。但无论如何感谢您的信息!
2021-04-03 03:56:01

W3C 的WebAudio API

截至 2012 年 7 月,Chrome 现在支持WebAudio API,Firefox 至少部分支持,并计划从第 6 版开始添加到 IOS。

尽管它足够健壮,可以以编程方式用于基本任务,但 Audio 元素从未打算为游戏等提供完整的音频支持。它旨在允许将单个媒体嵌入页面中,类似于 img标签。尝试在游戏中使用 Audio 标签有很多问题:

  • 时间间隔在音频元素中很常见
  • 每个声音实例都需要一个 Audio 元素
  • 加载事件并不完全可靠,但
  • 没有常见的音量控制,没有衰落,没有过滤器/效果

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

这是一个比公认的更好的答案,因为它专注于问题的正确解决方案(WebAudio API),以及 Audio 元素不是一个好的解决方案的原因,而不是试图将一个糟糕的解决方案与 Audio 元素结合在一起
2021-03-20 03:56:01

咆哮.js

对于游戏创作,最好的解决方案之一是使用一个库来解决我们在为 Web 编写代码时面临的许多问题,例如howler.jshowler.js 将伟大(但低级)的Web Audio API抽象为一个易于使用的框架。如果 Web 音频 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);

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 的音乐编辑器、效果生成器或视频游戏。

非常好的框架,在移动设备上也很好用。你必须用 touchstart 来触发它......但是一旦完成它就可以开箱即用了:)
2021-03-24 03:56:01
到目前为止,howler.js 很棒。
2021-04-06 03:56:01
无法对游戏开发发表评论,但我将其用于界面中的一些较小的音频反馈,因此它绝对是一种享受。快速、简单和简单。
2021-04-09 03:56:01

在某些情况下,您可能还想使用它来检测 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/, ''));
}
感谢您注意到这一点。我从 has.js 学到了这个方法,但我发现它在 Firefox 中存在一些问题,根据 has.js 源代码,显然在 Opera 中也是如此。(参考:github.com/phiggins42/has.js/issues/48 github.com/phiggins42/has.js/blob/master/detect/audio.js#L19
2021-04-12 03:56:01

这是一种可以同时播放相同声音的方法。结合预加载器,一切就绪。这至少适用于 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");
@Pawel True,这不应该用作播放声音的主要方法,但据我所知,示例中的原理是同时播放相同声音多次的唯一方法,或者如 OP 所表达的那样, “重叠播放”。(不需要浏览器插件。)我在当前项目中的实际实现比我发布的示例代码复杂得多。
2021-03-21 03:56:01
不。我认为为每个单独的声音播放创建一个新对象根本不是解决方案。这是一种快速而肮脏的解决方法,但可以做得更好。
2021-03-23 03:56:01