Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maintaining aspect ratio with FFmpeg

People also ask

Can FFmpeg resize an image?

FFMpeg is using the libswscale library to resize the input. The libswscale library contains video image scaling and colorspace/pixelformat conversion routines. When we scale an image without specifying the size, the input dimension is used as the default value. We set the width of the output image to 250 pixels.

How do I use FFmpeg without losing quality?

Instead of -sameq (removed by FFMpeg), use -qscale 0 : the file size will increase but it will preserve the quality.

How does FFmpeg reduce video size?

Download and set up FFmpeg on your computer, use command line to compress video with FFmpeg by changing video codec format, lowering down bitrate, cutting video length, etc. For example, set CRF in FFmpeg to reduce video file size (ffmpeg -i input. mp4 -vcodec libx264 -crf 24 output.

What is Setsar in FFmpeg?

The setsar filter sets the Sample (aka Pixel) Aspect Ratio for the filter output video. Note that as a consequence of the application of this filter, the output display aspect ratio will change according to the equation above.


-vf "scale=640:-1"

works great until you will encounter error

[libx264 @ 0x2f08120] height not divisible by 2 (640x853)

So most generic approach is use filter expressions:

scale=640:trunc(ow/a/2)*2

It takes output width (ow), divides it by aspect ratio (a), divides by 2, truncates digits after decimal point and multiplies by 2. It guarantees that resulting height is divisible by 2.

Credits to ffmpeg trac

UPDATE

As comments pointed out simpler way would be to use -vf "scale=640:-2". Credits to @BradWerth for elegant solution


For example:

1920x1080 aspect ratio 16:9 => 640x480 aspect 4:3:

ffmpeg -y -i import.media -aspect 16:9 scale=640x360,pad=640:480:0:60:black output.media

aspect ratio 16:9 , size width 640pixel => height 360pixel:
With final output size 640x480, and pad 60pixel black image (top and bottom):

"-vf scale=640x360,pad=640:480:0:60:black"

I've asked this a long time ago, but I've actually got a solution which was not known to me at the time -- in order to keep the aspect ratio, you should use the video filter scale, which is a very powerful filter.

You can simply use it like this:

-vf "scale=640:-1" 

Which will fix the width and supply the height required to keep the aspect ratio. But you can also use many other options and even mathematical functions, check the documentation here - http://ffmpeg.org/ffmpeg.html#scale


Although most of these answers are great, I was looking for a command that could resize to a target dimension (width or height) while maintaining aspect ratio. I was able to accomplish this using ffmpeg's Expression Evaluation.

Here's the relevant video filter, with a target dimension of 512:

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


For the output width:

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

If width is greater than height, return the target, otherwise, return the proportional width.


For the output height:

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

If width is greater than height, return the proportional height, otherwise, return the target.


Use force_original_aspect_ratio, from the ffmpeg trac:

ffmpeg -i input.mp4 -vf scale=720:400:force_original_aspect_ratio=decrease output.mp4