librespot icon indicating copy to clipboard operation
librespot copied to clipboard

Expose updates from other connect devices when not active

Open photovoltex opened this issue 11 months ago • 4 comments

Is your feature request related to a problem? Please describe. When implementing librespot as client (mostly GUI related) and not being the active connect device, there isn't any option to update the client UI as the remote events/updates are not exposed.

Describe the solution you'd like It would be nice to call a similar method like player_event_handler on the spirc instance to retrieve a channel that exposes remote updates. Additionally we could also provide some local updates that exposes internal knowledge like the current next and previous tracks for example.

Additional context

  • remote updates are send as ClusterUpdate
    • https://github.com/librespot-org/librespot/blob/dev/connect/src/spirc.rs#L816
  • updates to the remote server when we are active are send as PutStateRequest
    • https://github.com/librespot-org/librespot/blob/dev/connect/src/spirc.rs#L1525

photovoltex avatar Jan 18 '25 21:01 photovoltex

This is nice. There's already a bunch of useful events to keep track of the player, but one challenge I'm seeing is how to keep track of the playback context, i.e. expose changes to the current playlist or queue.

It could also be useful to offer APIs for context manipulation, for instance when the user removes a track from the queue (that is not a playlist). Though I'm not sure if that's even feasible.

hrkfdn avatar Sep 01 '25 19:09 hrkfdn

Yeah that should also be be doable. As we are the active device we don't need to go over any apis we can just modify the next tracks which are just a mix of context, queue and autoplay items depending on the current state. After "publishing" the state again, the passive connect devices update their state to the active state. Anyhow...

but one challenge I'm seeing is how to keep track of the playback context, i.e. expose changes to the current playlist or queue.

Yes that's the biggest part we have to get right. I see two options currently:

  • either we just expose it "as is" (lazy and more flexible option)
    • we could forward only some parts like prev_tracks and next_tracks
    • or forward the entire state
  • or we expose it preprocessed (library handling with less flexibility, but easier usage)
    • that means holding additional data and only providing specific events/data to the user
    • this could be like "track added", "context changed", "track removed", etc.

photovoltex avatar Sep 01 '25 19:09 photovoltex

I can only speak for myself/ncspot, of course. So some of this may not necessarily make sense from a library perspective, buuuut:

Maybe the first option is good as an MVP approach? I think just forwarding the entire state/sending events on changes could already be a win and maybe flexible is actually good, not sure if all of the ncspot behavior even translates to Spotify Connect clients 😅

hrkfdn avatar Sep 01 '25 19:09 hrkfdn

I made a quick initial implementation (https://github.com/photovoltex/librespot/tree/feat/forward-player-state) where it just forwards the underlying PlayerState. This is pretty ruff so I will probably look into how we can make it easier to work with.

photovoltex avatar Sep 09 '25 20:09 photovoltex