功能概述
微信小程序同声传译插件提供了强大的语音识别能力,可以将用户的实时语音转换为文字内容。这个功能特别适合用于聊天输入、语音搜索、语音笔记等场景。
核心实现步骤
1. 插件配置
首先需要在 manifest.json 中配置插件信息:
            
            
              json
              
              
            
          
          {
  "mp-weixin": {
    "plugins": {
      "WechatSI": {
        "version": "插件的版本号",
        "provider": "插件的appId"
      }
    }
  }
}
        2. 权限管理
语音功能需要用户授权,我们封装了权限检查方法:
            
            
              javascript
              
              
            
          
          export function authorize(scope) {
  return new Promise((resolve, reject) => {
    uni.getSetting({
      success(res) {
        if (!res.authSetting[scope]) {
          uni.authorize({
            scope: scope,
            success(res) {
              resolve(res)
            },
            fail(err) {
              resolve(err)
              console.log(err.errMsg)
            }
          })
        } else {
          resolve(res)
        }
      }
    })
  })
}
        3. 录音状态管理
使用 ref 管理录音的各个状态:
            
            
              javascript
              
              
            
          
          const recordState = ref(-1) // -1 未授权 0 未录音 1 正在录音 2 解析录音
const startTime = ref(0)
const endTime = ref(0)
        核心功能实现
初始化语音识别管理器
            
            
              javascript
              
              
            
          
          const plugin = requirePlugin('WechatSI')
const manager = plugin.getRecordRecognitionManager()
// 开始识别回调
manager.onRecognize = function(res) {
  console.log("成功开始识别", res)
}
// 开始录音回调
manager.onStart = function(res) {
  console.log("成功开始录音", res)
}
        错误处理机制
完善的错误处理是良好用户体验的关键:
            
            
              javascript
              
              
            
          
          manager.onError = function(res) {
  console.error("error msg", res)
  let error = '微信异常或超时,请重试或手动输入~'
  
  if(recordState.value) {
    if(res.retcode == -30004) {
      error = '声音太小,请重试~'
    }
    if(res.retcode != -30012) {  
      wx.showModal({
        title: '提示',
        content: error,
        showCancel: false
      })
    }
    onMikeEnd()			
  }
  recordState.value = 0
}
        录音结束处理
当用户停止录音时,获取识别结果:
            
            
              javascript
              
              
            
          
          manager.onStop = function(res) {
  let text = res.result
  console.log('结束录音,语音内容: ' + text)
  if (!text || text.length == 0) {
    wx.showModal({
      title: '提示',
      content: '听不清楚,请重新说一遍!',
      showCancel: false
    })
    return
  }
  content.value += text
  recordState.value = 0
  
  // 自动发送逻辑
  if(roomStore.$audioAutoSend) {
    uni.$emit("SEND_MESSAGE", {
      speechInput: true
    })
  }
}
        用户体验优化
防误触处理
通过时间判断避免用户误触:
            
            
              javascript
              
              
            
          
          function onMikeStart(e) {
  startTime.value = new Date().getTime()
  recordState.value = 1
  setTimeout(function() {
    if (!recordState.value) {
      console.log("时间小于0.5秒,认为误点,不进行录音")
      return
    }
    
    manager.start({
      duration: 30000, // 最长30秒
      lang: 'zh_CN'    // 支持中文识别
    })
  }, 100)
}
        录音时长控制
            
            
              javascript
              
              
            
          
          function onMikeEnd() {
  endTime.value = new Date().getTime()
  let time = endTime.value - startTime.value
  
  // 时间太短不处理
  if (time < 500) {
    console.log("时间太短,不调用manager.stop()")
    return
  }
  
  recordState.value = 2
  manager.stop()
}
        技术要点总结
- 权限管理:必须先获取用户授权才能使用录音功能
 - 状态管理:清晰的状态机确保流程正确
 - 错误处理:针对不同错误码提供友好提示
 - 性能优化:防误触、超时控制等细节处理
 
完整代码
            
            
              javascript
              
              
            
          
          export function useSpeech() {
  const plugin = requirePlugin('WechatSI')
  const manager = plugin.getRecordRecognitionManager()
  
  // 事件监听
  manager.onRecognize = function(res) {
    console.log("成功开始识别", res)
  }
  
  manager.onStart = function(res) {
    console.log("成功开始录音", res)
  }
  
  manager.onError = function(res) {
    console.error("error msg", res)
    let error = '微信异常或超时,请重试或手动输入~'
    if(recordState.value) {
      if(res.retcode == -30004) {
        error = '声音太小,请重试~'
      }
      if(res.retcode != -30012) {  
        wx.showModal({
          title: '提示',
          content: error,
          showCancel: false
        })
      }
      onMikeEnd()			
    }
    recordState.value = 0
  }
  
  manager.onStop = function(res) {
    let text = res.result
    console.log('结束录音,语音内容: ' + text)
    if (!text || text.length == 0) {
      wx.showModal({
        title: '提示',
        content: '听不清楚,请重新说一遍!',
        showCancel: false
      })
      return
    }
    content.value += text
    recordState.value = 0
    
    if(roomStore.$audioAutoSend) {
      uni.$emit("SEND_MESSAGE", {
        speechInput: true
      })
    }
  }
  const recordState = ref(-1)
  const startTime = ref(0)
  const endTime = ref(0)
  const startOver = ref(true)
  const endEnable = ref(true)
  function onMikeStart(e) {
    if (!startOver.value) {
      endEnable.value = false
      return
    } else {
      startOver.value = false
      endEnable.value = true
    }
    startTime.value = new Date().getTime()
    recordState.value = 1
    setTimeout(function() {
      if (!recordState.value) {
        console.log("时间小于0.5秒,认为误点,不进行录音")
        startOver.value = true
        return
      }
      manager.start({
        duration: 30000,
        lang: 'zh_CN'
      })
      startOver.value = true
    }, 100)
  }
  function onMikeEnd() {
    if (!endEnable.value || recordState.value == 2) {
      return
    }
    recordState.value = 2
    endTime.value = new Date().getTime()
    
    let time = endTime.value - startTime.value
    if (time < 500) {
      return
    }
    manager.stop()
  }
  
  return {
    getRecordAuth,
    recordState,
    onMikeStart,
    onMikeEnd
  }
}