欢迎来到站长教程网!

JavaScript

当前位置:主页 > 网页制作 > JavaScript >

基于Web Audio API实现音频可视化效果

时间:2020-06-12|栏目:JavaScript|点击:

网页音频接口最有趣的特性之一它就是可以获取频率、波形和其它来自声源的数据,这些数据可以被用作音频可视化。这篇文章将解释如何做到可视化,并提供了一些基础使用案例。
基本概念节
要从你的音频源获取数据,你需要一个 AnalyserNode节点,它可以用 AudioContext.createAnalyser() 方法创建,比如:

var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); var analyser = audioCtx.createAnalyser();

然后把这个节点(node)连接到你的声源:

source = audioCtx.createMediaStreamSource(stream); source.connect(analyser); analyser.connect(distortion);

// etc.
注意: 分析器节点(Analyser Node) 不一定输出到另一个节点,不输出时也可以正常使用。但前提是它必须与一个声源相连(直接或者通过其他节点间接相连都可以)。

分析器节点(Analyser Node) 将在一个特定的频率域里使用快速傅立叶变换(Fast Fourier Transform (FFT) )来捕获音频数据,这取决于你给 AnalyserNode.fftSize 属性赋的值(如果没有赋值,默认值为2048)。

注意: 你也可以为FFT数据缩放范围指定一个最小值和最大值,使用AnalyserNode.minDecibels 和AnalyserNode.maxDecibels进行设置,要获得不同数据的平均常量,使用 AnalyserNode.smoothingTimeConstant。阅读这些页面以获得更多如何使用它们的信息。

要捕获数据,你需要使用 AnalyserNode.getFloatFrequencyData() 或 AnalyserNode.getByteFrequencyData() 方法来获取频率数据,用 AnalyserNode.getByteTimeDomainData() 或 AnalyserNode.getFloatTimeDomainData() 来获取波形数据。

这些方法把数据复制进了一个特定的数组当中,所以你在调用它们之前要先创建一个新数组。第一个方法会产生一个32位浮点数组,第二个和第三个方法会产生8位无符号整型数组,因此一个标准的JavaScript数组就不能使用 —— 你需要用一个 Float32Array 或者 Uint8Array 数组,具体需要哪个视情况而定。

那么让我们来看看例子,比如我们正在处理一个2048尺寸的FFT。我们返回 AnalyserNode.frequencyBinCount 值,它是FFT的一半,然后调用Uint8Array(),把frequencyBinCount作为它的长度参数 —— 这代表我们将对这个尺寸的FFT收集多少数据点。

analyser.fftSize = 2048; var bufferLength = analyser.frequencyBinCount; var dataArray = new Uint8Array(bufferLength);

要正确检索数据并把它复制到我们的数组里,就要调用我们想要的数据收集方法,把数组作为参数传递给它,例如:

analyser.getByteTimeDomainData(dataArray);

现在我们就获取了那时的音频数据,并存到了我们的数组里,而且可以把它做成我们喜欢的可视化效果了,比如把它画在一个HTML5 <canvas> 画布上。

创建一个频率条形图节
另一种小巧的可视化方法是创建频率条形图,
现在让我们来看看它是如何实现的。

首先,我们设置好解析器和空数组,之后用 clearRect() 清空画布。与之前的唯一区别是我们这次大大减小了FFT的大小,这样做的原因是为了使得每个频率条足够宽,让它们看着像“条”而不是“细杆”。

analyser.fftSize = 256; var bufferLength = analyser.frequencyBinCount; console.log(bufferLength); var dataArray = new Uint8Array(bufferLength); canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);

接下来我们写好 draw() 函数,再一次用 requestAnimationFrame() 设置一个循环,这样显示的数据就可以保持刷新,并且每一帧都清空一次画布。

function draw() { drawVisual = requestAnimationFrame(draw); analyser.getByteFrequencyData(dataArray); canvasCtx.fillStyle = 'rgb(0, 0, 0)'; canvasCtx.fillRect(0, 0, WIDTH, HEIGHT); }

现在我们来设置一个 barWidth 变量,它等于每一个条形的宽度。理论上用花布宽度除以条的个数就可以得到它,但是在这里我们还要乘以2.5。这是因为有很多返回的频率区域中是没有声音的,我们每天听到的大多数声音也只是在一个很小的频率区域当中。在条形图中我们肯定不想看到大片的空白条,所以我们就把一些能正常显示的条形拉宽来填充这些空白区域。

我们还要设置一个条高度变量 barHeight,还有一个 x 变量来记录当前条形的位置。

var barWidth = (WIDTH / bufferLength) * 2.5; var barHeight; var x = 0;

像之前一样,我们进入循环来遍历 dataArray 数组中的数据。在每一次循环过程中,我们让条形的高度 barHeight 等于数组的数值,之后根据高度设置条形的填充色(条形越高,填充色越亮),然后在横坐标 x 处按照设置的宽度和高度的一半把条形画出来(我们最后决定只画高度的一半因为这样条形看起来更美观)。

需要多加解释的一点是每个条形竖直方向的位置,我们在 HEIGHT-barHeight/2 的位置画每一条,这是因为我想让每个条形从底部向上伸出,而不是从顶部向下(如果我们把竖直位置设置为0它就会这样画)。所以,我们把竖直位置设置为画布高度减去条形高度的一半,这样每个条形就会从中间向下画,直到画布最底部。

上一篇:js实现mp3录音通过websocket实时传送+简易波形图效

栏    目:JavaScript

下一篇:Jquery ajax书写方法代码实例解析

本文标题:基于Web Audio API实现音频可视化效果

本文地址:http://www.blue1000.com/wangyezhizuo/JavaScript/1791.html

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:1961407250 | 邮箱:1961407250#qq.com(#换成@)

Copyright © 2002-2022 BK网络学院版权所有 Power by DedeCms 粤ICP备19027147号-7