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属性内容请自己在本机找一个浏览器支持的声音源格式。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="Author" contect="GabrielChen">
  6. <meta name="keywords" contect="Web Audio API">
  7. <title>Web Audio API 学习</title>
  8. <script>
  9. var canvas;
  10. var ctx;
  11. var audioContext;
  12. var analyser;
  13. var mic;
  14.  
  15. function init() {
  16. canvasOne = document.getElementById('canvasOne');
  17. ctx = canvasOne.getContext("2d");
  18. canvasTwo = document.getElementById('canvasTwo');
  19. ctx2 = canvasTwo.getContext("2d");
  20.  
  21. }
  22.  
  23. navigator.getMedia = ( navigator.getUserMedia ||
  24. navigator.webkitGetUserMedia ||
  25. navigator.mozGetUserMedia ||
  26. navigator.msGetUserMedia);
  27.  
  28. navigator.getMedia ( { audio: true }, function (stream) {
  29. audioContext = new (window.AudioContext || window.webkitAudioContext);
  30.  
  31. mic = audioContext.createMediaStreamSource(stream);
  32.  
  33. analyser= audioContext.createAnalyser();
  34.  
  35. analyser.fftSize = 256;
  36. mic.connect(analyser);
  37. drawSpectrum();
  38. },function(){});
  39.  
  40. function drawSpectrum() {
  41. var WIDTH = canvasOne.width;
  42. var HEIGHT= canvasOne.height;
  43.  
  44. var array = new Uint8Array(128);
  45. analyser.getByteFrequencyData(array);
  46. ctx.clearRect(0, 0, WIDTH, HEIGHT);
  47. ctx2.clearRect(0, 0, 800, 800);
  48. for ( var i = 0; i < (array.length); i++ ){
  49. var value = array[i];
  50. ctx.fillRect(i*5,HEIGHT-value,3,HEIGHT);
  51. }
  52.  
  53. for ( var i = 0; i < (array.length); i++ ){
  54. var value = array[i];
  55. ctx2.beginPath();
  56. ctx2.arc(300,300,value,0,360,false);
  57. ctx2.lineWidth=5;
  58. ctx2.strokeStyle="rgba("+value+","+value+",0,0.2)";
  59. ctx2.stroke();//画空心圆
  60. ctx2.closePath();
  61.  
  62. }
  63.  
  64. requestAnimationFrame(drawSpectrum);
  65. };
  66.  
  67. </script>
  68. <style>
  69. #canvasOne {
  70. border: 1px solid #ddd;
  71. }
  72. </style>
  73. </head>
  74. <body onload="init();">
  75. <h1>从audio源获取声音</h1>
  76. <audio src="./Fatbros.ogg" controls="controls" id="audio">你的浏览器不支持audio标签</audio>
  77. <h1>audio读取声音</h1>
  78. <canvas id="canvasFormAudio" width="640"></canvas>
  79. <h1>频域图模仿</h1>
  80. <canvas id="canvasOne" width="640"></canvas>
  81. <h1>圆形声波图</h1>
  82. <canvas id="canvasTwo" width="800" height="800"></canvas>
  83.  
  84. <script type="text/javascript">
  85.  
  86. var context1;
  87. var source;
  88. var analyserfa;
  89. var canvasFormAudio;
  90. var ctxfa;
  91.  
  92. canvasFormAudio = document.getElementById('canvasFormAudio');
  93. ctxfa = canvasFormAudio.getContext("2d");
  94. try {
  95.  
  96. context1 = new (window.AudioContext || window.webkitAudioContext);
  97. } catch(e) {
  98. throw new Error('The Web Audio API is unavailable');
  99. }
  100.  
  101. analyserfa=context1.createAnalyser();
  102.  
  103. window.addEventListener('load', function(e) {
  104. var audio =document.getElementById("audio");
  105. var source = context1.createMediaElementSource(audio);
  106. source.connect(analyserfa);
  107. analyserfa.connect(context1.destination);
  108.  
  109. drawSpectrumfa();
  110.  
  111. }, false);
  112. function drawSpectrumfa() {
  113. var WIDTH = canvasFormAudio.width;
  114. var HEIGHT= canvasFormAudio.height;
  115.  
  116. var array = new Uint8Array(128);
  117.  
  118. analyserfa.getByteFrequencyData(array);
  119.  
  120. ctxfa.clearRect(0, 0, WIDTH, HEIGHT);
  121.  
  122. for ( var i = 0; i < (array.length); i++ ){
  123. var value = array[i];
  124.          ctxfa.fillRect(i*5,HEIGHT-value,3,HEIGHT);
  125. }
  126.  
  127. requestAnimationFrame(drawSpectrumfa);
  128. }
  129. </script>
  130. </body>
  131. </html>

  

  

