webAudio是网页上除了audio之外可以用来播放声音的东西,和audio相比,webAudio就显得更加专业,可操作性更强。今天我们就通过几个小demo来简单认识一下webAudio,看看这东西怎么玩。利用webAudio发声
我们知道audio是无法自己发出声音的,只能通过链接到mp3等文件,然后播放发声,但是webAduio自己是可以发出声音的:
上面就是一个简单的demo,鼠标移不同的键上会有不同的声音,这个是怎么做到的呢?
在讲解之前,我先抛出一个webAudio播放声音的一般套路,因为和audio那种简单的播放声音方式不同,webAudio播放声音是有一套流程的。
webAudio播放声音必须要有一个声音源,这个声音源可以来自声音数据,也可以利用webAudio创造一个音调;有了声音源之后,我们就可以在后面链接处理器,比如控制音量的处理器,声音波形的处理器等,过滤器可以多个,一个链接一个;最后需要链接扬声器,播放声音。
知道了上面的套路之后,那么对于理解代码将会有所帮助,现在看看webAudio播放声音的关键代码:
var oscillator = audioCtx.createOscillator(); //webAudio创造的音调
var gainNode = audioCtx.createGain(); //控制音量的过滤器
oscillator.connect(gainNode);//声音源链接过滤器
gainNode.connect(audioCtx.destination);//过滤器链接杨声器我们可以看到它们是用connect来链接的,按照上面的顺序,一个链接一个。
audioCtx.createOscillator创造的音调有几个参数,第一个是type,type表明声波的不同类型,有sine,square,sawtooth,triangle四种类型;frequency表示声音的频率,这里通过设置不同的频率来发出不同的声音。
需要注意的是,在webAudio中的声音源只能播放一次,例如上面的createOscillator一旦调用了start,那么就不能调用第二次。如果需要多次调用,每次都需要重新生一个声音源。XHR获取声音
之前我们说到,webAudio中的声音源可以来自声音数据,这里webAudio播放的声音数据为ArrayBuffer格式的。那么如何通过XHR获取声音呢?
jQuery的ajax底层就是封装了XHR,但是jQuery的ajax没有接受arraryBuffer类型的数据,因此为了可以获取到arrayBuffer数据,我们需要用原始的XHR:
var request = new XMLHttpRequest(); //建立一个请求
request.open('GET', 'a.mp3', true); //配置好请求类型,文件路径等
request.responseType = 'arraybuffer'; //配置数据返回类型
// 一旦获取完成,对音频进行进一步操作,比如解码
request.onload =function(){}
request.send();
接下来我们将传过来的arrayBuffer进行解析,解析之后就可以作为声音源进行播放了。
audioContext.decodeAudioData(arraybuffer, function(buffer) {
var audioBufferSouceNode = audioContext.createBufferSource();
audioBufferSouceNode.buffer = buffer;
});audioCtx.createGain()是创建一个声音的控制器,用来控制声音的音量的,它会链接在声音源的后面。
audioContext的suspend和resume是用来暂停和恢复声音播放的,然后audioContext的onended事件将会在声音停止后调用。文件选择获取声音
上面讲了XHR获取声音,我们是通过XHR设置arrayBuffer类型来获取内容,那如何通过文件选择来获取声音呢?
var file = this.files[0];
var fileReader = new FileReader();
fileReader.onload = function(e) {
var arraybuffer = e.target.result;
audioContext.decodeAudioData(arraybuffer, function(buffer) {
var audioBufferSouceNode = audioContext.createBufferSource();
audioBufferSouceNode.buffer = buffer;
});
}
fileReader.readAsArrayBuffer(file);
这里要做的是将得到的file对象转换成arrayBuffer。