摘要:Web Audio API是对<audio> 标签功能上的补充,我们可以用它完成混音、音效、平移等各种复杂的音频处理,本文简单的使用其完成音波图的绘制。

PS:本例子使用ES6编程,最好在新版chrome中运行。

一、前端文件index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>audiogram</title>
</head>
<body>
<canvas id="canvas" width="400" height="100"></canvas>
<button class="play" style="width: 50px;height: 50px;">开始</button>
<button class="stop" style="width: 50px;height: 50px;">停止</button>
</body>
<script type="module" src="Main.js"></script>
</html>

PS:浏览器加载ES6模板使用<script>标签时,要加入type = “module”属性,浏览器会默认异步加载,并知道Main.js是一个ES6模块。

二、创建Audio类

//audit类,用于加载,播放音乐
export class Audio { //单例
static getInstance() {
if (!Audio.instance) {
Audio.instance = new Audio();
}
return Audio.instance;
} //构造函数
constructor() {
this.ctx = new (window.AudioContext || window.webkitAudioContext)();
} //加载资源
getData() {
this.analyser = this.ctx.createAnalyser();
//从元素创建媒体节点 可以直接将audio元素传入后创建,就不用request来请求资源
//this.source = this.ctx.createMediaElementSource(audio);
this.source = this.ctx.createBufferSource();
this.source.loop = true;
//创建AnalyserNode,用来显示音频时间和频率的数据
this.source.connect(this.analyser);
//最后连接到音频渲染设备,发出声音
this.analyser.connect(this.ctx.destination); //获取频率
this.freqs = new Uint8Array(this.analyser.frequencyBinCount); //请求资源
let request = new XMLHttpRequest(); request.open('get', 'res/bgm.mp3', true); //responseType属性须设置为arraybuffer
request.responseType = 'arraybuffer'; //decodeAudioData方法用于解码音频文件
request.onload = () => {
var audioData = request.response;
this.ctx.decodeAudioData(audioData, (buffer) => {
//将解码后的音频文件作为声音的来源
this.source.buffer = buffer;
//立即开始播放声音
this.source.start(0);
}, (e) => {
"Error with decoding audio data" + e.error
});
}; request.send();
} }

三、创建Main类

import {Audio} from "./js/Audio.js";

//用于控制整个页面的流程
class Main {
constructor() {
//获取audio实例
this.audio = Audio.getInstance();
this.init();
} //初始化
init() {
//初始化按钮
this.play = document.querySelector('.play');
this.stop = document.querySelector('.stop'); //确保加载完资源后开始输出
let promise = new Promise((resolve) => {
this.audio.getData();
resolve();
});
promise.then(() => {
this.initCanvas();
this.outPut()
}); //播放按钮
this.play.onclick = () => {
this.audio.ctx.resume();
this.outPut();
this.play.setAttribute('disabled', 'disabled');
} //停止按钮
this.stop.onclick = () => {
this.audio.ctx.suspend();
//this.audio.source.stop(0);使用stop停止时无法恢复,需要重载资源
cancelAnimationFrame(this.timer);
this.play.removeAttribute('disabled');
}
} //初始化canvas
initCanvas() {
let cv = document.querySelector('#canvas');
this.canvasWidth = cv.width;
this.canvasHeight = cv.height;
this.canvas = cv.getContext("2d");
this.canvas.translate(0.5, 0.5);
this.outPutData = this.audio.freqs;
} //输出图像
outPut() {
var height = this.canvasHeight;
var width = this.canvasWidth;
var outPutData = this.outPutData;
var length = outPutData.length;
this.audio.analyser.getByteFrequencyData(outPutData);
//将缓冲区的数据绘制到Canvas上
this.canvas.clearRect(-0.5, -0.5, width, height);
this.canvas.beginPath(), this.canvas.moveTo(0, height);
for (var i = 0; i < width; i++)
this.canvas.lineTo(i, height - height * outPutData[Math.round(length * i / width)] / 255);
this.canvas.lineTo(i, height), this.canvas.fill();
//请求下一帧
this.timer = requestAnimationFrame(() => {
this.outPut()
});
}
}
new Main();

PS:在ES6中使用箭头函数时,箭头函数中的this指向Main,真的超级好用。

注意:使用chrome打开时会出现 Origin 'null' is therefore not allowed access.这是由于在本地html页面ajax请求本地或者局域网server的资源时,被浏览器禁止了,跨域请求会带来安全隐患,因此谷歌浏览器对此做出了限制。

