先看實作效果:
利用百度UNIT預置的智能問答技能和微信小程式,實作語音問答機器人,這里主要介紹小程式功能開發實作程序,分享主要功能實作的子程式模塊,都是干貨!
想了解UNIT預置技能呼叫,請參看我之前的帖子:《UNIT搭建機器人助理》
https://ai.baidu.com/forum/topic/show/953021
想了解微信小程式的開發程序,請參看我之前的帖子:《UNIT接入小程式》https://ai.baidu.com/forum/topic/show/953022
1 系統框架
用到的技術主要有:百度語音識別、語音合成、UNIT語意決議和微信小程式,小程式通過語音識別,將用戶的問題提交給百度UNIT,進行語意決議,回傳的回答結果通過語音合成,轉化為語音,實作與用戶的語音互動,全部功能都在小程式客戶端完成,不需要服務器,適合個人開發者使用,
2 小程式專案
2.1 程式創建
在根目錄的全域組態檔app.json中增加:"pages/contact/contact" ,會自動創建相關頁面檔案,結構如下:
contact.js:功能邏輯模塊
contact.wxss:頁面樣式檔案
contact.wxml:頁面布局檔案
contact.json:頁面組態檔
2.2 小程式錄音功能實作
采用微信提供的錄音管理器 recorderManager實作錄音,錄音格式aac,需要注意的是,電腦上的微信開發工具和手機上錄音結果檔案是不一致的, format設定為 'aac',電腦端的錄音是aac格式,手機端錄音是m4a格式,由于百度語音識別極速版目前支持微信小程式錄音m4a格式,所以上傳語音檔案時不用轉格式,方便許多!
// 獲取全域唯一的錄音管理器 recorderManagerconst recorderManager = wx.getRecorderManager();// 錄音時需要的引數, format設定為aacconst voiceOptions = { duration: 60000, sampleRate: 16000, numberOfChannels: 1, encodeBitRate: 48000, format: 'aac', frameSize: 50}// 按鈕按下 touchdown: function () { // 開始錄音 recorderManager.start(voiceOptions); this.setData({ isSpeaking: true, }) that.speaking.call(); console.log("[Console log]:Touch down!Start recording!"); }, // 停止錄音,會觸發onStop事件 touchup: function () { recorderManager.stop(voiceOptions) console.log("[Console log]:Touch up!Stop recording!"); this.setData({ isSpeaking: false, speakerUrl: '/res/image/speaker.png', }) clearInterval(that.speakerInterval);//定時器停止 },// 添加錄音停止觸發事件,這段代碼可以放到onLoad()里,頁面加載的時候就添加上 recorderManager.onStop((res) => { const { tempFilePath, fileSize } = res //錄音完成呼叫語音識別API this.sendAsrRequest(res.tempFilePath, res.fileSize); });
2.3 小程式語音播放功能實作
需要注意的是:小程式自身錄音,用wx.playVoice()函式播放不了,要用到innerAudioContext,
//微信語音播放, play: function (e) { const innerAudioContext = wx.createInnerAudioContext() innerAudioContext.autoplay = true innerAudioContext.src = https://www.cnblogs.com/AIBOOM/p/filePath innerAudioContext.onPlay(() => { console.log('開始播放') }) innerAudioContext.onError((res) => { console.log(res.errMsg) console.log(res.errCode) }) },3 呼叫語音識別極速版API
3.1 首先要在控制臺創建應用,呼叫語音識別極速版API,“獲取API Key/Secret Key”,
介面檔案地址:https://ai.baidu.com/docs#/ASR-API-PRO/top
請求URL: https://vop.baidu.com/pro_api
3.2 語音識別功能實作
//發送語音識別請求,傳入語音檔案路徑及長度,len為錄音結束回傳的位元組長度:res.fileSize, ASRRequest: function (tempFilePath,len,arg) { // corpus是要發送的對話;arg是回呼方法 var that = this; // appkey var appkey = that.globalData.NLPAppkey; // appsecret var appSecret = that.globalData.NLPAppSecret; var api = "nli"; var timestamp = new Date().getTime(); var voice0 = fs.readFileSync(tempFilePath, "base64"); console.log("[Console log]voice:" + voice0); console.log("[Console log]len:" + len); var rqJson = { 'dev_pid': 80001, 'format': 'm4a', 'rate': 16000, 'token': '填入獲得的token ', 'cuid': '填入cuid ', 'channel': 1, 'len': len, 'speech': voice0 }; var rq = JSON.stringify(rqJson); console.log(rq); var ASRUrl = that.globalData.ASRUrl; // cusid是用來實作背景關系的,可以自己隨意定義內容,要夠長夠隨機 var cusid = that.globalData.NLPCusid; console.log("[Console log]:ASRRequest(),URL:" + ASRUrl); wx.request({ url: ASRUrl, data: rq, header: { 'content-type': 'application/json' }, method: 'POST', success: function (res) { var resData = https://www.cnblogs.com/AIBOOM/p/res.data; console.log("[Console log]:ASTRequest() success..."); console.log("[Console log]:Result:" + resData); var nli = JSON.stringify(resData); // 回呼函式,決議資料 typeof arg.success == "function" && arg.success(nli); }, fail: function (res) { console.log("[Console log]:ASRRequest() failed..."); console.error("[Console log]:Error Message:" + res.errMsg); typeof arg.fail == "function" && arg.fail(); }, complete: function () { console.log("[Console log]:ASRRequest() complete..."); typeof arg.complete == "function" && arg.complete(); } }) },4 呼叫UNIT介面,獲得回答
4.1 首先要在控制臺創建應用,呼叫UNIT介面,“獲取API Key/Secret Key”,
介面檔案地址:https://ai.baidu.com/docs#/UNIT-v2-API/top
請求URL: https://aip.baidubce.com/rpc/2.0/unit/bot/chat
4.2 程式實作
NLIRequest: function (corpus, arg) { // corpus是要發送的對話;arg是回呼方法 var that = this; // appkey var appkey = that.globalData.NLPAppkey; // appsecret var appSecret = that.globalData.NLPAppSecret; var api = "nli"; var timestamp = new Date().getTime(); var rqJson = { "bot_session": "", "log_id": "7758521", "request": { "bernard_level": 0, "client_session": "{\"client_results\":\"\", \"candidate_options\":[]}", "query": corpus, "query_info": { "asr_candidates": [], "source": "KEYBOARD", "type": "TEXT" }, "updates": "", "user_id": "88888" }, "bot_id": "64053", "version": "2.0" }; var rq = JSON.stringify(rqJson); var nliUrl = that.globalData.NLPUrl; // cusid是用來實作背景關系的,可以自己隨意定義內容,要夠長夠隨機 var cusid = that.globalData.NLPCusid; console.log("[Console log]:NLIRequest(),URL:" + nliUrl); wx.request({ url: nliUrl, data: rq, header: { 'content-type': 'application/x-www-form-urlencoded' }, method: 'POST', success: function (res) { console.log("[Console log]:res:"+ res); var resData = https://www.cnblogs.com/AIBOOM/p/res.data; console.log("[Console log]:NLIRequest() success..."); console.log("[Console log]:Result:"); console.log("[Console log]:resData:"+resData); var nli = JSON.stringify(resData); console.log("[Console log]:nli:" + nli); // 回呼函式,決議資料 typeof arg.success == "function" && arg.success(nli); }, fail: function (res) { console.log("[Console log]:NLIRequest() failed..."); console.error("[Console log]:Error Message:" + res.errMsg); typeof arg.fail == "function" && arg.fail(); }, complete: function () { console.log("[Console log]:NLIRequest() complete..."); typeof arg.complete == "function" && arg.complete(); } }) },5 呼叫語音合成API
5.1 首先要在控制臺創建應用,呼叫語音合成API,“獲取API Key/Secret Key”,
介面檔案地址:https://ai.baidu.com/docs#/TTS-API/top
請求URL: https://tsn.baidu.com/text2audio
5.2 程式實作
// 語音合成 tts: function (e) { console.log("[Console log]tts:" + e); var tex = encodeURI(e);//轉換編碼url_encode UTF8編碼 var tok = "填入獲得的token"; var cuid = app.globalData.NLPCusid; var ctp = 1; var lan = "zh"; // zh表示中文 // 字符編碼 var spd = 5; // 表示朗讀的語速,9代表最快,1是最慢(撩妹請用2,繞口令請用9) var url = "https://tsn.baidu.com/text2audio?tex=" + tex + "&lan=" + lan + "&cuid=" + cuid + "&ctp=" + ctp + "&tok=" + tok + "&spd=" + spd wx.downloadFile({ url: url, success: function (res) { console.log(res) filePath = res.tempFilePath; // 只要服務器有回應資料,就會把回應內容寫入檔案并進入 success 回呼 if (res.statusCode === 200) { //小程式自身錄音,用playVoice播放不了,要用innerAudioContext /* wx.playVoice({ filePath: res.tempFilePath })*/ var filepath = res.tempFilePath; console.log(filepath); const innerAudioContext = wx.createInnerAudioContext(); innerAudioContext.src = https://www.cnblogs.com/AIBOOM/p/filepath; innerAudioContext.onPlay(() => { console.log('開始播放') }); innerAudioContext.onError((res) => { console.log(res.errMsg) console.log(res.errCode) }); innerAudioContext.play(); } } }) },
作者:wangwei8638
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/7248.html
標籤:其他
