A few methods to convert AAC (m4a) to MP3 under Linux

Picked up a 8 GB Sansa Clip+ for 30 bucks, transferred my wakeboarding playlist over and found that it won't play AAC files. For now, decided to stick with factory firmware and simply convert the few AAC files I had in the playlist to MP3. Below is a list of things I tried and what I ended up using.

Each method was tested on the same machine using the same source m4a file.

Convert m4a to mp3 using a fixed bitrate matching bitrate of the source

First, a function to get the bitrate of the source, this method requires mediainfo (sudo apt-get install mediainfo):

GetInfo()
{
  info=$(mediainfo $f | sed -r 's/[ ]+:[ ]/|/') 
  bitrate=$(echo "$info" | awk -F'|' '$1=="Bit rate" {gsub(/([ A-Za-z]+)/,"",$2); print$2}')
}

1. Convert with faad + lame (sudo apt-get install faad lame):

for f in *.m4a; do
  GetInfo
  faad -q -o - "$f" | 
  lame -h -b $bitrate - "${f%.m4a}.mp3"
done

Conversion took 10.307 sec. None of the audio metadata (e.g. tags -- title, artist, album, etc) from the m4a was transferred to mp3.

2. Convert with avconv (ffmpeg replacement in Debian/Ubuntu, sudo apt-get install libav-tools):

for f in *.m4a; do
  GetInfo
  avconv -i $f -ab ${bitrate}k "${f%.m4a}.mp3"
done

Conversion took 5.510 sec. Most of the tags (title, artist, album, not year, not comment) from m4a transferred to mp3.

3. Convert with pacpl (Perl Audio Converter, sudo apt-get install pacpl):

for f in *.m4a; do
  GetInfo
  pacpl --bitrate $bitrate --to mp3 $f
done

Conversion took 12.235 sec. All audio tags from m4a transferred to mp3.

Convert m4a to mp3 using a variable bitrate

Realized that my AAC files were actually using 192 kbps VBR, so then I switched to VBR for the destination mp3.

1. Convert with faad + lame (VBR):

for f in *.m4a; do
  faad -q -o - "$f" | 
  lame --vbr-new -V 2 - "${f%.m4a}.mp3"
done

Conversion took 5.794 sec.

2. Convert with avconv (VBR):

for f in *.m4a; do
  avconv -i $f -aq 2 "${f%.m4a}.mp3"
done

Conversion took 5.481 sec.

3. Convert with pacpl (VBR):

Turned out that pacpl doesn't support VBR directly, but allows passing parameters to LAME, which it uses create the mp3 (as I understand, anyway).

From the pacpl manual:

       --eopts options
 
       this option allows you to use encoder options not implemented by pacpl.

From the LAME manual:

       VBR (variable bitrate) options:
 
       -v     use variable bitrate (--vbr-new)
 
       --vbr-old
              Invokes the oldest, most tested VBR algorithm.  It  produces  very  good  quality  files,
              though is not very fast.  This has, up through v3.89, been considered the "workhorse" VBR
              algorithm.
 
       --vbr-new
              Invokes the newest VBR algorithm.  During the development of version  3.90,  considerable
              tuning  was done on this algorithm, and it is now considered to be on par with the origiā€
              nal --vbr-old.  It has the added advantage of being very fast  (over  twice  as  fast  as
              --vbr-old).
 
       -V n   0 <= n <= 9
              Enable  VBR (Variable BitRate) and specifies the value of VBR quality (default = 4).  0 =
              highest quality.

Using the above, I arrived at the following:

for f in *.m4a; do
  pacpl --eopts="--vbr-new -V 2" --to mp3 $f
done

Conversion took 7.551 sec.

And the winner is..

At this point, I transferred all the test mp3 files over to the Sansa and found that files created with avconv crashed the player. Interesting. Files converted with faad + lame and pacpl played fine.

Because pacpl also moved all the audio metadata over, it was the clear winner for my needs and the following syntax is what I ended up using:

pacpl --eopts="--vbr-new -V 2" --to mp3 *m4a

The above will convert all m4a files in current directory to mp3. I chose to delete source m4a files after conversion myself, but pacpl would happily do that with the "--delete" option.

4 Comments

  • 1. Paul BROWN replies at 15th January 2013, 12:57 am :

    pacpl –eopts=”–vbr-new -V 2″ –to mp3 *m4a

    Thanks – I found this really helpful, except that for whatever reason (haven’t bothered to figure this out), my system (Ubuntu 10.04 install) is using twolame, and twolame doesn’t support the –vbr-new flag, so I was getting an “encode failed with exit status: 256″ error message. Adding a –verbose flag to the pacpl call helped figure that out. THANKS!

  • 2. William Carter replies at 7th July 2013, 1:53 am :

    Thanks. This is a fantastic article.

    Did you ever find out why mp3s converted with avconv crashed the player? I’m getting the same problem with pacpl.

  • 3. Alain Kelder replies at 7th July 2013, 8:34 am :

    @William

    No, but I switched to RockBox, which fixed that problem, as well as giving me a better device overall. See http://giantdorks.org/alain/sandisk-sansa-clip-stock-firmware-update-and-rockbox-install/

  • 4. John Utz replies at 8th May 2014, 12:59 pm :

    Hi;

    Nice piece of work!

    I do notice an assumption in your script that is easily fixed with a pair of doublequotes

    Your script presupposes a lack of spaces in the filenames.

    so filenames like “01 Waiting for an Alibi” fail with ‘no such file or directory’ because bash cant help but split “01″ and “Waiting for an Alibi”

    suggest changing $f to “$f”, that will consume the whole filename, spaces and all.

    tnx!

    johnu

Leave a comment

NOTE: Enclose quotes in <blockquote></blockquote>. Enclose code in <pre lang="LANG"></pre> (where LANG is one of these).