/
/
# What does this implement/fix?
Fixes the queue's `corrected_elapsed_time` freezing at the seek position
on players that reach their device through an output protocol player
(observed on a HA Voice PE via Sendspin under a Universal Player, in
flow mode), while audio plays on normally.
Root cause: `_reconcile_position_anchor` adopted a `None -> numeric`
anchor transition silently with `jumped=False` ("incomplete anchor
data"). A playback session restart (seek) resets the protocol player's
elapsed to None, so the new session's first elapsed write is exactly
that transition. Since `elapsed_time` is excluded from regular change
detection by design, the `position_jumped` signal is the only
propagation path from a protocol player to its parent wrapper, and that
single opportunity was swallowed. The wrapper then stays on the mirrored
None anchor, and the flow mapping computes `seek_position + 0`
indefinitely, until some unrelated player-registry event happens to
trigger a wrapper update, which is what made the bug look intermittent.
The fix: an incomplete anchor becoming complete now reports
`jumped=True`, so the session's first elapsed write routes through
`on_player_position_jumped`, the wrapper re-mirrors, and the queue
rebases. This covers every protocol-wrapped player after any session
restart, not just the device it was found on.
Diagnosed with temporary instrumentation across the sendspin commit
loop, the flow mapping, and the state forwarding path; the frozen
position was independently confirmed by matching the visualizer's
pending-beat counts against the track's stored beat analysis (pinned to
the exact seek offset). Surfaced while working on #5864, whose audio tap
anchors to queue time and resync-looped every 3 seconds against the
frozen input.
**Related issue (if applicable):**
- related issue <link to issue>
## Types of changes
<!--
Tick exactly one box. CI (.github/workflows/pr-labels.yaml) derives
the label from the ticked box and applies it automatically; the
release-notes generator uses that same label to slot this change
into the next release notes.
-->
- [x] Bugfix (non-breaking change which fixes an issue) — `bugfix`
- [ ] New feature (non-breaking change which adds functionality) —
`new-feature`
- [ ] Enhancement to an existing feature — `enhancement`
- [ ] New music/player/metadata/plugin provider — `new-provider`
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected) — `breaking-change`
- [ ] Refactor (no behaviour change) — `refactor`
- [ ] Documentation only — `documentation`
- [ ] Maintenance / chore — `maintenance`
- [ ] CI / workflow change — `ci`
- [ ] Dependencies bump — `dependencies`
## Checklist
- [x] The code change is tested and works locally.
- [x] `pre-commit run --all-files` passes.
- [x] `pytest` passes, and tests have been added/updated under `tests/`
where applicable.
- [ ] For changes to shared models, the companion PR in
`music-assistant/models` is linked.
- [ ] For changes affecting the UI, the companion PR in
`music-assistant/frontend` is linked.
- [x] I have read and complied with the project's [AI
Policy](https://github.com/music-assistant/.github/blob/main/AI_POLICY.md)
for any AI-assisted contributions.
- [ ] I have [raised a PR against the documentation
repository](https://github.com/music-assistant/music-assistant.io/blob/main/CONTRIBUTING.md)
targeting the main or beta branch as appropriate.