专栏名称: ryyyyy
前端工程师
目录
相关文章推荐
河南日报  ·  董宇辉最新回应 ·  昨天  
河南日报  ·  董宇辉最新回应 ·  昨天  
济南音乐广播Music887  ·  《哪吒2》“急急如律令”翻译成“biu ... ·  昨天  
济南音乐广播Music887  ·  《哪吒2》“急急如律令”翻译成“biu ... ·  昨天  
51好读  ›  专栏  ›  ryyyyy

有节奏的音乐跳动

ryyyyy  · 掘金  ·  · 2017-12-29 03:19

正文

写在最前:

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

照例,贴下 我的博客 地址,别忘了去点赞哈~

成果展示:

audio

Git地址:

github.com/ry928330/we…

功能说明:

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

实现细节:

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

创建基于audio的语音环境,代码如下:

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);

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

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信息。

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







请到「今天看啥」查看全文