Commit 374802f
fix: route Mercury AP playlist events to enable unlimited DJ Switch it up
Root cause of the 7-8 Switch it up limit in both zeroconf and interactive
mode: the Spotify server delivers vibe-section playlist pushes through TWO
separate channels simultaneously —
1. The Dealer WebSocket (hm://playlist/v2/playlist/…)
2. The Mercury AP event channel (PacketTypeMercuryEvent, same URI)
go-librespot already subscribed to the Dealer path, so a handful of pushes
were processed. But the overwhelming majority — the initial burst of ~68
sections at DJ startup plus 1-4 new sections pushed every ~30 s as
switch-ups consume the queue — arrived via PacketTypeMercuryEvent.
The Mercury client's receive loop had a hard `continue` after logging each
event, so every AP-channel playlist push was silently discarded. Only the
small subset that happened to duplicate onto the Dealer channel ever reached
the section buffer. With ~6 sections instead of ~68, the buffer ran dry after
roughly 7 switch-ups and djPoll fell back to repeating the same 35 lexicon
tracks, causing the looping the user observed.
Why Mercury is 100% needed
--------------------------
TLS capture of the official Spotify desktop client confirmed that during a
single DJ session with 15 switch-ups it received 100 playlist-push events
across 37 unique vibe-section playlists:
• +11 s — initial burst: 68 pushes (34 unique playlists)
• +97 s onward — continuous trickle: 1-4 new sections every ~30 s,
perfectly correlated with active switch-ups
Zero of these appeared as HTTP/2 calls — the desktop makes no lexicon
requests at switch-up time. It purely navigates a local queue that the server
keeps topped up via Mercury AP events. go-librespot must receive and buffer
these events or the queue will always exhaust after a handful of jumps.
Changes
-------
mercury/client.go
- Add eventSubscriber / EventMessage types and eventSubs list to Client.
- In the PacketTypeMercuryEvent branch of recvLoop(), route events to any
matching subscriber channel (non-blocking, buffered 64) instead of
discarding with `continue`.
- Add SubscribeEvent(uriPrefixes…) method so callers can tap the stream.
cmd/daemon/player.go
- Subscribe to "hm://playlist/v2/playlist/" on the Mercury client at
startup alongside the existing Dealer subscription.
- Add a select case that converts the eventMessage into a dealer.Message
and hands it to the existing handleDealerMessage path — no duplicate
handling code.
- Fix section-buffer gating: remove the ContextUri == djCachedContextUri
guard from the playlist-update handler so sections received during a
context transition (Switch it up briefly loads a regular playlist) are
not silently dropped.
cmd/daemon/controls.go
- Mirror the proactive low-queue djPoll trigger into skipNext's targeted-
skip path. Previously the check only ran inside advanceNext, which is
never called when skip_next carries an explicit target track (the DJ
Switch it up case), so the lexicon refresh was never scheduled and the
queue silently drained to zero before djPoll fired.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1 parent bf5acbb commit 374802f
3 files changed
Lines changed: 95 additions & 17 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
273 | 273 | | |
274 | 274 | | |
275 | 275 | | |
276 | | - | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
277 | 280 | | |
278 | 281 | | |
279 | 282 | | |
| |||
301 | 304 | | |
302 | 305 | | |
303 | 306 | | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
304 | 316 | | |
305 | 317 | | |
306 | 318 | | |
| |||
836 | 848 | | |
837 | 849 | | |
838 | 850 | | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
839 | 867 | | |
840 | 868 | | |
841 | 869 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
222 | 222 | | |
223 | 223 | | |
224 | 224 | | |
225 | | - | |
226 | | - | |
227 | | - | |
228 | | - | |
229 | | - | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
230 | 230 | | |
231 | 231 | | |
232 | 232 | | |
| |||
1118 | 1118 | | |
1119 | 1119 | | |
1120 | 1120 | | |
| 1121 | + | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
1121 | 1125 | | |
1122 | 1126 | | |
1123 | 1127 | | |
| |||
1143 | 1147 | | |
1144 | 1148 | | |
1145 | 1149 | | |
| 1150 | + | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + | |
| 1154 | + | |
1146 | 1155 | | |
1147 | 1156 | | |
1148 | 1157 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
28 | 29 | | |
29 | 30 | | |
30 | 31 | | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
31 | 45 | | |
32 | 46 | | |
33 | 47 | | |
34 | 48 | | |
35 | 49 | | |
36 | 50 | | |
37 | 51 | | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
38 | 55 | | |
39 | 56 | | |
40 | 57 | | |
| |||
100 | 117 | | |
101 | 118 | | |
102 | 119 | | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
103 | 129 | | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
112 | 142 | | |
113 | | - | |
114 | | - | |
115 | | - | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
116 | 146 | | |
117 | 147 | | |
118 | 148 | | |
| |||
280 | 310 | | |
281 | 311 | | |
282 | 312 | | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
0 commit comments