diff --git a/AAXtoMP3 b/AAXtoMP3 index a77242a..70d5b84 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:" @@ -381,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. @@ -409,7 +415,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 +428,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 +498,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() @@ -521,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 | @@ -693,7 +704,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 +723,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 +867,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 diff --git a/README.md b/README.md index ba288b3..a7d8903 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](#ffmpegffprobe). ## Audible-cli integration Some information are not present in the AAX file. For example the chapters's