fix: handle ID3v2 TXXX frames and UFID in MBID extraction
The dhowden/tag library returns ID3v2 TXXX frames as *tag.Comm structs (key='TXXX_N', Description='MusicBrainz Artist Id', Text='uuid'), not plain strings. Vorbis comments are plain strings (key='musicbrainz_artistid', value='uuid'). Previous code only handled the string case — all MP3 files silently got empty MBIDs. Now handles three value types: - string: Vorbis comments (FLAC/OGG) — key is the tag name - *tag.Comm: ID3v2 TXXX frames (MP3) — Description is the tag name - *tag.UFID: ID3v2 UFID frame (MP3) — MusicBrainz recording ID Requires a full rescan to backfill MBIDs for MP3 files.
This commit is contained in:
@@ -125,18 +125,37 @@ var mbidTagKeys = map[string][]string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extractMBIDs populates the MBID fields of meta from the raw tag
|
// extractMBIDs populates the MBID fields of meta from the raw tag
|
||||||
// map. Handles varying key names across ID3v2, Vorbis, and MP4.
|
// map. Handles both Vorbis comments (plain string values with
|
||||||
|
// lowercase keys) and ID3v2 TXXX frames (*tag.Comm values with
|
||||||
|
// TXXX_N keys and the tag name in the Description field).
|
||||||
func extractMBIDs(raw map[string]interface{}, meta *TrackMetadata) {
|
func extractMBIDs(raw map[string]interface{}, meta *TrackMetadata) {
|
||||||
if len(raw) == 0 {
|
if len(raw) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a lowercased key → value map for case-insensitive lookup.
|
// Build a lowercased description → value map that works for
|
||||||
|
// both formats:
|
||||||
|
// Vorbis: key="musicbrainz_artistid", value="uuid" (string)
|
||||||
|
// ID3v2: key="TXXX_13", value=*tag.Comm{Description:"MusicBrainz Artist Id", Text:"uuid"}
|
||||||
normalized := make(map[string]string, len(raw))
|
normalized := make(map[string]string, len(raw))
|
||||||
|
|
||||||
for k, v := range raw {
|
for k, v := range raw {
|
||||||
if s, ok := v.(string); ok {
|
switch val := v.(type) {
|
||||||
normalized[strings.ToLower(k)] = s
|
case string:
|
||||||
|
// Vorbis comments — key is the tag name.
|
||||||
|
normalized[strings.ToLower(k)] = val
|
||||||
|
|
||||||
|
case *tag.Comm:
|
||||||
|
// ID3v2 TXXX frames — Description is the tag name.
|
||||||
|
if val != nil && val.Description != "" {
|
||||||
|
normalized[strings.ToLower(val.Description)] = strings.TrimSpace(val.Text)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *tag.UFID:
|
||||||
|
// ID3v2 UFID frame — MusicBrainz recording ID.
|
||||||
|
if val != nil && val.Provider == "http://musicbrainz.org" {
|
||||||
|
meta.RecordingMBID = strings.TrimSpace(string(val.Identifier))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user