Translation(s): English - French


ffmpeg/libav is a suite of open source software in command line that permit to manage audio or video streams. With ffmpeg/libav, we can make recordings, playings, making corrections with filters, or transcode media from a format to an other.

libav is a fork of ffmpeg that we can find in the Debian repositories. If you want to use ffmpeg, you will juste need to change the word "avconv" to "ffmpeg" in the different commands lines, the rest stay the same.

Installation

To install libav:

 # apt-get install libav-tools 

To install ffmpeg (not available un Debian 8 jessie):

# apt-get install ffmpeg

To find out in which deposit the package is available, look here debpkg:libav or here debpkg:ffmpeg

Usecases :

FFmpeg or Libav can be use from GUI like:

Or direcly from the command line interface, like we explain bellow.

Introduction

An introduction to the terminology of video could be useful to understand the ffmpeg syntax.

Formats :

The format is the container that allows the transport of video, audio and subtitles or as a file (mkv, mov ...) or via stream (MPEG TS). Inside a container can be inserted (mux) or extract (demux):

We talk about "multiplexing different tracks or streams in a format.

FFmpeg/Libav provide a list of supported format:

$ avconv -formats

...
DE avi             AVI (Audio Video Interleaved)
DE ogg             Ogg
D  matroska,webm   Matroska / WebM
 E mov             QuickTime / MOV
D  mov,mp4,m4a,3gp,3g2,mj2 QuickTime / MOV
 E webm            WebM
...

Codecs

The codec is an algorithm used to encode the video or sound to suit the transport protocol (IP, DVB, file ...) including reducing the flow rate (Kbits / s). According codecs, compression can result in loss of quality in picture or sound more or less important.

In the same way as for formats, ffmpeg / libav lists the codecs that it can handle:

$ avconv -codecs

Filters

ffmpeg / libav also has a significant base of filters that can modify the content of each stream, such as changing resolution, change the volume of a track, superimpose a logo etc ....

$ avconv -filters

Formats + Codecs + Filters

To summarize, ffmpeg / libav can multiplex or de-multiplex in different formats:

And modify, using filters, the content of each stream independently.

But if ffmpeg / libav can handle tons of formats and tons of different codecs, all combinations are not possible, as shown in this table: http://www.videolan.org/streaming-features.html.

Indeed, each codec or format has its own standard with more or less restrictive licenses, all combinations are not possible. Fortunately the free world provides several formats as well as several free codecs:

Knowing the contents of a file

Before starting any encoding it is good to know its contents, ffprobe or avprobe can read the header of the "format":

$ avprobe tears_of_steel.mkv

Which return:

  Input #0, matroska,webm, from 'tears_of_steel.mkv':
  Metadata:
    title           : 
    ARTIST          : 
    COMPOSER        : 
    SYNOPSIS        : 
    DATE_RELEASED   : 
    GENRE           : 
    ENCODER         : Lavf54.29.104
  Duration: 00:12:14.12, start: 0.000000, bitrate: 4615 kb/s
    Stream #0:0(eng): Video: h264 (Main), yuv420p, 1280x534 [SAR 1:1 DAR 640:267], 24 fps, 24 tbr, 1k tbn, 180k tbc (default)
    Stream #0:1(eng): Audio: aac, 44100 Hz, stereo, s16 (default)
    Stream #0:2(eng): Audio: ac3, 48000 Hz, 5.1(side), s16, 448 kb/s (default)
    Stream #0:3(eng): Subtitle: ssa (default)
    Stream #0:4(fr): Subtitle: ssa (default)

So for this file, we can see that:

Change the Format

You can easily change format without affecting the stream:

$ avconv -i tears_of_steel.mkv -c copy tears_of_steel.mov

If we do not tells ffmpeg/libav to make an exact copy of streams, it will launch an encoding default profile.

If we want to differentiate streams between them:

For files with more than 3 streams, it seems there is a bug with the "copy" function. Some streams are lost when copying, you have to use the mapping function to be able to copy all.

Organize the order of the streams (mapping)

                 Streams:         _________      _________      _________
                  #0:0           |         |    |         |    |         |
                +------->------->| decoder |--->| filters |--->| encoder |--->----+
                |                |_________|    |_________|    |_________|        |
 __________     |                 _________      _________      _________         |       ___________
