uniapp实现语音输入全攻略:微信小程序与H5双端适配指南

uniapp实现语音输入全攻略:微信小程序与H5双端适配指南

一、语音输入功能技术选型分析

在uniapp生态中实现语音输入功能,需根据目标平台特性选择适配方案。微信小程序端可通过官方wx.getRecorderManagerAPI实现原生录音,而H5端则依赖浏览器WebRTC标准或第三方语音识别SDK。

1.1 微信小程序实现原理

微信小程序提供完整的录音管理API,包括start()stop()onStart等事件监听方法。录音数据可通过ArrayBuffer或临时文件路径获取,配合后端语音转文字服务实现完整功能链。

  1. // 微信小程序录音管理器示例
  2. const recorderManager = wx.getRecorderManager()
  3. recorderManager.onStart(() => {
  4. console.log('录音开始')
  5. })
  6. recorderManager.onStop((res) => {
  7. console.log('录音文件路径', res.tempFilePath)
  8. // 此处可上传文件至服务器进行语音识别
  9. })
  10. // 开始录音
  11. recorderManager.start({
  12. format: 'mp3',
  13. duration: 60000 // 最大录音时长
  14. })

1.2 H5端实现技术路径

H5环境受限于浏览器安全策略,需采用以下方案之一:

  • WebRTC标准:通过MediaRecorderAPI实现浏览器原生录音(需HTTPS环境)
  • 第三方SDK:集成科大讯飞、腾讯云等语音服务(需申请API密钥)
  • WebAssembly方案:将语音识别模型编译为WASM模块(适合离线场景)

二、uniapp跨平台兼容实现方案

2.1 条件编译实现双端适配

利用uniapp的条件编译特性,针对不同平台编写差异化代码:

  1. // #ifdef MP-WEIXIN
  2. // 微信小程序实现
  3. const startRecord = () => {
  4. const recorderManager = wx.getRecorderManager()
  5. // ...录音逻辑
  6. }
  7. // #endif
  8. // #ifdef H5
  9. // H5实现(示例使用MediaRecorder)
  10. const startRecordH5 = async () => {
  11. const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
  12. const mediaRecorder = new MediaRecorder(stream)
  13. mediaRecorder.ondataavailable = (e) => {
  14. const blob = e.data
  15. // 处理音频数据
  16. }
  17. mediaRecorder.start()
  18. }
  19. // #endif

2.2 语音数据格式转换

不同平台产生的音频格式存在差异,需统一处理:

  • 微信小程序默认输出MP3格式
  • H5端MediaRecorder可能输出WebM/Ogg格式
  • 建议在后端统一转换为WAV格式进行语音识别

三、完整功能实现流程

3.1 微信小程序端完整实现

  1. 配置权限:在manifest.json中声明录音权限

    1. {
    2. "mp-weixin": {
    3. "requiredPrivateInfos": ["getRecorderManager"]
    4. }
    5. }
  2. UI组件设计

    1. <template>
    2. <view>
    3. <button @click="startRecord">开始录音</button>
    4. <button @click="stopRecord">停止录音</button>
    5. <text v-if="transText">识别结果:{{transText}}</text>
    6. </view>
    7. </template>
  3. 完整业务逻辑

    1. export default {
    2. data() {
    3. return {
    4. recorderManager: null,
    5. transText: ''
    6. }
    7. },
    8. onLoad() {
    9. this.recorderManager = wx.getRecorderManager()
    10. this.setupListeners()
    11. },
    12. methods: {
    13. setupListeners() {
    14. this.recorderManager.onStop((res) => {
    15. this.uploadAudio(res.tempFilePath)
    16. })
    17. },
    18. async uploadAudio(filePath) {
    19. // 示例:使用uni.uploadFile上传文件
    20. const res = await uni.uploadFile({
    21. url: 'https://your-api.com/recognize',
    22. filePath: filePath,
    23. name: 'audio'
    24. })
    25. this.transText = JSON.parse(res.data).result
    26. }
    27. }
    28. }

