Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

绘制音乐的波形图(使用Analyser节点)

  之前的文章中介绍过使用ScriptProcessor节点绘制音乐的波形图的方法。但那么做是杀鸡用牛刀了,它的效率是极低的。AudioAPI提供了Analyser节点,它可以取到通过它的波形字节流动,省去了手动将数据从inputBuffer复制到outputBuffer上的步骤。
  但是Analyser节点并没有像ScriptProcessor节点的onprocessor事件那样的东西,我们需要使用计时器来处理帧。即便如此,对于绘制波形图来说计时器的速度已经足够了。
  演示:[实例]
<canvas id="canvas" width="400" height="100"></canvas>
<audio id="audio" autoplay src="SuperMario.mp3"></audio>
<br/>
<input type="button" onclick="audio.play()" value="播放" />
<input type="button" onclick="audio.pause()" value="暂停" />
<script>
var AudioContext=AudioContext||webkitAudioContext;
var context=new AudioContext;
//从元素创建媒体节点
var source=context.createMediaElementSource(audio);
//创建脚本处理节点
var analyser=context.createAnalyser();
//Canvas初始化
var width=canvas.width,height=canvas.height;
var g=canvas.getContext("2d");
g.translate(0.5,height/2+0.5);
//连接:source → analyser → destination
source.connect(analyser);
analyser.connect(context.destination);
//以fftSize为长度创建一个字节数组作为数据缓冲区
var output=new Uint8Array(analyser.fftSize);
//播放帧
(function callee(e){
  analyser.getByteTimeDomainData(output);
  //将缓冲区的数据绘制到Canvas上
  g.clearRect(-0.5,-height/2-0.5,width,height);
  g.beginPath();
  for(var i=0;i<width;i++)
    g.lineTo(i,height/2*(output[output.length*i/width|0]/256-0.5));
  g.stroke();
  //请求下一帧
  requestAnimationFrame(callee);
})();
</script>
  其实这套AudioAPI的设计有点偏底层了。比如getByteTimeDomainData方法,它的参数实际上是一个定长的强类型数组数组指针,用于接收返回的数据。与一般的JavaScript风格不同,这是类似C的写法,这样可以得到更高的性能。
  fftSize属性是获取数据块的长度,用这个长度去创建一个强类型数组。这个强类型数组作为一数据缓冲区,用于接收getByteTimeDomainData方法得到的数据。值得注意的是,这里得到的类型是字节数组,每个采样点是无符号整型,而不是ScriptProcessor方式得到的浮点数组。
网名:
3.84.186.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^