1
0
Fork 0
bin/reflac

174 lines
5.5 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
VERSION=1.5
VERBOSE=0
RECURSIVE=0
NOACTION=0
SYNC=1
FLAC_LEVEL=5 # Default FLAC compression level
PRESERVE_MODTIME="" # for -p|--preserve
SELF="$(readlink -f "$0")"
OPTS=$(getopt -o Vvhrnps012345678 \
-l version,verbose,help,recursive,preserve,no-action,no-sync,fast,best \
-n reflac -- "$@")
TMPDIR="$(mktemp --tmpdir -d reflac.XXXXXXXXXX)"
eval set -- "$OPTS"
trap "exit 1" INT
usage()
{
cat <<EOF
reflac recompresses FLAC files while maintaining tags and file names.
Usage: reflac [OPTION]... [--] DIRECTORY...
-h --help Displays this help text
-V --version Displays the version of this program
-v --verbose Increases the verbosity. Use once to display the FLACs
currently being processed, use twice for the full flac
output.
-r --recursive Recurse into directories.
-n --no-action Do not recompress. With --verbose, displays a list of
files that would be processed.
-p --preserve Preserve file modification time.
-s --no-sync Do not synchronize file data. Will return faster, with
the potential danger to lose your files in a system crash.
-0 --fast Use the fastest, but worst, compression possible.
-1..-7 Adjust FLAC compresion between these standard ranges.
The default is -5, the same as for flac itself.
-8 --best Use the slowest, but best, compression possible.
DIRECTORY should point reflac to somewhere that contains *.flac
files. Optionally terminate the argument list with -- so that any
possible directory names dont get misinterpreted as arguments.
EOF
rmdir "$TMPDIR"
exit 0
}
recompress()
{
for flac in *.flac; do
if [ $VERBOSE -eq 1 ]; then
echo " $flac"
fi
if [ $NOACTION -eq 0 ]; then
HAS_COVER_ART=1
metaflac --no-utf8-convert \
--export-tags-to="$TMPDIR/$(basename -s flac -- "$flac")tag" \
-- "$flac"
metaflac --export-picture-to="$TMPDIR/$(basename -s flac -- "$flac")img" \
-- "$flac" > /dev/null 2>&1 || HAS_COVER_ART=0 #the error is handled later. do not exit the script
if [ $VERBOSE -gt 1 ]; then
flac --force-rf64-format --output-prefix="$TMPDIR/" -d -- "$flac"
flac --delete-input-file -$FLAC_LEVEL -- \
"$TMPDIR/$(basename -s flac -- "$flac")rf64"
else
flac -s --force-rf64-format --output-prefix="$TMPDIR/" -d -- "$flac"
flac -s --delete-input-file -$FLAC_LEVEL -- \
"$TMPDIR/$(basename -s flac -- "$flac")rf64"
fi
if [ $HAS_COVER_ART -eq 1 ]; then
metaflac --no-utf8-convert $PRESERVE_MODTIME \
--import-tags-from="$TMPDIR/$(basename -s flac -- "$flac")tag" \
--import-picture-from="$TMPDIR/$(basename -s flac -- "$flac")img" \
-- "$TMPDIR/$flac"
else
metaflac --no-utf8-convert $PRESERVE_MODTIME \
--import-tags-from="$TMPDIR/$(basename -s flac -- "$flac")tag" \
-- "$TMPDIR/$flac"
fi
mv -f -- "$TMPDIR/$flac" "$flac.new"
if [ $SYNC -eq 1 ]; then
sync "$flac.new"
mv -f "$flac.new" "$flac"
sync "$flac"
else
mv -f "$flac.new" "$flac"
fi
rm -f -- "$TMPDIR/$(basename -s flac -- "$flac")tag" \
"$TMPDIR/$(basename -s flac -- "$flac")img"
fi
done
}
while true ; do
case "$1" in
-v|--verbose)
VERBOSE=$((VERBOSE+1))
shift ;;
-r|--recursive)
RECURSIVE=1
shift ;;
-0|-1|-2|-3|-4|-5|-6|-7|-8)
FLAC_LEVEL=${1#-}
shift ;;
--fast)
FLAC_LEVEL=0
shift ;;
--best)
FLAC_LEVEL=8
shift ;;
-n|--no-action)
NOACTION=1
shift ;;
-p|--preserve)
PRESERVE_MODTIME="--preserve-modtime"
shift ;;
-s|--no-sync)
SYNC=0
shift ;;
-V|--version)
echo "reflac version $VERSION"
rmdir "$TMPDIR"
exit 0 ;;
-h|--help)
usage ;;
--) shift; break ;;
*) echo "$0: This should never happen!" >&2; exit 1 ;;
esac
done
if [ -z "$*" ]; then
usage
fi
if [ $VERBOSE -eq 0 ] && [ $NOACTION -eq 1 ]; then
rmdir "$TMPDIR"
exit 0
fi
for dir do
if [ $RECURSIVE -eq 1 ] && [ $NOACTION -eq 1 ]; then
find "$(readlink -f -- "$dir")" -type d -execdir "$SELF" -nv {} \;
elif [ $RECURSIVE -eq 1 ]; then
if [ $VERBOSE -eq 1 ]; then
find "$(readlink -f -- "$dir")" -type d \
-execdir "$SELF" -v -"$FLAC_LEVEL" {} \;
elif [ $VERBOSE -ge 2 ]; then
find "$(readlink -f -- "$dir")" -type d \
-execdir "$SELF" -vv -"$FLAC_LEVEL" {} \;
else
find "$(readlink -f -- "$dir")" -type d \
-execdir "$SELF" -"$FLAC_LEVEL" {} \;
fi
else
pushd -- "$dir" >/dev/null
if [ $VERBOSE -gt 0 ]; then readlink -f .; fi
if [ ! -z "$(ls -- *.flac 2>/dev/null)" ]; then
recompress
fi
popd >/dev/null
fi
done
rmdir "$TMPDIR"