Load cover art from file directory
This commit adds support for loading cover art from media file directories, according to configured filename priorities (of which an additional, special choice of `embedded` is given). Cover art paths are resolved during scanning and stored in the database as part of the `album.cover_art_path` column; if embedded cover art is matched, this will default to the path of the media file itself, and if no cover art is matched at all. Similarly, the `album.cover_art_id` column will default to a reference to `media_file.id` if embedded cover art is wanted, but if an external cover art file is matched, this will instead be set to a reference to the `album.id` value itself, prefixed with the `al-` constant. Stored cover art paths are once again resolved and matched against configuration when covers are requested; that is, any change in configuration between scanning and requesting cover art may not return correct data until a re-scan is complete. Tests will be added in future commits.
This commit is contained in:
committed by
Deluan Quintão
parent
6563897692
commit
08cd28af2d
+39
-5
@@ -11,6 +11,7 @@ import (
|
||||
_ "image/png"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -91,6 +92,7 @@ func (c *cover) getCoverPath(ctx context.Context, id string) (path string, lastU
|
||||
if found, err = c.ds.Album(ctx).Exists(id); err != nil {
|
||||
return
|
||||
}
|
||||
var coverPath string
|
||||
if found {
|
||||
var al *model.Album
|
||||
al, err = c.ds.Album(ctx).Get(id)
|
||||
@@ -102,15 +104,22 @@ func (c *cover) getCoverPath(ctx context.Context, id string) (path string, lastU
|
||||
return
|
||||
}
|
||||
id = al.CoverArtId
|
||||
coverPath = al.CoverArtPath
|
||||
}
|
||||
var mf *model.MediaFile
|
||||
mf, err = c.ds.MediaFile(ctx).Get(id)
|
||||
if err != nil {
|
||||
if err == nil && mf.HasCoverArt {
|
||||
return mf.Path, mf.UpdatedAt, nil
|
||||
} else if err != nil && coverPath != "" {
|
||||
info, err := os.Stat(coverPath)
|
||||
if err != nil {
|
||||
return "", time.Time{}, model.ErrNotFound
|
||||
}
|
||||
return coverPath, info.ModTime(), nil
|
||||
} else if err != nil {
|
||||
return
|
||||
}
|
||||
if mf.HasCoverArt {
|
||||
return mf.Path, mf.UpdatedAt, nil
|
||||
}
|
||||
|
||||
return "", time.Time{}, model.ErrNotFound
|
||||
}
|
||||
|
||||
@@ -126,7 +135,17 @@ func (c *cover) getCover(ctx context.Context, path string, size int) (reader io.
|
||||
}
|
||||
}()
|
||||
var data []byte
|
||||
data, err = readFromTag(path)
|
||||
for _, p := range strings.Split(conf.Server.CoverArtPriority, ",") {
|
||||
pat := strings.ToLower(strings.TrimSpace(p))
|
||||
if pat == "embedded" {
|
||||
data, err = readFromTag(path)
|
||||
} else if ok, _ := filepath.Match(pat, strings.ToLower(filepath.Base(path))); ok {
|
||||
data, err = readFromFile(path)
|
||||
}
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil && size > 0 {
|
||||
data, err = resizeImage(bytes.NewReader(data), size)
|
||||
@@ -171,6 +190,21 @@ func readFromTag(path string) ([]byte, error) {
|
||||
return picture.Data, nil
|
||||
}
|
||||
|
||||
func readFromFile(path string) ([]byte, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
var buf bytes.Buffer
|
||||
if _, err := buf.ReadFrom(f); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func NewImageCache() (ImageCache, error) {
|
||||
return newFileCache("Image", conf.Server.ImageCacheSize, consts.ImageCacheDir, consts.DefaultImageCacheMaxItems)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user