在服务端我们可以设置response.setHeader("Access-Control-Allow-Origin: *")允许这么做,如果是客户端的话我们可以右键chrome快捷方式—>属性->目标-> 将"--allow-file-access-from-files"添加至最后重启浏览器即可。

工程目录结构:

└── audiogram
    ├── js
    │   └── Audio.js
    ├── res   
     │   └── bgm.mp3
     ├ ─ ─   index.html
     └ ─ ─   Main.js
 
效果图:

使用Web Audio API绘制音波图的更多相关文章

  1. Web Audio API之手把手教你用web api处理声音信号:可视化音乐demo

    1.Web Audio API 介绍 Web Audio API 提供了在Web上控制音频的一个非常有效通用的系统 ,这些通用系统通俗的讲就是我们可以利用Web Audio API提供的各种方法操作各 ...

  2. HTML5 ——web audio API 音乐可视化(二)

    上一篇 web audio API 音乐可视化(一)介绍了一些基本的API,以及如何简单的播放一个音频,本篇介绍一下怎么对获取到的音频进行分析,并将分析后的数据绘制成图像. 最终效果请戳这里; 完整版 ...

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

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

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

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

  5. [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 ...

  6. 关于Web Audio API的入门

    Web Audio API提供了一个简单强大的机制来实现控制web应用程序的音频内容.它允许你开发复杂的混音,音效,平移以及更多. 可以先看一下MDN的这篇文章<Web Audio API的运用 ...

  7. H5的Web Audio Api

    概述 研究Web Audio Api的主要原因是:工作中需要在ios中实现声音的淡出效果,主要是通过setInterval来改audio标签的volume属性实现的,但是ios上面volume属性是只 ...

  8. HTML5 ——web audio API 音乐可视化(一)

    使用Web Audio API可以对音频进行分析和操作,最终实现一个音频可视化程序. 最终效果请戳这里; 完整版代码请戳这里,如果还看得过眼,请给一个start⭐ 一.API AudioContext ...

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

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

随机推荐

  1. Python学习之条件判断和循环

    #coding= utf-8 # 条件判断和循环 # 如果if语句判断是True,就把缩进的两行print语句执行了,否则,什么也不做 age1 = 20 if age1 >= 18: prin ...

  2. centos7 yum相关的常用命令

    [root@mini1 ~]# history |grep yum 40 yum repolist 42 cd /etc/yum.repos.d/ 49 yum clean all 50 yum re ...

  3. python/匿名函数和内置函数

    1 匿名函数 匿名函数是lambda定义的没有名字的具有一些小功能的函数 具体形式是 lambda 参数列表:返回值表达式 lambda x: X**2 # 求平方操作 lambda x: x> ...

  4. xpath的一般用法与特殊用法

    # xpath的使用 安装lxml from lxml import etree Selector = etree.HTML(网页代码) Selector.xpath(一段神奇的代码) xpath的一 ...

  5. ecshop PC版本智能跳转到对应手机版页面

    以下适用于PC跳转到ectouch手机版的写法.其他手机端的方法类似. 修改文件 includes/lib_main.php 增加以下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...

  6. 解决:My97DatePicker 日期插件引用在PHP文件中maxDate和minDate控制失效问题

    开发环境: 语言:PHP 框架:ThinkPHP 问题:在引用插件My97DatePicker时,想实现:开始日期不能大于结束日期,结束时间不能小于开始时间 步骤一.查看文档官方文档http://ww ...

  7. Set<E> 接口简明

    java. util. Set 接口 Set 接口中的方法和 Collection 中方法一致的.Set 接口取出方式只有一种, 迭代器 . HashSet : 底层数据结构是哈希表,线程 是不同步的 ...

  8. 关于jsp页面加载时报错500的问题

    先说一下,问题的发生,个人做了个小系统,成品以后运行了几次,没有问题,结果最后一次测试时,发现登陆页面报错了: 账号密码输入正确,经过后台登陆后,按理说是应该进入登陆成功后的jsp页面,然而结果却是: ...

  9. OS模块文件操作一

    1          文件操作 1.1               OS模块 l  import os  #引入os模块 l  import os.path  #引入os下的path子模块 l  os ...

  10. springboot集成mybatis(一)

    MyBatis简介 MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyB ...