--- name: speaking-voice-input overview: 在 Speaking.vue 中增加语音输入功能,调用豆包流式语音识别 API 实现语音转文字 todos: - id: update-config content: 在 config/index.js 中添加 DOUBAO_ASR_WS_PATH 配置 status: completed - id: add-recording-state content: 在 Speaking.vue 中添加录音相关状态和变量 status: completed dependencies: - update-config - id: implement-recording content: 实现录音功能(MediaRecorder 音频采集和转换) status: completed dependencies: - add-recording-state - id: implement-websocket content: 实现 WebSocket 流式识别(连接管理、消息收发) status: completed dependencies: - implement-recording - id: add-voice-input-ui content: 添加麦克风按钮 UI 和录音状态动画 status: completed dependencies: - implement-websocket - id: cleanup-resources content: 添加组件卸载时的资源清理逻辑 status: completed dependencies: - add-voice-input-ui --- ## 产品需求 在英语口语对话页面(Speaking.vue)中增加语音输入功能,让用户可以通过麦克风进行语音输入,系统调用豆包大模型流式语音识别 API 将语音转换为文字。 ## 核心功能 - **麦克风按钮**:在输入框旁边添加麦克风图标按钮,支持点击开始/停止录音 - **实时录音**:使用浏览器 MediaRecorder API 采集麦克风音频(16kHz, 16bit, 单声道, PCM 格式) - **流式识别**:通过 WebSocket 发送音频流到豆包 ASR API,实时接收识别结果 - **结果回填**:将识别文字自动填入输入框,用户可编辑后发送 - **状态反馈**:录音状态(空闲/录音中)的视觉反馈,包括按钮样式变化和波形动画 ## 用户交互流程 1. 用户点击麦克风按钮,开始录音 2. 页面显示录音中状态,按钮变为红色闪烁 3. 用户说话,音频数据通过 WebSocket 实时发送到服务器 4. 服务器返回识别结果,显示在输入框中 5. 用户点击停止按钮或再次点击麦克风停止录音 6. 用户确认输入内容后点击发送按钮 ## 技术栈 - 前端框架:Vue 3 + Composition API - 样式:Scss(现有项目使用) - 音频采集:浏览器 MediaRecorder API - 实时通信:WebSocket - 认证方式:与 TTS 相同(X-Api-App-Id + X-Api-Access-Key) ## 实现方案 ### 1. 配置更新 (config/index.js) 添加流式 ASR WebSocket 地址配置: ```javascript // 豆包流式语音识别 ASR export const DOUBAO_ASR_WS_PATH = "wss://openspeech.bytedance.com/api/v1/asr/ws_binary"; ``` ### 2. Speaking.vue 功能实现 #### 录音控制 - 使用 `navigator.mediaDevices.getUserMedia` 获取麦克风权限 - 使用 `MediaRecorder` API 录制音频(mimeType: 'audio/webm;codecs=opus' 或 'audio/pcm') - 由于浏览器不直接支持录制 PCM,需要录制后转换或使用 AudioContext 重采样 #### WebSocket 通信 - 建立 WebSocket 连接,使用认证头 - 发送初始化消息(包含音频参数配置) - 分帧发送音频数据(建议每 40ms 一帧) - 接收并处理识别结果消息 #### 音频处理 由于浏览器 MediaRecorder 不直接支持录制 PCM,需要: - 方案一:录制 webm/opus 格式,发送时解码为 PCM - 方案二:使用 AudioContext + ScriptProcessor/AudioWorklet 实时采集 PCM - 推荐方案一,实现更简单,兼容性更好 #### UI 组件 - 麦克风按钮(SVG 图标) - 录音状态动画(波形或脉冲效果) - 录音时长显示(可选) ## 关键代码结构 ### 录音状态管理 ```javascript const isRecording = ref(false); const recordingDuration = ref(0); let mediaRecorder = null; let audioContext = null; let websocket = null; ``` ### WebSocket 消息处理 ```javascript // 初始化消息格式 { "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