有节奏的音乐跳动

写在最前:

 最近在作一些新技术的调研,不巧在掘金上看到有人分享系列关于h5技术的运用,主要包括一些音频,媒体流,用户位置,环境光等H5核心设备接口的运用,因此本身准备照着那个目录动手作一番。这篇就是关于音频对象AudioContext作的小小DEMO,固然看了下别人的DEMO了,但愿各位读者喜欢~html

 照例,贴下个人博客地址,别忘了去点赞哈~html5

成果展现:

audio

Git地址:

github.com/ry928330/we…git

功能说明:

1.根据你在页面载入的音乐,以可视化的方式展现音乐的律动; 2.点击模式切换,以时域波形的方式展现当前音乐的节奏。github

实现细节:

 整个DEMO其实比较简单,主要就是熟悉一些跟Web Audio相关的API,因此讲解的时候我会介绍下本次DEMO用到的一些API的使用方式。还有,本次DEMO的一个难点就是你看到的条形图上顶部小方块儿的下落特效,这个我也会作下解释。页面中所看到的动画都是基于canvas绘制,这个我就很少说了。接下来,进入主题。web

建立基于audio的语音环境,代码以下:canvas

window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;
var audioContext = new AudioContext(); 
var analyser = audioContext.createAnalyser(); 
analyser.fftSize = 2048;
var audio = document.getElementById('audio');
var audioSrc = audioContext.createMediaElementSource(audio); 
audioSrc.connect(analyser);
analyser.connect(audioContext.destination);
复制代码

 代码就这么几行,挨个进行解释。api

1.window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;
2.var audioContext = new AudioContext(); 
复制代码

 建立语音环境上下文,之后关于语音的一切操做都是在这个环境下进行。其实就跟canvas的getContext操做一个意思。为了兼容不一样的浏览器,加了不一样的前缀。数组

3.var analyser = audioContext.createAnalyser();
4.analyser.fftSize = 2048;
复制代码

 建立一个Analyser节点,能够经过该节点获取音频信号的事件和频率数据。而后经过语句4能够设置频域FFT(快速傅里叶变换)取样点的多少。它的取值fftSize 属性的值必须是从32到32768范围内的2的非零幂,默认值是2048。可是,咱们用不到这么多的点,因此后来只是选取了部分点的值用于展现音乐节奏。浏览器

5.var audioSrc = audioContext.createMediaElementSource(audio);
复制代码

 建立一个MediaElementAudioSourceNode接口来关联HTMLMediaElement. 这能够用来播放和处理来自video或audio 元素的音频。并且,咱们还能够经过createMediaStreamSource()接口来获取计算机麦克风或者其余来源的音频流MediaStream信息。bash

6.audioSrc.connect(analyser);
7.analyser.connect(audioContext.destination);
复制代码

 将analyser节点关联到目标音频环境上来,这里audioContext.destination返回AudioDestinationNode对象,AudioDestinationNode接口表示音频图形在特定状况下的最终输出地址,一般为扬声器。意思就是和音频设备关联。

获取音频数据,渲染可视化律动界面:

 环境建立结束以后,咱们就该取相关音频数据,基于canvas渲染可视化律动界面了。代码以下:

var array = new Uint8Array(analyser.frequencyBinCount); 
analyser.getByteFrequencyData(array);
复制代码

 analyser.frequencyBinCount该值获取fftSize值的一半,一般状况下是等于将要用于可视化的数据数值的数量。而后,经过analyser.getByteFrequencyData(array)函数,将当前频域数据拷贝进Uint8Array数组中。而后,就是本次的难点,如何渲染顶部降落方块儿。

var barWidth = 10;
var gap = 2;
var barNum = Math.round(cWidth / (barWidth + gap));  //绘制多少个条形
for (var i = 0; i < barNum; i++) {
    var value = array[i];
    if (topArr.length < barNum) {
        topArr.push(value)
    }
    if (value < topArr[i]) {
        ctx.fillRect(i * (barWidth + gap), cHeight - (topArr[i] -= 1) - topHeight, barWidth, topHeight);
    } else {
        ctx.fillRect(i * (barWidth + gap), cHeight - value - topHeight, barWidth, topHeight);
        topArr[i] = value;
    }
}
复制代码

 根据canvas的宽度以及条形的宽度和间距咱们计算了将要绘制的条形数量,而后该数量值也就决定了咱们用来选取的音频数据的多少。对于顶部小方块儿,咱们建立了一个数组,数组初始化值为音频数据,若是新的音频数据比以前对应的初始化的数据值要大,咱们就直接绘制出顶部的小方块儿,而后根据新的音频数据更新初始化的数据值。反之,若是新来的音频数据比初始化的数据要小,这时候,经过初始值的逐渐减一效果,达到小方块儿不断降落的特效。最后,对于条形的渲染以下:

var grd = ctx.createLinearGradient(i * barWidth, cHeight - value, i * barWidth, cHeight);
grd.addColorStop(0, "yellow");
grd.addColorStop(0.3, "rgb(255,0,0)");
grd.addColorStop(0.5, "rgb(200,0,0)");
grd.addColorStop(0.7, "rgb(150,20,20)");
grd.addColorStop(1, "rgb(100,0,0)");
ctx.fillStyle = grd;
ctx.fillRect(i * (barWidth + gap), cHeight - value, barWidth, topArr[i]);
ctx.fill();
复制代码

 这里,咱们给条形的颜色加了一个线性的渐变,让其看上去稍微那么好看些哈~(好像并无好看多少...)

波形模式的切换:

 有了前面音频数据的条形渲染,这个就显得更简单了,就是数据源取值的不一样而已,经过如下代码将时域数据拷贝进array数组里面,剩下的绘制就是经过canvas的moveTo以及lineTo的API了,我就不作详细的介绍了。

analyser.getByteTimeDomainData(array);
复制代码

参考资料:

1.http://www.codes5…

2.张鑫旭的利用HTML5Web Audio API给网页JS交互增长声音

3.MDN Web Audio 接口

相关文章
相关标签/搜索