Review MUST-FIX + SHOULD-FIX (#145):
- Repeat Play with unchanged settings was fully broken: the manifest GET is
what starts a session server-side, but an identical URL made setPlayerSrc a
state no-op, so HlsPlayer never re-attached and no request was issued —
while the poll saw the previous session's stored result and toasted a
spurious success over a dead player. HlsPlayer now takes a playToken prop
(incremented per Play) that forces teardown/re-attach even for identical src.
- First-poll race: PrepareTroubleshootingPlayback runs DB queries BEFORE
taking the playback lock, so polls right after Play can still see the stale
settled result. Replaced the manually-seeded 'running' assumption with a
play-phase machine (idle -> starting -> running -> idle): settled statuses
are ignored during 'starting' until the server has reported running at
least once, with a 30s timeout that surfaces an error and stops polling.
Play + downloads are gated and a Starting/Transcoding indicator shows for
the whole busy window.
Nits: mediaItem takes precedence over channel when both query params are
present (matching Blazor); on-mount poll comment notes the intentional
post-restart log recovery. Tests: repeat-play re-issues loadSource, stale
settled ignored until running observed, starting timeout, download gating
while busy, both-params precedence (web suite 378 -> 384).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>