externalize ArtworkFolder configuration, load any supported image format

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan 2025-02-22 21:28:54 -05:00
parent 9cbea79b11
commit 71543cba27
3 changed files with 21 additions and 9 deletions

View File

@ -66,6 +66,7 @@ type configOptions struct {
FFmpegPath string
MPVPath string
MPVCmdTemplate string
ArtworkFolder string
CoverArtPriority string
CoverJpegQuality int
ArtistArtPriority string
@ -236,6 +237,10 @@ func Load(noConfigDump bool) {
os.Exit(1)
}
if Server.ArtworkFolder == "" {
Server.ArtworkFolder = filepath.Join(Server.DataFolder, "artwork")
}
Server.ConfigFile = viper.GetViper().ConfigFileUsed()
if Server.DbPath == "" {
Server.DbPath = filepath.Join(Server.DataFolder, consts.DefaultDbPath)
@ -452,6 +457,7 @@ func init() {
viper.SetDefault("ffmpegpath", "")
viper.SetDefault("mpvcmdtemplate", "mpv --audio-device=%d --no-audio-display --pause %f --input-ipc-server=%s")
viper.SetDefault("ArtworkFolder", "")
viper.SetDefault("coverartpriority", "cover.*, folder.*, front.*, embedded, external")
viper.SetDefault("coverjpegquality", 75)
viper.SetDefault("artistartpriority", "artist.*, album/artist.*, external")

View File

@ -15,7 +15,10 @@ type mimeConf struct {
Lossless []string `yaml:"lossless"`
}
var LosslessFormats []string
var (
LosslessFormats []string
ValidImageExtensions []string
)
func initMimeTypes() {
// In some circumstances, Windows sets JS mime-type to `text/plain`!
@ -36,6 +39,9 @@ func initMimeTypes() {
}
for ext, typ := range mimeConf.Types {
_ = mime.AddExtensionType(ext, typ)
if strings.HasPrefix(typ, "image/") {
ValidImageExtensions = append(ValidImageExtensions, ext)
}
}
for _, ext := range mimeConf.Lossless {

View File

@ -14,6 +14,7 @@ import (
"github.com/disintegration/imaging"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/conf/mime"
"github.com/navidrome/navidrome/log"
"github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/utils/slice"
@ -57,7 +58,7 @@ func (a *playlistArtworkReader) Reader(ctx context.Context) (io.ReadCloser, stri
func (a *playlistArtworkReader) fromPlaylistNamedCover(ctx context.Context) sourceFunc {
return func() (io.ReadCloser, string, error) {
playlistName := a.pl.Name
imagePath, err := findMatchingImage(playlistName)
imagePath, err := findMatchingImage(ctx, "playlist", playlistName)
if err != nil {
return nil, "", err
}
@ -69,13 +70,12 @@ func (a *playlistArtworkReader) fromPlaylistNamedCover(ctx context.Context) sour
}
}
func findMatchingImage(playlistName string) (string, error) {
extensions := []string{".png", ".jpg", ".jpeg"}
for _, ext := range extensions {
mediaFolder := conf.Server.MusicFolder
path := filepath.Join(mediaFolder, "/customArtwork", playlistName+ext)
if _, err := os.Stat(path); err == nil {
return path, nil
func findMatchingImage(_ context.Context, resource string, name string) (string, error) {
path := filepath.Join(conf.Server.ArtworkFolder, resource, name)
for _, ext := range mime.ValidImageExtensions {
filename := path + ext
if _, err := os.Stat(filename); err == nil {
return filename, nil
}
}
return "", errors.New("no matching image found")