Most efficient way to convert a large ALAC library to MP3

5

5

I have a large library of CDs ripped to alac which I use as my main music library. I'd like to convert a copy of this library to vbr mp3 for portable devices, however I don't want to have to do this on my laptop, as there is approximately 650Gb of music and I travel to much to leave my laptop sitting for the time it would require to convert my whole library. My friend has some server space (running Debian Squeeze) he is willing to lend me for a week or two to power through converting my library. What would be the best utility or way to go about this. For single songs or single albums I just use something like

#!/bin/sh
for file in "$@" ; do
name=`echo "$file" | sed -e "s/.mp4$//g"`
ffmpeg -i "$file" -ac 2 -f wav - | lame --preset standard - "$name.mp3"
done

I'm sure there is a much more efficient way to do this. My music is currently organised as "Artist - Albums - Tracks" and I would like the output to mirror this.

Leda

Posted 2011-09-25T15:23:22.320

Reputation: 371

How many CPUs/cores does the server have? (LAME only supports single-threaded encoding, but on quad-core you could encode four songs at once.) – user1686 – 2011-09-25T15:50:37.923

I have 4 CPU cores available on the server for transcoding. – Leda – 2011-09-25T16:38:45.843

Answers

4

In the examples below, ~/Music/ is assumed as the source directory.


Create a convert.sh script:

$ cat > convert
#!/bin/bash
input=$1
output=${input#.*}.mp3
ffmpeg -i "$input" -ac 2 -f wav - | lame -V 2 - "$output"
[Ctrl-D]
$ chmod +x convert
  • If you want a different location to be used for the outputs, add this before ffmpeg:

    output=~/Converted/${output#~/Music/}
    mkdir -p "${output%/*}"
    

Convert using parallel from moreutils:

$ find ~/Music/ -type f -name '*.mp4' -print0 | xargs -0 parallel ./convert --

Not to be confused with GNU parallel, which uses a different syntax:

$ find ~/Music/ -type f -name '*.mp4' | parallel ./convert

user1686

Posted 2011-09-25T15:23:22.320

Reputation: 283 655

2

With GNU Parallel you do not even need the script:

find ~/Music/ -type f -name '*.mp4' | parallel ffmpeg -i {} -ac 2 -f wav - \| lame -V 2 - {.}.mp3

The same thing can be accomplished without using lame, assuming your version of ffmpeg is compiled with libmp3lame enabled (most versions are):

find ~/Music/ -type f -name '*.mp4' | parallel ffmpeg -i {} -c:a libmp3lame -q:a 2 {.}.mp3

You can also use -iname instead of -name in the find command, to get case insensitive matches (so it'll pick up all *.mp4 and *.MP4, and all the case variations). Also, -ac 2 is not strictly required in the second version; MP3 can only support a maximum of two channels anyway, so ffmpeg will automatically convert audio down to two channels if it needs to, which will avoid you adding an extra pointless channel to any mono audio you may have.

See this ffmpeg wiki page for some basic information about encoding MP3s, and this hydrogenaudio guide for more in-depth information.

If you have other machines that you can ssh to (e.g. maybe your laptop is available during the nights) GNU Parallel can use those CPUs, too. Look at the examples of --trc (to transfer the files) and --retries (to deal with the laptop being away during the day). See http://www.gnu.org/software/parallel/man.html#example__using_remote_computers

Watch the intro videos to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange

Posted 2011-09-25T15:23:22.320

Reputation: 3 034