This guide will explain how to encode video in the following formats: .mp4 (h264), .webm (VP8), .ogv (theora), .3gp (h263) and .mov (mpg), which should provide you with all the formats required to have your video shown on all devices.

FFmpeg is an extremely versatile command-line video and audio tool. You can read more about how to get it on ffmpeg.org.

When encoding videos, make sure you have the best possible input source available (uncompressed is preferred). The better the quality of the input source, the better the end result will be.

Quick summary:

For the impatient, here are the standard commands for each of the listed video formats. No cropping or resizing - just recompression of Video and Audio. If need be, you can adjust the -vb (video bitrate) if you are working with different input/output sizes.

.mp4

The preferred container for internet based video. H264 video and AAC audio. Supported by all major browsers.

600Kb video bitrate should be sufficient for a 960x540.mp4 video.

ffmpeg -y -i 960x540.mp4 -qmin 10 -qmax 40 -crf 30 -c:v libx264 -b:v 600k -c:a aac -ar 48000 -b:a 128k 960x540-recompressed.mp4

.webm

The open source alternative to .mp4. VP8/9 video and Vorbis audio. Supported by Chrome 4 and Firefox 35.

600Kb video bitrate should be sufficient for a 960x540.webm video.

ffmpeg -y -i 960x540.mp4 -qmin 10 -qmax 40 -crf 30 -c:v libvpx -b:v 600k -c:a libvorbis -ar 48000 -b:a 128k 960x540-recompressed.webm

.ogv

The "even more open source" alternative. Theora video and Vorbis audio. Supported from Chrome 4 and Firefox 3.5.

Theora requires about 3 timers higher bitrate to get a similar video quality, and omitting the qmin and qmax generally gives a better result.

ffmpeg -y -i 960x540.mp4 -c:v libtheora -b:v 1800k -c:a libvorbis -ar 48000 -b:a 128k 960x540-recompressed.ogv

.3gp

The "mobile" standard. H263 video and AAC audio. Fixed CIF output format required. Supported by almost all mobile devices. 

In this example we output to QCIF (176x144) and use only 200Kb video bitrate due to the smaller view size.

ffmpeg -y -i 960x540.mp4 -c:v h263 -b:v 200k -c:a aac -ac 1 -ar 32000 -b:a 32k -s qcif 176x144-recompressed.3gp

.mov

The original (and old) Quicktime container. MP2 video and MP3 audio. This is as standard as it gets.

The video compression is pretty far from what we know today, so let FFmpeg decide the bitrate to achieve a decent quality.

ffmpeg -y -i 960x540.mp4 -c:v mpeg2video -c:a libmp3lame -f mov 960x540-recompressed.mov

Getting into the details

Each "format" is indeed a combination of a video codec and an audio codec. Actually, what we tend to refer to as a "format" is really a container, which in some cases can contain multiple video and audio tracks. In theory you can combine the video and audio codecs as you please and add them to any container format you like, but then it will probably not play back as you intended across platforms and devices.

On purpose we skip specific windows formats as those are not strictly required to support older windows platforms, where .mov will also work.

Breakdown of the command

-i #INPUT FILE# -qmin #MINIMUM QUALITY# -qmax #MAXIMUM QUALITY# -crf #CONSTANT RATE FACTOR# -c:v #VIDEO CODEC# -b:v #VIDEO BITRATE# -c:a #AUDIO CODEC# -ar #SAMPLE RATE# -b:a #AUDIO BITRATE# #OUTPUT FILE#

Note: There are slightly different settings available when encoding for the different codecs. The setting options are provided by the codec and not by ffmpeg itself.

Choose the right codec combination.

mp4 = H264 + AAC

The .mp4 container expects H264 video and AAC audio.

-c:v libx264 -c:a aac

webm = VP8 / Vorbis

The .webm container expects VP8 video and Vorbis audio.

-c:v libvpx -c:a libvorbis

ogv = Theora + Vorbis

The .ogv container expects Theora video and Vorbis audio.

-c:v libtheora -c:a libvorbis

3gp = H263 / AAC

The .3gp container expects H263 video and AAC audio.

-c:v h263 -c:a aac

mov = MP2 + MP3

The .mov container expects MP2 video and MP3 audio.

-c:v mpeg2video -c:a libmp3lame

A note on AAC

The AAC audio codec, comes in two flavours. The natively build-in aac and the slightly better Fraunhofer FDK AAC, libfdk_aac, which requires your FFmpeg to be built using --enable-libfdk-aac. You can check if you have the Fraunhofer codec installed by checking the list of installed codecs:

ffmpeg -codecs

Fine tune the compression

The qmin, qmax, crf, b:v and b:a are the most relevant for optimising the video output.

The qmin and qmax specifies a quality range. The accepted values are 0-63, but qmin should always be less the qmax.

The crf specifies the constant rate factor. Accepted values are 0-63. Lower value means higher quality and larger filesize.

The b:v and the b:a parameters sets the video and audio bitrates. They are pretty much straight forward. The lower the bitrate, the smaller the output file. Bitrates are stated in b (bytes), k (kilobytes) or m (megabytes).

Note: The older codecs (Theora, h263 and mpeg2video) does not fully support qmin, qmax and crf. I recommend you omit them, when using these codecs.

Change video output size

You can easily specify the output size for your video, but if the input and the output size does not have the same proportion, the result will be distorted.

Change the output size:

-s WIDTHxHEIGHT

To get the output video in 960x540, use:

-s 960x540

Input 960x540 to output 480x270:

ffmpeg -y -i 960x540.mp4 -s 480x270 480x270-resized.mp4

Crop the video

If you want to crop a video, you should apply a cropping as well as a new output size.

Cropping is specified using the -vf flag with a crop value. The crop value is composed of width, height, offset top, offset bottom.

If you want to do a centered crop of a 960x540 video to 920x530 it would look like this:

-vf crop=920:530:20:5 -s 920x530

To crop from top left corner it would look like this:

-vf crop=920:530:0:0 -s 920x530

Pad the video

To apply padding to a video, you need to define a padding and a new output size.

Padding is specified using the -vf flag with a scale and a pad value. The pad value is composed of width, height, offset top, offset bottom, while the scale value defines the input size to be padded.

If you want to add padding to a 920x530 video, to make it 960x540 without scaling (adding black bars all around):

-vf scale=920:530,pad=960:540:20:5 -s 920x530

Other relevant settings

To exclude audio from output file, add the -an flag:

ffmpeg -y -i 960x540.mp4 -an 960x540-no-audio.mp4

To exclude video from output file, add the -vn flag:

ffmpeg -y -i 960x540.mp4 -vn 960x540-no-video.mp3

Change duration of the output file:

ffmpeg -y -i 960x540.mp4 -t 00:00:01.000 960x540-1-sec-duration.mp4

Change the start offset of the output file:

ffmpeg -y -i 960x540.mp4 -ss 00:00:01.000 960x540-1-sec-start-offset.mp4

To create the tiniest black screen mp4 video file:

ffmpeg -f lavfi -i color=c=black:s=16x9:d=0.1 -s 16x8 -t 0.1 black.mp4

To create the tiniest silent AAC audio file:

ffmpeg -f lavfi -i anullsrc -t 0.1 -c:a aac silent.aac

To merge audio and video tracks:

ffmpeg -i black.mp4 -i silent.aac -c:v copy -c:a copy -bsf:a aac_adtstoasc -t 0.1 merged.mp4

To increase the volume:

ffmpeg -y -i 960x540.mp4 -vcodec copy -af "volume=2" 960x540-louder.mp4