diff --git a/internal/api/media.go b/internal/api/media.go index 8f496d80..4d5591ca 100644 --- a/internal/api/media.go +++ b/internal/api/media.go @@ -17,30 +17,10 @@ import ( "github.com/go-chi/chi/v5" "github.com/jackc/pgx/v5" + "git.fabledsword.com/bvandeusen/minstrel/internal/coverart" "git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq" ) -// sidecarNames is the lookup order for cover art living next to audio files. -// Matches common library conventions: cover.* wins over folder.*; JPEG wins -// over PNG when both exist. -var sidecarNames = []string{ - "cover.jpg", "cover.jpeg", "cover.png", - "folder.jpg", "folder.jpeg", "folder.png", -} - -// findSidecarCover looks for a conventional cover image in the directory that -// contains trackPath. Returns "" if no sidecar exists. -func findSidecarCover(trackPath string) string { - dir := filepath.Dir(trackPath) - for _, name := range sidecarNames { - candidate := filepath.Join(dir, name) - if info, err := os.Stat(candidate); err == nil && !info.IsDir() { - return candidate - } - } - return "" -} - // resolveAlbumCoverPath returns the filesystem path to the album's cover art. // It prefers an explicit cover_art_path (set by the scanner in a future // milestone) and falls back to a sidecar next to the first track in the @@ -55,7 +35,7 @@ func resolveAlbumCoverPath(ctx context.Context, q *dbq.Queries, album dbq.Album) if err != nil || len(tracks) == 0 { return "" } - return findSidecarCover(tracks[0].FilePath) + return coverart.FindSidecar(filepath.Dir(tracks[0].FilePath)) } // audioContentType maps the short file_format recorded on tracks (mp3, flac, diff --git a/internal/subsonic/stream.go b/internal/subsonic/stream.go index 8aad9342..3a62b278 100644 --- a/internal/subsonic/stream.go +++ b/internal/subsonic/stream.go @@ -15,6 +15,7 @@ import ( "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" + "git.fabledsword.com/bvandeusen/minstrel/internal/coverart" "git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq" "git.fabledsword.com/bvandeusen/minstrel/internal/playevents" ) @@ -143,28 +144,7 @@ func resolveAlbumCoverPath(ctx context.Context, q *dbq.Queries, album dbq.Album) if err != nil || len(tracks) == 0 { return "" } - return findSidecarCover(tracks[0].FilePath) -} - -// sidecarNames are the conventional names for album art living next to audio -// files. Order matches how most library tools write them — cover.* wins over -// folder.*, and JPEG wins over PNG when both are present. -var sidecarNames = []string{ - "cover.jpg", "cover.jpeg", "cover.png", - "folder.jpg", "folder.jpeg", "folder.png", -} - -// findSidecarCover looks for a cover image in the directory containing the -// given track file. Returns "" if no sidecar exists. -func findSidecarCover(trackPath string) string { - dir := filepath.Dir(trackPath) - for _, name := range sidecarNames { - candidate := filepath.Join(dir, name) - if info, err := os.Stat(candidate); err == nil && !info.IsDir() { - return candidate - } - } - return "" + return coverart.FindSidecar(filepath.Dir(tracks[0].FilePath)) } func serveImage(w http.ResponseWriter, r *http.Request, path string) {