如何使视频适合特定尺寸,但不使用 FFmpeg 对其进行放大?

如何使视频适合特定尺寸,但不使用 FFmpeg 对其进行放大?

我需要将视频调整为 640x360(我的手机播放器可以处理的最大值),同时还要保持纵横比,但如果视频小于 640x360,我还希望视频保持不变(毕竟放大它是没有意义的)。

有没有办法使用 ffmpeg 的命令行来获得这种行为?

答案1

使用较新的 ffmpeg 版本,您可以使用scale过滤器的force_original_aspect_ratio选项。例如,要将视频调整为 1280×720,而无需升级(请参阅这个帖子了解更多信息):

ffmpeg -i input.mp4 -filter:v "scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output.mp4

在这里,scale如果输入视频大于 1280×720,则过滤器会将其缩放到 1280×720。如果输入视频小于 1280×720,则不会对其进行放大。如果输出视频pad的宽高比或大小与目标大小不同,则需要使用过滤器将其缩放到 1280×720。


对于较旧的 ffmpeg 版本,有一个有点棘手的解决方法。首先,定义输出的宽度、高度和纵横比。这将为我们节省一些输入工作。

width=640; height=360
aspect=$( bc <<< "scale=3; $width / $height") # <= floating point division

现在,让我们应用超级复杂的过滤命令吉姆·沃勒尔写道

ffmpeg -i input.mp4 -vf "scale = min(1\,gt(iw\,$width)+gt(ih\,$height)) * (gte(a\,$aspect)*$width + \
lt(a\,$aspect)*(($height*iw)/ih)) + not(min(1\,gt(iw\,$width)+gt(ih\,$height)))*iw : \
min(1\,gt(iw\,$width)+gt(ih\,$height)) * (lte(a\,$aspect)*$height + \
gt(a\,$aspect)*(($width*ih)/iw)) + not(min(1\,gt(iw\,$width)+gt(ih\,$height)))*ih" \
output.mp4

我不会真正解释这一切的作用,但基本上你可以输入任何视频,它只会缩小比例,而不会放大。如果你愿意的话,你可以将过滤器分解成单独的表达式。也许可以缩短它,但它也是这样工作的。

答案2

更易读的版本如下所示:

-filter_complex "scale=iw*min(1\,min(640/iw\,360/ih)):-1"

640/iw 是水平缩放因子,360/ih 是垂直缩放因子

您希望将缩放后的图像放入输出框内并保持(存储)纵横比。您可以通过使用最小函数选择最小缩放因子来实现:min(640/iw, 360/ih)

您想要防止任何升级(即缩放因子> 1.0),因此您添加另一个最小函数:min(1,min(640 / iw,360 / ih))

下一步是通过将比例因子与输入宽度和输入高度相乘来计算输出分辨率:
输出宽度 = iw * min(1, min(640/iw, 360/ih))
输出高度 = ih * min(1, min(640/iw, 360/ih))

最后一步是构造过滤器命令。无需指定输出高度,您可以指定 -1,ffmpeg 将通过应用与宽度相同的缩放因子来保持纵横比。

答案3

我也遇到了同样的问题,但通过将视频调整为 640x640 的正方形解决了(因为用智能手机制作的视频是垂直的)。

因此使用伊默齐逻辑和一些研究我最终得到以下结果:

-vf "scale=iw*min(1\,if(gt(iw\,ih)\,640/iw\,(640*sar)/ih)):(floor((ow/dar)/2))*2"

最后一部分是为了使高度能被 2 整除,这是许多编码器所需要的。

相关内容