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

需要多加解释的一点是每个条形竖直方向的位置,我们在 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" value=""> <p></p> <canvas></canvas> </body> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script type="text/javascript"> //随机变颜色 function randomRgbColor() { //随机生成RGB颜色 var r = Math.floor(Math.random() * 256); //随机生成256以内r值 var g = Math.floor(Math.random() * 256); //随机生成256以内g值 var b = Math.floor(Math.random() * 256); //随机生成256以内b值 return `rgb(${r},${g},${b})`; //返回rgb(r,g,b)格式颜色 } //随机数 0-255 function sum (m,n){   var num = Math.floor(Math.random()*(m - n) + n); } console.log(sum(0,100)); console.log(sum(100,255)); //展示音频可视化 var canvas = document.getElementById("casvased"); var canvasCtx = canvas.getContext("2d"); //首先实例化AudioContext对象 很遗憾浏览器不兼容,只能用兼容性写法;audioContext用于音频处理的接口,并且工作原理是将AudioContext创建出来的各种节点(AudioNode)相互连接,音频数据流经这些节点并作出相应处理。 //总结就一句话 AudioContext 是音频对象,就像 new Date()是一个时间对象一样 var AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext; if (!AudioContext) { alert("您的浏览器不支持audio API,请更换浏览器(chrome、firefox)再尝试,另外本人强烈建议使用谷歌浏览器!") } var audioContext = new AudioContext();//实例化 // 总结一下接下来的步骤 // 1 先获取音频文件(目前只支持单个上传) // 2 读取音频文件,读取后,获得二进制类型的音频文件 // 3 对读取后的二进制文件进行解码 $('#musicFile').change(function(){ if (this.files.length == 0) return; var file = $('#musicFile')[0].files[0];//通过input上传的音频文件 var fileReader = new FileReader();//使用FileReader异步读取文件 fileReader.readAsArrayBuffer(file);//开始读取音频文件 fileReader.onload = function(e) {//读取文件完成的回调 //e.target.result 即为读取的音频文件(此文件为二进制文件) //下面开始解码操作 解码需要一定时间,这个时间应该让用户感知到 var count = 0; $('#tip').text('开始解码') var timer = setInterval(function(){ count++; $('#tip').text('解码中,已用时'+count+'秒') },1000) //开始解码,解码成功后执行回调函数 audioContext.decodeAudioData(e.target.result, function(buffer) { clearInterval(timer) $('#tip').text('解码成功,用时共计:'+count+'秒') // 创建AudioBufferSourceNode 用于播放解码出来的buffer的节点 var audioBufferSourceNode = audioContext.createBufferSource(); // 创建AnalyserNode 用于分析音频频谱的节点 var analyser = audioContext.createAnalyser(); //fftSize (Fast Fourier Transform) 是快速傅里叶变换,一般情况下是固定值2048。具体作用是什么我也不太清除,但是经过研究,这个值可以决定音频频谱的密集程度。值大了,频谱就松散,值小就密集。 analyser.fftSize = 256; // 连接节点,audioContext.destination是音频要最终输出的目标, // 我们可以把它理解为声卡。所以所有节点中的最后一个节点应该再 // 连接到audioContext.destination才能听到声音。 audioBufferSourceNode.connect(analyser); analyser.connect(audioContext.destination); console.log(audioContext.destination) // 播放音频 audioBufferSourceNode.buffer = buffer; //回调函数传入的参数 audioBufferSourceNode.start(); //部分浏览器是noteOn()函数,用法相同 //可视化 创建数据 // var dataArray = new Uint8Array(analyser.fftSize); // analyser.getByteFrequencyData(dataArray)//将数据放入数组,用来进行频谱的可视化绘制 // console.log(analyser.getByteFrequencyData) var bufferLength = analyser.frequencyBinCount; console.log(bufferLength); var dataArray = new Uint8Array(bufferLength); console.log(dataArray) canvasCtx.clearRect(0, 0, 500, 500); function draw() { drawVisual = requestAnimationFrame(draw); analyser.getByteFrequencyData(dataArray); canvasCtx.fillStyle = 'rgb(0, 0, 0)'; //canvasCtx.fillStyle = ; canvasCtx.fillRect(0, 0, 500, 500); var barWidth = (500 / bufferLength) * 2.5; var barHeight; var x = 0; for(var i = 0; i < bufferLength; i++) { barHeight = dataArray[i]; //随机数0-255 Math.floor(Math.random()*255) // 随机数 10*Math.random() canvasCtx.fillStyle = 'rgb(' + (barHeight+100) + ','+Math.floor(Math.random()*(20- 120) + 120)+','+Math.floor(Math.random()*(10 - 50) + 50)+')'; canvasCtx.fillRect(x,500-barHeight/2,barWidth,barHeight/2); x += barWidth + 1; } }; draw(); }); } }) </script> </html>

 注意:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjfssz.html