3.代码分析

我们从body部分入手分析

  1. <body onload="init();">
  2. <h1>从audio源获取声音</h1>
  3. <audio src="./Fatbros.ogg" controls="controls" id="audio">你的浏览器不支持audio标签</audio>
  4. <h1>audio读取声音</h1>
  5. <canvas id="canvasFormAudio" width="640"></canvas>
  6. <h1>频域图模仿</h1>
  7. <canvas id="canvasOne" width="640"></canvas>
  8. <h1>圆形声波图</h1>
  9. <canvas id="canvasTwo" width="800" height="800"></canvas>

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

  1. function init() {
  2. canvasOne = document.getElementById('canvasOne');
  3. ctx = canvasOne.getContext("2d");
  4. canvasTwo = document.getElementById('canvasTwo');
  5. ctx2 = canvasTwo.getContext("2d");
  6.  
  7. }

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

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

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

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

获取声音源以及绘图

  1. //直接从audio处理音频源,声明一些必要的变量
  2. var context1;
  3. var source;
  4. var analyserfa;
  5. var canvasFormAudio;
  6. var ctxfa;
  7. //初始化画布
  8. canvasFormAudio = document.getElementById('canvasFormAudio');
  9. ctxfa = canvasFormAudio.getContext("2d");
    //建立一个音频环境,因为浏览器实现不同,做了一点兼容性处理
  10. try {
  11.  
  12. context1 = new (window.AudioContext || window.webkitAudioContext);
  13. } catch(e) {
  14. throw new Error('The Web Audio API is unavailable');
  15. }
  16. //建立一个分析器
  17. analyserfa=context1.createAnalyser();
  18.  
  19. window.addEventListener('load', function(e) {
  20. // 从audio标签获取声音源 source
  21. var audio =document.getElementById("audio");
  22. var source = context1.createMediaElementSource(audio);
  23. source.connect(analyserfa);
  24. analyserfa.connect(context1.destination);
  25. //调用绘图函数
  26. drawSpectrumfa();
  27.  
  28. }, false);
          //绘图函数
  29. function drawSpectrumfa() {
  30. var WIDTH = canvasFormAudio.width;
  31. var HEIGHT= canvasFormAudio.height;
  32.  
  33. var array = new Uint8Array(128);
  34. //复制当前的频率值到一个无符号数组中
  35. analyserfa.getByteFrequencyData(array);
  36.  
  37. //clearRect(矩形左上角x坐标,矩形左上角y坐标,清除矩形的宽,清除矩形的高)
  38. ctxfa.clearRect(0, 0, WIDTH, HEIGHT);
  39. //循环生成长条矩形
  40. for ( var i = 0; i < (array.length); i++ ){
  41. var value = array[i];
  42.  
  43. //fillRect(矩形左上角x坐标,矩形左上角y坐标,矩形宽,矩形高)
             //这里我们的array一共有128组数据,所以我们当时canvas设置的宽度为5*128=640
  44. ctxfa.fillRect(i*5,HEIGHT-value,3,HEIGHT);
  45. }
  46.  
  47. //根据浏览器频率绘图或者操作一些非css效果
  48. requestAnimationFrame(drawSpectrumfa);
  49. }

  

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

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

