Exporting an MP3 mix from iTunes — April 24, 2010

Exporting an MP3 mix from iTunes

Suppose you make an MP3 mix for someone in iTunes. It’s easy enough to export the *list* of songs in that mix. And it’s easy enough to burn those songs to a CD. But it seems nontrivial to export *the actual MP3s*. Am I just not seeing an obvious way to do this?

Using a little shell-scripting, you can do this fairly easily:

#!/bin/bash
m3u_file=$1
export_dir=$2

function check_for_executables() {
# Paths to executables
TEST=/bin/test
MKDIR=/bin/mkdir
GREP=/usr/bin/grep
CP=/bin/cp
BASENAME=/usr/bin/basename

bad_execs=()
# Test that all executables are there
for executable in $TEST $MKDIR $GREP $CP $BASENAME; do
if ! $TEST -x $executable; then
bad_execs=”$bad_execs $executable”
fi
done

if ! $TEST -z $bad_execs; then
echo “Some required executables are missing: $bad_execs”
exit 1
fi
}
function process_args() {
if $TEST -z “$m3u_file”; then
echo “Must give the path to an M3U file.”
exit 1
fi

if $TEST -z $export_dir; then
export_dir=$(realpath $(pwd))
fi

echo “Exporting to $export_dir”

if ! $TEST -d $export_dir; then
echo “$export_dir does not exist or is not a directory; trying to create it”
if ! $MKDIR -p $export_dir; then
echo “Failed to create export directory $export_dir; quitting.”
exit 1
fi
fi
}
function export_playlist() {
i=0
cat “$m3u_file” |while read line; do
# Skip comment lines and blank lines
if echo $line |$GREP -q ‘^#|^s*$’; then
continue
fi
let i=i+1
if `echo $line |$GREP -q ‘^s*$’`; then
# line is blank, so skip it
continue
fi

filename=$(printf ‘%02d’ $i)_$($BASENAME “$line”)
export_path=${export_dir}/$filename
$CP “$line” “$export_path”
done
}

function main() {
check_for_executables
process_args
export_playlist
}

main

(Obvious improvements:

1. The `printf` statement prepends each track with its track number in the mix, and assumes that there are at most 100 songs in your mix. Have the script figure out the number of tracks in the mix, then compute the appropriate number of digits from that. The appropriate number of digits would be something like floor(log10(n))+1, where n is the number of tracks in the mix and floor(x) is the greatest integer that’s no larger than x.
2. If the script is longer than about 10 lines, contains nontrivial logic, could usefully stand to compute logarithms, and can be meaningfully decomposed into functions, shell is no longer an appropriate language; use something like Perl or Python instead.

Exercises for the reader.)