在过去的几年里,随着最新的 HTML5 标准不断得到实施,浏览器的功能得到了巨大的提升。我们现在可以在画布上渲染高级图形,使用 WebSockets 实时通信,访问本地文件系统,创建离线应用等等。然而,音频领域却落后了。
HTML5 音频 元素非常适合一些特定用途(例如播放音乐),但当您需要低延迟、精确播放时,它就不那么有效了。
在过去的一年里,为浏览器开发了一种新的音频标准,它使开发人员可以直接访问音频数据。 Web Audio API 允许进行高精度和高性能的音频播放,以及 HTML5 音频元素无法实现的许多高级功能。但是,支持仍然有限,并且 API 比 HTML5 音频复杂得多。
介绍 howler.js
高性能音频最明显的用例是游戏,但大多数开发人员不得不使用 HTML5 音频并辅以 Flash 回退来获得浏览器兼容性。我的公司,GoldFire Studios,专门为开放网络开发游戏,我们着手寻找一个能够提供游戏所需音频支持的音频库,而无需依赖过时的技术。不幸的是,我们没有找到任何合适的库,因此我们自己编写了一个库并将其开源:howler.js。
Howler.js 默认使用 Web Audio API,并使用 HTML5 音频作为回退。该库极大地简化了 API,并自动处理所有棘手的问题。这是一个创建音频精灵(类似于 CSS 精灵,但使用音频文件)并播放其中一个声音的简单示例
var sound = new Howl({
urls: ['sounds.mp3', 'sounds.ogg'],
sprite: {
blast: [0, 2000],
laser: [3000, 700],
winner: [5000, 9000]
}
});
// shoot the laser!
sound.play('laser');
使用特性检测
在最基本的层面上,这是通过特性检测来实现的。以下代码片段检测 Web Audio API 是否可用,如果可用则创建音频上下文。目前对 Web Audio API 的支持包括 Chrome 10+、Safari 6+ 和 iOS 6+。它也正在 Firefox、Opera 和大多数其他移动浏览器中进行开发。
var ctx = null,
usingWebAudio = true;
if (typeof AudioContext !== 'undefined') {
ctx = new AudioContext();
} else if (typeof webkitAudioContext !== 'undefined') {
ctx = new webkitAudioContext();
} else {
usingWebAudio = false;
}
不同编解码器的音频支持在不同浏览器中也有所不同,因此我们使用 canPlayType
方法检测从您提供的源数组中哪个格式最适合使用
var audioTest = new Audio();
var codecs = {
mp3: !!audioTest.canPlayType('audio/mpeg;').replace(/^no$/,''),
ogg: !!audioTest.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,''),
wav: !!audioTest.canPlayType('audio/wav; codecs="1"').replace(/^no$/,''),
m4a: !!(audioTest.canPlayType('audio/x-m4a;') || audioTest.canPlayType('audio/aac;')).replace(/^no$/,''),
webm: !!audioTest.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,'')
};
简化操作
howler.js 的这两个关键组件允许库自动选择最佳的播放方法和要加载和播放的源文件。然后,库会抽象出这两个不同的 API,并将以下内容(一个简化的 Web Audio API 示例,不包含所有额外的回退支持和额外功能)
// create gain node
var gainNode, bufferSource;
gainNode = ctx.createGain();
gainNode.gain.value = volume;
loadBuffer('sound.wav');
var loadBuffer = function(url) {
// load the buffer from the URL
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
// decode the buffer into an audio source
ctx.decodeAudioData(xhr.response, function(buffer) {
if (buffer) {
bufferSource = ctx.createBufferSource();
bufferSource.buffer = buffer;
bufferSource.connect(gainNode);
bufferSource.start(0);
}
});
};
xhr.send();
};
(注意:某些旧的 已弃用的名称 是 createGainNode
和 noteOn
,如果您在网络上的其他示例中看到它们)
转换为以下内容
var sound = new Howl({
urls: ['sound.wav'],
autoplay: true
});
需要注意的是,Web Audio API 和 HTML5 音频都不是解决所有问题的完美方案。与任何事物一样,选择合适的工具来完成相应的工作非常重要。例如,您不希望使用 Web Audio API 加载大型背景音乐文件,因为您必须等待整个数据源加载完毕才能播放。HTML5 音频能够在下载开始后非常快地播放,这就是 howler.js 也实现了一个覆盖功能,允许您在应用中混合和匹配这两个 API 的原因。
浏览器中的音频已准备就绪
我经常听到有人说浏览器中的音频已损坏,并且在相当长的一段时间内将无法用于除基本音频流之外的任何用途。这与事实完全相反。当今的现代浏览器已经具备了这些工具。高质量的音频支持现已推出,Web Audio API 和 HTML5 结合起来,提供了真正的无插件、跨浏览器的音频支持。浏览器音频不再是二等公民,所以让我们停止将其视为二等公民,并继续为开放网络开发应用。
关于 James Simpson
James 是 GoldFire Studios 的首席执行官兼创始人,该公司使用 HTML5 为网络开发实时多人游戏。在过去的十多年里,自 13 岁开始开发以来,他的游戏和游戏相关产品已覆盖全球数百万用户。他经常在 Twitter 上发布关于 Javascript、HTML5、游戏开发和创业公司的推文。
关于 Robert Nyman [荣誉编辑]
Mozilla Hacks 的技术布道师和编辑。发表演讲和博客文章,主题包括 HTML5、JavaScript 和开放网络。Robert 是 HTML5 和开放网络的坚定支持者,自 1999 年以来一直在从事 Web 前端开发工作——在瑞典和纽约市。他还定期在 http://robertnyman.com 上发表博客文章,并且喜欢旅行和结识新朋友。
10 条评论