字幕优先的视频转写
核心锚点是“字幕优先”:人工字幕 → 平台自动字幕 → ASR。原始字幕或原始转写是证据,AI 整理稿不能覆盖它。
支持范围
- 单条、多个或 URL 文件中的 B 站、YouTube 视频;
- B 站 UP 主空间、YouTube 频道或播放列表的批量发现;
- 已有
.srt/.vtt字幕; - 本地视频文件的 ASR 分支;
- 每条视频独立记录来源、成功、待 ASR 或失败状态,可断点续跑。
固定输出合同
output/
├── raw/
├── clean/
├── review/
├── status/
├── source-manifest.jsonl
├── failures.md
└── run-log.md
详情见 output-contract.md。
批量入口
先检查只需要 Python 与 yt-dlp 的批量字幕分支:
python3 scripts/doctor.py --json --branch batch-url
先列出并去重,不下载字幕、音频或模型:
python3 scripts/batch_video_transcripts.py \
--source-url 'https://space.bilibili.com/UP_ID' \
--source-url 'https://www.youtube.com/@CHANNEL/videos' \
--limit 20 \
--output-dir /path/to/output \
--list-only
确认清单后续跑;B 站需要登录状态时显式增加 --cookie-browser chrome:
python3 scripts/batch_video_transcripts.py \
--output-dir /path/to/output \
--resume
批量脚本对每条视频固定执行:字幕探测 → 人工字幕 → 自动字幕。字幕检查报错时该条失败并停止,不能把网络、登录或解析失败误判为“无字幕”。只有两类字幕都确认不存在时,才写入 needs-asr,且不会提前下载音频。
确认 ASR 依赖和模型后,再显式继续:
python3 scripts/doctor.py --json --branch batch-asr
python3 scripts/batch_video_transcripts.py \
--output-dir /path/to/output \
--resume \
--asr-backend mlx-whisper \
--asr-model /path/to/local-model
模型不在本地时,只有用户明确允许,才可增加 --allow-model-download。批量命令、输入形式和两平台差异见 source-routing.md。
字幕优先步骤
1. 识别来源与权限
保存稳定视频 ID、原 URL/本地路径、标题和获取时间。对 URL 先检查当前站点与当前视频,不因 yt-dlp 列出 extractor 就宣称整站已验证。
完成标准:来源、登录需求、批量范围、筛选上限和 ASR 授权明确。
2. 检查当前分支依赖
python3 scripts/doctor.py --json --branch subtitle-file
已有字幕使用 --branch subtitle-file,单条 B 站或 YouTube URL 分别使用 --branch bilibili-url 或 --branch youtube-url,批量使用 --branch batch-url;确定要 ASR 时再使用 --branch asr 或 --branch batch-asr。已有字幕只需 Python;URL 与批量发现需要 yt-dlp;只有 ASR 才需要 ffmpeg 和一个 Whisper 实现。检测器不安装依赖。
完成标准:只检查即将执行的分支,不用缺少 ASR 依赖阻塞可完成的字幕分支。
3. 先列字幕
对每个 URL 先用 yt-dlp --list-subs 或等价能力列出人工与自动字幕。需要登录时可临时使用浏览器登录状态,但命令输出、状态文件和日志不得包含 Cookie 内容。批量发现只生成视频清单,不能直接触发整批音频下载。
完成标准:明确选择人工字幕、自动字幕或“无可用字幕”;未确认前不下载大音频。
4. 获取原始文字
优先下载人工字幕,其次平台自动字幕。只有两者都不存在且用户允许时,才下载/抽取音频并运行 ASR。本地视频直接进入 ASR。
完成标准:raw/ 中存在未经 AI 改写的原始字幕或原始 SRT;来源类型写入状态。
5. 生成三层资产
已有字幕可运行:
python3 scripts/subtitle_to_assets.py \
--subtitle /path/to/input.srt \
--output-dir /path/to/output \
--video-id sample-id \
--source-url https://example.invalid/video \
--source-type manual-subtitle
clean/ 去掉字幕序号和冗余时间码但保留时间定位;review/ 是给 Agent 的后续任务包;status/ 记录完成/失败、来源与相对产物路径。
完成标准:四层文件互相引用,且 raw/ 没有被清洗稿覆盖。
6. 抽查与停止
每种来源至少抽查一条视频开头约两分钟的术语、重复与漏字,并把 status/<视频ID>.json 的 human_spot_check 从 pending 更新为 passed 或 needs-review。若“应有字幕”却意外进入音频下载或 ASR,立即停止整批并检查字幕发现、语言名称、登录状态与工具版本。
完成标准:成功项可从清洗稿回到原始文本和视频时间;失败项保留可重试原因。
后续分支
摘要、课程笔记、选题和 PDF 渲染必须在转写验收后单独执行,不计入本 Skill 的完成条件。
站点、登录与 ASR 分支见 source-routing.md。