Web Audio API 进入 Firefox

我们一直在 Firefox 中实现 Web Audio API,目前已在 Firefox NightlyFirefox Aurora 中实现了对该 API 的基本支持。Web Audio 提供了许多很酷的功能,可用于创建音乐应用程序、游戏以及基本上任何需要高级音频处理的应用程序。

功能

以下是一些功能示例

  • 在音频播放期间安排事件在精确的时间发生
  • 各种类型的音频滤波器,用于创建回声、降噪等效果。
  • 声音合成,用于创建电子音乐
  • 3D 定位音频,用于模拟游戏场景中声源移动等效果
  • 与 WebRTC 集成,以将效果应用于来自外部输入(WebRTC 通话、插入设备的吉他等)的声音,或应用于传输到 WebRTC 通话中另一方的音频
  • 分析音频数据以创建声音可视化器等。

代码示例

这是一个使用 Web Audio 可以构建的简单示例。假设您正在开发一款游戏,并且希望在玩家点击游戏画布时播放枪声。为了确保您不受网络延迟、音频解码器延迟等因素的影响,您可以使用 Web Audio 将音频预加载到缓冲区中,作为游戏加载过程的一部分,并在收到点击事件时精确地安排播放。

为了创建更清晰的音效,我们还可以持续播放声音,直到鼠标按下,并在释放鼠标时创建淡出效果。以下代码示例展示了如何执行此操作。

// Load the sound file from the network
var decodedBuffer;
var ctx = new AudioContext();
var xhr = new XMLHttpRequest();
xhr.open("GET", "gunshot.ogg", true);
xhr.responseType = "arraybuffer";
xhr.send();
xhr.onload = function() {
  // At this point, xhr.response contains the encoded data for gunshot.ogg,
  // so let's decode it into an AudioBuffer first.
  ctx.decodeAudioData(xhr.response, function onDecodeSuccess(buffer) {
    decodedBuffer = buffer;
  }, function onDecodeFailure() { alert('decode error!'); });
};

// Set up a mousedown/mouseup handler on your game canvas
canvas.addEventListener("mousedown", function onMouseDown() {
  var src = ctx.createBufferSource();
  src.buffer = decodedBuffer;                                      // play back the decoded buffer
  src.loop = true;                                                 // set the sound to loop while the mouse is down
  var gain = ctx.createGain();                                     // create a gain node in order to create the fade-out effect when the mouse is released
  src.connect(gain);
  gain.connect(ctx.destination);
  canvas.src = src;                                                // save a reference to our nodes to use it later
  canvas.gain = gain;
  src.start(0);                                                    // start playback immediately
}, false);
canvas.addEventListener("mouseup", function onMouseUp() {
  var src = canvas.src, gain = canvas.gain;
  src.stop(ctx.currentTime + 0.2);                                 // set up playback to stop in 200ms
  gain.gain.setValueAtTime(1.0, ctx.currentTime);
  gain.gain.linearRampToValueAtTime(0.001, ctx.currentTime + 0.2); // set up the sound to fade out within 200ms
}, false);

首个 WebAudio 实现和 WebKit

Web Audio API 最初是在 Google Chrome 中使用 webkitAudioContext 前缀实现的。我们一直在 W3C 音频工作组讨论该 API,并一直在尝试解决 API 早期版本中的一些问题。在某些情况下,这意味着我们需要破坏针对 webkitAudioContext 的代码的后向兼容性。

有一份 指南介绍如何将这些应用程序移植到标准 API。还有一个可用的 webkitAudioContext 猴子补丁,它可以自动处理其中的一些更改,这有助于使一些针对 webkitAudioContext 的代码在标准 API 中工作。

Firefox 中的实现

在 Firefox 中,我们实现了标准 API。如果您是一位对在 Web 上创建高级音频应用程序感兴趣的 Web 开发人员,审查 将 webkitAudioContext 代码移植到基于标准的 AudioContext 将非常有帮助,以便了解通过标准化过程对 API 进行的所有不向后兼容的更改。

我们目前希望在 Firefox 24 桌面版和 Android 版中发布 Web Audio 支持,除非发生一些意外情况导致我们延迟发布,但您现在可以在 Nightly 和 Aurora 上使用 API 的大部分功能。

还有一些缺失的部分,包括 MediaStreamAudioSourceNodeMediaElementAudioSourceNodeOscillatorNodePannerNode 的 HRTF 泛音。我们将在接下来的几周内在 Nightly 和 Firefox Aurora 上添加对 API 剩余部分的支持。

关于 Ehsan Akhgari

Ehsan 从事 Gecko 中的各种功能开发。

更多 Ehsan Akhgari 的文章…

关于 Robert Nyman [荣誉编辑]

