1.Web Audio API 介绍

Web Audio API 提供了在Web上控制音频的一个非常有效通用的系统 ,这些通用系统通俗的讲就是我们可以利用Web Audio API提供的各种方法操作各种源中的声音,处理声音,使声音可视化等。

  要使用Web Audio API,我们还是先来简单的了解一下它的工作流程:

  1. 创建音频环境(eg. AudioContext..)
  2. 在音频环境里创建源 — 例如 , 振荡器, 流(eg. navigator.getUserMedia/createMediaElementSource..)
  3. 创建效果节点,例如混响、双二阶滤波器、平移、压缩(Web Audio API 提供一些简单的滤波器或者延时器等,可以制作一个简单的混音工具)
  4. 为音频选择一个目地,例如你的系统扬声器
  5. 连接源到效果器,以及效果器和目地(分析和可视化eg. AnalyserNode)

兼容性如下:

  桌面端

浏览器 Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
支持版本 14  23 未实现 15 6

  移动端

浏览器

Android

Chrome

Firefox Mobile (Gecko)

Firefox OS

IE Phone

Opera Mobile

Safari Mobile

支持版本 未实现 28  25 1.2 未实现 未实现

2.示例代码

  "talking is cheap , show me the codes."

  我知道各位看官并不想听什么时域频域变换,什么傅立叶变换,什么web audio api原理,那我就废话不多说,直接放码过来了,先看看效果再来给大家解释。

  尽情复制粘贴,然后拿个现代一点的浏览器跑一下(用IE的请点右上角红叉,谢谢)。

注意:audio标签的src属性内容请自己在本机找一个浏览器支持的声音源格式。

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8" /><meta name="Author" contect="GabrielChen"><meta name="keywords" contect="Web Audio API"><title>Web Audio API 学习</title><script>var canvas;var ctx;var audioContext;var analyser;var mic;function init() {canvasOne = document.getElementById('canvasOne');ctx = canvasOne.getContext("2d");canvasTwo = document.getElementById('canvasTwo');ctx2 = canvasTwo.getContext("2d");}navigator.getMedia = ( navigator.getUserMedia ||navigator.webkitGetUserMedia ||navigator.mozGetUserMedia ||navigator.msGetUserMedia);navigator.getMedia ( { audio: true }, function (stream) {audioContext = new (window.AudioContext || window.webkitAudioContext);mic = audioContext.createMediaStreamSource(stream);analyser= audioContext.createAnalyser();analyser.fftSize = 256;mic.connect(analyser);drawSpectrum();},function(){});function drawSpectrum() {var WIDTH = canvasOne.width;var HEIGHT= canvasOne.height;var array =  new Uint8Array(128);analyser.getByteFrequencyData(array);ctx.clearRect(0, 0, WIDTH, HEIGHT);ctx2.clearRect(0, 0, 800, 800);for ( var i = 0; i < (array.length); i++ ){var value = array[i];ctx.fillRect(i*5,HEIGHT-value,3,HEIGHT);}for ( var i = 0; i < (array.length); i++ ){var value = array[i];ctx2.beginPath();ctx2.arc(300,300,value,0,360,false);ctx2.lineWidth=5;ctx2.strokeStyle="rgba("+value+","+value+",0,0.2)";ctx2.stroke();//画空心圆ctx2.closePath();}requestAnimationFrame(drawSpectrum);};</script><style>#canvasOne {border: 1px solid #ddd;}</style>
</head>
<body οnlοad="init();">
<h1>从audio源获取声音</h1>
<audio src="./Fatbros.ogg" controls="controls" id="audio">你的浏览器不支持audio标签</audio>
<h1>audio读取声音</h1>
<canvas id="canvasFormAudio" width="640"></canvas>
<h1>频域图模仿</h1>
<canvas id="canvasOne" width="640"></canvas>
<h1>圆形声波图</h1>
<canvas id="canvasTwo" width="800" height="800"></canvas><script type="text/javascript">var context1;var source;var analyserfa;var canvasFormAudio;var ctxfa;canvasFormAudio = document.getElementById('canvasFormAudio');ctxfa = canvasFormAudio.getContext("2d");try {context1 = new (window.AudioContext || window.webkitAudioContext);} catch(e) {throw new Error('The Web Audio API is unavailable');}analyserfa=context1.createAnalyser();window.addEventListener('load', function(e) {var audio =document.getElementById("audio");var source = context1.createMediaElementSource(audio);source.connect(analyserfa);analyserfa.connect(context1.destination);drawSpectrumfa();}, false);function drawSpectrumfa() {var WIDTH = canvasFormAudio.width;var HEIGHT= canvasFormAudio.height;var array =  new Uint8Array(128);analyserfa.getByteFrequencyData(array);ctxfa.clearRect(0, 0, WIDTH, HEIGHT);for ( var i = 0; i < (array.length); i++ ){var value = array[i];ctxfa.fillRect(i*5,HEIGHT-value,3,HEIGHT);}requestAnimationFrame(drawSpectrumfa);}
</script>
</body>
</html>

  

  

