Getting started with FFmpeg

The tool I use the most to clip videos and (re)encode media is FFmpeg, a command line bundle of utilities and libraries that is very powerful but not necessarily intuitive.

This is a small guide about the most useful commands.

Basic command line

The basic command is composed by an input and an output:

# Conserve the same format
ffmpeg -i "./input.mp4" "./output.mp4"

# Conserve the same exact encoding settings
ffmpeg -i "./input.mp4" -c copy "./output.mp4"

# Conserve only the sound
ffmpeg -i "./input.mp4" "./output.mp3"

In the command line we have the input parameter marked by the -i option. The output is positioned at the end of the command.

The -c argument correspond to video and audio codecs when followed by copy to conserve the same streams as they were encoded in the input.

Argument quirks

FFmpeg uses the position of the arguments, the input cannot be place elsewhere than at the start of the line and all options related to the input must be placed before the input file.

The output options can be place after the inputs.

Extracting a clip

Sometimes you are proud of the way you handled a boss in a game or you just want to clip out a part of a movie, to do that you will need to provide the start of the clip and sometimes the length of the clip you wish to extract.

ffmpeg              \
  -ss 01:37         \ 
  -i "./input.mp4"  \
  -t 01:00          \
  "./output.mp4"

Let’s break down this command line by line:

  1. We call FFmpeg;
  2. We set the start of the clip with -ss and specifying a time code;
  3. We set the input file;
  4. We set the length of the clip;
  5. We set the output.

The start and length are expressed as a time code:

Hours Minutes Secondes Milliseconds
00 : 01 : 37 . 000

In our case we are working with minutes and seconds, but we can go as low a milliseconds. Keep in mind that if you do not re-encode you might end up with a couple of unwanted frames.

Encoding

More often than not encoding will be necessary if you want to publish online, reduce the file size or edit the media file. Here are a couple of snippets for different formats.

Implicitly convert

For the programmer lazy people like me it’s possible to quickly extract the sound or convert a video as a gif:

# Convert a video to an audio only file
ffmpeg             \
  -i "./input.mp4" \
  "./output.mp3"

# Convert to a gif
ffmpeg             \
  -i "./input.mp4" \
  "./output.gif"

This will use default settings, you can tweak the settings by going in-depth depending on the output format you choose (Encode/MP3).

Same codec, different bitrate

Changing the bitrate is possible, for a loss in quality.

# Convert to h264 with a bitrate of 
ffmpeg             \
  -i "./input.mp4" \
  "./output.mp4"

It’s also possible to run two passes by adding the parameter -pass with the argument 1 or 2 for the first and second pass.

# Convert to h264 with a bitrate of 
ffmpeg -i "./input.mp4" -c:v libx264 -b:v 2600k -pass 1 -an -f mp4 /dev/null
ffmpeg -i "./input.mp4" -c:v libx264 -b:v 2600k -pass 2 -c:a aac -b:a 128k "./output.mp4"

As you see on line 2 we use the argument -an to not treat the audio but during the second pass we specify a codec with -c:a and the audio bitrate -b:a, this is because the first pass only treats the video stream.
If you wish you can add the audio the the first pass, nothing is stopping you from doing so.

We still supply the video codec for both passes with -c:v and the bitrate -b:v.
Please note that bitrates can also be expressed in other units such as M for megabits.

We also don’t output the video stream to a file on line 2 because we are having FFmpeg generate a log file for the second pass. We also need to specify the output format to the encode with -f so that the second pass is not lost.

You can read more on h264 encode on the FFmpeg wiki.

What about the WebM format? Well it’s a bit the same but with different codecs:

# Convert to a webm (VP9)
ffmpeg             \
  -i "./input.mp4" \
  -c:v libvpx-vp9  \
  -crf 10          \
  -b:v 0           \
  -c:a libvorbis   \
  "./output.webm"

A new option on line 5 is the constant quality mode and this is the reason we have set the video bitrate to 0. Instead of imposing a fixed bitrate we will instead of have a variable bitrate used to target the quality we want.
It is possible to omit -crf and specify a video bitrate instead.

If you wish to target a lossless quality you can do so by setting the argument -lossless to 1.

VP9 does support two pass encoding and will work the same as h264.

Read more about VP9.

Editing

It’s also possible to reduce the frame rate and the resolution.

ffmpeg             \
  -i "./input.mp4" \
  -r 25            \
  -vf scale=160x90 \
  -c:v libvpx-vp9  \
  -b:v 2M          \
  -c:a libvorbis   \
  "./output.webm"

Here we reduce the frame rate to 25 with the option -r. The resolution is lowered with option -vf scale= to 160 by 90. It’s possible to keep the aspect ratio by specifying -1 in the scaling such as scale=1280x-1 to scale down to 720p from 1080p (assuming the aspect ratio was 16:9).

Conclusion

FFmpeg is a great tool that can basically do anything when working with media files. It’s very popular and used everywhere because of how powerful it is.

Published by

SenpaiSilver

Junk food tastes good.