Files
ShowenV2/docs/PLAN_M2.1_NEXT.md
XiuchengWu 6f7e24db63 feat: M2.1 客户端骨架、BLE 修复、仓库整理与现状板
- BLE: 修复 BlueZ LocalName 与 Includes 冲突,串行注册与退避
- HTTP: 语音对话补 Live2D talking 标志与 session;Web 补 X-Session-Id
- Flutter: 角色/对话/模型页 + API,Gradle/依赖升级,麦克风权限
- 文档: 新增 docs/STATUS.md,校准 CLAUDE/PROGRESS/README
- 清理: 移除根目录截图与临时模型,运维脚本迁入 scripts/device
2026-07-09 12:41:34 +08:00

205 lines
6.5 KiB
Markdown
Raw Permalink 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.
# M2.1 下一阶段实施计划
> 创建2026-07-09
> 背景功能不完善AI 与 Live2D/视频**尚未完整联动**App/Web 为半成品。
> 对照:`docs/STATUS.md`(现状)· `docs/M2.1_PRD.md`(产品定义)
---
## 0. 目标(本阶段完成的定义)
**可演示的闭环P0 验收)**
1. 设备开机 → App/Web 可连
2. 切换角色(至少狗/猫/Live2D 配置)→ 画面与人设同步
3. 文字对话 → 客户端播 TTS → **画面有“在说话”反馈**
4. App 按住说话 → 同上
5. 模型列表可见;切换 LLM 后下一回合生效(失败有明确提示)
**不做本阶段(明确边界)**
- 设备本机麦克风/扬声器直连(硬件未接)
- 精细口型同步 / 流式打断
- 数字人/歌姬全套新视频素材制作
- 云端 LLM 实装
---
## 1. 现状结论(计划前提)
| 层 | 现状 |
|----|------|
| AI 管线 | 本地 ASR/LLM/TTS 可跑HTTP `/api/chat/*` 可用 |
| Live2D | 有字幕 `Subtitle``live2d_talking` 标志在 HTTP 内,**未驱动嘴部动画** |
| 视频状态机 | 有 `talk_state` 配置字段;**对话不会 ChangeScene** |
| App | 角色/对话/模型页已写;真机旅程未系统验 |
| Web | chat 控制台有入口HTTP 录音受限 |
| 仓库 | 2026-07-09 已提交整理与骨架改动(见 git log |
---
## 2. 工作包拆分
### WP-A · AI ↔ 画面联动(核心缺口)
**A1. Live2D 说话态接通(优先)**
| 步骤 | 内容 | 验收 |
|------|------|------|
| A1.1 | 定义共享通道:消息 `Message::Live2dTalking { on: bool }` **或** 注入 Arc 状态到 Live2D 插件 | 二选一,文档写清 |
| A1.2 | HTTP chat 成功路径:开始 `talking=true`,结束按**音频时长或字数**回 `false` | 与 TTS 结束大致对齐(误差 ≤1.5s 可接受) |
| A1.3 | Live2D 渲染循环读 talking → `animation.set_talking` | 说话时嘴部开合,结束后回 idle |
| A1.4 | 字幕路径保持:`Subtitle` 继续走 | 字+嘴同时有反馈 |
**A2. 视频角色 talk 状态(次优先)**
| 步骤 | 内容 | 验收 |
|------|------|------|
| A2.1 | chat 开始:向 video 发 `ChangeScene(config.character.talk_state)` 或等价 trigger | 有 talk 片段则切过去 |
| A2.2 | chat 结束:回 `idle`(或配置的默认态) | 不卡在 talk |
| A2.3 | 无 talk 状态时优雅降级(日志 + 保持当前态,不 500 | 猫狗旧包不炸 |
**A3. 时长与互斥**
| 步骤 | 内容 |
|------|------|
| A3.1 | 优先用回复音频时长驱动 talking 窗口;无音频则字数估算 |
| A3.2 | 对话进行中拒绝二次对话 / 切角色(或排队策略写死一种) |
**负责建议**:内核/HTTP张明远 or 王浩然)+ Live2D/视频(李思琪)
**预估**A1 12 天 · A2 1 天 · A3 0.5 天
---
### WP-B · 设备对齐与回归
| 步骤 | 内容 | 验收 |
|------|------|------|
| B1 | 本机已提交代码同步到设备 `192.168.31.105` | git 一致或 rsync 可追溯 |
| B2 | `cargo check --workspace --all-targets` 零 warning | 贴输出 |
| B3 | `cargo test --workspace` 全绿 | 贴输出 |
| B4 | `systemctl --user restart showen_v2` + BLE ActiveInstances=1 | 服务稳定 |
| B5 | `POST /api/chat/text` 冒烟 | 有 reply_textLive2D 有嘴/字幕 |
---
### WP-C · App 真机验收与修补
| 步骤 | 内容 | 验收 |
|------|------|------|
| C1 | 安装 debug APK配置 `192.168.31.105:5000` | 能连 |
| C2 | 角色页切换 3 套配置 | 画面+人设变 |
| C3 | 文字对话 + 自动播 TTS + 重播 | 有声有字 |
| C4 | 按住说话一轮 | 转写+回复(允许慢) |
| C5 | 模型页列表/切换 | 失败有文案 |
| C6 | 按失败项修 Flutter超时、503、权限 | 不再静默失败 |
**依赖**WP-A 至少完成 A1 后再验“说话联动”。
---
### WP-D · Web 验收与修补
| 步骤 | 内容 |
|------|------|
| D1 | 角色/文字对话/模型三页真机点通 |
| D2 | HTTP 下录音禁用时的固定文案(与 PRD 一致) |
| D3 | 切角色清空会话上下文 |
---
### WP-E · 产品化收尾P1AD 之后)
| 步骤 | 内容 |
|------|------|
| E1 | App 对话历史本地持久化 + 一键清空 |
| E2 | 模型下载进度轮询/失败重试 UX |
| E3 | release APK 签名与安装说明 |
| E4 | M1.2 tag `m1.2`(老板) |
| E5 | 素材:数字人/歌姬 talk/idle外部依赖可并行 |
---
## 3. 推荐执行顺序
```text
Day 0 本计划评审(老板/CEO
Day 1 WP-A1 Live2D talking 接通 + B 设备同步回归
Day 2 WP-A2 视频 talk 降级策略 + A3 互斥
Day 3 WP-C App 真机四旅程 + 修洞
Day 4 WP-D Web 点通 + 文档 STATUS 更新
Day 5+ WP-E 按优先级穿插
```
---
## 4. 技术要点备忘(实现时)
### 4.1 Live2D talking 推荐实现
```
HTTP chat 开始
→ state.set_live2d_talking(true)
→ tx.send(Message::Live2dTalking { on: true }) // 或等价
→ tx.send(Message::Subtitle { text })
Live2DPlugin::handle_message
→ renderer.set_talking(on)
HTTP chat 结束spawn 延迟)
→ set_live2d_talking(false) + Live2dTalking { on: false }
```
避免 Live2D 去轮询 HTTP 内部 AtomicBool跨插件耦合差
### 4.2 视频 talk
```
render_type == video 时:
chat 开始 → PlayerCommand::ChangeScene(talk_state)
chat 结束 → ChangeScene("idle") // 或配置 default_idle
无该 scene 时: 忽略并 log不返回 5xx
```
### 4.3 验证命令(设备)
```bash
ssh -p 2222 showen@192.168.31.105
systemctl --user status showen_v2
curl -sS -m 60 -X POST http://127.0.0.1:5000/api/chat/text \
-H 'Content-Type: application/json' \
-d '{"text":"你好","session_id":"plan_test"}'
# 同时观察 Live2D 嘴部与字幕
```
---
## 5. 风险
| 风险 | 应对 |
|------|------|
| 对话延迟 515s 体感差 | 先保证正确联动;优化单独立项(锁核/更小模型) |
| 宠物包无 talk 片段 | 强制降级,不阻塞 Live2D 路径 |
| 设备与 git 漂移 | B1 强制对齐后再验 |
| 录音权限/机型差异 | App 明确权限引导;失败可走文字 |
---
## 6. 完成检查清单(勾选)
- [ ] Live2D对话时嘴部动画 + 字幕
- [ ] 视频:有 talk 则切 talk无则降级
- [ ] App角色 / 文字 / 语音 / 模型 四旅程通过
- [ ] Web角色 / 文字对话 / 模型通过
- [ ] 设备 `cargo test --workspace` 全绿
- [ ] `docs/STATUS.md` 矩阵更新为与实机一致
- [ ] 可选release APK
---
## 7. 变更记录
| 日期 | 说明 |
|------|------|
| 2026-07-09 | 初稿:联动缺口 + 分 WP 计划;对应 git 提交含骨架与整理 |