3.代码分析

我们从body部分入手分析

<body οnlοad="init();">
<h1>从audio源获取声音</h1>
<audio src="./Fatbros.ogg" controls="controls" id="audio">你的浏览器不支持audio标签</audio>
<h1>audio读取声音</h1>
<canvas id="canvasFormAudio" width="640"></canvas>
<h1>频域图模仿</h1>
<canvas id="canvasOne" width="640"></canvas>
<h1>圆形声波图</h1>
<canvas id="canvasTwo" width="800" height="800"></canvas>

用onload属性调用初始化函数init(),主要在页面生成之后初始化一些变量,避免读不到相关DOM。

       function init() {canvasOne = document.getElementById('canvasOne');ctx = canvasOne.getContext("2d");canvasTwo = document.getElementById('canvasTwo');ctx2 = canvasTwo.getContext("2d");}

第一块canvas:从audio源获取声音

首先一个audio标签,在本机选定一个src,设置controls属性代表浏览器显示播放器控制页面,设置id为audio。

再设置一个id为"canvasFormAudio"的画布canvas。

<audio src="./Fatbros.ogg" controls="controls" id="audio">你的浏览器不支持audio标签</audio>
<h1>audio读取声音</h1>
<canvas id="canvasFormAudio" width="640"></canvas>

获取声音源以及绘图

//直接从audio处理音频源,声明一些必要的变量var context1;var source;var analyserfa;var canvasFormAudio;var ctxfa;
//初始化画布canvasFormAudio = document.getElementById('canvasFormAudio');ctxfa = canvasFormAudio.getContext("2d");//建立一个音频环境,因为浏览器实现不同,做了一点兼容性处理try {context1 = new (window.AudioContext || window.webkitAudioContext);} catch(e) {throw new Error('The Web Audio API is unavailable');}
//建立一个分析器analyserfa=context1.createAnalyser();window.addEventListener('load', function(e) {// 从audio标签获取声音源 sourcevar audio =document.getElementById("audio");var source = context1.createMediaElementSource(audio);source.connect(analyserfa);analyserfa.connect(context1.destination);//调用绘图函数drawSpectrumfa();}, false);      //绘图函数function drawSpectrumfa() {var WIDTH = canvasFormAudio.width;var HEIGHT= canvasFormAudio.height;var array =  new Uint8Array(128);//复制当前的频率值到一个无符号数组中analyserfa.getByteFrequencyData(array);//clearRect(矩形左上角x坐标,矩形左上角y坐标,清除矩形的宽,清除矩形的高)ctxfa.clearRect(0, 0, WIDTH, HEIGHT);//循环生成长条矩形for ( var i = 0; i < (array.length); i++ ){var value = array[i];//fillRect(矩形左上角x坐标,矩形左上角y坐标,矩形宽,矩形高)         //这里我们的array一共有128组数据,所以我们当时canvas设置的宽度为5*128=640ctxfa.fillRect(i*5,HEIGHT-value,3,HEIGHT);}//根据浏览器频率绘图或者操作一些非css效果requestAnimationFrame(drawSpectrumfa);}

  

第二块:频域图模仿和圆形声波图

这两个图的音源都是利用浏览器调用电脑麦克风取得,所以一定要同意浏览器请求的麦克风权限。

绘图区域

