Search Deezer and MusicBrainz together; add preview clips
Search
- Albums and songs search Deezer and MusicBrainz at once and merge the
results: duplicates keep the Deezer copy, best word matches first.
Deezer's search misses albums it carries (Death Magnetic) and most game
soundtracks; MusicBrainz finds them
- MusicBrainz secondary types are shown ("Soundtrack", "Live")
- Settings: Deezer + MusicBrainz (default), Deezer only, MusicBrainz only
- Search results show which service they came from
Previews
- Songs and albums get a play button (cards, rows, detail view, editor,
and Deezer search results) for a 30-second Deezer clip; albums play
their most popular track
- Clips are looked up fresh (Deezer URLs expire), cached 10 minutes, and
streamed through Canon with Range support; hidden lists stay private
- Entries from MusicBrainz or added by hand are matched to Deezer on save
so they can preview too
- "Play previews" toggle in Settings → Profile
Tests cover merging and title/artist matching; `-tags live` runs checks
against the real services.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6d92b46130
commit
b09533cc00
20 files changed
+736
-19
No files matched your search
@@ -134,6 +134,9 @@ func (d *deezer) Search(ctx context.Context, query string) ([]Result, error) {
|
||||
}
|
||||
|
||||
func (d *deezer) Details(ctx context.Context, res Result) (Result, error) {
|
||||
if res.Provider != "deezer" {
|
||||
return res, nil
|
||||
}
|
||||
kind, id, _ := strings.Cut(res.ProviderID, ":")
|
||||
if res.Extra == nil {
|
||||
res.Extra = map[string]string{}
|
||||
@@ -206,6 +209,7 @@ func (m *musicbrainz) Search(ctx context.Context, query string) ([]Result, error
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
PrimaryType string `json:"primary-type"`
|
||||
SecondaryTypes []string `json:"secondary-types"`
|
||||
FirstReleaseDate string `json:"first-release-date"`
|
||||
ArtistCredit []mbCredit `json:"artist-credit"`
|
||||
} `json:"release-groups"`
|
||||
@@ -225,8 +229,13 @@ func (m *musicbrainz) Search(ctx context.Context, query string) ([]Result, error
|
||||
ExternalURL: "https://musicbrainz.org/release-group/" + rg.ID,
|
||||
Extra: map[string]string{},
|
||||
}
|
||||
// e.g. "Soundtrack", "Live", "EP · Soundtrack"
|
||||
types := rg.SecondaryTypes
|
||||
if rg.PrimaryType != "" && rg.PrimaryType != "Album" {
|
||||
r.Extra["type"] = rg.PrimaryType
|
||||
types = append([]string{rg.PrimaryType}, types...)
|
||||
}
|
||||
if len(types) > 0 {
|
||||
r.Extra["type"] = strings.Join(types, " · ")
|
||||
}
|
||||
out = append(out, r)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user