Repository navigation
Conversation
…th no stream Switching a Connect device back to a zone in the last seconds of a track left the zone frozen at end-of-track — playback never advanced. The handoff that moved the account away tears the zone's stream down (finishTrack), and coming back is announced as a `device_changed`, which carries no `status`. onEvent only re-adopts on a `status === 'playing'` event, so the reactivation itself never triggers it. Mid-track the following `playing`/`track_changed` events re-adopt the zone; but when the switch-back lands at the track boundary Soloist reaches the end before any of them arrive and then sends none, leaving the zone owner=`queue`, no stream, stuck at end-of-track while Soloist plays on into a pipe nobody reads. Re-adopt on `device_changed` when the device is active again but has no stream, so the pipe is reopened, playback is consumed, and the track advances. Fixes sonn-audio#352. Verified against a deterministic repro (transfer to zone B -> seek dur-5s -> transfer back to zone A): without the fix the zone pins at progress==duration; with it, it adopts ("took this zone over") and advances to the next track. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #352 — root cause found and fix verified against the deterministic repro (patched into the running
container's
dist, reproduced with vs. without).Root cause (confirmed by instrumenting
onEvent)Logging every
onEventcall through a switch-back-at-the-boundary showed the exact sequence for the zone:The reactivation arrives as a
device_changedwith nostatus. The only path that re-opens the pipe isthe
status === 'playing'adopt, sodevice_changedslips past it, andowner === 'queue'makes onEventreturn. Mid-track this is harmless — the
playing/track_changedevents that follow re-adopt the zone. Butwhen the switch-back lands in the last seconds, Soloist hits the track end before any such event and then
emits none, so the zone is left
owner=queue,stream=null, stuck at end-of-track while Soloist streams intoa pipe nobody reads.
Fix
Re-adopt on
device_changedwhen the device is active again but has no stream:(placed right after the
!runner.ws.isActiveblock, soisActiveis already guaranteed true there.)Verification
Repro: two Soloist zones on one account;
transfer B→seek dur-5s→transfer A.progress == duration,is_playing == true, never advances.FIX reactivation re-adopt→the spotify app took this zone over→playback advances (
220/222s "Dass es hier so schön ist"→0/130s "Zugabe"→ continues). No freeze.Control (switch not near the boundary) was unaffected either way.