楔 子

  随着移动互联网时代的开启,各种移动设备走进了我们的生活。无论是日常生活中人手一部的手机,还是夜跑者必备的各种智能腕带,亦或者是充满未来科技感的google glass云云,它们正渐渐改变着我们的生活习惯以及用户交互习惯。触摸屏取代了实体按键,Siri开始慢慢释放我们的双手,而leap motion之类的硬件更是让我们彻底不需要接触IT设备便能通过手势控制它们。在这样的大背景下,前端的交互将涉及越来越多元的交叉学科,我们正如十几年前人们经历Css的诞生一样,见证着一场带动整个行业乃至社会的变革。

放下IE6正如你放下table布局

  如果现今你的工作还只是每天严谨地去兼容IE6,那么是时候起身遥望身边的风景了,HTML5已经远远不只是那些渐变和圆角了。这篇博文中,我会像大家介绍Web SpeechWeb Audio两组API,这是MyVoix.js框架的核心组成部分,在早前好几个版本的chrome这就已经实现,你可以通过webkit前缀调用他们。

Web Speech

  WebSpeech API是由Speech API Community Group发布,主要功能是将语音输入转换成文字,如果你能加上一个语义分析的服务器,那它就是一个Siri。你也可以简单地把它理解成一个可编程的input语音输入框(如下代码)。

<input type=”text” x-webkit-speech lang=”zh-CN” />

  在Siri刚刚出世的那个年代,上面这行代码就是前端界让屌丝变高富帅的利器,老板才不知道你才写了一行代码就搞出一个语音输入框(偷偷在input上加过x-webkit-speech的同学们请点赞)。但是,仅仅一个输入框标签显然不能满足程序员们那熊熊燃烧对代码的控制欲,于是Web Speech应运而生。

  再回到代码,要使用webSpeech API我们首先要创建一个window.webkitSpeechRecognition对象。

 var _rec =new window.webkitSpeechRecognition();
_rec.continuous=true;
_rec.interimResults=false;
_rec.lang='en-US';
_rec.maxAlternatives=1;

  为了大家看的清楚,这里我稍稍修改了MyVoix中的源码。可以看到新建SpeechRecognition实例后,有几个参数需要我们配置。

  continuous:如果置为false,那么当实例start之后,若没有输入或者输入错误就会立刻返回。这里需要等到有意义的输入才返回,所以我们置为true。

  interimResults:如果设置为true,那么在onresult的时候就会不断有分析过程中的单词返回。这里只需要最后的分析结果,所以置为false。

  lang:这个是语言,大家应该都看的懂。

  maxAlternatives:设置的是每个result最大的SpeechRecognitionAlternatives。

  接下来我们调用实例的start方法就会开启SpeechdRecognition的监听。但是在此之前还需要指定实例的onresult事件,语音分析完成后的单词会传入这个方法。

 _rec.onresult=function(eve){
var len = eve.results.length,
i = eve.resultIndex,
j = 0,
listeners,
command;
for (i; i < len; i += 1) {
if (eve.results[i].isFinal) {
// get words
command = eve.results[i][0].transcript.replace(/^\s+|\s+$/g, '').toLowerCase();
if(console.log){
console.log(eve.results[i][0].transcript);
}
//your code here....
}
}
};
_rec.start();

  MyVoix中对于单词事件的绑定有自己的架构,之后的博文有机会会详述。

Web Audio

搞定了语音识别,接下来我们就需要获得麦克风的输入信号,以便实现MyVoix中的绘制波形功能。如果你用javascript调用过摄像头,那你一定用过navigator.webkitGetUserMedia这个东西,Web Audio中获取麦克风的音源数据就需要用到它。先看一下MyVoix中的源码:

 navigator.webkitGetUserMedia({audio:true},function(e){
var context = new webkitAudioContext(),
javascriptNode = context.createScriptProcessor(2048, 1, 1),
audioInput = context.createMediaStreamSource(e),
analyser = context.createAnalyser(),
splitter = context.createChannelSplitter();
analyser.smoothingTimeConstant = 0.3;
analyser.fftSize = 1024;
audioInput.connect(splitter);
splitter.connect(analyser,0,0);
analyser.connect(javascriptNode);
javascriptNode.connect (context.destination); javascriptNode.onaudioprocess = function(e) {
var array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(array);
var average = me.getAverageVolume(e.inputBuffer.getChannelData (0));
if (average > 0) {
me.changeNoise(average);
me.changeFrequence(average);
}
}
},function(){});

  初看之下,和WebGL有点类似,你需要链接一堆堆的东西。进一步分析代码:

