From 1d85f3fd842a8dc43bb17932b7a96209828b6d07 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Fri, 7 Jun 2024 09:21:10 -0700 Subject: [PATCH] Create bash script based on other project. --- rename_music_files.sh | 235 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 rename_music_files.sh diff --git a/rename_music_files.sh b/rename_music_files.sh new file mode 100644 index 0000000..5aeb446 --- /dev/null +++ b/rename_music_files.sh @@ -0,0 +1,235 @@ +#!/bin/bash +# 2024-06-07 C.Greenwood +# Rename all files in a music library based on metadata. +# Uses the format "[Track] [Title].mp3" + +# TBD Remove all the stuff from AddTrackToTitle. + +# 2022-08-30 Hyperling +# Put the files' Track in their Title so that Toyota Entune plays the songs in the right frikken order!!! +# At least with the 2019 RAV4, it acknowledges the Track#, but still sorts albums alphabetically for whatever reason. +# +# Return Codes: +# 0) Success! +# 1) Parameter passed +# 2) Pre-requisite tool not installed +# 3) Failure to find music metadata +# 4) Failure to create fixed file +# 5) Fixed file is missing +# 6) Unknown operator +# + + +## Variables ## + +PROG="`basename $0`" +DIR="`dirname $0`" +EXT=".mp3" +ADD="(Fixed)" +TIME="`which time`" +TRUE="T" +FALSE="F" +UNDO="$FALSE" + + +## Functions ## + +function usage { + cat <<- EOF + Usage: + $PROG [-h] [-u] + + Parameters: + -h : Help, display the usage and exit succesfully. + -u : Undo, attempt to un-fix files which have had the normal script run against them. + + Place this file at the root of your music destined for a flash drive and run it without any parameters. + It will dive through all folders and convert your MP3's to have the Track# in the Title. + The process changes the filenames to contain (Fixed) so you know it's touched the file. + Please be sure you only run this on a copy of your music, not the main source! + + This tool has a few pre-requisites you should make sure you have installed: + - exiftool + - ffmpeg + + Thanks for using $PROG! + EOF + exit $1 +} + +function error { + num_chars=$(( 7 + ${#1} )) + echo "" + printf '*%.0s' $(seq 1 $num_chars) + echo -e "\nERROR: $1" + printf '*%.0s' $(seq 1 $num_chars) + echo -e "\n" + usage $2 +} + + +## Validations ## + +# Check for parameters. +while getopts ":hu" opt; do + case "$opt" in + h) usage 0 + ;; + u) UNDO="$TRUE" + ;; + *) error "Operator $OPTARG not recognized." 6 + ;; + esac +done + +# Ensure critical tools are available. +if [[ ! `which exiftool` ]]; then + error "exiftool not found" 2 +fi +if [[ ! `which ffmpeg` ]]; then + error "exiftool not found" 2 +fi +if [[ ! `which bc` ]]; then + error "bc not found" 2 +fi +if [[ ! `ls /usr/bin/time` ]]; then + error "/usr/bin/time not found" 2 +fi + +# Make sure the user understands they're going to change their music's title. +typeset -l change +read -p "Please acknowledge you are OK with irreversibly modifying your music's metadata. [y/N] " change +if [[ $change != "y" ]]; then + echo -e "\nThank you for your honesty. Come back when you feel more confident. :)\n" + usage 0 +fi + +# Make sure the user has a backup of the music different than the folder they're running this in. +typeset -l backup +read -p 'Please ensure you have a backup. There is no warranty for this program! [y/N] ' backup +if [[ $backup != "y" ]]; then + echo -e "\nThank you for your honesty. Please backup your music and come back soon. :)\n" + usage 0 +fi + +printf 'User has provided permission to alter data.\nMoving forward in 5... ' +sleep 1 +printf '4... ' +sleep 1 +printf '3... ' +sleep 1 +printf '2... ' +sleep 1 +printf '1... \n' +sleep 1 + + +## Main ## + +# Loop through all files in and lower than the current directory. +count=0 +total="`find $DIR -name "*${EXT}" -printf . | wc -c`" +avg_time=0 +total_time=0 +time_count=0 +est_guess=0 +time find $DIR -name "*${EXT}" | while read file; do + count=$(( count + 1 )) + + echo -e "\n$file" + + # Skip file if it's already correct. + if [[ "$UNDO" == "$FALSE" && "$file" == *"$ADD"* ]]; then + echo "Already fixed, skipping." + continue + elif [[ "$UNDO" == "$TRUE" && "$file" != *"$ADD"* ]]; then + echo "Already unfixed, skipping." + continue + fi + + # 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" + + # Retrieve and clean the Title + title="" + title="`exiftool -Title "$file"`" + title="${title//Title /}" + title="${title// : /}" + title="`echo $title`" + echo "Title=$title" + + # Skip file if title is already changed. + if [[ "$UNDO" == "$FALSE" && "$title" == "$track"* ]]; then + echo "Title already contains Track, skipping." + continue + elif [[ "$UNDO" == "$TRUE" && "$title" != "$track"* ]]; then + echo "Title already missing Track, skipping." + continue + fi + + # Create the new file with the correct Title + new_title="" + new_file="" + if [[ "$UNDO" == "$FALSE" ]]; then + new_title="${track}. ${title}" + new_file="${file//$EXT/$ADD$EXT}" + else + new_title="${title/${track}. }" + new_file="${file//$ADD/}" + fi + if [[ ! -z "$track" && ! -z "$title" ]]; then + echo "Creating '`basename "$new_file"`' with Title '$new_title'." + AV_LOG_FORCE_NOCOLOR=1 + /usr/bin/time -f '%e' -o time.txt ffmpeg -nostdin -hide_banner -loglevel quiet -i "$file" -metadata "Title=$new_title" "$new_file" + time=`cat time.txt` + #rm time.txt + ffstatus="$?" + if [[ $ffstatus ]]; then + echo "Success! Completed in $time seconds." + time_count=$(( time_count + 1 )) + total_time=$(echo "$total_time + $time" | bc -l) + avg_time=$(echo "$total_time / $time_count" | bc -l) + else + error "Did something bad happen? ffmpeg returned $ffstatus." 4 + fi + elif [[ -z "$track" && ! -z "$title" ]]; then + echo "No Track# found, leaving Title alone." + continue + else + error "File does not have Track or Title metadata. Are you sure you're running this on music?" 3 + fi + + # Confirm the new file exists and remove the old file if so + if [[ -e "$new_file" ]]; then + echo "Removing file..." + rm -v "$file" + else + error "$new_file was not created successfully." 5 + fi + + # Give an estimate for time remaining. The magic number is to account for non-ffmpeg time. + magic="1.2" + est_guess_total="$( echo "est=(($total - $count) * $avg_time) * $magic; scale=0; est/1" | bc )" + est_guess_secs="$( echo "est=$est_guess_total % 60; scale=0; est/1" | bc )" + est_guess_mins="$( echo "est=($est_guess_total/60) % 60; scale=0; est/1" | bc )" + est_guess_hours="$( echo "est=($est_guess_total/(60*60)); scale=0; est/1" | bc )" + est_guess="$est_guess_hours hour(s) $est_guess_mins minute(s) $est_guess_secs second(s)" + + echo -e "\nFinished $count of $total. Estimated time remaining is $est_guess." +done + +echo -e "\nProcess has completed. Enjoy having your songs in album-order!" + +exit 0