Converting Audio to Multiple Formats using ffmpeg or avconv

The following is a Bash shell script that uses ffmpeg (or avconv) to convert an audio file such as a PCM/WAV file to different formats using different codecs (e.g. to MP3). I created it to demonstrate the conversion process and to be able to compare audio encoded with different codecs.

The script works on my computers using Ubuntu 13.04 (and 12.04). It is poorly written, inefficient and may not work on other systems. However it achieved my aim. I recommend you read through and customise for your system, especially the list of codecs and rates to use.

To use, copy and paste into a file such as convaudio, save that file and then execute:

$ bash convaudio infile.wav

Here it is:

#!/bin/bash
# Convert an audio recording to multiple different formats
# Steven Gordon  2013-08-26
#
# Usage:
#  convaudio infile.wav
#  where infile.wav is the original audio file
# The output will be multiple audio files and a summary of the conversion.
#
# There are two sets of parameters that you may want to change in this script:
# 1. list of codecs/formats - see the 1st for loop
# 2. encoding bit rates - see the 2nd for loop
#
# ffmpeg/avconv is used to perform the conversion. A simple example of using
# ffmpeg to convert WAV to 64kb/s MP3 is
#  ffmpeg -i infile.wav -codec:a libmp3lame -b 64k outfile.mp3
# In many cases the "-codec:a CODEC" option is not needed as ffmpeg will
# guess the codec based on the output extension. 

# Input file name
ifn=$1

# Extract the extension from the input file name
inext=`echo ${ifn} | cut -d "." -f 2`

# Some Linux systems (including Ubuntu) install avconv by default, others ffmpeg. You can 
# select which one to use by comment/uncommenting the following lines. 
app="ffmpeg"
#app="avconv";

# Temp file
tf=`mktemp`

# Display the header for the summary output
echo "CODEC FORMAT RATE FILESIZE TIME"

# The set of codecs/formats to use are listed below. Separate the codec and format
# by a dot (.). To see a list of codecs/formats supported by ffmpeg/avconv type:
#   ffmpeg -codecs
#   ffmpeg -formats
# Some codecs may only be available on certain versions of ffmpeg.
# Other codecs that you may try include:
#   libfaac
#   mp2
#   libspeex
#   ac3
#   wmav2
for i in libvo_aacenc.aac flac.flac libmp3lame.mp3 libvorbis.ogg alac.m4a libgsm_ms.wav;
do
	# Extract the codec name and extension/format name 
	codec=`echo ${i} | cut -d "." -f 1`;
	ext=`echo ${i} | cut -d "." -f 2`;

	# Special cases
	# GSM must use a rate of 13k
	if [ ${codec} = "libgsm_ms" ];
	then
		options=" -b 13k -ar 8000 "
	else
		options="";
	fi

	# Set the list of rates here
	# Note that for some codecs the rates are not applied (e.g. FLAC, ALAC)
	for rate in 32k 64k;
	do
		# Output codec, format and rate
		echo -n "${codec} ${ext} ${rate} "

		# Determine output file name
		ofn="`basename ${ifn} .${inext}`-${codec}-${rate}.${ext}"

		# Convert, also recording the time of the conversion
		/usr/bin/time --output=${tf} -f'%S + %U' ${app} -loglevel quiet -y -i ${ifn} -codec:a ${codec} -b ${rate} ${options} ${ofn}

		# Calculate output file size
		fs=`ls -l ${ofn} | cut -d " " -f 5`

		# Output file size and time 
		echo -n "${fs} "
		cat ${tf} | bc
	done
done

# Delete temp file
rm ${tf}