提示

返回博客列表

从硬字幕提取到 Whisper 双语字幕:我的字幕工作流(全流程)

从硬字幕提取到 Whisper 双语字幕:我的字幕工作流(全流程)

下载完一个外语视频,最烦的就是没字幕,或者只有"烧"在画面上的硬字幕(hardsub)去不掉。这两年我搭了一套从"识别硬字幕"到"生成可编辑双语字幕"的流程,省了不少手工活。这篇文章把完整链路讲一遍,包含我踩过的坑、工具对比、以及对齐字幕时间轴的小技巧。

一、先分清两种字幕

  • 软字幕:独立 .srt/.vtt 文件,可开关、可翻译、可编辑,最理想。下载时优先用 --write-subs(yt-dlp)拿。
  • 硬字幕:直接画在每一帧画面上的文字,文件里没有独立文本,只能"看图识字"(OCR)。
  • 外挂字幕轨道:mkv/mp4 里封装的软字幕,用 ffmpeg -i video.mkv 能看到,提取出来即可。

很多人下完发现没软字幕,才想起去截硬字幕。所以第一步永远是:先试探源站有没有软字幕轨道,没有再走 OCR。

二、硬字幕提取:OCR 这一关

思路:ffmpeg 把视频按固定间隔截帧 → OCR 引擎识别每帧底部文字 → 按时间合并去重。

# 每秒截一帧
ffmpeg -i video.mp4 -vf "fps=1" frames/%03d.png
# 对每帧跑 OCR,只取画面底部 20% 区域(字幕通常在那)
python ocr_subs.py frames/ --region bottom

工具对比:
- tesseract:开源老牌,中文识别率一般,对手写体、艺术字体、半透明描边经常翻车。
- PaddleOCR(百度):对中文硬字幕友好很多,竖排、艺术字、模糊都能扛一部分,我主力用这个。
- EasyOCR:英文场景强,中文也不错,但模型大、慢。

坑点清单:
1. 截帧太密浪费:1fps 足够,2fps 让后续去重压力大。动态字幕(一句显示 3 秒)用 1fps 刚好每句截到 1~2 帧。
2. 去重是关键:相邻帧字幕往往一样,OCR 完要按文本相似度合并,否则生成几千条重复字幕。我用一个"文本相同且时间相邻就合并"的逻辑,量能压到 1/10。
3. 位置裁剪:字幕只占底部一条,全图 OCR 会把画面里的文字(比如路牌、标题)也吃进来干扰。先 crop 再识别,准确率直线上升。
4. 预处理提效:识别前把帧做二值化/放大对比度,能明显改善 OCR 效果,尤其半透明描边字幕。

三、没有硬字幕,直接生成:Whisper

如果源视频连硬字幕都没有,上语音识别。OpenAI 的 whisper 目前最省事:

whisper video.mp4 --model medium --language zh --output_format srt

模型选哪个:
- tiny/base:快但准度低,只适合草稿;
- small/medium:中文够用,性价比高;
- large-v3:最准但慢 3 倍、吃显存(GPU 才划算,CPU 跑一部电影能跑一小时)。

显存不够就 CPU 跑 medium,或者上 faster-whisper(用 CTranslate2 加速,同精度快 4 倍)。

Whisper 的断句问题:它输出的 srt 经常把一句话切成三四段,或把两句并在一段。我跑完都用个小脚本按标点合并短句、按静音点切长句。这步省不掉,否则字幕读着累。

四、做双语字幕

两条路线:
1. 翻译已有的源语言字幕:把 srt 丢给翻译 API(或本地模型),再拼回去,保留原时间戳只替换文本。
2. Whisper 直接出双语:Whisper 有 translate 任务能把非英语翻成英文,但中文→中英双语得自己两步:先识别中文,再翻译,最后合并成 原文\n译文 格式。

我常用的中文视频双语流程:

whisper video.mp4 --model medium --language zh --output_format srt   # 中文 srt
# 翻译模型出英文(本地用 argos/ctranslate2,或调用 API)
# 合并成 bilingual.srt,每句:中文\nEnglish

五、时间轴对齐:ffsubsync

翻译会引入轻微时间偏移(尤其机器翻译句子变长),直接用会"字幕慢半拍"。用 ffsubsync 以音频为基准重新对齐字幕:

ffsubsync video.mp4 -i zh.srt -o zh_aligned.srt
ffsubsync video.mp4 -i en.srt -o en_aligned.srt

原理是用音频指纹把字幕时间戳对齐到语音,效果立竿见影。双语两条都要对齐,且用同一个视频做基准,保证中英文同步。

六、烧录还是封装

  • 想在任何播放器都显示:用 ffmpeg subtitles 滤镜烧进画面(变硬字幕,不可逆,且中文字体要指定否则乱码):
    bash ffmpeg -i video.mp4 -vf "subtitles=zh.srt:force_style='FontSize=24,FontName=Noto Sans CJK SC'" out_hardsub.mp4
  • 想保留开关:封装进 mkv/mp4 作软字幕轨道:
    bash ffmpeg -i video.mp4 -i zh.srt -i en.srt -c copy -map 0 -map 1 -map 2 out.mkv
    我一般留软字幕,除非对方设备太老不认。

七、批量流水线

几百个视频时,我把上面步骤串成脚本:截帧 OCR / Whisper → 去重合并 → 翻译 → ffsubsync → 封装。用上一段说的"线程下载 + 进程池后处理"架构,OCR/Whisper 这种 CPU 活丢进程池,不阻塞下载。

八、常见坑速查

现象 原因 解法
OCR 大量错字 没 crop、没二值化 先裁底部再预处理
字幕几千条重复 没去重 按时间相邻合并
Whisper 断句奇葩 默认策略 后处理按标点合并
双语不同步 翻译偏移 ffsubsync 对齐
烧录中文乱码 没指定字体 force_style 设 CJK 字体
识别慢到哭 用了 large+CPU 换 faster-whisper 或 medium

九、一句总结

能拿软字幕绝不 OCR;硬字幕走 PaddleOCR + 去重;纯无字幕上 Whisper + 后处理;双语靠翻译 + ffsubsync 对齐。这套下来,一个两小时外语片从"没字幕"到"可开关中英双语",跑两三个命令的功夫,剩下的手工校对机器暂时替代不了——但已经省了九成力气。

想亲手试试?用 VidDown 一键解析下载

粘贴视频链接即可解析,多平台支持、网页端即用;下载桌面客户端解锁海外平台本地解析,开通会员更享不限次下载。

顶部