本系列文章主要是介绍 Web Audio API 的相关知识,由于该技术还处在 web 草案阶段(很多标准被提出来,至于取舍需要等待稳定版文档来确定,草案阶段的文档很多都会被再次编辑甚至重写、全部删除等,不适合作为正式参考),很多 API 都是未确定的,目前支持 Web Audio API 的浏览器是较新版的 Google Chrome 和 FireFox,其他浏览器暂时还没有兼容。

现在的网络硬件环境还没有达到普遍语音通信的条件,但是 web语音通信 一定会成为后期 web 研究的一个重要话题,凭着一点个人兴趣,拿出来研究研究~

本文主要介绍 Web Audio API 的相关特性,以及音频源的获取方式。

本文地址:http://www.cnblogs.com/hustskyking/p/webAudio-listen.html,转载请注明源地址。

一、Web Audio

<audio> 标签的到来之前,Flash 以及其他的插件相继打破 web 的宁静,而如今 audio 被送到了 web 开发之中,我们再也不需要引用各种插件来播放声音了。

1. Web Audio API 的特性

Web Audio API 是 JavaScript 中主要用于在网页应用中处理音频请求的一个高级应用接口,这个 API 目的是用于让最新技术与传统的游戏音频引擎的综合处理相兼容,也即尽力提供一些桌面音频处理程序的要求。

  • 查看音频播放期间调度事件发生的确切时间;
  • 支持各种类型的音频过滤波器以实现各种效果,包括回声、消除噪音等;
  • 支持利用合成声音(Sound synthesis)创建电子音乐;
  • 支持3D位置音频模拟效果,比如某种声音随着游戏场景而移动;
  • 支持外部输入的声音与 WebRTC 进行集成(调用 WebRTC ,在你的设备中增添吉他声),或者在 WebRTC 中调用其他地方传输过来的声音;
  • 利用音频数据分析创造良好的可视化声音等。

2. AudioContent 简介

Web Audio API 可以用来操作或者播放网页以及应用中的 audio 资源,在一个 Audio上下文环境(AudioContext)中,有各种 Audio节点(AudioNode),如:

Interface description
AudioContext 包含表示连接中间件 AudioNodes 的音频信号曲线图
AudioNode 表示 audio源,audio输出以及 中间处理模块,他处在 AudioContext 的上下文中
AudioDestinationNode 他是 AudioNode 的一个子类,表示所有被渲染音频流到达的最终地点
AudioBuffer 表示 audio资源 的一个临时缓存,可表示一个音频剪辑
AudioBufferSourceNode 从 AudioBuffer 中生成 audio 的 AudioNode 节点
ScriptProcessorNode 一个可以直接被 JS 操作的 AudioNode 节点
GainNode 音频增益节点
OscillatorNode 一个可产生固定频率的 audio 源

还有其他的 API 可以查看http://www.w3.org/TR/webaudio/#APIOverview.

使用 AudioContext 实例,我们可以将生成的一个或者多个音频流连接到声音的输出位置,这个连接并不一定是直接送到输出端,期间可以使用 AudioNodes 作为中继器和处理器,让这些声音信号有一个更好的效果。

单个 AudioContext 实例可以支持多音频的输入,所以对于一个 audio 应用我们只需要创建一个实例就行了。很多诸如创建一个 AudioNode 节点、解码音频文件等方法都是 AudioContext 的内置方法。创建一个 AudioContext 上下文也十分简单:

var context;
try{
window.AudioContext = window.AudioContext || window.webkitAudioContext;
context = new AudioContext();
}
catch(e) {
alert('请更新至最新版的 Chrome 或者 Firefox');
}

二、音频流的获取

1. 标签引入

标签引入是最直接的方式,

<audio autoplay src="http://qianduannotes.duapp.com/file/tankWar.mp3">
浏览器不支持 audio 标签。
</audio>

如果浏览器不支持 audio 标签,便会将其当做一个普通元素来解析,中间一行字也就会被显示出来。而支持 audio 标签的浏览器会忽略标签内任何文本。我们还可以为他加上 autoplay 、loop 等属性,使音频在进入页面之后立即循环播放。

