Comprehensive Guide to Using FFmpeg to Convert Media Files

Featured Image with FFmpeg logo

FFmpeg is one of those modern marvels of open source software. It is a suite of libraries and smaller programs to handle video and audio files primarily.

It works with images and other multimedia files such as video streaming formats. It has lots of uses like video transcoding, video editing, video scaling, video cropping or other video manipulation work.

At its heart FFmpeg is a command line tool used with the ffmpeg command.

It has a basic simple video player and ability to probe video media information for analysis.

[powerkit_alert type=”info” dismissible=”false” multiline=”false”]
FFmpeg is also included in the workflow of other software like the popular video player VLC. Enterprise companies like YouTube use it in their core processing when ingesting video uploads.

Overall FFmpeg can play, record, convert, and stream audio and video. It includes libavcodec – the leading audio/video codec library.

In this tutorial we’ll install FFmpeg and learn how to use some its most popular features through practical examples and detailed explanations.

Install FFmpeg

FFmpeg officially supports Linux, Windows and MacOS.

Install FFmpeg on Linux

It’s really simple to install FFmpeg on most Linux distros. The distro official repositories most likely has the latest version tested and verified to work on that distro..

While it’s not the absolute latest version of FFmpeg that one can install, it is a version not that far behind.

Installing FFmpeg on Debian-based Distros (Ubuntu, Debian, etc)

To install FFmpeg on Ubuntu, first we’ll update our package index and our system packages to the latest version.

sudo apt update && sudo apt upgrade

Now we can install FFmpeg:

sudo apt install ffmpeg

FFmpeg itself is not big and it will install quickly like in the demo.

Installing FFmpeg on RHEL-based Distros (Fedora, Rocky Linux, AlmaLinux, CentOS)

First we update our package index and upgrade our system packages to the latest version.

sudo dnf update

Next we can install FFmpeg on our RHEL-based distro:

sudo dnf install ffmpeg

If you don’t have all the additional libraries and dependencies that FFmpeg requires, it will take a little bit longer than our demonstration to finish installing everything. Depending on your internet connection speed and processing power of your computer it can take up to two minutes or more.

Don’t worry if it takes a few minutes, the amount of additional libraries FFmpeg uses are a lot.

The way FFmpeg works is that it doesn’t try to reinvent everything, it uses already established libraries and it applies them into its workflow. That way the developers are focused on the core of the product instead of redeveloping everything themselves.

Installing FFmpeg on Windows

To install FFmpeg on Windows feel free to check our quick tutorial and return here after successfully installing it.

Installing FFmpeg on MacOS

We don’t currently have a guide on installing FFmpeg on MacOS but you should be able to easily install it using this tutorial on YouTube.

Check if FFmpeg is Installed

After installation we can check if it was installed successfully by running ffmpeg with a -version option.

ffmpeg -version

word image 61

This tells us information about our installation. What version, in our example it is the 4.4-6 Ubuntu maintained version. We see all the libraries that are enabled under configuration.

Finally we can see the codecs that come integrated with it.

[powerkit_alert type=”info” dismissible=”false” multiline=”false”]
A codec is a computer program that compresses or decompresses digital video or audio data. Codecs are necessary for encoding and decoding (playing) audio and video. Multiple codecs exist, and each codec has its own advantages and disadvantages. The reason there are so many codecs is that no single codec can do everything.

Now that we installed FFmpeg on our system there’s a myriad of work we can do with multimedia files. We will learn of a few of them below.

What Are Video Container Formats

When it comes to converting videos to other formats it’s important to understand what that other format refers to.

Videos are usually saved in a container format. A container format is a file format that allows multiple data streams to be embedded on them.

To make an illustration of what this means let’s go over what videos are.

Videos are still frame pictures grouped together successively to create the illusion of motion.

A Hollywood movie typically has 24 frames per second.

In a one minute video that is 1440 frames, or pictures to easily illustrate. So the container keeps these picture data streams and displays it at a set frequency. In a short explanation that is how digital videos work.

