...making Linux just a little more fun!
Ben Okopnik [ben at linuxgazette.net]
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 <[email protected]> # 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 *