Converting Multiple mp4 Video Files to webm and ogv Using a Simple Shell Script
This tutorial explains how to easily convert multiple video files located in a specified directory and its subdirectories to other formats, for example, to use on the web, making your video clips accessible to a greater range of web browsers.
Note that you need avconv or ffmpeg to be installed on your machine. If you don't have it, you can install it by running one of the following one-liners:sudo apt-get install libav-tools
sudo apt-get install ffmpeg
Here is the snippet of code that actually does the conversion:
#! /bin/sh -
# Usage:
# ./video-converter.sh [/path/to/some_dir]
CONVERTER=ffmpeg
if test "$1"
then
srcdir="$1" # Use the path to directory provided.
else
srcdir=. # Use the current directory (.) instead.
fi
find "$srcdir" -type f -iname '*.mp4' | while read file
do
$CONVERTER -i "$file" "${file%.*}.webm"
$CONVERTER -i "$file" "${file%.*}.ogv"
done
If you curious how it works, here is a step by step explanation:
Setting up: because on some systems there's a package named avconv and others ffmpeg, I make the script more flexible by assigning the CONVERTER variable to the name of the package installed on the current machine to use later in the script.
CONVERTER=ffmpeg
1. To determine where the directory containing the video files located the script checks if a shell script argument ($1) has been provided; otherwise the current directory (.) will be used. The resulting value is assigned to the srcdir variable:
if test $1
then
srcdir="$1"
else
srcdir=.
fi
A much shorter, albeit criptic way of checking if a variable exists and isn't null is to use substitution operator:
srcdir="${1:-.}"
The substitution operator can also be placed straight along the find command, making the code even shorter like so:
find "${1:-.}" ...
2. To search for mp4 files recursively, traversing the directory tree the find command is used with the following options:
- -type f to look only for files (ignoring directories, links and other file types)
- -iname *.mp4 that tells the find to look for files with filenames that can be anything but end with a dot followed by mp4.
3. When there's a match, the output of the find command, that is to say a path to a file, is piped into the while loop that uses the read command to assign this path to a variable named file:
... | while read file
4. Now, inside the loop, we can conveniently use this variable on the lines that actually do the conversion:
$CONVERTER -i "$file" "${file%.*}.webm"
$CONVERTER -i "$file" "${file%.*}.ogv"
In its basic form, the avconv/ffmpeg program needs only two arguments to be supplied: the input file (prepended with -i) and the name of the output file; both of those programs scan the extension of the latter and automatically choose the appropriate algorithm for conversion.
The $file variable enclosed in the braces like so ${file%.*} tells the interpreter to remove everything that goes after the dot in the string that it holds, (in our case it's the mp4 substring). After that we append a new file extension (webm or ogv).
$file → some_file.mp4
${file%.*} → some_file
${file%.*}.webm → some_file.webm
I hope you enjoyed this little tutorial, if you have any comments or questions, feel free to ask me using the comments below or the contact page