141 lines
4.4 KiB
Markdown
141 lines
4.4 KiB
Markdown
---
|
||
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 |