我有几个具有不同长宽比的视频。
我使用此命令将它们全部放入 1920x1080p 帧内:
ffmpeg -i input -vcodec libx264 -s 1920x1080 -r 30 -strict experimental output
这是可行的,并且所有视频在 1080p 分辨率下都保持其纵横比。
完成后,我将它们与此连接起来,看到两种意外的行为:
ffmpeg -f concat -safe 0 -i videolist.txt -vcodec libx264 -s 1920x1080 -r 30 -strict experimental -c copy 1080p_merged\output.mp4
首先,垂直视频会水平拉伸,即使它们已经是 1920x1080p 帧,同时保持其宽高比。这怎么可能呢?
其次,我发现帧速率从我每次设置的 30fps 下降(原始视频也是 30fps),到 29.95 或 29.81 左右。
我究竟做错了什么?
答案1
奇怪的长宽比的原因与 SAR 有关 -样本纵横比。
通常 SAR 为 1:1,应用方形像素。
非 1:1 的 SAR 值应用非方形像素。
您的第一个命令修改了 SAR 属性,这就是导致奇怪结果的原因。
让我们首先构建一些合成视频样本:
ffmpeg -y -f lavfi -i testsrc=size=320x240:rate=30:duration=5 -vcodec libx264 -pix_fmt yuv420p -crf 17 in1.mkv
ffmpeg -y -f lavfi -i testsrc=size=640x120:rate=30:duration=5 -vcodec libx264 -pix_fmt yuv420p -crf 17 in2.mkv
ffmpeg -y -f lavfi -i testsrc=size=240x320:rate=30:duration=5 -vcodec libx264 -pix_fmt yuv420p -crf 17 in3.mkv
使用命令将分辨率转换为 1920x1080:
ffmpeg -i in1.mkv -vcodec libx264 -pix_fmt yuv420p -crf 17 -s 1920x1080 -r 30 out1.mp4
ffmpeg -i in2.mkv -vcodec libx264 -pix_fmt yuv420p -crf 17 -s 1920x1080 -r 30 out2.mp4
ffmpeg -i in3.mkv -vcodec libx264 -pix_fmt yuv420p -crf 17 -s 1920x1080 -r 30 out3.mp4
查询width
、height
和SAR
DAR
使用 FFprobe:
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,sample_aspect_ratio,display_aspect_ratio -of default=noprint_wrappers=1 in1.mkv
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,sample_aspect_ratio,display_aspect_ratio -of default=noprint_wrappers=1 in2.mkv
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,sample_aspect_ratio,display_aspect_ratio -of default=noprint_wrappers=1 in3.mkv
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,sample_aspect_ratio,display_aspect_ratio -of default=noprint_wrappers=1 out1.mp4
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,sample_aspect_ratio,display_aspect_ratio -of default=noprint_wrappers=1 out2.mp4
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,sample_aspect_ratio,display_aspect_ratio -of default=noprint_wrappers=1 out3.mp4
FFprobe 输出:
in1.mkv
width=320
height=240
sample_aspect_ratio=1:1
display_aspect_ratio=4:3
in2.mkv
width=640
height=120
sample_aspect_ratio=1:1
display_aspect_ratio=16:3
in3.mkv
width=240
height=320
sample_aspect_ratio=1:1
display_aspect_ratio=3:4
out1.mp4
width=1920
height=1080
sample_aspect_ratio=3:4
display_aspect_ratio=4:3
out2.mp4
width=1920
height=1080
sample_aspect_ratio=3:1
display_aspect_ratio=16:3
out3.mp4
width=1920
height=1080
sample_aspect_ratio=27:64
display_aspect_ratio=3:4
可以看出,输入视频的 SAR 是,1:1
但输出视频的 SAR 受原始输入视频分辨率的影响。
事实上,SAR 并非如此,这1:1
会导致奇怪的纵横比问题。
注意:我不知道为什么 FFmpeg 默认修改 SAR,但它就是这样工作的。
为了解决这个问题,你可以使用scale
过滤器,setsar
如所述这里:
ffmpeg -y -i in1.mkv -vf scale=1920:1080,setsar=1:1 -vcodec libx264 -pix_fmt yuv420p -crf 17 -s 1920x1080 -r 30 out1.mp4
ffmpeg -y -i in2.mkv -vf scale=1920:1080,setsar=1:1 -vcodec libx264 -pix_fmt yuv420p -crf 17 -s 1920x1080 -r 30 out2.mp4
ffmpeg -y -i in3.mkv -vf scale=1920:1080,setsar=1:1 -vcodec libx264 -pix_fmt yuv420p -crf 17 -s 1920x1080 -r 30 out3.mp4
FFprobe 输出:
width=1920
height=1080
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
width=1920
height=1080
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
width=1920
height=1080
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
现在 SAR 是1:1
, DAR 是16:9
。
您可以连接上述文件,而无需修改纵横比。
修复FPS:
平均FPS是一个估计值,不准确的原因是多方面的。
很难说出轻微不准确的原因。
根据 concat demuxer文档:
所有文件必须具有相同的流(相同的编解码器、相同的时间基准等)
我们可以尝试-r 30
用每秒帧数过滤器(设置时间基准,并修复时间点以防万一......):
ffmpeg -y -i in1.mkv -vf scale=1920:1080,setsar=1:1,fps=fps=30,settb=AVTB,setpts=PTS-STARTPTS -vcodec libx264 -pix_fmt yuv420p -crf 17 out1.mp4
ffmpeg -y -i in2.mkv -vf scale=1920:1080,setsar=1:1,fps=fps=30,settb=AVTB,setpts=PTS-STARTPTS -vcodec libx264 -pix_fmt yuv420p -crf 17 out2.mp4
ffmpeg -y -i in3.mkv -vf scale=1920:1080,setsar=1:1,fps=fps=30,settb=AVTB,setpts=PTS-STARTPTS -vcodec libx264 -pix_fmt yuv420p -crf 17 out3.mp4
我不确定它是否能解决 FPS 问题。
注意:
准备输入文件然后重新编码并不是最好的解决方案,因为您要对视频进行两次重新编码,从而降低质量。
我建议你使用连接过滤器,而不是 concat demuxer,并在一个命令中完成所有操作(如果它不是太困难的话)。
答案2
该选项-s 1920x1080
没有定义放置这些视频的“框架边框”。它定义了输出视频的分辨率,并间接定义了输出视频的预期宽高比为 16:9。
当您合并具有不同纵横比的视频时,它们将被拉伸以达到相同的纵横比。
为了防止这种情况,您可以在将输入视频缩放到 1920x1080 之前,以除 16:9 之外的宽高比添加一些填充(水平或垂直黑条)。
以下是一些例子如何添加这样的黑条。