refactor(server): unify stream URL builders + MIME tables + cover-path helper
test-go / test (push) Successful in 28s
test-go / integration (push) Has been cancelled

Closes Scribe #614, #615, server half of #616 surfaced by the 2026-06-04 divergent-provider audit.

- streamURL helper now used everywhere /api/tracks/{id}/stream is built (was inline concat in playlists.go and cast_token.go); add streamURLWithExt for the .ext cast variant.

- audioContentType in media.go is the canonical file_format -> MIME lookup; mimeForFormat in cast_token.go is now a thin wrapper that overrides the unknown-format fallback to audio/mpeg (Sonos rejects octet-stream). Adds mpeg/vorbis/wave aliases. Subsonic's contentTypeForFormat stays frozen per docs.

- coverart.ResolveAlbumPath extracted; api and subsonic both delegate to it.
This commit is contained in:
2026-06-04 08:29:51 -04:00
parent edd198cdf5
commit 024493f2a7
6 changed files with 69 additions and 62 deletions
+3 -14
View File
@@ -130,21 +130,10 @@ func (m *mediaHandlers) handleGetCoverArt(w http.ResponseWriter, r *http.Request
WriteFail(w, r, ErrDataNotFound, "Cover art not found")
}
// resolveAlbumCoverPath returns the filesystem path to the album's cover art,
// preferring an explicit cover_art_path (set by the scanner in a future
// milestone) and falling back to a sidecar image next to any track in the
// album directory. "" means no art was found.
// resolveAlbumCoverPath delegates to coverart.ResolveAlbumPath; kept as a
// local alias so the call sites in this file read naturally.
func resolveAlbumCoverPath(ctx context.Context, q *dbq.Queries, album dbq.Album) string {
if album.CoverArtPath != nil && *album.CoverArtPath != "" {
if _, err := os.Stat(*album.CoverArtPath); err == nil {
return *album.CoverArtPath
}
}
tracks, err := q.ListTracksByAlbum(ctx, dbq.ListTracksByAlbumParams{AlbumID: album.ID})
if err != nil || len(tracks) == 0 {
return ""
}
return coverart.FindSidecar(filepath.Dir(tracks[0].FilePath))
return coverart.ResolveAlbumPath(ctx, q, album)
}
func serveImage(w http.ResponseWriter, r *http.Request, path string) {