General FFmpeg encoding guide

This guide concentrates on some common delivery codecs, and it is not an exhaustive list. I am in the process of writing a guide for intermediate video codecs. For archiving audio I would generally recommend FLAC, but see this hydrogenaudio comparison and decide for yourself.

This document is a draft form; I may change things around & will probably split the video & audio sections into two separate articles at some time in the future. For now, you can just endure the work-in-progress state: I’ve done my best to ascertain that all of this information is accurate (I’ve tested much of it myself), so no need to worry on that front.

1. Quality-based approach

You can target a certain ‘quality level’, letting the encoder decide what bit rate should be used to achieve that quality. Normally, this is set with the -qscale (‘quality scale’), or -q option, with a numerical scale determined by the specific encoder (but generally between 1-31). For example, using -c:v mpeg4 -q:v 3 will encode MPEG4 video at a very high quality. There are some encoders (like x264 and libfdk_aac) that use their own special option for determining quality.

Unless you absolutely need the output file to be a certain size, you should generally take this approach.

2. Bit rate-based approach

If quality is of secondary concern to control of file size, you can target a bit rate. Some codecs have a true ‘constant bit rate’ mode, where a certain number of bits are allocated to a second of the video/audio. Others simulate this with a very constrained ‘variable bit rate’ mode; either way, use the -b option to set the bit rate. For example: -c:a libmp3lame -b:a 192k will encode MP3 audio with a bit rate of 192kb/s.

Two-pass encoding

This is a method for encoding videos, targeting a bit rate, that provides the highest quality at the target bit rate. The first pass evaluates the video and feeds information to a file (ffmpeg2pass.log in the working directory by default; this can be changed using the -passlogfile option); the second pass uses the information contained in that file to give a better-quality encode.

Let’s say you want to compress a 90-minute film down to 700MB, so that it will fit on a CD-ROM. Since bit rate=size/time:

700MB*8192=5734400kb (convert MB to kb)
90 minutes*60=5400 seconds
5734400kb/5400 seconds=1061.9259kb/s target bit rate

To stay on the safe side, round this down to 1060kb/s. For the audio you choose libfdk_aac; mixing the audio down to 2 channels with -ac 2, a bit rate of 128kb/s will give good quality, which leaves 932kb/s for the video. Currently libx264, the h.264 encoder, is the best quality lossy encoder for ffmpeg – and it has a fair amount of hardware support when used in an MP4 container format. Since the audio won’t benefit from two-pass encoding, on the first pass use -an to disable it; similarly, on the first pass you can use the container format ‘rawvideo’, to save a small amount of processing on the container file. As we only need the first pass to generate a log file, we can send the video output to /dev/null (Windows users should use NUL instead); the -y option before the input tells FFmpeg to automatically overwrite the output, which is required for writing to /dev/null, or to a named pipe.

ffmpeg -y -i input.file -c:v libx264 -b:v 932k -preset veryfast -pass 1 -an -f rawvideo /dev/null
ffmpeg -i input.file -c:v libx264 -b:v 932k -preset veryfast -pass 2 \
-c:a libfdk_aac -b:a 128k -ac 2 output.mp4

The examples below are focused on quality-based encoding, but you can target a bit rate with any of them.

Container Formats

