我正在使用 MakeMKV 创建我的蓝光光盘的数字副本,并创建了一个脚本对生成的 MKV 文件进行一些处理:
- 重新采样(并根据需要缩小尺寸)视频
- 将单个音轨转换为 AAC 和 AC3(针对我想要的每种语言)并丢弃“输入”音轨
- 复制特定语言的所有字幕
- 复制章节标记
我想扩展脚本以刻录单个 PGS 字幕轨道。但是,当我添加适当的叠加过滤器时,刻录的字幕不同步。
一般来说,脚本使用mkvextract
提取相关的视频和音频轨道,并使用ffmpeg
将它们转换为新轨道。转换后,所有输出轨道均使用 合并mkvmerge
。
对于字幕处理,我使用mkvextract
将适当的字幕轨道提取到.sup
文件中并将其作为附加输入传递给ffmpeg
:
ffmpeg -i ./title_t00/in/title_t00.mkv.h264 \
-i ./title_t00/in/title_t00.mkv.en.sup \
-codec:v libx264 \
-filter_complex "[0:v][1:s]overlay[v1]; [v1]scale=w=-2:h=480:flags=gauss[v2]"\
-map "[v2]" \
-sws_flags gauss \
-crf 10 \
./title_t00/out/title_t00.mkv.h264
过滤器从第一个输入获取视频轨道,从第二个输入获取字幕轨道,并将两者叠加。这样会生成一个新的视频流,该视频流v1
会通过scale
过滤器,结果会被保存。
如上所述,叠加层可以工作,但字幕不同步。有什么方法可以正确同步它们吗?
或者是否存在某种神奇的ffmpeg
调用方式可以一次性完成所有操作?
答案1
研究流映射后,我发现了以下解决方案:
ffmpeg -i INPUT.mkv \
-filter_complex "[0:v][0:s]overlay[v1]; [v1]scale=w=-2:h=480:flags=gauss[v2]"
-map "[v2]" \
-map 0:1
-map 0:1
-map 0:2
-codec:v:0 libx264 -crf 10
-codec:a:0 libfdk_aac -ac:a:0 2
-codec:a:1 ac3 -ac:a:1 6
-codec:s copy \
OUTPUT.mkv
该过滤器将第一个视频轨道与第一个字幕轨道叠加,缩小到 480p 的高度,并将过滤后的视频流映射为第一个输出流。接下来的两个-map
将音频流两次传递到输出,这样我就可以创建 AAC 和 AC-3 流。最后一个-map
用于字幕流,它只是复制到输出。
这需要进行微调,以便支持音频流的多种语言,过滤任何不需要的字幕轨道,并过滤刻录的字幕轨道。
看如何在 FFMPEG 中映射流了解有关流映射的更多信息。