微信小程序与 Vue3 Web 端语音模块技术对比及迁移实践
一、技术介绍
我们团队维护两个前端项目: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 端的语音质量,缩小与原生小程序体验的差距。
更多推荐
所有评论(0)