Skip to content

Instantly share code, notes, and snippets.

@YellowApple
Created October 19, 2021 22:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YellowApple/7b9cc54cf6fbc20bf79cf2408b7f550d to your computer and use it in GitHub Desktop.
Save YellowApple/7b9cc54cf6fbc20bf79cf2408b7f550d to your computer and use it in GitHub Desktop.
ID3-Tag-Inator: Automatically populates ID3 tags for all MP3 files in the Tri-State Area
#!/bin/sh
SELF=$(basename $0)
usage () {
echo "usage: $SELF [-dfhv] [basedir]"
}
help () {
echo "\
ID3-Tag-inator: Automatically populates ID3 tags for all MP3 files in the
Tri-State Area."
usage
echo '
Options:
-d
Dry run (output ID3-editing commands instead of running them)
-f
Force updating ID3 tags even if they are already set
-h
This help screen
-v
Verbose output
Parameters:
basedir
A directory with subdirectories for each artist, each with
subdirectories for each album, each with MP3 files; defaults to the
current directory
Notes:
Artist, album, and title values are derived from the folder and file names
ID3-Tag-inator encounters, which no attempt to clean them up. It is up to
the user to rename the corresponding folders and files accordingly
beforehand.
Only MP3 files are supported, and their filenames must end in .mp3.
Copyright (C) 2021 Ryan S. Northrup ("RyNo") <northrup@yellowapple.us>
Permission to use, copy, modify, and distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice
and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.'
exit 0
}
badopt () {
echo "unknown option -- $1"
usage
exit 1
}
dep_not_found () {
echo "$1 not found; exiting."
exit 1
}
check_dep () {
which $1 >/dev/null 2>&1 || dep_not_found $1
}
verbose () {
test $VERBOSE -gt 0
}
dryrun () {
test $DRYRUN -gt 0
}
force () {
test $FORCE -gt 0
}
tag_is_unset () {
test -z "$(echo $1 | grep $2)"
}
current_tags () {
id3v2 -l "$1"
}
process_artist () {
ARTIST="$1"
verbose && echo "ARTIST: '$ARTIST'"
cd "$ARTIST"
pwd
for ALBUM in */; do
ALBUM=${ALBUM%*/}
process_album "$ALBUM" "$ARTIST"
done
cd ..
verbose && echo "================"
}
process_album () {
ALBUM="$1"
ARTIST="$2"
verbose && echo "ALBUM: '$ALBUM'"
cd "$ALBUM"
pwd
for TITLE in *.mp3; do
TITLE=${TITLE%*.mp3}
process_song "$TITLE" "$ALBUM" "$ARTIST"
done
cd ..
verbose && echo "----------------"
}
process_song () {
TITLE="$1"
ALBUM="$2"
ARTIST="$3"
CURRENT_TAGS=`current_tags "$TITLE.mp3"`
verbose && echo "PROCESS '$TITLE.mp3':"
COMMAND="id3v2"
if (force || tag_is_unset "$CURRENT_TAGS" TIT2); then
COMMAND="$COMMAND -t \"$TITLE\""
verbose && echo " SET title (TIT2): \"$TITLE\""
else
verbose && echo " SKIP title (TIT2); already set"
fi
if (force || tag_is_unset "$CURRENT_TAGS" TALB); then
COMMAND="$COMMAND -A \"$ALBUM\""
verbose && echo " SET album (TALB): \"$ALBUM\""
else
verbose && echo " SKIP album (TALB); already set"
fi
if (force || tag_is_unset "$CURRENT_TAGS" TPE1); then
COMMAND="$COMMAND -a \"$ARTIST\""
verbose && echo " SET artist (TPE1): \"$ARTIST\""
else
verbose && echo " SKIP artist (TPE1); already set"
fi
COMMAND="$COMMAND \"$TITLE.mp3\" >/dev/null 2>&1"
if dryrun; then
echo $COMMAND
else
eval "$COMMAND"
fi
}
VERBOSE=0
DRYRUN=0
FORCE=0
while getopts ":vdfh" arg; do
case $arg in
v)
VERBOSE=1
;;
d)
DRYRUN=1
;;
f)
FORCE=1
;;
h)
help
;;
*)
badopt $OPTARG
;;
esac
done
shift $((OPTIND-1))
check_dep id3v2
BASEPATH=${1:-.}
verbose && echo "Parameters:"
verbose && echo " BASEPATH: $BASEPATH"
verbose && echo " VERBOSE: $VERBOSE"
verbose && echo " DRYRUN: $DRYRUN"
verbose && echo " FORCE: $FORCE"
cd "$BASEPATH"
for ARTIST in */; do
pwd
ARTIST=${ARTIST%*/}
process_artist "$ARTIST"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment