feat: 媒体库字幕重生成统计脚本(数量/时长/旧字幕备份)

模型与管线切换后需要把媒体库里旧管线生成的字幕整批重跑。批量引擎按"视频旁
已有字幕即 SKIPPED"判定,重跑前必须先统计范围、再把旧字幕改名备份,否则建出来
的任务会把所有视频全部跳过。

- `scripts/plan_regenerate_subtitles.py`:扫描媒体库,按 CN 产物的最早 mtime 判定
  生成时间,统计待重生成的数量/时长/体积并输出 JSON 计划;`--backup-old [--apply]
  [--select]` 把旧字幕原地改名为 `<原名>.old-<日期>` 供批量重跑。脚本不依赖仓库,
  可拷到媒体库主机直接跑(CIFS 挂载下逐文件 ffprobe 太慢)。
- 测试覆盖真实 10 秒视频与真实字幕文件,含 ffprobe 时长探测、分类边界、
  备份幂等与选择清单解析。
This commit is contained in:
2026-09-18 22:23:19 +08:00
parent dcdc5e8604
commit f656ec98c5
6 changed files with 673 additions and 0 deletions
+34
View File
@@ -160,6 +160,40 @@
- **环境变量**`WOV_BATCH_ENABLED`(默认 1)、`WOV_BATCH_INTERVAL_SECONDS`
(默认 1.0),完整列表见 [configuration.md](./configuration.md)。
## 媒体库历史字幕重建(统计 → 备份 → 批量重跑)
模型或管线切换后,媒体库里由旧管线生成的字幕需要整批重跑。批量引擎按
“视频旁已有字幕即 SKIPPED”判定,所以重跑前必须先统计范围、再把旧字幕改名
备份,否则建出来的任务会把所有视频全部跳过。工具是 `scripts/plan_regenerate_subtitles.py`
(**不依赖仓库**,可拷到媒体库主机直接跑:CIFS 挂载下逐文件 ffprobe 与
目录扫描都慢得多,在 NAS 本地跑 524 个视频只要几秒)。
生成时间的判定口径:只看本流水线产出的 CN 产物(`<视频名>.CN.srt`、
`<视频名>.CN_dual_eye.ass`),取它们**最早**的 mtime——双目 `.ass` 可能被样式
统一脚本原地改写而“变新”,中文字幕的 mtime 才是真实生成时间。
```bash
# 1) 统计:数量 / 时长 / 体积 / 按月分布,并写出逐条明细 JSON
python3 scripts/plan_regenerate_subtitles.py /vol1/1000/123 \
--before 2026-09-01 --out data/experiments/regen_plan/plan_2026-09-01.json
# 2) 备份旧字幕(默认预览,--apply 才落盘):改名 <原名>.old-<当天日期>
python3 scripts/plan_regenerate_subtitles.py /vol1/1000/123 --backup-old
python3 scripts/plan_regenerate_subtitles.py /vol1/1000/123 --backup-old --apply \
--select sample10.txt # 只处理清单里的视频,支持 # 注释
# 3) 建批量任务(批量页或 POST /api/batch/jobs
```
- 备份文件名带 `.old-<日期>` 后缀,扩展名不再是字幕后缀,批量引擎不会再把它当
旁挂字幕;确认新字幕无误后删除备份,需要回退则去掉后缀改回原名。
- 未备份的视频仍有旁挂字幕 → 创建任务时记 SKIPPED,因此“整库建一个任务”即可,
实际只会处理被备份的那批;已重跑的视频产出新 CN 字幕(mtime 变新),全量重建
时自动归入“已是最新”,不会重复处理。
- 实测数据(380 个待重生成 / 207.88 小时;10 个样本 6.54 小时素材跑 77.7 分钟、
GPU 平均 289.6 W、约 0.375 kWh,全量推算约 41 小时 / 整机 15 kWh)见
`data/experiments/regen_plan/REPORT.md`。
## 相关文档
- 环境变量全表:[configuration.md](./configuration.md)