绘图区域

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

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

  1. var canvas;
  2. var ctx;
  3. var audioContext;
  4. var analyser;
  5. var mic;
  6. //初始化两个画布的函数,声明为2d绘图
  7. function init() {
  8. canvasOne = document.getElementById('canvasOne');
  9. ctx = canvasOne.getContext("2d");
  10. canvasTwo = document.getElementById('canvasTwo');
  11. ctx2 = canvasTwo.getContext("2d");
  12.  
  13. }
  14. //getMedia调用参数如下,返回一个多媒体流
        //constraints可选{ video: true, audio: true },代表获取多媒体的类型
    //var stream = navigator.getUserMedia(constraints, successCallback, errorCallback);
  15.  
  16. navigator.getMedia = ( navigator.getUserMedia ||
  17. navigator.webkitGetUserMedia ||
  18. navigator.mozGetUserMedia ||
  19. navigator.msGetUserMedia);
  20.  
  21. navigator.getMedia ( { audio: true }, function (stream) {
  22. audioContext = new (window.AudioContext || window.webkitAudioContext);
  23. //返回一个多媒体流
  24. mic = audioContext.createMediaStreamSource(stream);
  25. //creates an AnalyserNode 创建一个分析节点
  26. analyser= audioContext.createAnalyser();
  27. //fftsize默认值2048,是快速傅立叶变换用于频域分析的值,必须为2的幂,而我们得到的数据通常为其的一半,下面会说道
  28. analyser.fftSize = 256;
  29. mic.connect(analyser);
          //调用绘图函数
  30. drawSpectrum();
  31. },function(){});
  32.  
  33.      //圆形声波绘图和矩形绘图
  34. function drawSpectrum() {
  35. var WIDTH = canvasOne.width;
  36. var HEIGHT= canvasOne.height;
  37.        //长度为128无符号数组用于保存getByteFrequencyData返回的频域数据
  38. var array = new Uint8Array(128);
  39. analyser.getByteFrequencyData(array);
           //以下是根据频率数据画图,主要为canvas知识,不做详细解答
  40. ctx.clearRect(0, 0, WIDTH, HEIGHT);
  41. ctx2.clearRect(0, 0, 800, 800);
  42. for ( var i = 0; i < (array.length); i++ ){
  43. var value = array[i];
  44. ctx.fillRect(i*5,HEIGHT-value,3,HEIGHT);
  45. }
  46.  
  47. //ctx2.clearRect(700, 700, WIDTH, HEIGHT);
  48. for ( var i = 0; i < (array.length); i++ ){
  49. var value = array[i];
  50. ctx2.beginPath();
  51. ctx2.arc(300,300,value,0,360,false);
  52. ctx2.lineWidth=5;
  53. ctx2.strokeStyle="rgba("+value+","+value+",0,0.2)";
  54. ctx2.stroke();//画空心圆
  55. ctx2.closePath();
  56.  
  57. }
  58. //
  59. requestAnimationFrame(drawSpectrum);
  60. };

 

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

  

