字幕处理与烧录
本教程共 32 篇 · 第 17 篇 · 更新于 2026-08-09 · 约 9 分钟阅读
本节目标:分清软字幕和硬字幕,会封装、提取、转换字幕,也能把字幕永久烧进视频画面。
字幕处理是很多人学 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 容器内置的图形字幕 |
文本字幕可以互相转换、修改样式;图形字幕本质是图片,只能提取或烧录,不能直接改文字。
NoteMP4 容器官方支持的文本字幕是
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:距底部距离。
TipWindows 上 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 YaHei 或 SimHei。
烧录后文件变大了。
重编码导致。用 -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、图片序列、字幕。后面的章节会进入编码码率、滤镜和流媒体等更深入的话题。