HTML5真是太多炫酷的东西了,其中Web Audio API算一个,琢磨着弄了个音乐可视化的demo,先上效果图:
项目演示:别说话,点我! 源码已经挂到github上了,有兴趣的同学也可以去star或者fork我,源码注释超清楚的哦~~之前看刘大神的文章和源码,感觉其他方面的内容太多了,对初学者来说可能一下子难以抓到Web Audio API的重点,所以我就从一个初学者的角度来给大家说说Web Audio API这些事吧。
Web Audio API与HTML5提供的Audio标签并不是同样的东西,他们之间的区别可以自行搜索。简单的说Audio就是一个自带GUI的标签,他对音频的操作还是比较弱的,而Web Audio API则封装了非常多的对音频的操作,功能十分强大。Web Audio API目前还是一个草案,最新版本可以浏览这里:https://www.w3.org/TR/webaudio/,当然还有MDN上面的介绍:
注意:由于Web Audio API还是非常新,所以现在浏览器的支持不是非常好,具体兼容性如下:
一、整体流程:
一般来说,一个典型的Audio应用的流程都是这样的:
1、创建音频环境(audio Context)
2、创建音源,可以通过audio标签、文件流等方式
3、创建效果节点,可以是混响、压缩、延迟、增益等效果器、也可以是分析节点。
4、为音频选一个输出,比说说你的扬声器。然后将源、效果器和输出连接起来。
玩过吉他或者贝斯的哥们应该很容易理解了:音频环境就是你整个乐器硬件系统,音源就是你的乐器,效果节点就是各种效果器,当然也需要音箱输出和各种连线了。要对音乐进行处理,最重要的就是效果器节点了。这个项目没有增加其他效果,只用了一个分析节点,用来量化音频信号再关联到图形元素上面,得到可视化效果。
二、最简版本代码
简单测试您的浏览器不支持canvas标签您的浏览器不支持audio标签 () { 12 try { window.webkitAudioContext)(); (err) { ); 16 }; ), ), ), audioCtx.createMediaElementSource(myAudio), audioCtx.createAnalyser(); 22 source.connect(analyser); 23 analyser.connect(audioCtx.destination); draw () { myCanvas.width, myCanvas.height, ); 28 analyser.getByteFrequencyData(array); , cwidth, cheight); ) { , cheight); 32 } 33 requestAnimationFrame(draw); 34 }; 35 };
这个是最精简的版本,相信可以帮助大家快速理解整个流程,但是需要注意的是这个版本不兼容移动端。
三、关键代码分析 1、创建音频环境(audio Context)
创建音频环境非常简单,但是要考虑到浏览器兼容问题,需要用一个或语句来兼容不同浏览器。另外,对于不支持AudioContext的浏览器,还需要加一个try catch来避免报错。
try { var audioCtx = new (window.AudioContext ||window.webkitAudioContext)(); } catch (err) { alert('!Your browser does not support Web Audio API!'); };
2、创建音源创建音源的方法有以下几种:
1) 直接从HTML的video/audio元素中获取,使用的方法为AudioContext.createMediaElementSource().
var source = audioCtx.createMediaElementSource(myMediaElement); //myMediaElement可以是页面中的元素,也可以是用new创建的audio/video对象
注意:由于audio标签在移动端还有相当多的坑,大家可以搜索一下,避免踩坑哈!如果不考虑移动端的话,最简单的办法就是这种啦。
2) 从原始的PCM数据中创建音源,方法有AudioContext.createBuffer(),AudioContext.createBufferSource(), 和AudioContext.decodeAudioData(). 这里可以分成从网络中获取或者从本地文件中选择两种方式,关键代码如下。
var source = audioCtx.createBufferSource(); //创建一个空的音源,一般使用该方式,后续将解码的缓冲数据放入source中,直接对source操作。 // var buffer = audioCtx.createBuffer(2, 22050, 44100); //创建一个双通道、22050帧,44.1k采样率的缓冲数据。 audioCtx.decodeAudioData(audioData, function(buffer) { source.buffer = buffer; }, function(err){ alert('!Fail to decode the file!'); //解码出错处理 });
网络获取方式,需要开一个Ajax异步请求来获取文件,并且设置请求返回类型为'ArrayBuffer',代码如下: