做本地化、出海内容或者课程多语言版本时,字幕几乎是最磨人的一环:手动翻译慢、时间轴容易对不齐、多语言还要能切换。本文给一套可复现的工程化流程——先用 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 封装软字幕或烧录硬字幕 → 按需产出多语言版本。要可控、可批量就自己写脚本;临时一段本地视频不想配环境,用在线方案顶一下也行。

需要在线方案的同学,官网见评论区。

注:命令参数与库版本以你本地环境为准;本文仅分享使用方式,不构成任何商业建议。

更多推荐