What is FFmpeg?
Chances are you’ve probably heard of FFmpeg already. It’s a set of tools dedicated to decoding, encoding and transcoding video and audio. FFmpeg is based on the popular
libavformat libraries that can be found in many other video conversion applications, like Handbrake.
So why would you need FFmpeg? Got a video in an obscure format that every other player couldn’t recognize? Transcode it with FFmpeg. Want to automate cutting video segments out of movies? Write a short batch script that uses FFmpeg. Where I work, I constantly have to encode and process video material, and I’d never want to go back to using a GUI tool for doing this.
This post is a follow-up on Video Conversion done right: Codecs and Software, where I discussed the various codecs and containers that you can find these days. For a quick overview, I’d suggest to read this one as well, because it covers some important basics.
Now, let’s dive into the more practical aspects.
FFmpeg is free and open source, and it’s cross-platform. You’ll be able to install it on your Windows PC as well as your Linux server. The only thing you need to be comfortable with is using your command line. As it’s actively developed, you should try to update your version from time to time. Sometimes, new features are added, and bugs are fixed. You won’t believe how many times updating FFmpeg solved encoding problems I had.
Compiling FFmpeg on Windows is not too easy. That’s why there are (semi-) automated builds of the latest version available online, most prominently the ones from Zeranoe.com. Download the latest build labeled as “static” for your 32 or 64 Bit system. Those builds work fairly well, but they might not include all possible codecs. For the commands where I used
libfaac below, with the Zeranoe builds you have to choose another AAC codec instead, like
aac, with the additional options
The Zeranoe download will include
ffmpeg.exe, which is the main tool we are going to use. And you’re done. That was easy, was it?
On OS X, you have the tools for building programs from source. It’s very easy to install FFmpeg if you use a package manager like Homebrew or MacPorts. Install one of them if you haven’t already, and then run either
brew install ffmpeg --with-ffplay
This takes a while, because dependencies have to be built too. When you’re done, you should be able to call FFmpeg by running
sudo port install ffmpeg-devel
ffmpegfrom the command line. You should see a copyright header and some build details.
If you’re lazy, you can also download a static build, which just works out of the box. You only need to extract the archive and you’ll find an
Note that there’s also ffmpegX, but its bundled version always is a bit behind, and I wouldn’t recommend using it unless you have a good reason for doing so. The
.app package contains a compiled version of the
ffmpeg command line tool already, which you could theoretically use.
On many Linux distributions, FFmpeg comes in the default packages (e.g. on Ubuntu, where Libav – an FFmpeg fork – is bundled). However, mostly this is a very old release version. Do yourself a favor and compile from source – it sounds harder than it actually is. FFmpeg has a few dependencies, so therefore you’ll want to install encoders such as LAME for MP3 and x264 for videos as well. To compile FFmpeg, look at the FFmpeg wiki, which has a few compilation guides for various Linux distributions.
Similar to Windows, static builds for FFmpeg are also available. You can download these if you don’t want to compile yourself or install the outdate version from your package manager.
Our first encoded Video
Now that we have FFmpeg working, we can start with our video or audio conversion. Note that this is always a very resource intensive task, especially with video. Expect some conversions to take a little while, for example when re-encoding whole movies. A quad-core CPU like the i7 can easily be saturated with a good encoder and performs very fast then.
Before you handle videos, you should know what the difference between “codec” and “container” (also, “format”) is, as I will be using these terms without explaining them any further. I know these can be easily mixed up and aren’t as self-explaining as you’d like them to be. To read more about this, see this Super User answer: What is a Codec (e.g. DivX?), and how does it differ from a File Format (e.g. MPG)?
Okay, now let’s start. The most basic form of an FFmpeg command goes like this – note the absence of an output option like
And you’re done. For example, you could convert an MP3 into a WAV file, or an MKV video into MP4 (but don’t do that just yet, please). You could also just extract audio from a video file.
ffmpeg -i input output
FFmpeg will guess which codecs you want to use depending on the format specifier (e.g. “.wav” container obviously needs a WAV codec inside, and MKV video will use x264 video and AC3 audio). But that’s not always what we want. Let’s say you have an MP4 container – which video codec should it include? There are a couple of possible answers. So, we’re better off specifying these codecs ourselves, since some codecs are better than others or have particularities that you might need.
ffmpeg -i audio.mp3 audio.wav
ffmpeg -i video.mp4 video.mkv
ffmpeg -i video.mp4 audio.wav
Specifying Video and Audio codecs
In most cases, you want a specific output codec, like h.264, or AAC audio. Today, there’s almost no reason not to encode to h.264, as it offers incredible quality at small file sizes. But which codecs do really work in FFmpeg? Luckily, it has a ton of built-in codecs and formats, which you can get a list of. Check the output: The
E stand for “decoding” and/or “encoding” capabilities, respectively.
Now, we can use any of those to perform our transcoding. Use the
-coption to specify a codec, with a
:vfor audio and video codecs respectively. These are called “streams” in FFmpeg – normally there is one video and one audio stream, but you could of course use more. Let’s start by encoding an audio file with just one audio stream, and then a video file with a video stream and an audio stream.
The possible combinations are countless, but obviously restricted by the format/container. Especially those pesky old AVI containers don’t like all codecs, so you’re better off encoding to MP4 or MKV containers these days, because they accept more codecs and can be easily handled by any modern player.
ffmpeg -i input.wav -c:a libfaac output.mp4
ffmpeg -i input.avi -c:v libx264 -c:a libfaac output.mkv
When to copy, when to encode?
You might not have thought about this before, but sometimes, you want to just copy the contents of a video and not re-encode. This is actually very critical when just cutting out portions from a file, or only changing containers (and not the codecs inside). In the example I gave above, we wanted to change MP4 to MKV.
The following command is wrong: It will re-encode your video. It will take forever, and the result will (probably) look bad.
What FFmpeg did here was encoding the file yet another time, because you didn’t tell it to copy. This command however does it right:
ffmpeg -i input.mp4 output.mkv
If you were to re-encode your videos all the time when you cut them, instead of just copying the codec contents, you’d eventually end up with something like this (exaggerated, but still highly entertaining) example of generation loss. Looks scary, does it?
ffmpeg -i input.mp4 -c:v copy -c:a copy output.mkv
If changing the container without encoding does not work for you, you can try the
mkvmerge tool that mkvtoolnix offers. This will for example create an MKV file.
Similarly, MP4Box can create MP4 files from existing video.
mkvmerge input.avi -o output.mkv
If you’ve used some test videos or audio files for the above sequences, you might have seen that the quality wasn’t good enough to be useful. This is completely normal. Also, you will probably have constraints about bit rate, file size or target devices, such as when encoding a video for the PlayStation 3 or your Android phone.
Quality comes first. What is “quality”, even? Generally, the more bits you can spend on a file, the better it will look or sound. This means, that for the same codec, larger file size (or larger bit rate) will equal in better quality. In most cases, that is.
Most people associate quality with “bit rate”. This is a relict from the good old days where everyone would encode MP3 files from their CDs. Of course, this is a relatively simple approach, and you can get a good feeling for the bit rates you might need for certain videos. If you want to set the bit rate, you can do that with the
-b option, again specifying the audio or video stream (just to resolve any ambiguities). The bit rate can be specified with suffixes like “K” for kBit/s or “M” for mBit/s.
But often, bit rate is not enough. You only need to restrict bit rate when you have a very specific target file size to reach. In all other cases, use a better concept, called “constant quality”. The reason is that sometimes you don’t want to spend the same amount of bits to a segment of a file. That’s when you should use variable bit rate. Actually, this concept is very well known for MP3 audio, where VBR rips are commonly found.
ffmpeg -i input.wav -b:a 192K out.mp3
ffmpeg -i input.avi -c:v libx264 -b:v 500K -c:a copy out.mp4
In video, this means setting a certain value called Constant Rate Factor. For x264 (the h.264 encoder you should use), this is very easy:
The CRF can be anything within 0 and 51, with the reasonable range being 17 to 26. The lower, the better the quality, the higher the file size. The default value is 23 here. For MPEG-4 video (like XviD), a similar concept exists, called “qscale”.
ffmpeg -i source.mp4 -c:v libx264 -crf 23 out.mp4
ffmpeg -i source.mp4 -c:v mpeg4 -qscale:v 3 out.mp4
qscale:vcan range from 1 to 31. The lower, the higher the quality, with values of 3 to 5 giving a good enough result in most cases.
In general, the best bet is to just try and see for yourself what looks good. Take into account the result file size you want and how much quality you can trade in for smaller file sizes. It’s all up to you. As a last note, don’t ever fall for the
sameq option. Sameq does not mean same quality and you should never use it.
Often, you want to just cut out a portion from a file. FFmpeg supports basic cutting with the
-ss options. The first one will specify the duration of the output, and the second one will specify the start point. For example, to get the first five seconds, starting from one minute and 30 seconds:
The time values can either be seconds or in the form of
ffmpeg -ss 00:01:30 -i input.mov -c:v copy -c:a copy -t 5 output.mov
HH:MM:SS.ms. So, you could also cut one minute, ten seconds and 500 milliseconds:
Note that we’ve again just copied the contents instead of re-encoding because we used the
ffmpeg -ss 00:01:30 -i input.mov -c:v copy -c:a copy -t 00:01:30.500 output.mov
copycodec. Also, see how the
-ssoption is before the actual input? This will first seek to the point in the file, and then start to encode and cut. This is especially useful when you’re actually not just copying content, but encoding it, because it’ll speed up your conversion (although it’s less accurate). If you want to be more accurate, you’ll have to tell FFmpeg to encode the whole video and just discard the output until the position indicated by
ffmpeg -i input.mov -ss 00:01:30 -c:v copy -c:a copy -t 5 output.mov
Got a High Definition 1080p video that you want to watch on your mobile phone? Scale it down first! FFmpeg supports software-based scaling when encoding with the
-s option. The following example will do that:
Phones have some restrictions on video playback, which can be tackled by using so-called “profiles” when encoding. More about this can be found in the resources at the bottom.
ffmpeg -i hd-movie.mkv -c:v libx264 -s:v 854x480 -c:a copy out.mp4
Other useful Examples
On Super User, I’m currently very active in the FFmpeg tag. You could browse the questions there, or see this list of questions and answers I’ve compiled.
- Resources To Use FFMPEG Effectively, including some general links and resources
- What do the numbers 240 and 360 mean when downloading video? How can I tell which video is more compressed?, which focuses on tradeoffs between bit rate, file size, video dimensions, et cetera.
Specific conversion problems:
- Convert from MOV to MP4 Container format, which talks about switching containers only
- How to convert any video to DVD (.vob) in good video quality?, about the limitations of retaining quality when converting
- What parameters should I be looking at to reduce the size of a .MOV file?, in depth explanation about how to use the Constant Rate Factor
- Use DivX settings to encode to mp4 with ffmpeg, more examples about CRF and how to set advanced x264 options like presets and profiles
- Convert any video to HD Video, about up- or downscaling video
- How to cut at exact frames using ffmpeg?, which shows how to calculate cutting points for video
Of course, if you have any specific problem, feel free to ask it on the main site and we Super Users can help you out! However, make sure you always post the command you’re using and the full, uncut output FFmpeg gives you. Also, always try to use the latest version if possible. Ideally, we’d like to see a sample video as well.