watchparty/docs
Nicolas 4b2d4822ef
All checks were successful
Publier l'image Docker / publish (push) Successful in 14s
Fix language/subtitle selection: force our pick onto Emby's negotiation
Bug report: picking an audio language or subtitle track in the player's
settings menu had no effect. First real-world bug reachable only once
streaming itself was already confirmed working end to end (this is that
confirmation, per docs/architecture.md).

Root cause, reasoned from how Emby's API actually works (no way to verify
directly - see below): real Emby web clients negotiate track selection via
a POST /Items/{id}/PlaybackInfo body with a DeviceProfile; this app only
ever sent AudioStreamIndex/SubtitleStreamIndex as bare GET query params,
which PlaybackInfo's negotiation likely doesn't apply the same way -  so
the TranscodingUrl it returned just reflected Emby's own default track,
regardless of what was actually requested. Separately, even a correctly
selected subtitle has a second silent-failure path: Emby can deliver text
subtitles burned into the video (SubtitleMethod=Encode) or as their own
selectable HLS rendition (SubtitleMethod=Hls) - this player's hls.js setup
never wires up subtitleTrack/subtitleTracks, so a Hls-method subtitle would
sit in the manifest unused.

server/src/index.js: new applyPlaybackOverrides forces
AudioStreamIndex/SubtitleStreamIndex/MaxStreamingBitrate onto whichever URL
the /master.m3u8 route ends up with - Emby's own TranscodingUrl, or the
hand-built fallback (which, before this fix, dropped these three params
entirely - a second, independent way the same symptom could happen).
Picking a subtitle also forces SubtitleMethod=Encode; picking "Aucun"
deletes both SubtitleStreamIndex and SubtitleMethod rather than just not
adding one, so it also cancels a subtitle Emby's negotiation had defaulted
to on its own. The negotiation call no longer needs to be trusted to apply
these params - it only needs to return a playable MediaSource, since every
control this app's UI exposes gets forced afterward regardless.

Verified as far as possible without real Emby access:
applyPlaybackOverrides is pure URLSearchParams manipulation, unit-tested in
isolation (adding a subtitle, removing one Emby had defaulted to,
re-sending an unchanged selection across an audio-only change, quality
override, the no-selection-yet initial load) - all pass. Confirmed
client-side too, by mocking Hls to capture what loadSource was actually
called with: initial load sends the default track's index, each dropdown
change re-sends a full reload with exactly the accumulated params expected.
What's not verified is the real Emby round trip - that needs a live
retest, which this environment has no credentials to do.

docs/architecture.md has the full writeup, and its "Assumptions to verify"
section got a broader pass while in there: several items long-flagged as
"not yet exercised against the real server" are now implicitly confirmed
by everything that's worked in real usage so far (response field names,
auth headers, playlist rewriting, basic HLS playback) - narrowed the list
down to what's genuinely still unconfirmed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 00:35:22 +02:00
..
architecture.md Fix language/subtitle selection: force our pick onto Emby's negotiation 2026-09-14 00:35:22 +02:00