Demystifying the video encoder FFmpeg arguments

Demystifying the video encoder FFmpeg arguments

By | 2016-12-01T16:37:38+00:00 January 20th, 2016|Tips & Tricks|0 Comments

The Gallery Server Binary Pack includes FFmpeg, the popular open source utility that provides powerful video and audio capabilities. Gallery Server uses it to rotate videos, create web-optimized versions of your original audio and video files, and generate thumbnails from a video. Haven’t installed it yet? It’s free, so get it now (expand the ‘more downloads’ section to see it).

Let’s say you have a bunch of WMV videos you want to share with the world. Browsers must have a supporting plugin such as Silverlight in order for them to play in the browser, and an increasing number of operating systems and browsers don’t support plugins (iOS, Android, Microsoft Edge). It would be better if these videos were converted to H.264 MP4, which is natively supported by most modern browsers and operating systems, including iOS and Android.

That’s exactly what Gallery Server does when you upload a video – it preserves the original and then transcodes a copy into a 640 by 480 px MP4 video, adjusting the dimensions as needed to preserve the aspect ratio. When you view the video, Gallery Server gives you the MP4, which downloads fast, plays smoothly, and looks great in any browser.

The transcoding is done by FFmpeg, which is configured on the Video & Audio page in the site admin area.

FFmpeg encoder settings in Gallery Server

You can read more about the various settings in the Admin Guide. For this post I’m going to focus on the FFmpeg arguments for the ‘All video to mp4’ setting:

-y -i “{SourceFilePath}” -vf “scale=min(iw*min(640/iw\,480/ih)\,iw):min(ih*min(640/iw\,480/ih)\,ih){AutoRotateFilter}” -vcodec libx264 -movflags +faststart -metadata:s:v:0 rotate=0 “{DestinationFilePath}”

It’s pretty intimidating at first glance, so let’s break it down.

-y: This flag says it’s OK to overwrite any existing file at the {DestinationFilePath}. Gallery Server already takes care to never create a file at the same location as an existing one, so this flag just adds a little robustness.

-i “{SourceFilePath}”: This specifies the full path to the original video file. At runtime, Gallery Server replaces {SourceFilePath} with the actual file path.

-vf “scale=min(iw*min(640/iw\,480/ih)\,iw):min(ih*min(640/iw\,480/ih)\,ih){AutoRotateFilter}”

This is a scale filter that tells FFmpeg to create a video that is at most 640 by 480 px while preserving the aspect ratio. It uses expressions to dynamically calculate the width and height based on the original video’s dimensions.

For the moment, let’s ignore {AutoRotateFilter}. What’s left is essentially “scale=W:H” where W and H are the width and height. The formulas aren’t quite so daunting when we look at them separately:

W = min(iw*min(640/iw\,480/ih)\,iw)

H = min(ih*min(640/iw\,480/ih)\,ih)

iw and ih are the input width and height. We have to escape the comma with a backslash, so that’s why we have ‘\,’ in there. To get a good understanding of these expressions, key them into Excel and run a few experiments. Here are a few I just did for several input sizes:

640 x 480 => 640 x 480
640 x 320 => 640 x 320
480 x 640 => 360 x 480
800 x 600 => 640 x 480
1280 x 1024 => 600 x 480
640 x 640 => 480 x 480
1280 x 1280 => 480 x 480

Now getting back to {AutoRotateFilter}, that’s a replacement parameter that instructs FFmpeg to rotate the video. This is really useful when your camera is turned sideways. Without it you’d have to turn your head when watching the video. Gallery Server inspects the original video for any orientation metadata, then uses that to replace the text {AutoRotateFilter} with one of the following values:

empty string: No rotation specified. FFmpeg creates the video with the same orientation as the original
transpose=clock: Rotate the video 90 degrees clockwise
hflip,vflip: Rotate the video 180 degrees
transpose=cclock: Rotate the video 90 degrees counterclockwise

This only scratches the surface of what you can do with a scale filter. But let’s move on.

-vcodec libx264: Use the x264 H.264/MPEG-4 AVC encoder wrapper. That is, generate an MP4 video.

-movflags +faststart This setting results in a video that starts playing after a short buffering period. Without it the entire video must be downloaded before it starts. Under the hood, it’s instructing FFmpeg to run a second pass on the video, moving the index (moov atom) to the beginning of the file. It’s documented in FFmpeg mov, mp4, ismv muxer options.

-metadata:s:v:0 rotate=0 This sets the ‘rotate’ metadata property to 0 (normal orientation) on the first video stream in the generated file. Without this setting, the video would have the same orientation property as the original. In cases where we rotated the video, that’s a problem because now the actual rotation of the file differs from the rotation meta property. It’s documented in FFmpeg main options.

“{DestinationFilePath}”: The full path to the output video file. Gallery Server updates this to a unique file path before sending it off to FFmpeg.

So there we go. Now you know what each of the pieces do, feel free to tweak the settings to fit your requirements.

About the Author:

Founder and Lead Developer of Gallery Server

Leave A Comment