首页 / FFmpeg 入门教程 / 字幕处理与烧录

FFmpeg 入门教程

字幕处理与烧录

本教程共 32 篇 · 第 17 篇 · 更新于 2026-08-09 · 约 9 分钟阅读

FFmpeg字幕SRTASS硬字幕软字幕subtitles滤镜burn-in

本节目标:分清软字幕和硬字幕,会封装、提取、转换字幕,也能把字幕永久烧进视频画面。

字幕处理是很多人学 FFmpeg 的直接动机:下载的片源没中文字幕、想把字幕压进视频里在电视上播、要给视频加双语字幕……这一章把字幕相关的操作一次讲清。

两种字幕:软字幕 vs 硬字幕

软字幕(soft subtitle)

字幕作为独立的流封装在视频文件里(MKV、MP4 都支持)。播放时由播放器渲染到画面上。

  • 优点:可以开关、切换、修改样式、提取出来编辑。
  • 缺点:不是所有设备/播放器都支持,某些电视、老软件可能不显示。

硬字幕(hard subtitle / burn-in)

字幕被直接画进视频画面,成为像素的一部分。

  • 优点:任何设备都能看到,兼容性 100%。
  • 缺点:不可关闭、不可修改,必须重新编码视频,多次压制会有画质损失。

一句话:给朋友传文件用软字幕,往网上传或在不支持的设备上播放用硬字幕。

常见字幕格式

格式类型特点
SRT (SubRip)文本最简单通用,只有时间轴和文字
ASS/SSA文本支持字体、颜色、位置、特效,动漫常用
VTT (WebVTT)文本HTML5 视频标准,和 SRT 类似
mov_text文本MP4 容器里的字幕标准格式
dvdsub图形DVD 用的位图字幕
pgssub图形蓝光用的位图字幕
xsub图形AVI 容器内置的图形字幕

文本字幕可以互相转换、修改样式;图形字幕本质是图片,只能提取或烧录,不能直接改文字。

Note

MP4 容器官方支持的文本字幕是 mov_text(QuickTime Text)。SRT/ASS 不能直接封进 MP4,需要转码成 mov_text,或者封装到 MKV 里。MKV 几乎接受所有字幕格式。

封装软字幕

把 SRT/ASS 封装进 MKV

MKV 最宽松,SRT 和 ASS 可以直接复制:

ffmpeg -i input.mp4 -i subtitle.srt \
  -c:v copy -c:a copy -c:s srt \
  -metadata:s:s:0 language=chi \
  output.mkv
  • -c:s srt:字幕编码为 SRT(如果源是 ASS 想保留样式,写 -c:s ass)。
  • -metadata:s:s:0 language=chi:第 0 条字幕流的语言设为中文(ISO 639-2 三位代码)。

如果字幕已经是 ASS:

ffmpeg -i input.mp4 -i subtitle.ass \
  -c copy \
  output.mkv

视频、音频、字幕全部直接复制,秒完成。

封装进 MP4

MP4 需要 mov_text:

ffmpeg -i input.mp4 -i subtitle.srt \
  -c:v copy -c:a copy -c:s mov_text \
  -metadata:s:s:0 language=chi \
  -metadata:s:s:0 title="简体中文" \
  output.mp4

title 是字幕流的显示名字,播放器里可能会显示为「简体中文」。

设为默认字幕

有多条字幕时,标记某条为默认:

ffmpeg -i input.mkv -i sub-zh.srt -i sub-en.srt \
  -c copy \
  -metadata:s:s:0 language=chi -disposition:s:0 default \
  -metadata:s:s:1 language=eng -disposition:s:1 0 \
  output.mkv
  • -disposition:s:0 default:第 0 条字幕设为默认。
  • -disposition:s:1 0:清除第 1 条的默认标记。

批量内挂字幕(PowerShell)

把文件夹里所有同名 .ass 字幕挂进 .mkv

