fix: hi-res cover art for Tidal/Qobuz and album metadata override

This commit is contained in:
zarzet
2026-03-25 23:17:45 +07:00
parent 1125c757fe
commit 85d3e58a26
3 changed files with 65 additions and 12 deletions

View File

@@ -17,6 +17,8 @@ const (
// Deezer CDN supports these sizes: 56, 250, 500, 1000, 1400, 1800
var deezerSizeRegex = regexp.MustCompile(`/(\d+)x(\d+)-\d+-\d+-\d+-\d+\.jpg$`)
var tidalSizeRegex = regexp.MustCompile(`/\d+x\d+\.jpg$`)
func convertSmallToMedium(imageURL string) string {
if strings.Contains(imageURL, spotifySize300) {
return strings.Replace(imageURL, spotifySize300, spotifySize640, 1)
@@ -96,6 +98,16 @@ func upgradeToMaxQuality(coverURL string) string {
return upgradeDeezerCover(coverURL)
}
// Tidal CDN upgrade: 1280x1280 → origin
if strings.Contains(coverURL, "resources.tidal.com") {
return upgradeTidalCover(coverURL)
}
// Qobuz CDN upgrade: _600 → _max
if strings.Contains(coverURL, "static.qobuz.com") {
return upgradeQobuzCover(coverURL)
}
return coverURL
}
@@ -111,6 +123,30 @@ func upgradeDeezerCover(coverURL string) string {
return upgraded
}
func upgradeTidalCover(coverURL string) string {
if !strings.Contains(coverURL, "resources.tidal.com") {
return coverURL
}
upgraded := tidalSizeRegex.ReplaceAllString(coverURL, "/origin.jpg")
if upgraded != coverURL {
GoLog("[Cover] Tidal: upgraded to origin resolution")
}
return upgraded
}
func upgradeQobuzCover(coverURL string) string {
if !strings.Contains(coverURL, "static.qobuz.com") {
return coverURL
}
upgraded := qobuzImageSizeRe.ReplaceAllString(coverURL, "_max.jpg")
if upgraded != coverURL {
GoLog("[Cover] Qobuz: upgraded to max resolution")
}
return upgraded
}
func GetCoverFromSpotify(imageURL string, maxQuality bool) string {
if imageURL == "" {
return ""

View File

@@ -262,26 +262,35 @@ func qobuzTrackDisplayTitle(track *QobuzTrack) string {
return fmt.Sprintf("%s (%s)", title, version)
}
var qobuzImageSizeRe = regexp.MustCompile(`_\d+\.jpg$`)
func qobuzUpscaleImageURL(url string) string {
if url == "" {
return ""
}
return qobuzImageSizeRe.ReplaceAllString(url, "_max.jpg")
}
func qobuzTrackAlbumImage(track *QobuzTrack) string {
if track == nil {
return ""
}
return qobuzFirstNonEmpty(
return qobuzUpscaleImageURL(qobuzFirstNonEmpty(
track.Album.Image.Large,
track.Album.Image.Small,
track.Album.Image.Thumbnail,
)
))
}
func qobuzAlbumImage(album *qobuzAlbumDetails) string {
if album == nil {
return ""
}
return qobuzFirstNonEmpty(
return qobuzUpscaleImageURL(qobuzFirstNonEmpty(
album.Image.Large,
album.Image.Small,
album.Image.Thumbnail,
)
))
}
func qobuzTrackArtistID(track *QobuzTrack) string {
@@ -936,7 +945,17 @@ func (q *QobuzDownloader) GetAlbumMetadata(resourceID string) (*AlbumResponsePay
tracks := make([]AlbumTrackMetadata, 0, len(album.Tracks.Items))
for i := range album.Tracks.Items {
tracks = append(tracks, qobuzTrackToAlbumTrackMetadata(&album.Tracks.Items[i]))
track := &album.Tracks.Items[i]
track.Album.ID = album.ID
track.Album.Title = album.Title
track.Album.ReleaseDate = album.ReleaseDateOriginal
track.Album.Image = qobuzImageSet{
Thumbnail: album.Image.Thumbnail,
Small: album.Image.Small,
Large: album.Image.Large,
}
track.Album.TracksCount = album.TracksCount
tracks = append(tracks, qobuzTrackToAlbumTrackMetadata(track))
}
return &AlbumResponsePayload{

View File

@@ -1015,13 +1015,11 @@ func (t *TidalDownloader) GetAlbumMetadata(resourceID string) (*AlbumResponsePay
tracks := make([]AlbumTrackMetadata, 0, len(itemsModule.PagedList.Items))
for _, item := range itemsModule.PagedList.Items {
track := item.Item
if track.Album.ID == 0 {
track.Album.ID = headerModule.Album.ID
track.Album.Title = headerModule.Album.Title
track.Album.Cover = headerModule.Album.Cover
track.Album.ReleaseDate = headerModule.Album.ReleaseDate
track.Album.URL = headerModule.Album.URL
}
track.Album.ID = headerModule.Album.ID
track.Album.Title = headerModule.Album.Title
track.Album.Cover = headerModule.Album.Cover
track.Album.ReleaseDate = headerModule.Album.ReleaseDate
track.Album.URL = headerModule.Album.URL
tracks = append(tracks, tidalTrackToAlbumTrackMetadata(&track))
}