Skip to content

Fix multi-server admission gaps and gate audio on playback - #315

Draft
maximmaxim345 wants to merge 8 commits into
mainfrom
fix/arbitrate-pairing-connection-adding-playback
Draft

maximmaxim345 wants to merge 8 commits into
mainfrom
fix/arbitrate-pairing-connection-adding-playback

Conversation

@maximmaxim345

@maximmaxim345 maximmaxim345 commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Fixes a gap where a pairing connection held next to a playback connection could add 'playback' without arbitration, so two servers could play on one client.
This keeps the current admission model and patches each gap in it with its own rule.

While a pairing connection is held next to a playback connection:

  • A pairing connection that adds 'playback' is arbitrated against the playback connection, the same way as when it drops 'pairing'.
  • The pairing connection is only allowed next to a connection that only plays, not one that is pairing itself.
  • A new connection that declares 'pairing' is also arbitrated against the held pairing connection.
  • A playback connection that drops 'playback' or adds 'pairing' is arbitrated against the held pairing connection.

'playback' now also gates the audio: the player and visualizer streams and the source role's start. Artwork, metadata and controller state don't need it, but a server still declares it while the client's group plays, so it can also take over a client that only shows metadata. The client also ignores the audio streams and start on a connection without 'playback', since with unpaired access a pairing connection can still hold these roles. Player commands are ignored the same way, but only while another connection has 'playback'.

Alternative that reworks admission around activities instead:

Closes #299

Breaking change

Clients that admit only one connection keep their admission behavior. Clients that hold a playback and a pairing connection now reject a new pairing connection while the playback connection is pairing itself, instead of holding both, and arbitrate the later activations listed above. That changes one outcome the old text defined. The alternative changes two more: a new playback connection is held next to a lone pairing connection, and a new pairing connection displaces the held pairing connection unless its attempt is in progress.

Servers must not start a player or visualizer stream or send the source start command without 'playback', and must end the player and visualizer streams before dropping it. Clients ignore them without 'playback', and a source client stops its input stream when 'playback' is dropped. Player commands don't need 'playback', so a server can still change the volume of a stopped speaker.

Servers should declare 'playback' while the client's group plays or while they use its source, and drop it only once that ends, not at a track change or a move to another playing group.

Limitations compared to the alternative

  • Later activations are only arbitrated in the cases the text names, so each new case needs its own rule.

  • A new playback connection still displaces a pairing connection that is held alone, or is rejected during its pairing attempt, instead of being held next to it.

  • Like the alternative, an idle connection is only admitted alone.

  • I accept the Contributor License Agreement for this contribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Should a held pairing connection that adds the playback activity trigger arbitration?

1 participant