
Create m4b from mp3 audiobooks for ipod
I just wanted to listen to an audiobook this morning, the problem is that I wanted to listen to it on ipod, but I could not find it anywhere in m4b format, only mp3.
After a long googling, a post was found with ideas on how to do this, but without a normal implementation. I managed to share my ideas and decisions with the author of this post, but he, after some time, rubbed them for some reason.
The bottom line is that .m4b is an AAC file in the mp4 container, but with bookmarks and renamed. Therefore, it is necessary to overtake all mp3s in aac and generate a chapters file in quicktime format, and then put the whole thing into an mp4 container.
Under linux, there is only 1 normal AAC encoder - NeroAacEncoder . The code is closed, but it is free and works.
There is an alternative to ffmpeg, but it is very raw.
There is also alac encoder \ decoder, also in ffmpeg, but it does not control the bitrate at all - a 10 meter mp3 turns into a 100 MB monster.
Initially, it was planned to cram into the container using MP4Box, which is included in the gpac package . And use libmp4v2 for tagging and processing the chapters file (you just have to use trunk-r355 snapshot, there are a lot of bug fixes, and the stable version still doesn't work correctly).
And then it turned out that MP4Box has a restriction on stuffing into one container - 20 files (why and why it is not clear). Yes, and the chapters-file, with this approach, you need to generate yourself. The result was this script.140 lines and a few problems.
A little later, a much more optimal solution was found - to transfer mp3 to wav, and then to transfer them all together in bulk through NeroAacEnc, which knows how to generate chapters and has no restrictions on the number of incoming files. Tags can be arranged by NeroAacTag (they come bundled) on one line, and there is an opinion that this will be more correct and accurate. True, this does not eliminate the use of mp4chaps (from libmp4v2) for converting nero bookmarks to quicktime bookmarks.
UPD: This is pretty obvious, but still - the files must have the correct names \ numbering so that `ls -1` displays them in the correct order. Not 1..12, but 01..12, for example.
Or, as xn__p2a rightly pointed out , use “ls -1v” (for output 1..12).
Of course, now the screw is not aac, but huge wav, which will need to be killed later, and through fifo (as it was in the first script) is somehow more elegant, but everything has become much simpler.
UPD: there is an opinion that using mplayer to get wav from mp3 is overkill.
Some alternatives:
In the newly m4b file, the names of the chapters will be of the type 'Chapter 01', but this can be easily fixed by editing the bookmark file:
How and how to edit - of your choice.
gtkpod-1.0.0 and libgpod-0.8.0 have learned to support 5th generation ipod nano, so I use them.
UPD: after a long correspondence with xn__p2a , the third version of the script appeared:
This option is recognized as more elegant, because only 0B fifo needs to be cleaned: `find -maxdepth 1 -type p -exec rm {} +`
PS: It’s a pity that it is impossible to wrap the mplayer’s exhaust into neroAacEnc input, so that he would take them for separate files (otherwise there would be no auto-marking) .
PPS: DO NOT install systemwide libmp4v2 trunk 335 - it will fly off 1 \ 2 things depending on this lib, and gtkpod will forget how to understand m4a \ m4b files.
PPPS: You can wrap individual aac in separate mp4 and rename it in m4a if you want to loseless music on ipod.
After a long googling, a post was found with ideas on how to do this, but without a normal implementation. I managed to share my ideas and decisions with the author of this post, but he, after some time, rubbed them for some reason.
The bottom line is that .m4b is an AAC file in the mp4 container, but with bookmarks and renamed. Therefore, it is necessary to overtake all mp3s in aac and generate a chapters file in quicktime format, and then put the whole thing into an mp4 container.
Under linux, there is only 1 normal AAC encoder - NeroAacEncoder . The code is closed, but it is free and works.
There is an alternative to ffmpeg, but it is very raw.
There is also alac encoder \ decoder, also in ffmpeg, but it does not control the bitrate at all - a 10 meter mp3 turns into a 100 MB monster.
Initially, it was planned to cram into the container using MP4Box, which is included in the gpac package . And use libmp4v2 for tagging and processing the chapters file (you just have to use trunk-r355 snapshot, there are a lot of bug fixes, and the stable version still doesn't work correctly).
And then it turned out that MP4Box has a restriction on stuffing into one container - 20 files (why and why it is not clear). Yes, and the chapters-file, with this approach, you need to generate yourself. The result was this script.140 lines and a few problems.
A little later, a much more optimal solution was found - to transfer mp3 to wav, and then to transfer them all together in bulk through NeroAacEnc, which knows how to generate chapters and has no restrictions on the number of incoming files. Tags can be arranged by NeroAacTag (they come bundled) on one line, and there is an opinion that this will be more correct and accurate. True, this does not eliminate the use of mp4chaps (from libmp4v2) for converting nero bookmarks to quicktime bookmarks.
UPD: This is pretty obvious, but still - the files must have the correct names \ numbering so that `ls -1` displays them in the correct order. Not 1..12, but 01..12, for example.
Or, as xn__p2a rightly pointed out , use “ls -1v” (for output 1..12).
# FIELD SEPARATOR
IFS=$'\n'
# ALL MP3 TO WAV
for i in `ls -1 *.mp3`; do mplayer -nocorrect-pts -vo null -vc null -ao pcm:fast:file="${i%%mp3}wav" "$i"; done
# CONCATE ALL WAV TO MP4 WITH AUTOMATIC CREATION OF CHAPTER MARKS
for i in `ls -1 *.wav`; do printf %s "-if \"$i\" ";done | xargs ../neroAacEnc -of OUT.mp4
# SET CORRECT TAGS
../neroAacTag -meta:title="MY_TITLE" -meta:artist="MY_AUTHOR" -add-cover:front:BOOK_COVER.jpg OUT.mp4
# CONVERT CHAPTERS FOR IPOD
mp4chaps -convert --chapter-qt OUT.mp4
Of course, now the screw is not aac, but huge wav, which will need to be killed later, and through fifo (as it was in the first script) is somehow more elegant, but everything has become much simpler.
UPD: there is an opinion that using mplayer to get wav from mp3 is overkill.
Some alternatives:
ffmpeg -i input.mp3 output.wav
mpg123 -w output.wav input.mp3
lame -decode input.mp3 output.wav
In the newly m4b file, the names of the chapters will be of the type 'Chapter 01', but this can be easily fixed by editing the bookmark file:
# EXPORT CHAPTERS TO MP4FILE.CHAPTERS.TXT
mp4chaps -x test.mp4
# NOW YOU CAN MODIFY THEM AND IMPORT BACK
mp4chaps -i test.mp4
How and how to edit - of your choice.
gtkpod-1.0.0 and libgpod-0.8.0 have learned to support 5th generation ipod nano, so I use them.
UPD: after a long correspondence with xn__p2a , the third version of the script appeared:
#!/bin/bash
# INPUT FIELD SEPARATOR
IFS=$'\n'
# JUST MORE CONVINIENT
function mpfifo {
mplayer -nocorrect-pts -vo null -vc null -ao pcm:fast:file="${1%%mp3}wav" "$1" &>"/dev/null" &
}
# NEED MORE FIFO!!111
for i in `ls -1v *.mp3`; do mkfifo "${i%%mp3}wav"; done
# RUN NEROAACENC
for i in `ls -1v *.mp3`; do printf %s " -if \""${i%%mp3}wav"\"";done | xargs ../../neroAacEnc -of test.mp4 &
# RUN ALL MP3
for i in `ls -1v *.mp3`; do mpfifo "$i"; done
# CONVERT CHAPTERS
mp4chaps -convert --chapter-qt test.mp4
This option is recognized as more elegant, because only 0B fifo needs to be cleaned: `find -maxdepth 1 -type p -exec rm {} +`
PPS: DO NOT install systemwide libmp4v2 trunk 335 - it will fly off 1 \ 2 things depending on this lib, and gtkpod will forget how to understand m4a \ m4b files.
PPPS: You can wrap individual aac in separate mp4 and rename it in m4a if you want to loseless music on ipod.