Tux

...making Linux just a little more fun!

2-cent Tip: Converting from $FOO to MP3

Ben Okopnik [ben at linuxgazette.net]


Wed, 25 Mar 2009 10:03:21 -0400

Recently, while organizing my (very large) music library, I analyzed the whole thing and found out that I had almost 30 (!) different file types. Much of this was a variety of info files that came with the music (text, PDF, MS-docs, etc.) as well as image files in every conceivable format (which I ended up "flattening" to JPG) - but a large number of these were music formats of every kind, a sort of a living museum of "Music Formats Throughout the Ages." I decided to "flatten" all of that as well by converting all the odd formats to MP3.

Fortunately, there's a wonderful Linux app that will take pretty much every kind of audio - "mplayer" (http://www.mplayerhq.hu/DOCS/codecs-status.html#ac). It can also dump that audio to a single, easily-convertible format (WAV). As a result, I created a script that uses "mplayer" and "lame" to process a directory of music files called "2mp3".

It was surprisingly difficult to get everything to work together as it should, with some odd challenges along the way; for example, redirecting error output for either of the above programs was rather tricky. The script processes each file, creates an MP3, and appends to a log called '2mp3.LOG' in the current directory. It does not delete the original files - that part is up to you. Enjoy!

#!/bin/bash
# Created by Ben Okopnik on Mon Jul  2 01:16:32 EDT 2007
# Convert various audio files to MP3 format
#
# Copyright (C) 2007 Ben Okopnik <ben@okopnik.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
 
########## User-modifiable variables ###########################
set="*{ape,flac,m4a,wma,qt,ra,pcm,dv,aac,mlp,ac3,mpc,ogg}"
########## User-modifiable variables ###########################
 
# Need to have Bash expand the construct
set=`eval "ls -1 $set" 2>/dev/null`
# Set the IFS to a newline (i.e., ignore spaces and tabs in filenames)
IFS='
'
# Turn off the 'fake filenames' for failed matches
shopt -s nullglob
 
# Figure out if any of these files are present. 'ls' doesn't work (reports
# '.' for the match when no matching files are present) and neither does
# 'echo [pattern]|wc -w' (fails on filenames with spaces); this strange
# method seems to do just fine. 
for f in "$set"; do ((count++)); done
[ -z "$count" ] && { echo "None of '$set' found; exiting."; exit 1; }
 
# Blow away the previous log, if any

>"${0##*/}.LOG"
# The child process spawned just below allows dealing with the STDERR # redirection; it seems that you can't just do 'exec 2>foo' in the current # shell. This may be a Bash bug. ( for i in $set do fn="${i##*/}" base="${fn%.*}" # Dump STDERR to the log; 'mplayer' can't handle the '2>foo' # redirection semantics exec 2>>"${0##*/}.LOG" echo "######### ${0##*/}: Processing $i #########" >&2 echo -n "*** MPLAYER: ***" >&2 echo -n "'$i': Dumping via Mplayer... " time /usr/bin/mplayer -msglevel all=-1 -vc null -vo null -af resample=44100 -ao pcm:fast "$i" > /dev/null [ "$?" -gt 0 ] && echo "############ ERROR (mplayer): Check ${0##*/}.LOG for details." echo -ne "\n*** LAME: ***" >&2 echo -n "Encoding via Lame... " time /usr/bin/lame -S -m s audiodump.wav -o $base.mp3 [ "$?" -gt 0 ] && echo "############ ERROR (lame): Check ${0##*/}.LOG for details." [ -e "audiodump.wav" ] && /bin/rm audiodump.wav # Wrap the console report line echo done )
-- 
* Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *


Top    Back