Files
life-echo/docs/plans/2026-03-26-tts-interrupt-read-aloud-design.md
2026-03-26 14:32:30 +08:00

3.8 KiB
Raw Permalink Blame History

TTS 打断、朗读态与重复朗读 — 设计定稿

日期: 2026-03-26
范围: Expo 对话页;后端已具备 TTS 上传与 URL 落库,本设计侧重客户端与可选协议增强。


1. 目标

  • 打断B 开始录音时立即停止 TTS 并清空待播队列。
  • 打断C 在「自动 TTS 正在播放」时,点击助手文本气泡区域停止朗读。
  • 区分纯文本: 正在朗读时,助手气泡有明确视觉态(描边/底 + 行内「朗读中」或扬声器动效)。
  • 重复朗读: 对已落库且带有 COS URL 列表的助手消息,可再次按序播放,不重新合成(见第 4 节)。

手势分工: 气泡空白区域在播放中 = 停止;独立「朗读 / 再读」控件 = 开始或重播,避免与「点一下停」冲突。


2. 后端现状(方案 C 已具备)

  • Segment / ConversationMessage 均有 tts_audio_urlsJSON 数组)。
  • pipeline._send_tts_audio 上传 COS 后返回 URL回合结束 attach_ai_tts_audio_urls 写库。
  • 历史/API 已透出 ttsAudioUrlscamelCase

重复朗读策略: 客户端从消息读取 ttsAudioUrls,按顺序 enqueue;无需新增「按文本重合成」接口作为默认路径。


3. 客户端缺口与数据模型

3.1 MessageItem

  • 增加可选字段:ttsAudioUrls?: string[](与后端一致)。
  • 从 REST / React Query 缓存映射时填入;无数组或为空则隐藏「朗读」或置灰。

3.2 PlaybackItemuse-player / features/voice/types

  • 扩展:kind: 'tts_auto' | 'tts_repeat' | 'voice'(或保留 label 并规范化)。
  • messageRef?: { listKey: string }(或 messageId),用于高亮对应气泡。
  • 入队时:自动 TTS 片段写入 kind: 'tts_auto' + 当前助手消息引用(若能从会话层解析);手动「再读」写入 kind: 'tts_repeat' + 该条 listKey

3.3 RealtimeSession / WS

  • TtsSegmentPayload 携带 index / total(类型已存在,需从 client 映射到回调)。
  • 理想情况:后端在 tts_audio 中增加 assistant_message_id(或与 segment 对齐的 id便于客户端稳定绑定「哪一条在播」。未上字段前: 流式阶段可仅用「当前 streaming 轮次」+ 全局条提示;落库后以 messageId + ttsAudioUrls 为准。

4. 打断与串播

  • stop() 已在 usePlayer;在开始录音成功后调用 stop(),保证队列清空(除 audioFocus 外,逻辑上立即静音)。
  • 服务端后续片段: 若用户已 stop() 仍收到 tts_audio,可能再次入队。推荐客户端维护 ttsPlaybackGeneration(打断时自增),仅处理与当前 generation 匹配的片段;或后续增加 tts_cancel WS 与 pipeline 短路(可选)。

5. UI 要点

  • 助手文本气泡:内联「朗读」按钮(图标 + a11y 文案);播放中可显示为停止或与气泡点击一致。
  • 播放中:气泡弱高亮 + 「朗读中…」;流式未结束时可对 streaming 区使用同一套样式。
  • 与用户语音条:沿用 Play/Pause 或扬声器语义,降低认知成本。

6. 错误与测试

  • ttsAudioUrls 提示「暂无法朗读」或隐藏按钮。
  • 单测: stop() 后队列为空generation 丢弃旧片段(若实现)。
  • 手测: 录音打断、点气泡停止、自动播完后高亮消失、用历史 URL 重播同一条。

7. 实施顺序建议

  1. 类型与 API 映射:ttsAudioUrlsMessageItem
  2. PlaybackItem + usePlayer 入队参数TTS 回调写入 messageRef(力所能及)。
  3. 录音与气泡 Pressable 调用 stop() / generation。
  4. 助手气泡 UI朗读按钮 + 朗读中高亮。
  5. 可选WS tts_cancelassistant_message_id