From 11e021b43d8617c4af1b1feaa9cb0f3509213e4c Mon Sep 17 00:00:00 2001 From: fruchti Date: Sun, 15 Jan 2023 19:41:19 +0100 Subject: [PATCH] Use command line arguments, die function --- transcode.sh | 158 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 98 insertions(+), 60 deletions(-) diff --git a/transcode.sh b/transcode.sh index 7358f78..2c6e13c 100755 --- a/transcode.sh +++ b/transcode.sh @@ -1,54 +1,61 @@ #!/usr/bin/env bash -input_directory=/data/music - -input_directory=/data/music/flac +set -eu tmp_directory=/tmp/transcode lock_file=/tmp/music-transcode.lock +function die() +{ + printf '%s\n' "$1" >&2 + exit "${2-1}" +} + function transcode_to_mp3() { - input_file="$1" - output_directory="$2" - output_file="$(echo "$input_file" | sed -E "s#^$input_directory(.+)\\.[a-z0-9]+\\$#$output_directory\\1.mp3#g")" + input_directory="$1" + input_file_name="$2" + mp3_directory="$3" + input_path="$input_directory/$input_file_name" + output_file_name="$(echo "$input_file_name" | sed -E 's/(\.[^. ]+)?$/.mp3/g')" + output_path="$mp3_directory/$output_file_name" - directory="$(dirname "$output_file")" - if [ ! -d "$directory" ] ; then - echo "New Directory: \"$directory\"" - mkdir -p "$directory" || { echo "Could not create directory \"$directory\"." ; return 1 ; } + output_directory="$(dirname "$output_path")" + if [ ! -d "$output_directory" ] ; then + echo "New Directory: \"$output_directory\"" + mkdir -p "$output_directory" || die "Could not create directory \"$output_directory\"." fi transcode=false - if [ ! -f "$output_file" ] ; then - echo "New MP3: \"$output_file\"" + if [ ! -f "$output_path" ] ; then + echo "New MP3: \"$output_path\"" transcode=true - elif [ "$input_file" -nt "$output_file" ] ; then - echo "Input file is newer: \"$output_file\"" + elif [ "$input_path" -nt "$output_path" ] ; then + echo "Input file is newer: \"$output_path\"" transcode=true fi if [ "$transcode" = true ] ; then - input_type="$(file -b --mime-type "$input_file")" + input_type="$(file -b --mime-type "$input_path")" case "$input_type" in "audio/flac"|"audio/x-flac") - tmp_file="$tmp_directory/$(basename "$output_file")" + tmp_path="$tmp_directory/$(basename "$output_path")" echo "Transcoding MP3..." - ffmpeg -hide_banner -loglevel fatal -i "$input_file" -y -b:a 320k -qscale:a 2 -id3v2_version 3 -f mp3 "$tmp_file" || { echo "Failed to transcode to \"$tmp_file\"." ; return 1 ; } - mv -f "$tmp_file" "$output_file" || { echo "Could not move file to \"$output_file\"." ; return 1 ; } + ffmpeg -hide_banner -loglevel fatal -i "$input_path" -y -b:a 320k -qscale:a 2 -id3v2_version 3 -f mp3 "$tmp_path" < /dev/null || die "Failed to transcode to \"$tmp_path\"." + mv -f "$tmp_path" "$output_path" || die "Could not move file to \"$output_path\"." ;; application/octet-stream) - echo "Warning: Assuming \"$input_file\" is a MP3 file." + echo "Warning: Assuming \"$input_path\" is a MP3 file." ;& audio/mpeg) echo "Copying MP3..." - cp -f "$input_file" "$output_file" + cp -f "$input_path" "$output_path" ;; *) - echo "Unsupported input type $input_type (\"$input_file\")" + echo "Unsupported input type $input_type (\"$input_path\")" return 1 ;; esac @@ -70,15 +77,15 @@ function ogg_add_cover() sed -i -e '/^metadata_block_picture/d' "$tmp_metafile" && \ echo -n "" > "$tmp_mdimg" && \ printf "0: %.8x" 3 | xxd -r -g0 >> "$tmp_mdimg" && \ - printf "0: %.8x" $(echo -n "$cover_mime_type" | wc -c) | xxd -r -g0 >> "$tmp_mdimg" && \ + printf "0: %.8x" "$(echo -n "$cover_mime_type" | wc -c)" | xxd -r -g0 >> "$tmp_mdimg" && \ echo -n "$cover_mime_type" >> "$tmp_mdimg" && \ - printf "0: %.8x" $(echo -n "$description" | wc -c) | xxd -r -g0 >> "$tmp_mdimg" && \ + printf "0: %.8x" "$(echo -n "$description" | wc -c)" | xxd -r -g0 >> "$tmp_mdimg" && \ echo -n "$description" >> "$tmp_mdimg" && \ printf "0: %.8x" 0 | xxd -r -g0 >> "$tmp_mdimg" && \ printf "0: %.8x" 0 | xxd -r -g0 >> "$tmp_mdimg" && \ printf "0: %.8x" 0 | xxd -r -g0 >> "$tmp_mdimg" && \ printf "0: %.8x" 0 | xxd -r -g0 >> "$tmp_mdimg" && \ - printf "0: %.8x" $(wc -c "$cover_file" | cut --delimiter=' ' --fields=1) | xxd -r -g0 >> "$tmp_mdimg" && \ + printf "0: %.8x" "$(wc -c "$cover_file" | cut --delimiter=' ' --fields=1)" | xxd -r -g0 >> "$tmp_mdimg" && \ cat "$tmp_cover" >> "$tmp_mdimg" && \ echo "metadata_block_picture=$(base64 --wrap=0 < "$tmp_mdimg")" >> "$tmp_metafile" && \ vorbiscomment --write --raw --commentfile "$tmp_metafile" "$ogg_file" && \ @@ -87,75 +94,72 @@ function ogg_add_cover() function transcode_to_ogg() { - input_file="$1" - output_directory="$2" - output_file="$(echo "$input_file" | sed -E "s#^$input_directory(.+)\\.[a-z0-9]+\\$#$output_directory\\1.ogg#g")" + input_directory="$1" + input_file_name="$2" + ogg_directory="$3" + input_path="$input_directory/$input_file_name" + output_file_name="$(echo "$input_file_name" | sed -E 's/(\.[^. ]+)?$/.ogg/g')" + output_path="$ogg_directory/$output_file_name" - directory="$(dirname "$output_file")" + directory="$(dirname "$output_path")" if [ ! -d "$directory" ] ; then echo "New Directory: \"$directory\"" - mkdir -p "$directory" || { echo "Could not create directory \"$directory\"." ; return 1 ; } + mkdir -p "$directory" || die "Could not create directory \"$directory\"." fi transcode=false - if [ ! -f "$output_file" ] ; then - echo "New OGG: \"$output_file\"" + if [ ! -f "$output_path" ] ; then + echo "New OGG: \"$output_path\"" transcode=true - elif [ "$input_file" -nt "$output_file" ] ; then - echo "Input file is newer: \"$output_file\"" + elif [ "$input_path" -nt "$output_path" ] ; then + echo "Input file is newer: \"$output_path\"" transcode=true fi if [ "$transcode" = true ] ; then - input_type="$(file -b --mime-type "$input_file")" + input_type="$(file -b --mime-type "$input_path")" - tmp_ogg="$tmp_directory/$(basename "$output_file")" + tmp_ogg="$tmp_directory/$(basename "$output_path")" tmp_cover="$tmp_directory/cover" case "$input_type" in "audio/flac"|"audio/x-flac") echo "Transcoding OGG..." - ffmpeg -hide_banner -loglevel fatal -i "$input_file" -y -map a -qscale:a 6 -id3v2_version 3 -f ogg "$tmp_ogg" || { echo "Could not transcode to \"$tmp_ogg\"." ; return 1 ; } + ffmpeg -hide_banner -loglevel fatal -i "$input_path" -y -map a -qscale:a 6 -id3v2_version 3 -f ogg "$tmp_ogg" < /dev/null || die "Could not transcode to \"$tmp_ogg\"." echo "Adding OGG cover image..." - metaflac --export-picture-to="$tmp_cover" "$input_file" && \ - ogg_add_cover "$tmp_ogg" "$tmp_cover" || { echo "Could not add cover image to \"$tmp_ogg\"." ; return 1 ; } + metaflac --export-picture-to="$tmp_cover" "$input_path" || die "Could not export cover image." + ogg_add_cover "$tmp_ogg" "$tmp_cover" || die "Could not add cover image to \"$tmp_ogg\"." - mv -f "$tmp_ogg" "$output_file" || { echo "Could not move file to \"$output_file\"." ; return 1 ; } + mv -f "$tmp_ogg" "$output_path" || die "Could not move file to \"$output_path\"." ;; application/octet-stream) - echo "Warning: Assuming \"$input_file\" is a MP3 file." + echo "Warning: Assuming \"$input_path\" is a MP3 file." ;& audio/mpeg) echo "Transcoding OGG..." - ffmpeg -hide_banner -loglevel fatal -i "$input_file" -y -map a -qscale:a 6 -id3v2_version 3 -f ogg "$tmp_ogg" || die "Could not transcode to \"$tmp_ogg\"." + ffmpeg -hide_banner -loglevel fatal -i "$input_path" -y -map a -qscale:a 6 -id3v2_version 3 -f ogg "$tmp_ogg" || die "Could not transcode to \"$tmp_ogg\"." echo "Adding OGG cover image..." - exiftool -Picture -b "$input_file" > "$tmp_cover" && \ - ogg_add_cover "$tmp_ogg" "$tmp_cover" || { echo "Could not add cover image to \"$tmp_ogg\"." ; return 1 ; } + exiftool -Picture -b "$input_path" > "$tmp_cover" || die "Could not export cover image." + ogg_add_cover "$tmp_ogg" "$tmp_cover" || die "Could not add cover image to \"$tmp_ogg\"." - mv -f "$tmp_ogg" "$output_file" || { echo "Could not move file to \"$output_file\"." ; return 1 ; } + mv -f "$tmp_ogg" "$output_path" || die "Could not move file to \"$output_path\"." ;; *) - echo "Unsupported input type $input_type (\"$input_file\")" + echo "Unsupported input type $input_type (\"$input_path\")" return 1 ;; esac fi } -function die() -{ - printf '%s\n' "$1" >&2 - exit "${2-1}" -} - if [ -f "$lock_file" ] ; then echo "Another instance is already running. Exiting." - echo "If you are certain this is the only instance, you can delete the lock file $lockfile" + echo "If you are certain this is the only instance, you can delete the lock file $lock_file" exit 2 else touch "$lock_file" || die "Could not create lock file." @@ -167,18 +171,52 @@ function cleanup() rm -rf "$tmp_directory" } -trap cleanup EXIT SIGTERM SIGKILL +trap cleanup EXIT SIGTERM if [ ! -d "$tmp_directory" ] ; then mkdir -p "$tmp_directory" || die "Could not create temporary directory \"$tmp_directory\"." fi -SAVEIFS=$IFS -IFS=$(echo -ne "\n\b") -for file in $(find "$input_directory" -name '*.flac' -or -name '*.mp3' | sort); do - transcode_to_mp3 "$file" "/data/music/mp3" || break - transcode_to_ogg "$file" "/data/music/ogg" || break +mp3_out='' +ogg_out='' + +while [ $# -gt 1 ] ; do + case "$1" in + '--mp3-out') + mp3_out="$2" + shift 2 + ;; + '--ogg-out') + ogg_out="$2" + shift 2 + ;; + '--') + shift + break + ;; + *) + >&2 echo "Unknown argument: $1" + exit 1 + ;; + esac done -echo "Done Transcoding." -IFS=$SAVEIFS +if [ $# -lt 1 ] ; then + >&2 echo "Missing input directory argument" + exit 1 +fi + +input_directory="$1" + +while IFS= read -r -d '' file; do + if [ "$mp3_out" != '' ] ; then + transcode_to_mp3 "$input_directory" "$file" "$mp3_out" || break + fi + if [ "$ogg_out" != '' ] ; then + transcode_to_ogg "$input_directory" "$file" "$ogg_out" || break + fi +done < <( + find -P "$input_directory" \( -iname '*.flac' -or -iname '*.mp3' \) -printf '%P\0' | sort -z +) + +echo "Done transcoding."