为什么我连接 1920x1080p 的视频后它们仍然会被拉伸和扭曲?

为什么我连接 1920x1080p 的视频后它们仍然会被拉伸和扭曲?

我有几个具有不同长宽比的视频。

我使用此命令将它们全部放入 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

查询widthheightSARDAR 使用 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 之外的宽高比添加一些填充(水平或垂直黑条)。

以下是一些例子如何添加这样的黑条。

相关内容