这两天有些语音指令上的功能上的需求,然后回到APICloud创建了个APP,加载了几个语音模块,简单模拟一遍APP上语音转指令的操作。
2. 由于当时忘记了APICloud的默认设计图的尺寸,然后记成微信小程序的默认尺寸750px去了,尴尬
3. 好吧,这些都不重要了,界面神马的都是小kiss ,主要是实现语音指令功能:
(1)自定义APPLoader ,安装到安卓模拟器上
(2)调试ip端口号对应上
(3)直接调用模块
4. 这次loader中加载了一个云知声和科大讯飞的免费版的模块,具体调用难度几乎没有,配置好appid和appsercet就好,但是收费版的科大讯飞的语音唤醒没调用明白,这倒是有点遗憾
5. 好一切准备就绪,就差上下左右的移动和边界处理,其实也很简单就是一个二维数组的简单算法操作,封装一下即可。在scripts文件夹中新建tool.js ,封装相关的工具方法
function Tool(){ } Tool.prototype = { constructor: Tool, getNewIndex: function(cols,len,index,direc){ var rsg = { 'goalIndex': index*1, 'mes': '' }; switch(direc){ //1. 向上移动 case 1 : //如果在第一横排 if(index < cols){ rsg.mes = '到顶部了!'; return rsg; } rsg.goalIndex = (index - cols); break; //2. 向右移动 case 2 : //如果是最后一个 if(index == len-1){ rsg.mes = '到最后一个了!'; return rsg; } rsg.goalIndex = (index*1+1); break; //3. 向下移动 case 3 : //如果是最后一排 if(index >= len-cols){ rsg.mes = '已经到最后一排了!'; return rsg; } rsg.goalIndex = parseInt(index*1 + cols*1); break; //4. 向左移动 case 4 : //如果是第一个 if(index == 0){ rsg.mes = '已经到第一个了!'; return rsg; } rsg.goalIndex = parseInt(index - 1); break; } return rsg; }, randomValue: function(arr){ var r = Math.floor(Math.random()*arr.length); return arr[r]; }, getFocusDirec: function(els,ac,ngoal){ //获取当前的坐标 var cIndex = 0; var newIndex = 0; var mes = ''; for(var i=0;i<els.length;i++){ if(els[i].classList.contains('active')){ cIndex = els[i].dataset.index; els[i].classList.remove('active'); break; } } var infos = this.getNewIndex(4,els.length,cIndex,ngoal); newIndex = this.getNewIndex(4,els.length,cIndex,ngoal).goalIndex*1; mes = this.getNewIndex(4,els.length,cIndex,ngoal).mes; if(newIndex >= 0){ els[newIndex].classList.add('active'); } //els[newIndex].classList.add('active'); }, getRecDirection: function(words,arrs){ var twords = words; var vs = []; var index = 1; var code = 0; var onoff = true; for(var value in arrs){ vs = arrs[value].strArr; for(var i=0;i<vs.length;i++){ if(words.match(vs[i]) && onoff){ code = arrs[value].code; break; onoff = false; } } //console.log(JSON.stringify(arrs[value])); } return code; } }
6. 还有声音的模糊处理,毕竟每个人发音不同,所以需要做一次模糊识别库(简单的用数组代替即可),最后简单用正则一次匹配即可。当然若是要更精确,则只能权重化正则匹配了。
9. 核心模块调用代码展示:
//打开讯飞 function openKeXunFei(){ var speechRecognizer = api.require('speechRecognizer'); speechRecognizer.record({ vadbos: 5000, vadeos: 5000, rate: 16000, asrptt: 1, audioPath: 'fs://speechRecogniser/speech.pcm' }, function(ret, err) { if (ret.status) { console.log(JSON.stringify(ret)); if(xunoff){ var words = ret.wordStr; if(!words){ console.log('请说话!'); return; } var d = tool.getRecDirection(words,languages); if(d>0){ $api.html($api.dom('.showDirec'),d); tool.getFocusDirec($api.domAll('.item'),'active',d); } } xunoff = false; } else { console.log(JSON.stringify({ msg: err.msg })); } }); } //关闭讯飞 function closeKeXunFei(){ var speechRecognizer = api.require('speechRecognizer'); speechRecognizer.stopRecord(); xunoff = true; } //云通讯 function getYunTongxun(){ //云通讯 //加载语音模块 var uscVoiceRecognizer = api.require('uscVoiceRecognizer'); //配置语音模块 uscVoiceRecognizer.configuration({ appKey : 'mjdeyp2b46lc7vx3hfrlzlxepn3vootwmzk2sqqx', secret : '6bc6f10bbce3588b1a77052f6e385df6' }); uscVoiceRecognizer.startSpeechUnderstander({ },function(ret) { if (ret) { console.log(JSON.stringify(ret)); var words = ret.resultStr; if(!words){ console.log('请说话!'); return; } var d = tool.getRecDirection(words,languages); if(d>0){ $api.html($api.dom('.showDirec'),d); tool.getFocusDirec($api.domAll('.item'),'active',d); } } }); } function closeYunTongxun(){ //加载语音模块 var uscVoiceRecognizer = api.require('uscVoiceRecognizer'); //配置语音模块 uscVoiceRecognizer.configuration({ appKey : 'mjdeyp2b46lc7vx3hfrlzlxepn3vootwmzk2sqqx', secret : '6bc6f10bbce3588b1a77052f6e385df6' }); uscVoiceRecognizer.stopSpeechUnderstander(); }