4.4 KiB
4.4 KiB
| name | overview | todos | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| speaking-voice-input | 在 Speaking.vue 中增加语音输入功能,调用豆包流式语音识别 API 实现语音转文字 |
|
产品需求
在英语口语对话页面(Speaking.vue)中增加语音输入功能,让用户可以通过麦克风进行语音输入,系统调用豆包大模型流式语音识别 API 将语音转换为文字。
核心功能
- 麦克风按钮:在输入框旁边添加麦克风图标按钮,支持点击开始/停止录音
- 实时录音:使用浏览器 MediaRecorder API 采集麦克风音频(16kHz, 16bit, 单声道, PCM 格式)
- 流式识别:通过 WebSocket 发送音频流到豆包 ASR API,实时接收识别结果
- 结果回填:将识别文字自动填入输入框,用户可编辑后发送
- 状态反馈:录音状态(空闲/录音中)的视觉反馈,包括按钮样式变化和波形动画
用户交互流程
- 用户点击麦克风按钮,开始录音
- 页面显示录音中状态,按钮变为红色闪烁
- 用户说话,音频数据通过 WebSocket 实时发送到服务器
- 服务器返回识别结果,显示在输入框中
- 用户点击停止按钮或再次点击麦克风停止录音
- 用户确认输入内容后点击发送按钮
技术栈
- 前端框架:Vue 3 + Composition API
- 样式:Scss(现有项目使用)
- 音频采集:浏览器 MediaRecorder API
- 实时通信:WebSocket
- 认证方式:与 TTS 相同(X-Api-App-Id + X-Api-Access-Key)
实现方案
1. 配置更新 (config/index.js)
添加流式 ASR WebSocket 地址配置:
// 豆包流式语音识别 ASR
export const DOUBAO_ASR_WS_PATH = "wss://openspeech.bytedance.com/api/v1/asr/ws_binary";
2. Speaking.vue 功能实现
录音控制
- 使用
navigator.mediaDevices.getUserMedia获取麦克风权限 - 使用
MediaRecorderAPI 录制音频(mimeType: 'audio/webm;codecs=opus' 或 'audio/pcm') - 由于浏览器不直接支持录制 PCM,需要录制后转换或使用 AudioContext 重采样
WebSocket 通信
- 建立 WebSocket 连接,使用认证头
- 发送初始化消息(包含音频参数配置)
- 分帧发送音频数据(建议每 40ms 一帧)
- 接收并处理识别结果消息
音频处理
由于浏览器 MediaRecorder 不直接支持录制 PCM,需要:
- 方案一:录制 webm/opus 格式,发送时解码为 PCM
- 方案二:使用 AudioContext + ScriptProcessor/AudioWorklet 实时采集 PCM
- 推荐方案一,实现更简单,兼容性更好
UI 组件
- 麦克风按钮(SVG 图标)
- 录音状态动画(波形或脉冲效果)
- 录音时长显示(可选)
关键代码结构
录音状态管理
const isRecording = ref(false);
const recordingDuration = ref(0);
let mediaRecorder = null;
let audioContext = null;
let websocket = null;
WebSocket 消息处理
// 初始化消息格式
{
"app": { "appid": DOUBAO_APP_ID, "token": DOUBAO_ACCESS_TOKEN },
"user": { "uid": "speaking_asr_" + Date.now() },
"audio": { "format": "pcm", "rate": 16000, "bits": 16, "channel": 1 }
}
性能考虑
- 音频帧发送间隔:40ms(与 16kHz 采样率匹配)
- WebSocket 心跳:防止连接断开
- 错误重连:录音中断时自动尝试重连
- 内存管理:及时释放音频资源
兼容性
- 使用
MediaRecorder.isTypeSupported检测浏览器支持 - 降级处理:浏览器不支持时隐藏麦克风按钮
Agent Extensions
此任务不需要使用任何 Agent Extensions