Files
live-caption/README.md
T
blumia 8b9a8c420e chore(pack): add CPack configuration to build a deb package
Add install rules and CPack settings so cpack produces an installable
.deb. Dependencies are derived with dpkg-shlibdeps, so they follow the
binaries. The sherpa-onnx runtime the streaming backend needs is bundled
because no distro package provides it. The fetch-models script now also
locates its registry when installed system-wide.

增加 CPack 配置,可直接用 cpack 打出 deb:安装规则含桌面入口、应用图标、
模型注册表与下载脚本、用户文档;依赖由 dpkg-shlibdeps 自动推导;流式后端
需要的 sherpa-onnx 运行时(发行版无对应包)随包携带;fetch-models 脚本
装到系统后也能找到注册表。
2026-10-13 11:53:07 +08:00

8.6 KiB
Raw Blame History

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     模型注册表(编译进二进制,加模型=加一条数据)
data/live-caption.desktop / .svg    桌面入口与应用图标
data/deb/            deb 的 postinst / postrm(刷新应用菜单与图标缓存)
cmake/Packaging.cmake  安装规则与 CPack 配置(打 deb)
tests/               单元测试(QtTest,只链 core)
scripts/fetch-models.sh  命令行下载模型(装到系统后叫 live-caption-fetch-models)
experiments/         Phase 0/1 的验证脚本

拆分的意义:业务逻辑全在 core 且不依赖 Qt,所以流式策略、VAD、输出解析这些最容易出错的部分可以脱离真模型和显示环境做单元测试;模型管理单独一层,GUI 与 CLI 各自独立演进,CLI 也不再需要链接 Qt Widgets。

打包成 deb

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
(cd build && cpack)                    # → build/live-caption_<版本>-<修订>_<架构>.deb
sudo apt install ./build/live-caption_*.deb

依赖由 dpkg-shlibdeps 从二进制自动推导;流式 ONNX 后端需要的 sherpa-onnx 运行时 (发行版没有对应包)默认随包携带。细节与可调选项见 docs/packaging.md。

文档

文档 内容
docs/gui.md 图形界面:首次配置、设置项说明、托盘、下载与校验
docs/cli.md 全部命令行选项(含仅测试用的那些)
docs/asr-backends.md 双后端结构、模型注册表、实测对比、语言推荐
docs/packaging.md 用 CPack 打 deb:包内容、依赖、RPATH、可调选项
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 悬浮字幕窗