思泉 發表於 2019-10-23 11:59:00

利用百度AI快速开发出一款“问答机器人”并接入小程序

<p>先看实现效果:</p>
<p><img src="https://ai.bdstatic.com/file/1AD6EDBC9AC0438D9EE0FA772BF22C6D"></p>
<p>&nbsp;</p>
<p>利用百度UNIT预置的智能问答技能和微信小程序,实现语音问答机器人。这里主要介绍小程序功能开发实现过程,分享主要功能实现的子程序模块,都是干货!</p>
<p>想了解UNIT预置技能调用,请参看我之前的帖子:《UNIT搭建机器人助理》</p>
<p>https://ai.baidu.com/forum/topic/show/953021</p>
<p>想了解微信小程序的开发过程,请参看我之前的帖子:《UNIT接入小程序》https://ai.baidu.com/forum/topic/show/953022</p>
<p>1 系统框架</p>
<p>用到的技术主要有:百度语音识别、语音合成、UNIT语义解析和微信小程序。小程序通过语音识别,将用户的问题提交给百度UNIT,进行语义解析。返回的回答结果通过语音合成,转化为语音,实现与用户的语音交互。全部功能都在小程序客户端完成,不需要服务器,适合个人开发者使用。</p>
<p>2 小程序项目</p>
<p>2.1 程序创建</p>
<p>在根目录的全局配置文件app.json中增加:"pages/contact/contact"&nbsp;,会自动创建相关页面文件,结构如下:</p>
<p>contact.js:功能逻辑模块</p>
<p>contact.wxss:页面样式文件</p>
<p>contact.wxml:页面布局文件</p>
<p>contact.json:页面配置文件</p>
<p><img src="https://ai.bdstatic.com/file/3A11383FC5704171AEC1971CB5C106EE"></p>
<p>2.2 小程序录音功能实现</p>
<p>采用微信提供的录音管理器 recorderManager实现录音,录音格式aac。需要注意的是,电脑上的微信开发工具和手机上录音结果文件是不一致的,&nbsp; format设置为 'aac',电脑端的录音是aac格式,手机端录音是m4a格式。由于百度语音识别极速版目前支持微信小程序录音m4a格式,所以上传语音文件时不用转格式,方便许多!</p>
<pre class=" language-undefined">// 获取全局唯一的录音管理器 recorderManager

const recorderManager = wx.getRecorderManager();

// 录音时需要的参数, format设置为aac

const 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(":Touch down!Start recording!");

},

// 停止录音,会触发onStop事件

touchup: function () {

    recorderManager.stop(voiceOptions)

    console.log(":Touch up!Stop recording!");

    this.setData({

      isSpeaking: false,

      speakerUrl: '/res/image/speaker.png',

    })

    clearInterval(that.speakerInterval);//定时器停止

},



// 添加录音停止触发事件,这段代码可以放到onLoad()里,页面加载的时候就添加上

    recorderManager.onStop((res) =&gt; {

      const { tempFilePath, fileSize } = res

//录音完成调用语音识别API

      this.sendAsrRequest(res.tempFilePath, res.fileSize);

    });</pre>
<p>&nbsp;</p>
<p>2.3 小程序语音播放功能实现</p>
<p>需要注意的是:小程序自身录音,用wx.playVoice()函数播放不了,要用到innerAudioContext。&nbsp;</p>
<pre class=" language-undefined">//微信语音播放,

play: function (e) {

    const innerAudioContext = wx.createInnerAudioContext()

    innerAudioContext.autoplay = true

    innerAudioContext.src = filePath

    innerAudioContext.onPlay(() =&gt; {

      console.log('开始播放')

    })

    innerAudioContext.onError((res) =&gt; {

      console.log(res.errMsg)

      console.log(res.errCode)

    })

},</pre>
<p>3 调用语音识别极速版API</p>
<p>3.1 首先要在控制台创建应用,调用语音识别极速版API,“获取API Key/Secret Key”。</p>
<p>接口文档地址:https://ai.baidu.com/docs#/ASR-API-PRO/top</p>
<p>请求URL:&nbsp;https://vop.baidu.com/pro_api</p>
<p>3.2 语音识别功能实现</p>
<pre class=" language-undefined">//发送语音识别请求,传入语音文件路径及长度,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("voice:" + voice0);

    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(":ASRRequest(),URL:" + ASRUrl);

    wx.request({

      url: ASRUrl,

      data: rq,

      header: { 'content-type': 'application/json' },

      method: 'POST',

      success: function (res) {

      var resData = res.data;

      console.log(":ASTRequest() success...");

      console.log(":Result:" + resData);

      var nli = JSON.stringify(resData);

      

      // 回调函数,解析数据

      typeof arg.success == "function" &amp;&amp; arg.success(nli);

      },

      fail: function (res) {

      console.log(":ASRRequest() failed...");

      console.error(":Error Message:" + res.errMsg);

      typeof arg.fail == "function" &amp;&amp; arg.fail();

      },

      complete: function () {

      console.log(":ASRRequest() complete...");

      typeof arg.complete == "function" &amp;&amp; arg.complete();

      }

    })

},</pre>
<p>4 调用UNIT接口,获得回答</p>
<p>4.1 首先要在控制台创建应用,调用UNIT接口,“获取API Key/Secret Key”。</p>
<p>接口文档地址:https://ai.baidu.com/docs#/UNIT-v2-API/top</p>
<p>请求URL:&nbsp;https://aip.baidubce.com/rpc/2.0/unit/bot/chat</p>
<p>4.2 程序实现</p>
<pre class=" language-undefined">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(":NLIRequest(),URL:" + nliUrl);

    wx.request({

      url: nliUrl,

      data: rq,

      header: { 'content-type': 'application/x-www-form-urlencoded' },

      method: 'POST',

      success: function (res) {

      console.log(":res:"+ res);

      var resData = res.data;

      console.log(":NLIRequest() success...");

      console.log(":Result:");

      console.log(":resData:"+resData);

      var nli = JSON.stringify(resData);

      console.log(":nli:" + nli);

      

      // 回调函数,解析数据

      typeof arg.success == "function" &amp;&amp; arg.success(nli);

      },

      fail: function (res) {

      console.log(":NLIRequest() failed...");

      console.error(":Error Message:" + res.errMsg);

      typeof arg.fail == "function" &amp;&amp; arg.fail();

      },

      complete: function () {

      console.log(":NLIRequest() complete...");

      typeof arg.complete == "function" &amp;&amp; arg.complete();

      }

    })

},</pre>
<p>5 调用语音合成API</p>
<p>5.1 首先要在控制台创建应用,调用语音合成API,“获取API Key/Secret Key”。</p>
<p>接口文档地址:https://ai.baidu.com/docs#/TTS-API/top</p>
<p>请求URL:&nbsp;https://tsn.baidu.com/text2audio</p>
<p>5.2 程序实现</p>
<pre class=" language-undefined">// 语音合成

tts: function (e) {

    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 + "&amp;lan=" + lan + "&amp;cuid=" + cuid + "&amp;ctp=" + ctp + "&amp;tok=" + tok + "&amp;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 = filepath;

          innerAudioContext.onPlay(() =&gt; {

            console.log('开始播放')

          });

          innerAudioContext.onError((res) =&gt; {

            console.log(res.errMsg)

            console.log(res.errCode)

          });

          innerAudioContext.play();

      }

      }

    })

},<br><br>作者:wangwei8638</pre><br><br>
来源:https://www.cnblogs.com/AIBOOM/p/11725525.html
頁: [1]
查看完整版本: 利用百度AI快速开发出一款“问答机器人”并接入小程序