mirror of
https://github.com/librespot-org/librespot.git
synced 2026-04-27 08:15:50 +03:00
[GH-ISSUE #57] Support for Spotify Radio/Dynamic Playlists (Context Support) #46
Labels
No labels
A-Alsa
SpotifyAPI
Tokio 1.0
audio
bug
can't reproduce
compilation
dependencies
duplicate
enhancement
good first issue
help wanted
high priority
imported
imported
invalid
new api
pull-request
question
reverse engineering
wiki
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/librespot#46
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @sashahilton00 on GitHub (Jan 29, 2018).
Original GitHub issue: https://github.com/librespot-org/librespot/issues/57
Friday May 12, 2017 at 16:48 GMT
Originally opened as https://github.com/plietar/librespot/issues/184
Since forever I've noticed that when playing spotify Radio (launching it from an official spotify android client or from a linux client), librespot will play about ten songs and then it will restart from the first song, instead of continuing to pull new songs to play from the "dynamic playlist".
This indeed seems to be a librespot problem with dynamic playlists (that keep adding content forever). If one plays the media locally, then the client continues adding new content to the dynamic playlist and never repeats a song.
There is a long issue thread in spotify's support site, people complaining that their SpotifyConnect speakers will behave as described above. However, recently spotify people advised that this is not an issue with the Spotify Client, but an issue with very old firmware in the SpotifyConnect / speakers i.e. librespot.
Here's the thread.
https://community.spotify.com/t5/Ongoing-Issues/Radio-not-loading-more-songs-when-using-Spotify-Connect/idc-p/1673495#M42870
Hereby the request to have librespot support spotify's dynamic playlists including Radio
@sashahilton00 commented on GitHub (Jan 29, 2018):
Friday May 12, 2017 at 17:00 GMT
I'm not sure radio support has been implemented yet. I assume this is happening because librespot just receives the seed track list and doesn't listen/poll for updates to the song radio?
@sashahilton00 commented on GitHub (Jan 29, 2018):
Friday May 12, 2017 at 17:08 GMT
Radio works, the problem is that it only plays 10 songs and then restarts. Same as older spotifyConnect clients apparently, lots of people complained in that thread. Looks like librespot is expected to "refresh the list" when it's reaching the end, radio is a special kind of playlist - dynamic playlist that never ends. The current behavior is a bit annoying.
It's been like this from the beginning and I thought it was time to raise it. Coudn't find previous references so here we are.
@sashahilton00 commented on GitHub (Jan 29, 2018):
Friday May 12, 2017 at 17:12 GMT
The way Connect works is the remote sends a "Context URI" and a short list of tracks from that context.
If the receiver supports that context type, it can just use it to get the track list, otherwise it falls back to that list sent by the client.
Librespot doesn't support contexts at all, so it will always use that list. This is why radios and eg long playlists only play a few tracks in a loop
@sashahilton00 commented on GitHub (Jan 29, 2018):
Friday May 12, 2017 at 17:19 GMT
I see, thanks.
Is there any chance we could get that in librespot? It's a fairly common use case, very useful, and librespot has been uber stable for some time (at least on my raspberry). It would be great to have this feature
@sashahilton00 commented on GitHub (Jan 29, 2018):
Saturday May 13, 2017 at 11:08 GMT
I suppose the same thing goes for playing similar tracks when an album ends and daily mixes. This is very desirable to have.
@sashahilton00 commented on GitHub (Jan 29, 2018):
Thursday May 18, 2017 at 07:44 GMT
I'm not sure what a "long" playlist is, but I've tested playlists as long as 100 tracks and Librespot plays them fine.
However, I notice the 10-track-loop constantly on Radio and Daily Mixes, and would love to have context working correctly to support those features. As a bonus, I bet it would also add support for showing (in Spotify clients) which playlist/track is currently playing (such as the speaker icon next to the playlist name, the track highlighted green in the list of songs for the playlist, etc).
Playing on another device (top) vs playing on Librespot (bottom):

I believe issue #21 is related to this feature request.
@sashahilton00 commented on GitHub (Jan 29, 2018):
Wednesday May 24, 2017 at 11:13 GMT
Aaah... this issue explains why my Onkyo Audio Receiver (2012 lineup) has this behavior since Spotify introduced Radio and Mix Tapes features some months ago. So it is actually because these older devices and librespot rely on some kind of fallback.
I'd love to see this "dynamic" feature introduced in librespot :)
@sashahilton00 commented on GitHub (Jan 29, 2018):
Sunday Jun 04, 2017 at 19:48 GMT
might be worth adding the feature request tag to this
@sashahilton00 commented on GitHub (Jan 29, 2018):
Thursday Sep 07, 2017 at 21:53 GMT
Yes very old spotify firmware in speakers has the same problem as librespot, it's unable to play more than a dozen songs from a dynamic list (dynamic lists include Spotify Radios and Daily Mixes), and then it starts repeating the same few songs instead of loading new ones.
Still hoping that librespot will get support for this.
@sashahilton00 I couldn't find the way to add a Feature Request tag. Looks like only the project owner can.
@sashahilton00 commented on GitHub (Jan 29, 2018):
This should be a priority, as quite a bit of stuff seemingly depends on it (dynamic playlists, radio, daily mix, green selected bar in spotify, etc.)
@sashahilton00 commented on GitHub (Mar 8, 2018):
Just to note, the websockets API from Spotify uses context URI's quite a lot, and provides a good example of how they are structured/used if we're looking to implement support for them. /cc @kingosticks fyi.
@mfeif commented on GitHub (May 16, 2018):
Is anyone working on this right now perhaps in a fork or another thread? I'd like to help... I'm trying to figure out where to familiarize myself with what's going wrong and what's necessary (re ContextURI) before I make a commitment that I don't have the skills to back up.
I presume that official clients are following the rules 😃so when the platform sends play signals to the connect clients (like librespot) something is going wrong there (as written above).
Seems like @plietar had some detailed understanding about a year ago; is it a state thing, like the playback software needs to be told its in "radio mode" and has to ask for more tracks via some other api? Or is something more magical supposed to happen?
(I've got Chromecasts and other officially supported devices running, but I prefer librespot for a number of reasons, so I'd like to help any effort to bring this to parity.)
@plietar commented on GitHub (May 16, 2018):
Basically you need to add support for fetching a list of tracks given a Context URI. You should be able to see the context uri by adding some println in
spirc.rs.You can look at how the official client fetches the track list using spotify-analyze (works on macOS and soon on linux: https://github.com/librespot-org/spotify-analyze/pull/1). Look at the requests it makes, especially the mercury related ones.
You would then need to reimplement the fetching for each type of Context URI (eg. playlist, radio, album, artist, search, ...). Given a "hermes"/"mercury" URI (starts with
hm://) you can fetch the resource using :This gives you a future which will eventually resolve to the response.
To start off easily, you can reuse the
play.rsexample and docore.run(future), which will wait for the result.Let me know if there's anything else you would need help with
@sashahilton00 commented on GitHub (May 16, 2018):
I'll also add, you can use Chrome to inspect the websockets API for play.spotify.com if you just want to see the context URIs and the retrieved tracks easily, though it won't help in terms of understanding how to implement it in librespot.
@mfeif commented on GitHub (May 16, 2018):
Thanks for the fast response! But what does librespot need to do with these responses?
Do we need a whole suite of logic to be changed according to these instead of the old API/way?
Is it that radical of a change?
@Danappelxx commented on GitHub (Dec 10, 2018):
I've been tweaking librespot a little for personal purposes and ran into similar issues with shuffling as others have reported. I'm interested in adding support for proper queue and context management. Has any progress been made on fetching the tracklist from a context uri (before I dive too deep down the rabbit hole)?
@ashthespy commented on GitHub (Dec 10, 2018):
FWIW:
github.com/ashthespy/librespot@8a0b004b6cI have working dynamic playlists - except for the dailymix stuff.@Danappelxx commented on GitHub (Dec 10, 2018):
Very cool! I'll base my work off of that. Any reason the features on that branch never got merged?
@ashthespy commented on GitHub (Dec 10, 2018):
Hmm because I couldn't find the proper mercury endpoint to give me that data in protobuf format. Currently it's in JSON and rather inelegant if you ask me.
@mendeldesign commented on GitHub (Jan 3, 2019):
Will this eventually be merged with the master? I use Raspotify since a few days and notice the same issues. Would like to turn on a track-based radio and listen to it forever, but I am not comfortable with tweaking the code as described by @ashthespy . Thanks though for figuring this out!
@devgianlu commented on GitHub (Jan 4, 2019):
@ashthespy If you use
hm://context-resolve/v1/it will give you the next page URL and there you can retrieve the next tracks in JSON format. The problem I am facing is that when I add them to the tracks list and send it to server it returns 500.The playback works, but the client isn't being updated.
@ashthespy commented on GitHub (Jan 4, 2019):
@devgianlu I retrieve the track references and next page url via the
hm://radio-apolloendpoint.Then update frame with the resolved tracks to get it to update on the client side. This seems to work as expected so far :)
@mendeldesign My implementation is very rudimentary and could use a some refinement before being merged into master. I for one don't like the JSON endpoint, and would prefer to sniff out the protobuf one. I do believe there is a protobuf endpoint - there is a
ContextPageprotobuf message that I saw when pulling proto files from the official client.I have a few pre-compiled binaries with a few customisations (and a socket for Volumio) for the usual fruity boards over at https://github.com/ashthespy/Vollibrespot/releases
@devgianlu commented on GitHub (Jan 5, 2019):
@mendeldesign I have the radio working on librespot-java, version 0.1.3. As sad by Ash there is some junkiness going on, but it works.
@ashthespy commented on GitHub (Jan 5, 2019):
@devgianlu Does the
context-resolveendpoint support the daily-mix stuff?@mendeldesign commented on GitHub (Jan 5, 2019):
Thanks @ashthespy and @devgianlu, I fear though that I am not skilled enough to implement these solutions. I used the step-by-step installation from Raspotify and am happy that I got it working, but I am missing the radio feature and controlling pauze/play via a python script would be nice to have. I will try to get the latter working by adding Spotipy to my pi to control playback. However, I am (still!) uncomfortable with installing pre-compiled binaries or replacing the implementation I currently have in Raspbian. If an future update to librespot (and thus to Raspbian) fixes the dynamic playlist issue, I will be happy.
@devgianlu commented on GitHub (Jan 5, 2019):
@ashthespy It doesn't, returns 404. I'm hoping the webgate one does.