<h1>频域图模仿</h1>
<canvas id="canvasOne" width="640"></canvas>
<h1>圆形声波图</h1>
<canvas id="canvasTwo" width="800" height="800"></canvas>

初始化init()函数、从麦克风获取音源和绘图函数

        var canvas;var ctx;var audioContext;var analyser;var mic;
//初始化两个画布的函数,声明为2d绘图function init() {canvasOne = document.getElementById('canvasOne');ctx = canvasOne.getContext("2d");canvasTwo = document.getElementById('canvasTwo');ctx2 = canvasTwo.getContext("2d");}//getMedia调用参数如下,返回一个多媒体流    //constraints可选{ video: true, audio: true },代表获取多媒体的类型       //var stream = navigator.getUserMedia(constraints, successCallback, errorCallback);navigator.getMedia = ( navigator.getUserMedia ||navigator.webkitGetUserMedia ||navigator.mozGetUserMedia ||navigator.msGetUserMedia);navigator.getMedia ( { audio: true }, function (stream) {audioContext = new (window.AudioContext || window.webkitAudioContext);//返回一个多媒体流mic = audioContext.createMediaStreamSource(stream);//creates an AnalyserNode 创建一个分析节点analyser= audioContext.createAnalyser();//fftsize默认值2048,是快速傅立叶变换用于频域分析的值,必须为2的幂,而我们得到的数据通常为其的一半,下面会说道analyser.fftSize = 256;mic.connect(analyser);      //调用绘图函数drawSpectrum();},function(){});//圆形声波绘图和矩形绘图function drawSpectrum() {var WIDTH = canvasOne.width;var HEIGHT= canvasOne.height;//长度为128无符号数组用于保存getByteFrequencyData返回的频域数据var array =  new Uint8Array(128);analyser.getByteFrequencyData(array);       //以下是根据频率数据画图,主要为canvas知识,不做详细解答ctx.clearRect(0, 0, WIDTH, HEIGHT);ctx2.clearRect(0, 0, 800, 800);for ( var i = 0; i < (array.length); i++ ){var value = array[i];ctx.fillRect(i*5,HEIGHT-value,3,HEIGHT);}//ctx2.clearRect(700, 700, WIDTH, HEIGHT);for ( var i = 0; i < (array.length); i++ ){var value = array[i];ctx2.beginPath();ctx2.arc(300,300,value,0,360,false);ctx2.lineWidth=5;ctx2.strokeStyle="rgba("+value+","+value+",0,0.2)";ctx2.stroke();//画空心圆ctx2.closePath();}//requestAnimationFrame(drawSpectrum);};

 

4.最终效果

6.最新进展

  文中的getMedia方法(getUserMedia)在chrome 47后已经不可以从非安全源访问(Insecure Origins),即http协议,.firefox还可以但不知道为什么有bug,几秒钟后就share设备失败。

  现在chrome开发者可以使用以下方法继续在非安全源使用这个函数:

  You can run chrome with the --unsafely-treat-insecure-origin-as-secure="example.com" flag (replacing "example.com"with the origin you actually want to test), which will treat that origin as secure for this session. Note that you also need to include the --user-data-dir=/test/only/profile/dir to create a fresh testing profile for the flag to work

7.参考

1.MDN

2.api接口查询

3.chrome

  

转载于:https://www.cnblogs.com/gabrielchen/p/5078760.html

