作者:Sanpeier

https://juejin.im/post/5dd88289e51d4523564243da

什么是音频可视化

音频可视化,顾名思义,就是通过获取音频的波形、频率和其他来自音频的数据转换成图像,再到屏幕上显示出来。通过它,我们能够制作一些炫酷的前端音乐界面。

下面,我将分析一个来自云音乐技术团队的音频可视化开发案例,快速帮助小白,制作自己喜欢的炫酷的音频可视化界面。

先上图


想开发这么一个炫酷的音频界面,我们可以先来聊聊 canvas

canvas是什么

canvas是HTML5中用于图形绘制的容器元素,它通常通过JavaScript脚本来完成图形绘制。要完成我们下面的音频可视化开发,我们可以借组结构canvas的几个方法,下面将通过开发一个页面倒计时的小案例来帮助初学者了解canvas的一些属性和方法。

先上代码

  <canvas id="myCanvas">    canvas>    <script>        const canvas = document.getElementById('myCanvas');        var ctx = canvas.getContext('2d');        ctx.fillStyle = 'red';        ctx.font = "50px Verdana";        let dis = 550;        let i = 10;        function animation(){        requestAnimationFrame(function(){            if(dis >= 0){                --dis;                if(dis%50 == 0 ){                    ctx.clearRect(0,0,300,150);                    ctx.fillText(i--,100,100);                }                animation();            }        });        }        animation();script>

我们在html页面创建一个canvas画布元素并设置id为myCanvas,它的默认大小是300*150,创建好了这块画布,接下来我们就能在JavaScript脚本中绘制图形了。

先通过getElementById()找到这个元素,然后创建canvas对象ctx并设置填充色为红色,字体为Verdana,大小为50px,设置dis变量用于条件控制,再定义一个i变量用于显示倒计时数字,然后我们就可以开始在我们的画布里绘制倒计时数字了。

创建一个animation函数,在这个函数里面,我们使用了一个html5专门用于请求动画的APIrequestAnimationFrame请求动画帧,相比于定时器setTimeout,它不会引起丢帧、丢帧,看起来更加流畅。

requestAnimationFrame里面,先设置刷帧条件dis>=0dis每次减一,总共550次,再设置条件为每50次执行一次绘制操作,在每次绘制之前,通过clearRect(x,y,width,height)方法将画布上给定矩形清空,它的4个参数分别表示要清除的矩形左上角的x,y坐标,以及要清空矩形的宽度和高度,单位以像素计算。然后再通过fillText()画布指定位置绘制倒计时数字,该方法接收四个参数:text输出的文本,x绘制文本的x坐标,y绘制文本的y坐标,注意:这两个值都是相对于画布,最后一个参数maxWidth表示允许文本的最大宽度,它是一个可选参数。

接着我们通过递归的方式调用animation()函数直到倒计时结束,最后在外部调用一下animation()函数,至此,一个简单的倒计时界面完成。我们还可以给canvas通过innerWidthinnerHeight设置

画布大小。

canvas可以绘制各种图形,更多内容请自行参看canvas内容

聊完了canvas,接下来就是我们的正题了。

Web Audio

在开始之前,我们还需要了解什么是Web Audio。

Web Audio 是 Web 端处理和分析音频的一套 API 。它可以使用户在音频上下文中进行音频操作,具有模块化路由的特点,它也使我们能够控制音频的空间化。

通过Web Audio,我们能够实现取数据映射数据两个过程,下面我们将实现这两个过程。

项目实现

我们先在页面创建一个canvas元素和一个audio标签以及一个用于作播放按钮的a标签。

然后在JavaScript里面获取audioa这两个元素,并给a标签设置单击事件。

    var btn = document.getElementById('play-btn');        var audio = document.getElementById('audio');        btn.addEventListener('click',function(){            btn.style.display = 'none';            audio.play();            onloadAudio();        })

onLoadAudio()函数里面,我们先获取canvas元素,设置它占满整个页面,再创建canvas的对象。

  var canvas = document.getElementById('canvas');        canvas.width = window.innerWidth;        canvas.height = window.innerHeight;        var ctx = canvas.getContext('2d');

