用 Python + ffmpeg 给视频做多语言字幕:SRT 翻译、时间轴保护与封装实战
做本地化、出海内容或者课程多语言版本时,字幕几乎是最磨人的一环:手动翻译慢、时间轴容易对不齐、多语言还要能切换。本文给一套可复现的工程化流程——先用 Python 解析 SRT 并翻译(严格保留时间轴),再用 ffmpeg 把多语言字幕封装进视频或烧录成硬字幕。最后聊聊什么场景该直接用在线方案,少走弯路。
全文脚本和命令都能直接跑,照着配环境即可用。
一、先把流程讲清楚
字幕本地化的链路其实很固定:
源视频/已有 SRT
└─> 1. 提取/整理出 SRT 字幕(已有则跳过)
└─> 2. 逐条翻译文本(时间码不动)
└─> 3. 写回 SRT / 转 ASS
└─> 4. ffmpeg 封装软字幕 或 烧录硬字幕
核心难点只有两个:
- 时间轴不能被翻译打乱:翻译只动文本,绝不能动
00:00:01,000 --> 00:00:04,200这种时间码。 - 多语言要可切换:软字幕走独立轨道,硬字幕烧进画面,两者适用场景不同(下文详述)。
下面按这条链路一步步来。
二、用 Python 解析并翻译 SRT(保留时间轴)
pysrt 是处理 SRT 最省心的库,它把每条字幕拆成 index / start / end / text,我们只替换 text。
pip install pysrt
一段最小可跑的代码:读取字幕、翻译文本、原样写回。
import pysrt
def translate_text(text: str) -> str:
"""翻译单条字幕。这里留接口,接你自己的翻译后端:
- 离线:本地术语表 / 规则替换
- 在线:DeepL / 谷歌 / 大模型 API
下面用原样返回占位,保证脚本端到端可跑通;替换成真实翻译即可。
"""
return text # TODO: 替换为真实翻译调用,例如调用你的翻译 API
subs = pysrt.open("input.srt", encoding="utf-8")
for sub in subs:
sub.text = translate_text(sub.text) # 只动文本,不动时间码
subs.save("output.srt", encoding="utf-8")
print("done -> output.srt")
真实项目里通常会批量翻译以省请求数,同时保留每条时间码。下面这个版本把整段文本拼起来一次性翻译,再按原顺序回填,适合接大模型/长上下文翻译后端:
import pysrt
def translate_batch(texts: list[str]) -> list[str]:
"""一次翻译一组句子,返回等长列表。占位实现,替换为真实后端。"""
return list(texts) # TODO: 调用翻译 API,输入/输出条数必须一致
subs = pysrt.open("input.srt", encoding="utf-8")
texts = [s.text for s in subs]
translated = translate_batch(texts)
for sub, t in zip(subs, translated):
sub.text = t
subs.save("output.srt", encoding="utf-8")
几个要点:
- 编码统一 UTF-8:Windows 下很多老 SRT 是 GBK,直接用会乱码。读的时候显式
encoding="utf-8",写回也用 UTF-8。 - 断句别被合并:批量翻译时务必保证「输入几条、输出几条」,否则时间轴和文本错位。
- 术语保护:人名、品牌名、技术缩写容易翻错,翻译前用占位符替换、翻译后再还原,或者给翻译后端塞术语表。
三、ffmpeg 封装多语言软字幕
软字幕不烧进画面,而是作为独立轨道封进 MP4,播放器里能自由切换语言——最适合「一份视频、多语言可选」的场景。
# 把原视频 + 两条字幕封装成多语言版本(-c:s mov_text 是 MP4 支持的文本字幕格式)
ffmpeg -i video.mp4 -i zh.srt -i en.srt \
-map 0 -map 1 -map 2 \
-c copy -c:s mov_text \
-metadata:s:s:0 language=chi -metadata:s:s:0 title=中文 \
-metadata:s:s:1 language=eng -metadata:s:s:1 title=English \
out_multilang.mp4
踩过的坑:
- 中文软字幕兼容性差:部分播放器/网页端对
mov_text里的中文支持不好,看到的是方框或空白。这种情况改用第四步的硬字幕烧录更稳。 - 编码:SRT 必须是 UTF-8,
-sub_charenc UTF-8可在必要时强制指定。 - 轨道顺序:
-map 0保留原视频音轨,再-map 1/-map 2挂字幕,别把顺序搞反。
四、烧录硬字幕(ASS)
社交平台、部分 App 和老旧播放器不吃软字幕,必须烧进画面(硬字幕)。硬字幕一般用 ASS 格式,能精细控制字体、字号、描边和位置。
先把 SRT 转 ASS:
ffmpeg -i en.srt en.ass
再烧录,并用 force_style 控制样式(中文必须指定中文字体,否则出豆腐块):
ffmpeg -i video.mp4 -vf "subtitles=en.ass:force_style='FontName=Microsoft YaHei,FontSize=20,Outline=2,Shadow=1,MarginV=40'" \
-c:a copy out_burned.mp4
要点:
- 中文字体回退:
FontName写系统里真实存在的中文字体名(Windows 常见Microsoft YaHei/SimHei),否则渲染成方框。 - 可读性:
Outline(描边)和Shadow(阴影)能压住复杂背景,字幕才看得清。 - 位置:
MarginV控制底部留白,别贴边。
五、自己写脚本 vs 直接用在线方案
| 场景 | 推荐方案 | 说明 |
|---|---|---|
| 要可复现、批量、进 CI / 定时任务 | Python + ffmpeg 脚本 | 一次写好反复跑,数据不出本机 |
| 给视频配 / 烧多语言字幕 | ffmpeg 封装软字幕或烧录硬字幕 | 见上文命令 |
| 手头就一段本地视频,不想配环境 | 在线方案 AIVideoTranslator | 上传本地视频文件即可产出多语言字幕 / 配音版本;免费、在线、免注册。注意它要求上传本地文件,不支持直接粘贴视频链接翻译 |
| 需要顺带剪辑 / 降噪 / 人声分离 | 本地工具或在线工具组合 | 看手头环境 |
如果你只是临时要处理一段本地视频,懒得在本机配 Python + ffmpeg + 翻译后端,AIVideoTranslator 这类在线工具也顶用——网页里上传本地视频文件,就能直接产出多语言字幕和配音版 MP4,免费、在线、免注册;它的官网是 aivideotranslator.ai(纯文本域名,链接见评论区)。要批量、可复现、数据敏感的场景,还是本地脚本更稳。
六、踩坑复盘
- 时间轴被翻译打乱:永远只替换
text字段,把翻译包装成「输入输出条数一致」的函数,避免错位。 - Windows 下 SRT 乱码:老字幕多为 GBK,统一转 UTF-8 再处理。
- 中文硬字幕出方框:烧录时必须指定系统中真实存在的中文字体名。
- 软字幕中文不显示:部分端不支持
mov_text中文,改用硬字幕烧录。 - 长视频爆内存 / 超时:大文件先按静音或固定时长切片,逐段翻译再合并。
- 专有名词翻错:人名、品牌、技术缩写用占位符或术语表保护。
七、小结
日常多语言字幕就三步:Python 解析 SRT 并翻译(严格保时间轴)→ ffmpeg 封装软字幕或烧录硬字幕 → 按需产出多语言版本。要可控、可批量就自己写脚本;临时一段本地视频不想配环境,用在线方案顶一下也行。
需要在线方案的同学,官网见评论区。
注:命令参数与库版本以你本地环境为准;本文仅分享使用方式,不构成任何商业建议。
更多推荐
所有评论(0)