mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-12 02:37:18 +02:00
feat(extensions): embed full metadata and cover after extension downloads
Replace duplicate genre/label-only embedding with a shared post-download step that writes complete FLAC tags and optional cover art when the output file is available locally.
This commit is contained in:
1 parent
5f11f5b114
commit
2b8ec744dd
1 file changed
+74
-18
@@ -2602,15 +2602,7 @@ func DownloadWithExtensionFallback(req DownloadRequest) (*DownloadResponse, erro
|
|||||||
resp.Composer = req.Composer
|
resp.Composer = req.Composer
|
||||||
}
|
}
|
||||||
|
|
||||||
if !alreadyExists && req.EmbedMetadata && (req.Genre != "" || req.Label != "") && canEmbedGenreLabel(normalizedResult.FilePath) {
|
embedExtensionDownloadMetadata(resp, req, alreadyExists)
|
||||||
if err := EmbedGenreLabel(normalizedResult.FilePath, req.Genre, req.Label); err != nil {
|
|
||||||
GoLog("[DownloadWithExtensionFallback] Warning: failed to embed genre/label: %v\n", err)
|
|
||||||
} else {
|
|
||||||
GoLog("[DownloadWithExtensionFallback] Embedded genre=%q label=%q\n", req.Genre, req.Label)
|
|
||||||
}
|
|
||||||
} else if !alreadyExists && req.EmbedMetadata && (req.Genre != "" || req.Label != "") {
|
|
||||||
GoLog("[DownloadWithExtensionFallback] Skipping genre/label embed for non-local output path: %q\n", normalizedResult.FilePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !alreadyExists && !isFDOutput(req.OutputFD) && strings.TrimSpace(req.OutputDir) != "" {
|
if !alreadyExists && !isFDOutput(req.OutputFD) && strings.TrimSpace(req.OutputDir) != "" {
|
||||||
indexISRC := strings.TrimSpace(resp.ISRC)
|
indexISRC := strings.TrimSpace(resp.ISRC)
|
||||||
@@ -2808,15 +2800,7 @@ func DownloadWithExtensionFallback(req DownloadRequest) (*DownloadResponse, erro
|
|||||||
}
|
}
|
||||||
applyExtensionRequestFallbacks(&resp, req)
|
applyExtensionRequestFallbacks(&resp, req)
|
||||||
|
|
||||||
if !alreadyExists && req.EmbedMetadata && (req.Genre != "" || req.Label != "") && canEmbedGenreLabel(normalizedResult.FilePath) {
|
embedExtensionDownloadMetadata(resp, req, alreadyExists)
|
||||||
if err := EmbedGenreLabel(normalizedResult.FilePath, req.Genre, req.Label); err != nil {
|
|
||||||
GoLog("[DownloadWithExtensionFallback] Warning: failed to embed genre/label: %v\n", err)
|
|
||||||
} else {
|
|
||||||
GoLog("[DownloadWithExtensionFallback] Embedded genre=%q label=%q\n", req.Genre, req.Label)
|
|
||||||
}
|
|
||||||
} else if !alreadyExists && req.EmbedMetadata && (req.Genre != "" || req.Label != "") {
|
|
||||||
GoLog("[DownloadWithExtensionFallback] Skipping genre/label embed for non-local output path: %q\n", normalizedResult.FilePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !alreadyExists && !isFDOutput(req.OutputFD) && strings.TrimSpace(req.OutputDir) != "" {
|
if !alreadyExists && !isFDOutput(req.OutputFD) && strings.TrimSpace(req.OutputDir) != "" {
|
||||||
indexISRC := strings.TrimSpace(resp.ISRC)
|
indexISRC := strings.TrimSpace(resp.ISRC)
|
||||||
@@ -3008,6 +2992,78 @@ func canEmbedGenreLabel(filePath string) bool {
|
|||||||
return err == nil && !info.IsDir() && info.Size() > 0
|
return err == nil && !info.IsDir() && info.Size() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func embedExtensionDownloadMetadata(resp DownloadResponse, req DownloadRequest, alreadyExists bool) {
|
||||||
|
if alreadyExists || !req.EmbedMetadata {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := strings.TrimSpace(resp.FilePath)
|
||||||
|
if !canEmbedGenreLabel(filePath) {
|
||||||
|
if req.Genre != "" || req.Label != "" || resp.CoverURL != "" || req.CoverURL != "" {
|
||||||
|
GoLog("[DownloadWithExtensionFallback] Skipping metadata/cover embed for non-local FLAC output path: %q\n", filePath)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
coverURL := firstNonEmptyTrimmed(resp.CoverURL, req.CoverURL)
|
||||||
|
var coverData []byte
|
||||||
|
if coverURL != "" {
|
||||||
|
data, err := downloadCoverToMemory(coverURL, req.EmbedMaxQualityCover)
|
||||||
|
if err != nil {
|
||||||
|
GoLog("[DownloadWithExtensionFallback] Warning: failed to download cover for metadata embed: %v\n", err)
|
||||||
|
} else if len(data) > 0 {
|
||||||
|
coverData = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata := Metadata{
|
||||||
|
Title: firstNonEmptyTrimmed(resp.Title, req.TrackName),
|
||||||
|
Artist: firstNonEmptyTrimmed(resp.Artist, req.ArtistName),
|
||||||
|
Album: firstNonEmptyTrimmed(resp.Album, req.AlbumName),
|
||||||
|
AlbumArtist: firstNonEmptyTrimmed(resp.AlbumArtist, req.AlbumArtist),
|
||||||
|
ArtistTagMode: req.ArtistTagMode,
|
||||||
|
Date: firstNonEmptyTrimmed(resp.ReleaseDate, req.ReleaseDate),
|
||||||
|
TrackNumber: firstPositiveInt(resp.TrackNumber, req.TrackNumber),
|
||||||
|
TotalTracks: firstPositiveInt(resp.TotalTracks, req.TotalTracks),
|
||||||
|
DiscNumber: firstPositiveInt(resp.DiscNumber, req.DiscNumber),
|
||||||
|
TotalDiscs: firstPositiveInt(resp.TotalDiscs, req.TotalDiscs),
|
||||||
|
ISRC: firstNonEmptyTrimmed(resp.ISRC, req.ISRC),
|
||||||
|
Genre: firstNonEmptyTrimmed(resp.Genre, req.Genre),
|
||||||
|
Label: firstNonEmptyTrimmed(resp.Label, req.Label),
|
||||||
|
Copyright: firstNonEmptyTrimmed(resp.Copyright, req.Copyright),
|
||||||
|
Composer: firstNonEmptyTrimmed(resp.Composer, req.Composer),
|
||||||
|
}
|
||||||
|
if req.EmbedLyrics {
|
||||||
|
metadata.Lyrics = resp.LyricsLRC
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
if len(coverData) > 0 {
|
||||||
|
err = EmbedMetadataWithCoverData(filePath, metadata, coverData)
|
||||||
|
} else {
|
||||||
|
err = EmbedMetadata(filePath, metadata, "")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
GoLog("[DownloadWithExtensionFallback] Warning: failed to embed metadata/cover: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(coverData) > 0 {
|
||||||
|
GoLog("[DownloadWithExtensionFallback] Embedded metadata and cover from %q\n", coverURL)
|
||||||
|
} else {
|
||||||
|
GoLog("[DownloadWithExtensionFallback] Embedded metadata without cover\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func firstPositiveInt(values ...int) int {
|
||||||
|
for _, value := range values {
|
||||||
|
if value > 0 {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
func (p *extensionProviderWrapper) CustomSearch(query string, options map[string]interface{}) ([]ExtTrackMetadata, error) {
|
func (p *extensionProviderWrapper) CustomSearch(query string, options map[string]interface{}) ([]ExtTrackMetadata, error) {
|
||||||
return p.customSearch(query, options, "", "")
|
return p.customSearch(query, options, "", "")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user