fix album-level tag consistency for mixed-artist tracks

Use album artist overrides during album ripping so compilation-style tracks do not change album performer tags, and add safer disc-number fallbacks for metadata/path generation when providers omit disc fields.
This commit is contained in:
2026-04-20 00:59:10 +02:00
parent b2688ce949
commit b5a5368fa8
2 changed files with 70 additions and 2 deletions

View File

@@ -39,6 +39,7 @@ type Main struct {
type ripTrackOptions struct {
albumFolder string
albumEmbedCover string
albumArtist string
index int
total int
albumDiscTotal int
@@ -498,7 +499,7 @@ func (m *Main) ripAlbum(ctx context.Context, p provider.Client, source, albumID
if !m.Config.Session.Downloads.Concurrency || m.Config.Session.Downloads.MaxConnections == 1 {
for i, trackID := range trackIDs {
opts := ripTrackOptions{albumFolder: folder, albumEmbedCover: artRes.EmbedPath, index: i + 1, total: total, albumDiscTotal: discTotal}
opts := ripTrackOptions{albumFolder: folder, albumEmbedCover: artRes.EmbedPath, albumArtist: albumArtist, index: i + 1, total: total, albumDiscTotal: discTotal}
if err := m.ripTrack(ctx, p, source, trackID, "", opts); err != nil {
failures++
m.logf("track failed: id=%s reason=%v\n", trackID, err)
@@ -523,7 +524,7 @@ func (m *Main) ripAlbum(ctx context.Context, p provider.Client, source, albumID
go func(idx int, tid string) {
defer wg.Done()
defer func() { <-sem }()
opts := ripTrackOptions{albumFolder: folder, albumEmbedCover: artRes.EmbedPath, index: idx, total: total, albumDiscTotal: discTotal}
opts := ripTrackOptions{albumFolder: folder, albumEmbedCover: artRes.EmbedPath, albumArtist: albumArtist, index: idx, total: total, albumDiscTotal: discTotal}
if err := m.ripTrack(ctx, p, source, tid, "", opts); err != nil {
errCh <- err
}
@@ -836,6 +837,15 @@ func (m *Main) trackOutputPath(source, id, title, ext string, trackMeta map[stri
base = albumFolder
if m.Config.Session.Downloads.DiscSubdirectories && albumDiscTotal > 1 {
discNumber := intFromAny(trackMeta["media_number"])
if discNumber == 0 {
discNumber = intFromAny(trackMeta["volumeNumber"])
}
if discNumber == 0 {
discNumber = intFromAny(trackMeta["disk_number"])
}
if discNumber == 0 {
discNumber = 1
}
if discNumber > 0 {
base = filepath.Join(base, "Disc "+strconv.Itoa(discNumber))
}
@@ -1012,6 +1022,9 @@ func buildTagMetadata(trackMeta map[string]any, title, source, trackID string, o
if albumArtist == "" {
albumArtist = artist
}
if strings.TrimSpace(opts.albumArtist) != "" {
albumArtist = strings.TrimSpace(opts.albumArtist)
}
trackNumber := intFromAny(trackMeta["track_number"])
if trackNumber == 0 {
trackNumber = intFromAny(trackMeta["trackNumber"])
@@ -1020,6 +1033,9 @@ func buildTagMetadata(trackMeta map[string]any, title, source, trackID string, o
if discNumber == 0 {
discNumber = intFromAny(trackMeta["volumeNumber"])
}
if discNumber == 0 {
discNumber = intFromAny(trackMeta["disk_number"])
}
date := stringFromAny(trackMeta["release_date_original"])
if date == "" {
date = stringFromAny(trackMeta["release_date"])
@@ -1046,9 +1062,15 @@ func buildTagMetadata(trackMeta map[string]any, title, source, trackID string, o
if discTotal == 0 {
discTotal = intFromAny(trackMeta["numberOfVolumes"])
}
if discTotal == 0 && opts.albumDiscTotal > 0 {
discTotal = opts.albumDiscTotal
}
if opts.forPlaylist {
discTotal = 1
}
if !opts.forPlaylist && discNumber == 0 {
discNumber = 1
}
genre := nestedString(trackMeta, "genre", "name")
if genre == "" {