1. Overview
ffmpeg is a free and open-source set of multimedia file management tools. Using ffmpeg, we can convert between different video and audio formats. Also, we can alter sample rates, record streaming audio and video, resize videos, and concatenate videos.
In this tutorial, we start with the steps to install the program on Ubuntu, CentOS, and Debian. Importantly, we’ll also demonstrate how to concatenate videos using the command.
2. Installing ffmpeg
The installation process of ffmpeg requires root or sudo privileges. To demonstrate, let’s update the apt package list and install ffmpeg:
$ sudo apt update
...
$ sudo apt install ffmpeg
...
Finally, let’s print information about ffmpeg via -version to check our installation:
$ ffmpeg -version
ffmpeg version 4.4.2-1ubuntu3 Copyright (c) 2000-2022 the FFmpeg developers
...
The output’s header shows the version of the program, but we can also see its configuration and the libraries it uses.
Also, we can use snap to install the latest stable version of ffmpeg on a Debian/Ubuntu machine.
Next, let’s move to video concatenation.
3. Concatenation Prerequisites
There are various methods to employ when merging videos using ffmpeg. Among them are the concat functions:
- demuxer
- filter
- protocol
Further, each use case depends on the properties of the videos in question. Importantly, we need to ensure all encoding-related properties align with our method of choice:
- timebase
- height and width
- codecs
- pixel format
For some methods, we have to use files with the same encoding, while others allow different files.
4. Concat Script Demuxer
The concat script demuxer is usually the most simple of all methods for merging. It’s very fast and has no quality loss. This is because there is no decoding or re-encoding required.
To concatenate videos with the concat demuxer method, we first create a text file, listing all video files. Then we run a command, to process that list. In this case, we’ll use the files Kali.mp4, openLDAP.mp4, and SSH.mp4.
4.1. Listing Files for Concat Demuxer
Let’s compile a list of videos to concatenate in a text file using the printf command:
$ printf "file '%s'\n" *.mp4 > list.txt
This command writes the name of files ending in .mp4 in the current directory to list.txt. Note, that the video file paths should be on new lines, within single quotes, prefixed with the word file:
$ cat list.txt
file 'Kali.mp4'
file 'openLDAP.mp4'
file 'SSH.mp4'
ffmpeg reads and concatenates the videos in order, as they appear on the list. Importantly, the first file begins at timestamp zero (0), while each ensuing file begins where the previous one ends. Hence, ffmpeg uses the duration of each file to adjust the timestamps of the next file.
4.2. Concatenating Using Concat Demuxer
Now, let’s use the -f concat flag to merge the videos from our list.txt file:
$ ffmpeg -f concat -i list.txt -c copy outfile.mp4
Here, the value of the -i flag indicates the path to the input file. Also, -c copy ensures there is no re-encoding.
Next, we add -safe as an important option, the value of which decides whether to reject (1) or accept (0) unsafe paths:
$ ffmpeg -f concat -safe 0 -i list.txt -c copy outfile.mp4
Mostly, a file path is safe if it:
- does not specify a protocol
- contains only characters from the portable character set (letters, numerals, period, underscore, and hyphen)
- has no period at the beginning of its name
Lastly, the transcoding process of ff**mpeg includes demuxing, decoding, encoding, and muxing. Since we’re using -c copy, this leaves only demuxing and muxing.
5. Concat Multimedia Filter
Of course, we often have videos with different encodings. We can merge those with the concat filter since it re-encodes as part of its process. Also, it enables filtering the input files before merging. Since it goes through the whole transcoding chain, this method is generally slower.
Critically, for the concat filter to work correctly, all video files must start at timestamp zero (0.00).
5.1. Concatenating Videos With a Single Audio Stream
To explain the contact filter, we’ll use start.mkv, body.mkv, and rear.mkv with a single audio stream:
$ ffmpeg -i start.mkv -i body.mkv -i rear.mkv -filter_complex \
"[0:v] [0:a] [1:v] [1:a] [2:v] [2:a]
concat=n=3:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mkv
Here’s a quick rundown of what’s going on in the command:
- Supply input files with the -i flags
- Use -filter_complex to select streams from the input files
- Select the actual streams in a specific order: video and audio from the first, second, and third file
- Use the filter concat=n=3:v=1:a=1 [v] [a]
- Map the resulting audio and video streams to the output
In step 4, the number of files we want to join is in the value of n (default is 2). Next, we follow with v (default is 1), which sets the number of output video streams. Similarly, a (default is 0) sets the number of audio streams in each section. It also sets the number of output audio streams.
Finally, the -map flag in step 5 allows for a custom stream selection in each output file if there are multiple. Users can skip –map and let ffmpeg handle stream selection.
5.2. Concatenating Videos With Multiple Audio Streams
Likewise, let’s concatenate an opening, an episode, and an ending, with two audio streams. That is, video in stream 0, audio in streams 1 and 2:
$ ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv -filter_complex \
'[0:0] [0:1] [0:2] [1:0] [1:1] [1:2] [2:0] [2:1] [2:2]
concat=n=3:v=1:a=2 [v] [a1] [a2]' \
-map '[v]' -map '[a1]' -map '[a2]' output.mkv
Notice that the second line in this example is like [0:v] [0:a] [0:a] [1:v] [1:a] [1:a] [2:v] [2:a] [2:a] in the notation of our previous examples. In fact, this shows that we have a single video stream ([0:v], [1:v], [2:v]) and dual audio streams ([0:a][0:a], [1:a][1:a], [2:a][2:a]).
6. Physical Concatenation Protocol
The concat protocol is another way of concatenating videos with ffmpeg. It reads and seeks from a large pool of resources, treating each one as unique.
However, this approach doesn’t work with several formats, including MP4. It’s the nature of these formats as well as the method’s basic concatenation that prevents its general application. We can use the concat protocol with formats like MPEG, which allows file-level concatenation.
For example, let’s concatenate the files clay.mpeg, sculpt.mpeg, and mold.mpeg:
$ ffmpeg -i "concat:clay.mpeg\|sculpt.mpeg\|mold.mpeg" -c copy output.mkv
Notice that we use *\* (backslash) to escape the pipe symbol.
7. Conclusion
In this article, we saw several ways for concatenating videos with ffmpeg. We also saw how to install ffmpeg on various Linux distributions.