Resize videos with different widths to a fixed height preserving aspect ratio with ffmpeg

I'd like to convert a lot of video files to flash video for our company's website. I have a requirement that all of the videos must be in 360p format, so their size would be Nx360.

FFMpeg uses -s argument to specify target resolution as WxH. I don't know Width, as it depends on source file aspect ratio. If source is 640x480, target will be 480x360. If source is 848x480, target will be 636x360.

Is there a way to do it with some switch of ffmpeg? That it will preserve aspect ratio and I'll only specify the height of target video?

I could easily solve it by making a program that will launch ffprobe to get source video size, calculate aspect ratio and then calculate a new width.


Solution 1:

You could try adding this video filter:

-vf "scale=-1:360" 

-1 in this case means variable / unknown, thus this filter resizes the video to preserve the aspect ratio of the input, keeping 360 as the height.

For me this achieved the same result you are looking for.

Solution 2:

Don't have enough points to comment on an existing answer yet, but this is following user65600's answer and going further when specific codecs require a width/height that is divisible by 2 (e.g. libx264)

When you use -1 (variable/unknown), it can return an odd #. To guarantee an even #, you have to use something like trunc(ow/a/2)*2, which'll automatically calculate the closest even # while preserving the aspect ratio.

-vf "scale=trunc(ow/a/2)*2:360"

Source: https://ffmpeg.org/trac/ffmpeg/ticket/309

Solution 3:

-vf "scale=trunc(ow/a/2)*2:360" doesn't work because of "self-referencing" error.

Instead, the following works :

-vf "scale=-1:360, scale=trunc(iw/2)*2:360"

Self-referencing is thus avoided by two consecutive scaling, and the rounding is done in the second step. Cute, isn't it? :)