A small percentage of Audible AAX files – usually radio dramatizations / plays – are encoded at a sample rate of 44.1kHz. These files do not seem to play natively on Android, but are accepted by tools and players on Linux, e.g. mplayer, ffmpeg, etc. Trying to use them with Booksonic causes playback to fail if transcoding is not enabled for m4a / m4b files. Similarly, playing through Plex results in a forced server-side transcode. A bug was filed against Booksonic partly about this:

https://github.com/popeen/Popeens-DSub/issues/67

After much investigation, it seems the only difference between files that play and those that don’t, apart from the sample rate, bit rate, etc., is a single bit set in the “Audio Object Type Specific Config” in the ESDS atom in an M4A file. This bit is described as “dependsOnCoreCoder” in most sources:

https://wiki.multimedia.cx/index.php/Understanding_AAC
https://wiki.multimedia.cx/index.php/MPEG-4_Audio
https://stackoverflow.com/questions/3987850/mp4-atom-how-to-discriminate-the-audio-codec-is-it-aac-or-mp3

Trying to extract the AAC audio to an ADTS file with ffmpeg yields the error “Scalable configurations are not allowed in ADTS”, which would suggest this bit is something to do with Scalable Sampling Rate AAC.

https://github.com/FFmpeg/FFmpeg/blob/f0c0ad4455e5f72edf175e81a06e52562cdd1ab2/libavformat/adtsenc.c#L77

Various code fragments found online suggest that this bit should be followed by several bits of extra data, but this does not appear to be the case in the problematic AAC files – it is possible they are therefore considered malformed:

https://android.googlesource.com/platform/frameworks/av/+/jb-release/media/libstagefright/codecs/aacdec/get_ga_specific_config.cpp#341
https://github.com/MediaArea/MediaInfoLib/blob/5cf78d3af8a2847589f22ac7d7acb6735ec9c200/Source/MediaInfo/Audio/File_Aac_GeneralAudio.cpp#L77
https://github.com/FFmpeg/FFmpeg/blob/fd3ee7a92e9227ee44e2a0d837ba9879959b15d7/libavcodec/aacdec_template.c#L831

It turns out that flipping the bit in question is enough to fix these AAC files and make them playable. This can be done with the tools provided at https://www.bento4.com/ . For example:

f="$1"
t=`mktemp`
mp4extract moov/trak/mdia/minf/stbl/stsd/mp4a/esds \
    "$f" /dev/stdout | xxd -p | tr -d '\n' >$t
magic=$(sed -re 's/^.*0580808002(....).*$/\1/' $t)
if [ "$magic" != "1212" ]; then
    echo "no need to fix"
    rm "$t"
    exit 0
fi
t2=`mktemp`
new=$(sed -re 's/05808080021212/05808080021210/' $t | xxd -r -p >$t2)
rm $t
old="${f}.pre-fix"
mv -v "$f" "$old"
mp4edit --replace \
    moov/trak/mdia/minf/stbl/stsd/mp4a/esds:"$t2" \
    "$old" \
    "$f"
Edit
Pub: Feb 15 2020 15:20 UTC
Edit: Feb 15 2020 15:32 UTC
Views: 213