FFmpeg: The ultimate Video and Audio Manipulation Tool(原标题)
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 libavcodec
and libavformat
libraries that can be found in many other video conversion applications, like Handbrake.
很可能你已经听说过FFmpeg了,他是一系列专注于音视频解码,编码和转换的工具。FFmpeg基于流行的libavcodec
和libavformat
库,以至于他能够在很多视频转换工具中见到,比如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.
那么为什么你需要FFmpeg呢?
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.
Installation
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.
Windows
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 libvo_aacenc
, or aac
, with the additional options -strict experimental
.
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?
OS X
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
or
sudo port install ffmpeg-devel
This takes a while, because dependencies have to be built too. When you’re done, you should be able to call FFmpeg by running ffmpeg
from 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 ffmpeg
binary.
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.
Linux
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)?
Basic Syntax
Okay, now let’s start. The most basic form of an FFmpeg command goes like this – note the absence of an output option like -o
:
ffmpeg -i input output
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 audio.mp3 audio.wav
ffmpeg -i video.mp4 video.mkv
ffmpeg -i video.mp4 audio.wav
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.
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 D
and E
stand for “decoding” and/or “encoding” capabilities, respectively.
ffmpeg -codecs
ffmpeg -formats
Now, we can use any of those to perform our transcoding. Use the -c
option to specify a codec, with a :a
or :v
for 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.
ffmpeg -i input.wav -c:a libfaac output.mp4
ffmpeg -i input.avi -c:v libx264 -c:a libfaac output.mkv
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.
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.
ffmpeg -i input.mp4 output.mkv
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 -c:v copy -c:a copy 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?
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.
mkvmerge input.avi -o output.mkv
Similarly, MP4Box can create MP4 files from existing video.
Advanced Options
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 Settings
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.
谈起质量很多人会联想到“比特率”,其实这是从当年人们从CD盘里转码MP3文件时代遗留下来的一个观念。当然相对来说这比较容易理解,并且你能对具体的视频需要一个多大的比特率拥有一个比较直观的感受。如果你想设置比特率,你可以通过 -b 选项,再提供音频或者视频流(只是为了区分流)。比特率的值的后缀可以是“K” 表示 KBit/s 或者“M”表示 mBit/s。
ffmpeg -i input.wav -b:a 192K out.mp3
ffmpeg -i input.avi -c:v libx264 -b:v 500K -c:a copy out.mp4
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.
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:
通常情况下,只有比特率是不够的。你只有在需要达到一个特定目标的文件大小的时候才需要限制比特率。其他情况下,可以使用更好的概念,叫做“constant quality”。原因是大部分时候你并不想往一段文件中存储相同数量的数据。这时你应该使用动态比特率,事实上,这在VBR rips能够普遍找到的MP3音频上是一个非常常见的概念。
对于视频,这意味着需要设定一个叫做“Constant Rate Factor”的特定值,对于 x264(你应该用h.264编码器),这简单的很:
ffmpeg -i source.mp4 -c:v libx264 -crf 23 out.mp4
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”.
CRF可以是0到51之间的任何值,合理的取值范围在17到26之间,值越小,质量越高,文件越大。默认值是23。对于MPEG-4视频(比如XviD),有一个类似的概念叫做“qscale”。
ffmpeg -i source.mp4 -c:v mpeg4 -qscale:v 3 out.mp4
Here, the qscale:v
can 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.
此处的qscale:v的取值可以在1到31之间。越低,视频质量越高,大部分情况下,取值3到5就能达到一个相当不错的效果了。
Cutting Video
Often, you want to just cut out a portion from a file. FFmpeg supports basic cutting with the -t
and -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:
ffmpeg -ss 00:01:30 -i input.mov -c:v copy -c:a copy -t 5 output.mov
The time values can either be seconds or in the form of HH:MM:SS.ms
. So, you could also cut one minute, ten seconds and 500 milliseconds:
ffmpeg -ss 00:01:30 -i input.mov -c:v copy -c:a copy -t 00:01:30.500 output.mov
Note that we’ve again just copied the contents instead of re-encoding because we used the copy
codec. Also, see how the -ss
option 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 -ss
:
ffmpeg -i input.mov -ss 00:01:30 -c:v copy -c:a copy -t 5 output.mov
Resizing
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:
ffmpeg -i hd-movie.mkv -c:v libx264 -s:v 854x480 -c:a copy out.mp4
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.
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.
General issues:
- 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.
Filed under Compression Software Utilities