用FFmpeg保持纵横比

用FFmpeg保持纵横比,ffmpeg,video-processing,aspect-ratio,Ffmpeg,Video Processing,Aspect Ratio,我需要使用FFmpeg转换一组视频文件。我运行了一个Bash文件,可以很好地转换所有文件,但是如果转换的文件不是16:9格式,则会出现问题 当我将屏幕大小固定为-s 720x400时,如果原稿的纵横比为4:3,FFmpeg将创建一个16:9的输出文件,从而扭曲纵横比 是否有一种设置允许将纵横比设置为主要参数,并调整大小(例如,仅通过固定X或Y尺寸)?您可以使用ffmpeg-i获取原始文件的尺寸,并在编码命令中使用该设置。你在什么平台上使用ffmpeg?我很久以前就问过这个问题,但我实际上得到了一

我需要使用FFmpeg转换一组视频文件。我运行了一个Bash文件,可以很好地转换所有文件,但是如果转换的文件不是16:9格式,则会出现问题

当我将屏幕大小固定为-s 720x400时,如果原稿的纵横比为4:3,FFmpeg将创建一个16:9的输出文件,从而扭曲纵横比


是否有一种设置允许将纵横比设置为主要参数,并调整大小(例如,仅通过固定X或Y尺寸)?

您可以使用ffmpeg-i获取原始文件的尺寸,并在编码命令中使用该设置。你在什么平台上使用ffmpeg?

我很久以前就问过这个问题,但我实际上得到了一个当时我不知道的解决方案——为了保持纵横比,你应该使用视频过滤器比例,这是一个非常强大的过滤器

您可以这样简单地使用它:

-vf "scale=640:-1" 
这将固定宽度并提供保持纵横比所需的高度。但您也可以使用许多其他选项,甚至数学函数,请查看此处的文档-

例如:

1920x1080宽高比16:9=>640x480宽高比4:3:

ffmpeg -y -i import.media -aspect 16:9 scale=640x360,pad=640:480:0:60:black output.media
纵横比16:9,大小宽度640像素=>高度360像素:
最终输出尺寸为640x480,焊盘为60像素黑色图像(顶部和底部):

在遇到错误之前工作得很好

[libx264 @ 0x2f08120] height not divisible by 2 (640x853)
因此,最通用的方法是使用过滤器表达式:

scale=640:trunc(ow/a/2)*2
它采用输出宽度(ow),除以纵横比(a),除以2,截断小数点后的数字并乘以2。它保证生成的高度可以被2整除

归功于

更新

正如评论所指出的,更简单的方法是使用
-vf“scale=640:-2”

感谢@BradWerth提供了优雅的解决方案

尽管这些答案中的大多数都很好,但我一直在寻找一个可以在保持纵横比的同时将尺寸调整为目标尺寸(宽度或高度)的命令。我能够使用ffmpeg的实现这一点

以下是相关的视频过滤器,目标尺寸为512:

-vf“缩略图,比例=”如果(gt(iw,ih),512,trunc(oh*a/2)*2):“如果(gt(iw,ih),trunc(ow/a/2)*2512”


对于输出宽度:

'if(gt(iw,ih),512,trunc(oh*a/2)*2)

如果宽度大于高度,则返回目标,否则返回比例宽度


对于输出高度:

'if(gt(iw,ih),trunc(ow/a/2)*2512)


如果宽度大于高度,则返回比例高度,否则返回目标。

使用
强制原始纵横比
,从:


如果您试图拟合边界框,那么按照使用
force\u original\u aspect\u ratio
是一个很好的起点

但是,如果您的输入视频大小怪异,并且您的编码格式要求维度可以被2整除,则这不起作用,从而导致错误

在这种情况下,可以在
scale
函数中使用表达式求值,就像在中使用的那样

假设输出边界框为720x400:

-vf“scale='trunc(min(1,min(720/iw,400/ih))*iw/2)*2':'trunc(min(1,min(720/iw,400/ih))*ih/2'

要分解这一点:

  • min(1,min(720/iw,400/ih)
    查找要在边界框(from)中拟合的比例因子,将其限制为最大值1,以确保其仅缩小比例,以及
  • trunc(*iw/2)*2
    trunc(*iw/2)*2
    确保维度可以被2整除,方法是除以2,使结果为整数,然后再乘以2

这就不需要在编码之前查找输入视频的尺寸。

如果存在“-aspect x:y”,并且输出文件格式为ISO媒体文件格式(mp4),则ffmpeg将pasp atom(PixelAspectRatioBox)添加到视频曲目中的stsd框中,以向播放器指示预期的尺寸 纵横比。播放器应分别缩放视频帧。
编码或转码之前不需要缩放视频以适应纵横比,它应该由播放器执行。

嗨,我在Linux上使用它。理想情况下,我希望有一个bash脚本,可以在不考虑纵横比的情况下工作。我想我可以手动调整它以获得非宽屏分辨率,但ffmpeg I thoug中有无数选项我只是不知道一个技巧设置…是的,这是一个答案,因为通过使用原始尺寸并通过简单的计算将其缩小(或增大),OP可以“手动”解决问题。我发现它在任何情况下都很有用。就我个人而言,我很高兴发布了这个答案。这很好,但我仍然发现,如果高度不能被2整除,我可能会遇到问题。知道如何解决这个问题吗?注意
-vf“scale=640:-2”
这里也有答案。或者,如果您想指定高度并让ffmpeg按比例设置宽度,
scale=trunc(oh*a/2)*2:min(480\,iw)
@BradWerth这有没有记录在案?@Adam我想不起来了。我相信我在实现这一出色的答案时只是在阅读选项和玩设置。小调:
scale=640:trunc(ow/a/2)*2
scale=640:-2
都是足够的答案,但不一定相等。前者中的截断可以给出一个更小的值,例如2像素,取决于输入源的大小。@AndersEmil据我所知,它只适用于x264,与宽度和高度相关。我只需要从640x480到1280x720并且使用了
-aspect 16:9-vf scale=960x720,pad=1280:720:160:0:white
(我也需要白色填充而不是黑色)。谢谢!我需要走相反的路,从640x480到1920x1080,使用柱形装箱:
-vf“scale=1440x1080,pad=1920:1080:240:0:black”
我用它工作了
[libx264 @ 0x2f08120] height not divisible by 2 (640x853)
scale=640:trunc(ow/a/2)*2
ffmpeg -i input.mp4 -vf scale=720:400:force_original_aspect_ratio=decrease output.mp4