Web Audio API之手把手教你用web api处理声音信号:可视化音乐demo的更多相关文章

  1. 手把手教你把web应用丢到服务器上(单页应用+ 服务端渲染)

    前两篇文章中,我分别介绍了框架的搭建利用vue-cli + vant搭建一个移动端开发模板,并且把项目中axios请求和vuex的用法做了简要的介绍如何在项目里管理好axios请求与vuex.在这两篇 ...

  2. 手把手教你入门web.xml:吃透监听器

    监听器的原理: 被监听对象→对象拥有的事件→捕获到事件变化→监听器捕捉事件→监听器处理该事件 Web服务器上有4个范围,抛开page范围,还有request范围,session范围,applicati ...

  3. 手把手教你搭建WEB服务器和FTP服务器

    注:本次教程的环境是在“Windows 10 PC中远程控制的Windows Server 2012 R2服务器”,你可以自己在自己电脑中安装虚拟机再安装Windows Server 2012 R2服 ...

  4. 手把手教你用Python网络爬虫获取网易云音乐歌曲

    前天给大家分享了用Python网络爬虫爬取了网易云歌词,在文尾说要爬取网易云歌曲,今天小编带大家一起来利用Python爬取网易云音乐,分分钟将网站上的音乐down到本地. 跟着小编运行过代码的筒子们将 ...

  5. 【Web Audio API】 — 那些年的 web audio

    转 TAT.Jdo:[Web Audio API] - 那些年的 web audio 这主题主要是早期对 web audio api的一些尝试,这里整理一下以便以后翻阅,如有错误,诚请指正. 在这之前 ...

  6. 手把手教你如何优雅的使用Aop记录带参数的复杂Web接口日志

    前言 不久前,因为需求的原因,需要实现一个操作日志.几乎每一个接口被调用后,都要记录一条跟这个参数挂钩的特定的日志到数据库.举个例子,就比如禁言操作,日志中需要记录因为什么禁言,被禁言的人的id和各种 ...

  7. 【HTML5】Web Audio API打造超炫的音乐可视化效果

    HTML5真是太多炫酷的东西了,其中Web Audio API算一个,琢磨着弄了个音乐可视化的demo,先上效果图: 项目演示:别说话,点我!  源码已经挂到github上了,有兴趣的同学也可以去st ...

  8. 关于HTML5音频——audio标签和Web Audio API各平台浏览器的支持情况

    对比audio标签 和 Web Audio API 各平台浏览器的支持情况:   audio element Web Audio API desktop browsers Chrome 14 Yes  ...

  9. [Javascript] Intro to the Web Audio API

    An introduction to the Web Audio API. In this lesson, we cover creating an audio context and an osci ...

随机推荐

  1. Attention注意力机制介绍

    什么是Attention机制 Attention机制通俗的讲就是把注意力集中放在重要的点上,而忽略其他不重要的因素.其中重要程度的判断取决于应用场景,拿个现实生活中的例子,比如1000个人眼中有100 ...

  2. HADOOP docker(七):hive权限管理

    1. hive权限简介1.1 hive中的用户与组1.2 使用场景1.3 权限模型1.3 hive的超级用户2. 授权管理2.1 开启权限管理2.2 实现超级用户2.3 实现hiveserver2用户 ...

  3. Python3 数据类型-集合

    在Python中集合set是基本数据类型的一种,它有可变集合(set)和不可变集合(frozenset)两种.创建集合set.集合set添加.集合删除.交集.并集.差集的操作都是非常实用的方法. 集合 ...

  4. from module import 和 import 的区别

    最近在用codecademy学python,遇到一些题目错误,小小记录一下 如from math import sqrt是把sqrt作为本文件的方法导入进来了,使用的时候只需要直接调用sqrt. 而如 ...

  5. 常用排序算法--java版

    package com.whw.sortPractice; import java.util.Arrays; public class Sort { /** * 遍历一个数组 * @param sor ...

  6. JS DOM视频相关的知识

    1.实现点击a标签改变图片时,如果a的href属性有一个目标网址,但是点击又必须跳转到另外一张图,往往会最后跳转到目标网址,可以在onclick事件函数中加入ruturn false,阻止跳转到页面. ...

  7. 【alpha】Scrum站立会议第2次....10.17

    小组名称:nice! 小组成员:李权 于淼 杨柳 刘芳芳 项目内容:约跑app 1.任务进度 成员 已完成 今日完成 李权 数据库设计 消息发送代码实现 于淼 注册.登录界面,以及登录界面后台代码.发 ...

  8. 原生js移动端可拖动进度条插件

    该插件最初的想法来自网上的一篇文章,直达链接:https://www.cnblogs.com/libin-1/p/6220056.html 笔者因为业务需要寻找到这个插件,然后拿来用之,发现各种不方便 ...

  9. 【Quartz.net】- Cron表达式

    一.结构 corn从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份 二.各字段的含义   字段 允许值 允许的特殊字符 秒(Seconds) 0~59的整数 , - * / ...

  10. win7系统日志分支删除方法

    这篇日志有问题,自己亲身尝试失败,这里只提供思路,谢谢(改天突破再做修改) 之前电脑装过德国的叫啥子软件来着,当时在系统自动创建了日志,后来软件卸载了,发现还是有这个日志主键,(我有强迫症)心里不爽, ...