支持语音识别、自然语言理解的微信小程序(“遥知之”智能小秘)完整源码分享
来源:互联网 发布:今晚非农数据最新消息 编辑:程序博客网 时间:2024/05/23 12:44
记录自己搭建https的silk录音文件语音识别服务的调用过程,所有代码可在文中找链接打包下载
>>>>>>>>>>>>>>>>>>>>>>>> 欢迎转载 <<<<<<<<<<<<<<<<<<<<<<<<
本文原地址:http://blog.csdn.net/happycxz/article/details/78024986
“遥知之”微信小程序完整源码下载:
码云:http://git.oschina.net/happycxz/nlp_olami_yaozhizhi_wechat_littleapp_demo
github: https://github.com/happycxz/nlp_olami_yaozhizhi_wechat_littleapp_demo
与本小程序密切相关的几个文章:
====本文中提到的silk转wav服务端https的API搭建过程详解见====
微信小程序语音识别服务搭建全过程解析(内附免费的供小程序语音识别的https服务)
微信小程序——智能小秘“遥知之”源码分享(语义理解基于olami)(注:这个是原来不支持语音识别的版本)
这次的改动是基于原来的“遥知之”版本v0.2基础之上的。加上了语音识别,界面变化较大 。下面主要介绍一下新版本首页面的功能和代码实现。
实现功能
实现一个智能生活信息查询的小秘书功能,支持查天气、新闻、日历、汇率、笑话、故事、百科、诗词、邮编、区号、菜谱、股票、节目预告,还支持闲聊、算24点、数学计算、单位换算、购物、搜索等功能。
使用方式:
新版上线支持语音识别,按下说话,松开发送。
老版本上支持摇一摇、点界面按钮、手动输入、下拉刷新这四种方式。
扫码试用(左右皆可)
界面展示
开发资源
- 免费开放语义接口平台 olami.ai
- 微信小程序平台
- js, css
- 我自己搭建的https的语音识别API接口
源码分析
这里主要介绍新版本首页相关的代码,其它部分代码在 微信小程序——智能小秘“遥知之”源码分享(语义理解基于olami)(注:这个是原来不支持语音识别的版本) 的基础上,变化不怎么大,具体可参考那篇文章。
asr.js源码:
/** * 作者:happycxz * 时间:2017.09.19 * 源码分享链接:http://blog.csdn.net/happycxz/article/details/78024986 * * https的silk语音识别API(专供微信小程序调用):https://api.happycxz.com/wxapp/silk2asr * 该API服务搭建全过程解析及源码分享贴:http://blog.csdn.net/happycxz/article/details/78016299 * 需要使用此API请联系作者QQ:404499164 * * 遵循开放、分享、自由、免费的精神,把开源坚持到底 *///获取应用实例 var app = getApp()var UTIL = require('../../utils/util.js');var GUID = require('../../utils/GUID.js');var NLI = require('../../utils/NLI.js');const appkey = require('../../config').appkeyconst appsecret = require('../../config').appsecret//弹幕定时器var timer;var pageSelf = undefined;var doommList = [];class Doomm { constructor() { this.text = UTIL.getRandomItem(app.globalData.corpus); this.top = Math.ceil(Math.random() * 40); this.time = Math.ceil(Math.random() * 8 + 6); this.color = getRandomColor(); this.display = true; let that = this; setTimeout(function () { doommList.splice(doommList.indexOf(that), 1); doommList.push(new Doomm()); pageSelf.setData({ doommData: doommList }) }, this.time * 1000) }}function getRandomColor() { let rgb = [] for (let i = 0; i < 3; ++i) { let color = Math.floor(Math.random() * 256).toString(16) color = color.length == 1 ? '0' + color : color rgb.push(color) } return '#' + rgb.join('')}Page({ data: { j: 1,//帧动画初始图片 isSpeaking: false,//是否正在说话 outputTxt : "", //输出识别结果 doommData: [] }, initDoomm: function () { doommList.push(new Doomm()); doommList.push(new Doomm()); doommList.push(new Doomm()); this.setData({ doommData: doommList }) }, onLoad: function () { pageSelf = this; this.initDoomm(); }, //手指按下 touchdown: function () { UTIL.log("手指按下了... new date : " + new Date) var _this = this; speaking.call(this); this.setData({ isSpeaking: true }) //开始录音 wx.startRecord({ success: function (res) { //临时路径,下次进入小程序时无法正常使用 var tempFilePath = res.tempFilePath; UTIL.log('record SUCCESS file path:' + tempFilePath) _this.setData({ recordPath: tempFilePath }); }, fail: function (res) { //录音失败 wx.showModal({ title: '提示', content: '录音的姿势不对!', showCancel: false, success: function (res) { if (res.confirm) { UTIL.log('用户点击确定') return } } }) } }) }, //手指抬起 touchup: function () { UTIL.log("手指抬起了...") this.setData({ isSpeaking: false, }) clearInterval(this.timer) wx.stopRecord() var _this = this setTimeout(function () { var urls = "https://api.happycxz.com/wxapp/silk2asr"; UTIL.log(_this.data.recordPath); wx.uploadFile({ url: urls, filePath: _this.data.recordPath, name: 'file', formData: { "appKey": appkey, "appSecret": appsecret, "userId": UTIL.getUserUnique() }, header: { 'content-type': 'multipart/form-data' }, success: function (res) { UTIL.log('res.data:' + res.data); var nliResult = getNliFromResult(res.data); UTIL.log('nliResult:' + nliResult); var stt = getSttFromResult(res.data); UTIL.log('stt:' + stt); var sentenceResult; try { sentenceResult = NLI.getSentenceFromNliResult(nliResult); } catch (e) { UTIL.log('touchup() 错误' + e.message + '发生在' + e.lineNumber + '行'); sentenceResult = '没明白你说的,换个话题?' } var lastOutput = "==>语音识别结果:\n" + stt + "\n\n==>语义处理结果:\n" + sentenceResult; _this.setData({ outputTxt: lastOutput, }); wx.hideToast(); }, fail: function (res) { UTIL.log(res); wx.showModal({ title: '提示', content: "网络请求失败,请确保网络是否正常", showCancel: false, success: function (res) { } }); wx.hideToast(); } }); }, 1000) }, //切换到老版本 turnToOld: function() { wx.navigateTo({ url: '../index/index', }) },})function getNliFromResult(res_data) { var res_data_json = JSON.parse(res_data); var res_data_result_json = JSON.parse(res_data_json.result); return res_data_result_json.nli;}function getSttFromResult(res_data) { var res_data_json = JSON.parse(res_data); var res_data_result_json = JSON.parse(res_data_json.result); return res_data_result_json.asr.result;}//麦克风帧动画 function speaking() { var _this = this; //话筒帧动画 var i = 1; this.timer = setInterval(function () { i++; i = i % 5; _this.setData({ j: i }) }, 200);}
这部分主要实现录音按钮被按下和松开触发话筒录音及结束录音,当按钮被按下后,触发调用话筒动画特效(其实是四五个图片轮流显示的效果),同时调用wx.startRecord开始录音。
当按钮松开时停止录音,然后将录音临时文件往 https://api.happycxz.com/wxapp/silk2asr 上发送,同时发olami上注册申请的appKey和appSecret,以及用户唯一识别号。
从语音识别接口返回的结果是原封不动的olami官方输出结果,我们只需要取一下语音识别结果以及语义理解结果即可。 语义理解结果在原来 微信小程序——智能小秘“遥知之”源码分享(语义理解基于olami)(注:这个是原来不支持语音识别的版本) 中已经有方法解析,为了代码复用性强些,把解析nli结果的方法简单改了下,即适用新版语音识别的,也适用以前老版本的手动输入的。
代码逻辑很简单,看看就明白了,这里不再多述。:)
asr.json源码:
{ "window": { "enablePullDownRefresh": false }}
因为老版项目中我开启了下拉刷新,新界面上不需要了,所以在asr页面的.json这里特意关闭了此功能。
asr.wxml源码:
<view class="container"> <view class="page-section"> <view class="text-box" scroll-y="true"> <text style="max-width:200px;overflow-y:auto;height:200px;" selectable="true">{{outputTxt}}</text> </view> </view> <view class="page-section"> <text selectable="true" class="text-head">语义理解基于olami.ai,作者QQ:404499164</text> </view> <view class="little-gap-top button-selection2 button-show bottom-button"> <button size="mini" type="default" open-type="contact">联系作者</button> <button size="mini" type="default" bindtap="turnToOld">切老版本</button> <button size="mini" type="default" open-type="share">帮忙分享</button> </view> <view class="page-section"> <view class="doommview"> <block wx:for="{{doommData}}" wx:key="id"> <text wx:if="{{item.display}}" class="aon" style="animation: first {{item.time}}s linear infinite;top:{{item.top}}%;color:{{item.color}};"> {{item.text}} </text> </block> </view> </view><view wx:if="{{isSpeaking}}" class="speak-style"> <image class="sound-style" src="../../pics/voice_icon_speech_sound_1.png" ></image> <image wx:if="{{j==2}}" class="sound-style" src="../../pics/voice_icon_speech_sound_2.png" ></image> <image wx:if="{{j==3}}" class="sound-style" src="../../pics/voice_icon_speech_sound_3.png" ></image> <image wx:if="{{j==4}}" class="sound-style" src="../../pics/voice_icon_speech_sound_4.png" ></image> <image wx:if="{{j==5}}"class="sound-style" src="../../pics/voice_icon_speech_sound_5.png" ></image></view></view><view class="record-style"> <button type="primary" class="btn-style" bindtouchstart="touchdown" bindtouchend="touchup">按下录音,松开结束</button></view>
布局调了半天,还是没有达到我想要的效果,前端布局我没系统学习过,基本就是凑凑拼拼,望有基本审美观的各位看官理解……
asr.wxss源码:
/* pages/asr/asr.wxss */page{ background-color:beige; background-image: url(http://img.blog.csdn.net/20170720105808995?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGFwcHljeHo=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast); background-size: cover;}.page-section{ display: flex; flex-direction: column; margin-bottom: 10rpx;}.text-head{ color: #ff0000; font-size: 28rpx; align-items: center; margin-top: 5rpx;}.button-selection { display: flex; flex-direction: column; justify-content: center; align-items: center;}.button-selection2 { justify-content: space-between; align-content: space-between; flex-shrink:1;}.little-gap-top { margin-top: 10rpx; }.big-gap-top { margin-top: 100rpx; }.button-show { display: flex; align-self: center; justify-content: center;}.bottom-button { justify-content: space-around; flex-shrink:0;}.text-box{ margin-bottom: 0rpx; margin-left: 50rpx; margin-right: 50rpx; padding: 40rpx 0; display: flex; min-height: 650rpx; max-width: 600rpx; width:600rpx; background-color: #ffffff; justify-content: center; align-items: center; text-align: left; font-size: 30rpx; color: #353535; line-height: 2em; word-wrap: break-word; border: 1px solid cornflowerblue;}/* 录音 */.speak-style{ position: relative; height: 240rpx; width: 240rpx; border-radius: 20rpx; margin: 0 auto; background: #26A5FF; } .record-style{ position: fixed; bottom: 0; left: 0; height: 120rpx; width: 100%; } .btn-style{ margin-left: 30rpx; margin-right: 30rpx; } .sound-style{ position: absolute; width: 74rpx; height:150rpx; margin-top: 45rpx; margin-left: 83rpx; } /* 弹幕 */.button{ position: absolute; bottom: 0; width: 100%;}.aon{position: absolute;white-space:nowrap;animation-timing-function: linear;animation-fill-mode: none;}.doommview{ z-index: 3; height: 80%; width: 100%;/* position: absolute; */}@keyframes first{ from{left: 100%; } to{left: -100%;}}
弹幕部分原先是硬代码实现的,后来在小程序联盟里请教后才得知,css里有可以实现动画特效的功能,就顺便修改了一下。还是有点显示方面BUG的,不折腾了。
其它代码还是参照我原来的那个文章里介绍的吧:微信小程序——智能小秘“遥知之”源码分享(语义理解基于olami)(注:这个是原来不支持语音识别的版本) ,基本变动比较少。
想要全局直观的看完整代码,欢迎访问该项目对应码云链接:http://git.oschina.net/happycxz/nlp_olami_yaozhizhi_wechat_littleapp_demo
>>>>>>>>>>>>>>>>>>>>>>>> 欢迎转载 <<<<<<<<<<<<<<<<<<<<<<<<
本文原地址:http://blog.csdn.net/happycxz/article/details/78024986
“遥知之”微信小程序完整源码下载:
码云:http://git.oschina.net/happycxz/nlp_olami_yaozhizhi_wechat_littleapp_demo
github: https://github.com/happycxz/nlp_olami_yaozhizhi_wechat_littleapp_demo
写在最后
这次小程序的版本更新,还是上一次的延续,上次老版本未能支持上语音识别,用起来很不方便,网上也找不到相应的免费的接口,于是索性凑了点时间专门自己搭个HTTPS服务出来,方便同样想在微信小程序上DEBUG语音识别功能的伙伴们和兴趣开发者们调试和做些小玩意,好在,总算是一路走过来了,特别感谢kn007大神提供的silk decoder源码以及ffmpeg转码脚本,关于此议题(解码转换QQ微信的SILK v3编码音频为MP3或其他格式)在他本人的博客中火热地讨论了一年多了,感兴趣的也可以去膜拜一下这位大神。
- 支持语音识别、自然语言理解的微信小程序(“遥知之”智能小秘)完整源码分享
- 微信小程序——智能小秘“遥知之”源码分享(语义理解基于olami)
- 微信小程序——智能小秘“遥知之”源码分享(语义理解基于olami)
- 微信小程序——智能小秘“遥知之”源码分享(语义理解基于olami)
- 手把手教你做自然语言理解智能对话的微信小程序【完整源码分享】
- 微信小程序——智能小秘“遥知之”(语义理解基于olami,源码见原文链接,PC端打开)
- 微信小程序语音聊天智能对话(源码分享)
- 微信小程序之语音识别(附小程序+服务器源码)
- java自然语言理解demo,源码分享(基于欧拉蜜)
- 语音识别,语义理解一站式解决之智能照相机(人脸识别,olami)
- 微信小程序源码分享—智能小蜜
- Android 实现语音识别的完整代码
- 语音识别,自然语言处理的价值正被弱化?
- 微信小程序语音识别探索
- 微信小程序 语音识别开发
- 【VS开发】【智能语音处理】DTW算法(语音识别)
- 语音识别之HMM算法及其源码
- 分享: 语音识别Matlab源码免费下载-智慧石
- wordpress搭建网站
- try-catch和throw,throws的区别
- 在浏览器中输入 网址 后执行的全部过程
- es6版打灰机游戏 --- 玩家飞机类的构建
- jquery ajax 方法及各参数详解
- 支持语音识别、自然语言理解的微信小程序(“遥知之”智能小秘)完整源码分享
- HTML学习之路01--设置背景
- nginx安装——centos
- 324. Wiggle Sort II
- python
- spring和mybatis集成出现的问题
- Go入门(六)-interface与反射机制
- xsd是什么
- 第1周第2节课 算法及其描述、算法分析基础