fix(library): read every genre of FLAC, Ogg, Opus and MP4 files (#2500)
release / govulncheck (push) Successful in 50s
release / web (push) Successful in 2m3s
release / go (push) Successful in 2m18s
release / integration (push) Successful in 5m42s
release / android (push) Successful in 6m30s
release / Build signed APK (releases and dev) (push) Successful in 6m0s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 1m20s
release / Verify release artifacts (tag releases only) (push) Skipped
release / govulncheck (push) Successful in 50s
release / web (push) Successful in 2m3s
release / go (push) Successful in 2m18s
release / integration (push) Successful in 5m42s
release / android (push) Successful in 6m30s
release / Build signed APK (releases and dev) (push) Successful in 6m0s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 1m20s
release / Verify release artifacts (tag releases only) (push) Skipped
Vorbis comments repeat a field to give it several values (GENRE=Boom Bap, GENRE=Downtempo, ...). dhowden/tag keeps comments in a map keyed by field name, so each repeat overwrote the previous one and only the last genre was stored. MP4 has the same gap: several data atoms in one ©gen atom, or repeated ©gen atoms, collapse to one value. On the operator's library 3,658 of 4,092 FLACs declare more than one genre. Kupla's Life Forms carries eight and was stored as "Instrumental Hip Hop" alone, so browse and the taste profile never saw the other seven. - vorbisgenre.go reads the comment block directly: FLAC's metadata block (including FLACs behind an ID3v2 tag), and the comment packet of Ogg Vorbis and Opus, reassembled across pages when cover art makes it span several. - mp4genre.go walks moov > udta > meta > ilst and returns every ©gen text value. It handles ISO and QuickTime meta layouts and a moov placed after mdat. A file with only the numeric gnre atom still falls back to dhowden, which resolves it. - extractGenres routes VORBIS and MP4 through them, as #2499 did for ID3v2. - tagReadVersion 3 -> 4, so the next scan re-reads the tags of files already indexed. Unchanged files keep their duration and fingerprint, so the pass costs tag reads only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,11 +32,25 @@ func extractGenres(meta tag.Metadata, rs io.ReadSeeker) (genres []string, fellBa
|
||||
// No frame at all is the common case for untagged files, and
|
||||
// dhowden/tag will have nothing either — not worth flagging.
|
||||
fellBack = meta.Genre() != ""
|
||||
default:
|
||||
// Vorbis comments (FLAC/OGG/Opus) and MP4 atoms don't go through
|
||||
// dhowden's welding path, so its value is already a faithful read of
|
||||
// the primary genre. Multi-value handling for those containers is a
|
||||
// separate, unproven concern — see #2500.
|
||||
case tag.VORBIS, tag.MP4:
|
||||
// dhowden/tag keeps only the last of a repeated field here (#2500):
|
||||
// see vorbisgenre.go and mp4genre.go.
|
||||
var values []string
|
||||
var err error
|
||||
switch {
|
||||
case meta.Format() == tag.MP4:
|
||||
values, err = readMP4GenreValues(rs)
|
||||
case meta.FileType() == tag.OGG:
|
||||
values, err = readOggGenreValues(rs)
|
||||
default:
|
||||
values, err = readFLACGenreValues(rs)
|
||||
}
|
||||
if err == nil && len(values) > 0 {
|
||||
return normaliseGenres(values), false
|
||||
}
|
||||
// err == nil with no values: the file declares no genre of its own
|
||||
// (or, for MP4, only the numeric gnre atom, which dhowden resolves).
|
||||
fellBack = err != nil && meta.Genre() != ""
|
||||
}
|
||||
return normaliseGenres([]string{meta.Genre()}), fellBack
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user