In this article you will learn how to use Bash scripting to automatically perform multiple FFMPEG tasks, to effortlessly convert or extract media files.
The Importance of FFmpeg
In our daily computing life, we make use of software and programs without realizing that we are using a particular different program used by our main program. One very good example of this description is FFMPEG.
FFMPEG is actually a command line utility (CLI) used mainly by software developers and media industry professionals, to perform operations on media files such as format conversion, encoding, resizing, concatenation, and compression.
This project has a lot of useful features, specially the conversion feature. For the majority of people, the idea of converting video files may not be even in their dictionary. Unless they are part in a video production project or they happen to manage media files in regular bases. However, a normal person can be in situations where they require the capability of converting video files, for example: to ensure that the video can be played on different devices, to compress videos to smaller file sizes, or to improve the bitrates.
In this article we will discuss how to use bash to automate multiple FFmpeg tasks.
There a high chance that anyone could run into a situation where they want to extract or convert a large quantity of media files. In such situations, it’s imperative to understand how to use bash scripting to work for your advantage.
Basic FFmepg commands consist of four elements:
ffmpeg [Input File] [Options] [Output File]
Why Should We Use Bash With FFmpeg?
The Bash shell is a powerful command language interpreter which allows users to automate tedious and repetitive tasks on any Linux system.
Most everyday Linux users benefit from bash scripting to automate tasks and make their day to day jobs a lot easier by not repeating tedious and time consuming tasks every day.
In this article we will use bash scripting to automate multiple ffmpeg
tasks at once. For example converting or extracting audio files from 100 media file.
How to Install FFmpeg
To install FFMPEG, we first go to our terminal, and type the following update command to download package information from all configured sources:
sudo apt update
After making sure that the first command got executed correctly, Type the below given command to install the project:
sudo apt install ffmpeg
After executing the preceding command. FFMPEG will get installed onto our system, and also add the ffmpeg
binary to the path variable. So now we can use the ffmpeg
command in the command line.
One final step left is to verify that FFMPEG is actually installed. Let’s type ffmpeg
to check the ffmpeg configuration.
ffmpeg
ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
[powerkit_alert type=”info” dismissible=”false” multiline=”false”]
Note: Another way to display the version of ffmpeg
, is by adding the -version
command line switch.
[/powerkit_alert]
Getting Started With BASH Scripting
Let’s start by creating our bash file using the touch command:
touch auto_ffmpeg.sh ls
auto_ffmpeg.sh Bbear_EP_02.mkv Bbear_EP_04.mkv Bbear_EP_06.mkv Bbear_EP_01.mkv Bbear_EP_03.mkv Bbear_EP_05.mkv
[powerkit_alert type=”info” dismissible=”false” multiline=”false”]
Note: Adding the .sh
denominator for Bash files is not a necessary thing, but it’s a best practice.
[/powerkit_alert]
Next step is to define bash as an interpreter for our script. To do that, we will have to know its executable binary’s path using the which
command.
which bash
/bin/bash
Now prefix this path with the shebang #!
and add it to the bash script auto_ffmpeg.sh
just as so:
nano auto_ffmpeg.sh ...
cat auto_ffmpeg.sh
#! /bin/bash
Note: You should know that Bash is the default interpreter for most Linux systems. This why our scripts will be interpreted as bash without us adding the interpreter line. You can check the default interpreter used by your system by executing the following:
echo $SHELL
/bin/bash
Before starting using ffmpeg
commands in our script, it’s better to start with a simple echo command to iterate through a directory and print to the screen all our media files (.mkv
for example).
Open our bash script auto_ffmpeg.sh
with any text editor of your choosing , and then add the following new lines to it just like so:
cat auto_ffmpeg.sh
#! usr/bin/bash for mediafile in *.mkv; do echo $mediafile done
The above script is making use of a for loop to iterate over the .mkv
files of the current directory, additionally it print out the $mediafile
variable’s value which holds the name of the file.
[powerkit_alert type=”info” dismissible=”false” multiline=”false”]
Note: we used * as a wildcard to match any string. So, *.mkv
matches all filenames ending with .mkv
.
[/powerkit_alert]
Let’s make our bash script executable and then execute it. Follow the mentioned below commands:
chmod +x auto_ffmpeg.sh ./auto_ffmpeg.sh
Bbear_EP_01.mkv Bbear_EP_02.mkv Bbear_EP_03.mkv Bbear_EP_04.mkv Bbear_EP_05.mkv Bbear_EP_06.mkv
Using Bash Scripting To Automate FFmpeg Tasks
With ffmpeg we can choose between two different ways to convert media files. The first and easy one is to copy streams into the desired container, and the second one is to re- encode those streams in order to change their quality or size. But for our purposes we will consider only the first method due to its simplicity.
To convert mkv
to mp4
is actually quite easy, we can use the ffmpeg
command to copy the original video and audio streams into a new container. In order to achieve this, execute the following line:
ffmpeg -i Bbear.mkv -c copy Bbear_wout.mp4
Bbear.mkv
is our original media file, and -c copy Bbear_wout.mp4
is for specifying the name of the converted file.Now let’s implement what we have learned so far. Technically all we have to do is to replace the echo command with the preceding ffmpeg
command, with a little bit of tweaks. Check the following script for better understanding.
cat auto_ffmpeg.sh
#! /bin/bash for mediafile in *.mkv; do ffmpeg -i $mediafile -c copy "${mediafile%.mkv}.mp4" done
%
symbol to strip off the .mkv
string from the base name, then we added the .mp4
part.Execute the bash file just as before, then check the output files.
./auto_ffmpeg.sh ls
auto_ffmpeg.sh Bbear_EP_02.mp4 Bbear_EP_04.mp4 Bbear_EP_06.mp4 Bbear_EP_01.mkv Bbear_EP_03.mkv Bbear_EP_05.mkv Bbear_EP_01.mp4 Bbear_EP_03.mp4 Bbear_EP_05.mp4 Bbear_EP_02.mkv Bbear_EP_04.mkv Bbear_EP_06.mkv
Making Your BASH Script More User-friendly
To make our bash script more flexible it’s better to let the user choose the media file extensions for both the input and the output; additionally, it’s also more convenient to choose the directories on the script run-time.
Observe the changes below and add them to your script.
cat auto_ffmpeg.sh
#! /bin/bash # the extension of input files in_exten=$1 # the extension of converted files out_exten=$2 # input files directory in_dir=$3 # converted files directory out_dir=$4 for mediafile in "$in_dir"/*.$in_exten; do ffmpeg -i $mediafile -c copy "$out_dir"/"${mediafile%.$in_exten}.$out_exten" done
First we should understand the above script before executing it.
We used four positional parameters to handle the input and output extension, plus the input and output directories (as described in the comments), these changes will enable our script to convert files from/to any location on the system and also it will allow the user to choose media containers without having to edit the script in other situations (e.g. avi
to ogg
).
Let’s execute our bash script.
./auto_ffmpeg.sh mkv mp4 . output_files
.
represents the current directory (./
).ls output_files/
Bbear_EP_01.mp4 Bbear_EP_03.mp4 Bbear_EP_05.mp4 Bbear_EP_02.mp4 Bbear_EP_04.mp4 Bbear_EP_06.mp4
As shown above, we are converting mkv
media files (first parameter), to mp4
(second parameter), from the current directory (Third parameter) , to the output_files directory (fourth parameter).
Bonus: Extracting Multiple Audio Files at Once
So far we used a simple ffmpeg
command to convert media files from mkv to mp4. However, if you implement what we have learned so far, you should be able to make custom bash scripts that automate other ffmpeg
commands for you, with just small tweaks.
Let’s take a gander at the script given below that is using an ffmpeg
command to extract audio files from multiple .mp4 files located in directory.
cat auto_ffmpeg_exrtact.sh
#! /bin/bash in_exten=$1 out_exten=$2 in_dir=$3 out_dir=$4 for mediafile in "$in_dir"/*.$in_exten; do ffmpeg -i $mediafile -vn -acodec copy "$out_dir"/"${mediafile%.$in_exten}.$out_exten" done
Note: we based the ffmpeg
on the below command that extracts audio stream (ac3
) from the media file (mp4
):
ffmpeg -i Bbear_EP_03.mp4 -vn -acodec copy audio.ac3
Now let’s execute the script and check the results:
./auto_ffmpeg_exrtact.sh mp4 ac3 . output_filesubuzz@ubuntuz:~/ffmpeg_bash$ ls output_files/ ls output_files/
Bbear_EP_01.ac3 Bbear_EP_03.ac3 Bbear_EP_05.ac3 Bbear_EP_02.ac3 Bbear_EP_04.ac3 Bbear_EP_06.ac3
Conclusion
In this how to article, we’ve walked you through how to automate FFmpeg tasks using bash scripting. We hope these instructions may come in handy for you.
very very very good. thank you
This part: ffmpeg -i $mediafile
should have $mediafile in quotation marks as well. FFmpeg doesn’t accept file names with whitespace or special characters. That is, unless it’s in quotation marks: ffmpeg -i “$mediafile”
I know they weren’t needed in the examples, but if some copies this (and has files with whitespace in their names), it might take them hours to realize why they are getting errors. The error messages don’t really make it clear (they just say: “first part of file name”: No such file or directory).
I usually convert many files in a batch. Normally I use Winff to manage the queue for me. However as it’s no longer developed (stuck on gtk+ 2, it still receives fixes if something breaks) I was looking for another solution. Which led me here.
After adding the quotation marks it works great. Just have to be careful not to leave old files in the input directory.