This is a list of commonly-used container formats. Again, it is not exhaustive. My two general recommendations are h.264 video & AAC audio in an MP4 (if you don’t need softsubs) or an MKV (if you do, or you need to use non-MPEG codecs). Of course, there are many cases where that general recommendation isn’t appropriate.

  • AVI – an old format. There are a few old hardware players that cannot support MP4, but apart from that it should be considered obsolete.
    • This normally contains MPEG4 part 2/Divx/Xvid video, and either MP3 or AC3 audio, though it can support many other codecs. Support for subtitle streams is very limited, which is one of the reasons it should be considered obsolete.
  • FLV – flash video. Since all vaguely modern flash players support MP4, you should probably use that instead.
    • Supported video codecs (that FFmpeg can encode): Sorenson Spark (flv1), h.264 (libx264).
    • Supported audio codecs: MP3 (libmp3lame), AAC (libfdk_aac should be preferred), and two variants of PCM (uncompressed audio).
  • MPG – MPEG Program Stream. Can be concatenated at the file level.
    • Supported Video codecs: MPEG1, MPEG2, MPEG4 part 2.
    • Supported Audio codecs: MP3, MP2, MP1, AAC, AC3, DTS.
    • VOB files used on DVDs are a subset of the MPEG Program Stream; supporting MPEG2 and MPEG1 video and MP2, AC3, DTS, or Linear PCM audio.
  • TS – MPEG Transport Stream. Mostly used for broadcast. Can contain any MPEG format.
  • MP4 – with h.264 video and AAC audio, this is the current standard, enjoying widespread support amongst hardware players.
    • Supported video codecs: h.264, MPEG4 part 2/Divx/Xvid, MPEG2, MPEG1.
    • Supported audio codecs: AAC, Apple Lossless/ALAC, MP3, MP2, and a few others.
    • Subtitle support is limited to DVD subtitles (which are bitmap-based), and 3GPP timed text, which FFmpeg does not currently support (SRT and ASS subtitles can be converted to 3GPP timed text using MP4Box, another open-source tool).
    • For an MP4 containing only audio – either AAC or ALAC – the extension M4A is often used. M4B is a customary extension for audiobooks. M4V is also sometimes used for videos.
    • If you are intending to use an MP4 for streaming over the internet, use -movflags faststart when you are encoding your file.
  • MKV – the king of container formats. It can contain almost all video, audio, or subtitle codecs. Unfortunately, it has very little hardware support.
    • WEBM is a renamed MKV file that should only contain VP8 video and Vorbis audio.
  • OGG – the xiph.org container format, mostly used for their codecs.
    • Supported video codecs: Theora, Dirac.
    • Supported audio codecs: Vorbis, Speex (speech codec), Opus.
    • Kate is the current de-facto subtitle standard for OGG, but unfortunately FFmpeg currently does not support it. SRT subtitles can be muxed into the OGG container with few problems.

Video

This is a list of common lossy delivery codecs.

h.264 (MPEG4 part 10)

The best encoder for this is the open-source x264 implementation, which is included in FFmpeg by way of libx264.

Set quality by using the -crf option, rather than -q:v. The total range is from 0 to 51, where 0 is lossless, 18 can be considered ‘visually lossless’, and 51 is terrible quality. A sane range is 18-26, and the default is 23. The better the quality, the larger the file size.

You can control the speed of the encode by using one of x264’s presets, with the -preset option; the faster presets will produce larger files. The useful presets are: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower and veryslow. The most noticeable dropoff in file size is between superfast and veryfast. The default is medium.

Here is an example using libfdk_aac to produce AAC audio:

ffmpeg -i input.file -c:v libx264 -crf 22 -preset veryfast -c:a libfdk_aac -vbr 3 output.mp4

MPEG4 part 2 / Divx / Xvid

Until h.264 was developed, this was the best and most popular video codec. It still has its uses: some old hardware devices support it, and it is much less complicated (and therefore less processor-intensive) than h.264.

FFmpeg’s internal mpeg4 encoder is very good. You can trick players into thinking that it was encoded with Xvid by using -tag:v xvid, which may be necessary for some players.

Set quality with the -q:v option: the range is 1-31, where 1 is best quality and a sane range is 3-6 – any value higher than that and visual artefacts start to become noticeable. Here is an example using MP3 audio in an AVI container, for use on an older device:

ffmpeg -i input.file -c:v mpeg4 -q:v 3 -tag:v xvid -c:a libmp3lame -q:a 4 output.avi

MPEG2

Most notable as the video codec used on DVDs. FFmpeg has its own encoder for this: mpeg2video.

Set quality with the -q:v option. The quantiser range is the same as for MPEG4 part 2: 1-31, where 1 is best quality and a useful range is 3-6. Here is an example VOB file using AC3 audio, at a suitable bit rate for stereo sound:

ffmpeg -i input.file -c:v mpeg2video -q:v 3 -c:a ac3 -b:a 150k output.vob

Theora

The Xiph.org video codec. This has mainly been used by people who wanted an entirely open source video codec. It originally aimed to be competitive with MPEG4 part 2. Its developers are currently trying to bring it to a similar level as x264. FFmpeg uses libtheora to encode this.

Set the quality with -q:v. The range is 0-10, where 10 is the best quality and 0 the absolute worst. 7 or above should give very good quality. Here is an example using Vorbis audio in an OGG container:

ffmpeg -i input.file -c:v libtheora -q:v 7 -c:a libvorbis -q:a 5 output.ogg

VP8

Google purchased and released this codec as open-source for use in their WEBM format, aimed at HTML5 video. It is not quite as good as x264, but is still pretty good quality. Both an internal FFmpeg encoder and an implementation by one of the x264 developers are in the works, but for now we must rely on the reference encoder, libvpx.

