视频转写 + 搜索全家桶
想给几十小时 YouTube / 播客 / 会议视频按内容做索引的工程师 10 件套:yt-dlp 抓源,whisper.cpp / Faster Whisper / WhisperX 出带词级时间戳和说话人分离的转写,Groq + AssemblyAI 走云端加速,Meetily 本地开会,yt-fts 全文搜,LeMUR 总结提问,Remotion 渲染带时间戳的字幕。
这个 pack 包含什么
互联网上最值钱的文本,大多锁在 YouTube 视频、播客 feed、Zoom 录像里 — 而每个平台的搜索框基本没用。这套就是为了把这部分文本释放出来。10 件套按一条精心设计的管线串:抓源 → 转写 → 说话人分离 → 切片 → 嵌入/搜索 → 总结。每一件做好一段,合起来就把几十小时的音频变成一个能 grep 的索引。
每一段都配了本地 + 云端两个选项。原型阶段先走云(Groq Whisper 亚秒级返回、AssemblyAI 开箱即用的说话人分离),上量或者隐私敏感了就切本地(whisper.cpp + WhisperX 跑在桌下那台箱子上)。管线不变,后端可替换。
目标用户是研究员 / 记者 / 工程师 — 手里有一堆录音,想按内容搜:「过去 40 期我嘉宾哪几次提到了『销售税』」「Speaker 2 反驳的那 30 秒在哪」「上周 9 场会议浓缩成一页简报」。
推荐安装顺序(抓源 → 转写 → 说话人分离 → 切片 → 嵌入/搜索 → 总结)
- yt-dlp — 抓源头。基石:YouTube、Vimeo、播客 RSS、X 视频、Bilibili、1000+ 网站一行命令搞定。
yt-dlp -x --audio-format wav <url>出转写要的 WAV。没有 yt-dlp 你就在手动下载;有了它,整条频道用一个 for 循环全归档。 - whisper.cpp — 本地转写,零依赖。Whisper 的 C/C++ 移植,MacBook Air 上不用 Python / CUDA / 折腾模型也能跑。
large-v3默认追准度;只搞英语就用medium.en更快。这是干 80% 活的那个低调工具。 - Faster Whisper — 用 CTranslate2 把 OpenAI Whisper 加速 4 倍。whisper.cpp 跟不上你 batch 时切它:4090 上
large-v3处理一小时音频只要 2-3 分钟,准度和 OpenAI 参考一致,显存约一半。 - WhisperX — 一遍出词级时间戳 + 说话人分离。杀手特性是强制对齐:每个词都有毫秒级精度的 start/end,所以搜索命中能跳到准确的秒,而不是「30 秒区间里某处」。顺带打包 pyannote 系的 diarization。
- AssemblyAI Diarization — 不想管模型时的云端说话人分离。2-10 个说话人自动识别,无需 GPU,一个 HTTP 调用搞定。适合那些「Speaker 1 / Speaker 2 标签不能错」且你不想 debug pyannote 权重的录音。
- Groq Whisper — 亚秒级云端 STT。同样的 Whisper 模型,但跑在 Groq 的 LPU 上,每分钟音频不到 1 秒返回。直播字幕、语音 agent、任何延迟比 batch 成本更重要的场景,选它。
- yt-fts — YouTube 频道全文搜索。把频道每个视频的自动字幕拉下来塞进 SQLite FTS5,跨多年内容按关键词搜。简陋但有效的「第一版搜索」,等你真要做语义搜索之前先用它。
- Meetily — 隐私优先的 AI 会议助手。加入你的 Zoom / Meet / Teams,本地转写、本地生成总结 — 数据不离开你的机器。访谈、招聘、并购、心理咨询录音这种敏感内容用它。
- LeMUR — 在转写上跑 LLM 的工业化封装。AssemblyAI 的 LLM 端点,接收一个 transcript + 一个 prompt,返回总结、action items、自定义 JSON 提取、问答。让你不用自己搭 RAG 也能做总结提取那段。
- Remotion Captions & Subtitles — 把转写渲染回视频。校对完字幕通常要烧进视频。Remotion 把你的 SRT 变成带统一字体、按词逐个出现的动态字幕,导出 MP4。
它们怎么协同(管线示意)
┌── yt-dlp ──┐
│ (出 WAV) │ ← YouTube / 播客 feed / Zoom .m4a
└─────┬──────┘
▼
┌─── 转写 ──────────────────────────────────┐
│ whisper.cpp (本地, 无 Python) │
│ Faster Whisper (GPU 4 倍速) │
│ Groq Whisper (云端, 亚秒级) │
│ → 原始文本 + 段级时间戳 │
└─────────────────┬─────────────────────────┘
▼
┌── 词对齐 + 说话人分离 ─────────────────────┐
│ WhisperX (本地, 词级 + 说话人) │
│ AssemblyAI Diarization (云端) │
│ → 带 [SPEAKER_01] + word.start 的 SRT │
└─────────────────┬─────────────────────────┘
▼
┌── 按时间戳切片 ───────────────────────────┐
│ 按说话人 turn 切 / 或按 > 0.5s 静音切 │
│ / 或 30-60s 窗口 + 10s 重叠 │
│ emit (text, video_id, start, end, speaker)│
└─────────────────┬─────────────────────────┘
▼
┌── 搜索 ──────┐ ┌── 总结 ────────┐
│ yt-fts FTS5 │ │ LeMUR (LLM) │
│ + 自选向量库 │ │ 总结、问答、 │
│ │ │ 结构化提取 │
└────────┬─────┘ └────────┬───────┘
▼ ▼
Meetily UI Remotion 烧字幕
(实时会议) (回视频)
「按时间戳切片」这一步本 pack 故意没配独立工具 — 在 WhisperX 的词输出之上写个 30 行脚本即可。有说话人分离的内容按 turn 切;独白按 > 500ms 静音切;其他一律 30-60s 固定窗口 + 10s 重叠。无论怎么切,每个 chunk 都带 (text, video_id, start_sec, end_sec, speaker),这样搜索命中就能深链到具体时间戳。
你会遇到的取舍
- whisper.cpp vs Faster Whisper — whisper.cpp 赢在可移植(单个 binary,MacBook 也能跑),Faster Whisper 赢在速度(CUDA + CTranslate2)。GPU 上每天处理 > 1 小时音频就切 Faster Whisper;只在自己 MacBook 上偶尔跑就留 whisper.cpp。
- WhisperX vs AssemblyAI Diarization — WhisperX 免费,2-3 个明显不同说话人的分离质量很好;处理重叠说话、人群录音、> 5 人会议时拉胯。AssemblyAI 托管版能稳定处理这些边角,$0.37/小时。经验法则:播客(主持 + 1-2 嘉宾)用 WhisperX,圆桌 / Q&A 录音用 AssemblyAI。
- Groq Whisper vs 本地 whisper.cpp — Groq < 1 秒延迟,直播字幕、语音 agent 必选。本地赢在 batch 场景:通宵转写一堆文件、数据不能出本机、或者录音是 Groq 托管模型不擅长的语种。按延迟预算选,不按成本选 — batch 模式两边都是几分钱。
- yt-fts(FTS5 关键词)vs 语义嵌入 — yt-fts 5 分钟搭好回答「哪期提到了关键词 X」。语义搜索回答「哪期关于 X」,但要加 embedding、向量库、查询管线。先 yt-fts;等关键词搜索开始漏掉真正相关命中再升级到 embedding。
- Meetily vs 通用 Whisper 管线 — Meetily 是封装好的产品(自动入会、生成总结、自带 UI)。原生 Whisper 管线更折腾但每一步都能改。Meetily 给团队里非工程的同事用;Whisper 管线给工程团队拥有的归档。
常见踩坑
- 多人录音跳过说话人分离。 4 个人录的播客做出来没有 speaker 标签,搜索时每条引用都归到「这段转写」而不是「某个人」— 索引被毒化了。先 diarize 再 index。
- 扔掉词级时间戳。 Whisper 默认是 30 秒段级时间戳;搜索命中说「在这 30 秒区间里」对深链毫无用处。用 WhisperX(或 AssemblyAI 开
word_timestamps),让每个词都有自己的start。 - 多人内容用 30 秒固定窗口切片。 30 秒窗口经常跨两个说话人,嵌入向量谁都不像。先按说话人 turn 边界切,长 turn 再按句切 — 别按时钟切。
- 每次改 prompt 都重新转写。 转写是最贵的一步。SRT + 词级 JSON 落盘、版本化,后续只对缓存输出重跑总结/搜索管线。缓存 key 用源音频的 content hash。
- 无脑信 YouTube 自动字幕。 自动字幕会漏人名、术语、数字 — 恰恰是你最想搜的东西。建索引前一律用 whisper.cpp
large-v3重转一遍;自动字幕是免费初稿,不是真源。 - 忘了静音段会让 Whisper 幻觉。 Whisper 对长静音会编出听起来很合理的文本。先跑 VAD(voice activity detection),只对真有人声的段转写;WhisperX 自带
--vad_filter。
10 个资产打包就绪
常见问题
10 个非要全装吗?能不能从小起步?
从 3 件开始:yt-dlp 抓源、whisper.cpp 转写、yt-fts 搜索。一个下午就能给任意 YouTube 频道搭出一个可关键词搜索的归档。后续:要按词深链到具体秒就加 WhisperX;whisper.cpp 跟不上 batch 就加 Faster Whisper;WhisperX 说话人标签开始串人就加 AssemblyAI Diarization;要亚秒级延迟的直播场景就加 Groq Whisper;要在本机录会议不泄数据就加 Meetily;想对整个归档做 LLM 总结就加 LeMUR;要把校对过的字幕烧回视频就加 Remotion Captions。10 件全套,归档超过 50 小时音频才真用得上。
单 GPU 实际转写吞吐能到多少?
RTX 4090 + Faster Whisper large-v3 + beam_size=5:约 20-30 倍实时,即一小时音频 2-3 分钟。WhisperX 同箱子 ~15 倍实时(含对齐 + 分离)。M3 MacBook Air + whisper.cpp + medium.en:~5-8 倍实时,够通宵 batch 但跟不上直播。容量规划:Faster Whisper 一个 GPU-小时处理 20-30 小时源音频;whisper.cpp 一个 M 系列笔记本-小时处理 5-8 小时源音频。
Whisper 自带时间戳了,为什么还要 WhisperX?
Whisper 出的是段级时间戳,每段约 30 秒。给视频烧字幕够用,但本 pack 关心的两件事它做不到:(1)搜索命中深链到「具体哪一秒说的」;(2)按说话人 turn 边界切片而不是按固定时钟切片。WhisperX 加了强制对齐,每个词都有自己的 start / end(通常精度 20-50ms),并打包了 pyannote 系说话人分离 — 每个词还带 speaker 标签。这两个特性把转写从「一坨文本」变成「可查询、可深链的索引」。
这套支持非英语内容吗?
支持,按语种有差异。whisper.cpp / Faster Whisper / WhisperX 共用 OpenAI Whisper 多语种模型 — large-v3 处理 90+ 语言可用质量,西/法/德/日/中/葡最好,低资源的非洲、中亚语种较弱。Groq 托管的 Whisper 语种覆盖一致。AssemblyAI 的 diarization 对说话人标签是语种无关的,但转写引擎主力支持英、西、法、德、意、葡、日。yt-fts 的 FTS5 搜索语种无关;LeMUR 总结跟底层 LLM(Claude / GPT)的能力一致。中文(普通话 / 粤语)建议同时试一下 SenseVoice 作为转写模型替代 — 我们的经验它在中文口音上比 Whisper 好。
新一期播客上线后怎么增量同步索引?
把管线当成单向 ingest,每晚 cron 跑:(1) yt-dlp -x --download-archive archive.txt <channel_url> 只拉新单集 — archive 文件挡住重复下载;(2) whisper.cpp 或 Faster Whisper 转写每个新音频,把 JSON 与音频同目录写盘,附 content hash;(3) WhisperX 对新文件做对齐 + 分离(按 hash 判断是否处理过);(4) indexer 读 JSON,按 turn 切片,按 (video_id, chunk_id) upsert 到 yt-fts / 你的向量库;(5) LeMUR 对每期跑一遍总结 prompt,结果写库。整个 cron 通常 50-80 行 Python + 一份 Makefile。不要在 chunk 粒度做增量 — 缓存未命中时整文件重跑比追踪部分状态更简单更便宜。