#!/usr/bin/env bash set -o errexit -o noclobber -o nounset -o pipefail codec=libmp3lame extension=mp3 mode=chaptered authcode=".authcode"; auth=""; if [ -z ${HOME+x} ] && ! [ -z ${USERPROFILE+x} ]; then HOME="$USERPROFILE"; fi authcodeDirs="${HOME}/ ./" GREP=$(grep --version | grep -q GNU && echo "grep" || echo "ggrep") if ! [[ $(type -P "$GREP") ]]; then echo "$GREP (GNU grep) is not in your PATH" echo "Without it, this script will break." echo "On macOS, you may want to try: brew install grep" exit 1 fi if ! [[ $(type -P ffmpeg) ]]; then echo "ffmpeg is not in your PATH" echo "Without it, this script will break." exit 1 fi function print_manual(){ echo "" echo "Usage: bash AAXtoMP3 [--flac] [--aac] [--opus ] [--single] --auth=AUTHCODE {FILES}" echo " Note that when you enter conflicting parameters, the last one will be the one used." echo " You HAVE to use the equals-sign. You may also use -a=AUTHCODE. But the '=' is mandatory." echo " Everything after the authcode must be a filename to a file which you want to convert" echo "" echo " [--flac]: The flac codec is used in the resulting files. Default is MP3" echo " [--aac]: The aac codec is used in the resulting files. Default is MP3" echo " [--opus]: The opus codec is used in the resulting files. Default is MP3" echo " [--single] : Prevents creation of chapters. Results in a single file." echo " --authcode=XXXXXXXX: Your personal autcode. Everything after this parameter will be used as an inputfile!" echo " {FILES}: Files to convert, seperated by spaces." echo "" } if [ "$#" -eq 0 ]; then print_manual exit 1 fi if [[ "$1" = '-h' ]]; then print_manual exit 1 fi if [[ "$1" = '--help' ]]; then print_manual exit 1 fi ParamArray=() #the multithreadcontroller adds whitespaces to the params, they are removed here. for var in "$@" do if ! [[ "$var" = '' ]] then ParamArray+=("$var") fi done #Iterate over the parameter to find all entered ones for var in "${ParamArray[@]}" do if [[ "$var" = '--flac' ]] then codec=flac extension=flac shift fi if [[ "$var" == '--aac' ]] then codec=copy extension=m4a mode=single shift fi if [[ "$var" = '--opus' ]] then codec=libopus extension=ogg shift fi if [[ "$var" == '--single' ]] then mode=single shift fi case "$var" in -a=*|--auth=*) auth=$(echo $var | cut -d '=' -f 2) shift esac done auth_code=""; for dir in $authcodeDirs; do codeFile="${dir}$authcode"; if [ ! -f "$codeFile" -o ! -s "$codeFile" ]; then codeFile="" echo "INFO: Sorry, missing or empty \"$codeFile\" found, skipping."; fi; done; if [ -f "$codeFile" ]; then auth_code=`head -1 "$codeFile"` fi if [ -z "$auth_code" ]; then auth_code="$auth"; fi; if [ -z "$auth_code" ]; then echo "INFO: Sorry, no authcode provided."; exit 1; fi; debug() { echo "$(date "+%F %T%z") ${1}" } trap 'rm -r -f "${working_directory}"' EXIT working_directory=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'` metadata_file="${working_directory}/metadata.txt" save_metadata() { local media_file media_file="$1" ffprobe -i "$media_file" 2> "$metadata_file" } get_metadata_value() { local key key="$1" normalize_whitespace "$($GREP --max-count=1 --only-matching "${key} *: .*" "$metadata_file" | cut -d : -f 2- | sed -e 's#/##g;s/ (Unabridged)//' | tr -s '[:blank:]' ' ')" } get_bitrate() { get_metadata_value bitrate | $GREP --only-matching '[0-9]\+' } normalize_whitespace() { echo $* } alreadys_skipped_to_auth=0 for path in "${ParamArray[@]}" do if (( $alreadys_skipped_to_auth == 0 )) then case "$path" in -a=*|--auth=*) alreadys_skipped_to_auth=1; continue ; esac continue ; fi if (( $alreadys_skipped_to_auth == 1 )) then debug "Decoding ${path} with auth code ${auth_code}..." save_metadata "${path}" genre=$(get_metadata_value genre) artist=$(get_metadata_value artist) title=$(get_metadata_value title | sed 's/'\:'/'\ -'/g' | xargs -0) output_directory="$(dirname "${path}")/${genre}/${artist}/${title}" mkdir -p "${output_directory}" full_file_path="${output_directory}/${title}.${extension}"