navigator.webkitGetUserMedia({audio:true},function(e){
//success callback
//...
},function(){
//error callback
//...
};

  第一步使用webkitGetUserMedia对象调用本地麦克风,主要代码在成功回调函数中实现。

var context = new webkitAudioContext(),
audioInput = context.createMediaStreamSource(e);

  之后我们需要建立一个webkitAudioContext实例,通过该实例可以创建许多有用的元件。这里通过createMediaStreamSource方法和getUserMedia成功回调函数中的参数可以创建一个输入源。 通过一层层的传递可以最终连接到context.destination这个输出位置。我们简单过一下MyVoix中用到的几个节点:

  analyser:这个一看就是分析音源用的,具体一般用在声音可视化上。

  splitter:此节点用以声道转换,在MyVoix中我们用它把音源变成了左右两个声道。

  javascriptNode:这个节点我们用来进行javascript级别的监听处理。通过onaudioprocess函数,在每次声音完成采样的时候,调用我们绘制波形的函数,并最终通过它连接到输出端。

  在MyVoix2.0中,大致就只用到了以上几个AudioContext创造的节点。通过类似的方法加入其他节点,Web Audio还可以实现声音在3D空间中定位播放等功能。

 

尾 声

  本文介绍了在MyVoix中用到的两个核心的技术,通过这篇博文希望大家对语音技术在html端的实现有大致的了解。我们在园子里写作,不用像鲁迅先生一样战斗,却也盼着技术推进这个时代。

myvoix源码地址

  转发请注明出处http://www.cnblogs.com/Arthus/p/3889457.html

MyVoix2.0.js 源码分析 WebSpeech与WebAudio篇的更多相关文章

  1. Vue.js 源码分析(二十三) 指令篇 v-show指令详解

    v-show的作用是将表达式值转换为布尔值,根据该布尔值的真假来显示/隐藏切换元素,它是通过切换元素的display这个css属性值来实现的,例如: <!DOCTYPE html> < ...

  2. Vue.js 源码分析(二十一) 指令篇 v-pre指令详解

    该指令会跳过所在元素和它的子元素的编译过程,也就是把这个节点及其子节点当作一个静态节点来处理,例如: <!DOCTYPE html> <html lang="en" ...

  3. Vue.js 源码分析(二十) 指令篇 v-once指令详解

    数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值,例如:<p>Message: {{ msg }}</p>以后每当msg属性发生了改变,插值处的内 ...

  4. Vue.js 源码分析(十九) 指令篇 v-html和v-text指令详解

    双大括号会将数据解释为普通文本,而非 HTML 代码.为了输出真正的 HTML,你需要使用 v-html 指令,例如: <!DOCTYPE html> <html lang=&quo ...

  5. Vue.js 源码分析(十八) 指令篇 v-for 指令详解

    我们可以用 v-for 指令基于一个数组or对象来渲染一个列表,有五种使用方法,如下: <!DOCTYPE html> <html lang="en"> & ...

  6. Vue.js 源码分析(十六) 指令篇 v-on指令详解

    可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码,例如: <!DOCTYPE html> <html lang="en"& ...

  7. Vue.js 源码分析(十五) 指令篇 v-bind指令详解

    指令是Vue.js模板中最常用的一项功能,它带有前缀v-,比如上面说的v-if.v-html.v-pre等.指令的主要职责就是当其表达式的值改变时,相应的将某些行为应用到DOM上,先介绍v-bind指 ...

  8. Vue.js 源码分析(十四) 基础篇 组件 自定义事件详解

    我们在开发组件时有时需要和父组件沟通,此时可以用自定义事件来实现 组件的事件分为自定义事件和原生事件,前者用于子组件给父组件发送消息的,后者用于在组件的根元素上直接监听一个原生事件,区别就是绑定原生事 ...

  9. Vue.js 源码分析(十二) 基础篇 组件详解

    组件是可复用的Vue实例,一个组件本质上是一个拥有预定义选项的一个Vue实例,组件和组件之间通过一些属性进行联系. 组件有两种注册方式,分别是全局注册和局部注册,前者通过Vue.component() ...

随机推荐

  1. 如何唯一确定一台iOS设备

    如果你的iOS应用需要针对设备做特定的操作,或者需要硬件的信息来进行判定等等的,你就需要对iOS设备进行唯一性的判定. 苹果设备有个先天的东西符合这个需求,UDID,这个东东用iTunes就可以看到, ...

  2. 2016 cocoapods的安装和使用以及版本升级遇到的问题

    一.CocoaPods是什么? CocoaPods是一个负责管理iOS项目中第三方开源库的工具.CocoaPods的项目源码在Github上管理.该项目开始于2011年8月12日,在这两年多的时间里, ...

  3. 跟Google学习Android开发-起始篇-构建你的第一个应用程序(4)

    说明:此系列教程翻译自Google Android开发者官网的Training教程,利用Chome浏览器的自动翻译功能作初译,然后在一些语句不顺或容易造成误解的地方作局部修正.方便英文不好的开发者查看 ...

  4. CSDN挑战编程——《数学问题》

    数学问题 题目详情: 给你两个长度为n的正整数序列分别为{a1,a2,a3...an},{b1,b2,b3...bn},0<ai,bi<=100: 设S=max{x1*a1+x2*a2+x ...

  5. Winform Textbox实现滚动条始终在最下面

    在用textbox时,实现一些信息追加时,要使滚动条始终呆在最下面的实现方法. 以textbox1为例,事件TextChanged中执行以下代码即可 private void textBox1_Tex ...

  6. IPC进程间通信 - AIDL+Binder

      原理 http://www.linuxidc.com/Linux/2012-07/66195.htm   服务端,客户端处在用户空间,而binder驱动处在内核空间. 服务器端.一个Binder服 ...

  7. yii 自动生成的内容,分页信息(Displaying 1-10 of 15 results.)如何修改或是yii cgridview template summary

    问的白一点就是 Displaying 1-10 of 15 results 如何翻译 如果搜索的话, 搜这个会出来很多内容 yii cgridview template summary 好了,其他不说 ...

  8. Dijkstra算法and Floyd算法 HDU 1874 畅通工程续

    Dijkstra算法描述起来比较容易:它是求单源最短路径的,也就是求某一个点到其他各个点的最短路径,大体思想和prim算法差不多,有个数组dis,用来保存源点到其它各个点的距离,刚开始很好办,只需要把 ...

  9. spring03autowire属性

    1.创建需要的实体类 public class Student { //学生实体类 private String name; //姓名 private Integer age; //年龄 privat ...

  10. 关于IIS部署成功后,局域网其他用户无法访问的问题解决方法

    关于win7部署iis后,局域网的其他用户不能访问的问题.   在win7系统中,部署好iis后,自己本地可以发布和预览.但在局域网中的其他用户不可以访问.下面说一下这个原因. 这是因为win7自带的 ...