The extension of a video file usually corresponds to a container format, although not always. Popular video container formats used today are:

  1. MPEG-4 Part 14 using the .mp4 extension.
  2. Matroska using the .mkv extension.
  3. QuickTime File Format using the .mov extension.
  4. Audio Video Interleave using the .avi extension.
  5. MPEG Transport Stream using the .ts extension.
  6. WebM using the .webm extension.

These are some of the most popular container formats used on the web today.

It’s important to note that while any file can have any of these extensions used, it doesn’t necessarily mean that the video container of the file is of that format.

For example, I can change the extension of a video file to party.mp4 but that doesn’t mean that the container got changed. The container of this party.mp4 will still be the QuickTime File Format.

In order to change the container of the file it needs a process called transmuxing, it’s something that FFmpeg can do.

Encoding, Transcoding, and Transmuxing

Before we proceed to examples of how to use FFmpeg we need to understand the difference between encoding, transcoding and transmuxing. All three of them are formatting a data stream into a container so it can be a playable video but they differ slightly.

What is Encoding

Encoding is compressing raw video data from either a camera sensor or an analog source like a cassette tape. It’s compressed into a video container file to be playable.

The important thing to remember about encoding is that it’s being compressed from a raw source.

Since usually raw video data contains so much information the process of encoding takes longer than transcoding or transmuxing and it’s a CPU intensive task.

What is Transcoding

Transcoding is when we take a video that has already been compressed into a container file format and change it to another format with different video settings.

Transcoding will also compress data into a video container file ready to be playable. The source, though, was a video that was already encoded. Since transcoding is changing the format completely, it is also a time consuming process.

What is Transmuxing

Transmuxing is the process of changing the container file but instead of transcoding into a different format with different video settings, transmuxing just changes the container keeping the same video settings.

The process is a lot quicker and it’s not CPU intensive. What it does is just reassigns the video data into the container file’s format, but the video data stays the same.

Convert Videos to Another Extension

So now we know that just changing an extension of a video file doesn’t change what container it uses. We need to transmux the file in order to change its container format.

To transmux a file with FFmpeg we can run a command like the following:

ffmpeg -i bigbuckbunny.mp4 -c copy bunny.mkv

This is one of the most simple tasks we can do with FFmpeg. Let’s explain the above command.

First we ran the command ffmpeg with the -i option followed by indicating the video file to use.

After inputting the video file name that we are going to use, with the -c option we told it to copy into a file name bunny.mkv.

The -c option is an important one on FFmpeg because it corresponds to the codec the video should use.

In this case we didn’t want to transcode into another video format with different video settings, so instead of inputting our encoding configuration we just simply told it to copy.

All that did was exchange the container wrappers while keeping the same video encode.

We will save quality and a lot of time by just changing the containers if there is no need to transcode into different settings.

How To Download M3U8 HLS Streaming Files with FFmpeg

Nowadays that streaming is getting more and more popular, some streaming formats don’t make it so easy to be able to download a video like we used to.

One such format is the M3U8 file format. M3U8 is a playlist format that aggregates thousands of smaller chunks of MPEG Transport Stream .ts files.

.ts is a popular format for streaming because it’s a long video file cut into small chunks of a few seconds, while the video is playing the browser is downloading these chunks of small video files and buffering them in the memory.

This technique to stream video saves video providers over the web a lot of bandwidth as just the played portion gets downloaded to the user and not the whole video file.

For example, a 2 hour movie does not need to download the whole file so the user can play, it will only download the 5 minutes the user watched before closing the web page.

But because this format has literally thousands of chunks of a few seconds of time span, it’s hard to download. FFmpeg can help us here.

ffmpeg -i,640x360_400,640x360_700,640x360_1000,950x540_1500,.f4v.csmil/master.m3u8 -c copy downloadbunny.mp4

As our aim here is to simply download the file, we again are only going to remux the video.

We run the ffmpeg command this time with the -i option indicating the web URL of the .m3u8 playlist file. For the codec portion -c we will again copy as to not transcode, then we give it a file name to save to, in our example downloadbunny.mp4.

In less than 2 minutes we were able to download the complete 10 minute that was hosted on the .m3u8 playlist file.

This type of download and remux combination can be done with other streaming formats also like MPEG-DASH and others.

