68 lines
1.6 KiB
Bash
Executable File
68 lines
1.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Sync and transcode music files to a destination directory
|
|
set -e
|
|
|
|
SRC="${1:?Source directory required}"
|
|
DST="${2:?Destination directory required}"
|
|
JOBS="${3:-12}"
|
|
|
|
command -v opusenc >/dev/null || { echo "ERROR: opusenc not found" >&2; exit 1; }
|
|
|
|
mkdir -p "$DST"
|
|
|
|
echo "Syncing music from $SRC to $DST (using $JOBS parallel jobs)"
|
|
|
|
# Process source files in parallel
|
|
process_file() {
|
|
local src="$1"
|
|
local rel="${src#"$SRC/"}"
|
|
local dst="$DST/$rel"
|
|
|
|
case "${src,,}" in
|
|
*.flac)
|
|
dst="${dst%.*}.opus"
|
|
if [[ ! -f "$dst" || "$src" -nt "$dst" ]]; then
|
|
echo "Converting: $rel"
|
|
mkdir -p "$(dirname "$dst")"
|
|
opusenc --quiet --bitrate 160 --vbr "$src" "$dst"
|
|
fi
|
|
;;
|
|
*.mp3)
|
|
if [[ ! -f "$dst" || "$src" -nt "$dst" ]]; then
|
|
echo "Copying: $rel"
|
|
mkdir -p "$(dirname "$dst")"
|
|
cp -p "$src" "$dst"
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
export -f process_file
|
|
export SRC DST
|
|
|
|
find -L "$SRC" -type f \( -iname "*.flac" -o -iname "*.mp3" \) -print0 | \
|
|
xargs -0 -P "$JOBS" -I {} bash -c 'process_file "$@"' _ {}
|
|
|
|
# Remove stray files
|
|
while IFS= read -r -d '' dst; do
|
|
rel="${dst#"$DST/"}"
|
|
base="${rel%.*}"
|
|
|
|
case "${dst,,}" in
|
|
*.opus)
|
|
[[ -f "$SRC/$base.flac" || -f "$SRC/$base.FLAC" ]] && continue
|
|
echo "Removing: $rel"
|
|
rm -f "$dst"
|
|
;;
|
|
*.mp3)
|
|
[[ -f "$SRC/$rel" ]] && continue
|
|
echo "Removing: $rel"
|
|
rm -f "$dst"
|
|
;;
|
|
esac
|
|
done < <(find -L "$DST" -type f \( -iname "*.opus" -o -iname "*.mp3" \) -print0)
|
|
|
|
# Clean empty directories
|
|
find "$DST" -type d -empty -delete 2>/dev/null || true
|
|
|
|
echo "Done" |