Use command line arguments, die function

This commit is contained in:
fruchti 2023-01-15 19:41:19 +01:00
parent 8ee42e7a1c
commit 11e021b43d

View file

@ -1,54 +1,61 @@
#!/usr/bin/env bash #!/usr/bin/env bash
input_directory=/data/music set -eu
input_directory=/data/music/flac
tmp_directory=/tmp/transcode tmp_directory=/tmp/transcode
lock_file=/tmp/music-transcode.lock lock_file=/tmp/music-transcode.lock
function die()
{
printf '%s\n' "$1" >&2
exit "${2-1}"
}
function transcode_to_mp3() function transcode_to_mp3()
{ {
input_file="$1" input_directory="$1"
output_directory="$2" input_file_name="$2"
output_file="$(echo "$input_file" | sed -E "s#^$input_directory(.+)\\.[a-z0-9]+\\$#$output_directory\\1.mp3#g")" 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")" output_directory="$(dirname "$output_path")"
if [ ! -d "$directory" ] ; then if [ ! -d "$output_directory" ] ; then
echo "New Directory: \"$directory\"" echo "New Directory: \"$output_directory\""
mkdir -p "$directory" || { echo "Could not create directory \"$directory\"." ; return 1 ; } mkdir -p "$output_directory" || die "Could not create directory \"$output_directory\"."
fi fi
transcode=false transcode=false
if [ ! -f "$output_file" ] ; then if [ ! -f "$output_path" ] ; then
echo "New MP3: \"$output_file\"" echo "New MP3: \"$output_path\""
transcode=true transcode=true
elif [ "$input_file" -nt "$output_file" ] ; then elif [ "$input_path" -nt "$output_path" ] ; then
echo "Input file is newer: \"$output_file\"" echo "Input file is newer: \"$output_path\""
transcode=true transcode=true
fi fi
if [ "$transcode" = true ] ; then if [ "$transcode" = true ] ; then
input_type="$(file -b --mime-type "$input_file")" input_type="$(file -b --mime-type "$input_path")"
case "$input_type" in case "$input_type" in
"audio/flac"|"audio/x-flac") "audio/flac"|"audio/x-flac")
tmp_file="$tmp_directory/$(basename "$output_file")" tmp_path="$tmp_directory/$(basename "$output_path")"
echo "Transcoding MP3..." 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 ; } 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_file" "$output_file" || { echo "Could not move file to \"$output_file\"." ; return 1 ; } mv -f "$tmp_path" "$output_path" || die "Could not move file to \"$output_path\"."
;; ;;
application/octet-stream) application/octet-stream)
echo "Warning: Assuming \"$input_file\" is a MP3 file." echo "Warning: Assuming \"$input_path\" is a MP3 file."
;& ;&
audio/mpeg) audio/mpeg)
echo "Copying MP3..." 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 return 1
;; ;;
esac esac
@ -70,15 +77,15 @@ function ogg_add_cover()
sed -i -e '/^metadata_block_picture/d' "$tmp_metafile" && \ sed -i -e '/^metadata_block_picture/d' "$tmp_metafile" && \
echo -n "" > "$tmp_mdimg" && \ echo -n "" > "$tmp_mdimg" && \
printf "0: %.8x" 3 | xxd -r -g0 >> "$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" && \ 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" && \ 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" 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" && \ cat "$tmp_cover" >> "$tmp_mdimg" && \
echo "metadata_block_picture=$(base64 --wrap=0 < "$tmp_mdimg")" >> "$tmp_metafile" && \ echo "metadata_block_picture=$(base64 --wrap=0 < "$tmp_mdimg")" >> "$tmp_metafile" && \
vorbiscomment --write --raw --commentfile "$tmp_metafile" "$ogg_file" && \ vorbiscomment --write --raw --commentfile "$tmp_metafile" "$ogg_file" && \
@ -87,75 +94,72 @@ function ogg_add_cover()
function transcode_to_ogg() function transcode_to_ogg()
{ {
input_file="$1" input_directory="$1"
output_directory="$2" input_file_name="$2"
output_file="$(echo "$input_file" | sed -E "s#^$input_directory(.+)\\.[a-z0-9]+\\$#$output_directory\\1.ogg#g")" 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 if [ ! -d "$directory" ] ; then
echo "New Directory: \"$directory\"" 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 fi
transcode=false transcode=false
if [ ! -f "$output_file" ] ; then if [ ! -f "$output_path" ] ; then
echo "New OGG: \"$output_file\"" echo "New OGG: \"$output_path\""
transcode=true transcode=true
elif [ "$input_file" -nt "$output_file" ] ; then elif [ "$input_path" -nt "$output_path" ] ; then
echo "Input file is newer: \"$output_file\"" echo "Input file is newer: \"$output_path\""
transcode=true transcode=true
fi fi
if [ "$transcode" = true ] ; then 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" tmp_cover="$tmp_directory/cover"
case "$input_type" in case "$input_type" in
"audio/flac"|"audio/x-flac") "audio/flac"|"audio/x-flac")
echo "Transcoding OGG..." 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..." echo "Adding OGG cover image..."
metaflac --export-picture-to="$tmp_cover" "$input_file" && \ metaflac --export-picture-to="$tmp_cover" "$input_path" || die "Could not export cover image."
ogg_add_cover "$tmp_ogg" "$tmp_cover" || { echo "Could not add cover image to \"$tmp_ogg\"." ; return 1 ; } 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) application/octet-stream)
echo "Warning: Assuming \"$input_file\" is a MP3 file." echo "Warning: Assuming \"$input_path\" is a MP3 file."
;& ;&
audio/mpeg) audio/mpeg)
echo "Transcoding OGG..." 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..." echo "Adding OGG cover image..."
exiftool -Picture -b "$input_file" > "$tmp_cover" && \ exiftool -Picture -b "$input_path" > "$tmp_cover" || die "Could not export cover image."
ogg_add_cover "$tmp_ogg" "$tmp_cover" || { echo "Could not add cover image to \"$tmp_ogg\"." ; return 1 ; } 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 return 1
;; ;;
esac esac
fi fi
} }
function die()
{
printf '%s\n' "$1" >&2
exit "${2-1}"
}
if [ -f "$lock_file" ] ; then if [ -f "$lock_file" ] ; then
echo "Another instance is already running. Exiting." 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 exit 2
else else
touch "$lock_file" || die "Could not create lock file." touch "$lock_file" || die "Could not create lock file."
@ -167,18 +171,52 @@ function cleanup()
rm -rf "$tmp_directory" rm -rf "$tmp_directory"
} }
trap cleanup EXIT SIGTERM SIGKILL trap cleanup EXIT SIGTERM
if [ ! -d "$tmp_directory" ] ; then if [ ! -d "$tmp_directory" ] ; then
mkdir -p "$tmp_directory" || die "Could not create temporary directory \"$tmp_directory\"." mkdir -p "$tmp_directory" || die "Could not create temporary directory \"$tmp_directory\"."
fi fi
SAVEIFS=$IFS mp3_out=''
IFS=$(echo -ne "\n\b") ogg_out=''
for file in $(find "$input_directory" -name '*.flac' -or -name '*.mp3' | sort); do
transcode_to_mp3 "$file" "/data/music/mp3" || break while [ $# -gt 1 ] ; do
transcode_to_ogg "$file" "/data/music/ogg" || break 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 done
echo "Done Transcoding." if [ $# -lt 1 ] ; then
IFS=$SAVEIFS >&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."