Monday, February 14, 2011

m4b audiobook to cd's with Ubuntu: Valentine's Day Edition

My wife came to me asking about putting her large .m4b audiobook files on cd's to listen to while she is on the road for work.  These are biiiiig files with some over 10 hours each.  They were not DRM'ed, but they did have still jpeg images as a video stream.

Bad Solution:
Files this big require using compressed output since WAV files will exceed aloud maximum size.  This prevented me from using the mplayer -ao pcm trick successfully to write a file.  I ended up with WAV files that only captured half or less of each book.

Good Solution:
I settled on ffmpeg to write mp3 files.  After getting the mp3's, it would be easy if she had an mp3 cd player in her car, but she doesn't.  Therefore I will also describe how to split the mp3's at cd-length intervals at the end.

1.) First get the tools.  Only the first two are needed if you don't want to split your mp3's at the end.

sudo apt-get install ffmpeg libavcodec-extra-52 mp3splt

Also, if you have spaces in your file names and a bunch of m4b files you will want to process iteratively, you may want to replace the spaces with underscores.  Otherwise, common shell for looping methods will treat each word like a filename.  This can be done easily with rename.

rename 's/\ /_/g' *.m4b 

This says to replace all spaces in all file names ending in '.m4b' with underscores.

2.) Create an mp3 file from your m4b file.

ffmpeg -i yourfile.m4b -acodec libmp3lame -ar 22050 -ab 320k yourfile.mp3

The codec libmp3lame is included in that libavcodec package I told you to get.  The sample rate of 22050 sounds fine for most audio books, but you can adjust this if needed.  Lastly, set the bitrate for encoding your mp3.  Even though I specified 320k, the software only did it at 160k owing to a codec implementation limitation I suppose.

I had a bunch of m4b files to convert, so I used the following one liner to do all of them.  It will replace the extension with .mp3.

for m4b in *.m4b; do ffmpeg -i $m4b -acodec libmp3lame -ar 22050 -ab 320k ${m4b%.m4b}.mp3; done

3.) Now you have one or many big mp3's.  If that is all you need, then have fun.  For me, the 10 hour mp3's are a problem.  Now you'll need to split the large mp3's.  Luckily this is trivial on Linux with mp3splt.

mp3splt -t 80.0 yourfile.mp3

My cd's are 80 minutes, so the command above says split my file into as many 80 minute and 0 second files as needed. The split files will be named with start and end time data in this case, but the mp3splt tool has options to customize how the file names are numbered and named if you want more control.

In my case, I used this on a bunch of mp3 files so I did the following.

for m in *.mp3; do mp3splt -t 80.0 -d ${m%.mp3} $m; done

This command creates a separate directory (-d flag) which has the name with the original mp3 sans ".mp3" and places all the split files inside it (handy to prevent creating a jumble of files).

Have fun, and happy valentine's day.