FFmpeg 字幕压制与软封装
FFmpeg 压制硬字幕与软封装的字段详解,覆盖 libass 参数、流复制、码率控制与常见封装格式选择。
FFmpeg 字幕压制与软封装
FFmpeg 是字幕压制的工业级工具。但参数多、组合复杂,新手很难上手。这篇按场景整理常用命令。
软封装
软封装是把字幕作为独立轨道封装到视频文件,不烧入画面。
ffmpeg -i video.mp4 -i subtitle.ass -c copy -c:s ass output.mkv
参数说明:
-i video.mp4:输入视频-i subtitle.ass:输入字幕-c copy:视频和音频流直接复制(不重编码,速度快)-c:s ass:字幕流编码为 ASS 格式output.mkv:输出 MKV 容器
MKV 是支持 ASS 软封装的最佳容器。MP4 也支持软字幕,但只能用 mov_text 格式(丢失 ASS 样式),不推荐。
多字幕封装
ffmpeg -i video.mp4 \
-i zh.ass -i en.srt -i ja.ass \
-map 0 -map 1 -map 2 -map 3 \
-c:v copy -c:a copy \
-c:s:0 ass -c:s:1 mov_text -c:s:2 ass \
-metadata:s:s:0 language=chi \
-metadata:s:s:1 language=eng \
-metadata:s:s:2 language=jpn \
output.mkv
-map:手动指定流映射-c:s:N:第 N 条字幕流的编码格式-metadata:s:s:N language=xxx:设置语言标签
播放器会按语言标签显示字幕选择菜单。
硬压制
硬压制是把字幕烧入视频画面。
基础硬压制
ffmpeg -i video.mp4 -vf "ass=subtitle.ass" -c:a copy output.mp4
-vf "ass=subtitle.ass":视频滤镜,使用 libass 渲染 ASS 字幕-c:a copy:音频直接复制- 输出 MP4
注意:硬压制必须重编码视频流,-c:v copy 无效。默认使用 H.264 编码。
指定编码参数
ffmpeg -i video.mp4 \
-vf "ass=subtitle.ass" \
-c:v libx264 \
-preset slow \
-crf 18 \
-pix_fmt yuv420p \
-c:a copy \
output.mp4
-preset slow:编码速度(slow 质量高但慢)-crf 18:质量(18 视觉无损,23 默认,28 低质量)-pix_fmt yuv420p:像素格式(兼容性最好)
CRF 推荐值:
- 18:视觉无损
- 20:高质量
- 23:默认
- 26:中等质量
- 30:低质量
ASS 字幕参数
ass 滤镜支持参数:
-vf "ass=subtitle.ass:original_size=1920x1080:fontsdir=/path/to/fonts"
original_size:字幕设计分辨率(与 ASS 的 PlayRes 对应)fontsdir:字体目录(如果用了非系统字体)
多字幕叠加
ffmpeg -i video.mp4 \
-vf "ass=zh.ass,ass=en.ass" \
-c:v libx264 -crf 18 \
-c:a copy \
output.mp4
滤镜按顺序应用,后一个 ass 滤镜在前一个的结果上叠加。
字幕 + 其他滤镜
ffmpeg -i video.mp4 \
-vf "scale=1920:1080,ass=subtitle.ass,unsharp=5:5:1.0" \
-c:v libx264 -crf 18 \
-c:a copy \
output.mp4
先缩放到 1080p,再叠加字幕,最后锐化。
硬件加速
CPU 编码慢,硬件加速能快 5-10 倍。
NVIDIA NVENC
ffmpeg -i video.mp4 \
-vf "ass=subtitle.ass" \
-c:v h264_nvenc \
-preset p6 \
-tune hq \
-rc vbr \
-cq 20 \
-b:v 0 \
-c:a copy \
output.mp4
h264_nvenc:NVIDIA H.264 编码器preset p6:p1-p7,p6 质量好-cq 20:质量(类似 CRF)-rc vbr:可变码率
需要 NVIDIA 显卡和 ffmpeg 编译时启用 nvenc。
Intel QSV
-c:v h264_qsv -preset veryslow -global_quality 20
AMD AMF
-c:v h264_amf -quality quality -rc cqp -qp_i 20 -qp_p 20
硬件加速质量略低于 CPU 编码,但速度快很多。日常生产推荐硬件加速,最终交付用 CPU 编码。
流复制与重编码混合
有时只需要重编码视频,音频和字幕直接复制:
ffmpeg -i input.mkv \
-map 0:v:0 -map 0:a:0 -map 0:s:0 \
-c:v libx264 -crf 18 \
-c:a copy \
-c:s copy \
output.mkv
-map 0:v:0:选择第 0 个视频流-map 0:a:0:选择第 0 个音频流-map 0:s:0:选择第 0 个字幕流- 视频 libx264 重编码,音频和字幕 copy
这种混合模式在实际工作中最常用。
码率控制
CRF(恒定质量)
-crf 23
CRF 是质量优先,码率会根据画面复杂度自动调整。推荐用于存档。
2-pass(恒定码率)
# 第一次:分析
ffmpeg -i input.mp4 -c:v libx264 -b:v 4000k -pass 1 -an -f mp4 /dev/null
# 第二次:编码
ffmpeg -i input.mp4 -c:v libx264 -b:v 4000k -pass 2 -c:a copy output.mp4
2-pass 是码率优先,质量略低于 CRF 但码率可控。推荐用于流媒体分发。
CBR(绝对恒定码率)
-minrate 4000k -maxrate 4000k -bufsize 8000k
CBR 用于直播或严格码率限制场景。
封装格式选择
| 格式 | 字幕支持 | 兼容性 | 推荐场景 |
|---|---|---|---|
| MKV | ASS/SRT/VTT | 桌面播放器 | 字幕组归档 |
| MP4 | mov_text | 全平台 | 网页/移动 |
| WebM | WebVTT | Chrome/Firefox | 网页 |
| MOV | tx3g | Apple 设备 | 苹果生态 |
字幕组的标准配置:
- 工作文件:MKV(保留 ASS 全部样式)
- 网页分发:MP4(兼容性好,字幕用 mov_text)
- 移动端:MP4(同上)
- 直播:HLS + WebVTT
常见错误
字体缺失
Error: font not found: HarmonyOS Sans SC
解决:把字体文件放到 ~/.fonts/ 或在命令里指定 fontsdir:
-vf "ass=subtitle.ass:fontsdir=/path/to/fonts"
字幕错位
字幕位置与视频画面不匹配。
原因:ASS 的 PlayResX/PlayResY 与视频分辨率不一致。
解决:在 ASS 文件里修改 PlayRes 为视频实际分辨率:
PlayResX: 1920
PlayResY: 1080
或者用 original_size 参数:
-vf "ass=subtitle.ass:original_size=1920x1080"
字幕显示延迟
字幕比声音晚 200 毫秒以上。
解决:用 -itsoffset 调整字幕时间戳:
ffmpeg -i video.mp4 -itsoffset 0.2 -i subtitle.ass -c copy -c:s ass output.mkv
正数延后字幕,负数提前字幕。
FFmpeg 是字幕工程师的瑞士军刀。
翻译理论札记
写到这里想插入一段翻译理论的思考。奈达的功能对等强调译文读者读到译文时的反应,应当与原文读者读到原文时的反应基本一致,这意味着翻译不是字面替换,而是要在目标语里重新构造等值效果。我们做字幕,观众在屏幕前只有几秒钟读完一行字,反应时间被严重压缩,所以功能对等在字幕里被推到了极端——可读性优先于忠实度。
纽马克的区分更实用:交际翻译关注译文效果,语义翻译关注原文意义。字幕绝大多数时候走交际翻译路线,但遇到关键术语、专有名词、文化负载词时又要切回语义翻译,避免观众被误导。这两条路线在字幕里不停切换,做久了会形成直觉。
韦努蒂的归化异化是另一条轴线。归化是让译文流畅得像目标语原创,异化是保留原文的陌生感。日漫字幕里大量保留"前辈""学园""王道"等词就是异化,因为这些词在中文语境里已经形成了稳定的亚文化共识,强行归化反而失味。但纪录片、欧美剧的台词又需要强归化,否则观众跳戏。题材决定策略,没有一招通吃的方案。
—— 这些理论看起来抽象,但实际做字幕时每天都在用,只是未必意识到。把直觉变成方法论,是新人到熟手的分水岭。