创建 **AudioContext **对象,用来控制它所包含的节点的创建,以及音频处理、解码操作的执行。

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

通过 createAnalyser() 方法创建 **AnalyserNode **用来获取音频时间和频率数据,实现音频数据可视化。

  var analyser = audioCtx.createAnalyser();    analyser.fftSize = 512;

fftSize 在 MDN 里面介绍是快速傅里叶变换的一个参数,取值必须是从32到32768范围内的2的非零幂,默认值为2048,在这里我们取512。另外,fftSize 的值决定了 frequencyData 的长度。

将音频节点关联到 AudioContext上,作为整个音频分析的输入。

我们采用MediaElementAudioSourceNode 将节点作为输入源,并将音频关联到分析器,再将分析器关联到输出设备。

var source = audioCtx.createMediaElementSource(audio);        source.connect(analyser);        analyser.connect(audioCtx.destination);

接下来获取频率数组。

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

frequencyBinCount()的值是 fftSize 取值的一半,所以这里的 Uint8Array() 数组的长度就是256。

然后设置音柱的宽度,而高度只定义变量而不赋值,留在后面通过dataArray[]数组动态设置

  var barWidth = WIDTH / bufferLength*1.5;        var barHeight;

绘制音柱

定义一个 renderFrame() 函数用于绘制音柱,并且每次绘制之前都先将整个画布清除,然后更新频率数组。

    ctx.clearRect(0,0,WIDTH,HEIGHT);        analyser.getByteFrequencyData(dataArray);

通过for循环里面设置每一个矩形的高度,再根据高度设置一个背景色,然后绘制矩形,并填充背景颜色。然后通过递归的方式调用函数。

barHeight = dataArray[i];        var r = barHeight + 25 * (i / bufferLength);        var g = 250 * (i / bufferLength);        var b = 50;        ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")";        ctx.fillRect(x,HEIGHT-barHeight,barWidth,barHeight);        x += barWidth+2;

最后,运行代码,体验属于你的可视化音乐吧。

小结

本文简单介绍了 canvas 的使用和如何通过 Web Audio 的相关 API 获取音频的频率数据。

然而 canvasWeb Audio的用处远远不止于此,读者还可以发挥想象力和创造力,开发出更多有意思的项目。

附上项目源码:

https://github.com/anpeier/lesson_shuidi/tree/master/html5/visualize

 --------  END  ---------

推荐阅读

(点击标题可跳转阅读)

十款 Windows 下必装软件,大大增强工作幸福

漫画:什么是 HTTPS 协议?

又一个框架来了!被称为要取代 React , vue ,Aangular !

        朕已阅 

