Ai_GirlFriend/xuniYou/最新优化说明.md
2026-02-28 18:04:34 +08:00

236 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 语音通话最新优化说明
## 📅 优化时间
2026-02-28
## 🎯 优化目标
解决 "idle timeout" 问题确保语音通话流程完整运行ASR → LLM → TTS
## ✅ 已完成的优化
### 1. 服务器端优化
#### 增加超时时间
- **文件**: `lover/.env`
- **修改**: 添加 `VOICE_CALL_IDLE_TIMEOUT=120`
- **说明**: 从默认的 60 秒增加到 120 秒,给 ASR + LLM + TTS 处理留出足够时间
- **重要**: 修改后需要重启 FastAPI 服务器才能生效
### 2. 客户端优化
#### 使用官方推荐参数
- **文件**: `xuniYou/pages/chat/phone.vue`
- **修改**: `sendAudioInChunks()` 方法
- **参数调整**:
- 每片大小: 8192 bytes → **3200 bytes**(官方推荐)
- 发送间隔: 50ms → **100ms**(官方推荐)
#### 为什么使用 3200 bytes
根据官方文档和音频参数计算:
```
PCM 音频参数:
- 采样率: 16000 Hz
- 位深度: 16 bit = 2 bytes
- 声道数: 1单声道
每秒数据量 = 16000 × 2 × 1 = 32000 bytes
官方建议每包 100ms 音频:
100ms 数据量 = 32000 × 0.1 = 3200 bytes
```
这就是官方示例代码中使用 `f.read(3200)` 的原因!
## 📊 优化效果对比
### 优化前
```
每片: 8KB
间隔: 50ms
速率: 8192 / 0.05 = 163840 bytes/s = 160 KB/s
实际音频速率: 32000 bytes/s = 31.25 KB/s
速率比: 5.12 倍(发送太快)
```
### 优化后
```
每片: 3.2KB
间隔: 100ms
速率: 3200 / 0.1 = 32000 bytes/s = 31.25 KB/s
实际音频速率: 32000 bytes/s = 31.25 KB/s
速率比: 1 倍(完美匹配实时音频流)
```
## 🔧 如何测试
### 1. 重启服务器(必须)
```bash
# 在服务器上
cd /path/to/lover
# 停止旧进程
pkill -f "uvicorn.*main:app"
# 启动新进程
uvicorn main:app --host 0.0.0.0 --port 30101 --reload
```
### 2. 重新编译客户端
在 HBuilderX 中:
1. 选择运行 → 运行到手机或模拟器
2. 或者制作自定义调试基座
### 3. 测试步骤
1. 打开 App进入语音通话页面
2. 按住"按住说话"按钮
3. **清晰地说 3-5 秒的话**(重要!之前测试只有 1 秒太短)
4. 松开按钮
5. 观察日志和响应
### 4. 预期日志
#### 客户端日志
```
📦 开始分片发送(官方推荐参数)
📊 总大小: 160000 bytes
📊 每片大小: 3200 bytes
📊 发送间隔: 100 ms
📊 预计发送时间: 5000 ms
📤 发送第 1 片,大小: 3200 bytes
✅ 第 1 片发送成功
...
✅ 所有音频片段发送完成,共 50 片
📊 实际发送时间: 5000 ms
📤 发送结束标记 "end"
✅ 结束标记发送成功,等待服务器处理...
```
#### 服务器日志
```
ASR connection opened
ASR event end=False sentence=...
ASR event end=True sentence=你好,我想问一个问题
ASR complete
Handle sentence: 你好,我想问一个问题
[LLM 生成回复]
[TTS 合成语音]
```
#### 客户端收到响应
```
📋 收到控制消息, type: reply_text
📋 完整消息: {"type":"reply_text","text":"你好呀,有什么问题尽管问我~"}
🎵 收到音频数据流, 当前缓存数量: 1
🎵 收到音频数据流, 当前缓存数量: 2
...
📋 收到控制消息, type: reply_end
[开始播放音频]
```
## ⚠️ 注意事项
### 1. 录音时长要求
- **最少 2-3 秒**:太短的音频 ASR 可能无法识别
- **建议 3-5 秒**:足够的语音内容,识别率更高
- **最多 10 秒**:避免单次录音过长
### 2. 录音环境
- 安静环境,减少背景噪音
- 清晰发音,不要含糊不清
- 正常语速,不要太快或太慢
### 3. 网络要求
- 稳定的网络连接
- WebSocket 保持连接
- 如果网络不稳定,会自动重连
## 🐛 问题排查
### 如果还是出现 "idle timeout"
#### 1. 检查服务器是否重启
```bash
# 查看进程
ps aux | grep uvicorn
# 查看日志
tail -f /path/to/lover/logs/app.log
```
#### 2. 检查 .env 配置是否生效
```bash
# 在服务器上
cd /path/to/lover
cat .env | grep VOICE_CALL_IDLE_TIMEOUT
```
应该显示:
```
VOICE_CALL_IDLE_TIMEOUT=120
```
#### 3. 检查录音时长
查看客户端日志中的 "总大小"
```
📊 总大小: 160000 bytes
```
计算时长:
```
时长 = 总大小 / 32000
160000 / 32000 = 5 秒 ✅ 足够
如果只有 9000 bytes
9000 / 32000 = 0.28 秒 ❌ 太短
```
#### 4. 检查服务器日志
如果服务器日志中没有 "ASR event",说明 ASR 没有收到数据或无法识别。
可能原因:
- 音频格式不对(应该是 PCM 16kHz 单声道)
- 音频太短
- 音频质量太差(噪音太大)
## 📚 参考文档
- [Paraformer 实时语音识别 Python SDK](https://help.aliyun.com/zh/model-studio/paraformer-real-time-speech-recognition-python-sdk)
- [实时语音识别](https://help.aliyun.com/zh/model-studio/real-time-speech-recognition)
- `xuniYou/官方文档分析和正确实现.md` - 详细的技术分析
- `xuniYou/问题定位总结.md` - 问题诊断过程
## 🎉 预期结果
优化后,语音通话应该能够:
1. ✅ 录音正常PCM 格式16kHz
2. ✅ 分片发送3200 bytes/片100ms 间隔)
3. ✅ ASR 识别成功(收到识别结果)
4. ✅ LLM 生成回复(收到文本回复)
5. ✅ TTS 合成语音(收到音频数据)
6. ✅ 播放音频(听到 AI 的声音)
7. ✅ 不再出现 "idle timeout" 错误
## 💡 下一步优化建议
如果基本功能正常,可以考虑:
1. **实时流式录音**:使用 `onFrameRecorded` 实现真正的实时传输
2. **降低延迟**:优化 LLM 和 TTS 的响应速度
3. **打断功能**:允许用户在 AI 说话时打断
4. **多轮对话**:优化对话历史管理
5. **情感识别**:根据用户语气调整回复风格
## 📞 技术支持
如果遇到问题,请提供:
1. 客户端完整日志(从按下按钮到收到响应)
2. 服务器日志ASR/LLM/TTS 相关)
3. 录音时长和文件大小
4. 网络状态和 WebSocket 连接状态