10分钟

任务 5 小程序利用插件调用ASR接口

任务目的

现在已经初步完成小程序界面和功能,但无法做到真正的录音,接下来将继续改写小程序。首先先完成调用ASR接口实现语音识别,这个功能可以利用小程序的插件实现,相对比较简单。

任务步骤

1.开通ASR接口

与开通TTS接口相似。在腾讯云官网搜索“ASR”,搜索结果会出现【语音识别】,点击【立即使用】按钮。在语音识别界面勾选“我已阅读并同意《用户协议》”,点击【免费试用】按钮,即可开通ASR接口。

2.小程序接入【腾讯云智能语音】插件

使用管理员账号登录微信公众平台。在小程序管理后台,点击【设置】按钮,进入设置页面。

进入微信小程序管理后台

点击【第三方设置】进入相应页签,点击【添加插件】按钮。

进入第三方设置页面

在添加插件的弹窗中搜索"wx3e17776051baf153",添加插件。

添加插件

显示以下弹窗说明添加成功。

添加插件成功

接下来需要配置插件,将 miniprogram 下的 app.json 替换成以下代码

{
  "pages": [
    "pages/index/index"
  ],
  "window": {
    "backgroundColor": "#F6F6F6",
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#F6F6F6",
    "navigationBarTitleText": "趣味复读机器人",
    "navigationBarTextStyle": "black"
  },
  "plugins": {
    "QCloudAIVoice": {
      "version": "1.0.6",
      "provider": "wx3e17776051baf153"
    }
  },
  "sitemapLocation": "sitemap.json",
  "style": "v2"
}

这里相较于原本的内容多添加了 plugins 插件部分。

3.修改 index.js 文件

将 index.js 修改为以下代码。

const appid = "yourAppId"
const secretid = "yourSecretId"    # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
const secretkey = "yourSecretKey"  # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
let plugin = requirePlugin("QCloudAIVoice")
plugin.setQCloudSecret(appid, secretid, secretkey)  # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成
                                                    # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
                                                    # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
let manager = plugin.getRecordRecognitionManager()
const recordOptions = {
  duration: 60000,
  engine_model_type: "16k_0"
};
let innerAudioContext = wx.createInnerAudioContext()

