6c04071bb5837aed10fa76cc7c60a460a0eab9fd
These were command-line only. Add them to the settings dialog so the whole feature set is reachable without arguments: stream mode, window limit, segment limit, prefix-rollback token count, cold-start chunk count, max tokens per step, thread count, verbose logging and the model directory. The streaming group is grouped and greyed out for streaming-ONNX models, which only use the commit granularity. The backend fingerprint now includes them, so changing one restarts the recogniser; appearance changes still apply live. Also add a test-only --settings-tab so a specific page can be screenshotted. 设置「高级」页补上原来只有命令行才有的选项:流式策略/滑窗上限/单段最长/前缀回滚 token 数/冷启动 chunk 数/单段最多生成 token/线程数/详细日志/模型目录。流式那一组 单独成组,选了流式 ONNX 模型时置灰(它们只用「更新粒度」)。这些值纳入「后端指纹」, 改动会重启识别后端;外观类改动仍然即时生效。另加测试用 --settings-tab 以便给单个 页签截图。
live-caption
Linux 桌面实时字幕:采集系统正在播放的声音,实时转写成字幕显示(类似 Chrome 实时字幕)。
技术栈:C++ / Qt6 / CMake。推理后端两个,全部纯 C++,运行时不需要 Python:
llama:llama.cpp / ggml + Qwen3-ASR 的 GGUF 模型(准确率高、语言最全);sherpa:sherpa-onnx + 流式 ONNX 模型(zipformer / X-ASR / Nemotron,原生流式、CPU 占用低)。
当前进度
| 阶段 | 内容 | 状态 |
|---|---|---|
| Phase 0 | 可行性验证(采集 / 模型 / CPU 实时性) | ✅ 见 docs/phase0-verification.md |
| Phase 1 | 命令行原型(进程内推理 + monitor 采集 + 滑窗 + 稳定前缀) | ✅ 见 experiments/phase1/README.md |
| Phase 2 | 原生流式解码(切片 + 增量 KV 复用 + 前缀回滚) | ✅ 见 docs/phase2-streaming.md |
| Phase 3 | Qt 悬浮字幕窗(折叠/展开、语言标签、置顶、实时链路) | ✅ 见 docs/phase3-caption-window.md |
| Phase 3.5 | 双后端(llama / sherpa)+ 模型注册表 + 流式 ONNX | ✅ 见 docs/asr-backends.md |
| Phase 4 | 全 GUI 可用:设置对话框、应用内下载、托盘、采集设备、完整性校验 | ✅ 见 docs/gui.md |
| Phase 5 | Wayland 支持、打包、模型分发 | 部分(模型下载/分发已可用,见上) |
关键结论(Phase 0 实测)
- 系统播放音频可从默认输出的 monitor 源采集(PipeWire + pipewire-pulse,走 libpulse,兼容 PulseAudio)。
Qwen3-ASR-0.6B在本机(i5-13420H,无独显)纯推理 RTF ≈ 0.19,实时有充足余量。 注意口径:这是llama-cli纯生成的数字;程序内走 mtmd 音频编码的实现实测 RTF ≈ 0.56 (见 docs/asr-backends.md 的实测对比)。两者都远低于 1.0,够实时。- 模型与推理运行时必须锁版本:只有 ggml-org 官方 GGUF(
general.architecture = qwen3vl)与系统 llama.cpp 兼容;社区的 Q4 量化用的是qwen3asr/qwen3_asr,装不进去。 - 转写原始输出为
language <LANG><asr_text><正文>,语言名正好用于 UI 的语言标签。
快速开始
# 1. 构建
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
# 2. 悬浮字幕窗:首次启动会打开设置对话框,在里面下载并选择模型
./build/live-caption
# 完全通过 GUI 操作:
# · 首次启动 → 设置对话框:下载模型 / 选择当前使用 / 选识别语言 / 采集设备 / 下载源与代理
# · 点左上角的语言标签 → 再次打开设置
# · 底部的「应用」= 应用但不关闭,方便实时预览(不透明度、字号等)
# · 「校验完整性」= 重算 sha256,确认模型文件没有损坏
# · 托盘图标:显示/隐藏字幕、设置、退出
# · 窗口的 ✕ = 隐藏到托盘(用托盘菜单可以再显示回来)
# 命令行参数仍保留,仅用于自动化测试(显式给出时覆盖设置),全部选项见 docs/cli.md
# 3. 也可以先用脚本把模型下到应用数据目录(不进 GUI)
./scripts/fetch-models.sh # 列出模型与安装状态
./scripts/fetch-models.sh zipformer-zh-2025 # 下载指定模型
# 4. 命令行:单文件转写 / 流式转写 / 无窗口实时
./build/live-caption-cli --model M --mmproj MM --file some_16k_mono.wav
./build/live-caption-cli --model M --mmproj MM --stream-file some_16k_mono.wav
./build/live-caption-cli --asr-backend sherpa --asr-model zipformer-zh-2025 --cli-live
# 5. 单元测试(不需要模型,也不需要显示环境)
ctest --test-dir build --output-on-failure
推理后端
支持两条后端,正常情况下不用手动选:GUI 会根据所选的模型自动决定用哪条
(data/models.json 里每个模型都写了 backend)。命令行下可以用 --asr-backend 强制指定
(详见 docs/asr-backends.md):
llama(默认):llama.cpp/ggml + Qwen3-ASR 的 GGUF 模型 —— 准确率高、52 种语言,但每步成本随段落增长。sherpa:sherpa-onnx + 流式 ONNX 模型(X-ASR / zipformer / Nemotron)—— 原生流式,每步成本恒定,CPU 约为前者的 1/35,中英准确率持平。
模型都放在 ~/.local/share/live-caption/models/<id>/,注册表是 data/models.json
(加模型只加一条数据,不改代码)。GUI 里可以直接下载(支持设置下载源与代理、断点续传、
sha256 校验),命令行下也可以用 scripts/fetch-models.sh。
# 流式后端
./build/live-caption-cli --asr-backend sherpa --asr-model zipformer-zh-2025
./build/live-caption-cli --asr-backend sherpa --asr-model nemotron35-560ms --language ja
# 辅助
./build/live-caption-cli --list-devices # 列出可选采集设备
./build/live-caption-cli --cli-live --device <sink> # 指定采集源
./build/live-caption-cli --verify-model zipformer-zh-2025 # 校验模型完整性
代码结构
src/core/ → liblivecaption_core(静态库,**不依赖 Qt**)
iasr.h 推理后端抽象(便于用假实现测流式策略)
transcript.{h,cpp} 输出解析、语言名映射
audio.{h,cpp} monitor 采集 / 输出设备枚举 / WAV 读取 / 重采样
qwen3asr.{h,cpp} 进程内推理(libllama + libmtmd)
sherpaasr.{h,cpp} sherpa-onnx C API 适配(流式 ONNX)
streamingasr.{h,cpp} 流式策略(切片复用 / 前缀回滚 / 原生流式分支)
vad.h 能量 VAD
livepipeline.{h,cpp} 实时管线:采集→VAD→分段→流式转写
src/models/ → liblivecaption_models(静态库,Qt6::Core/Network)
modelstore.{h,cpp} 注册表解析、安装检查、sha256 校验
modeldownloader.{h,cpp} 应用内下载(镜像 / 代理 / 断点续传 / 进度)
src/ui/ → liblivecaption_ui(静态库,Qt6::Widgets)
captionwindow.{h,cpp} 悬浮字幕窗
settingsdialog.{h,cpp} 设置对话框
appsettings.{h,cpp} QSettings 配置
livetranscriber.{h,cpp} LivePipeline 的 Qt 适配器(只转信号)
apps/gui/ → live-caption (悬浮窗 + 托盘 + 设置)
apps/cli/ → live-caption-cli (命令行程序,只链 Qt6::Core)
apps/common/ 两个程序共用的命令行选项与后端工厂
data/models.json 模型注册表(编译进二进制,加模型=加一条数据)
tests/ 单元测试(QtTest,只链 core)
scripts/fetch-models.sh 命令行下载模型
experiments/ Phase 0/1 的验证脚本
拆分的意义:业务逻辑全在 core 且不依赖 Qt,所以流式策略、VAD、输出解析这些最容易出错的部分可以脱离真模型和显示环境做单元测试;模型管理单独一层,GUI 与 CLI 各自独立演进,CLI 也不再需要链接 Qt Widgets。
文档
| 文档 | 内容 |
|---|---|
| docs/gui.md | 图形界面:首次配置、设置项说明、托盘、下载与校验 |
| docs/cli.md | 全部命令行选项(含仅测试用的那些) |
| docs/asr-backends.md | 双后端结构、模型注册表、实测对比、语言推荐 |
| docs/troubleshooting.md | 常见问题(窗口不见了、模型没下全、Wayland 置顶…) |
| docs/testing.md | 测试分层、回归用例、GUI 交互测试钩子 |
| docs/phase0-verification.md | Phase 0 可行性验证报告 |
| docs/phase2-streaming.md | Phase 2 流式解码 |
| docs/phase3-caption-window.md | Phase 3 悬浮字幕窗 |
Languages
C++
89%
CMake
6.6%
Shell
3.6%
Python
0.8%