This will not work when the HLS stream is encrypted on the server side because we wouldn’t have the decryption key.

Download Subtitles With FFmpeg

If the HLS stream .m3u8 playlist file we are downloading also contains webvtt subtitles to accompany the video, we can also download them with FFmpeg.

ffmpeg -i ",640x360_400,640x360_700,640x360_1000,950x540_1500,.f4v.csmil/master.m3u8" -c:s srt

Here we are running ffmpeg with the same m3u8 playlist file URL as the example before that we indicated with the -i option.

We will use another of FFmpeg’s not so well known options, the -c:s option. That option will tell it to download any subtitles that it finds and to write it on our computer using the srt format of subtitles.

Then we give it a name to the subtitle file it will create, in our example

Fetch How Many Frames A Video Has with ffprobe

Sometimes when working with video files it’s important to know information about it. An accompanying utility installed with FFmpeg is ffprobe.

The role of ffprobe is to probe for information about a video file. It’s used to extract information from multimedia streams and print it in human- and machine-readable fashion.

One such useful piece of information is the amount of frames a video has. We can do that easily with the following command.

ffprobe -v error -select_streams v:0 -count_frames -show_entries stream=nb_read_frames -of csv=p=0 downloadbunny.mp4

word image 62

We run the ffprobe utility with the -v option set to error.

This option omits more information and gives us only the frame count we are looking for.

The -select_streams v:0 tells it to start with the first video stream in the container. While most video files usually only have one video stream in it, there could be more than one.

-count_frames is telling it to count the number of frames per stream.

-show_entries stream=nb_read_frames is to tell it to show us only entries for frames.

Finally -of csv=p=0 tells it to hide descriptions and only output the value.

From the previous HLS stream video we had downloaded, now we know that it contains 17876 frames.

Depending on the CPU power of your computer this probe can take a little while to complete as it counts the frames.

ffprobe is an excellent utility and we should always keep it in mind when working with video files.

Upscale A Video To A Higher Resolution with FFmpeg

Sometimes we are not fortunate to have a higher resolution version of a video. Maybe it’s an old one from a few years or decades past. We would like to play this video in higher HD resolution.

With FFmpeg we can upscale the video to another resolution.

ffmpeg -i bigbuckbunny.mp4 -vf scale=1920x1080:flags=lanczos upscaled_1080p.mp4

In this example we are getting our big buck bunny video which is 480 x 270 (width x height).

That is a very small resolution for our enjoyment so we use ffmpeg with the -i option to pick our video.

This time we will use the -vf option to indicate that we want to scale the video to a resolution of =1920×1080 and we are flagging it to use the lanczos algorithm.

FFmpeg has three algorithms to choose from when scaling:

  1. Bilinear
  2. Bicubic
  3. Lanczos

While Lanczos won’t be the sharpest, it provides a combination of sharpness and smoothness to make the footage look better.

After a few minutes of transcoding it will output us a new file, upscaled_1080p.mp4 in our example.

Downscale a Video to a Lower Resolution

Using the same concept we can downscale a video to a lower resolution.

ffmpeg -i scaled_1080p.mp4 -vf scale=1280x720:flags=lanczos downscaled_720p.mp4

Here we take the 1920 x 1080 (width x height) video that we just upscaled and are downscaling it to a 1280 x 720 resolution using the same settings.

Transcode a Video With FFmpeg

Transcoding is the process of converting one type of video or audio file into another. It’s a very common task in the multimedia world, and FFmpeg makes it easy to achieve.

In the previous video we transcoded a video and we didn’t even know it.

In that example we didn’t indicate any codec settings but because it was an up and down scale we had to transcode, it couldn’t simply copy like we had been doing before. In the previous example FFmpeg simply used the default transcoding settings.

FFmpeg has a plethora of codecs it can use. To see a list of them you can run the command.

ffmpeg -codecs

Not all of them can encode, so to get a list of all the encoders on our system we can run the command.

ffmpeg -encoders

One of the most popular encoders for videos is the h264 encoder.

The h264 encoder is compatible with web browsers, meaning videos encoded with it can be played embedded on a website.

There are some encoders that are not compatible with web browsers like the h265 encoder.

Some phones use the h265 encoder when using the smartphone camera for example, h265 is more modern and has better compression than h264, so smartphone providers use h265 so their users save on storage space. But h265 is not web compatible so if we upload a video that was encoded with h265 it won’t play on a website.

So what do sites like YouTube and Facebook do when users upload a h265 encoded video to a website? They transcode the video on their servers and then serve a h264 encoded version.

YouTube and Facebook, Instagram and TikTok, practically everybody on the internet use FFmpeg on their servers to process the videos.

Next we’ll transcode our video

ffmpeg -i bigbuckbunny.mp4 -map 0 -c:v libx264 -crf 18 -vf format=yuv420p -c:a copy h264bunny.mp4

Here we are using ffmpeg with the -i option, as we have learned by now, to indicate the file we are going to be working with.

-map 0 options tells it to perform the transcode on all available video streams in the container. The default is only 1 so that’s why we had the need to configure this. 0 means “all streams” in this case.

As we know, the -c option indicates the codec and :v portion indicates that we are only talking about the video codec and not the audio.

Remember when we were just copying transmuxing and not transcoding, we would just tell it a single -c option as we were merely copying the audio and video, but this time we are indicating the video only with -c:v libx264, the libx264 tells it to use the h264 encoder.

It’s very important when transcoding video to indicate the c:v.

The other options -crf 18 consist of the quality of the output we want, this is a huge topic on itself out of the scope of this tutorial. The quality settings options of FFmpeg are immense.

The -vf format=yuv420p refers to the pixel format and yuv420p is one of the most web compatible pixel formats and safe to use. Lastly again we are using the -c option but this time with the :a to indicate the audio codec that in this example we are indicating it to just copy.

At the end of the command we have the title of the output video, downscaled_720p.mp4.

Running this command will make a totally new transcoded version of bigbuckbunny.mp4, that in this example is supposedly a h265 encoded video that we are reencoding to h264 format to make it web compatible.

When working with codecs we can use -c:v for video, -c:a for audio, and -c:s for subtitles.

This is just one simple example of transcoding using FFmpeg. Transcoding goes in hand with changing the audio and video settings of which there are literally thousands of options.

How to Extract Audio From A Music Video with FFmpeg

Sometimes we hear a nice song on a video and we would like to save it.

ffmpeg -i bigbuckbunny.mp4 -c:a copy -vn bunnyrock.aac

It’s pretty simple to extract audio from a video. Notice that we are only copying the audio portion with -c:a copy. The -vn tells it to disable the processing of the video stream.

So here FFmpeg is just copying the audio stream, omitting the video stream and saving it to an audio only file format, the aac container with the .aac extension.

How To Split or Cut A Video File With FFmpeg

Sometimes it’s useful to split or cut a video into portions we want to save and archive. Instead of saving lots of unnecessary footage taking up storage space we cut parts of a video with FFmpeg.

ffmpeg -ss 00:00:00 -t 00:00:10 -i bigbuckbunny.mp4 -c copy buncute.mp4

This time we are running ffmpeg but before telling which file to use with the -i option, we will indicate the start time and duration of our output video.

The -ss 00:00:00 portion indicates at what point in the video our cut will start in the format of hours, minutes and seconds.

The -t 00:00:10 portion indicates the duration our video will have.

In our example we are cutting from the start of the video and lasting for only 10 seconds.

The rest of the options are as we know them, -i indicates which video and -c copy indicates that we are using the copy codec with buncute.mp4 being the final output file.


FFmpeg is a monster of an open source free software. Not only its capabilities are huge in quantity but the quality of its job is par with none.

Whole industries run ffmpeg in their core.

Websites like YouTube and Facebook wouldn’t exist without it. It’s one of those rare pieces of software that command respect at all levels, and for Linux users it’s a great tool to learn to use.

Notify of
Receive notifications when your comment receives a reply. (Optional)
Your username will link to your website. (Optional)

Inline Feedbacks
View all comments
You May Also Like
Bash Wait Command
Read More

Bash Wait Command

The wait command in bash is a process management command that waits for the specified process running in…