Page({
  data: {
    message_list: [],
    scroll_height: wx.getSystemInfoSync().windowHeight - 54,
    page_index: 0,
    cancel: false,
    status: 0,
    tips: ['按住 说话', '松开 结束', '取消 发送'],
    voiceTypes: [{
      name: '亲和女声',
      num: 0,
      checked: true
    }, {
      name: '亲和男声',
      num: 1,
      checked: false
    }, {
      name: '成熟男声',
      num: 2,
      checked: false
    }, {
      name: '温暖女声',
      num: 4,
      checked: false
    }],
    voiceType: 0,
    state: {
      'normal': 0,
      'pressed': 1,
      'cancel': 2
    },
    toView: '',
    currentText: ''
  },

  onLoad: function () {
    let that = this
    manager.onStart((res) => {
      console.log('recorder start', res.msg)
    })
    manager.onStop((res) => {
      console.log("识别结束")
      console.log(res)
      that.setData({
        currentText: res.result
      })
      that.sendVoice(res.tempFilePath, 1)
    })
    manager.onError((res) => {
      console.log('recorder error', res.errMsg)
    })
    manager.onRecognize((res) => {
      console.log("识别中")
      console.log(res)
      that.setData({
        currentText: res.result
      })
    })
    wx.authorize({
      scope: 'scope.record',
      success() {
        wx.showToast({
          title: '录音授权成功',
        })
      }
    })
  },
  record: function () {
    manager.start(recordOptions);
  },
  stop: function () {
    wx.showModal({
      title: '识别成功',
      content: this.data.currentText,
    })
    manager.stop();
    // this.sendVoice("tempfile", 1)
    // this.sendVoice("tempfile", 0)
  },
  touchStart: function (e) {
    // 触摸开始
    var startY = e.touches[0].clientY;
    // 记录初始Y值
    this.setData({
      startY: startY,
      status: this.data.state.pressed
    });
  },
  touchMove: function (e) {
    // 触摸移动
    var movedY = e.touches[0].clientY;
    var distance = this.data.startY - movedY;
    this.setData({
      status: distance > 50 ? this.data.state.cancel : this.data.state.pressed
    });
  },
  touchEnd: function (e) {
    // 触摸结束
    var endY = e.changedTouches[0].clientY;
    var distance = this.data.startY - endY;
    this.setData({
      cancel: distance > 50 ? true : false,
      status: this.data.state.normal
    });
    // 不论如何,都结束录音
    this.stop();
  },
  scrollToBottom: function () {
    this.setData({
      toView: 'row_' + (this.data.message_list.length - 1)
    });
  },
  sendVoice: function (tempUrl, num) {
    var message_list = this.data.message_list;
    var message = {
      myself: num,
      head_img_url: '/images/userimg.jpg',
      content: tempUrl,
    };
    message_list.push(message);
    this.setData({
      message_list: message_list
    })
    this.scrollToBottom()
    setTimeout(() => {
      wx.hideLoading();
    }, 500)
  },
  changeVoiceType: function (e) {
    let voiceType = e.currentTarget.dataset.voicetype;
    let arrys = this.data.voiceTypes;
    for (let i = 0; i < arrys.length; i++) {
      if (arrys[i].num == voiceType) {
        arrys[i].checked = true
      } else {
        arrys[i].checked = false
      }
    }
    this.setData({
      voiceTypes: arrys,
      voiceType: voiceType
    })
  },
  playVoice: function (e) {
    innerAudioContext.src = e.currentTarget.dataset.src
    innerAudioContext.onPlay(() => {
      console.log('开始播放')
    })
    innerAudioContext.onError((res) => {
      console.log(res.errMsg)
      console.log(res.errCode)
    })
    innerAudioContext.play()
  }
})

新的代码添加了使用插件调用语音识别接口的过程。

这段代码首先设置了appid,secretid,secretkey,

const appid = "yourAppId"         # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成
const secretid = "yourSecretId"   # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
const secretkey = "yourSecretKey" # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140

然后引入插件 plugin,使用 plugin 插件调用录音机组件 RecordRecognitionManager,并通过微信接口获取 innerAudioContex 组件。

let plugin = requirePlugin("QCloudAIVoice")
plugin.setQCloudSecret(appid, secretid, secretkey)    # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成
                                                      # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
                                                      # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
let manager = plugin.getRecordRecognitionManager()
const recordOptions = {
  duration: 60000,
  engine_model_type: "16k_0"
};
let innerAudioContext = wx.createInnerAudioContext()

注意:使用本插件需要提前初始化 RecordRecognitionManager 的onStart、onStop、onError、onRecognize 方法,否则无法使用。另外获取录音机组件需要先获取手机的录音权限,否则无法调用成功。这里这些工作都在小程序 onLoad 函数中完成。

onLoad: function () {
  let that = this
  manager.onStart((res) => {
    console.log('recorder start', res.msg)
  })
  manager.onStop((res) => {
    console.log("识别结束")
    console.log(res)
    that.setData({
      currentText: res.result
    })
    that.sendVoice(res.tempFilePath, 1)
  })
  manager.onError((res) => {
    console.log('recorder error', res.errMsg)
  })
  manager.onRecognize((res) => {
    console.log("识别中")
    console.log(res)
    that.setData({
      currentText: res.result
    })
  })
  wx.authorize({
    scope: 'scope.record',
    success() {
      wx.showToast({
        title: '录音授权成功',
      })
    }
  })
}

最后完成了 record 和 playVoice 函数,改写了 stop 函数。

4.测试语音识别接口效果

重新编译小程序代码,点击【预览】按钮,会出现二维码。使用微信扫描二维码。

预览小程序

按住下方按钮说话,本次测试说的语音是“测试语音识别”,松手后会自动识别语音,如图所示。

语音识别测试

注意:开发者工具上的录音文件与移动端格式不同,暂时只可在工具上进行播放调试,无法直接播放或者在客户端上播放。