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

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

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.

  • 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
    Sep 25 '11 at 15:50
  • I have 4 CPU cores available on the server for transcoding.
    – Leda
    Sep 25 '11 at 16:38

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

Create a convert.sh script:

$ cat > convert
ffmpeg -i "$input" -ac 2 -f wav - | lame -V 2 - "$output"
$ chmod +x convert
  • If you want a different location to be used for the outputs, add this before ffmpeg:

    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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.