Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c7cf83a1b |
@@ -19,6 +19,42 @@
|
||||
# which is the lesser of two evils vs. corrupting real band names.
|
||||
_PRIMARY_ARTIST_SEP_PATTERN=' / | feat\. | feat | ft\. | ft |; '
|
||||
|
||||
# Read one ID3 text frame (e.g. TPE1, TIT2, TPE2) via mutagen instead of the
|
||||
# `id3v2` CLI. id3v2 is id3lib-3.8.3 (last released 2013) and cannot parse
|
||||
# ID3v2.4 tags at all -- it reports "No ID3 tag" on a file that has complete,
|
||||
# valid tags, just written in the modern version most taggers (Mp3tag,
|
||||
# yt-dlp, foobar2000) default to. That false negative used to send fully-
|
||||
# tagged mp3s to quarantine. Usage: _mp3_tag <file> <frame>
|
||||
_mp3_tag() {
|
||||
python3 - "$1" "$2" 2>/dev/null <<'PY'
|
||||
import sys
|
||||
from mutagen.id3 import ID3
|
||||
try:
|
||||
tags = ID3(sys.argv[1])
|
||||
frame = tags.get(sys.argv[2])
|
||||
print(str(frame) if frame else "")
|
||||
except Exception:
|
||||
print("")
|
||||
PY
|
||||
}
|
||||
|
||||
# Set one ID3 text frame via mutagen, preserving every other frame on the
|
||||
# file. The `id3v2` CLI cannot be used for this: writing even a single frame
|
||||
# with it to a file that already has an ID3v2.4 tag silently drops every
|
||||
# other frame (title, album, genre, date, artwork -- all of it), because
|
||||
# id3lib doesn't understand v2.4 and rewrites the whole tag as v2.3 with only
|
||||
# the frame(s) it was told to set. Usage: _mp3_set_tag <file> <frame> <value>
|
||||
_mp3_set_tag() {
|
||||
python3 - "$1" "$2" "$3" <<'PY'
|
||||
import sys
|
||||
from mutagen.id3 import ID3, Frames
|
||||
tags = ID3(sys.argv[1])
|
||||
frame_cls = Frames[sys.argv[2]]
|
||||
tags.setall(sys.argv[2], [frame_cls(encoding=3, text=[sys.argv[3]])])
|
||||
tags.save(sys.argv[1])
|
||||
PY
|
||||
}
|
||||
|
||||
# For each audio file under $scan_dir that has no ALBUMARTIST tag, set
|
||||
# ALBUMARTIST to the primary artist (everything before the first separator
|
||||
# in the ARTIST tag). Prevents Navidrome from coining ghost album-artists
|
||||
@@ -45,12 +81,12 @@ set_albumartist_fallback() {
|
||||
;;
|
||||
mp3|MP3)
|
||||
local cur_aa artist primary
|
||||
cur_aa=$(id3v2 -l "$file" 2>/dev/null | sed -n 's/^TPE2[^:]*: //p' | head -1)
|
||||
cur_aa=$(_mp3_tag "$file" TPE2)
|
||||
[[ -n "$cur_aa" ]] && continue
|
||||
artist=$(id3v2 -l "$file" 2>/dev/null | sed -n 's/^TPE1[^:]*: //p' | head -1)
|
||||
artist=$(_mp3_tag "$file" TPE1)
|
||||
[[ -z "$artist" ]] && continue
|
||||
primary=$(echo "$artist" | sed -E "s#(${_PRIMARY_ARTIST_SEP_PATTERN}).*##")
|
||||
id3v2 --TPE2 "$primary" "$file" 2>>"$logfile"
|
||||
_mp3_set_tag "$file" TPE2 "$primary" 2>>"$logfile"
|
||||
count=$((count + 1))
|
||||
;;
|
||||
esac
|
||||
@@ -76,8 +112,8 @@ quarantine_untagged() {
|
||||
|
||||
_has_mp3_tags() {
|
||||
local artist title
|
||||
artist=$(id3v2 -l "$1" 2>/dev/null | sed -n 's/^TPE1[^:]*: //p' | head -1)
|
||||
title=$(id3v2 -l "$1" 2>/dev/null | sed -n 's/^TIT2[^:]*: //p' | head -1)
|
||||
artist=$(_mp3_tag "$1" TPE1)
|
||||
title=$(_mp3_tag "$1" TIT2)
|
||||
[[ -n "$artist" && -n "$title" ]]
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user