傅里叶变换音频可视化_快速上手网易云音乐可视化相关推荐

  1. python爬取网易云音乐_爬取网易云音乐评论(一)——用python执行JS脚本

    抓包分析 可以发现网页是post请求,表单数据有两个参数params和encSecKey,应该是经过js加密所得 因此在 Initiator 栏里找到对应的js,也就是core...js,点击打开查看 ...

  2. 解锁网易云音乐小工具_什么?网易云音乐又变灰了

    目前音乐市场主要有三大巨头:酷狗音乐,QQ音乐,网易云音乐.QQ音乐与网易云音乐进入市场都较晚,但是网易云音乐凭借灵活的音乐社交玩法积累了非常多的用户,而QQ音乐凭借着有钱优势,购买了很多音乐版权,网 ...

  3. python3爬取网易云歌单数据清洗_实例 | 使用网易云音乐数据演示数据整合与数据清洗...

    作者 | 小F 来源 | 法纳斯特(walker398) 数据整合是对数据进行行列选择.创建.删除等操作. 数据清洗则是将整合好的数据去除其中的错误和异常. 本文利用之前获取的网易云音乐用户数据,来简 ...

  4. python爬虫网易云音乐评论再分析_爬取网易云音乐的评论后,竟有这种发现!

    原标题:爬取网易云音乐的评论后,竟有这种发现! 作者 | 志颖 责编 | 胡巍巍 用过网易云音乐听歌的朋友都知道,网易云音乐每首歌曲后面都有很多评论,热门歌曲的评论更是接近百万或者是超过百万条. 现在 ...

  5. 网易云音乐爬虫 数据可视化分析

    网易云音乐爬虫 & 数据可视化分析 1. 数据爬取 1.1 评论爬取 1.2 用户信息爬取 2 数据清洗 & 可视化 歌评文本分析 个人博客:Archiew's blog 源码:htt ...

  6. 带你手把手撸一个网易云音乐首页(上篇)

    标题前言 Hello,大家好,近期我一直在学习用 Swift 编码,由于之前很多项目我都是用 OC 实现的,所以导致我现在对 Swift 还是处于一个学习的阶段中.为了提高自己的学习效率,每次我都会为 ...

  7. 网易云信联手网易云音乐,“一起听”创新音乐社交体验

    还记得"我的耳机分你一半"的感觉吗? 学生时代,教室里.操场边,抑或是上下学的公交车站,我们都曾与好朋友分享过同一副耳机,你的右耳,他的左耳,两只耳朵一起聆听着同一段属于青春的旋律 ...

  8. 矿小助 全局主题 | 一个插件实现网易云音乐主题效果 | Flutter

    矿小助拥有三种主题,实现起来非常复杂,总结起来就更不用说了,头皮发麻QAQ. 因此,花了半天时间将其拆分出来,做成插件,开源给大家使用.具体的细节大家自己研究吧(溜). 第一次做插件,难免考虑不周,还 ...

  9. python可视化分析网易云音乐评论_网易云音乐热门评论api分析

    网上有现成的例子我就扒过来了!! title: 网易云评论api分析 date: 2018-12-24 20:54:46 tags: [python] 网易云音乐是个好地方,里面各个都是人才,特别是评 ...

最新文章

  1. 区块链技术特点之去中心化特性
  2. windows下本地或者远程连接MYSQL数据库,报1130错误的解决方法
  3. golang interface 转 int string slice struct 类型
  4. NYOJ 589 糖果
  5. Android—内存泄漏、GC及LeakCanary源码解析
  6. 了解ThreadLocal背后的概念
  7. 基于ubuntu13.04搜狗输入法安装方法
  8. Cracking the Coding Interview 6.5
  9. 生命周期 用户可以操作dom_当面试官问:能否介绍下Vue生命周期时,该如何回答...
  10. 该设备或资源(Web 代理)未设置为接受端口1080上的连接
  11. Ext3文件读写流程概述
  12. sql 2005性能调优
  13. Jeecg-Boot前后端分离版
  14. Windows多媒体开发框架介绍
  15. build-up to Ajax v,to build up是什么意思
  16. 虚拟服务器的磁盘合并,磁盘管理怎么合并分区
  17. 与化学相关的计算机应用情况,计算机化学的发展、应用与展望
  18. html 表格 选择,html表格选择与colspan或rowspan
  19. CCNA-NAT协议 静态NAT 动态NAT(多对多) PAT(多对一) 内网与外网之间的通信 GNS3实验验证
  20. maya导出带有alpha通道的动画

热门文章

  1. Qt QPushButton圆形图片设置为背景
  2. python和c混合编程 gil_终于搞明白python与gil
  3. 关闭笔记本显示器指定组合键才能打开_笔记本外接显示器怎么设置 笔记本外接显示器设置方法【详解】...
  4. ffmpeg 硬件解码rtsp流_树莓派使用硬件加速视频转码
  5. Linux IPC / 分类
  6. Tiniux 3.0 / Memory.c / OSMemFree
  7. 启明云端分享|ESP32-C3(ESP32­C3­MINI­1)使用的RISC与CISC有什么区别
  8. 解决方法|ESP8266环境搭建出现 usrbinenv bashr :没有那个文件或目录
  9. “云智一体“全场景智能视频技术与应用解析白皮书下载申请
  10. 如何洞察行业中的应用场景?(上篇)