h5出现之前,要进行Web音频的展示,往往需要在浏览器加载flash等插件,h5中新增的<audio>标签允许用户进行一些基本的音频流操作,但是对于一些复杂的音频处理应用,其功能远远不能满足需求,而h5中提供的Audio API就派上了用场。H5的Web Audio API很强大,我们可以利用它去创建各种音频,甚至可以创建一段完整的音乐。在进行一些网站建设时,我们前端攻城狮可以摆脱网上搜索背景音乐或特定音频的束缚,完全可以自己创作一段满足网站需求的音频(比如游戏背景音乐,按键点击音乐等)。本文简单介绍一下音频处理流程以及Audio 的应用。
模块化音频节点
音频节点接口是一个个音频处理模块,包括音频源、音频输出、中间处理模块。音频节点模块化允许在两个音频节点之间进行任意连接,每个中间节点有输入和输出。源节点没有输入,只有一个输出;目的节点只有一个输入源没有输出,其他的节点,能够设置在源节点和目的节点之间。
在最简单的例子中,一个音频源可以直接输出,所有的音频路由在一个音频上下文(AudioContext)中进行:
如果要对源进行一些处理,就可以插入中间处理模块:
在这里,我们没有输入音频源,而是通过Oscillator创建了一个输入源。
创建音频步骤
- AudioContext
AudioContext是一个音频上下文,所有的音频节点处理在音频上下文中进行,类似于canvas中的context,进行音频操作前,需要获取音频上下文。
var AudioContext = new(window.AudioContext || window.webkitAudioContext)();
考虑IE的兼容性问题,如果是IE浏览器,则报错:
try {
var AudioContext = new(window.AudioContext || window.webkitAudioContext)();
} catch (e) {
Console.log('浏览器不支持 ');
}
var audioCtx = new AudioContext();
该上下文对象包含很多属性和方法,用于创建各种音频元和音频处理模块。
2.创建音频振荡器OscillatorNode
var oscillator = audioCtx.createOscillator(); //创建振荡器
oscillator.type = 'triangle'; //设置波形,可选值:'square','triangle','sawtooth','sine'
oscillator.frequency.value = 198; //设置频率
声音的本质其实是震动,通过定义震动的频率,振幅,波形可以发出不同的声音,这也是我们创建声音的本质。因此波形不一样,最终的声音也就不一样,波还受频率影响,最终表现为不一样的音调高低。
createOscillator()是AudioContext对象的一个方法,该方法创建一个音频振荡器节点。振荡器是一个重复的波形。它有一个频率和振幅。一个振荡器最重要的特征,除了频率和振幅,是它波形的形状。四种的振荡器波形分别是正弦、三角、方形、锯齿:
利用振荡器输出一个音调。不同的波形决定了音调的不同。
3.创建音量节点GainNode
var gainNode = audioCtx.createGain(); //创建音量控制节点
gainNode.gain.setValueAtTime(0, audioCtx.currentTime);
gainNode.gain.linearRampToValueAtTime(volume, audioCtx.currentTime + 0.01);
我们可以通过创建一个音量控制节点GainNode来调节音量大小。GainNode的gain返回一个AduioParam对象,这里调用AudioParam.setValueAtTime()方法,该方法支持两个参数,一个是音量(范围0-1),另一个参数是时间。这里调用setValueAtTime(0, audioCtx.currentTime)
表示当下就把音量设为0
,也就是没声音。
linearRampToValueAtTime()
方法表示音量在某时间线性变化到某值,这里linearRampToValueAtTime(1, audioCtx.currentTime + 0.01)
实际上表示的是在0.01
秒的时间内,声音音量线性从0
到1
。
4.关联中间模块
关联振荡器和音量控制器:
oscillator.connect(gainNode);
音量控制器关联目的输出节点:
gainNode.connect(audioCtx.destination);
5.播放音频
出现声音:
oscillator.start(audioCtx.currentTime);
6.音频音量变化,淡入淡出
gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 1);
exponentialRampToValueAtTime()
方法表示音量在某时间指数变化到某值,这里的exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 1)
实际上表示的是在1.00
秒的时间内,音量由之前的1
以指数曲线的速度降到极低的0.001
音量。
7. 关闭音频
oscillator.stop(audioCtx.currentTime + 1)
1秒后,声音关闭。
通过以上步骤,实现了创建音频,控制音量到停止音频播放的应用。利用以上原理,可以制作一些小应用。戳这里,查看Audio钢琴小demo。效果图如下,点击不同的按键,会调整频率,达到发出不同音调声音的目的。github地址:https://github.com/jianfeng418/h5-pinao