Get-ChildItem *.mkv | ForEach-Object {
    $base = $_.BaseName
    $sub = "$base.ass"
    if (Test-Path $sub) {
        ffmpeg -i $_.Name -i $sub `
          -c:v copy -c:a copy -c:s ass `
          -metadata:s:s:0 language=chi -disposition:s:0 default `
          "$base-subbed.mkv"
    }
}

提取字幕

从视频里把字幕流抽出来:

# 先看字幕流的编号和类型
ffprobe -hide_banner input.mkv

# 提取第 0 条字幕流,直接复制
ffmpeg -i input.mkv -map 0:s:0 -c:s copy output.srt

如果字幕是图形格式(dvdsub/pgssub),提取出来的是 .sub + .idx.sup 文件,不能直接当文本编辑。文本字幕(SRT/ASS)提取出来就是纯文本文件。

字幕格式转换

SRT 转 ASS

ffmpeg -i subtitle.srt subtitle.ass

转换后可以用 Aegisub 等工具进一步调整字体、样式。

ASS 转 SRT

ffmpeg -i subtitle.ass subtitle.srt

ASS 里的样式信息会丢失,只剩文字和时间轴。

SRT 转 VTT

ffmpeg -i subtitle.srt subtitle.vtt

烧录硬字幕

硬字幕要用滤镜把字幕画到每一帧上,必须重编码视频。

subtitles 滤镜(最常用)

ffmpeg -i input.mp4 -vf "subtitles=subtitle.srt" output.mp4

这条命令会用 libass 库把 SRT 字幕渲染到视频上。默认编码参数可能一般,建议显式指定:

ffmpeg -i input.mp4 \
  -vf "subtitles=subtitle.srt" \
  -c:v libx264 -crf 20 -preset medium \
  -c:a copy \
  output.mp4

视频重编码,音频直接复制。CRF 20 画质很好,避免二次压制太糊。

烧录视频里已内嵌的字幕

字幕已经在 MKV 文件里作为流存在,想直接烧录:

ffmpeg -i input.mkv -vf "subtitles=input.mkv:si=0" output.mp4

si=0 表示使用输入文件的第 0 条字幕流。选第 1 条写 si=1

烧录 ASS 字幕

ASS 字幕带样式,subtitles 滤镜也能直接处理:

ffmpeg -i input.mp4 -vf "subtitles=subtitle.ass" output.mp4

或者用专门的 ass 滤镜(功能相同,但只接受 ASS):

ffmpeg -i input.mp4 -vf "ass=subtitle.ass" output.mp4

如果只有 SRT,想先转成 ASS 自定义样式再烧:

ffmpeg -i subtitle.srt subtitle.ass
# 用编辑器调整 subtitle.ass 的样式
ffmpeg -i input.mp4 -vf "ass=subtitle.ass" output.mp4

烧录图形字幕(dvdsub/pgssub)

图形字幕不能用 subtitles 滤镜,要用 overlay:

ffmpeg -i input.mkv \
  -filter_complex "[0:v][0:s:0]overlay[v]" \
  -map "[v]" -map 0:a \
  -c:v libx264 -c:a copy \
  output.mp4

[0:v] 是视频,[0:s:0] 是第 0 条字幕流(图形),overlay 把图形叠在画面上。

烧录时的样式调整

subtitles 滤镜支持通过 force_style 覆盖样式:

ffmpeg -i input.mp4 \
  -vf "subtitles=subtitle.srt:force_style='FontName=Microsoft YaHei,FontSize=24,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,Outline=2,Shadow=1,MarginV=30'" \
  -c:v libx264 -crf 20 -c:a copy \
  output.mp4

常用样式字段:

  • FontName:字体名。
  • FontSize:字号。
  • PrimaryColour:字体颜色,ASS 颜色格式 &HAABBGGRR(注意是 BGR 不是 RGB,AA 是透明度)。
  • OutlineColour:描边颜色。
  • Outline:描边粗细。
  • Shadow:阴影深度。
  • MarginV:距底部距离。
Tip

Windows 上 subtitles 滤镜依赖 fontconfig 来找字体。如果烧出来的字幕字体不对或报错找不到字体,需要配置 fonts.conf,或者把字幕转成 ASS 并在 ASS 里明确指定字体文件路径。gyan.dev 的 full 构建一般自带 fontconfig 配置,开箱即用。

字幕路径里的特殊字符

subtitles 滤镜的文件名在滤镜表达式里,特殊字符要转义:

# Windows 路径的反斜杠和冒号要转义
ffmpeg -i input.mp4 -vf "subtitles=D\\:/videos/sub.srt" output.mp4

# 文件名有空格或单引号
ffmpeg -i input.mp4 -vf "subtitles='my subtitles.srt'" output.mp4

Windows 路径最稳妥的写法是用正斜杠并转义冒号:D\\:/path/to/sub.srt

截取时字幕不同步

如果用 -ss 截取片段并同时烧录字幕,subtitles 滤镜会从字幕文件开头读字幕,可能和视频时间对不上。解决方法是加 -copyts 并在输出端再 seek 一次:

ffmpeg -ss 5:00 -copyts -i input.mp4 -ss 5:00 -vf "subtitles=subtitle.srt" output.mp4

或者更简单——先把视频截好,再单独给截好的片段烧字幕。

常见问题

播放器不显示字幕。 要么是设备不支持该字幕格式(MP4 里的 ASS 经常不显示),要么字幕没设为默认。MKV 兼容性最好;不行就烧硬字幕。

烧出来是乱码或方块。 SRT 文件编码不是 UTF-8。用记事本或 VS Code 另存为 UTF-8;中文字幕建议指定 FontName=Microsoft YaHeiSimHei

烧录后文件变大了。 重编码导致。用 -crf 20-24 控制体积,和原文件码率接近就行。

想保留双语字幕同时显示。 软字幕可以封多条,播放器切换;硬字幕同时显示两条需要用 ASS 把两条字幕排好版,或者用复杂滤镜叠加两次 subtitles。

小结

  • 软字幕是独立的流,可以开关切换;硬字幕烧进画面,兼容性最好但不可逆。
  • MKV 几乎接受所有字幕格式;MP4 只认 mov_text。
  • 封装字幕用 -c:s copy(或 srt/ass/mov_text),提取用 -map 0:s:N -c:s copy
  • 烧录用 -vf subtitles=文件.srt,视频必须重编码。
  • ASS 字幕支持自定义字体、颜色、位置;用 force_style 可临时覆盖样式。
  • Windows 注意字幕文件用 UTF-8,路径特殊字符要转义。

到这里,基础操作篇就全部完成了。你已经掌握了 FFmpeg 最常用的核心能力:查看信息、转换格式、提取流、截取片段、截图、几何变换、拼接、GIF、图片序列、字幕。后面的章节会进入编码码率、滤镜和流媒体等更深入的话题。