Use command line arguments, die function
This commit is contained in:
parent
8ee42e7a1c
commit
11e021b43d
158
transcode.sh
158
transcode.sh
|
@ -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."
|
||||||
|
|
Loading…
Reference in a new issue