In this quick note I am going to look at this problem: how to edit a group of videos using FFmpeg.
I will work specifically with the Linux operating system. But most of the text applies well to other systems, although results may vary.
And without further ado, let’s get to it….
List of materials
Let’s say that in a given directory I have a set of videos.
Just for the well being of this example i am going to use only four videos. They can be more or less videos, it is simply a test for the idea to work.
So I have these files, and I want to extract a single fragment from each one. It’s what can be a simple video montage, I want to extract a part of each shot (a “mini video” if you will) to create a new sequence.
My first job is going to be to know the timecode of each of these shots that I’m going to cut. In other words, I have to know when each cut starts and ends in each file.
These aforementioned audiovisuals are now called “video001”, “video002”, “video003” and “video004”.
What I have to do is to create a text document that I will call: “timecode.txt”.
In this file I am going to write the name of the video I am cutting, the time where cutting starts, the time where cutting ends and the name of the resulting new file. For example:
video001.mp4, 00:00:10.0, 00:00:20.0, cut01.mp4
This means that “video001.mp4” will be cut between the second “00:00:10.0” and the second “00:00:20.0”. In the end, the new ten-second file that will result from running the code will be called “cut01.mp4”.
And the complete text file looks like this:
video001.mp4, 00:00:10.0, 00:00:20.0, cut01.mp4 video002.mp4, 00:00:08.0, 00:00:11.0, cut02.mp4 video003.mp4, 00:00:02.0, 00:00:05.0, cut03.mp4 video004.mp4, 00:01:03.0, 00:01:25.0, cut04.mp4
Well, this is just the first thing I need. This way of doing things is not completely automatic, I need to know the videos and where each cut is going to go to get started.
Things are about to get more interesting, as everything is going to start to fill in more easily.
Reading the file and cutting the video
To cut the video I’m going to need an ffmpeg command. That command is as follows:
ffmpeg -ss BEGIN -to END -i INPUT -c copy OUTPUT
What this command does is to cut a video between the “start” timecode and the “end” timecode. It does this on an “input” file and returns an “output” file.
For example, if I wanted to cut only one of the videos the command would look like this:
ffmpeg -ss 00:00:10.0 -to 00:00:20.0 -i video001.mp4 -c copy cut01.mp4
The file to be exported will not be modified in any of its characteristics. It retains its format, its extension and that sort of thing.
That is material for another note, so in this case this way of doing the job will work best if all the files share the same type. But that’s not difficult, if for example all the videos are from the same camera or have the same origin.
So I have the command to cut a video. But in my list I have four files, and I could have a list with some cuts.
How do I read the text file and enter that into the command?
Well, for that I’m going to use another command. This one is called “gawk” and its manual tells me:
NAME
gawk – pattern scanning and processing language
from the GAWK manual
Well, gawk is the GNU implementation of “Awk”, a tool for pattern scanning and language processing.
This tool looks quite complex and is a programming language in itself… luckily I’m only interested in one thing: to be able to read the text file, separating each line in fragments and adding everything later as parts of another command.
For example in this first line of “timecode.txt” I have:
file01.mp4, 00:00:10.0, 00:00:20.0, newfile01.mp4.
That is, four elements separated by a “comma” (,) each.
If I now combine Gawk with the ffmpeg command I have:
'gawk -F, '{cmd="ffmpeg -ss " $2 " -to " $3 " -i " $1 " -c copy " $4 " """; system(cmd)}' timecode.txt
How does this work?
Well, as far as I can understand it Gawk understands each of the fragments of a line as variables, and separates them like this:
$1 $2 $3 $4 file01.mp4, 00:00:10.0, 00:00:20.0, newfile01.mp4
Then these variables are included inside the command. And they are repeated each time, one for each line inside timecode.txt to help me edit each video.
With this I not only get to read a text file to use as variables for a command, I now have four freshly cut videos ready to be integrated into a new audiovisual.
Editing a set of videos with ffmpeg
I now have four new videos in my directory. These videos range from “cut01.mp4″ to ” cut01.mp4″… through the two in between, which is easy to imagine.
However in order to continue I’m going to need a new text file. That file has to contain the name of each video, each name occupying a different line.
Luckily I can create this new list quickly with the “ls” command, running it in the folder like this:
ls -1 *.mp4 | sed 's/^/file /' > montage.txt
The result should be a text file with the name “montage.txt”, where in each line appears the name of each of the videos. And in front of each name the “sed” command will add the prefix “file” to each name, so that ffmpeg can understand that those are the files to join.
Actually what the command does is to use a wildcard to list all the .mp4 files in my folder, but since in my case there are only four of them those are the ones that appear in it.
Now that I think about it, maybe the best thing to do is to first move the videos I need to edit to a new directory, so that I don’t end up unintentionally listing the originals as well. At this point I need to work only with the new shorts.
The result is a text document that reads as follows:
file cut01.mp4 file cut02.mp4 file cut03.mp4 file cut04.mp4
The last thing I have left is to edit those four videos into one, and I can achieve that with the following command:
ffmpeg -f concat -safe 0 -i montage.txt -c copy finished.mp4
What ffmpeg does in that case is to concatenate all the files in the text “montage.txt” and gives me a new video called “finished.mp4”.
Keep in mind that, as I mentioned before, the results may vary.
It may happen that the video has some errors or “glitches” if there were differences between the details of the videos, such as different resolutions.
And another thing is that the cuts may not be completely accurate. It can happen, so I think it’s a matter of the number of frames in the file. Two files may have different amount of frames, or the cut may fall on a frame that generates some error.
Anyway ffmpeg has options to improve that, although reviewing them is something that escapes the brevity of this note. And the truth is that I can always ask an artificial intelligence to help me, every error is provisional.
Conclusion:
This is at least one way to do the editing of a group of videos using ffmpeg on Linux.
Surely there are other ways to automate the editing of large amounts of video using other programs. But this way we managed to do it using only the command terminal and some tools.
And the best thing is that the result comes very fast, ffmpeg cuts at full speed. Besides, it is always possible to join everything in the same Bash script, and make it even more practical.
Any ideas or criticisms you have, I would like to read your comments or emails.
We’ll follow it up in the next note.