<audio autoplay="autoplay" controls="controls" src="http://qianduannotes.duapp.com/file/tankWar.mp3">
浏览器不支持 audio 标签。
</audio>

controls 属性是用来控制显示音频文件的控制部分的。默认未设置 controls 属性。

2. webRTC mediaStream Media Capture (多谢@Hehe123提醒,RTC属于通信了,此处只是获取 media 流)

利用 getUserMedia 拿到本地的音频流。

// 前缀处理
window.AudioContext = window.AudioContext ||
window.webkitAudioContext;
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia; var context = new AudioContext(); navigator.getUserMedia({audio: true}, function(stream) {
// 获取本地流送入 AudioContext
var microphone = context.createMediaStreamSource(stream); // filter为一个中间处理器,用来过滤音频
var filter = context.createBiquadFilter(); // microphone -> filter -> destination.
microphone.connect(filter);
filter.connect(context.destination);
}, function(){
console.log("出了点问题~ 是否在服务器环境下运行?");
});

这里需要注意的是,使用 webRTC 需要在服务器环境下,你可以搭建一个本地服务器,也可以把代码上传到远程服务器上测试。

3. FileSystem

选择本地文件,读取音频流,拿到 Blob 流地址,送入 audio 中

<input type="file" onchange="return run(this.files);" /><br /><br />
<audio controls id="audio"></audio>
<script type="text/javascript">
function run(files){
var blob = window.webkitURL.createObjectURL(files[0]);
audio.src = blob;
audio.autoplay = "autoplay";
}
</script>

4. 移动设备,还可以使用如下方式

1)HTML Media Capture

<input type="file" accept="audio/*;capture=microphone">

2)device 元素

<device type="media" onchange="update(this.data)"></device>
<audio autoplay></video>
<script>
function update(stream) {
document.querySelector('audio').src = stream.url;
}
</script>

5. 从键盘获取

本质并不是从键盘获取,而是通过键盘获取到我们设定的频率值,然后通过程序创建一段音频。如下面的程序:

下面例子中可以按键盘上中间的一排按键(A到K)来发出不同的声音。

var AudioContext=AudioContext||webkitAudioContext;
var context=new AudioContext;
//为每个键盘位对应一个频率
var s={65:256,83:288,68:320,70:341,71:384,72:426,74:480,75:512};
//为每个频率创建一个Oscillator
for(var i in s)
value=s[i],
s[i]=context.createOscillator(),
s[i].frequency.value=value,
s[i].start();
//键盘按下时将相应频率的Oscillator连接到输出源上
addEventListener("keydown",function(e){
if(e=s[e.keyCode])e.connect(context.destination);
});
//键盘松开时将相应频率的Oscillator的连接取消
addEventListener("keyup",function(e){
if(e=s[e.keyCode])e.disconnect();
});

这段代码引自次碳酸钴的博客.

三、小结

本文是个介绍性的文章,提到了 Web Audio API 的相关知识,以及如何在你的 web 程序中引入 音频流。没有写相关 demo,感兴趣的童鞋可以复制代码自己去测试,在后续文章中会给出测试 DEMO。

四、参考文章

[Voice communications] 让音乐响起来的更多相关文章

  1. [Voice communications] 声音的滤波

    本系列文章主要是介绍 Web Audio API 的相关知识,以及 web语音通信 中会遇到的一些问题,阐述可能存在错误,还请多多斧正! 通过设备获取音频流会不可避免的渗入一些杂音,这些杂音可能来自你 ...

  2. [Voice communications] 声道的转换

    本系列文章主要是介绍 Web Audio API 的相关知识,以及 web语音通信 中会遇到的一些问题,阐述可能存在错误,还请多多斧正! 很多粤语剧都提供了两个声道,一个左声道为粤语,一个右声道有国语 ...

  3. [Voice communications] 音量的控制

    改变音频的音量是音频处理中最基础的部分,我们可以利用 GainNode 来构建 Mixers 的结构块.GainNode 的接口是很简单的: interface GainNode : AudioNod ...

  4. [Voice communications] 看得到的音频流

    上文介绍了 Web Audio API 的相关知识,以及如何在你的 web 程序中引入 音频流,内容都是介绍性的,所以没有写太多 DEMO.本文重点讲解如何利用 Web Audio API 中的中间节 ...

  5. [转载]jquery版小型婚礼(可动态添加祝福语)

    原文链接:http://www.cnblogs.com/tattoo/p/3788019.html 前两天在网上不小心看到“js许愿墙”这几个字,我的神经就全部被调动了.然后就开始我 的百度生涯,一直 ...

  6. jquery版小型婚礼(可动态添加祝福语)

    前两天在网上不小心看到“js许愿墙”这几个字,我的神经就全部被调动了.然后就开始我的百度生涯,一直寻觅许愿墙背景图片和便利贴图片,觅了好久……一直没找到满意的……无意间看到祝福语和一些卡通婚礼图片.最 ...

  7. (Step by Step)How to setup IP Phone Server(VoIP Server) for free.

    You must have heard about IP Phone and SIP (Software IP Phone).Nowadays standard PSTN phone are bein ...

  8. 从零开始学习PYTHON3讲义(十四)写一个mp3播放器

    <从零开始PYTHON3>第十四讲 通常来说,Python解释执行,运行速度慢,并不适合完整的开发游戏.随着电脑速度的快速提高,这种情况有所好转,但开发游戏仍然不是Python的重点工作. ...

  9. .Net外包篇:我是怎么看待外包的(二)

    延续上篇文章.net外包篇:我是如何看待外包的. 从这家公司辞职以后,得益于我校园信息平台和高校信息管理的经验,我进入了一个互联网类型公司.以前的经历,环环相扣,步步提升. 互联网时代 第四家客户(未 ...

随机推荐

  1. 利用(Tcmalloc) google-perftools优化Nginx和MySQL性能

    一.安装libunwind wget http://download.savannah.gnu.org/releases/libunwind/libunwind-1.1.tar.gz 本地下载:htt ...

  2. Hibrenate学习的第一天

    问题一:用sqlyog创建一个数据库,用Hibernate传入中文为什么变? 答:在hibernate中的数据连接处要添加 ?useUnicode=true&characterEncoding ...

  3. springAOP实现基于注解的数据源动态切换

    需求 代码实现读写数据库分离 武器 spring3.0以上版本 实现思路 1.继承org.springframework.jdbc.datasource.lookup.AbstractRoutingD ...

  4. js动态时间

    一.在<head></head> 之间写入下面js代码 <script type="text/javascript" language="J ...

  5. ubuntu14.04设置terminal配色方案以配合使用vim的Solarized插件

    在安装vim插件之前,首先安装Vundle插件,用来管理vim插件,安装方法查看Vundle在github上的指南.在安装vundle的时候出现了一个错误E117:unknown function v ...

  6. Swift基础语法(一)

    swift是一个基于objc进化过来的一个新的 OS X/IOS编程语言,而objc是基于c语言进化过来的一门编程语言.所以理论上说objc与c++是同一代产物并且objc与c++是相互独立的两套体系 ...

  7. 记录参加“牛津计划.Docker在线黑客松”比赛的过程

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  8. KIWI Syslog配置

    日志服务器Kiwi+Syslogd+8.3.7破解版 Window收集服务器日志evtsys_exe_32 默认地,kiwi使用UDP 514端口接收日志数据,安装成功后即可接收日志 使用命令nets ...

  9. mybatis按时间条件搜索

    dto接受前台字符串时间格式 @DateTimeFormat(pattern = "yyyy-MM-dd") private Date contractStartDt; @Date ...

  10. P1906联合权值

    描述 无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 WiWi, 每条边的长度均为 1.图上两点(u, v)的距离定义为 u 点到 v 点的最短距离. ...