3.2 H5端完整实现(基于MediaRecorder)

  1. 权限检测

    1. const checkPermission = async () => {
    2. try {
    3. await navigator.mediaDevices.getUserMedia({ audio: true })
    4. return true
    5. } catch (e) {
    6. uni.showToast({ title: '需要麦克风权限', icon: 'none' })
    7. return false
    8. }
    9. }
  2. 录音实现
    ```javascript
    let mediaRecorder = null
    let audioChunks = []

const startRecord = async () => {
if (!await checkPermission()) return

const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
mediaRecorder = new MediaRecorder(stream)

mediaRecorder.ondataavailable = (e) => {
audioChunks.push(e.data)
}

mediaRecorder.onstop = async () => {
const audioBlob = new Blob(audioChunks, { type: ‘audio/wav’ })
const formData = new FormData()
formData.append(‘audio’, audioBlob)

  1. // 上传处理
  2. const res = await uni.request({
  3. url: 'https://your-api.com/recognize',
  4. method: 'POST',
  5. data: formData,
  6. header: { 'Content-Type': 'multipart/form-data' }
  7. })
  8. // 处理识别结果...

}

mediaRecorder.start()
}

  1. ## 四、性能优化与最佳实践
  2. ### 4.1 录音质量优化
  3. - 微信小程序建议采样率16000Hz,声道数1
  4. - H5端通过`MediaRecorder``audioBitsPerSecond`控制码率
  5. - 录音时长限制建议不超过60
  6. ### 4.2 错误处理机制
  7. ```javascript
  8. // 微信小程序错误监听
  9. recorderManager.onError((err) => {
  10. console.error('录音错误', err)
  11. if (err.errMsg.includes('permission')) {
  12. uni.showModal({ title: '提示', content: '请开启麦克风权限' })
  13. }
  14. })
  15. // H5端错误处理
  16. navigator.mediaDevices.getUserMedia({ audio: true })
  17. .catch(err => {
  18. if (err.name === 'NotAllowedError') {
  19. // 用户拒绝权限
  20. }
  21. })

4.3 第三方服务集成建议

  1. 腾讯云语音识别

    1. // 示例调用腾讯云语音识别API
    2. const recognizeAudio = async (audioData) => {
    3. const res = await uni.request({
    4. url: 'https://api.tencentcloudapi.com/asr/v20190614/SentenceRecognition',
    5. method: 'POST',
    6. data: {
    7. EngineModelType: '16k_zh',
    8. ChannelNum: 1,
    9. // 其他参数...
    10. },
    11. header: {
    12. 'Authorization': 'YOUR_TENCENT_CLOUD_AUTH'
    13. }
    14. })
    15. return res.data
    16. }
  2. 科大讯飞SDK集成

    1. <!-- 在index.html中引入SDK -->
    2. <script src="https://cdn.jsdelivr.net/npm/ifly-voice-js@latest/ifly-voice.min.js"></script>

五、常见问题解决方案

5.1 微信小程序录音中断问题

  • 现象:调用stop后未触发onStop回调
  • 解决方案:增加超时处理机制
    1. const recordTimeout = setTimeout(() => {
    2. if (!this.isStopped) {
    3. recorderManager.stop()
    4. uni.showToast({ title: '录音超时', icon: 'none' })
    5. }
    6. }, 60000)

5.2 H5端兼容性问题

  • iOS Safari限制:需在用户交互事件(如click)中触发录音
  • Android Chrome问题:部分机型需要HTTPS环境
  • 解决方案
    1. // 在用户点击事件中初始化录音
    2. document.getElementById('recordBtn').addEventListener('click', async () => {
    3. try {
    4. const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
    5. // 初始化录音...
    6. } catch (e) {
    7. console.error('录音初始化失败', e)
    8. }
    9. })

六、进阶功能实现

6.1 实时语音转文字

  1. WebSocket方案
    ```javascript
    // 建立WebSocket连接
    const socket = new WebSocket(‘wss://your-api.com/asr’)

// 分段发送音频数据
const sendAudioChunk = (chunk) => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(chunk)
}
}

// 接收实时识别结果
socket.onmessage = (e) => {
const data = JSON.parse(e.data)
this.transText += data.result
}

  1. 2. **微信小程序实时识别**:
  2. ```javascript
  3. // 使用wx.startRecord(已废弃)或通过WebSocket实现
  4. // 推荐使用腾讯云实时语音识别服务

6.2 语音指令识别

  1. // 简单指令识别示例
  2. const recognizeCommand = (text) => {
  3. const commands = {
  4. '打开设置': () => uni.navigateTo({ url: '/pages/settings' }),
  5. '返回首页': () => uni.switchTab({ url: '/pages/index' })
  6. }
  7. for (const [cmd, action] of Object.entries(commands)) {
  8. if (text.includes(cmd)) {
  9. action()
  10. return true
  11. }
  12. }
  13. return false
  14. }

七、总结与建议

  1. 平台差异处理:始终使用条件编译处理平台差异代码
  2. 权限管理:在应用启动时检测并请求必要权限
  3. 错误恢复:实现完善的错误处理和用户提示机制
  4. 性能监控:对录音时长、上传速度等关键指标进行监控
  5. 安全考虑:敏感操作增加二次确认,音频数据传输使用HTTPS

通过本文介绍的方案,开发者可以在uniapp框架下高效实现跨平台的语音输入功能,覆盖微信小程序和H5双端场景。实际开发中应根据具体业务需求选择合适的技术方案,并做好充分的测试验证工作。