Compare commits

..

No commits in common. "master" and "v1.3" have entirely different histories.
master ... v1.3

2 changed files with 34 additions and 167 deletions

170
AAXtoMP3
View file

@ -9,14 +9,14 @@ usage=$'\nUsage: AAXtoMP3 [--flac] [--aac] [--opus ] [--single] [--level <COMPRE
[--chaptered] [-e:mp3] [-e:m4a] [-e:m4b] [--authcode <AUTHCODE>] [--no-clobber]
[--target_dir <PATH>] [--complete_dir <PATH>] [--validate] [--loglevel <LOGLEVEL>]
[--keep-author <N>] [--author <AUTHOR>] [--{dir,file,chapter}-naming-scheme <STRING>]
[--use-audible-cli-data] [--audible-cli-library-file <LIBRARY_PATH>] [--continue <CHAPTERNUMBER>] {FILES}\n'
[--use-audible-cli-data] [--continue <CHAPTERNUMBER>] {FILES}\n'
codec=libmp3lame # Default encoder.
extension=mp3 # Default encoder extension.
level=-1 # Compression level. Can be given for mp3, flac and opus. -1 = default/not specified.
mode=chaptered # Multi file output
auth_code= # Required to be set via file or option.
targetdir= # Optional output location. Note default is basedir of AAX file.
dirNameScheme= # Custom directory naming scheme, default is $genre/$artist/$title
dirNameScheme= # Custom directory naming scheme, default is $genre/$author/$title
customDNS=0
fileNameScheme= # Custom file naming scheme, default is $title
customFNS=0
@ -34,10 +34,6 @@ authorOverride= # Override the author, ignoring the metadata
audibleCli=0 # Default off, Use additional data gathered from mkb79/audible-cli
aaxc_key= # Initialize variables, in case we need them in debug_vars
aaxc_iv= # Initialize variables, in case we need them in debug_vars
ffmpegPath= # Set a custom path, useful for using the updated version that supports aaxc
ffmpegName=ffmpeg # Set a custom ffmpeg binary name, useful tailoring to local setup
ffprobeName=ffprobe # Set a custom ffprobe binary name, useful tailoring to local setup
library_file= # Libraryfile generated by mkb79/audible-cli
# -----
# Code tip Do not have any script above this point that calls a function or a binary. If you do
@ -48,6 +44,8 @@ while true; do
case "$1" in
# Flac encoding
-f | --flac ) codec=flac; extension=flac; mode=single; container=flac; shift ;;
# Apple m4a music format.
-a | --aac ) codec=copy; extension=m4a; mode=single; container=m4a; shift ;;
# Ogg Format
-o | --opus ) codec=libopus; extension=opus; container=ogg; shift ;;
# If appropriate use only a single file output.
@ -57,7 +55,7 @@ while true; do
# This is the same as --single option.
-e:mp3 ) codec=libmp3lame; extension=mp3; mode=single; container=mp3; shift ;;
# Identical to --acc option.
-e:m4a | -a | --aac ) codec=copy; extension=m4a; mode=single; container=mp4; shift ;;
-e:m4a ) codec=copy; extension=m4a; mode=single; container=mp4; shift ;;
# Similar to --aac but specific to audio books
-e:m4b ) codec=copy; extension=m4b; mode=single; container=mp4; shift ;;
# Change the working dir from AAX directory to what you choose.
@ -84,20 +82,12 @@ while true; do
--continue ) continueAt="$2"; continue=1; shift 2 ;;
# Use additional data got with mkb79/audible-cli
--use-audible-cli-data ) audibleCli=1; shift ;;
# Path of the library-file, generated by mkb79/audible-cli (audible library export -o ./library.tsv)
-L | --audible-cli-library-file ) library_file="$2"; shift 2 ;;
# Compression level
--level ) level="$2"; shift 2 ;;
# Keep author number n
--keep-author ) keepArtist="$2"; shift 2 ;;
# Author override
--author ) authorOverride="$2"; shift 2 ;;
# Ffmpeg path override
--ffmpeg-path ) ffmpegPath="$2"; shift 2 ;;
# Ffmpeg name override
--ffmpeg-name ) ffmpegName="$2"; shift 2 ;;
# Ffprobe name override
--ffprobe-name ) ffprobeName="$2"; shift 2 ;;
# Command synopsis.
-h | --help ) printf "$usage" $0 ; exit ;;
# Standard flag signifying the end of command line processing.
@ -222,16 +212,6 @@ else
SED="gsed"
fi
# Use custom ffmpeg (and ffprobe) binary ( --ffmpeg-path flag)
if [ -n "$ffmpegPath" ]; then
FFMPEG="$ffmpegPath/${ffmpegName}"
FFPROBE="$ffmpegPath/${ffprobeName}"
else
FFMPEG="${ffmpegName}"
FFPROBE="${ffprobeName}"
fi
debug_vars "ffmpeg/ffprobe paths" FFMPEG FFPROBE
# -----
# Detect which annoying version of grep we have
@ -262,7 +242,7 @@ fi
# -----
# Detect ffmpeg and ffprobe
if [[ "x$(type -P "$FFMPEG")" == "x" ]]; then
if [[ "x$(type -P ffmpeg)" == "x" ]]; then
echo "ERROR ffmpeg was not found on your env PATH variable"
echo "Without it, this script will break."
echo "INSTALL:"
@ -275,7 +255,7 @@ fi
# -----
# Detect ffmpeg and ffprobe
if [[ "x$(type -P "$FFPROBE")" == "x" ]]; then
if [[ "x$(type -P ffprobe)" == "x" ]]; then
echo "ERROR ffprobe was not found on your env PATH variable"
echo "Without it, this script will break."
echo "INSTALL:"
@ -422,7 +402,7 @@ validate_aax() {
set +e errexit
# Take a look at the aax file and see if it is valid. If the source file is aaxc, we give ffprobe additional flags
output="$("$FFPROBE" -loglevel warning ${decrypt_param} -i "${media_file}" 2>&1)"
output="$(ffprobe -loglevel warning ${decrypt_param} -i "${media_file}" 2>&1)"
# If invalid then say something.
if [[ $? != "0" ]] ; then
@ -435,7 +415,7 @@ validate_aax() {
# This is a big test only performed when the --validate switch is passed.
if [[ "${VALIDATE}" == "1" ]]; then
output="$("$FFMPEG" -hide_banner ${decrypt_param} -i "${media_file}" -vn -f null - 2>&1)"
output="$(ffmpeg -hide_banner ${decrypt_param} -i "${media_file}" -vn -f null - 2>&1)"
if [[ $? != "0" ]] ; then
log "ERROR: Invalid File: ${media_file}"
else
@ -497,15 +477,6 @@ validate_extra_files() {
return 1
fi
# Test for library file
if [[ ! -r "${library_file}" ]] ; then
library_file_exists=0
debug "library file not found"
else
library_file_exists=1
debug "library file found"
fi
debug "All expected audible-cli related file are here"
}
@ -514,7 +485,7 @@ validate_extra_files() {
save_metadata() {
local media_file
media_file="$1"
"$FFPROBE" -i "$media_file" 2> "$metadata_file"
ffprobe -i "$media_file" 2> "$metadata_file"
if [[ $(type -P mediainfo) ]]; then
echo "Mediainfo data START" >> "$metadata_file"
# Mediainfo output is structured like ffprobe, so we append it to the metadata file and then parse it with get_metadata_value()
@ -536,42 +507,9 @@ save_metadata() {
# we use some characters (#) as placeholder, add some new lines,
# put a ',' after the start value, we calculate the end of each chapter
# as start+length, and we convert (divide) the time stamps from ms to s.
# Then we delete all ':' and '/' since they make a filename invalid.
# Then we delete all ':' since they make a filename invalid.
jq -r '.content_metadata.chapter_info.chapters[] | "Chapter # start: \(.start_offset_ms/1000), end: \((.start_offset_ms+.length_ms)/1000) \n#\n# Title: \(.title)"' "${extra_chapter_file}" \
| $SED 's@[:/]@@g' >> "$metadata_file"
# In case we want to use a single file m4b we need to extract the
# chapter titles from the .json generated by audiblecli and store
# them correctly formatted for mp4chaps in a chapter.txt
if [ "${mode}" == "single" ]; then
# Creating a temp file to store the chapter data collected in save_metadata, as the output
# folder will only be defined after save_metadata has been executed.
# This file is only required when using audible-cli data and executing in single mode to
# get proper chapter titles in single file m4b output.
tmp_chapter_file="${working_directory}/chapter.txt"
jq -r \
'def pad(n): tostring | if (n > length) then ((n - length) * "0") + . else . end;
.content_metadata.chapter_info.chapters |
reduce .[] as $c ([]; if $c.chapters? then .+[$c | del(.chapters)]+[$c.chapters] else .+[$c] end) | flatten |
to_entries |
.[] |
"CHAPTER\((.key))=\((((((.value.start_offset_ms / (1000*60*60)) /24 | floor) *24 ) + ((.value.start_offset_ms / (1000*60*60)) %24 | floor)) | pad(2))):\(((.value.start_offset_ms / (1000*60)) %60 | floor | pad(2))):\(((.value.start_offset_ms / 1000) %60 | floor | pad(2))).\((.value.start_offset_ms % 1000 | pad(3)))
CHAPTER\((.key))NAME=\(.value.title)"' "${extra_chapter_file}" > "${tmp_chapter_file}"
fi
# get extra meta data from library.tsv
if [[ "${library_file_exists}" == 1 ]]; then
asin=$(jq -r '.content_metadata.content_reference.asin' "${extra_chapter_file}")
if [[ ! -z "${asin}" ]]; then
lib_entry=$($GREP "^${asin}" "${library_file}")
if [[ ! -z "${lib_entry}" ]]; then
series_title=$(echo "${lib_entry}" | awk -F '\t' '{print $6}')
series_sequence=$(echo "${lib_entry}" | awk -F '\t' '{print $7}')
$SED -i "/^ Metadata:/a\\
series : ${series_title}\\
series_sequence : ${series_sequence}" "${metadata_file}"
fi
fi
fi
| tr -d ':' >> "$metadata_file"
fi
debug "Metadata file $metadata_file"
debug_file "$metadata_file"
@ -679,8 +617,6 @@ do
album="$(get_metadata_value album)"
album_date="$(get_metadata_value date)"
copyright="$(get_metadata_value copyright)"
series="$(get_metadata_value series)"
series_sequence="$(get_metadata_value series_sequence)"
# Get more tags with mediainfo
if [[ $(type -P mediainfo) ]]; then
@ -703,9 +639,9 @@ do
# If we defined a target directory, use it. Otherwise use the location of the AAX file
if [ "x${targetdir}" != "x" ] ; then
output_directory="${targetdir}/${currentDirNameScheme}"
output_directory="${targetdir}/${currentDirNameScheme}/"
else
output_directory="$(dirname "${aax_file}")/${currentDirNameScheme}"
output_directory="$(dirname "${aax_file}")/${currentDirNameScheme}/"
fi
# Define the output_file
@ -718,9 +654,8 @@ do
output_file="${output_directory}/${currentFileNameScheme}.${extension}"
if [[ "${noclobber}" = "1" ]] && [[ -d "${output_directory}" ]]; then
log "Noclobber enabled but directory '${output_directory}' exists. Skipping to avoid overwriting"
rm -f "${metadata_file}" "${tmp_chapter_file}"
continue
log "Noclobber enabled but directory '${output_directory}' exists. Exiting to avoid overwriting"
exit 0
fi
mkdir -p "${output_directory}"
@ -739,7 +674,7 @@ do
# Display the total length of the audiobook in format hh:mm:ss
# 10#$var force base-10 interpretation. By default it's base-8, so values like 08 or 09 are not octal numbers
total_length="$("$FFPROBE" -v error ${decrypt_param} -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${aax_file}" | cut -d . -f 1)"
total_length="$(ffprobe -v error ${decrypt_param} -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${aax_file}" | cut -d . -f 1)"
hours="$((total_length/3600))"
if [ "$((hours<10))" = "1" ]; then hours="0$hours"; fi
minutes="$((total_length/60-60*10#$hours))"
@ -758,8 +693,8 @@ do
if [ "${continue}" == "0" ]; then
# This is the main work horse command. This is the primary transcoder.
# This is the primary transcode. All the heavy lifting is here.
debug '"$FFMPEG" -loglevel error -stats ${decrypt_param} -i "${aax_file}" -vn -codec:a "${codec}" -ab ${bitrate} -map_metadata -1 -metadata title="${title}" -metadata artist="${artist}" -metadata album_artist="${album_artist}" -metadata album="${album}" -metadata date="${album_date}" -metadata track="1/1" -metadata genre="${genre}" -metadata copyright="${copyright}" "${output_file}"'
</dev/null "$FFMPEG" -loglevel error \
debug 'ffmpeg -loglevel error -stats ${decrypt_param} -i "${aax_file}" -vn -codec:a "${codec}" -ab ${bitrate} -map_metadata -1 -metadata title="${title}" -metadata artist="${artist}" -metadata album_artist="${album_artist}" -metadata album="${album}" -metadata date="${album_date}" -metadata track="1/1" -metadata genre="${genre}" -metadata copyright="${copyright}" "${output_file}"'
</dev/null ffmpeg -loglevel error \
-stats \
${decrypt_param} \
-i "${aax_file}" \
@ -779,8 +714,6 @@ do
-metadata description="${description}" \
-metadata composer="${narrator}" \
-metadata publisher="${publisher}" \
-metadata series="${series}" \
-metadata series_sequence="${series_sequence}" \
-f ${container} \
"${output_file}"
if [ "$((${loglevel} > 0))" == "1" ]; then
@ -789,7 +722,8 @@ do
# -----
fi
# Grab the cover art if available.
cover_file="${output_directory}/${currentFileNameScheme}.jpg"
cover_file="${output_directory}/cover.jpg"
extra_crop_cover=''
if [ "${continue}" == "0" ]; then
if [ "${audibleCli}" == "1" ]; then
# We have a better quality cover file, copy it.
@ -797,27 +731,21 @@ do
log "Copy cover file to ${cover_file}..."
fi
cp "${extra_cover_file}" "${cover_file}"
# We now set a variable, ${extra_crop_cover}, which contains an additional
# ffmpeg flag. It crops the cover so the width and the height is divisible by two.
# Since the standard (in the aax file) image resolution is 512, we set the flag
# only if we use a custom cover art.
extra_crop_cover='-vf crop=trunc(iw/2)*2:trunc(ih/2)*2'
else
# Audible-cli not used, extract the cover from the aax file
if [ "$((${loglevel} > 1))" == "1" ]; then
log "Extracting cover into ${cover_file}..."
fi
</dev/null "$FFMPEG" -loglevel error -activation_bytes "${auth_code}" -i "${aax_file}" -an -codec:v copy "${cover_file}"
</dev/null ffmpeg -loglevel error -activation_bytes "${auth_code}" -i "${aax_file}" -an -codec:v copy "${cover_file}"
fi
fi
extra_crop_cover=''
cover_width=$(ffprobe -i "${cover_file}" 2>&1 | $GREP -Po "[0-9]+(?=x[0-9]+)" | tail -n 1)
if (( ${cover_width} % 2 == 1 )); then
if [ "$((${loglevel} > 1))" == "1" ]; then
log "Cover ${cover_file} has odd width ${cover_width}, setting extra_crop_cover to make even."
fi
# We now set a variable, ${extra_crop_cover}, which contains an additional
# ffmpeg flag. It crops the cover so the width and the height is divisible by two.
# Set the flag only if we use a cover art with an odd width.
extra_crop_cover='-vf crop=trunc(iw/2)*2:trunc(ih/2)*2'
fi
# -----
# If mode=chaptered, split the big converted file by chapter and remove it afterwards.
# Not all audio encodings make sense with multiple chapter outputs (see options section)
@ -895,7 +823,7 @@ do
#ffmpeg version 4+ and on the output for all older versions.
split_input=""
split_output=""
if [ "$(($("$FFMPEG" -version | $SED -E 's/[^0-9]*([0-9]).*/\1/g;1q') > 3))" = "1" ]; then
if [ "$(($(ffmpeg -version | $SED -E 's/[^0-9]*([0-9]).*/\1/g;1q') > 3))" = "1" ]; then
split_input="-ss ${chapter_start%?} -to ${chapter_end}"
else
split_output="-ss ${chapter_start%?} -to ${chapter_end}"
@ -909,7 +837,7 @@ do
if [ "$((${loglevel} > 1))" == "1" ]; then
log "Splitting chapter ${chapternum}/${chaptercount} start:${chapter_start%?}(s) end:${chapter_end}(s)"
fi
</dev/null "$FFMPEG" -loglevel quiet \
</dev/null ffmpeg -loglevel quiet \
-nostats \
${split_input} \
-i "${output_file}" \
@ -920,7 +848,7 @@ do
-map 1:0 \
-acodec ${chapter_codec} \
-metadata:s:v title="Album cover" \
-metadata:s:v comment="Cover (front)" \
-metadata:s:v comment="Cover (Front)" \
-metadata track="${chapternum}" \
-metadata title="${chapter}" \
-metadata:s:a title="${chapter}" \
@ -954,46 +882,12 @@ do
# Perform file tasks on output file.
# ----
# ffmpeg seems to copy only chapter position, not chapter names.
# use already created chapter.txt from save_metadata() in case
# audible-cli data is used else use ffprobe to extract from m4b
if [[ ${container} == "mp4" && $(type -P mp4chaps) ]]; then
if [ "${audibleCli}" == "1" ]; then
mv "${tmp_chapter_file}" "${output_directory}/${currentFileNameScheme}.chapters.txt"
else
"$FFPROBE" -i "${aax_file}" -print_format csv -show_chapters 2>/dev/null | awk -F "," '{printf "CHAPTER%d=%02d:%02d:%02.3f\nCHAPTER%dNAME=%s\n", NR, $5/60/60, $5/60%60, $5%60, NR, $8}' > "${output_directory}/${currentFileNameScheme}.chapters.txt"
fi
$SED -i 's/\,000/\.000/' "${output_directory}/${currentFileNameScheme}.chapters.txt"
ffprobe -i "${aax_file}" -print_format csv -show_chapters 2>/dev/null | awk -F "," '{printf "CHAPTER%02d=%02d:%02d:%02.3f\nCHAPTER%02dNAME=%s\n", NR, $5/60/60, $5/60%60, $5%60, NR, $8}' > "${output_directory}/${currentFileNameScheme}.chapters.txt"
mp4chaps -i "${output_file}"
fi
fi
if [ -f "${cover_file}" ]; then
log "Adding cover art"
# FFMPEG does not support MPEG-4 containers fully #
if [ "${container}" == "mp4" ] ; then
mp4art --add "${cover_file}" "${output_file}"
# FFMPEG for everything else #
else
# Create temporary output file name - ensure extention matches previous appropriate output file to keep ffmpeg happy
cover_output_file="${output_file%.*}.cover.${output_file##*.}"
# Copy audio stream from current output, and video stream from cover file, setting appropriate metadata
</dev/null "$FFMPEG" -loglevel quiet \
-nostats \
-i "${output_file}" \
-i "${cover_file}" \
-map 0:a:0 \
-map 1:v:0 \
-acodec copy \
-vcodec copy \
-id3v2_version 3 \
-metadata:s:v title="Album cover" \
-metadata:s:v comment="Cover (front)" \
"${cover_output_file}"
# Replace original output file with version including cover
mv "${cover_output_file}" "${output_file}"
fi
fi
# -----
# Announce that we have completed the transcode
if [ "$((${loglevel} > 0))" == "1" ]; then

View file

@ -25,7 +25,7 @@ Audible fails for some reason.
## Usage(s)
```
bash AAXtoMP3 [-f|--flac] [-o|--opus] [-a|--aac] [-s|--single] [--level <COMPRESSIONLEVEL>] [-c|--chaptered] [-e:mp3] [-e:m4a] [-e:m4b] [-A|--authcode <AUTHCODE>] [-n|--no-clobber] [-t|--target_dir <PATH>] [-C|--complete_dir <PATH>] [-V|--validate] [--use-audible-cli-data]] [-d|--debug] [-h|--help] [--continue <CHAPTERNUMBER>] <AAX/AAXC INPUT_FILES>...
bash AAXtoMP3 [-f|--flac] [-o|--opus] [-a|-aac] [-s|--single] [--level <COMPRESSIONLEVEL>] [-c|--chaptered] [-e:mp3] [-e:m4a] [-e:m4b] [-A|--authcode <AUTHCODE>] [-n|--no-clobber] [-t|--target_dir <PATH>] [-C|--complete_dir <PATH>] [-V|--validate] [--use-audible-cli-data]] [-d|--debug] [-h|--help] [--continue <CHAPTERNUMBER>] <AAX/AAXC INPUT_FILES>...
```
or if you want to get guided through the options
```
@ -57,10 +57,6 @@ bash interactiveAAXtoMP3 [-a|--advanced] [-h|--help]
* **--file-naming-scheme &lt;STRING&gt;** or **-F** Use a custom file naming scheme, with variables. See [below](#custom-naming-scheme) for more info.
* **--chapter-naming-scheme &lt;STRING&gt;** Use a custom chapter naming scheme, with variables. See [below](#custom-naming-scheme) for more info.
* **--use-audible-cli-data** Use additional data got with mkb79/audible-cli. See [below](#audible-cli-integration) for more info. Needed for the files in the `aaxc` format.
* **--audible-cli-library-file** or **-L** Path of the library-file, generated by mkb79/audible-cli (`audible library export -o ./library.tsv`). Only available if `--use-audible-cli-data` is set. This file is required to parse additional metadata such as `$series` or `$series_sequence`.
* **--ffmpeg-path** Set the ffmpeg/ffprobe binaries folder. Both of them must be executable and in the same folder.
* **--ffmpeg-name** Set a custom name for the ffmpeg binary. Must be executable and in path, or in custom path specified by --ffmpeg-path.
* **--ffprobe-name** Set a custom name for the ffprobe binary. Must be executable and in path, or in custom path specified by --ffmpeg-path.
## Options for interactiveAAXtoMP3
* **-a** or **--advanced** Get more options to choose. Not used right now.
@ -154,10 +150,6 @@ So you can use `--dir-naming-scheme '$(date +%Y)/$artist'`, but using `--file-na
* If you want shorter chapter names, use `--chapter-naming-scheme '$(printf %0${#chaptercount}d $chapternum) $chapter'`: only chapter number and chapter name
* If you want to append the narrator name to the title, use `--dir-naming-scheme '$genre/$artist/$title-$narrator' --file-naming-scheme '$title-$narrator'`
* If you don't want to have the books separated by author, use `--dir-naming-scheme '$genre/$title'`
* To be able to use `$series` or `$series_sequence` in the schemes the following is required:
* `--use-audible-cli-data` is set
* you have pre-generated the library-file via `audible library export -o ./library.tsv`
* you have set the path to the generated library-file via `--audible-cli-library-file ./library.tsv`
### Installing Dependencies.
In general, take a look at [command-not-found.com](https://command-not-found.com/)
@ -168,20 +160,6 @@ sudo apt-get update
sudo apt-get install ffmpeg libav-tools x264 x265 bc
```
In Debian-based system's repositories the ffmpeg version is often outdated. If you want
to convert .aaxc files, you need at least ffmpeg 4.4. So if your installed version
needs to be updated, you can either install a custom repository that has the newer version,
compile ffmpeg from source or download pre-compiled binaries.
You can then tell AAXtoMP3 to use the compiled binaries with the `--ffmpeg-path` flag.
You need to specify the folder where the ffmpeg and ffprobe binaries are. Make sure
they are both executable.
If you have snapd installed, you can also install a recent version of 4.4 from the edge channel:
```
snap install ffmpeg --edge
```
In this case you will need to confiure a custom path _and_ binary name for ffprobe, `--ffmpeg-path /snap/bin/ --ffprobe-name ffmpeg.ffprobe`.
__Fedora__
Fedora users need to enable the rpm fusion repository to install ffmpeg. Version 22 and upwards are currently supported. The following command works independent of your current version:
@ -220,17 +198,13 @@ brew install findutils
```
#### mp4art/mp4chaps
_Note: This is an optional dependency, required for adding cover art to m4a and b4b files only._
_Note: This is an optional dependency._
__Ubuntu, Linux Mint, Debian__
```
sudo apt-get update
sudo apt-get install mp4v2-utils
```
On Debian and Ubuntu the mp4v2-utils package has been deprecated and removed, as the upsteam project is no longer maintained.
The package was removed in Debian Buster, and Ubuntu Focal [ 20.04 ].
__CentOS, RHEL & Fedora__
```
# CentOS/RHEL and Fedora users make sure that you have enabled atrpms repository in system. Lets begin installing FFmpeg as per your operating system.
@ -265,7 +239,6 @@ Since getting those keys is not simple, for now the method used to get them
is handled by the package audible-cli, that stores
them in a file when downloading the aaxc file. This means that in order to
decrypt the aaxc files, they must be downloaded with audible-cli.
Note that you need at least [ffmpeg 4.4](#ffmpegffprobe).
## Audible-cli integration
Some information are not present in the AAX file. For example the chapters's