Spotify Connect: clearer transport errors and automatic stall recovery#4010
Merged
Conversation
…odec - Apply the active-device check from get_stream_details at the top of on_source_control and on_volume_change so next/previous/seek/volume hit the same user-friendly "not the active device" error instead of a Spotify Web API 403 - Start librespot with --passthrough so the FIFO carries the raw Ogg-Vorbis bytes from Spotify; set audio_format to OGG/VORBIS at 320 kbps so the frontend shows the real source codec. Drop --dither and --enable-volume-normalisation since both only apply when librespot is decoding
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates Spotify Connect handling so inactive-device transport commands fail with a user-facing error and Spotify Connect streams are advertised as Ogg-Vorbis instead of PCM.
Changes:
- Adds active-device guards for source control and volume changes.
- Starts librespot with
--passthrough. - Updates the advertised
AudioFormatto OGG/VORBIS at 320 kbps.
MarvinSchenkel
approved these changes
May 28, 2026
Contributor
MarvinSchenkel
left a comment
There was a problem hiding this comment.
Automated review (no CRITICAL/PROBLEM findings).
Verified:
- AudioFormat OGG/VORBIS + bit_rate=320 matches the new
--passthroughlibrespot mode. - Active-device guards in
on_source_control/on_volume_changemirror the existing check inget_stream_details. - Removed
--ditherand--enable-volume-normalisationare decode-only flags, correctly dropped under passthrough.
Thanks @marcelveldt 🎉
Note: the PR Labels workflow failed because the bugfix checkbox uses escaped backticks (`bugfix`) instead of plain backticks — the label regex won't match, so the bugfix label won't auto-apply. Worth fixing in the description or applying the label manually.
When session_connected isn't followed by a 'playing' or 'paused' event within 8 s the daemon is almost always blocked on a pipe write (no consumer attached yet). Read+discard from the FIFO for up to 2 s to unblock librespot's writer; the normal flow resumes on its own once 'playing' fires. Bails out early if librespot recovers or the regular stream pipeline is about to attach so we never split bytes with ffmpeg.
Match on "Connecting to AP" instead of the PCM-specific StdoutSink line so the daemon-started signal still fires regardless of audio backend or passthrough mode and doesn't trip the "unable to initialize" unload path if librespot ever changes its backend startup logging.
librespot emits a separate Ogg bitstream per Spotify track in passthrough mode and ffmpeg can't demux chained Ogg, so stop+play within the same session was failing with "Codec not found" once a new bitstream began. Expose chain_ogg_pages() in the existing ogg_handler (the radio-stream chained-Ogg stitcher) so any async byte source can use it, switch the provider's stream_type to CUSTOM and implement get_audio_stream() that pipes read_named_pipe through chain_ogg_pages. ffmpeg now sees one continuous Ogg bitstream regardless of how many Spotify tracks are concatenated.
Chained-Ogg stitching solved the stop+restart "Codec not found" but the multi-stage buffering (kernel FIFO -> StreamReader -> chain_ogg_pages page buffer -> ffmpeg stdin -> -re pacing) added several seconds of latency on track changes, which is much worse than the codec badge being wrong. Back to librespot's decoded PCM on the FIFO; the codec-display question can be revisited as a UI hint or via the planned librespot-go migration with its dedicated WebSocket API.
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.
What does this implement/fix?
Three small follow-ups to #4001 that make Spotify Connect playback control feel less fragile:
Types of changes
bugfixnew-featureenhancementnew-providerbreaking-changerefactordocumentationmaintenancecidependenciesChecklist
pre-commit run --all-filespasses.pytestpasses, and tests have been added/updated undertests/where applicable.music-assistant/modelsis linked.music-assistant/frontendis linked.