mirror of
https://github.com/wangdoc/webapi-tutorial.git
synced 2025-12-30 17:09:25 +08:00
124 lines
3.1 KiB
Markdown
124 lines
3.1 KiB
Markdown
# Web Audio API
|
||
|
||
Web Audio API 用于操作声音。这个 API 可以让网页发出声音。
|
||
|
||
## 基本用法
|
||
|
||
浏览器原生提供`AudioContext`对象,该对象用于生成一个声音的上下文,与扬声器相连。
|
||
|
||
```javascript
|
||
const audioContext = new AudioContext();
|
||
```
|
||
|
||
然后,获取音源文件,将其在内存中解码,就可以播放声音了。
|
||
|
||
```javascript
|
||
const context = new AudioContext();
|
||
|
||
fetch('sound.mp4')
|
||
.then(response => response.arrayBuffer())
|
||
.then(arrayBuffer => context.decodeAudioData(arrayBuffer))
|
||
.then(audioBuffer => {
|
||
// 播放声音
|
||
const source = context.createBufferSource();
|
||
source.buffer = audioBuffer;
|
||
source.connect(context.destination);
|
||
source.start();
|
||
});
|
||
```
|
||
|
||
## context.createBuffer()
|
||
|
||
`context.createBuffer()`方法生成一个内存的操作视图,用于存放数据。
|
||
|
||
```javascript
|
||
const buffer = audioContext.createBuffer(channels, signalLength, sampleRate);
|
||
```
|
||
|
||
`createBuffer`方法接受三个参数。
|
||
|
||
- channels:整数,表示声道。创建单声道的声音,该值为 1。
|
||
- signalLength:整数,表示声音数组的长度。
|
||
- sampleRate:浮点数,表示取样率,即一秒取样多少次。
|
||
|
||
`signalLength`和`sampleRate`这两个参数决定了声音的长度。比如,如果取样率是`1/3000`(每秒取样3000次),声音数组长度是6000,那么播放的声音是2秒长度。
|
||
|
||
接着,使用`buffer.getChannelData`方法取出一个声道。
|
||
|
||
```javascript
|
||
const data = buffer.getChannelData(0)
|
||
```
|
||
|
||
上面代码中,`buffer.getChannelData`的参数`0`表示取出第一个声道。
|
||
|
||
下一步,将声音数组放入这个声道。
|
||
|
||
```javascript
|
||
const data = buffer.getChannelData(0)
|
||
|
||
// singal 是一个声音数组
|
||
// singalLengal 是该数组的长度
|
||
for (let i = 0; i < signalLength; i += 1) {
|
||
data[i] = signal[i]
|
||
}
|
||
```
|
||
|
||
最后,使用`context.createBufferSource`方法生成一个声音节点。
|
||
|
||
```javascript
|
||
// 生成一个声音节点
|
||
const node = audioContext.createBufferSource();
|
||
// 将声音数组的内存对象,放入这个节点
|
||
node.buffer = buffer;
|
||
// 将声音上下文与节点连接
|
||
node.connect(audioContext.destination);
|
||
// 开始播放声音
|
||
node.start(audioContext.currentTime);
|
||
```
|
||
|
||
默认情况下,播放一次后就将停止播放。如果需要循环播放,可以将节点对象的`looping`属性设为`true`。
|
||
|
||
```javascript
|
||
node.looping = true;
|
||
```
|
||
|
||
## 过滤器
|
||
|
||
Web Audio API 原生提供了一些过滤器(filter),用来处理声音。
|
||
|
||
首先,使用`context.createBiquadFilter`方法建立过滤器实例。
|
||
|
||
```javascript
|
||
const filter = audioContext.createBiquadFilter();
|
||
```
|
||
|
||
然后,通过`filter.type`属性指定过滤器的类型。
|
||
|
||
```javascript
|
||
filter.type = 'lowpass';
|
||
```
|
||
|
||
目前,过滤器有以下这些类型。
|
||
|
||
- lowpass
|
||
- highpass
|
||
- bandpass
|
||
- lowshelf
|
||
- highshelf
|
||
- peaking
|
||
- notch
|
||
- allpass
|
||
|
||
然后指定过滤器的频率(frequency)属性。
|
||
|
||
```javascript
|
||
filter.frequency.value = frequency
|
||
```
|
||
|
||
最后,过滤器实例连接节点实例,就可以生效了。
|
||
|
||
```javascript
|
||
sourceNode.connect(filter);
|
||
```
|
||
|