Web Audio API之手把手教你用web api处理声音信号:可视化音乐demo相关推荐

  1. 小白都能看懂的实战教程 手把手教你Python Web全栈开发(DAY 3)

    小白都能看懂的实战教程 手把手教你Python Web全栈开发 Flask(Python Web)实战系列之在线论坛系统 第三讲 这是小白都能看懂的实战教程 手把手教你Python Web全栈开发 的 ...

  2. 手把手教你写web全栈入门项目—React+Koa+MongoDB(3w字教程,真的很详细,有代码)

    手把手教你写web全栈入门项目-React+Koa+MongoDB

  3. 小白都能看懂的实战教程 手把手教你Python Web全栈开发(DAY 1)

    小白都能看懂的实战教程 手把手教你Python Web全栈开发 Flask(Python Web)实战系列之在线论坛系统 第一讲 博主博客文章内容导航(实时更新) 更多优质文章推荐: 收藏!最详细的P ...

  4. 手把手教你搭建一个中式菜谱知识图谱可视化系统

    手把手教你搭建一个中式菜谱知识图谱可视化系统 中式菜谱知识图谱 1.系统功能 2.先来看看效果 实体间关联关系及实体信息显示 不同类型实体开关显示 搜索功能展示 3.系统实现流程 3.1 数据爬取 3 ...

  5. 手把手教你:基于Django的用户画像可视化系统

    系列文章 第九章.手把手教你:个人信贷违约预测模型 第八章.手把手教你:基于LSTM的股票预测系统 第七章.手把手教你:基于深度残差网络(ResNet)的水果分类识别系统 目录 系列文章 一.项目简介 ...

  6. 不会 Python 没关系,手把手教你用 web scraper 抓取豆瓣电影 top 250 和 b 站排行榜

    苏生不惑第190 篇原创文章,将本公众号设为 星标 ,第一时间看最新文章. 关于Python之前分享过很多文章了: Python 抓取知乎电影话题下万千网友推荐的电影,这个国庆节不愁没电影看了 王菲k ...

  7. 手把手教你调用百度api(以花卉识别为例)

    前言   虽说直接调用的人家接口比较方便,但是对于第一次写这个东西的人来说一开始也没有什么头绪,只能慢慢摸索,所以我想把整个过程梳理一下,对有这方面想法的小伙伴可以有个参考. 1.平台登录   首先百 ...

  8. 大厂年薪43w测试开发手把手教你搭建Web自动化测试框架,超详细

    测试框架的设计有两种思路,一种是自底向上,从脚本逐步演变完善成框架,这种适合新手了解框架的演变过程.另一种则是自顶向下,直接设计框架结构和选取各种问题的解决方案,这种适合有较多框架事件经验的人.本章和 ...

  9. 不会 Python 没关系,手把手教你用 web scraper 抓取豆瓣电影 top 250 和 b 站排行榜...

    苏生不惑第190 篇原创文章,将本公众号设为星标,第一时间看最新文章. 关于Python之前分享过很多文章了: Python 抓取知乎电影话题下万千网友推荐的电影,这个国庆节不愁没电影看了 王菲k歌又 ...

最新文章

  1. [转载]实现Application Tile 更新
  2. 关于不能成为专业软件测试人员的10大理由的一些阐述
  3. 史上最扯Java图形绘制(J2SE)之一JAVA动画效果
  4. 【计算机网络】第五章 数据链路层(3)
  5. “压扁数组”技巧(flattening the array)
  6. javascript中 this 指向问题
  7. 用户 'NT AUTHORITY/NETWORK SERVICE' 登录失败 的解决方法(转)
  8. c语言ATM机文件储存账号密码,C语言实现_ATM自动取款机系统
  9. 解读新突破“中国量子计算机”,真比神威·太湖之光还厉害?
  10. C++字符串处理封装类String
  11. 做系统ghost步骤图解_两台电脑硬盘对拷图解
  12. 加密与解密 调试篇(一)
  13. iocomp入门教程(绘制Plot)
  14. 平面设计如何才能自学会?需要掌握什么技能?
  15. P问题、NP问题、NPC问题、NP hard问题
  16. github的健步如飞
  17. R的可视化以及ggplot2
  18. 硬件设计22之高速电路设计保险丝的选型
  19. 电脑重装:微PE工具箱重装win10系统
  20. 微信小程序解密过程(java)

热门文章

  1. 面向6G的去中心化的人工智能理论与技术
  2. 详细分析PHP源代码后门事件及其供应链安全启示
  3. 19 | 防火墙:如何和黑客“划清界限”?
  4. Oracle - 【连接1】广义笛卡儿积+一般连接+自连接
  5. 支持串口上传图片和数据到服务器的4G低功耗摄像头方案
  6. my ReadTravel_ Choson / Tailand Racha Island / Phuket Island / Malaysia
  7. 学习笔记19—dpabi错误集
  8. 1024程序员节!!
  9. 烽火华为4.2 亿元联合中标武汉地铁云....
  10. Django实现excel导入数据库(超详细)