ffmpeg

ffmpeg is the swiss army knife of audio and video manipulation.

If you think about doing it, there is a ffmpeg switch that allows you to do it.
The problem is, as always, to find the proper combination of switches.

Over the years, I have written countless small scripts just because I couldn't remember all those switches, and found myself writing the same script again because I had forgotten about the one I wrote years ago.
So instead of grepping my collection of scripts to find the proper switch, I thought I'd rewrite the manual, just in a way that is useful for me (and hopefully others). (I am of course talking about the linux version here. It is available for other platforms, and millions of graphic user interface have been written for it, probably for the same reason I wrote this page. :-)

The simplest way to transform a file into another is to let ffmpeg take care of everything. So if you do
ffmpeg -i InFile.avi OutFile.mp4
It will transform the avi into mp4, no question asked. This will work most of the time. The devil being in the details, you need to know what the defaults settings are. For example, by default, it would only take the first video track and the first audio track of the avi, which means that if you had the original soundtrack and your language, one of them is lost. The surest way to avoid that is to tell it to map everything: -map 0.
The same map, by the way, allows you to reverse the order of tracks, since most readers will default to reading the first soundtrack. Just add a -map 0:2 -map 0:1 ; track 0 usually being the video. So again, one simple parameter, but very powerful. It is the same one you use to extract only a single tract to a file.
The same goes if you are transforming a file into mp3 file with no parameters: default is 128k.

First thing first: in order to minimize the output of ffmpeg, you may want to create an alias with -hide_banner. That will skip the compiling info every time you launch it.
And talking about that, usual redirections do not work with ffmpeg, as ffmpeg writes to StdErr (and not StdOut).
So to redirect the output, you need
   ffmpeg -i Somefile.mp4 2> result.txt
This is what I use to get some infos about a file. It is the exact same output as ffprobe.
Without further ado, here are some commands I use for simple things:
  • I travel a lot and use to the time to watch movies on my tablet. In order to save storage and processor time (rescaling) and therefore battery, I produce a file better suited to watch on my tablet:
    ffmpeg -i $1 -hide_banner -vf scale=iw/2:ih/2 -crf 22 New_$1
  • Simple concatenation of files: put filenames in a text file with "file " in front of path/name then do
    ffmpeg -f concat -safe 0 -i input.txt -map 0 -c copy output.mp4
  • Transform a .VOB file in mp4:
    ffmpeg -i $1.VOB -map 0 -c:v libx264 -c:a:0 libmp3lame -b:a:0 256k -c:s copy $1.mp4
  • Add a title to a mp4 file:
    ffmpeg -hide_banner -loglevel quiet -i $fichier -map 0 -metadata title="$titre" -codec copy New_$fichier;
  • Add a subtitle in the file with the proper language code:
    ffmpeg -i $fileOri -i $fileSub -hide_banner -map 0:v -map 0:a -map 1 -vcodec copy -acodec copy -scodec mov_text -metadata:s:s:0 language=$IsoCode $fileDest
  • Transform a movie into 3gp to watch on phone:
    ffmpeg -i $1.avi -s qcif -vcodec h263 -acodec mp3 -ac 1 -ar 8000 -r 25 -ab 32 -y $1.3gp
  • Crop the corner of a movie (going down)
    ffmpeg -i $Fich -vf crop=$DimX:$DimY:0:0 CroppedD_$Fich
    (Going up)
    ffmpeg -i $Fich -vf crop=in_w-$DimX:in_h-$DimY:$DimX:$DimY Cropped_$Fich
    You can visualize before using:
    ffplay -i $Fich -vf crop=$DimX:$DimY:0:0
  • add several subtitle files with the proper metadata:
    ffmpeg -hide_banner -loglevel warning -stats -i $stem.brut.mp4
    -i $stem.rus.srt -i $stem.eng.srt -i $stem.spa.srt
    -acodec copy -vcodec copy -c:s mov_text
    -map 0 -map 1 -map 2 -map 3
    -metadata:s:1 language=rus
    -metadata:s:s:0 language=rus -metadata:s:s:1 language=eng -metadata:s:s:2 language=spa
    $stem.mp4

  • Overlay an image (or another video) at DimX:DimY:
    ffmpeg -i input -i logo -filter_complex 'overlay=DimX:DimY' output
  • The same but only from second 5 to 20:
    ffmpeg -i input -i logo -filter_complex "overlay=DimX:DimY:enable='between(t,5,20)'" output
    (again replace ffmpeg by ffplay to visualize before burning)
  • Re-pack a movie to latest codec (to save space)
    ffmpeg -hide_banner -i $file -map 0 -c:v libx264 -preset slow -c:a mp3 -c:s mov_text New_$filename.mp4 ;
  • Increase the volume of a video (or audio)
    ffmpeg -i fileIn -vcodec copy -af "volume=10dB" fileOut.mp4
  • Decrease the volume of a video (or audio)
    ffmpeg -i fileIn -vcodec copy -af "volume=-10dB" fileOut.mp4
  • Transform a mkv into mp4
    ffmpeg -hide_banner -loglevel warning -i $filename.mkv -codec copy -c:s mov_text -map 0 $filename.mp4
  • Transform a mp4 to a ogv
    ffmpeg -i $1 -acodec libvorbis -vcodec libtheora $filename.ogv
  • Transform a file to webm
    ffmpeg -i $Input -vcodec vp9 -acodec libvorbis -aq 5 -ac 2 -qmax 25 -threads 2 $filename.webm
  • Transform a webm into mp4
    ffmpeg -fflags +genpts -i $1.webm -r 24 $1.mp4



Attention: big changes in parameters with version 6.0, see here

One last note: this is quite fast. Whereas rendering, scaling or cropping may be slow with other software, ffmpeg is quite fast, probably because it doesn't care about updating a fancy interface. The parameters that work for me (and are aliased) are -hide_banner -stats. This minimizes the output. I often add -loglevel warning on the command line for reducing even further.
Also note that the "-[avs]copy copy" must come after the input file, otherwise ffmpeg thinks the codec applies to decoding and is confused.