beetbox / beets

music library manager and MusicBrainz tagger
http://beets.io/
MIT License
12.72k stars 1.81k forks source link

Expose playlists within web API #5037

Closed mgoltzsche closed 3 months ago

mgoltzsche commented 9 months ago

I am using mopidy with the mopidy-beets plugin to play music that it streams from a beets web server that runs on another machine. However, while mopidy-beets lets me search for tracks and browse albums, unfortunately it doesn't let me access playlists (probably because the beets web API doesn't expose them). On the other hand, using beets' smartplaylist plugin, I have defined rules to generate playlists within my beets config under smartplaylist.playlists already. Now ideally I'd like to browse those playlists within mopidy. One way to do that could be to enhance the mopidy-beets plugin to be able to configure the same rules as for the smartplaylist beets plugin. However, that would require users to duplicate the playlist configuration and maintain it in two different places. Instead, to maintain the playlist configuration in a single/central place, the beets web API could expose the playlists defined by the smartplaylist plugin's configuration. Alternatively, there could be a separate object introduced within the beets config to define playlists and both the web and smartplaylist plugin would obtain their configuration also from that configuration object. Either way, clients such as mopidy-beets could be enhanced to provide more useful and individual/personalized ways of browsing a beets library using the playlists defined within that library.

Proposed solution

Let the beets web API expose the playlists defined by the existing smartplaylist.playlists beets configuration. Two new GET endpoints should be added that each return a JSON response:

Example response body of the /playlist/ endpoint:

{
  "playlists": [
    {
      "name": "jazz.m3u"
    },
  ]
}

Example response body of the /playlist/{name} endpoint:

{
  "items": [
    {
      "id": 1,
      "title": "Bag's Groove",
      "artist": "Miles Davis",
      ...
    },
    ...
  ]
}

Objective

Allow remote clients to easily access the playlists defined within the beets library.

Goals

Expose the playlists that can be defined and generated using the smartplaylist plugin within the beets web API.

Non-goals

Anti-goals

sampsyo commented 9 months ago

The proposed API looks perfectly reasonable! Thanks for the detailed proposal.

Although mopidy-beets doesn't support it yet, I also want to point you toward the AURA plugin, which is meant to be a successor to the web UI plugin that prioritizes a flexible API over use from our little web interface.

mgoltzsche commented 9 months ago

The AURA API looks interesting but it doesn't expose playlists either, does it?

sampsyo commented 9 months ago

Ah, yes, indeed—sorry for not being clear. It doesn't support playlists either, but I brought it up just to point to a place where we might want to focus long-term efforts on evolving the API. It's sort of an academic point, however, since stuff like beets-mopidy only supports the "old" web API.

mgoltzsche commented 9 months ago

Okay, I created a corresponding issue within the AURA API repo now: https://github.com/beetbox/aura/issues/31

sampsyo commented 9 months ago

Awesome; thanks!!

mgoltzsche commented 3 months ago

There is an alternative now: the webm3u plugin can be used to serve M3U playlists (generated by the smartplaylist plugin) via HTTP. The plugin also allows to specify a playlist item URI template as HTTP request parameter (uri-format) in order to be able to let another integration take care of loading the contained songs efficiently. E.g. to access the playlists from your Beets library on another host within Mopidy, you can let the Mopidy-WebM3U plugin delegate to the Mopidy-Beets plugin to load the songs contained within playlists by configuring a seed M3U playlist URL (that points to a webm3u server) with the parameter uri-format=beets:library:track;$id. Something similar could be done using the AURA API potentially in the future.