You should be able to set the quality with -crf; the range is 0-63, where 63 is best quality. However – this is currently broken, so you’ll have to target a bit rate with -b:v.

ffmpeg -i input.file -c:v libvpx -b:v 1000k -c:a libvorbis -q:a 5 output.webm

Audio

MP3 (MPEG2 Audio Layer III)

Though it has been surpassed by AAC and the Xiph.org codecs in terms of quality for a given bit rate, MP3 audio is still the most popular codec by a long way. For music, it is normally used without a container format, with the file extension MP3. FFmpeg encodes MP3 audio using LAME via libmp3lame. MP3 can only support two channels – no surround sound. For this reason, and due to its relatively poor performance in terms of quality, MP3 should be your last choice for audio connected to video.

Set quality using -q:a: the scale goes from 0-9, with 0 being best quality, and 4 being indistinguishable from original CD-quality input for many people.

ffmpeg -i input.wav -c:a libmp3lame -q:a 4 output.mp3

If you are encoding stereo audio using a fixed bit rate, 192kb/s will normally give you good quality (dependent on the nature of the audio); 320kb/s will give you the best possible quality (possibly better than -q:a 0), but at the cost of a very large file.

AAC (MPEG4 part 3)

This is the current standard audio delivery format, used in everything from blu-ray discs to internet streaming. Used within an MP4 container, with h.264 video if necessary, this enjoys widespread hardware player support.

There are a number of AAC encoder available for FFmpeg (see [here] for more), but the best one by a long way is libfdk_aac. Set quality with the -vbr option: the range is 1-5, where 5 is best quality. Even the lowest setting of 1 offers very good quality, however.

For use as standalone audio, M4A is customarily used instead of MP4; this is simply a naming convention.

ffmpeg -i input.wav -c:a libfdk_aac -vbr 3 output.m4a

If you are using a fixed bit rate mode, you should allow 64kb/s per channel in order to get transparency with an original lossless input; so 128kb/s for stereo audio, and 384kb/s for 5.1 surround sound.

AAC-HE

High-efficiency AAC is an extension of the AAC codec, meant for low bit rates. Version 1 gives good quality at 48-64kb/s for stereo, and 160kb/s for 5.1 surround sound; version 2 gives good quality at bit rates as low as 32kb/s for stereo, and 128kb/s for 5.1 surround sound. There is a catch, however: AAC-HE is not as widely supported as AAC-LC, the version described above. Support is growing, however: many smartphones support it, for example.

It also does not support the -vbr mode described above; you have to target a bit rate. Activate AAC-HE with -profile:a aac_he or -profile:a aac_he_v2.

AAC-HE version 1:

ffmpeg -i input.file -c:a libfdk_aac -b:a 64k -profile:a aac_he output.m4a

Version 2:

ffmpeg -i input.file -c:a libfdk_aac -b:a 32k -profile:a aac_he_v2 output.m4a 

At bit rates above those mentioned here, you should use AAC-LC.

AC3

Dolby Digital’s codec, most commonly found on DVDs because of its support for surround-sound. It doesn’t offer as good compression as AAC-LC, and the ffmpeg encoder doesn’t have the ability to target a quality – you’ll have to target a bit rate. 192kb/s should do for stereo audio, while 384kb/s – the maximum allowed in this codec – is used for 5.1 surround-sound.

In theory, this could be used for music just as well as any other codec on this list; in practice it is generally used within a video file. If you need the AC3 stream on its own, you can use the file extension *.ac3.

ffmpeg -i input.file -c:a ac3 -b:a 384k output.ac3

Vorbis

Probably Xiph.org’s most successful codec in terms of individual users. It is on par with AAC-LC, and enjoys (often undocumented) decent, but not universal hardware support.

Set the quality with -q:a; the scale ranges from -1 to 10, with 10 being best quality, and 5 being mostly indistinguishable from an original CD or DVD audio track. There is an internal FFmpeg Vorbis encoder, but it is not the best quality; instead, you should use libvorbis.

ffmpeg -i input.file -c:a libvorbis -q:a 5 output.ogg

If you are using the bit rate-targeting approach, around 160kb/s should be suitable for stereo sound.

About these ads

Tags: , ,

3 responses to “General FFmpeg encoding guide”

  1. someguy says :

    You have -movflags quickstart—is it not faststart?

  2. C says :

    Thanks for posting this, especially the two-pass encoding with the fixed size was helpful to me.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 28 other followers

%d bloggers like this: