按住说话的秘密:Jarvis AI Assistant的Push-to-Talk语音链路全解析

发布时间:2026/11/5 1:45:46
按住说话的秘密:Jarvis AI Assistant的Push-to-Talk语音链路全解析

【免费下载链接】jarvis-ai-assistant

Jarvis AI Assistant - Voice-powered AI assistant for Mac

项目地址:https://gitcode.com/gh_mirrors/jarvis/jarvis-ai-assistant
点击查看免费下载

Jarvis AI Assistant 是一款面向 Mac 的开源语音输入 AI 助手,它的核心玩法只有一个词:Push-to-Talk(按住说话)。按住Fn键开始说话,松开按键,一段干净、带标点的文字就会自动出现在你正在使用的任何输入框里——邮件、备忘录、代码编辑器都支持。整个过程通常只需一两秒。这篇文章带你拆解这条"按住 Fn 键 → 语音转文字 → 自动粘贴"的完整语音链路,看看它的速度从哪里来、每一环由哪个模块负责。

语音链路全景:一次按键触发的 5 个环节

在深入细节前,先建立整体认知。每次你按住并松开Fn键,Jarvis 内部会依次完成 5 件事:

  1. 按键监听——原生模块全局捕获Fn键的按下与抬起事件;
  2. 即时录音——按下瞬间就开始采集麦克风音频,零启动延迟;
  3. 语音转文字——根据设置走流式、滚动解码或传统整段转录三条路径之一;
  4. 智能后处理——先判断是否为语音命令,再做上下文感知的文本净化与格式化;
  5. 自动粘贴——把最终文字以最低延迟填入当前焦点窗口。

整条链路的总调度者是 PushToTalkOrchestrator,它把录音、转录、状态、输出等模块编排成一个协作流水线。对外则通过 PushToTalkService 暴露start()/stop()/cancel()三个简洁接口。

第一环:全局按键监听,让 Fn 键"按住即录"

Fn这类修饰键在普通应用里很难被可靠地全局捕获,Jarvis 的做法是绕开 JavaScript 层,直接下沉到系统底层:

  • 原生事件监听:fn_key_monitor.mm 用 Objective-C 编写,基于 macOS 的 CGEventTap 事件钩子,监听kCGEventFlagMaskSecondaryFn标志位的变化。按键状态一旦翻转,就向主线程回调FN_KEY_DOWN/FN_KEY_UP事件,从硬件到 JS 回调的路径极短,避免了轮询带来的延迟。
  • 按键可配置:监听器并非写死Fn。universal-key-service.ts 支持把热键换成Option、Control等,按下/抬起事件最终汇入 main.ts 中的handleHotkeyDown()与handleHotkeyUp()。
  • 权限校验:原生模块启动前会调用AXIsProcessTrusted()检查辅助功能权限——这也是新手最常踩的坑:如果按住Fn毫无反应,先去"系统设置 → 隐私与安全性 → 辅助功能"里勾选 Jarvis。

按键按下后,handleHotkeyDown()会先亮界面、再启录音:波形窗口showInactive()、各窗口广播push-to-talk-state-change事件,让你在按下瞬间就获得视觉与听觉反馈,录音的异步启动紧随其后。

第二环:零延迟录音,按下就开始采集

录音环节由 AudioSessionManager 负责,核心设计有两条:

  • 首选原生采集:优先使用 native-audio-recorder.ts 的 macOS 原生录音通道,不依赖外部 FFmpeg 二进制;一旦原生失败才回退到 fast-audio-recorder.ts。
  • 边录边送:录制并不只是把音频攒进缓冲区。startRecording()会传入一个 chunk 回调,每一小块 PCM16 音频数据被捕获后立刻转发给当前启用的流式转录后端——也就是说,你说话的同时,转录其实已经在后台悄悄进行。

PushToTalkOrchestrator 的start()里还藏着一个细节:录音启动的同时,用setImmediate把"上下文检测"(识别你当前在 Gmail、Slack 还是终端)和"流式初始化"丢进后台执行,不让它们占用主路径的任何一毫秒。

第三环:松开按键后,转录走的三条路径

stop()被触发时(也就是你松手的那一刻),系统会根据设置分流,这是"快"字的最大秘密所在:

路径一:流式转录(Streaming Flow)

启用 Deepgram 实时流式或本地流式模型(sherpa-online-transcriber.ts)时,音频块在录制期间就已被逐块喂给识别器并积累了部分文本。松手时如果已经攒到内容,Orchestrator 直接走"超快路径":跳过等待、跳过 finalize,文本几乎是松手即出的。

路径二:滚动解码(Rolling Decode)

使用本地 Parakeet 模型时,TranscriptionSessionManager 会启动"滚动解码":录音过程中每攒够一段音频就在后台安全识别器上并行解码。等你松开Fn时,大部分音频早已转完,只需补译最后一段尾巴。总耗时从"说话时长 + 解码时长"变成了两者的最大值,长文本体验提升尤其明显。

路径三:传统整段转录

关闭流式时走最稳妥的整段路径:停止录音、拿到完整AudioSessionData,交给 FastAssistantTranscriber 统一调度。它支持云端 Deepgram / GPT-4o,也支持完全离线的本地 Whisper 与 NVIDIA Parakeet(via Sherpa-ONNX),模型清单分别见 local-whisper-transcriber.ts 与 sherpa-models.ts。该构造器还会在启动时预热 API Key 与本地词典,避免"第一次说话特别慢"的尴尬。

三条路径最终都收敛为同一个TranscriptionResult结构,定义在 push-to-talk-types.ts,后两级处理因此与具体模型完全解耦。

第四环:命令识别与上下文感知后处理

转录结果不会直接粘贴,它先要过两道"安检":

  • 命令识别(command-processor.ts):先判断你这句话是不是指令。比如"打开 YouTube""设一个 5 分钟计时器"这类 Jarvis 命令或应用启动命令会被拦截执行,直接结束会话;命中助手提示词时则交给 assistant-processor.ts 生成回答。
  • 文本后处理(text-processor.ts):普通口述内容进入上下文感知后处理——检测到你在写邮件时会走专门的邮件格式通道(首字母大写、收尾句号、称呼落款),其他场景则按 AI 后处理开关决定是否清理"嗯、那个"等口水词并修正语法。

值得注意的是,上下文(比如"当前在 Gmail")在按下按键的当时就已经在后台探测完毕并缓存好了,松手时直接用,不再产生额外等待。

第五环:自动粘贴,文字落在任意输入框

最后一棒由 OutputManager 交出,真正的粘贴逻辑在 text-paster.ts。它按文本长度与场景自动选择fast(剪贴板直贴)、clipboard或keystroke(逐字符键入)等输出方式,并在 10 秒内连续多次口述时智能补空格,让多段语音拼成自然连贯的段落。每次输出都会记录"松手 → 文字出现"的端到端耗时,这也是项目持续优化的底气来源。

常见问题:为什么我的语音输入没反应或很慢?

Q:按住 Fn 没有任何反应?99% 的情况是缺少辅助功能权限。原生监听器在启动时会调用权限检查并明确报错,请到"系统设置 → 隐私与安全性 → 辅助功能"添加 Jarvis 后重启应用。

Q:第一次说话感觉慢,之后变快了?转录器在应用启动时就做了服务预热(API Key 预取、词典加载、本地模型热身),后续会话的冷启动开销被大幅摊薄。

Q:断网还能用吗?可以。选择本地 Whisper 或 Parakeet 模型后即可 100% 离线转录,整条链路不离开本机。

Q:如何让文字出来得更快?开启流式转录,或切换到支持滚动解码的 Parakeet 本地模型——说话的同时就完成大部分转写,松手几乎是"秒出"。

写在最后

Jarvis AI Assistant 的"按住说话"之所以顺滑,本质是把传统"录完 → 传完 → 等结果"的串行流程,重排成了"边说边转、后台并行、松手即贴"的流水线:按键事件走原生通道、录音零延迟启动、转录提前开始、上下文预先探测、粘贴按场景择优。如果你也在寻找一款支持本地模型、开源免费的 Mac 语音输入工具,这条链路的设计值得你亲自按住Fn键体验一下。

【免费下载链接】jarvis-ai-assistant

Jarvis AI Assistant - Voice-powered AI assistant for Mac

项目地址:https://gitcode.com/gh_mirrors/jarvis/jarvis-ai-assistant
点击查看免费下载

相关推荐

上一篇:Kornia Boxes3D.from_tensor "xyzwhd" 模式修复解析:非对称 3D 框宽高深字段序保真与几何约定
下一篇:Dopamine 中的 AcrobotFourierDQNNetwork:基于 Fourier 基的线性 DQN 价值网络解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考