他们多次尝试推出强大的 audio API 来解决我上面提到的这些音频限制。推出的这些 API 中值得注意的就是火狐浏览器设计的 Audio Data API 原型实现。Mozilla 试图用
相比于 Audio Data API, Web Audio API 使用了全新的模式,完全独立于
标签的实现,尽管有些点与其它 web API 有相交(详见第7章)。它在 web 应用中提供了更高级的 Javascript API 用于处理和混合音频。此 API 的目的是实现现代游戏所需的能力,包括混音、处理、滤镜特效等这些只能在现代桌面应用程序产品所能提供的能力。最终需要的是一个多功能的 API 可以被用于处理多样的音频相关的任务,从游戏到可交互应用,到高级音频合成应用与可视化。
音效在游戏外的应用也同样重要。它们在命令行工具内交互之始就被应用于 UI 的交互上,当输出出错时就发出“哔”的一声。同样被应用现代交互 UI 上,一般用于提醒功能,铃声,也应用于音视频通讯比如 Skype。像 Google Now 和 Siri 这样的助手软件同样提供了丰富的音效反馈。当我们深入发掘这个世界,通用计算设备,语音和手势交互等可脱离屏幕的交互方式更加的依赖于音频的反馈。最后,对于视障视弱的计算机用户来说,音频提示,语音合成与识别提供了最主要的用户体验原则
Web Audio API 是建立在 audio context 音频上下文的概念之上的。音频上下文是描述音频所有节点的,这些节点定义了音频流是如何从起点(一般是音频文件)到目的地(一般就是你的扬声器)。当音频通过每个节点时,音频的属性可被修改和查看。最简单的音频上下文就是起始节点到结束节点的直连如图 1-1
Web Audio API 现已被 Chrome 和 Safari 浏览器实现(包含 IOS 6 手机版 Safari )并且通过 JavaScript 开放给了网页开发者。在这些浏览器上,音频上下文创建时需要加上 webkit 前缀,你不能直接使用 new AudioContext 而应该使用 new webkitAudioContext 创建。然而在未来在 API 足够稳定且多数浏览器供应商都实现了后前缀可去掉。Mozilla 已宣布在火狐浏览器上实现 Web Audio API,Opera 也开始参与进工作组。记得这一点即可,下面是通用的兼容写法:
var contextClass = (window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.oAudioContext || window.msAudioContext);
if (contextClass) {
// Web Audio API is available.
var context = new contextClass();
} else {
// Web Audio API is not available. Ask the user to use a supported browser.
}
一个音频上下文即可支持多个音频的输入与复杂的音频图谱,一般来讲,一个应用使用一个音频上下文即可。音频上下文的实例包含了众多的方法用于创建音频节点以及操作全局音频属性。幸运的是这些方法不需要加前缀,且相对稳定。 API 仍在变更,所以还是要小心会有大的变化。
使用 connect() 方法可以将任意音频节点输出连接至任意其它的音频节点。在以下例子,我们连接了音源节点的输出到 gain 节点,并将其输出连接到了结束节点:
// Create the source.
var source = context.createBufferSource();
// Create the gain node.
var gain = context.createGain();
// Connect source to filter, filter to destination.
source.connect(gain);
gain.connect(context.destination);
浏览器对不同音频格式的支持差别很大。一般来说,如果是在浏览器上, Web Audio API 的实现与
标签的实现是一样的。一般来说 WAV(一种简单的无损压缩格式)格式所有浏览器都支持。 MP3 仍然有专利阻碍,因为在一些纯开源的浏览器上不支持(比如,Firefox, Chromium)。不幸的是,不太流行但无专利阻碍的 OGG 格式在我写这篇文章时Safari 还是不支持。更多格式信息可查看这里 http://mzl.la/13kGelS
Firefox Chrommium 现在是支持 mp3 格式的。
声音的加载与播放
Web Audio API 将缓冲与音源(source)节点区别的很清晰。这样的架构有利于解构音频资源与播放状态。以唱片机为例,缓冲区就像唱片,而源就像播放指针,而在 Web Audio API 的世界中你可以同时在多个播放指针处播放同一个唱片。由于许多应用程序涉及同一缓冲区的多个版本同时播放,因此这种模式是必不可少的。举个例子, 如果您希望快速连续地发出多个弹跳球的声音,则只需要加载一次弹跳缓冲并安排多个音源(source)。
在 Web Audio API 加载一个音频样本,我们可以使用一个 XMLHttpRequest 加载并对加载的结果用context.decodeAudioData进行音频解码处理。这些都是异步的不会阻塞主 UI 进程:
如你所见以上的代码,Web Audio API 需要一些初始化的程序设置。在真正的游戏中,可以考虑围绕 Web Audio API 执行 JavaScript 抽象。例如后续的 BufferClass 类。它将所有东西都整合进一个简单的加载器上,加载器提供了设置路径,返回音频缓冲的功能。以下是如何使用 BufferLoader 类的代码:
window.onload = init;
var context;
var bufferLoader;
function init() {
context = new webkitAudioContext();
bufferLoader = new BufferLoader( context,
[
'../sounds/hyper-reality/br-jam-loop.wav',
'../sounds/hyper-reality/laughter.wav',
],
finishedLoading
);
bufferLoader.load();
}
function finishedLoading(bufferList) {
// 创建两具音源并把它们整合到一起播放
var source1 = context.createBufferSource();
var source2 = context.createBufferSource();
source1.buffer = bufferList[0];
source2.buffer = bufferList[1];
source1.connect(context.destination);
source2.connect(context.destination);
source1.start(0);
source2.start(0);
}
评论区