|          |    | #0:1           |         |    |         |    |         |        |      |           |
| Input #O |----+------->.   ,-->| decoder |--->| filters |--->| encoder |--->----+----->| Output #O |
|__________|    |         \ /    |_________|    |_________|    |_________|        |      |___________|
                |          X      _______________________________________         |
                | #0:2    / \    |                                       |        |
                +------->ยด   `-->|                 copy                  |--->----+
                                 |_______________________________________|
            \________/ \______/                                             \________/
              demuxer   mapping                                                muxer

ffmpeg/libav can change the order of the stream to suit your uses with the parameter " -map ":

avconv -i tears_of_steel.mkv -map 0:0 -map 0:2 -map 0:1 -map 0:4 -map 0:3 -c copy tears_of_steel-v2.mkv

In this command I inverted the two audio streams between them and also the subtitles.

When running, ffmpeg indicate which intersection (mapping) it applies:

  Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:2 -> #0:1 (copy)
  Stream #0:1 -> #0:2 (copy)
  Stream #0:4 -> #0:3 (copy)
  Stream #0:3 -> #0:4 (copy)

Add a stream

The parameter -map allow also to add a stream, in the following example a subtitle in Spanish (TOS-es.srt) in position 4:

$ avconv -i tears_of_steel.mkv  -i TOS-es.srt -map 0:0 -map 0:1 -map 0:2 -map 1:0 -map 0:3 -map 0:4 -c:v copy -c:a copy  -metadata:s:s:0 language=esp tears_of_steel-v2.mkv

This allows to insert it where you want :

The option metadata can indicate the file language:

Extract un stream

Using the possibilities of mapping it is very easy to extract one stream from a file :

$ avconv -i tears_of_steel.mkv -map 0:2 -acodec copy tears_of_steel_soundtrack.mkv

In this example, we extract just one audio track.

Extract a audio track in MP3

$ avconv -i tears_of_steel.mkv -map 0:2 -acodec libmp3lame -ar 44100 -ac 2 -ab 192k tears_of_steel_soundtrack.mp3

Extract a subtitle

$ avconv -i tears_of_steel.mkv -map 0:4 -c:s srt tears_of_steel_FR.srt 

Extract a segment

FFmpeg/Libav can extract, pieces of media, stating a point of entry with '-ss '(-ss 00:06:46) and specifying a time with -t (-t 00:01:00). This function is very useful for making encoding tests to validate his command. Note that -ss and -t should be placed before the first input (-i).

$ avconv -ss 00:06:46 -t 00:01:00 -i tears_of_steel.mkv -c copy tears_of_steel_extract.mkv

Sometimes the term -t is not taken into account. You can use the option -to by placing it next to the output file

$ avconv -ss 00:06:46  -i tears_of_steel.mkv -c copy -to 00:01:00 tears_of_steel_extract.mkv 

Increase the number of threads

Depending on the codec, it's possible to run multiple threads processors on a transcode with the option threads:

$ avconv -threads 4 -i tears_of_steel.mkv -c copy tears_of_steel_extract.mkv 

Here I force it to work on 4 threads, that can save me valuable time. -threads 0 is the automatic mode and use the maximum of available threads, but it does not work with all the codecs.

Encoding videos

option

details

-b

set bitrate (in bits/s) 200kbps by default

-sameq

use the bitrate of the source

-s

set the size of the image (-s 320x240)

-aspect

sample aspect ratio (4:3, 16:9 or 1.3333, 1.7777)

-vcodec ou -c:v

to choose a codec

-pass

Select the pass number, one pass (-pass 1) or two (-pass 2)

-qmin

minimum video quantizer scale (VBR)

-qmax

maximum video quantizer scale (VBR)

-f

Force input or output file format.

-r

set the frame rate

Encode video in VP8

VP8 is a open source codec promoted by Google, a good replacement to H264/MP4

$ avconv -i tears_of_steel_720p.mkv -c:v:0 libvpx -crf 10 -vb 4M -c:a copy   tears_of_steel_vp8.mkv

Here, we use the libvpx with two options:

A list of possible options for encoding in VP8 is available here:

Encode video in H264/Mpeg4

The H264/MPEG4 is a proprietary codec commonly used for its good quality/speed ratio:

$ avconv -i tears_of_steel_720p.mkv -c:v:0 libx264 -preset slow -crf 22 -c:a copy tears_of_steel_h264.mkv

A more detailed documentation is available here : trac.ffmpeg.org

External Links