Skip to content

Instantly share code, notes, and snippets.

@liger1978
Created August 17, 2022 14:19
Show Gist options
  • Save liger1978/cc9bcd813586c92573d068ae9a88608e to your computer and use it in GitHub Desktop.
Save liger1978/cc9bcd813586c92573d068ae9a88608e to your computer and use it in GitHub Desktop.
#!/bin/bash
# Converts monolithic Audible AAX files to MP3 chapter files.
# Requires ffmpeg, ffprobe, jq, id3v2 and eyeD3
# AAX input file
in="$1"
# MP3 output directory
out="$2"
# Get activation bytes from https://audible-converter.ml/ or https://github.com/inAudible-NG/tables
activation_bytes="$3"
author="$4"
title="$5"
year="$6"
# File containing cover art
cover_file="$7"
# File containing track names (one per line - optional argument)
chapter_file="$8"
json_file=$(mktemp --suffix=.json)
text_file=$(mktemp --suffix=.txt)
# Covert from aax to m4b
ffmpeg -y -activation_bytes "${activation_bytes}" -i "${in}" -codec copy "${in}.m4b" 2> /dev/null
# Get chapters from m4b
ffprobe -i "${in}.m4b" -print_format json -show_chapters 1> "${json_file}" 2> /dev/null
# Create track text file and count tracks
jq -r '.chapters[] | (.tags.title | sub(" "; "_")) + " " + .start_time + " " + .end_time' "${json_file}" > "${text_file}"
total_tracks=$(wc -l < "${text_file}")
track_pad_length=${#total_tracks}
# Make output dir
mkdir -p "${out}"
# Split monolithic m4b file into chapter track files
line=1
splits=""
while read modified_chapter_title start_time end_time; do
track=$(printf "%0${track_pad_length}d" "${line}")
splits="${splits} -c copy -ss ${start_time} -to ${end_time} ${out}/${track}.m4b"
((line++))
done < "${text_file}"
ffmpeg -y -i "${in}.m4b" $splits 2> /dev/null
# Re-encode m4b files as mp3 files and add id3v2 metadata
line=1
while read modified_chapter_title start_time end_time; do
track=$(printf "%0${track_pad_length}d" "${line}")
if [ -z "$chapter_file" ]; then
chapter_title=${modified_chapter_title/_/ }
else
chapter_title=$(sed "${line}"'q;d' "${chapter_file}")
fi
m4b_in="${out}/${track}.m4b"
mp3_out="${out}/${author} - ${title} - ${track} - ${chapter_title}.mp3"
ffmpeg -nostdin -y -i "${m4b_in}" -codec:a libmp3lame "${mp3_out}" 2> /dev/null
id3v2 -2 -a "${author}" --TPE2 "${author}" -A "${title}" -T "${track}/${total_tracks}" -t "${chapter_title}" -y "${year}" "${mp3_out}"
eyeD3 --add-image "${cover_file}":FRONT_COVER "${mp3_out}" 1> /dev/null 2> /dev/null
rm -f "${m4b_in}"
((line++))
done < "${text_file}"
rm -f "${json_file}"
rm -f "${text_file}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment