From 56ca165063517ac9f25301235ff9378f865a4bda Mon Sep 17 00:00:00 2001 From: Stefan Weiberg <2744377+suntorytimed@users.noreply.github.com> Date: Thu, 16 Sep 2021 07:10:49 +0200 Subject: [PATCH 01/34] Fix #172 by adding parsing step to save_metadata * creates a correctly formatted chapter.txt file with titles from audible-cli .json * uses this chapter.txt instead of ffprobe output in case audible-cli data should be used --- AAXtoMP3 | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index adc91ef..150db65 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -381,6 +381,13 @@ trap 'rm -r -f "${working_directory}"' EXIT # Set up some basic working files ASAP. Note the trap will clean this up no matter what. working_directory=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'` metadata_file="${working_directory}/metadata.txt" +# 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. +if [[ "${audibleCli}" == "1" && "${mode}" == "single" ]] ; then + tmp_chapter_file="${working_directory}/chapter.txt" +fi # ----- # Validate the AAX and extract the metadata associated with the file. @@ -510,6 +517,18 @@ save_metadata() { # 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}" \ | tr -d ':' >> "$metadata_file" + # In case we want to use a single file m4b we need to extract the + # chapter titles from the .json generated by audible–cli and store + # them correctly formatted for mp4chaps in a chapter.txt + if [ "${mode}" == "single" ]; then + jq -r \ + 'def pad(n): tostring | if (n > length) then ((n - length) * "0") + . else . end; + .content_metadata.chapter_info.chapters | + to_entries | + .[] | + "CHAPTER\((.key | pad(2)))=\(((.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 | pad(2)))NAME=\(.value.title)"' "${extra_chapter_file}" > "${tmp_chapter_file}" + fi fi debug "Metadata file $metadata_file" debug_file "$metadata_file" @@ -882,8 +901,14 @@ 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 - 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" + 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%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" + fi mp4chaps -i "${output_file}" fi fi From aab2045959466ee70c47ee9cae07d0f8dc210092 Mon Sep 17 00:00:00 2001 From: Stefan Weiberg <2744377+suntorytimed@users.noreply.github.com> Date: Thu, 16 Sep 2021 11:46:43 +0200 Subject: [PATCH 02/34] Remove padding for chapter number Co-authored-by: fabh2o --- AAXtoMP3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 150db65..690a796 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -526,7 +526,7 @@ save_metadata() { .content_metadata.chapter_info.chapters | to_entries | .[] | - "CHAPTER\((.key | pad(2)))=\(((.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))=\(((.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 | pad(2)))NAME=\(.value.title)"' "${extra_chapter_file}" > "${tmp_chapter_file}" fi fi From e76b5442c13a776e54ec1c5473a01c7446fb6593 Mon Sep 17 00:00:00 2001 From: Stefan Weiberg <2744377+suntorytimed@users.noreply.github.com> Date: Thu, 16 Sep 2021 11:47:20 +0200 Subject: [PATCH 03/34] Apply suggestions from code review Remove padding for chapter number Co-authored-by: fabh2o --- AAXtoMP3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 690a796..a77242a 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -527,7 +527,7 @@ save_metadata() { to_entries | .[] | "CHAPTER\((.key))=\(((.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 | pad(2)))NAME=\(.value.title)"' "${extra_chapter_file}" > "${tmp_chapter_file}" +CHAPTER\((.key))NAME=\(.value.title)"' "${extra_chapter_file}" > "${tmp_chapter_file}" fi fi debug "Metadata file $metadata_file" @@ -907,7 +907,7 @@ do 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%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" + 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 mp4chaps -i "${output_file}" fi From fb86d4291cdf2e2b31531d501fac3718975b0d5b Mon Sep 17 00:00:00 2001 From: fabh2o Date: Mon, 20 Sep 2021 23:05:15 +0200 Subject: [PATCH 04/34] instruction to update ffmpeg --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 48be47c..ba288b3 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,11 @@ 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. + __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: From 58ecfbc72b4dc1df753ec1233e4f006e2fb418a5 Mon Sep 17 00:00:00 2001 From: fabh2o Date: Sun, 26 Sep 2021 18:28:59 +0200 Subject: [PATCH 05/34] remove useless / in output_folder definition --- AAXtoMP3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index a77242a..be49717 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -658,9 +658,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 From 68a91bbbbbaf3df3b78c9637f7f003e25f3bd458 Mon Sep 17 00:00:00 2001 From: fabh2o Date: Sun, 26 Sep 2021 18:30:44 +0200 Subject: [PATCH 06/34] --aac is identical to -e:m4a --- AAXtoMP3 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index be49717..1713aea 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -44,8 +44,6 @@ 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. @@ -55,7 +53,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 ) codec=copy; extension=m4a; mode=single; container=mp4; shift ;; + -e:m4a | -a | --aac ) 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. From f1c4b97bc10129dc44ae845f2ddc4b82adddad64 Mon Sep 17 00:00:00 2001 From: fabh2o Date: Tue, 28 Sep 2021 19:55:16 +0200 Subject: [PATCH 07/34] use custom path for ffmpeg/ffprobe binaries --- AAXtoMP3 | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index a77242a..67a5088 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -34,6 +34,7 @@ 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 # ----- # Code tip Do not have any script above this point that calls a function or a binary. If you do @@ -88,6 +89,8 @@ while true; do --keep-author ) keepArtist="$2"; shift 2 ;; # Author override --author ) authorOverride="$2"; shift 2 ;; + # Ffmpeg path override + --ffmpeg-path ) ffmpegPath="$2"; shift 2 ;; # Command synopsis. -h | --help ) printf "$usage" $0 ; exit ;; # Standard flag signifying the end of command line processing. @@ -212,6 +215,16 @@ else SED="gsed" fi +# Use custom ffmpeg (and ffprobe) binary ( --ffmpeg-path flag) +if [ -n "$ffmpegPath" ]; then + FFMPEG="$ffmpegPath/ffmpeg" + FFPROBE="$ffmpegPath/ffprobe" +else + FFMPEG="ffmpeg" + FFPROBE="ffprobe" +fi + +debug_vars "ffmpeg/ffprobe paths" FFMPEG FFPROBE # ----- # Detect which annoying version of grep we have @@ -242,7 +255,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:" @@ -255,7 +268,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:" @@ -409,7 +422,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 @@ -422,7 +435,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 @@ -492,7 +505,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() @@ -693,7 +706,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))" @@ -712,8 +725,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}"' - 1))" == "1" ]; then log "Extracting cover into ${cover_file}..." fi - 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}" @@ -856,7 +869,7 @@ do if [ "$((${loglevel} > 1))" == "1" ]; then log "Splitting chapter ${chapternum}/${chaptercount} start:${chapter_start%?}(s) end:${chapter_end}(s)" fi - /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" + "$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 mp4chaps -i "${output_file}" fi From bf1f38434135feb427a66ba8f5697b27c28f4a92 Mon Sep 17 00:00:00 2001 From: fabh2o Date: Tue, 28 Sep 2021 19:56:14 +0200 Subject: [PATCH 08/34] fix tmp_chapter_file: unbound variable --- AAXtoMP3 | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 67a5088..70d5b84 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -394,13 +394,6 @@ trap 'rm -r -f "${working_directory}"' EXIT # Set up some basic working files ASAP. Note the trap will clean this up no matter what. working_directory=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'` metadata_file="${working_directory}/metadata.txt" -# 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. -if [[ "${audibleCli}" == "1" && "${mode}" == "single" ]] ; then - tmp_chapter_file="${working_directory}/chapter.txt" -fi # ----- # Validate the AAX and extract the metadata associated with the file. @@ -534,6 +527,11 @@ save_metadata() { # chapter titles from the .json generated by audible–cli 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 | From d645e616fe65e5d2505b019f0987dc28b38c827e Mon Sep 17 00:00:00 2001 From: fabh2o Date: Tue, 28 Sep 2021 20:16:52 +0200 Subject: [PATCH 09/34] updated readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index ba288b3..66a72d5 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ bash interactiveAAXtoMP3 [-a|--advanced] [-h|--help] * **--file-naming-scheme <STRING>** or **-F** Use a custom file naming scheme, with variables. See [below](#custom-naming-scheme) for more info. * **--chapter-naming-scheme <STRING>** 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. +* **--ffmpeg-path** Set the ffmpeg/ffprobe binaries folder. Both of them must be executable and in the same folder. ## Options for interactiveAAXtoMP3 * **-a** or **--advanced** Get more options to choose. Not used right now. @@ -164,6 +165,9 @@ In Debian-based system's repositories the ffmpeg version is often outdated. If y 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. __Fedora__ @@ -244,6 +248,7 @@ 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](#FFMPEG,FFPROBE). ## Audible-cli integration Some information are not present in the AAX file. For example the chapters's From ce62e832ee4f131e8d628823b92985d312e9f858 Mon Sep 17 00:00:00 2001 From: fabh2o Date: Tue, 28 Sep 2021 22:06:33 +0200 Subject: [PATCH 10/34] fix anchor link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 66a72d5..a7d8903 100644 --- a/README.md +++ b/README.md @@ -248,7 +248,7 @@ 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](#FFMPEG,FFPROBE). +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 From a45c6245fec2af62f99f1663c620956c829944d6 Mon Sep 17 00:00:00 2001 From: fabh2o Date: Mon, 8 Nov 2021 10:50:52 +0100 Subject: [PATCH 11/34] delete '/' and ':' from chapter names --- AAXtoMP3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index f567698..d5a80a1 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -518,9 +518,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 ':' since they make a filename invalid. + # Then we delete all ':' and '/' 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}" \ - | tr -d ':' >> "$metadata_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 audible–cli and store # them correctly formatted for mp4chaps in a chapter.txt From ab91343dd56dbca8ce26fb49e66b3fd470692bc8 Mon Sep 17 00:00:00 2001 From: Nate Bohman Date: Tue, 9 Nov 2021 11:36:23 -0700 Subject: [PATCH 12/34] Add extra_crop_cover to All Odd Cover Widths When attempting to convert https://www.audible.com/pd/Stephen-Fry-Presents-a-Selection-of-Anton-Chekhovs-Short-Stories-Audiobook/B0036GPPWS using this tool and chaptered mode, ffmpeg fails out with [libx264 @ 0x5588ef28d780] width not divisible by 2 (483x500) Error initializing output stream 0:1 -- Error while opening encoder for output stream #0:1 - maybe incorrect parameters such as bit_rate, rate, width or height Conversion failed! This is because the cover file embedded in the downloaded mp4 file from Audible has the dimensions 483x500. Found the extra_crop_cover that's currently being used only for covers from the Audible CLI tool and extended the script to instead check the dimensions of the cover file and include the extra_crop_cover anytime the cover has an odd width. --- AAXtoMP3 | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index d5a80a1..028ccfc 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -751,7 +751,6 @@ do fi # Grab the cover art if available. 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. @@ -759,12 +758,6 @@ 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 @@ -774,6 +767,18 @@ do fi fi + extra_crop_cover='' + cover_width=$(ffprobe -i "${cover_file}" 2>&1 | grep -Po "[0-9]+(?=x[0-9]+)") + 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) From 12435d3e24eab18a00a21d9e917b0b0a26e952b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jerome=20K=C3=BCttner?= <12213711+jkuettner@users.noreply.github.com> Date: Fri, 7 Jan 2022 17:48:04 +0100 Subject: [PATCH 13/34] Continue if target directory already exists --- AAXtoMP3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index d5a80a1..d767858 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -682,8 +682,8 @@ do output_file="${output_directory}/${currentFileNameScheme}.${extension}" if [[ "${noclobber}" = "1" ]] && [[ -d "${output_directory}" ]]; then - log "Noclobber enabled but directory '${output_directory}' exists. Exiting to avoid overwriting" - exit 0 + log "Noclobber enabled but directory '${output_directory}' exists. Skipping to avoid overwriting" + continue fi mkdir -p "${output_directory}" From 45fd0d4852644343f854e453359db234d33533a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jerome=20K=C3=BCttner?= <12213711+jkuettner@users.noreply.github.com> Date: Fri, 7 Jan 2022 20:58:54 +0100 Subject: [PATCH 14/34] remove temp metadata_file on continue --- AAXtoMP3 | 1 + 1 file changed, 1 insertion(+) diff --git a/AAXtoMP3 b/AAXtoMP3 index d767858..9c0b8a8 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -683,6 +683,7 @@ do if [[ "${noclobber}" = "1" ]] && [[ -d "${output_directory}" ]]; then log "Noclobber enabled but directory '${output_directory}' exists. Skipping to avoid overwriting" + rm -f "${metadata_file}" continue fi mkdir -p "${output_directory}" From 7f1f3df0206e057d30a18251ce600c08f4334f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jerome=20K=C3=BCttner?= <12213711+jkuettner@users.noreply.github.com> Date: Sat, 8 Jan 2022 16:38:29 +0100 Subject: [PATCH 15/34] Add possibility to read the series from the audible library --- AAXtoMP3 | 33 ++++++++++++++++++++++++++++++++- README.md | 5 +++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 1fcbc58..5139adb 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -9,7 +9,7 @@ usage=$'\nUsage: AAXtoMP3 [--flac] [--aac] [--opus ] [--single] [--level ] [--no-clobber] [--target_dir ] [--complete_dir ] [--validate] [--loglevel ] [--keep-author ] [--author ] [--{dir,file,chapter}-naming-scheme ] -[--use-audible-cli-data] [--continue ] {FILES}\n' +[--use-audible-cli-data] [--audible-cli-library-file ] [--continue ] {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. @@ -35,6 +35,7 @@ audibleCli=0 # Default off, Use additional data gathered from mkb 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 +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 @@ -81,6 +82,8 @@ 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 @@ -488,6 +491,15 @@ 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" } @@ -538,6 +550,21 @@ save_metadata() { "CHAPTER\((.key))=\(((.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 fi debug "Metadata file $metadata_file" debug_file "$metadata_file" @@ -645,6 +672,8 @@ 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 @@ -743,6 +772,8 @@ 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 diff --git a/README.md b/README.md index a7d8903..c26d84e 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ bash interactiveAAXtoMP3 [-a|--advanced] [-h|--help] * **--file-naming-scheme <STRING>** or **-F** Use a custom file naming scheme, with variables. See [below](#custom-naming-scheme) for more info. * **--chapter-naming-scheme <STRING>** 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. ## Options for interactiveAAXtoMP3 @@ -151,6 +152,10 @@ 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/) From b87b08ee6af8432d5c3658e24d8a2efd813352af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jerome=20K=C3=BCttner?= <12213711+jkuettner@users.noreply.github.com> Date: Sat, 8 Jan 2022 21:13:28 +0100 Subject: [PATCH 16/34] fix continuing for existing files --- AAXtoMP3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 5139adb..3b8cb9f 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -712,7 +712,7 @@ do if [[ "${noclobber}" = "1" ]] && [[ -d "${output_directory}" ]]; then log "Noclobber enabled but directory '${output_directory}' exists. Skipping to avoid overwriting" - rm -f "${metadata_file}" + rm -f "${metadata_file}" "${tmp_chapter_file}" continue fi mkdir -p "${output_directory}" From 5010927559bccb7b4ea5f387b8d49052967970ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jerome=20K=C3=BCttner?= <12213711+jkuettner@users.noreply.github.com> Date: Sat, 8 Jan 2022 21:45:03 +0100 Subject: [PATCH 17/34] fix "syntax error in expression" --- AAXtoMP3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 3b8cb9f..2a88bd1 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -801,7 +801,7 @@ do extra_crop_cover='' cover_width=$(ffprobe -i "${cover_file}" 2>&1 | grep -Po "[0-9]+(?=x[0-9]+)") - if [ "$(( ${cover_width} % 2 ))" == "1" ]; then + 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 From 048e15a476c81479be85671283e7ee77be568ab1 Mon Sep 17 00:00:00 2001 From: Ben Saufley Date: Wed, 12 Jan 2022 00:12:20 -0500 Subject: [PATCH 18/34] Use GREP variable everywhere --- AAXtoMP3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 2a88bd1..bd2c94b 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -555,7 +555,7 @@ CHAPTER\((.key))NAME=\(.value.title)"' "${extra_chapter_file}" > "${tmp_chapter_ 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}") + 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}') @@ -800,7 +800,7 @@ do fi extra_crop_cover='' - cover_width=$(ffprobe -i "${cover_file}" 2>&1 | grep -Po "[0-9]+(?=x[0-9]+)") + cover_width=$(ffprobe -i "${cover_file}" 2>&1 | $GREP -Po "[0-9]+(?=x[0-9]+)") 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." From 20289a17741d6eebe73be8eda73424d1516bb0c0 Mon Sep 17 00:00:00 2001 From: Ben Saufley Date: Wed, 12 Jan 2022 00:28:52 -0500 Subject: [PATCH 19/34] One sed/gsed as well --- AAXtoMP3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index bd2c94b..7e0f55c 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -559,7 +559,7 @@ CHAPTER\((.key))NAME=\(.value.title)"' "${extra_chapter_file}" > "${tmp_chapter_ 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\\ + $SED -i "/^ Metadata:/a\\ series : ${series_title}\\ series_sequence : ${series_sequence}" "${metadata_file}" fi From 4dd095da2a663e7c79f538c4ec22acbb804b5bc7 Mon Sep 17 00:00:00 2001 From: Ben Saufley Date: Wed, 12 Jan 2022 09:34:59 -0500 Subject: [PATCH 20/34] Attempt to fix missing cover art for single output Solves #191 for me anecdotaly, but I don't know if there's a better solution or a different way to go about it. --- AAXtoMP3 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AAXtoMP3 b/AAXtoMP3 index 2a88bd1..eba3821 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -959,6 +959,11 @@ do fi fi + if [ -f "${cover_file}" ]; then + if [ "$loglevel" -gt 1 ]; then log "Adding cover art"; fi + mp4art --add "${cover_file}" "${output_file}" + fi + # ----- # Announce that we have completed the transcode if [ "$((${loglevel} > 0))" == "1" ]; then From e4f92461d3f07c305f460c5bc7369e9a8b5e7964 Mon Sep 17 00:00:00 2001 From: Max Zangs Date: Thu, 20 Jan 2022 11:45:49 +0100 Subject: [PATCH 21/34] Changing uses of `grep` to `$GREP` for non-linux --- AAXtoMP3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 2a88bd1..bd2c94b 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -555,7 +555,7 @@ CHAPTER\((.key))NAME=\(.value.title)"' "${extra_chapter_file}" > "${tmp_chapter_ 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}") + 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}') @@ -800,7 +800,7 @@ do fi extra_crop_cover='' - cover_width=$(ffprobe -i "${cover_file}" 2>&1 | grep -Po "[0-9]+(?=x[0-9]+)") + cover_width=$(ffprobe -i "${cover_file}" 2>&1 | $GREP -Po "[0-9]+(?=x[0-9]+)") 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." From 2272d9ce99787a3b92cc79916c2aa0ccffea0afb Mon Sep 17 00:00:00 2001 From: Max Zangs Date: Thu, 20 Jan 2022 11:59:10 +0100 Subject: [PATCH 22/34] Fixing `,000` issue with mp4chaps Replaces the `,000` in the chapters.txt file with `.000` to allow processing with `mp4chaps` --- AAXtoMP3 | 1 + 1 file changed, 1 insertion(+) diff --git a/AAXtoMP3 b/AAXtoMP3 index 2a88bd1..e943cd1 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -955,6 +955,7 @@ do 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" mp4chaps -i "${output_file}" fi fi From aa702cb97a6f4125d1fee1112bbd3676fc814587 Mon Sep 17 00:00:00 2001 From: Ben Saufley Date: Fri, 21 Jan 2022 17:09:43 -0500 Subject: [PATCH 23/34] Remove redundant loglevel check --- AAXtoMP3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index eba3821..bb55dc0 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -960,7 +960,7 @@ do fi if [ -f "${cover_file}" ]; then - if [ "$loglevel" -gt 1 ]; then log "Adding cover art"; fi + log "Adding cover art" mp4art --add "${cover_file}" "${output_file}" fi From 72794b678545faf37e083ee5975bf986ef9a6a88 Mon Sep 17 00:00:00 2001 From: jcat Date: Sat, 5 Feb 2022 23:30:14 +0000 Subject: [PATCH 24/34] feat: Use ffmpeg to cover add instead of mp4art from deprecated mp4v2-utils package closes: https://github.com/KrumpetPirate/AAXtoMP3/issues/198 --- AAXtoMP3 | 18 +++++++++++++++++- README.md | 19 ------------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 8eff27b..25feb46 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -962,7 +962,23 @@ do if [ -f "${cover_file}" ]; then log "Adding cover art" - mp4art --add "${cover_file}" "${output_file}" + # 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 + Date: Sun, 6 Feb 2022 00:03:57 +0000 Subject: [PATCH 25/34] feat: Add support for ffmpeg via snap package, requires ability to specify custom ffmpeg binary names if required closes: https://github.com/KrumpetPirate/AAXtoMP3/issues/200 --- AAXtoMP3 | 14 ++++++++++---- README.md | 8 ++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 8eff27b..9b7b07b 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -35,6 +35,8 @@ audibleCli=0 # Default off, Use additional data gathered from mkb 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 # ----- @@ -92,6 +94,10 @@ while true; do --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. @@ -218,11 +224,11 @@ fi # Use custom ffmpeg (and ffprobe) binary ( --ffmpeg-path flag) if [ -n "$ffmpegPath" ]; then - FFMPEG="$ffmpegPath/ffmpeg" - FFPROBE="$ffmpegPath/ffprobe" + FFMPEG="$ffmpegPath/${ffmpegName}" + FFPROBE="$ffmpegPath/${ffprobeName}" else - FFMPEG="ffmpeg" - FFPROBE="ffprobe" + FFMPEG="${ffmpegName}" + FFPROBE="${ffprobeName}" fi debug_vars "ffmpeg/ffprobe paths" FFMPEG FFPROBE diff --git a/README.md b/README.md index c26d84e..36e6d5e 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ bash interactiveAAXtoMP3 [-a|--advanced] [-h|--help] * **--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. @@ -174,6 +176,12 @@ You can then tell AAXtoMP3 to use the compiled binaries with the `--ffmpeg-path` 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: From b07737f5c40c6da0ea76a3b2af47e892f608f56d Mon Sep 17 00:00:00 2001 From: jcat Date: Sun, 6 Feb 2022 20:29:20 +0000 Subject: [PATCH 26/34] fix: video stream metadata for front cover comment should be lower case _front_ --- AAXtoMP3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 8eff27b..bbc9927 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -913,7 +913,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}" \ From be8473ffbaa6df5ad7100f68884e75968446c3a0 Mon Sep 17 00:00:00 2001 From: jcat Date: Wed, 9 Feb 2022 21:01:29 +0000 Subject: [PATCH 27/34] Revert "feat: Use ffmpeg to cover add instead of mp4art from deprecated mp4v2-utils package" This reverts commit 72794b678545faf37e083ee5975bf986ef9a6a88. This broke cover art addition for MPEG-4 containers --- AAXtoMP3 | 18 +----------------- README.md | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 9b16c09..c03be5c 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -968,23 +968,7 @@ do if [ -f "${cover_file}" ]; then log "Adding cover art" - # 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 - Date: Wed, 9 Feb 2022 21:24:14 +0000 Subject: [PATCH 28/34] feat: Use ffmpeg for cover art on non mpeg-4 containers instead of mp4art from deprecated mp4v2-utils package Closes: https://github.com/KrumpetPirate/AAXtoMP3/issues/203 --- AAXtoMP3 | 24 +++++++++++++++++++++++- README.md | 6 +++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index c03be5c..2a10ccb 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -968,7 +968,29 @@ do if [ -f "${cover_file}" ]; then log "Adding cover art" - mp4art --add "${cover_file}" "${output_file}" + # FFMGEP 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 + Date: Tue, 1 Mar 2022 21:38:17 -0800 Subject: [PATCH 29/34] Fixes for jq command generating chapters.txt Fixes #184 Adds a reduce + flatten step to generate a flat list of chapters. Fixes #206 Support for emitting timestamps greater than 24 hours. --- AAXtoMP3 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 2a10ccb..670f2e5 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -551,9 +551,10 @@ save_metadata() { 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 | 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))=\((((((.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 From 1ac69798857ccf6e510c40c2537157c0144907ea Mon Sep 17 00:00:00 2001 From: utf8please Date: Sun, 27 Mar 2022 20:04:49 -0700 Subject: [PATCH 30/34] Limit result to one line when parsing cover size. --- AAXtoMP3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 670f2e5..25999be 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -807,7 +807,7 @@ do fi extra_crop_cover='' - cover_width=$(ffprobe -i "${cover_file}" 2>&1 | $GREP -Po "[0-9]+(?=x[0-9]+)") + 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." From c289c10cd73bc57e44ebbdb71d3c6ef2fc2af931 Mon Sep 17 00:00:00 2001 From: Benjamin Porter Date: Fri, 10 Jun 2022 18:03:29 -0600 Subject: [PATCH 31/34] Fix typo in comment: FFMGEP -> FFMPEG --- AAXtoMP3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 670f2e5..90566ad 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -969,7 +969,7 @@ do if [ -f "${cover_file}" ]; then log "Adding cover art" - # FFMGEP does not support MPEG-4 containers fully # + # FFMPEG does not support MPEG-4 containers fully # if [ "${container}" == "mp4" ] ; then mp4art --add "${cover_file}" "${output_file}" # FFMPEG for everything else # From 8fc5e360d34ff17a41fedda0e507f12013a03470 Mon Sep 17 00:00:00 2001 From: JarrodCColburn Date: Thu, 7 Jul 2022 17:49:45 -0500 Subject: [PATCH 32/34] fix: typo '--aac' not '-aac' usage example has 'aac' prefixed with single dash '-' (but should be double dashes '--') --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2df29d0..ee45eda 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Audible fails for some reason. ## Usage(s) ``` -bash AAXtoMP3 [-f|--flac] [-o|--opus] [-a|-aac] [-s|--single] [--level ] [-c|--chaptered] [-e:mp3] [-e:m4a] [-e:m4b] [-A|--authcode ] [-n|--no-clobber] [-t|--target_dir ] [-C|--complete_dir ] [-V|--validate] [--use-audible-cli-data]] [-d|--debug] [-h|--help] [--continue ] ... +bash AAXtoMP3 [-f|--flac] [-o|--opus] [-a|--aac] [-s|--single] [--level ] [-c|--chaptered] [-e:mp3] [-e:m4a] [-e:m4b] [-A|--authcode ] [-n|--no-clobber] [-t|--target_dir ] [-C|--complete_dir ] [-V|--validate] [--use-audible-cli-data]] [-d|--debug] [-h|--help] [--continue ] ... ``` or if you want to get guided through the options ``` From 2a5a208a2d8245528a0d162ed4b945b404ebff7b Mon Sep 17 00:00:00 2001 From: -_- Date: Mon, 17 Oct 2022 16:54:21 +0200 Subject: [PATCH 33/34] Change cover.jpg to $currentFileNameScheme.jpg This change allow multiple covers of different audiobooks in the same target directory. --- AAXtoMP3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 90566ad..5a1796b 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -789,7 +789,7 @@ do # ----- fi # Grab the cover art if available. - cover_file="${output_directory}/cover.jpg" + cover_file="${output_directory}/${currentFileNameScheme}.jpg" if [ "${continue}" == "0" ]; then if [ "${audibleCli}" == "1" ]; then # We have a better quality cover file, copy it. From 1338f1e5c1a168ac150a0794a13eaaba2d3d2e08 Mon Sep 17 00:00:00 2001 From: Benjamin Porter Date: Mon, 2 Jan 2023 15:42:08 -0700 Subject: [PATCH 34/34] Fix incorrect variable name bug Fix misleading variable name. `$author` -> `$artist` This took 30 mins of head pounding to figure out what was wrong :-) --- AAXtoMP3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AAXtoMP3 b/AAXtoMP3 index 90566ad..2a27413 100755 --- a/AAXtoMP3 +++ b/AAXtoMP3 @@ -16,7 +16,7 @@ level=-1 # Compression level. Can be given for mp3, flac and 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/$author/$title +dirNameScheme= # Custom directory naming scheme, default is $genre/$artist/$title customDNS=0 fileNameScheme= # Custom file naming scheme, default is $title customFNS=0