支持语音识别、自然语言理解的微信小程序(“遥知之”智能小秘)完整源码分享

编程入门 行业动态 更新时间:2024-10-21 11:32:44

支持语音识别、<a href=https://www.elefans.com/category/jswz/34/1768401.html style=自然语言理解的微信小程序(“遥知之”智能小秘)完整源码分享"/>

支持语音识别、自然语言理解的微信小程序(“遥知之”智能小秘)完整源码分享

记录自己搭建https的silk录音文件语音识别服务的调用过程,所有代码可在文中找链接打包下载

>>>>>>>>>>>>>>>>>>>>>>>> 欢迎转载 <<<<<<<<<<<<<<<<<<<<<<<<

本文原地址:

“遥知之”微信小程序完整源码下载:

码云:

github:

与本小程序密切相关的几个文章:

====本文中提到的silk转wav服务端https的API搭建过程详解见====
微信小程序语音识别服务搭建全过程解析(内附免费的供小程序语音识别的https服务)

微信小程序——智能小秘“遥知之”源码分享(语义理解基于olami)(注:这个是原来不支持语音识别的版本)

这次的改动是基于原来的“遥知之”版本v0.2基础之上的。加上了语音识别,界面变化较大 。下面主要介绍一下新版本首页面的功能和代码实现。

实现功能

实现一个智能生活信息查询的小秘书功能,支持查天气、新闻、日历、汇率、笑话、故事、百科、诗词、邮编、区号、菜谱、股票、节目预告,还支持闲聊、算24点、数学计算、单位换算、购物、搜索等功能。

使用方式:

新版上线支持语音识别,按下说话,松开发送。

老版本上支持摇一摇、点界面按钮、手动输入、下拉刷新这四种方式。

扫码试用(左右皆可)

界面展示

开发资源

  1. 免费开放语义接口平台 olami.ai
  2. 微信小程序平台
  3. js, css
  4. 我自己搭建的https的语音识别API接口

源码分析

这里主要介绍新版本首页相关的代码,其它部分代码在 微信小程序——智能小秘“遥知之”源码分享(语义理解基于olami)(注:这个是原来不支持语音识别的版本) 的基础上,变化不怎么大,具体可参考那篇文章。

asr.js源码:
/*** 作者:happycxz* 时间:2017.09.19* 源码分享链接:* * https的silk语音识别API(专供微信小程序调用):* 该API服务搭建全过程解析及源码分享贴:* 需要使用此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').appkey
const 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 : colorrgb.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 = thissetTimeout(function () {var urls = "";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开始录音。

当按钮松开时停止录音,然后将录音临时文件往 上发送,同时发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(/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)(注:这个是原来不支持语音识别的版本) ,基本变动比较少。

想要全局直观的看完整代码,欢迎访问该项目对应码云链接:

>>>>>>>>>>>>>>>>>>>>>>>> 欢迎转载 <<<<<<<<<<<<<<<<<<<<<<<<

本文原地址:

“遥知之”微信小程序完整源码下载:

码云:

github:

写在最后

这次小程序的版本更新,还是上一次的延续,上次老版本未能支持上语音识别,用起来很不方便,网上也找不到相应的免费的接口,于是索性凑了点时间专门自己搭个HTTPS服务出来,方便同样想在微信小程序上DEBUG语音识别功能的伙伴们和兴趣开发者们调试和做些小玩意,好在,总算是一路走过来了,特别感谢kn007大神提供的silk decoder源码以及ffmpeg转码脚本,关于此议题(解码转换QQ微信的SILK v3编码音频为MP3或其他格式)在他本人的博客中火热地讨论了一年多了,感兴趣的也可以去膜拜一下这位大神。

更多推荐

支持语音识别、自然语言理解的微信小程序(“遥知之”智能小秘)完整源码分享

本文发布于:2024-03-10 20:21:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1728942.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自然语言   知之   源码   语音识别   完整

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!