网页音频接口最有趣的特性之一它就是可以获取频率、波形和其它来自声源的数据,这些数据可以被用作音频可视化。这篇文章将解释如何做到可视化,并提供了一些基础使用案例。
基本概念节
要从你的音频源获取数据,你需要一个 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它就会这样画)。所以,我们把竖直位置设置为画布高度减去条形高度的一半,这样每个条形就会从中间向下画,直到画布最底部。
for(var i = 0; i < bufferLength; i++) { barHeight = dataArray[i]/2; canvasCtx.fillStyle = 'rgb(' + (barHeight+100) + ',50,50)'; canvasCtx.fillRect(x,HEIGHT-barHeight/2,barWidth,barHeight); x += barWidth + 1; } };
和刚才一样,我们在最后调用 draw()
函数来开启整个可视化过程。
draw();
这些代码会带来下面的效果:
源码:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>可视化音乐播放器</title> </head> <body> <input type="file" name="" value="" id="musicFile"> <p id="tip"></p> <canvas id="casvased" width="500" height="500"></canvas> </body> <script src="/UploadFiles/2021-04-02/jquery.min.js">注意:
本文中的案例展现了 AnalyserNode.getByteFrequencyData() 和 AnalyserNode.getByteTimeDomainData() 的用法。如果想要查看AnalyserNode.getFloatFrequencyData() 和 AnalyserNode.getFloatTimeDomainData() 的用法,请参考我们的 Voice-change-O-matic-float-data 演示(也能看到 源代码 )——它和本文中出现的 Voice-change-O-matic 功能完全相同,唯一区别就是它使用的是浮点数作数据,而不是本文中的无符号整型数。
《参考:https://github.com/mdn/voice-change-o-matic 》
《案例一:https://mdn.github.io/voice-change-o-matic/ 》
《案例二:http://margox.github.io/vudio.js/ 》总结
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]