Compare commits

..

2 commits

Author SHA1 Message Date
04a9116f68 Merge pull request 'Fix host stream freeze when a guest joins an in-progress party' (#26) from fix/guest-join-freezes-host-stream into master
All checks were successful
Publier l'image Docker / test (push) Successful in 24s
Publier l'image Docker / publish (push) Successful in 8s
2026-09-23 20:34:12 +02:00
7fbf22419d Fix host stream freeze when a guest joins an in-progress party
Some checks failed
Publier l'image Docker / test (pull_request) Failing after 4s
Publier l'image Docker / publish (pull_request) Has been skipped
A joining member's player always called loadVideo(itemId, 0, false),
hardcoding a resume position of 0. Since a party's Emby stream is one
shared transcode session (PartyStreamService, keyed by partyId alone),
a newcomer's hls.js requesting segments from position 0 against a
session that already progressed well past that forces Emby to
seek/restart the shared transcode - stalling playback for every
member, host included, right as the newcomer joins.

Seed the initial resume position from the host's last-reported
position (already available in party.members) instead, so the first
segment request lands near where the shared session already is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 18:53:57 +02:00

View file

@ -1260,7 +1260,20 @@ function renderVideoPlayer(root: HTMLElement, partyId: string, party: PartyPubli
loadMarkers(party.itemId); // not awaited - see onItemChanged's own comment
await loadTrackOptions(party.itemId);
loadVideo(party.itemId, 0, false);
// Unlike onItemChanged's own loadVideo(..., 0, ...) - genuinely correct
// there since a fresh item has no position yet - mounting mid-party
// (a joining guest, or the host's own page reload) must NOT hardcode 0:
// the party's shared Emby transcode (PartyStreamService) is keyed by
// partyId alone, one PlaySessionId for every member, so a hls.js
// instance requesting segments from 0 against a session that already
// progressed well past that forces Emby to seek/restart the shared
// transcode - stalling it for every other member, host included, right
// as the newcomer joins. Seeding from the host's last-reported position
// (already in party.members, sent to every mount) lands the first
// segment request near where the shared session already is instead.
const hostMember = party.members.find((m) => m.isHost);
const initialResumeSeconds = hostMember ? hostMember.positionTicks / TICKS_PER_SECOND : 0;
loadVideo(party.itemId, initialResumeSeconds, false);
conn = connectParty(partyId, {
onMembers: renderMembers,