ffmpeg Review
I need to review ffmpeg for something that I am doing.
References
Notes
Introduction
$ ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...
ffmpeg
is a universal media converter. It can read a wide variety of inputs - including live grabbing/recording devices - filter, and transcode them into a plethora of output formats.
ffmpeg
reads from an arbitrary number of inputs (which can be regular files, pipes, network streams, grabbing devices, etc.) specified by the -i
option, and writes to an arbitrary number of outputs, which are specified by a plain output URL. Anything found on the command line which cannot be interpreted as an option is considered to be an output URL.
Each input or output can, in principle, contain any number of elementary streams of different types (video/audio/subtitle/attachment/data), though the allowed stream counts and/or types may be limited by the container format. Selecting which streams from which inputs will go into which output is either done automatically or with the -map
option.
As a general rule, options are applied to the next specified file. Therefore, order is important, and you can have the same option on the command line multiple times. Each occurrence is the applied to the next input or output files. Exception for this rule are global options, which should be specified first.
Do not mix input and output files - first specify all input files, then all output files. Also do not mix options which belong to different files. All options apply only to the next input or output files and are reset between files.
$ ffmpeg -i input.avi output.mp4 # Convert and input media file to a different format
$ ffmpeg -i input.avi -b:v 64k -buffsize 64k output.mp4
$ ffmpeg -i input.avi -r 24 output.mp4
$ ffmpeg -r 1 -i input.m2v -r 24 output.mp4
Detailed Descriotion
ffmpeg
builds a transcoding pipeline out of the components listed below. The program's operation then consists of input data chunks flowing from the sources down the pipes toward the sinks, while being transformed by the components they encounter along the way:
- Different kinds of components:
- Demuxers (short for
demultiplexers
) read in put source in order to extract - global properties such as metadata or chapters
- list of elementary streams and their properties
- One demuxer instance is created for each
-i
option and sends encoded packets to decoders or muxers
- Demuxers (short for
- Decoders receive encoded packets for an audio, video, or subtitle elementary stream, and decode them into raw frames (array of pixels for video, PCM for audio). A decoder is typically associated with an elementary stream in a demuxer, but sometimes may exist on its own.
- Filtergraphs process and transform raw audio or video frames. A filtergraph consists of one or more individual filters linked into a graph. Filtergraphs come in two flavors - simple and complex, configured with the
-filter
and-filter_complex
options, respectively. A simple filtergraph is associated with an output elementary stream, it receives the input to be filtered from a decoder and sends filtered output to that output stream's encoder. - Encoders receive raw audio, video, or subtitle frames and encode them into encoded packets. The encoding (compression) process is typically lossy - it degrades stream quality to make the output smaller, some encoders are lossless, but at the cost of much higher output size. Every encoder is associated with some muxer's output elementary stream and sends its output to that muxer.
- Muxers receive encoded packets for their elementary streams from encoders (the transcoding path) or directly from demuxers (the streamcopy path) interleave them (where there is more than one elementary stream), and write the resulting bytes into the output file (or pipe, network stream, etc.).
Streamcopy
The simplest pipeline in ffmpeg
is a single-stream streamcopy, that is copying one input elementary stream's packets without decoding, filtering, or encoding them. As an example, consider an input file called INPUT.mkv
with 3 elementary streams, from which we take the second and write it to file OUTPUT.mp4
.
$ ffmpeg -i INPUT.mkv -map 0:1 -c copy OUTPUT.mp4
- In this command:
- there is a single input with no options
- there is a single output with these options:
-map 0:1
selects the input stream to be used - from input with index 0 (the first one) the stream with with index 1 (the second one)-c copy
selects thecopy
encoder, i.e. streamcopy with no decoding or encoding
Streamcopy is useful for changing the elementary stream count, container format, or modifying container-level metadata.
Transcoding
Transcoding is the process of decoding a stream and then encoding it again. Since encoding tends to be computationally expensive and in most cases degrades the stream quality, you should only transcode when you need to and perform streamcopy otherwise. Typical reasons to transcode are:
- applying filters - e.g. resizing, deinterlacing, or overlaying video resampling or mixing audio
- you want to feed the stream to something that cannot decode the original codec
Note that ffmpeg
will transcode all audio, video, and subtitle streams unless you specify -c copy
for them.
ffmpeg
provides the-map
option for manual control of stream selection in each output file. Users can skip-map
and let ffmpeg perform automatic stream selection as described below. The-vn / -an / -sn / -dn
options can be used to skip inclusion of video, audio, subtitle and data streams respectively, whether manually mapped or automatically selected, except for those streams which are outputs of complex filtergraphs.