#!/usr/bin/env bash # Ben Zanin, 2023-10-25 # If you have downloaded the Best of Bootie - Halloween 10 (2023) mashup # from https://bootiemashup.com/mix-tapes/halloween-booootie-10-2023/ # only to discover that the MP3 files in the zip archive contain no tags # at all, run this script to populate some meaningful values in there. # # You'll need a host system that has bash 4.x or greater. Linux and WSL # or WSL2 under Windows should do; macOS has the unfortunate problem of # offering only bash 3.x, you'll need to install something less moribund # via 'brew install bash' or whatever mechanism you prefer. # # You'll also need the id3v2 utility installed, either via 'brew install # id3v2' under macOS or 'apt-get install id3v2' under Debian/Ubuntu or # however else you install software on your machine. # # This program looks for and honours two environment variables: 'DEBUG', # which makes the output much more chatty on standard error, and # USE_ID3V2_SLASH_SEPARATED_ARTISTS, which transforms the many artists # in each metadata tag to be separated by slashes instead of their more # human-friendly format listed on the Best of Bootie album page. if ! command -v id3v2 > /dev/null 2>&1; then >&2 printf 'could not find prerequisite tool: id3v2\n' exit 1 fi if [[ ! ${BASH_VERSINFO-UNSET} =~ ^[45] ]]; then >&2 printf 'we need bash >= 4.2 to run but found %s\n' \ "${BASH_VERSINFO-no \$BASH_VERSINFO variable set}" >&2 printf '(this program uses bash array features, see %s )\n' \ 'https://mywiki.wooledge.org/BashFAQ/061' exit 1 fi declare -a fn_artists missing opts_id3v2 declare -i i tracktotal tracknum declare fn artists title artist artist_tag_value fn_artists=( \ '01 fnogg - Shake It Down In My Dragula.mp3' 'Rob Zombie vs. Taylor Swift vs. Disturbed' '02 CastleR - There Will Be Life.mp3' 'Kim Petras vs. Backstreet Boys' '03 Titus Jones - Gimme Sweet Halloween.mp3' 'Korn vs. ABBA vs. Beyoncé vs. Muse' '04 reconthuse - Seven Nation Nightmare.mp3' 'Alice Cooper vs. White Stripes' '05 IamJstncrdble - Haunted Thriller.mp3' 'Taylor Swift vs. Michael Jackson' '06 iWillBattle - Vampire Hammer.mp3' 'Olivia Rodrigo vs. Ghost' '07 iWillBattle - Mucky Mary [GaGa Muck].mp3' 'The Cramps vs. Lady Gaga' "08 DSP - Somebody's Watching Girl.mp3" 'The Cure vs. Rockwell' '09 MasDaMind - I’m Your Black Wolf.mp3' 'KC & the Sunshine Band vs. Zombie Hyperdrive' '10 Lewis Wake - Scary Edge.mp3' 'Britney Spears vs. REZZ' '11 Aggro1 - Zombie Rootkit.mp3' 'The Cranberries vs. Emurse' '12 Voicedude - Werewolves On The Storm.mp3' 'Warren Zevon vs. The Doors + American Werewolf In London' '13 Kill_mR_DJ - Spell Box.mp3' 'Screaming Jay Hawkins vs. Portishead vs. Creedence Clearwater Revival' ) tracktotal=$((${#fn_artists[@]}/2)) for ((i=0; i<${#fn_artists[@]}; i+=2)); do fn=${fn_artists[i]} if [[ ! -f "$fn" ]]; then missing+=($((1+(i/2))) "$fn") fi done if ((${#missing[@]} > 0)); then >&2 printf 'missing track %02d, filename: %s\n' "${missing[@]}" exit 2 fi for ((i=0; i<${#fn_artists[@]}; i+=2)); do fn=${fn_artists[i+0]} artists=${fn_artists[i+1]} title=${fn#* - } title=${title%.mp3} artist=${fn%% - *} artist=${artist:3} tracknum=$((1+(i/2))) if [[ $title == *Your\ Black\ Wolf* ]]; then title=${title//’/\'} fi artist_tag_value="$artist: $artists" if [[ ${USE_ID3V2_SLASH_SEPARATED_ARTISTS+SET} == 'SET' ]]; then # not personally something I care about, but set and export this # variable if you have strong opinions about separating multiple # artists with slashes in the ID3v2 metadata artist_tag_value=${artist_tag_value/: /\/} artist_tag_value=${artist_tag_value// vs. /\/} fi opts_id3v2=( \ '--id3v2-only' '--artist' "$artist_tag_value" '--album' 'Best of Bootie - Halloween Bootie 10 (2023)' '--song' "$title" '--genre' 'bootie mashup' '--year' '2023' '--track' "$tracknum/$tracktotal" '--comment' 'See album info at https //bootiemashup.com/mix-tapes/halloween-booootie-10-2023/' # infuriatingly there seems to be no reasonable way to populate # a comment tag with the id3v2 tag if that value contains a ":" # character, so we use a stupid space instead. Harrumph. # # cf. https://www.jetmore.org/john/blog/2012/07/patch-allow-id3v21-to-include-colons-in-comment-fields/ # and http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=681847 ) if [[ ${DEBUG+SET} == 'SET' ]]; then declare -p fn title artists artist tracknum tracktotal printf 'id3v2:\n' printf ' %-10s %s\n' \ "${opts_id3v2[0]}" '' "${opts_id3v2[@]:1}" "$fn" '' fi if ! id3v2 -R "$fn" | grep -q -E ': No ID3 tag$'; then # don't mess around with files that already have metadata in them, # no sense in complicating things. To start over just extract the # MP3 files from the zip archive again. >&2 printf 'file already has id3v2 metadata, skipping: %s\n' \ "$fn" continue fi id3v2 "${opts_id3v2[@]}" "$fn" done