支援語音識別、自然語言理解的微信小程式(“遙知之”智慧小祕)完整原始碼分享
記錄自己搭建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').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 : 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);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
這部分主要實現錄音按鈕被按下和鬆開觸發話筒錄音及結束錄音,當按鈕被按下後,觸發呼叫話筒動畫特效(其實是四五個圖片輪流顯示的效果),同時呼叫wx.startRecord開始錄音。
當按鈕鬆開時停止錄音,然後將錄音臨時檔案往 https://api.happycxz.com/wxapp/silk2asr 上傳送,同時發olami上註冊申請的appKey和appSecret,以及使用者唯一識別號。
從語音識別介面返回的結果是原封不動的olami官方輸出結果,我們只需要取一下語音識別結果以及語義理解結果即可。 語義理解結果在原來 微信小程式——智慧小祕“遙知之”原始碼分享(語義理解基於olami)(注:這個是原來不支援語音識別的版本) 中已經有方法解析,為了程式碼複用性強些,把解析nli結果的方法簡單改了下,即適用新版語音識別的,也適用以前老版本的手動輸入的。
程式碼邏輯很簡單,看看就明白了,這裡不再多述。:)
asr.json原始碼:
{
"window": {
"enablePullDownRefresh": false
}
}
- 1
- 2
- 3
- 4
- 5
- 6
因為老版專案中我開啟了下拉重新整理,新介面上不需要了,所以在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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
佈局調了半天,還是沒有達到我想要的效果,前端佈局我沒系統學習過,基本就是湊湊拼拼,望有基本審美觀的各位看官理解……
asr.wxss原始碼:
/* pages/asr/asr.wxss */
page{
background-color:beige;
background-image: url(https://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%;}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
彈幕部分原先是硬程式碼實現的,後來在小程式聯盟裡請教後才得知,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或其他格式)在他本人的部落格中火熱地討論了一年多了,感興趣的也可以去膜拜一下這位大神。
- 本文已收錄於以下專欄:
- 自然語言理解、自然語言處理應用
相關文章
- 微信小程式語音同步智慧識別的實現案例微信小程式
- 機器配音微信小程式原始碼 多種語音任微信小程式原始碼
- 微信小程式使用同聲傳譯實現語音識別功能微信小程式
- 分享一個自然語言漢語時間語義識別的工具類
- 30分鐘實現小程式語音識別
- 微信小程式商城原始碼微信小程式原始碼
- 微信小程式身份證識別微信小程式
- hanlp自然語言處理包的人名識別程式碼解析HanLP自然語言處理
- 語言小知識-Java ArrayList類 深度解析Java
- 語言小知識-Java HashMap類 深度解析JavaHashMap
- 人工智慧之語音識別(ASR)人工智慧
- WebStorem 支援微信小程式 wepy 程式碼高亮WebREM微信小程式
- 小程式實現語音識別到底要填多少坑?
- 自然語言處理(NLP)系列(一)——自然語言理解(NLU)自然語言處理
- c語言常用小知識點總結1C語言
- NLP漢語自然語言處理入門基礎知識自然語言處理
- 語音助手的前世今生篇之微軟小娜微軟
- 成語答題小程式原始碼原始碼
- 智慧名片小程式原始碼,微信電子名片原始碼開發案例原始碼
- Java函數語言程式設計知識分享!Java函數程式設計
- 微信域名防封的小知識
- 199IT微信小程式原始碼分享_基於WordPress+Taro微信小程式原始碼
- 微信小程式掃碼解析小程式碼微信小程式
- 直播小程式原始碼,小程式生成二維碼 (相容H5、微信小程式)原始碼H5微信小程式
- 那些主流程式語言的知識,C語言(Ⅰ)C語言
- 微信小程式實戰影片教程附原始碼課件與多個微信小程式原始碼 14課微信小程式原始碼
- Pyhanlp自然語言處理中的新詞識別HanLP自然語言處理
- 微信小程式之支付微信小程式
- NLP漢語自然語言處理入門基礎知識介紹自然語言處理
- 開發微信小程式需要了解哪些知識?微信小程式
- 快商通首席科學家:語音識別的後半段路,從語言處理走向語言理解
- 微信小程式-仿QQ音樂微信小程式
- 人工智慧 (08) 語音識別人工智慧
- 微信小程式:小程式碼、小程式二維碼、普通二維碼微信小程式
- c語言實用小程式C語言
- 微信髮卡小程式原始碼 自動髮卡小程式原始碼 帶流量主功能原始碼
- 微信小程式音訊播放 InnerAudioContext 的用法微信小程式音訊Context
- 微信小程式實現商城案例(賦原始碼)微信小程式原始碼
- 微信小程式開發總結(附原始碼)微信小程式原始碼