記錄自己搭建https的silk錄音文件語(yǔ)音識(shí)別服務(wù)的調(diào)用過(guò)程,所有代碼可在文中找鏈接打包下載
>>>>>>>>>>>>>>>>>>>>>>>> 歡迎轉(zhuǎn)載 <<<<<<<<<<<<<<<<<<<<<<<<
本文原地址: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
與本小程序密切相關(guān)的幾個(gè)文章:
====本文中提到的silk轉(zhuǎn)wav服務(wù)端https的API搭建過(guò)程詳解見====
微信小程序語(yǔ)音識(shí)別服務(wù)搭建全過(guò)程解析(內(nèi)附免費(fèi)的供小程序語(yǔ)音識(shí)別的https服務(wù))
微信小程序——智能小秘“遙知之”源碼分享(語(yǔ)義理解基于olami)(注:這個(gè)是原來(lái)不支持語(yǔ)音識(shí)別的版本)
這次的改動(dòng)是基于原來(lái)的“遙知之”版本v0.2基礎(chǔ)之上的。加上了語(yǔ)音識(shí)別,界面變化較大 。下面主要介紹一下新版本首頁(yè)面的功能和代碼實(shí)現(xiàn)。
實(shí)現(xiàn)功能
實(shí)現(xiàn)一個(gè)智能生活信息查詢的小秘書功能,支持查天氣、新聞、日歷、匯率、笑話、故事、百科、詩(shī)詞、郵編、區(qū)號(hào)、菜譜、股票、節(jié)目預(yù)告,還支持閑聊、算24點(diǎn)、數(shù)學(xué)計(jì)算、單位換算、購(gòu)物、搜索等功能。
使用方式:
新版上線支持語(yǔ)音識(shí)別,按下說(shuō)話,松開發(fā)送。
老版本上支持搖一搖、點(diǎn)界面按鈕、手動(dòng)輸入、下拉刷新這四種方式。
掃碼試用(左右皆可)

界面展示


