一、技术介绍

我们团队维护两个前端项目:fronted(微信小程序)和 fronted-user-web(Vue3 + Vite Web 应用)。语音交互是两者共同的核心功能。

两者实现语音交互的技术栈对比如下:

微信小程序方案

录音:wx.getRecorderManager

播放:wx.createInnerAudioContext

通信:wx.connectSocket(WebSocket)

语音识别:后端 HTTP 接口

语音合成:后端 TTS + 小程序播放

Vue3 Web 方案

录音:getUserMedia + AudioWorkletNode

播放:HTMLAudioElement / AudioContext

通信:标准 WebSocket API

语音识别:后端 HTTP 接口(FormData 上传 WAV)

语音合成:后端 TTS + Web Speech API 降级

二、代码对比

小程序端录音实现


 

onst recorderManager = wx.getRecorderManager()

recorderManager.onStart(() => {

  console.log('录音开始')

})

recorderManager.onFrameRecorded((res) => {

  const { frameBuffer, isLastFrame } = res

  const base64 = wx.arrayBufferToBase64(frameBuffer)

  if (socket && socket.readyState === WebSocket.OPEN) {

    socket.send({

      event: 'audio_chunk',

      audioBase64: base64,

      isLast: isLastFrame

    })

  }

})

recorderManager.start({

  duration: 600000,

  sampleRate: 16000,

  numberOfChannels: 1,

  encodeBitRate: 64000,

  format: 'pcm',

  frameSize: 1

})

小程序录音一行代码就能开始,onFrameRecorded 回调直接拿到 PCM 帧数据。API 非常简洁,微信团队做了大量底层封装。

Web 端录音实现

const startRecording = async () => {

  const audioContext = new AudioContext({ sampleRate: 48000 })

  const mediaStream = await navigator.mediaDevices.getUserMedia({

    audio: { echoCancellation: true, noiseSuppression: true }

  })

  const source = audioContext.createMediaStreamSource(mediaStream)



  // AudioWorklet 处理 PCM

  await audioContext.audioWorklet.addModule('/audio/pcm-processor.js')

  const workletNode = new AudioWorkletNode(audioContext, 'pcm-processor', {

    processorOptions: { sampleRate: 48000 }

  })

  source.connect(workletNode)



  workletNode.port.onmessage = (event) => {

    const pcmData = new Int16Array(event.data.pcm)

    // 快速模式:直接通过 WebSocket 发送

    if (mode === 'quick' && socket.readyState === WebSocket.OPEN) {

      const base64 = arrayBufferToBase64(pcmData.buffer)

      socket.send(JSON.stringify({

        event: 'audio_chunk',

        audioBase64: base64

      }))

    } else {

      // 专家模式:缓冲后统一上传

      pcmBuffer.push(pcmData)

    }

  }

}

Web 端需要手动构建完整的音频处理链路。从 getUserMedia 到 AudioContext,再到 AudioWorkletNode,每一步都需要显式编写代码。好处是可以精细控制每个环节,比如降采样参数、音频格式转换等。

通信方式对比

小程序 WebSocket:

const socketTask = wx.connectSocket({

  url: 'wss://api.example.com/ws/speech',

  success: () => console.log('连接成功'),

  fail: (err) => console.error('连接失败', err)

})

socketTask.onMessage((res) => {

  const data = JSON.parse(res.data)

  // 处理消息

})

Web 端 WebSocket:

const socket = new WebSocket('ws://localhost:9527/api/ws/speech')

socket.onopen = () => console.log('连接成功')

socket.onmessage = (event) => {

  const data = JSON.parse(event.data)

  // 处理消息

}

两者 API 结构相似,但微信有自己的 SocketTask 对象。Web 端的 WebSocket 是标准 API,在 Vite 开发环境中需要额外配置代理支持 WebSocket。

Vite 代理配置

export default defineConfig({

  server: {

    port: 5173,

    proxy: {

      '/api': {

        target: 'http://localhost:9527',

        changeOrigin: true,

        ws: true,

        rewrite: (path) => path

      }

    }

  }

})

如果不配置 ws: true,WebSocket 连接会失败,这是一个容易被忽略的细节。

三、技术理解

通过同时维护小程序的 Web 端两个项目,对前端语音技术有了更深的理解:

API 抽象层级决定开发效率

微信小程序的 API 封装程度很高,RecorderManager 把录音的细节全部隐藏了。开发者只需要配置几个参数,就能拿到可用的 PCM 数据。这种设计适合快速开发。

Web 端的 API 更加底层,AudioContext 是一个完整的音频处理框架,需要开发者理解音频管道的概念。但底层 API 带来灵活性:可以自定义降采样算法、插入额外的音频处理节点、实时调整参数。

跨平台复用的架构设计

虽然两端的 API 不同,但架构可以复用:

1. 事件驱动:两端都采用事件驱动的消息处理模式

2. 状态管理:录音状态、连接状态、播报状态的管理逻辑可以复用

3. 错误处理:重试机制、超时处理、降级策略的设计可以通用

4. 数据格式:PCM 16kHz 单声道是两端约定的标准格式

AudioWorklet 的意义

Web 端的 AudioWorklet 是一个值得关注的技术趋势。它将音频处理从主线程剥离到独立的音频渲染线程,解决了 ScriptProcessorNode 在主线程处理音频导致的性能问题。

AudioWorklet 处理器运行在音频线程中,与主线程通过 port.postMessage 通信。通信时的 Transferable 对象传递避免了数据拷贝,性能更好。

VAD 的跨平台实现

小程序端通过 RecorderManager 的 onProgress 回调获取录音音量大小,实现简单的 VAD。Web 端通过 AnalyserNode 获取频域数据计算能量值。思路相同,API 不同。

四、技术进度

前端语音模块在两个项目中的完成情况:

fronted(微信小程序)

录音功能:已完成,RecorderManager 采集 PCM 数据

实时通信:已完成,WebSocket 传输音频帧

语音播报:已完成,后端 TTS + InnerAudioContext 播放

用户打断:已完成,支持说话打断播报

错误处理:已完成,重连 + 异常提示

fronted-user-web(Vue3 Web)

录音功能:已完成,getUserMedia + AudioWorkletNode

VAD 检测:已完成,AnalyserNode 频域分析

WebSocket 通信:已完成,Vite 代理配置

浏览器 TTS:已完成,Web Speech API 实现句子分段播报

自动降级:已完成,快速转专家模式、TTS 降级到浏览器播报

打断机制:已完成,用户开口自动切断播报

待完善功能

1. 自适应 VAD 阈值:根据环境噪声自动调整检测灵敏度

2. 多语言支持:粤语等方言的语音识别适配

3. 音频可视化:在界面上显示音量波形或频谱

4. 通话录音保存:通话结束后可回放录音

两个项目在语音功能上已实现功能对齐。差异主要体现在 API 层的封装程度,Web 端虽然实现代码更多,但灵活性和可定制性更好。后续优化方向是提升 Web 端的语音质量,缩小与原生小程序体验的差距。

更多推荐