save code
This commit is contained in:
+18
-10
@@ -8,7 +8,7 @@
|
||||
|
||||
- 服务端不再输出视频流,只输出音频流和动画控制帧。
|
||||
- 浏览器负责 Three.js/VRM 渲染、模型加载、动画缓冲和最终口型展示。
|
||||
- WebRTC 只承载音频。
|
||||
- 浏览器和服务端之间的语音收发都通过 `WS /ws/audio` 完成。
|
||||
- 字幕、状态和动画控制通过 HTTP/SSE/WebSocket 传输。
|
||||
|
||||
这意味着后续如果你要替换数字人渲染方案,优先改的是浏览器侧;如果你要替换识别、大模型或语音合成,优先改的是 `services/` 和 `core/`。
|
||||
@@ -18,21 +18,21 @@
|
||||
### 2.1 语音链路
|
||||
|
||||
1. 浏览器通过 `getUserMedia` 获取麦克风。
|
||||
2. 浏览器调用 `POST /webrtc/offer`,建立音频上行和下行连接。
|
||||
3. 服务端在 [main.py](../main.py) 中接收音轨并进入 `_consume_user_audio()`。
|
||||
2. 浏览器连接 `WS /ws/audio`,上传 `pcm_s16le` 音频块,并接收服务端回传的回复语音片段。
|
||||
3. 服务端在 [main.py](../main.py) 中接收二进制 PCM 并进入 `_process_user_audio_chunk()`。
|
||||
4. 音频被重采样为 16k 单声道后送入 VAD。
|
||||
5. VAD 检测到用户语音结束后,触发 `ChatPipeline.process_turn()`。
|
||||
6. `ASRService` 输出用户文本。
|
||||
7. `LLMService` 调用线上 DeepSeek 兼容接口生成回答。
|
||||
8. `TTSService` 按句子分段合成。
|
||||
9. 每段 TTS 音频一方面入 `AudioBus`,通过 WebRTC 下发给浏览器播放;另一方面经 `AvatarService` 转成动画帧,通过 `/ws/animation` 发给浏览器。
|
||||
9. 每段 TTS 音频一方面通过 `WS /ws/audio` 下发给浏览器播放;另一方面经 `AvatarService` 转成动画帧,通过 `/ws/animation` 发给浏览器。
|
||||
10. 浏览器在播放语音的同时,从动画缓冲队列中取帧,驱动 VRM 表情、GLTF morph target 和头部骨骼。
|
||||
|
||||
### 2.2 文本链路
|
||||
|
||||
1. 浏览器调用 `POST /chat/text`。
|
||||
2. 后端直接执行 `LLM -> TTS -> 动画控制`。
|
||||
3. 字幕通过 `/ws/subtitles` 下发,语音仍通过 WebRTC 下发。
|
||||
3. 字幕通过 `/ws/subtitles` 下发,语音通过 `WS /ws/audio` 下发。
|
||||
|
||||
文本链路主要用于调试 LLM/TTS/动画,不依赖麦克风、VAD 和 ASR。
|
||||
|
||||
@@ -44,10 +44,10 @@
|
||||
|
||||
- 应用初始化。
|
||||
- 管理全局单例服务。
|
||||
- 维护 WebRTC peer 集合、字幕客户端集合、动画客户端集合。
|
||||
- 维护音频、字幕、动画客户端集合。
|
||||
- 维护 `RuntimeState`,给 `/health` 和 `/events` 提供实时指标。
|
||||
|
||||
当前实现假设一次只保留一个主 WebRTC 连接。新连接到来时会主动关闭旧连接。这是刻意简化,不是 bug。
|
||||
当前实现假设一次只保留一个主音频 WebSocket 连接。新连接到来时会主动关闭旧连接。这是刻意简化,不是 bug。
|
||||
|
||||
### 3.2 会话状态机
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
[web/app.js](../web/app.js) 同时承担了以下职责:
|
||||
|
||||
- 创建 WebRTC 连接。
|
||||
- 建立音频 WebSocket。
|
||||
- 订阅 `/events`、`/ws/subtitles`、`/ws/animation`。
|
||||
- 维护聊天消息面板和诊断面板。
|
||||
- 用 Three.js + VRM 加载和渲染模型。
|
||||
@@ -166,7 +166,7 @@
|
||||
后端通过 `/health` 和 `/events` 暴露运行状态。推荐排查问题时按这个顺序看:
|
||||
|
||||
1. `state`: 当前状态机是否符合预期。
|
||||
2. `peers`: WebRTC 是否真正建连。
|
||||
2. `audio_clients`: 语音通道是否真正建连。
|
||||
3. `vad_start_count` / `vad_end_count`: 是否检测到语音边界。
|
||||
4. `last_asr_latency_ms` / `last_llm_latency_ms` / `last_tts_latency_ms`: 性能瓶颈在哪一段。
|
||||
5. `llm.ready` / `asr.ready` / `tts.ready` / `vad.ready`: 组件有没有降级。
|
||||
@@ -177,7 +177,7 @@
|
||||
这些约束需要后续开发明确知晓:
|
||||
|
||||
- 当前是进程内单例服务,不是多租户、多 session 设计。
|
||||
- 浏览器侧只允许一个主 WebRTC 会话接管服务端音频输出。
|
||||
- 浏览器侧只允许一个主音频 WebSocket 会话接管服务端语音输入输出。
|
||||
- 模型推理基本都直接跑在应用事件循环附近,适合研发验证,不适合高并发。
|
||||
- 当前动画驱动依赖音频能量和谱质心,不具备严格唇音级别精度。
|
||||
- 语音链路高度依赖 VAD;如果要做电话式长连接交互,建议补更稳的 turn management。
|
||||
@@ -197,9 +197,16 @@
|
||||
- `GET /health`: 看整体运行状态。
|
||||
- `GET /events`: 看持续状态流。
|
||||
- `POST /chat/text`: 快速验证 LLM/TTS/动画,不依赖麦克风。
|
||||
- `WS /ws/audio`: 看语音上传和语音回放主通道。
|
||||
- `GET /avatar/schema`: 看控制字段列表。
|
||||
- [scripts/run_all_checks.sh](../scripts/run_all_checks.sh): 统一检查入口。
|
||||
|
||||
脚本使用建议:
|
||||
|
||||
- [scripts/model_probe.py](../scripts/model_probe.py): 快速确认 ASR/TTS/VAD 是否能加载。
|
||||
- [scripts/qa_check.py](../scripts/qa_check.py): 直接压文本链路,适合看 LLM/TTS 延迟。
|
||||
- [scripts/smoke_test.py](../scripts/smoke_test.py): 输出 `wav + mp4`,其中 `mp4` 是基于动画控制帧绘制的调试视频,不是最终 3D 渲染结果。
|
||||
|
||||
如果你刚接手这个项目,建议先按下面顺序理解:
|
||||
|
||||
1. [README.md](../README.md)
|
||||
@@ -207,3 +214,4 @@
|
||||
3. [core/pipeline.py](../core/pipeline.py)
|
||||
4. [services/avatar.py](../services/avatar.py)
|
||||
5. [web/app.js](../web/app.js)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user