開發(fā)資源
-
免費(fèi)開放語(yǔ)義接口平臺(tái) olami.ai
-
微信小程序平臺(tái)
-
js, css
-
我自己搭建的https的語(yǔ)音識(shí)別API接口
源碼分析
這里主要介紹新版本首頁(yè)相關(guān)的代碼,其它部分代碼在 微信小程序——智能小秘“遙知之”源碼分享(語(yǔ)義理解基于olami)(注:這個(gè)是原來(lái)不支持語(yǔ)音識(shí)別的版本) 的基礎(chǔ)上,變化不怎么大,具體可參考那篇文章。
asr.js源碼:
/**
* 作者:happycxz
* 時(shí)間:2017.09.19
* 源碼分享鏈接:http://blog.csdn.net/happycxz/article/details/78024986
*
* https的silk語(yǔ)音識(shí)別API(專供微信小程序調(diào)用):https://api.happycxz.com/wxapp/silk2asr
* 該API服務(wù)搭建全過(guò)程解析及源碼分享貼:http://blog.csdn.net/happycxz/article/details/78016299
* 需要使用此API請(qǐng)聯(lián)系作者QQ:404499164
*
* 遵循開放、分享、自由、免費(fèi)的精神,把開源堅(jiān)持到底
*/
//獲取應(yīng)用實(shí)例
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
//彈幕定時(shí)器
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,//幀動(dòng)畫初始圖片
isSpeaking: false,//是否正在說(shuō)話
outputTxt : "", //輸出識(shí)別結(jié)果
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) {
//臨時(shí)路徑,下次進(jìn)入小程序時(shí)無(wú)法正常使用
var tempFilePath = res.tempFilePath;
UTIL.log('record SUCCESS file path:' + tempFilePath)
_this.setData({
recordPath: tempFilePath
});
},
fail: function (res) {
//錄音失敗
wx.showModal({
title: '提示',
content: '錄音的姿勢(shì)不對(duì)!',
showCancel: false,
success: function (res) {
if (res.confirm) {
UTIL.log('用戶點(diǎn)擊確定')
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() 錯(cuò)誤' + e.message + '發(fā)生在' + e.lineNumber + '行');
sentenceResult = '沒(méi)明白你說(shuō)的,換個(gè)話題?'
}
var lastOutput = "==>語(yǔ)音識(shí)別結(jié)果:\n" + stt + "\n\n==>語(yǔ)義處理結(jié)果:\n" + sentenceResult;
_this.setData({
outputTxt: lastOutput,
});
wx.hideToast();
},
fail: function (res) {
UTIL.log(res);
wx.showModal({
title: '提示',
content: "網(wǎng)絡(luò)請(qǐng)求失敗,請(qǐng)確保網(wǎng)絡(luò)是否正常",
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;
}
//麥克風(fēng)幀動(dòng)畫
function speaking() {
var _this = this;
//話筒幀動(dòng)畫
var i = 1;
this.timer = setInterval(function () {
i++;
i = i % 5;
_this.setData({
j: i
})
}, 200);
}
這部分主要實(shí)現(xiàn)錄音按鈕被按下和松開觸發(fā)話筒錄音及結(jié)束錄音,當(dāng)按鈕被按下后,觸發(fā)調(diào)用話筒動(dòng)畫特效(其實(shí)是四五個(gè)圖片輪流顯示的效果),同時(shí)調(diào)用wx.startRecord開始錄音。
當(dāng)按鈕松開時(shí)停止錄音,然后將錄音臨時(shí)文件往 https://api.happycxz.com/wxapp/silk2asr 上發(fā)送,同時(shí)發(fā)olami上注冊(cè)申請(qǐng)的appKey和appSecret,以及用戶唯一識(shí)別號(hào)。
從語(yǔ)音識(shí)別接口返回的結(jié)果是原封不動(dòng)的olami官方輸出結(jié)果,我們只需要取一下語(yǔ)音識(shí)別結(jié)果以及語(yǔ)義理解結(jié)果即可。 語(yǔ)義理解結(jié)果在原來(lái) 微信小程序——智能小秘“遙知之”源碼分享(語(yǔ)義理解基于olami)(注:這個(gè)是原來(lái)不支持語(yǔ)音識(shí)別的版本) 中已經(jīng)有方法解析,為了代碼復(fù)用性強(qiáng)些,把解析nli結(jié)果的方法簡(jiǎn)單改了下,即適用新版語(yǔ)音識(shí)別的,也適用以前老版本的手動(dòng)輸入的。
代碼邏輯很簡(jiǎn)單,看看就明白了,這里不再多述。:)
asr.json源碼:
{
"window": {
"enablePullDownRefresh": false
}
}
因?yàn)槔习骓?xiàng)目中我開啟了下拉刷新,新界面上不需要了,所以在asr頁(yè)面的.json這里特意關(guān)閉了此功能。
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">語(yǔ)義理解基于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">聯(lián)系作者</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">按下錄音,松開結(jié)束</button>
</view>
布局調(diào)了半天,還是沒(méi)有達(dá)到我想要的效果,前端布局我沒(méi)系統(tǒng)學(xué)習(xí)過(guò),基本就是湊湊拼拼,望有基本審美觀的各位看官理解……
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;
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%;}
}
彈幕部分原先是硬代碼實(shí)現(xiàn)的,后來(lái)在小程序聯(lián)盟里請(qǐng)教后才得知,css里有可以實(shí)現(xiàn)動(dòng)畫特效的功能,就順便修改了一下。還是有點(diǎn)顯示方面BUG的,不折騰了。
其它代碼還是參照我原來(lái)的那個(gè)文章里介紹的吧:微信小程序——智能小秘“遙知之”源碼分享(語(yǔ)義理解基于olami)(注:這個(gè)是原來(lái)不支持語(yǔ)音識(shí)別的版本) ,基本變動(dòng)比較少。
想要全局直觀的看完整代碼,歡迎訪問(wèn)該項(xiàng)目對(duì)應(yīng)碼云鏈接:http://git.oschina.net/happycxz/nlp_olami_yaozhizhi_wechat_littleapp_demo
>>>>>>>>>>>>>>>>>>>>>>>> 歡迎轉(zhuǎn)載 <<<<<<<<<<<<<<<<<<<<<<<<
本文原地址: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
寫在最后
這次小程序的版本更新,還是上一次的延續(xù),上次老版本未能支持上語(yǔ)音識(shí)別,用起來(lái)很不方便,網(wǎng)上也找不到相應(yīng)的免費(fèi)的接口,于是索性湊了點(diǎn)時(shí)間專門自己搭個(gè)HTTPS服務(wù)出來(lái),方便同樣想在微信小程序上DEBUG語(yǔ)音識(shí)別功能的伙伴們和興趣開發(fā)者們調(diào)試和做些小玩意,好在,總算是一路走過(guò)來(lái)了,特別感謝kn007大神提供的silk decoder源碼以及ffmpeg轉(zhuǎn)碼腳本,關(guān)于此議題(解碼轉(zhuǎn)換QQ微信的SILK v3編碼音頻為MP3或其他格式)在他本人的博客中火熱地討論了一年多了,感興趣的也可以去膜拜一下這位大神。