web Audio学习与音频播放
随着浏览器的越发强大,用原生js操作音频已经不是难事了。我们来使用web audio api简单地处理下音频资源。 简介在学习web audio api之前,先了解三个概念: 音频源,也就是音频输入,可以是直接从设备输入的音频,也可以是远程获取的音频文件。 处理节点,分析器和处理器,比如音调节点,音量节点,声音处理节点。 输出源,指音频渲染设备,一般情况下是用户设备的扬声器,即context.destination。 其实,音频源和输出源也都可以视为节点,这三者的关系可以用这张图表示: 当然,实际使用中,可能会有n个处理节点,都可以使用connect依次关联起来。 音频文件播放假如现在要用web audio api播放本地的一个音乐文件,按照前面的流程,我们来试下。 文件上传既然音频文件来自本地,那么得支持文件上传: <input type="file" id="file" accept="audio/x-wav,audio/mpeg" /> 我这儿限制先显示wav和mp3两种格式。 文件读取给input增加change事件,处理选中的文件: var context = new (window.AudioContext || window.webkitAudioContext)(); document.getElementById('file').addEventListener('change',function(e) { var read = new FileReader(); read.onload = function() { ????????// 将arrayBuffer转成audioBuffer context.decodeAudioData(this.result,function(buffer) { playSound(buffer); },function() { console.log('error'); }); }; ????// 利用filereader将file转成arraybuffer格式 read.readAsArrayBuffer(this.files[0]); }); 丢了一段代码,我们来看下,new AudioContext(),创建audio的上下文环境,至于webkitAudioContext是兼容较低版本的chrome的。 fileReader大伙应该见到的比较多了吧,这儿用他读取对应file对象中的文件数据,readAsArrayBuffer表示读取结果用arrayBuffer对象显示,由于此方法是异步读取的,所以只能放在onload回调中处理。 而我们拿到的arrayBuffer不能直接给web audio播放,需要使用decodeAudioData()方法将arrayBuffer转成audioBuffer,那么此时转化后的audioBuffer就是音频源啦。decodeAudioData更多介绍可以查看MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/AudioContext/decodeAudioData。 注:w3c文档上说明decodeAudioData支持audio标签支持的所有音频格式。MDN提示ArrayBuffer类型的对象旨在保存小型音频片段,通常小于45秒,对于较长的声音,实现它的对象MediaElementAudioSourceNode(audio元件)更合适。 音频播放音频数据到手,接下来就是播放啦。 文件上传后,我们拿到了音频audioBuffer形式的数据,接下来使用createBufferSource()方法播放音频数据,再connect到destination就可以播放了。 // 播放音频 function playSound(buffer) { var source = context.createBufferSource(); // 设置数据 source.buffer = buffer; // connect到扬声器 source.connect(context.destination); source.start(); } 一个简单的音频文件播放器就完成了,如果是从服务器上获取文件也是类似的,只不过是多了个ajax处理。 代码地址:webAudio播放本地音乐。 音频的话,可以去一些音乐网站下载,如果懒得下的话,我这直接提供音频下载:林俊杰_-_我还想她.mp3(已下载6次 – 6 MB) 小bug当连续选择多个文件时,你会发现,多个音频文件一起播放了,因此,多音频输入时,都一起connect到context.destination上就可以实现一起播放了。对于此处,这应该算是个bug,查看AudioBufferSourceNode文档,可以利用stop()方法去处理,大伙自个想下,处理下咯。 前面的例子里只出现了音频源和音频输出,并未出现处理节点。接下来,我们尝试自己创建音频,并使用音量处理节点。 自制音频并播放创建音频源此处我们不使用外部的音频文件,而是使用createOscillator()方法创建音频源。 该方法返回OscillatorNode,可以通过frequency属性设置他的振荡频率,type属性则可以用来指定要播放的波形。更多属性和方法参考OscillatorNode文档。 var context = new (window.AudioContext || window.webkitAudioContext)(); var oscillator = context.createOscillator(); // oscillator.type = 'sine'; // oscillator.frequency.value = 800; // 频率800Hz,默认440 创建音量处理节点使用createGain()方法,修改返回值中的value,既可以改变音量大小。 var gainNode = context.createGain(); gainNode.gain.value = 0.8; // 音量 0 ~ 1 节点关联与播放将这些”节点”connect起来就可以播放了。 oscillator.connect(gainNode); // 音频源关联到音量 gainNode.connect(context.destination); // 音量关联到扬声器 // chrome 73 需要用户点击才可播放 document.getElementById('start').addEventListener('click',function() { oscillator.start(); }); 虽然播放后是一片噪音,不过简单的web audio api我们已经会使用啦。 代码地址:webAudio制造噪音并播放。 其他自己尝试过程中,在控制台下遇到这个警告: The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. 大概意思就说AudioContext需要用户手动触发,所以只需要将new AudioContext()移动到事件内部就行了。 总结我们已经能够使用web audio播放本地音乐和制造噪音了,接下来,可以尝试下其他的api了。 想要看js录音的可以看这篇文章:纯js实现录音与播放。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |