A MusicBrainz client for the music of films and shows: the soundtrack albums named after a title, and their tracks. No key, no playback — each track can become a YouTube search link.
def deps do
[{:musicbrainz, "~> 0.1"}]
end{:ok, albums} = MusicBrainz.albums("Heat", year: 1995)
#=> [%{id: "…", title: "Heat (Music From the Motion Picture)", year: 1995, artist: "Various Artists"},
# %{id: "…", title: "Heat: The Score", year: 1996, artist: "Elliot Goldenthal"}]
{:ok, tracks} = MusicBrainz.tracks(hd(albums).id)
#=> [%{n: 1, title: "Heat", artist: "Elliot Goldenthal feat. Kronos Quartet", secs: 461}, …]
MusicBrainz.youtube(["Elliot Goldenthal", "Heat", "Heat"])
#=> "https://www.youtube.com/results?search_query=Elliot+Goldenthal+Heat"What it picks
MusicBrainz is searched for release groups of secondary type
soundtrack whose name begins with the title's words — a search also
matches on one word, and Body Heat is not Heat's. A film's albums are
those first released within a year of it (year:); a show's span its
seasons, so leave the year out. Oldest first: the original album before its
expanded editions, a show's seasons in order. Other names to try when the
first finds nothing (the original title) go in names:.
An album's tracks are those of its fullest official release, numbered through its discs. An artist credited only in kana is named by the Latin sort name MusicBrainz keeps ("Kanno, Yoko" → "Yoko Kanno"), so a search finds the song.
Being a good client
MusicBrainz is free and asks two things: a user agent that names your application with a way to reach you, and no more than one request a second.
config :musicbrainz, user_agent: "MyApp/1.0 (https://example.com)"Keep the second yourself: cache the answers (albums for a month, tracks for
a year — they do not change). A 503 comes back as {:error, :rate_limited}.
Testing
Every request merges req_options, so point it at Req.Test:
config :musicbrainz, req_options: [plug: {Req.Test, MusicBrainz}]License
MIT © Alexander Don