Skip to content

Instantly share code, notes, and snippets.

@toydotgame
Last active November 16, 2023 11:16
Show Gist options
  • Save toydotgame/e777b6d588f06952f4902e2cca01bb91 to your computer and use it in GitHub Desktop.
Save toydotgame/e777b6d588f06952f4902e2cca01bb91 to your computer and use it in GitHub Desktop.
Add album art, artist, and album to all MP3s in the current folder.
#!/bin/bash
FCLR="\e[0m"
FBLD="\e[1m"
FRED="\e[31m"
FYEL="\e[33m"
FWHT="\e[39m"
###########################################################################################
#### SCRIPT CREATED: 2021-07-11 #
#### AUTHOR: toydotgame #
#### Metadata script V2. Takes `--debug` argument. Assumes directory at ~/Music/, with #
#### ~/Music/Album Covers/ as art directory and an /Artist/Album/Song.ext file structure. #
#### Requires: curl, ffmpeg, yt-dlp #
###########################################################################################
# Init:
if [[ $1 = "--debug" ]]; then printf "$FBLD${FYEL}[Debug]$FWHT Beginning init...$FCLR\n"; fi
alias ffmpeg="ffmpeg -hide_banner -loglevel error"
if [[ $1 = "--debug" ]]; then
alias ffmpeg="ffmpeg -hide_banner"
fi
if [[ ! -d "/tmp/metadatash/" ]]; then
mkdir "/tmp/metadatash/"
else # Lazy not doing a check if files even exist in here because I'm not bothered to write a condition
rm -rf /tmp/metadatash/*
fi
if [[ ! -d "$HOME/Music/Album Covers/" ]]; then
mkdir -p "$HOME/Music/Album Covers/"
fi
USRRES= # User response
ARTLOC= # Location of album art (const)
ARTIST= # Metadata artist (const)
FSARTS= # UNIX FS-safe artist (const)
ALBUM= # Album name (const)
FSALBM= # UNIX FS-safe album (const)
TRCKNM= # UNIX FS-safe filename
RespToLower () {
USRRES=$(printf "$USRRES" | tr "[:upper:]" "[:lower:]")
}
if [[ $1 = "--debug" ]]; then printf "$FBLD${FYEL}[Debug]$FWHT Init complete. Press any key to continue.$FCLR"; read; fi
# Song downloader:
if [[ $1 = "--debug" ]]; then printf "$FBLD${FYEL}[Debug]$FWHT Beginning song download...$FCLR\n"; fi
printf "Is this album/song downloaded? [y/N]: "; read USRRES
RespToLower
if [[ "$USRRES" != "y" ]]; then
printf "What is the URL of the song/playlist?: "; read USRRES
if [[ -z "$USRRES" ]]; then
printf "$FBLD${FRED}[Error]$FWHT No URL supplied! Exiting.$FCLR\n"
exit
fi
cd "/tmp/metadatash/"
yt-dlp -q --progress -x --audio-format mp3 -o "%(title)s.%(ext)s" "$USRRES"
else
printf "Which directory holds the album/What path is the song at? (Must be relative to / or ~): "; read USRRES
if [[ -z "$USRRES" ]]; then
printf "$FBLD${FRED}[Error]$FWHT No path supplied! Exiting.$FCLR\n"
exit
fi
USRRES="${USRRES/#\~/$HOME}"
if [[ -d "$USRRES" ]]; then
cd "$USRRES"
for f in *; do
ffmpeg -i "$f" "/tmp/metadatash/${f%.*}.mp3"
done
elif [[ -f "$USRRES" ]]; then
ffmpeg -i "$USRRES" "/tmp/metadatash/$(basename "${USRRES%.*}").mp3"
else
printf "$FBLD${FRED}[Error]$FWHT Path does not exist or is not valid! Exiting.$FCLR\n"
exit
fi
fi
if [[ $1 = "--debug" ]]; then printf "$FBLD${FYEL}[Debug]$FWHT Song download complete. Press any key to continue.$FCLR"; read; fi
# Art:
if [[ $1 = "--debug" ]]; then printf "$FBLD${FYEL}[Debug]$FWHT Beginning art assignment...$FCLR\n"; fi
cd "/tmp/metadatash/"
printf "Where is the album art stored? (Can be a URL or file relative to / or ~): "; read USRRES
if [[ ! -z "$USRRES" ]]; then
if [[ "$USRRES" == http* ]]; then # URL location
curl -o "cover" "$USRRES"
ffmpeg -i "cover" "cover.png" && rm -f "cover"
else
USRRES="${USRRES/#\~/$HOME}"
ffmpeg -i "$USRRES" "cover.png" && rm -f "$USRRES"
fi
printf "What do you want to call the album art image file? (Will be a PNG): "; read USRRES
if [[ ! -z "$USRRES" ]]; then
mv "cover.png" "$HOME/Music/Album Covers/$USRRES.png"
ARTLOC="$HOME/Music/Album Covers/$USRRES.png"
for f in *; do
ffmpeg -i "$f" -i "$ARTLOC" -c copy -map 0 -map 1 -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" "${f%.*}-m0.mp3" && rm -f "$f"
done
fi
else
for f in *; do
mv "$f" "${f%.*}-m0.mp3"
done
fi
if [[ $1 = "--debug" ]]; then printf "$FBLD${FYEL}[Debug]$FWHT Art assignment complete. Press any key to continue.$FCLR"; read; fi
# Metadata editor:
if [[ $1 = "--debug" ]]; then printf "$FBLD${FYEL}[Debug]$FWHT Beginning metadata assignment...$FCLR\n"; fi
printf "Who is the artist?: "; read USRRES
if [[ -z "$USRRES" ]]; then
ARTIST="Unknown artist"
else
ARTIST="$USRRES"
if [[ "$ARTIST" == *"/"* ]]; then
FSARTS="${ARTIST//\//}" # Remove all slashes
if [[ -z "$FSARTS" ]]; then
FSARTS="Unknown artist"
fi
else
FSARTS="$ARTIST"
fi
fi
printf "What is name of the album?: "; read USRRES
if [[ -z "$USRRES" ]]; then
ALBUM="Unknown album"
else
ALBUM="$USRRES"
if [[ "$ALBUM" == *"/"* ]]; then
FSALBM="${ALBUM//\//}" # Remove all slashes
if [[ -z "$FSALBM" ]]; then
FSALBM="Unknown artist"
fi
else
FSALBM="$ALBUM"
fi
fi
if [[ ! -d "$HOME/Music/$FSARTS/$FSALBM/" ]]; then
mkdir -p "$HOME/Music/$FSARTS/$FSALBM/"
fi
for f in *; do
ffmpeg -i "$f" -c copy -metadata artist="$ARTIST" -metadata album="$ALBUM" "${f%.*},1.mp3" && rm -f "$f"
done
for f in *; do
printf "What is the track name of \"${f%-m0*}\"?: "; read USRRES
if [[ -z "$USRRES" ]]; then
USRRES="${f%-m0*}"
fi
if [[ "$USRRES" == *"/"* ]]; then
TRCKNM="${USRRES//\//}"
if [[ -z "$TRCKNM" ]]; then
TRCKNM="$(date +%N)" # Effectively random 9 digits
fi
else
TRCKNM="$USRRES"
fi
ffmpeg -i "$f" -c copy -metadata title="$USRRES" "${f%.*},2.mp3" && rm -f "$f"
printf "What is the track number of \"$USRRES\"?: "; read USRRES
if [[ "$USRRES" =~ ^[0-9]+$ ]]; then
ffmpeg -i "${f%.*},2.mp3" -c copy -metadata track="$USRRES" "$HOME/Music/$FSARTS/$FSALBM/$TRCKNM.mp3" && rm -f "${f%.*},2.mp3"
else
if [[ $1 = "--debug" ]]; then printf "$FBLD${FRED}[Error]$FWHT Track number \$USRRES=\"$USRRES\", NaN error! Setting to null.$FCLR\n"; fi
mv "${f%.*},2.mp3" "$HOME/Music/$FSARTS/$FSALBM/$TRCKNM.mp3"
fi
done
if [[ $1 = "--debug" ]]; then printf "$FBLD${FYEL}[Debug]$FWHT Metadata assignment complete. Press any key to continue.$FCLR"; read; fi
# Clean up:
if [[ $1 = "--debug" ]]; then printf "$FBLD${FYEL}[Debug]$FWHT Beginning cleanup...$FCLR\n"; fi
rm -rf "/tmp/metadatash/"
if [[ $1 = "--debug" ]]; then printf "$FBLD${FYEL}[Debug]$FWHT Cleanup complete. Press any key to continue.$FCLR"; read; fi
@toydotgame
Copy link
Author

toydotgame commented Jun 12, 2022

// TODO: Download `-f 251` copies of `--audio-format mp3` using `youtube-dl` (obviously note dependency in script description) function, to take a playlist or video URL and work with that. Maybe even create a child working directory.

@toydotgame
Copy link
Author

LOL! Done! V2 out and it downloads stuff! #GetRekt 2022 me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment