文章由来

这里通过简单的对话形式来描述接下来要讲的bug,相关界面在文章中都有展示,可以结合相关图片更好的理解问题

  • 测试小伙伴:界面一直停留在(语音识别中...);
  • 我:都到识别这一步了,应该是测试环境下后台不稳定吧,你再多试几次;
  • 测试小伙伴:我去问后台了,后台说应该是前端这边的问题;
  • 我:(开始检查代码),好像我这边代码也没有问题啊,你是怎么操作的?
  • 测试小伙伴:我点击了一下录音键,然后就一直转圈圈;
  • 我:不是长按?
  • 测试小伙伴:不是,就一般的点击操作;
  • 我:(开始检查代码),我这边再看看,好了跟你说。。。

定位问题

RecorderManager.stop()事件好像没生效,进微信社区查了一通,以下是社区反馈的问题捡几个重点,感兴趣的可以看看 

微信社区相关反馈

问题一、RecorderManager的状态管理

问题二、小程序recorderManager.stop()发生延迟停止,求解?

问题三、录音结束不能触发onStop()事件

相关解决方案、录音stop失效?你需要一套歪操作?

  • 综合上面几篇文章,终于定位到问题所在,接下来就是如何解决这个问题了

简化后代码

<!-- UI界面中红框组件 -->
<template>
  <div class="select-time">
    <h3 class="title">工作时间</h3>
    <textarea placeholder="例:每周一三五,上午 8:00-10:00" v-model="text" @blur="changeVal" placeholder-style="color:#b2b2b2;"></textarea>
    <image :src="iconRecord" @longpress ="startRecord" @touchend="endRecord" @tap="authorization" />
  </div>
</template>

<script>
import tool from '@/utils/tool' // 工具方法
const recorder = wx.getRecorderManager() // 录音管理器实例
export default {
  data () {
    return {
      iconRecord: require('@static/icon/icon_voice.png'), // 录音icon
      recordFlag: false // 控制endRecord事件执行
    }
  },
  props: {
    text: {
      type: String,
      default: ''
    } // textarea的值
  },
  methods: {
    changeVal (e) {
      const that = this
      that.$emit('getTime', e.mp.detail.value)
      // 调用父组件方法,并把值赋给父组件事先定义好的属性内
    },
    // icon点击事件
    authorization () {
      const that = this
      wx.getSetting({
        success (res) {
          if (!res.authSetting['scope.record']) {
            wx.authorize({
              scope: 'scope.record',
              success () {
                // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
              },
              fail () {
                that.failSetting()
              }
            })
          } else {
            // that.startRecord()
            tool.showToast('请长按说话', 500)
          }
        }
      })
    },
    // icon长按事件
    startRecord () {
      tool.showRecordLoading('语音输入中...')
      this.recordFlag = true
      recorder.start({
        duration: 15000,
        format: 'mp3'
      })
    },
    // 手指离开屏幕事件
    endRecord () {
      const that = this
      // 除非recordFlag为true,否则不执行接下来的逻辑
      if (that.recordFlag) {
        wx.getSetting({
          success (res) {
            if (res.authSetting['scope.record']) {
              wx.hideLoading()
              tool.showRecordLoading('语音识别中...')
              recorder.stop()
              recorder.onStop(res => {
                const { tempFilePath } = res
                wx.uploadFile({
                  url: '语音识别接口', // 接口地址
                  header: {
                    // 请求头相关配置
                  },
                  name: 'voice', // 上传文件名
                  filePath: tempFilePath,
                  success (res) {
                    wx.hideLoading()
                    const temp = JSON.parse(res.data)
                    if (temp.code === 1) {
                      // 得到语音转后的文字后拼接到原来的输入框内容之后,并赋值给父组件
                      that.$emit('getTime', that.text + temp.data)
                    }
                    that.recordFlag = false
                  },
                  fail () {
                    wx.hideLoading()
                    that.recordFlag = false
                    tool.showToast('语音识别失败')
                  }
                })
              })
            } else {
              wx.hideLoading()
            }
          }
        })
      }
    },
    // 拒绝授权和再次点击录音icon时触发前往授权的引导窗
    failSetting () {
      wx.showModal({
        title: '提示',
        content: '您未授权录音,功能将无法使用',
        showCancel: false,
        confirmText: '前往授权',
        confirmColor: '#5bb53c',
        success: function (res) {
          wx.openSetting({
            success (res) {
              // console.log(res)
            }
          })
        }
      })
    }
  }
}
</script>

这里着重说几点改动: 

  •  在录音icon上增加一个tap事件,事件作用是负责授权相关引导及提醒用户长按操作,不清楚微信授权的可以看看我上篇文章的讲解;
  • 将原来的touchstart事件换成longpress事件,只有用户长按时才会触发录音事件;
  • 添加一个recordFlag属性,控制touchend事件内部逻辑是否执行;
  • 最后简单提一下自己改造后的wx.showToast即上面的tool.showToast(默认显示时间为1.5s)
function showToast (name, duration = 1500) {
  wx.showToast({
    title: name,
    icon: 'none',
    duration: duration,
    mask: true
  })
}

UI界面

接下来重点展示相关的语音识别操作界面

未操作录音功能的静态页

重点关注下图红框及红框内的绿色区域(录音icon)

授权界面

用户首次进入页面,点击录音icon会出发授权弹窗

 

拒绝授权的相关界面 

当用户点击上图拒绝按钮,引导用户进入授权设置页,让用户知道只有授权录音后才能使用录音功能

当用户点击上图的前往授权进入授权设置页 

 

允许授权的相关界面 

 

当用户点击录音icon,并不是长按icon,这时提示用户请长按说话 

 

当用户长按录音icon开始提示用户这个时候正在进行录音操作,可以说话了,即(语音输入中 ...)

 

当用户手指移开录音icon后,提示用户正在识别语音,这个时候说话也没用,不记录了,即(语音识别中 ...) 

 

效果图

总结

  • 看到这里肯定有人会说我小题大做
  • 写文章并不全是为了给别人看的
  • 你们可以认为记录仅仅是我个人的一种习惯
  • 如果你正要做这个功能或想要做这个功能,看到这个文章希望多少能给你带来一点提示作用
  • 如果真的帮助到你,请不要吝啬你的赞
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