技术布道师和 Mozilla Hacks 编辑。发表关于 HTML5、JavaScript 和开放 Web 的演讲和博客文章。Robert 是 HTML5 和开放 Web 的坚定支持者,自 1999 年以来一直从事 Web 前端开发工作,在瑞典和纽约市都有工作经历。他还在 http://robertnyman.com 上定期发表博客文章,并且热爱旅行和结识新朋友。

更多 Robert Nyman [荣誉编辑] 的文章…


16 条评论

  1. Jan Krutisch

    首先,感谢你们推动了这项工作,我真的很高兴看到它实现了!

    这可能不是提出这个问题的合适地方(我很乐意接受建议),但是否有将此功能引入 FFOS/B2G 的路线图?我没有找到关于 Gecko/Firefox 版本如何集成到 B2G 中的任何好的信息,这可能是一个更相关的问题,对吧?

    我之所以这样问,是因为正如大家可以想象的,并且我的实验也表明,移动设备上的音频性能是一个更大的问题,而使用 B2G,音频数据 API 由于其有限的可能性,是进行复杂实时音频的唯一途径,因此我猜想,在不断增长的 B2G 开发者社区中,许多人都会希望拥有这个 API。(尤其是游戏,但也包括音乐应用程序)

    2013 年 7 月 9 日 14:42

    1. Robert Nyman [编辑]

      很高兴你喜欢!
      总的来说,最初的 Firefox OS 版本与 Firefox 的正常发布计划没有直接关联。随着时间的推移,我们希望它们能够更加同步。

      我目前还不能提供 Firefox OS 中 Web Audio API 支持的确切日期/版本,但我们自然会计划这样做。

      2013 年 7 月 9 日 16:41

  2. Carl Davidá

    不要忘了通过拒绝添加对 MPEG-4 系列中任何内容的支持来完全破坏其可用性,就像您在 H.264 视频困境期间所做的那样。

    2013 年 7 月 9 日 17:52

    1. Ehsan Akhgari

      我们目前在 Windows Vista+ 和 Android 上支持 MP3 和 H.264 播放,并且正在努力支持其他平台。

      2013 年 7 月 9 日 18:01

    2. Robert Nyman [编辑]

      如果您对我们关于不受许可证限制的开放标准的立场感兴趣,我建议您阅读 视频、移动和开放 Web

      2013 年 7 月 10 日 01:48

  3. phi2x

    如果您可以提供一个 polyfill 使 Web Audio API 的行为类似于音频数据 API,那就太好了。

    因为我真正需要的是一种方法来以固定的 125kHz 推送我在 JS 中生成的音频数据,并让音频 API 自动处理它并向下/向上采样到扬声器。

    2013 年 7 月 9 日 23:05

  4. Clayton Gulick

    只是想过来表示感谢 - 你们做得非常棒,并且真正地推进了“Web 作为平台”的发展。结合 WebRTC,这将使我能够编写一些非常不可思议的东西。

    实现这样规模和复杂度的规范绝非易事,向整个团队致敬!

    2013 年 7 月 10 日 09:27

    1. Robert Nyman [编辑]

      感谢 Clayton!毫无疑问,WebRTC 和 Web Audio 都是将使开放 Web 变得更好的功能。

      2013 年 7 月 10 日 11:06

  5. Nixon

    在浏览器中克服音频操作的政治难题,做得好!

    当前的实现是否允许通过 getUserMedia 从麦克风获取音频源?

    谢谢

    2013 年 7 月 10 日 10:10

  6. Bingo

    这是个好消息,你们什么时候会将其推送到默认配置中?我也期待在 Mac 上支持 mp3 格式。

    2013 年 7 月 10 日 22:55

  7. Bozho

    您提到了合成。它是否使用 MIDI?

    2013 年 7 月 12 日 00:11

    1. Jan Krutisch

      虽然有一个 WebMidi 规范正在制定中(参见 http://webaudio.github.io/web-midi-api/),但这与 midi 无关。Web Audio API 的合成通过将音频生成器与滤波器和效果连接来实现。目前,Firefox 的实现缺少一个非常重要的构建块(OscillatorNode),但它即将到来。

      如果您不介意使用旧 API 的示例,并且该示例目前仅在 Chrome 或 Safari 中运行,请查看此处:http://jsfiddle.net/halfbyte/Ta8QX/

      2013 年 7 月 12 日 01:01

  8. Kong Ying Jenny

    希望如此

    2013 年 7 月 12 日 07:03

  9. Amp

    出于好奇……背景服务 API 有任何更新吗?

    2013 年 7 月 12 日 07:30

  10. pablocubico

    您好!您知道 API 什么时候会在 Firefox OS 和 Firefox for Android 中可用吗?

    2013 年 7 月 25 日 07:34

    1. Ehsan Akhgari

      它将在 Firefox for Android 中与桌面版同时发布。对于 Firefox OS,我们正在尽最大努力将其作为 1.2 版本的一部分发布。

      2013 年 7 月 25 日 14:48

本文的评论已关闭。