微信小程序同声传译插件接入实战:语音识别功能完整实现指南

功能概述

微信小程序同声传译插件提供了强大的语音识别能力,可以将用户的实时语音转换为文字内容。这个功能特别适合用于聊天输入、语音搜索、语音笔记等场景。

核心实现步骤

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
  }
}
相关推荐
比老马还六4 小时前
Blockly串口积木开发
前端
小奋斗4 小时前
浏览器原理之详解渲染进程
前端·面试
伶俜monster4 小时前
搞定 Monorepo,工程能力升级,升职加薪快人一步
前端·架构
猪哥帅过吴彦祖4 小时前
Flutter 系列教程:常用基础组件 (下) - `TextField` 和 `Form`
前端·flutter·ios
刘发财4 小时前
一行代码将html页面转成矢量PDF
前端·javascript·vue.js
Dorian_Ov04 小时前
GeoServer添加要素图层的SLD样式文件以及中文乱码相关解决方案
前端·gis
Holin_浩霖4 小时前
前端开发者的 Web3 全图解实战 一
前端
uhakadotcom4 小时前
deno在2025年新出了哪些api可供使用?
前端·面试·github
uhakadotcom4 小时前
2025年honojs提供了哪些新的基础能力与API可以使用?
前端·javascript·面试