Three settings were only half-wired: - autoPickByLanguage was saved but never read anywhere: delete it. - showUnstableTail had a checkbox and a setter, but nothing ever called the setter, so the checkbox did nothing: apply it in applyAppearance and re-render from the cached text instead of blanking the caption. - the language dropdown was hard-coded to auto/zh/en/ja while the registry declares up to 16 languages per model: build it from the selected model's own language list, with an ISO-code to display-name mapping (plus a unit test covering every code in the registry). The caption window's language pill now follows the setting too, instead of keeping whatever it showed at startup. windowPos is not dead -- it stores the dragged window position -- so it stays. 三个「半死」设置:autoPickByLanguage 存了但从没被读取,直接删掉;showUnstableTail 有复选框也有 setter,但从来没人调用 setter(复选框点了没用),改为在 applyAppearance 里生效并用缓存文本重画;「识别语言」下拉原来硬编码 自动/中/英/日,而注册表里每个模型 声明了最多 16 种语言,改为按所选模型的语言动态生成,并补 ISO 码→显示名映射与单元测试。 字幕窗的语言标签也跟着设置走了(原来只在启动时读一次)。windowPos 不是死设置(它存的 是拖动后的位置),保留。
154 lines
7.3 KiB
Markdown
154 lines
7.3 KiB
Markdown
# 图形界面(Phase 4)
|
||
|
||
`live-caption` 是图形界面程序:悬浮字幕窗 + 系统托盘 + 设置对话框。
|
||
**不用任何命令行参数就能完整使用**;命令行参数只保留给自动化测试(显式给出时覆盖设置)。
|
||
|
||
## 首次运行
|
||
|
||
首次启动时如果还没有「已下载且被选中」的模型,程序会先弹出**设置对话框(标题为
|
||
「实时字幕 — 首次配置」)**,并挡住主流程 —— 下载一个模型、在「当前使用」里选中它,
|
||
点「确定」之后才会出现字幕窗。
|
||
|
||
```
|
||
第一次启动 → 设置对话框 → 下载模型 → 选择「当前使用」 → 确定 → 悬浮字幕窗
|
||
```
|
||
|
||
## 字幕窗
|
||
|
||
| 操作 | 行为 |
|
||
|---|---|
|
||
| 拖动 | 移动窗口;位置会被记住 |
|
||
| 左上角语言标签 | 点击 → 打开设置对话框 |
|
||
| 底部箭头 `⌄` / `⌃` | 折叠(2 行)/ 展开(8 行) |
|
||
| 右上角 `✕` | **隐藏到托盘**(不是退出;用托盘菜单可以再显示回来) |
|
||
|
||
窗口的文本分两段显示:**已稳定**部分是白色,**尚未稳定**的尾部是灰色。这就是 Chrome
|
||
实时字幕那种「字一个个长出来、末尾会改」的观感。
|
||
|
||
> 没有托盘时(`--no-tray`,或桌面环境不支持托盘)`✕` 会直接退出程序。
|
||
|
||
## 托盘
|
||
|
||
托盘菜单有三项:
|
||
|
||
- **显示/隐藏字幕**
|
||
- **设置…**
|
||
- **退出**
|
||
|
||
单击托盘图标也会切换字幕窗的显示/隐藏。
|
||
|
||
## 设置对话框
|
||
|
||
三个页签(模型 / 显示 / 高级),底部三个按钮:
|
||
|
||
| 按钮 | 行为 |
|
||
|---|---|
|
||
| **应用** | 应用设置但**不关闭**对话框 —— 方便实时预览(改不透明度、字号时立刻能看到效果) |
|
||
| 取消 | 放弃本次改动(已经用「应用」生效过的改动不会被回滚) |
|
||
| 确定 | 应用并关闭 |
|
||
|
||
**哪些改动要重启识别后端?** 只有**模型 / 识别语言 / 采集设备**,以及高级页里的**流式参数、
|
||
线程数、模型目录**变化时才会重建后端并重启转写;透明度、字号、行数、灰色尾部这类外观改动是
|
||
即时生效的,不会打断正在进行的转写。
|
||
|
||
### 模型页
|
||
|
||
- **模型表格**:列出注册表里的所有模型(名称 / 语言 / 许可 / 状态)。第一列是注册表 id,
|
||
状态列显示「已安装 / 未安装」,未安装时鼠标悬停会列出缺失的文件名。
|
||
- **下载**:把选中的模型下到 `~/.local/share/live-caption/models/<id>/`。
|
||
支持设置下载源(镜像)与代理、断点续传、实时进度。下载完成会自动刷新列表。
|
||
- **校验完整性**:对选中模型的所有文件**重算 sha256**,与注册表里的期望值比对;
|
||
失败会列出损坏的文件名(可删除后重新下载)。文件大时需要几秒。
|
||
- **删除**:删掉该模型已下载的文件。如果删的正是「当前使用」的模型,选择会被清空。
|
||
- **打开模型目录**:在文件管理器里打开模型存储目录。
|
||
- **采集设备**:默认「跟随系统默认输出」(即当前默认输出的 monitor)。
|
||
也可以指定某个具体输出设备(如 HDMI);列不出来或没列全时见
|
||
[troubleshooting.md](troubleshooting.md)。
|
||
- **当前使用**:选择实际生效的模型(只列出**已安装**的)。
|
||
- **识别语言**:语言提示,多语言模型用它(例如 Nemotron 必须指定语言,否则「自动」可能识别成别的语言);
|
||
「自动检测」= 留空。**候选项按所选模型支持的语言生成** —— 中文模型只给中文,Nemotron 给它的 16 种
|
||
语言,Qwen3-ASR 给常用语言。改完之后左上角的语言标签会同步更新。
|
||
- **下载源**:默认 `https://hf-mirror.com`(网络可达性最好的镜像);可改成其它镜像或官方源。
|
||
- **代理**:不使用 / 跟随系统 / 手动设置(主机、端口、用户名、密码)。
|
||
|
||
### 显示页
|
||
|
||
| 项 | 说明 |
|
||
|---|---|
|
||
| 字号 | 字幕文字大小(9–40) |
|
||
| 用灰色显示尚未稳定的尾部 | 关掉后就只显示已稳定的文本 |
|
||
| 折叠行数 / 展开行数 | 折叠态与展开态各显示几行 |
|
||
| 背景不透明度 | 20%–100%,默认 84%(纯黑底,保证任何桌面背景下文字都可读) |
|
||
|
||
### 高级页
|
||
|
||
**通用**
|
||
|
||
| 项 | 说明 |
|
||
|---|---|
|
||
| 更新粒度(秒) | 累积多少秒音频跑一步;「自动」= 由后端决定(流式模型 0.32s) |
|
||
|
||
**流式(只影响 Qwen3-ASR)** —— 这一组对应 llama 后端的流式参数,改动会重启识别后端。
|
||
选了流式 ONNX 模型(zipformer / X-ASR / Nemotron)时整组会**置灰**,因为那些模型只用「更新粒度」。
|
||
|
||
| 项 | 对应命令行 | 说明 |
|
||
|---|---|---|
|
||
| 策略 | `--stream-mode` | `incremental`(增量复用,1~2 秒就出字,推荐)/ `append`(追加式,成本平坦但需要大 chunk)/ `window`(早期的对比实现) |
|
||
| 滑窗上限(秒) | `--stream-window` | 仅 window 模式;「不限」= 不滑窗 |
|
||
| 单段最长时长(秒) | `--stream-segment` | 超过就提交并重置上下文;「不限」= 不设上限 |
|
||
| 前缀回滚 token 数 | `--unfixed-tokens` | 回滚丢弃最后 N 个 token —— 它们会显示成灰色的不稳定尾部 |
|
||
| 冷启动 chunk 数 | `--unfixed-chunks` | 前 N 个 chunk 不带前缀,避免开头重复 |
|
||
| 单段最多生成 token | `--max-tokens` | 单段生成的 token 上限 |
|
||
| 线程数 | `--threads` | 只影响 Qwen3-ASR;流式模型固定单线程(多线程反而更慢) |
|
||
|
||
**调试**
|
||
|
||
| 项 | 对应命令行 | 说明 |
|
||
|---|---|---|
|
||
| 输出详细日志 | `--verbose` | 打印 llama.cpp / mtmd 的详细日志(排查加载/推理问题时用) |
|
||
| 模型目录 | `--model-dir` | 留空 = 默认目录(占位符会显示实际路径);一般不需要改 |
|
||
|
||
## 配置文件
|
||
|
||
所有设置存在 `QSettings` 里:`~/.config/live-caption/live-caption.conf`,组名 `[app]`。
|
||
|
||
```ini
|
||
[app]
|
||
modelId=zipformer-zh-2025 ; 当前使用的模型 id
|
||
language= ; 空 = 自动
|
||
captureDevice= ; 空 = 跟随系统默认输出
|
||
opacity=84 fontSize=15 ; 外观
|
||
showUnstableTail=true
|
||
collapsedLines=2 expandedLines=8
|
||
windowX=179 windowY=725 ; 拖动后记录的位置
|
||
mirrorBase=https://hf-mirror.com
|
||
proxyMode=0 ; 0=不使用 1=跟随系统 2=手动
|
||
chunkSec=0 threads=8 ; 高级
|
||
streamMode=incremental ; 高级:流式参数(只影响 Qwen3-ASR)
|
||
streamWindowSec=16 streamSegmentSec=30
|
||
unfixedTokens=5 unfixedChunks=2 maxTokens=256
|
||
verbose=false modelDir= ; 高级:调试
|
||
```
|
||
|
||
删掉这个文件(或其中某个键)就回到默认值。模型文件在
|
||
`~/.local/share/live-caption/models/<id>/`,不受这个文件影响。
|
||
|
||
## 自动化测试钩子(仅测试用)
|
||
|
||
界面本身的行为可以完全用命令行脚本驱动,这些选项平时用不到:
|
||
|
||
```bash
|
||
# 打开设置对话框并截图后退出
|
||
./build/live-caption --screenshot-settings /tmp/settings.png
|
||
|
||
# 自动关掉设置对话框,用来测「关闭/确定/取消/应用」各条路径是否崩溃
|
||
./build/live-caption --asr-model zipformer-zh-2025 --no-tray \
|
||
--settings-autoclose {reject|close|accept|ok|apply} --quit-after 8
|
||
|
||
# 字幕窗自截图(折叠态 + 展开态)
|
||
./build/live-caption --asr-model zipformer-zh-2025 --no-tray \
|
||
--screenshot /tmp/win.png --screenshot-delay 6
|
||
```
|
||
|
||
完整列表见 [cli.md](cli.md)。
|