Files
openclaw/docs/zh-CN/platforms/mac/voice-overlay.md
2026-02-02 16:38:25 +01:00

68 lines
3.9 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.

---
read_when:
- 调整语音浮层行为
summary: 唤醒词与按键说话重叠时的语音浮层生命周期
title: 语音浮层
x-i18n:
generated_at: "2026-02-01T21:33:26Z"
model: claude-opus-4-5
provider: pi
source_hash: 3be1a60aa7940b2368ff62cd49f04b2b8422876030e8ea206b467f66a5a6bd4d
source_path: platforms/mac/voice-overlay.md
workflow: 15
---
# 语音浮层生命周期macOS
受众macOS 应用贡献者。目标:在唤醒词与按键说话重叠时保持语音浮层行为可预测。
### 当前意图
- 如果浮层已因唤醒词显示,此时用户按下热键,热键会话会*接管*现有文本而非重置。浮层在热键按住期间保持显示。用户松开时:如果有去除空白后的文本则发送,否则关闭。
- 单独使用唤醒词时仍在静音后自动发送;按键说话在松开时立即发送。
### 已实现2025 年 12 月 9 日)
- 浮层会话现在为每次捕获(唤醒词或按键说话)携带一个令牌。当令牌不匹配时,部分/最终/发送/关闭/音量更新会被丢弃,避免过时回调。
- 按键说话会接管任何可见的浮层文本作为前缀(因此在唤醒浮层显示时按下热键会保留文本并追加新语音)。它最多等待 1.5 秒获取最终转录结果,然后回退到当前文本。
- 提示音/浮层日志以 `info` 级别输出,分类为 `voicewake.overlay``voicewake.ptt``voicewake.chime`(会话开始、部分、最终、发送、关闭、提示音原因)。
### 后续步骤
1. **VoiceSessionCoordinatoractor**
- 同一时间只拥有一个 `VoiceSession`
- API基于令牌`beginWakeCapture``beginPushToTalk``updatePartial``endCapture``cancel``applyCooldown`
- 丢弃携带过时令牌的回调(防止旧识别器重新打开浮层)。
2. **VoiceSession模型**
- 字段:`token``source`wakeWord|pushToTalk、已提交/临时文本、提示音标志、计时器(自动发送、空闲)、`overlayMode`display|editing|sending、冷却截止时间。
3. **浮层绑定**
- `VoiceSessionPublisher``ObservableObject`)将活跃会话镜像到 SwiftUI。
- `VoiceWakeOverlayView` 仅通过 publisher 渲染;绝不直接修改全局单例。
- 浮层用户操作(`sendNow``dismiss``edit`)携带会话令牌回调到 coordinator。
4. **统一发送路径**
- `endCapture` 时:如果去除空白后文本为空 → 关闭;否则 `performSend(session:)`(播放一次发送提示音、转发、关闭)。
- 按键说话:无延迟;唤醒词:可选自动发送延迟。
- 按键说话结束后对唤醒运行时施加短暂冷却,防止唤醒词立即重新触发。
5. **日志**
- Coordinator 在子系统 `bot.molt`、分类 `voicewake.overlay``voicewake.chime` 下输出 `.info` 级别日志。
- 关键事件:`session_started``adopted_by_push_to_talk``partial``finalized``send``dismiss``cancel``cooldown`
### 调试清单
- 复现浮层粘滞问题时流式查看日志:
```bash
sudo log stream --predicate 'subsystem == "bot.molt" AND category CONTAINS "voicewake"' --level info --style compact
```
- 验证只有一个活跃会话令牌;过时回调应被 coordinator 丢弃。
- 确保按键说话松开时始终使用活跃令牌调用 `endCapture`;如果文本为空,预期 `dismiss` 且不播放提示音或发送。
### 迁移步骤(建议)
1. 添加 `VoiceSessionCoordinator`、`VoiceSession` 和 `VoiceSessionPublisher`。
2. 重构 `VoiceWakeRuntime`,使其创建/更新/结束会话,而非直接操作 `VoiceWakeOverlayController`。
3. 重构 `VoicePushToTalk`,使其接管现有会话并在松开时调用 `endCapture`;施加运行时冷却。
4. 将 `VoiceWakeOverlayController` 连接到 publisher移除来自 runtime/PTT 的直接调用。
5. 添加会话接管、冷却和空文本关闭的集成测试。