Web Audio API 小教程(2): 入门篇

(续上节:Web Audio API 小教程(1): 它能做什么?

【Gitbook 版本】

概念:AudioContext

AudioContext 是一个管理、播放声音的对象,大概跟 Canvas 的 context 差不多。

我们可以在 AudioContext 里“画”出各种声音。

初始化 AudioContext

1
2
var AudioContext = window.AudioContext || window.webkitAudioContext;
var ctx = new AudioContext();

加载、解码mp3文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 创建一个XMLHttpRequest请求对象
var request = new XMLHttpRequest();
// 请求一个MP3文件
request.open('GET', 'https://path/to/audio.mp3', true);
// Web Audio API 固定为 "arraybuffer"
request.responseType = 'arraybuffer';
// 加载完成后解码
request.onload = function() {
ctx.decodeAudioData(request.response, function(buffer) {
// 获得解码后的数据:buffer
// 这里可以立即播放解码后的 buffer,也可以把 buffer 值先存起来
// 这个 playBuffer() 将在下文讲解如此实现
playBuffer(buffer);
}, function (){
// 这里写解码出错的处理(例如文件损坏、格式不对等)
});
};
// 发送这个XMLHttpRequest请求
request.send();
  1. 使用 XMLHTTPRequest 对象加载mp3资源数据
  2. 加载完成后,mp3数据将被存储到 request.response 里
  3. 使用 ctx.decodeAudioData 把mp3解码成wav格式的 buffer(异步)

播放声音

1
2
3
4
5
6
function playBuffer(buffer) { 
var sourceNode = ctx.createBufferSource();
sourceNode.buffer = buffer;
sourceNode.connect(ctx.destination);
sourceNode.start(0);
}
  1. 加载mp3并解码得到 buffer 之后…
  2. 创建 sourceNode 对象(下文将详解这个对象);
  3. buffer 传入 sourceNode.buffer 属性;
  4. sourceNode 连接到 AudioContext 的音频输出口“.destination”;
  5. sourceNode 执行 .start(0),声音就出来了。

sourceNode 处理 buffer,然后传输到 destination

小结:播放声音的基本步骤

  1. 初始化 AudioContext 对象
  2. 使用 XMLHTTPRequest 对象从服务器获取mp3
  3. 把mp3数据用 ctx.decodeAudioData 转换成wav格式的 buffer
  4. 使用 SourceNode 对象(下文将详解这个对象)把 buffer 装起来
  5. SourceNode 连接到音频输出口 destination
  6. 执行 .start(0) 触发 SourceNode 开始播放声音

概念:SourceNode

SourceNode 是记录和输出波形声音的对象。

要使用 AudioContext 对象的 createBufferSource 方法创建,而不是 new。

1
var sourceNode = ctx.createBufferSource();

它是其中一种 AudioNode(下文将详解)。

概念:AudioNode

这是一种由 AudioContext 生成的基本对象,用于生成或者处理音频波形数据。

AudioContext 提供很多特定的 AudioNode 可供使用,例如均衡器、滤波器、振荡器……

AudioNode 大体可分3类。

第一种:作为【声音源头】的 AudioNode,用于存储或生成声音(例如上文的 SourceNode):

作为**声音源头**的 AudioNode

第二种:作为【过滤器】的 AudioNode,会对输入(In)的声音进行处理之后再输出(Out)。

(有些 AudioNode 可以有多个输入(In),然后对它们做混音后再输出。)

作为**过滤器**的 AudioNode

第三种:【destination】 是特殊的 AudioNode,它收到声音之后会直接传到耳机或扬声器,让我们最终听到声音。

声音传入 **destination** 就能让我们最终听到声音

把 AudioNode 连接起来…

多个 AudioNode 连接起来,可得到最终的声音:

1
2
3
4
5
sourceNode.connect(node1);
node1.connect(node2);
node2.connect(node3);
// ......
nodeN.connect(ctx.destination);

多个 AudioNode 连接起来,可得到最终的声音

注意

一般来说,作为【声音源头】的 AudioNode (例如 SourceNode,以及将于进阶篇提及的 OscillatorNode),它的声音播放完毕后,它自身会立即销毁。

若需要再次播放,必须重新创建它。

例如,对于 SourceNode,每当重新播放同一个音频,每次都需要重新执行以下代码:

1
2
3
4
5
6
function playBuffer(buffer) { 
var sourceNode = ctx.createBufferSource();
sourceNode.buffer = buffer;
sourceNode.connect(ctx.destination);
sourceNode.start(0);
}

接下来…

下一节:Web Audio API 小教程(3): 初级使用篇

将对 SourceNode 做更多的控制,例如中途停止、循环播放、调节音量,并介绍如何实现多个 SourceNode 同时播放。

一个更好的选择

如果觉得 Web Audio API 写起来代码量太大,那么可以考虑使用我已经封装好的 Javascript 库 —— Benz Audio Engine

项目 Github:https://github.com/BenzLeung/benz-audio-engine

Benz Audio Engine 只把 Web Audio API 常用功能做个简单的封装,实现音效的加载、播放、暂停、音量调节。简单、干净,没有多余的功能。

参考文献

Benz Leung wechat
同步更新的微信公众号
0%