150 lines
3.4 KiB
Bash
150 lines
3.4 KiB
Bash
#!/usr/bin/env bash
|
|
# 2025 Hyperling
|
|
# Clean up a music library. Improved version of rename_music_files.sh.
|
|
|
|
# Steps:
|
|
# 0) Ensure an OLD folder exists, it is what will be refactored.
|
|
# 1) Convert all non-mp3 files to mp3 and put them in an INTERIM folder.
|
|
# 2) Loop over all OLD and INTERIM's mp3 files and move them to NEW based on data.
|
|
# - Name the file as "${ZERO_LED_TRACK_NUMBER}. ${SONG_TITLE}
|
|
# - Name parent folder as "${YEAR} - ${ALBUM}" if both exist, otherwise just one or the other "${YEAR}${ALBUM}".
|
|
# - Name grandparent folder as "${ARTIST} - ${GENRE}" if both exist, otherwise "${ARTIST}${GENRE}".
|
|
|
|
# TODO list:
|
|
# - Organize tracks by Artist + Album folders.
|
|
# - Name parent folder as "$YEAR - $ALBUM" if both exist, otherwise just one or the other.
|
|
# - Name grandparent folder as ARTIST if it exists, otherwise GENRE.
|
|
|
|
## Facts and Variables ##
|
|
|
|
DIR="`pwd`"
|
|
PROG="$(basename -- "${BASH_SOURCE[0]}")"
|
|
|
|
FAIL=".$PROG.exit-error"
|
|
|
|
OLD="$DIR/OLD"
|
|
NEW="$DIR/NEW"
|
|
INT="$DIR/INTERIM"
|
|
|
|
## Checks and Setup ##
|
|
|
|
# System Packages #
|
|
echo "* Checking if necessary tools are installed."
|
|
function needed_progs {
|
|
cat <<- EOF
|
|
ffmpeg
|
|
exiftool
|
|
EOF
|
|
}
|
|
needed_progs | while read prog; do
|
|
if [[ -z "`which $prog`" ]]; then
|
|
echo "ERROR: $prog not found, please install."
|
|
touch $FAIL
|
|
fi
|
|
done
|
|
if [[ -e $FAIL ]]; then
|
|
rm -fv $FAIL
|
|
exit 1
|
|
fi
|
|
echo "** Tools are available."
|
|
|
|
# Old Directory #
|
|
echo "* Checking whether OLD directory exists."
|
|
if [[ "`pwd`" == *"/OLD" ]]; then
|
|
echo "** We are in the folder, moving up a directory."
|
|
cd ..
|
|
fi
|
|
if [[ ! -d "OLD" ]]; then
|
|
echo "ERROR: Could not find a folder named 'OLD'."
|
|
echo " Please create it and add your library there."
|
|
fi
|
|
echo "** Folder exists appropriately."
|
|
|
|
# Other Directories #
|
|
echo "* Ensuring working directories NEW and INTERIM exist."
|
|
mkdir -pv "$NEW" "$INT"
|
|
|
|
## Convert Media ##
|
|
|
|
echo "* Convert all files to mp3."
|
|
find "$OLD" ! -name "*".mp3 | while read file; do
|
|
ffmpeg -nostdin -hide_banner -loglevel quiet -i "$file" "$file".converted.mp3
|
|
done
|
|
echo "** Done converting mp3s."
|
|
|
|
## Transform Media ##
|
|
|
|
function migrate_music {
|
|
file="$1"
|
|
command="$2"
|
|
|
|
if [[ -z $file ]]; then
|
|
echo "ERROR: No filename retrieved, cannot migrate."
|
|
return 1
|
|
fi
|
|
if [[ -z "$command" ]]; then
|
|
command="cp"
|
|
fi
|
|
|
|
echo "** $file **"
|
|
|
|
# Retrieve and clean the Title
|
|
title=""
|
|
title="`exiftool -Title "$file"`"
|
|
title="${title//Title /}"
|
|
title="${title// : /}"
|
|
title="${title//[^[:alnum:][:space:].]/}"
|
|
title="`echo $title`"
|
|
while [[ "$title" == *" "* ]]; do
|
|
title="${title// / }"
|
|
done
|
|
echo "*** Title=$title"
|
|
|
|
new_file="$title$EXT"
|
|
|
|
# Retrieve and clean the Track#
|
|
track=""
|
|
# Get raw value
|
|
track="`exiftool -Track "$file"`"
|
|
# Filter the header
|
|
track="${track//Track /}"
|
|
track="${track// : /}"
|
|
# Remove disk designations
|
|
track="${track%%/*}"
|
|
# Remove any whitespace before/after
|
|
track="`echo $track`"
|
|
# Add a leading 0 to single digits.
|
|
[[ ${#track} == 1 ]] && track="0$track"
|
|
echo "*** Track=$track"
|
|
|
|
new_file="$track. $new_file"
|
|
|
|
# Add the Album and Year.
|
|
|
|
|
|
new_file="$parent/$new_file"
|
|
|
|
# Add the Artist and Genre.
|
|
|
|
|
|
new_file="$grandparent/$new_file"
|
|
|
|
# Move the file.
|
|
new_file="$NEW/$new_file"
|
|
$command "$file" "$new_file"
|
|
|
|
}
|
|
|
|
echo "* Moving INTERIM files to NEW."
|
|
find "$INT" -name "*".mp3 | while read file; do
|
|
migrate_music "$file" mv
|
|
done
|
|
|
|
echo "** Done with INTERIM, deleting."
|
|
rm -rfv "$INT"
|
|
|
|
echo "* Copying OLD files to NEW."
|
|
find "$OLD" -name "*".mp3 | while read file; do
|
|
migrate_music "$file" cp
|
|
done
|