保持FFMPEG宽高比

0-a*_*pha 43 ffmpeg

我需要使用ffmpeg转换一堆视频文件.我运行一个很好地转换所有文件的bash文件,但是如果转换的文件不是16:9格式则会出现问题.当我将屏幕尺寸固定为-s 720x400时,如果原件的纵横比为4:3,则ffmpeg会创建一个16:9输出文件,拧紧纵横比.

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

men*_*nte 60

-vf "scale=640:-1"
Run Code Online (Sandbox Code Playgroud)

很有效,直到你遇到错误

[libx264 @ 0x2f08120] height not divisible by 2 (640x853)
Run Code Online (Sandbox Code Playgroud)

所以最通用的方法是使用过滤器表达式:

scale=640:trunc(ow/a/2)*2
Run Code Online (Sandbox Code Playgroud)

它取输出宽度(ow),除以宽高比(a),除以2,截断小数点后的数字并乘以2.它保证得到的高度可被2整除.

ffmpeg trac

UPDATE

正如评论指出的更简单的方法是使用-vf "scale=640:-2".致@BradWerth优雅解决方案

  • 或者,如果你想指定高度并让ffmpeg按比例设置宽度,`scale = trunc(oh*a/2)*2:min(480 \,iw)`. (9认同)
  • 小注意事项: `scale=640:trunc(ow/a/2)*2` 和 `scale=640:-2` 都是足够的答案,但不一定等效。前者中的截断可以给出例如2个像素的值,该值更小,具体取决于输入源的大小。 (2认同)
  • @AndersEmil 据我所知,它仅适用于 x264 并且与宽度和高度相关 (2认同)

小智 28

例如:

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

ffmpeg -y -i import.media -aspect 16:9 scale=640x360,pad=640:480:0:60:black output.media
Run Code Online (Sandbox Code Playgroud)

宽高比16:9,尺寸宽度640pixel =>高度360pixel:
最终输出尺寸为640x480,并且垫60像素黑色图像(顶部和底部):

"-vf scale=640x360,pad=640:480:0:60:black"
Run Code Online (Sandbox Code Playgroud)

  • 我只需要从640x480到1280x720并使用`-aspect 16:9 -vf scale = 960x720,pad = 1280:720:160:0:white(我也需要白色填充而不是黑色).谢谢! (2认同)

0-a*_*pha 20

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

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

-vf "scale=640:-1" 
Run Code Online (Sandbox Code Playgroud)

这将固定宽度并提供保持纵横比所需的高度.但您也可以使用许多其他选项甚至数学函数,请查看此处的文档 - http://ffmpeg.org/ffmpeg.html#scale

  • 请注意`-vf"scale = 640:-2"`答案. (7认同)
  • 这很好但我仍然发现如果高度不能被2整除,我可能会遇到问题.任何想法如何解决这个问题? (3认同)

xme*_*eko 10

使用force_original_aspect_ratio,来自ffmpeg trac:

ffmpeg -i input.mp4 -vf scale=720:400:force_original_aspect_ratio=decrease output.mp4
Run Code Online (Sandbox Code Playgroud)

  • 我刚刚用 ffmpeg 3.4 和 3.2.9 测试了它,它很有魅力。视频变为:`719x400` 但没有错误。我可以用 VLC 媒体播放器播放它(在右边看到额外的像素)。Ubuntu 原生视频播放器也播放得很好。然后 ffmpeg 可以读取文件,然后转换为另一个文件 (2认同)

Cha*_*lie 9

虽然这些答案中的大多数都很棒,但我一直在寻找可以在保持纵横比的同时调整目标尺寸(宽度高度)的命令.我能够使用ffmpeg的Expression Evaluation完成此任务.

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

-vf "thumbnail,scale='if(gt(iw,ih),512,trunc(oh*a/2)*2)':'if(gt(iw,ih),trunc(ow/a/2)*2,512)'"


对于输出宽度:

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

如果width大于height,则返回目标,否则返回比例宽度.


对于输出高度:

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

如果width大于height,则返回比例高度,否则返回目标.


tvS*_*tic 6

如果你想要一个边界框,那么force_original_aspect_ratio根据xmedeko的答案使用是一个很好的起点.

但是,如果您的输入视频具有奇怪的大小并且您要编码为要求维度可被2整除的格式,则此操作无效,从而导致错误.

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

假设输出边界框为720x400:

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

打破这个:

  • min(1,min(720/iw,400/ih)找到适合在边界框内的缩放因子(从此处开始),将其限制为最大值1,以确保它仅缩小,并且
  • trunc(<scaling factor>*iw/2)*2trunc(<scaling factor>*iw/2)*2确保维度可以除以2除以2,使结果为整数,然后将其乘以2.

这消除了在编码之前找到输入视频的尺寸的需要.