fix: FLAC, Ogg and Opus tracks carry their MusicBrainz recording id from the tag: one reader in library gives the scanner, the backfills and the importer the same ids, and the next scan re-reads the library (#5637)
release / govulncheck (push) Successful in 20s
release / web (push) Successful in 1m30s
release / go (push) Successful in 1m50s
release / integration (push) Successful in 5m19s
release / android (push) Successful in 5m50s
release / Build signed APK (releases and dev) (push) Successful in 6m12s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 16s
release / Verify release artifacts (tag releases only) (push) Skipped

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-11 15:55:25 -04:00
co-authored by Claude Opus 5.5
parent c1305a547d
commit 9e7d50b38e
5 changed files with 109 additions and 76 deletions
+52 -10
View File
@@ -40,7 +40,8 @@ func TestExtractMBIDs_Vorbis(t *testing.T) {
"musicbrainz_artistid": "def",
},
}
a, ar := extractMBIDs(m)
ids := ReadTagMBIDs(m)
a, ar := ids.Release, ids.Artist
if a != "abc" || ar != "def" {
t.Errorf("got (%q, %q), want (\"abc\", \"def\")", a, ar)
}
@@ -62,7 +63,8 @@ func TestExtractMBIDs_ID3v2(t *testing.T) {
},
},
}
a, ar := extractMBIDs(m)
ids := ReadTagMBIDs(m)
a, ar := ids.Release, ids.Artist
if a != "abc-123" || ar != "def-456" {
t.Errorf("got (%q, %q), want (\"abc-123\", \"def-456\")", a, ar)
}
@@ -78,7 +80,8 @@ func TestExtractMBIDs_MP4(t *testing.T) {
"MusicBrainz Artist Id": "def",
},
}
a, ar := extractMBIDs(m)
ids := ReadTagMBIDs(m)
a, ar := ids.Release, ids.Artist
if a != "abc" || ar != "def" {
t.Errorf("got (%q, %q), want (\"abc\", \"def\")", a, ar)
}
@@ -86,7 +89,8 @@ func TestExtractMBIDs_MP4(t *testing.T) {
func TestExtractMBIDs_MissingTagsReturnEmpty(t *testing.T) {
m := stubMeta{format: tag.VORBIS, raw: map[string]interface{}{}}
a, ar := extractMBIDs(m)
ids := ReadTagMBIDs(m)
a, ar := ids.Release, ids.Artist
if a != "" || ar != "" {
t.Errorf("got (%q, %q), want empty", a, ar)
}
@@ -104,7 +108,8 @@ func TestExtractMBIDs_VorbisUppercaseKeysMiss(t *testing.T) {
"MUSICBRAINZ_ARTISTID": "wrong-case",
},
}
a, ar := extractMBIDs(m)
ids := ReadTagMBIDs(m)
a, ar := ids.Release, ids.Artist
if a != "" || ar != "" {
t.Errorf("uppercase Vorbis keys must not match dhowden output; got (%q, %q)", a, ar)
}
@@ -127,7 +132,8 @@ func TestExtractMBIDs_ID3v2StripsTrailingNUL(t *testing.T) {
},
},
}
a, ar := extractMBIDs(m)
ids := ReadTagMBIDs(m)
a, ar := ids.Release, ids.Artist
if a != "abc-123" || ar != "def-456" {
t.Errorf("got (%q, %q), want trailing NUL stripped", a, ar)
}
@@ -146,7 +152,7 @@ func TestExtractMBIDs_ID3v2MultiValueTakesFirst(t *testing.T) {
},
},
}
_, ar := extractMBIDs(m)
ar := ReadTagMBIDs(m).Artist
if ar != "primary-mbid" {
t.Errorf("got %q, want %q", ar, "primary-mbid")
}
@@ -186,17 +192,53 @@ func TestExtractReleaseGroupMBID(t *testing.T) {
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if got := extractReleaseGroupMBID(c.meta); got != "group-1" {
if got := ReadTagMBIDs(c.meta).ReleaseGroup; got != "group-1" {
t.Errorf("release group = %q, want group-1", got)
}
if album, _ := extractMBIDs(c.meta); album != "release-1" {
if album := ReadTagMBIDs(c.meta).Release; album != "release-1" {
t.Errorf("album (release) = %q, want release-1", album)
}
})
}
none := stubMeta{format: tag.VORBIS, raw: map[string]interface{}{"musicbrainz_albumid": "release-1"}}
if got := extractReleaseGroupMBID(none); got != "" {
if got := ReadTagMBIDs(none).ReleaseGroup; got != "" {
t.Errorf("untagged release group = %q, want empty", got)
}
}
// #5637: each format's recording id lands in Recording, and the release-track
// id never does. Picard calls the recording MUSICBRAINZ_TRACKID in Vorbis
// comments, the name mbz gives the release track.
func TestReadTagMBIDs_Recording(t *testing.T) {
cases := []struct {
name string
meta stubMeta
}{
{"vorbis", stubMeta{format: tag.VORBIS, raw: map[string]interface{}{
"musicbrainz_trackid": "rec-1",
"musicbrainz_releasetrackid": "reltrack-1",
}}},
{"id3v2 ufid", stubMeta{format: tag.ID3v2_4, raw: map[string]interface{}{
"UFID": &tag.UFID{Provider: "http://musicbrainz.org", Identifier: []byte("rec-1")},
"TXXX_0": &tag.Comm{Description: "MusicBrainz Release Track Id", Text: "reltrack-1\x00"},
}}},
{"mp4", stubMeta{format: tag.MP4, raw: map[string]interface{}{
"MusicBrainz Track Id": "rec-1",
"MusicBrainz Release Track Id": "reltrack-1",
}}},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if got := ReadTagMBIDs(c.meta).Recording; got != "rec-1" {
t.Errorf("recording = %q, want rec-1", got)
}
})
}
// A Vorbis file carrying only the release-track id has no recording id.
only := stubMeta{format: tag.VORBIS, raw: map[string]interface{}{"musicbrainz_releasetrackid": "reltrack-1"}}
if got := ReadTagMBIDs(only).Recording; got != "" {
t.Errorf("release track only: recording = %q, want empty", got)
}
}