How To Automate Multiple FFmpeg Commands With Bash

ffmpeg and bash logos on a green gradient background

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.

This tool powers many widespread media-based applications, such as: iTunes, Youtube and the famous video player VLC. FFMPEG is a very fast tool used for converting and streaming video and audio, and also used in grabbing from live video or audio sources.

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
Output
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
Output
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
Output
/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
Output
#! /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
Output
/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
Output
#! 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
Output
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
Note: 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
Output
#! /bin/bash

for mediafile in *.mkv; do
ffmpeg -i $mediafile -c copy  "${mediafile%.mkv}.mp4"
done
Note: We used the % 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
Output
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
Note: As with any command line interface, the user should specify the path of input or output files depending on their working directories. In the examples given in this article, it is assumed that the user has navigated to the working directory to execute the bash script/ffmpeg commands.

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
Output
#! /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
Note: the dot symbol . represents the current directory (./).
ls output_files/
Output
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
Output
#! /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/
Output
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.

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

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Name
1 year ago

very very very good. thank you

Laszlo
Laszlo
1 year ago

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.

Last edited 1 year ago by Laszlo
You May Also Like