Files
live-caption/docs/phase3-caption-window.md
blumia d234b9658d docs: refresh docs to match the current state, add GUI/CLI/troubleshooting
The README still listed the settings UI as "todo" and its quick start told
users to download models into the working directory; phase 3 still described
the caption window's close button as "quit" and used the wrong binary name.
Bring the docs up to date and fill the gaps: a GUI guide (first run, settings
tabs, tray, download, verify), a full CLI option reference marking the
test-only flags, a troubleshooting page, the model registry's size/sha256
fields plus a licence/size table, the RTF measurement caveat (llama-cli 0.19
vs the in-process 0.56), and a note that the streaming-ONNX backend has its
own code path. phase0/phase1 experiment docs are marked as historical.

文档与现状对齐:README 的 Phase 4 从「待做」改为完成、快速开始不再让人把模型下到当前
目录;phase3 的 ✕ 说明改为「隐藏到托盘」、用法改用 live-caption;新增 GUI/CLI/排错三份
文档;asr-backends 补上注册表的 size/sha256 字段与模型许可/体积表;phase0 补上 RTF 口径
说明(llama-cli 的 0.19 与程序内的 0.56);phase2 补上「流式 ONNX 走另一条分支」的说明。
2026-10-12 17:29:45 +08:00

95 lines
6.1 KiB
Markdown
Raw Permalink 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.
# Phase 3:Qt 悬浮字幕窗
状态:**完成**。悬浮窗可用,已接入实时采集 + 流式转写。
(窗口之外的交互 —— 托盘、设置对话框、应用内下载 —— 属于 Phase 4,见
[docs/gui.md](gui.md)。本文记录 Phase 3 当时的形态,并在末尾列出后续变化。)
![折叠态(英文)](images/phase3-en-collapsed.png)
![展开态(英文)](images/phase3-en-expanded.png)
![折叠态(中文)](images/phase3-zh-collapsed.png)
![不透明度 50%](images/phase3-opacity50.png)
## 已实现
- **悬浮窗**:无边框、半透明深色圆角、始终置顶、不接受焦点(`Qt::FramelessWindowHint | WindowStaysOnTopHint | Tool | WindowDoesNotAcceptFocus`),可拖动。
- **折叠 / 展开**:折叠两行、展开八行,底部箭头切换(折叠态 `⌄`、展开态 `⌃`)。
行数可在设置里改(Phase 4)。
- **语言标签**:左上角圆角 pill,显示识别到的语言(英语 / 中文 …);点击发 `languageClicked`
—— Phase 4 起就是用它打开设置对话框。
- **稳定/不稳定区分**:已稳定文本白色,不稳定尾部灰色 —— 与 CLI 版一致,也是 Chrome 那种"字长出来"的观感。
灰色尾部可以用设置里的「用灰色显示尚未稳定的尾部」关掉(Phase 4)。
- **背景**:**黑色 + 可调不透明度**(不是全透明;纯黑底才能保证任何桌面背景下文字都可读)。
默认 84%,范围限制 20~100,设置界面里是可拖的滑块(Phase 4),`--opacity` / `setPanelOpacity()` 也可调。
- **关闭**:右上角 `✕`。Phase 4 起它的行为是**隐藏到托盘**(否则关掉就没法再打开了);
只有在 `--no-tray` 或托盘不可用时才真正退出。
- **实时链路**:采集默认输出的 monitor → 流式转写 → 信号推给窗口,全部在主线程外的工作线程里跑。
## 实时分段
Phase 2 的结论是段不能无限长(解码器对 KV 的注意力随总长增长)。Phase 3 用**静音检测**决定段边界:
- 能量 VAD(噪声底用"快降慢升"的最小值跟踪,见 Phase 1 的教训);
- 检测到语音才开始把音频送进引擎,并保留 250ms 前导避免吃掉词头;
- **静音期间完全不送音频**:早期版本会把静音也喂进模型,模型对静音产生了幻觉(英文语音前冒出一个 `嗯。`);
- 静音超过 0.8s 就收束这一段(提交文本、清空 KV),下一段重新开始。
`--stream-segment`(默认 30s)仍作为兜底上界,设置界面对应「高级 → 单段最长时长」。
## 代码结构
```
src/
├─ captionwindow.{h,cpp} # 悬浮窗
├─ livetranscriber.{h,cpp} # 采集 + VAD + 分段 + 流式引擎(QObject)
├─ streamingasr.{h,cpp} # 流式策略(前缀回滚、切片、分段)
├─ qwen3asr.{h,cpp} # 进程内推理(libllama + libmtmd)
├─ audio.{h,cpp} # WAV 读取 + monitor 采集 + 重采样
└─ transcript.{h,cpp} # 输出解析与语言名映射
```
> 目录后来重排过:`captionwindow` / `livetranscriber` 现在在 `src/ui/`,
> 其余在 `src/core/`,模型管理独立成 `src/models/`。见 [README 的代码结构](../README.md#代码结构)。
## 过程中踩的坑
1. **静音幻觉**:第一版把采集到的静音也喂给了模型,模型对静音产生幻觉,英文语音前面冒出一个 `嗯。`。改为静音期间完全不送音频。
2. **自定义 QWidget 子类的样式表背景不生效**:`CaptionWindow { background-color: rgba(0,0,0,215) }` 这条规则在真实渲染时**根本没画**,面板全透明,只有文字和按钮浮在桌面上。原因是 Qt 不会为自定义 `QWidget` 子类绘制样式表背景(需要 `WA_StyledBackground`,或自己画)。改成在 `paintEvent()` 里用 `QPainter::drawRoundedRect` 画底板 —— 这也是 `WA_TranslucentBackground` 顶层窗口的推荐做法。
3. **验证方法骗了自己**:`QWidget::grab()` 的产物当时是合成到**深灰底色**上看的,「黑色 + 84%」和「全透明」在深色背景上几乎看不出区别,于是把第 2 条盖住了。改成**直接检查像素 alpha**(面板中央应为 `(0,0,0,≈214)`、圆角外应为 `(0,0,0,0)`),并合成到亮色背景上复核。
4. **DPI 警告不关本程序的事**:`setHighDpiScaleFactorRoundingPolicy must be called before creating the QGuiApplication instance` 连 5 行的空白 Qt 程序也会打印 —— 是 Deepin 会话环境设了 `QT_SCALE_FACTOR_ROUNDING_POLICY` 导致的。
## 用法
```bash
# 悬浮窗程序(图形界面,Phase 4 起带托盘与设置)
./build/live-caption
# 调整背景不透明度(20-100)—— 这是 GUI 程序的选项
./build/live-caption --opacity 60
# 无窗口、纯命令行实时(便于在无显示环境调试)
./build/live-caption-cli --asr-backend sherpa --asr-model zipformer-zh-2025 --cli-live
# 自截图(验证渲染,不依赖外部截图工具);会依次截折叠态与展开态
./build/live-caption --asr-backend sherpa --asr-model zipformer-zh-2025 \
--no-tray --screenshot out.png --screenshot-delay 12
```
> 自截图产物带 alpha 通道;要判断不透明度是否正确,**直接看像素 alpha**,不要靠肉眼看合成效果。
> 所有选项见 [docs/cli.md](cli.md)。
## Phase 3 之后的变化(Phase 4)
- ✕ 从「退出」改成「隐藏到托盘」,并加了托盘图标与菜单;
- 语言标签点击 → 打开设置对话框(模型下载/选择、语言、显示、采集设备、下载源与代理、校验);
- 背景不透明度、字号、行数、灰色尾部、窗口位置全部进了设置界面并持久化(`QSettings`);
- **采集设备可选**(原来固定跟随启动时的默认输出,切到 HDMI 不会跟着变);
- 细节见 [docs/gui.md](gui.md)。
## 已知限制 / 后续
- X11 下置顶与定位都正常;Wayland 下需要 layer-shell,属于 Phase 5(见 [docs/troubleshooting.md](troubleshooting.md))。
- 界面尚未做 HiDPI 之外的适配(当前主屏宽度 72%、最大 900 逻辑像素)。