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

6.5 KiB
Raw Blame History

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 有字幕 Subtitlelive2d_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. 推荐执行顺序

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 验证命令(设备)

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 提交含骨架与整理