语音唤醒与按压说话

模式

  • 语音唤醒模式(默认):始终开启的语音识别器等待触发词(swabbleTriggerWords)。在匹配后开始录音,显示部分文本的覆盖层,并在静音后自动发送。
  • 按压说话模式(按住右 Option 键):按住右 Option 键立即开始录音——无需触发词。按住时显示覆盖层;释放后经过短暂延迟进行最终处理,以便你调整文本。

运行时行为(语音唤醒)

  • 语音识别器位于 VoiceWakeRuntime 中。
  • 只有在语音唤醒词和下一个词之间有有意义的停顿(约 0.55 秒)时,触发才会生效。即使在命令开始前,停顿期间也可以启动覆盖层/提示音。
  • 静音窗口:语音流动时为 2.0 秒,仅听到唤醒词时为 5.0 秒。
  • 强制停止:120 秒以防止会话失控。
  • 会话之间的防抖:350 毫秒。
  • 覆盖层由 VoiceWakeOverlayController 控制,支持已提交/临时颜色。
  • 发送后,识别器会干净地重新启动,以监听下一个触发词。

生命周期不变性

  • 如果语音唤醒功能已启用且权限已授予,语音唤醒识别器应始终处于监听状态(除非正在进行显式的按压说话录音)。
  • 覆盖层的可见性(包括通过 X 按钮手动关闭)绝不能阻止识别器重新开始监听

粘性覆盖层失败模式(旧版)

以前,如果覆盖层卡在可见状态,并且用户手动关闭了它,语音唤醒可能会看起来“无响应”,因为运行时的重启尝试可能被覆盖层可见性阻塞,且没有后续的重启计划。

加固措施:

  • 语音唤醒运行时的重启不再受覆盖层可见性限制
  • 覆盖层关闭完成后,通过 VoiceSessionCoordinator 触发 VoiceWakeRuntime.refresh(...),因此手动关闭 X 按钮始终会恢复监听

按压说话的具体细节

  • 热键检测使用全局的 .flagsChanged 监听器来检测右 Option 键keyCode 61 + .option)。我们只观察事件(不拦截)。
  • 录音流程位于 VoicePushToTalk 中:立即开始语音识别,将部分文本流式传输到覆盖层,并在释放时调用 VoiceWakeForwarder
  • 当按压说话开始时,我们会暂停语音唤醒运行时,以避免音频冲突;释放后会自动重新启动。
  • 权限要求:需要麦克风和语音权限;监听事件还需要辅助功能/输入监控的批准。
  • 外部键盘:某些键盘可能无法正确识别右 Option 键——如果用户报告无法触发,应提供备用快捷键。

用户设置

  • 语音唤醒 开关:启用唤醒词功能。
  • 按住 Cmd+Fn 键说话:启用按压说话模式。在 macOS 版本低于 26 时禁用。
  • 语言和麦克风选择器、实时音量指示器、唤醒词表格、测试器(仅本地使用;不进行转发)。
  • 麦克风选择器在设备断开时会保留上次的选择,显示断开提示,并临时切换回系统默认麦克风,直到设备重新连接。

  • 声音:在检测到唤醒词和发送时会有提示音;默认使用 macOS 的“Glass”系统声音。你可以为每个事件选择任何可由 NSSound 加载的文件(例如 MP3/WAV/AIFF),或选择 无声音

转发行为

  • 当启用语音唤醒时,转录内容会转发到当前活动的网关/代理(与 macOS 应用程序其余部分使用的本地或远程模式相同)。
  • 回复会发送到 最后一次使用的主服务提供商(WhatsApp/Telegram/Discord/WebChat)。如果发送失败,会记录错误,但通过 WebChat/会话日志仍可查看运行记录。

转发内容

  • VoiceWakeForwarder.prefixedTranscript(_:) 在发送前会添加机器提示信息。该功能在唤醒词和按住说话两种路径中共享。