From 1d85f3fd842a8dc43bb17932b7a96209828b6d07 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Fri, 7 Jun 2024 09:21:10 -0700 Subject: [PATCH 1/5] 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 -- 2.47.2 From 6a0a12ad7a97cbc1eacb84dafda770b5e00af03c Mon Sep 17 00:00:00 2001 From: Hyperling Date: Fri, 7 Jun 2024 09:32:40 -0700 Subject: [PATCH 2/5] Got program into working order, still need to clean up. --- rename_music_files.sh | 106 ++++-------------------------------------- 1 file changed, 9 insertions(+), 97 deletions(-) mode change 100644 => 100755 rename_music_files.sh diff --git a/rename_music_files.sh b/rename_music_files.sh old mode 100644 new mode 100755 index 5aeb446..0d4c9cd --- a/rename_music_files.sh +++ b/rename_music_files.sh @@ -1,7 +1,7 @@ #!/bin/bash # 2024-06-07 C.Greenwood # Rename all files in a music library based on metadata. -# Uses the format "[Track] [Title].mp3" +# Uses the format "[Track]. [Title].mp3" # TBD Remove all the stuff from AddTrackToTitle. @@ -41,7 +41,6 @@ function usage { 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. @@ -71,12 +70,10 @@ function error { ## Validations ## # Check for parameters. -while getopts ":hu" opt; do +while getopts ":h" opt; do case "$opt" in h) usage 0 ;; - u) UNDO="$TRUE" - ;; *) error "Operator $OPTARG not recognized." 6 ;; esac @@ -86,42 +83,6 @@ done 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 ## @@ -138,15 +99,6 @@ time find $DIR -name "*${EXT}" | while read file; do 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 @@ -170,40 +122,11 @@ time find $DIR -name "*${EXT}" | while read file; do 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 + # Create the new file with the correct filename. + new_filename="$track. $title$EXT" 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 + echo "Creating '`basename "$new_filename"`'." + mv -v "$file" "$new_filename" elif [[ -z "$track" && ! -z "$title" ]]; then echo "No Track# found, leaving Title alone." continue @@ -212,22 +135,11 @@ time find $DIR -name "*${EXT}" | while read file; do fi # Confirm the new file exists and remove the old file if so - if [[ -e "$new_file" ]]; then - echo "Removing file..." - rm -v "$file" + if [[ -e "$new_filename" ]]; then + echo "Success!" else - error "$new_file was not created successfully." 5 + error "$new_filename 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!" -- 2.47.2 From 0a55a188bf6fbd7fd3369fa0397b3891e99d420f Mon Sep 17 00:00:00 2001 From: Hyperling Date: Fri, 7 Jun 2024 10:04:04 -0700 Subject: [PATCH 3/5] Fixed bugs, working great now on full library. --- rename_music_files.sh | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/rename_music_files.sh b/rename_music_files.sh index 0d4c9cd..0c437b7 100755 --- a/rename_music_files.sh +++ b/rename_music_files.sh @@ -23,7 +23,8 @@ ## Variables ## PROG="`basename $0`" -DIR="`dirname $0`" +#DIR="`dirname $0`" +DIR="`pwd`" EXT=".mp3" ADD="(Fixed)" TIME="`which time`" @@ -119,14 +120,20 @@ time find $DIR -name "*${EXT}" | while read file; do title="`exiftool -Title "$file"`" title="${title//Title /}" title="${title// : /}" + title="${title//[^[:alnum:][:space:].]/}" title="`echo $title`" echo "Title=$title" # Create the new file with the correct filename. - new_filename="$track. $title$EXT" + new_file="`dirname "$file"`/$track. $title$EXT" + if [[ ! -z "$track" && ! -z "$title" ]]; then - echo "Creating '`basename "$new_filename"`'." - mv -v "$file" "$new_filename" + if [[ "$file" == "$new_file" ]]; then + echo "SKIP: Filename already correct! :)" + continue + fi + echo "Creating '`basename "$new_file"`'." + mv -v "$file" "$new_file" elif [[ -z "$track" && ! -z "$title" ]]; then echo "No Track# found, leaving Title alone." continue @@ -135,10 +142,10 @@ time find $DIR -name "*${EXT}" | while read file; do fi # Confirm the new file exists and remove the old file if so - if [[ -e "$new_filename" ]]; then + if [[ -e "$new_file" ]]; then echo "Success!" else - error "$new_filename was not created successfully." 5 + error "$new_file was not created successfully." 5 fi done -- 2.47.2 From 5fe5e8106cefc7627b157d815fe498a272f2219c Mon Sep 17 00:00:00 2001 From: Hyperling Date: Fri, 7 Jun 2024 19:18:30 -0700 Subject: [PATCH 4/5] Also remove double whitespace. --- rename_music_files.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rename_music_files.sh b/rename_music_files.sh index 0c437b7..6dd0026 100755 --- a/rename_music_files.sh +++ b/rename_music_files.sh @@ -95,7 +95,7 @@ avg_time=0 total_time=0 time_count=0 est_guess=0 -time find $DIR -name "*${EXT}" | while read file; do +time find $DIR -name "*${EXT}" | sort | while read file; do count=$(( count + 1 )) echo -e "\n$file" @@ -122,6 +122,9 @@ time find $DIR -name "*${EXT}" | while read file; do title="${title// : /}" title="${title//[^[:alnum:][:space:].]/}" title="`echo $title`" + while [[ "$title" == *" "* ]]; do + title="${title// / }" + done echo "Title=$title" # Create the new file with the correct filename. @@ -138,7 +141,8 @@ time find $DIR -name "*${EXT}" | while read file; do 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 + echo "File does not have Track or Title metadata." + continue fi # Confirm the new file exists and remove the old file if so -- 2.47.2 From 916bcc3afc191fdecc666c7b52a49851e5cc4c36 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Sat, 8 Jun 2024 11:05:45 -0700 Subject: [PATCH 5/5] Finalize the code. Still needs final testing. --- rename_music_files.sh | 49 +++++++------------------------------------ 1 file changed, 7 insertions(+), 42 deletions(-) diff --git a/rename_music_files.sh b/rename_music_files.sh index 6dd0026..90da83c 100755 --- a/rename_music_files.sh +++ b/rename_music_files.sh @@ -3,35 +3,12 @@ # 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`" DIR="`pwd`" EXT=".mp3" -ADD="(Fixed)" -TIME="`which time`" -TRUE="T" -FALSE="F" -UNDO="$FALSE" - ## Functions ## @@ -44,13 +21,10 @@ function usage { -h : Help, display the usage and exit succesfully. 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! + It will dive through all folders and convert your MP3's to have the Track# and Title in the filename. - This tool has a few pre-requisites you should make sure you have installed: + This tool has a pre-requisite you should make sure you have installed: - exiftool - - ffmpeg Thanks for using $PROG! EOF @@ -67,7 +41,6 @@ function error { usage $2 } - ## Validations ## # Check for parameters. @@ -85,18 +58,10 @@ if [[ ! `which exiftool` ]]; then error "exiftool not found" 2 fi - ## 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}" | sort | while read file; do - count=$(( count + 1 )) echo -e "\n$file" @@ -129,12 +94,12 @@ time find $DIR -name "*${EXT}" | sort | while read file; do # Create the new file with the correct filename. new_file="`dirname "$file"`/$track. $title$EXT" + if [[ "$file" == "$new_file" ]]; then + echo "SKIP: Filename already correct! :)" + continue + fi if [[ ! -z "$track" && ! -z "$title" ]]; then - if [[ "$file" == "$new_file" ]]; then - echo "SKIP: Filename already correct! :)" - continue - fi echo "Creating '`basename "$new_file"`'." mv -v "$file" "$new_file" elif [[ -z "$track" && ! -z "$title" ]]; then @@ -153,6 +118,6 @@ time find $DIR -name "*${EXT}" | sort | while read file; do fi done -echo -e "\nProcess has completed. Enjoy having your songs in album-order!" +echo -e "\nProcess has completed. Enjoy having your songs named correctly!" exit 0 -- 2.47.2