Skip to content

fix(syncplay): send full series queue and resume position on initiate#2

Open
JenteJan wants to merge 1 commit into
irican-f:syncplayfrom
JenteJan:fix/syncplay-episode-queue-and-resume
Open

fix(syncplay): send full series queue and resume position on initiate#2
JenteJan wants to merge 1 commit into
irican-f:syncplayfrom
JenteJan:fix/syncplay-episode-queue-and-resume

Conversation

@JenteJan

@JenteJan JenteJan commented Jun 7, 2026

Copy link
Copy Markdown

Builds on the SyncPlay work in DonutWare#735 — targets the syncplay branch so it folds into that PR once merged.

Problem

Starting playback from Fladder while in a SyncPlay group didn't work for other participants — most visibly the official Jellyfin clients (verified against the Jellyfin web client and the LG webOS app):

  • TV episodes never started on the other client. Movies did, which made it look movie-vs-episode specific.
  • "Continue Watching" restarted the group from 0:00 instead of the saved resume position.

Root cause

_playSyncPlay sent a single-item queue: setNewQueue(itemIds: [itemModel.id], playingItemPosition: 0, startPositionTicks: 0).

  • Captured WebSocket traffic shows the official client always queues the whole series (with PlayingItemPosition at the chosen episode). A lone single-episode queue is not started by those clients; movies are single-item by nature, so they worked and hid the bug.
  • startPositionTicks fell back to 0 whenever no explicit startPosition was passed. The local playback path resolves the resume point via model.startDuration(); the SyncPlay path did not.

Fix

Mirror the local playback path in _playSyncPlay:

  • Build the queue with the existing collectQueue(itemModel) (full series for an episode/series/season; empty for a movie).
  • Resolve Series/Season → next-up episode (same as createPlaybackModel's firstItemToPlay).
  • Send the whole series with the correct playingItemPosition; movies fall back to a single item.
  • Fall back to the resolved item's saved resume position so Continue Watching resumes the whole group mid-item.

Also adds the matching cross-client regression scenarios to docs/syncplay-implementation.md per the regression checklist.

Testing

Manually verified in a real group, with Fladder as the initiator and official Jellyfin clients as the other participant — the Jellyfin web client and the LG webOS app:

  • Before: official clients didn't start episodes initiated from Fladder; movies worked. Continue Watching restarted at 0:00.
  • After: official clients start episodes initiated from Fladder; Continue Watching resumes at the saved position for all participants. Movies unchanged.

When starting playback in a SyncPlay group, _playSyncPlay sent a
single-item queue (PlayingQueue: [itemId], position 0, startPositionTicks
0). This broke playback for other participants, notably the official
Jellyfin clients (e.g. the webOS TV app):

- Episodes never started on other clients. The official client queues the
  whole series (with PlayingItemPosition pointing at the chosen episode);
  a lone single-episode queue is not started by those clients. Movies,
  being naturally single-item, worked - which made the bug look
  movie-vs-episode specific.
- The resume position was dropped. Continue Watching restarted the group
  from 0:00 because startPositionTicks fell back to 0 whenever no explicit
  startPosition was passed. The local playback path resolves this via
  model.startDuration(); the SyncPlay path did not.

Mirror the local playback path: build the queue via collectQueue (full
series for an episode/series/season, empty for a movie), resolve
Series/Season to their next-up episode, send the whole series with the
correct playingItemPosition, and fall back to the resolved item's saved
resume position.

Also document the matching cross-client regression scenarios per the
SyncPlay regression checklist (AGENTS.md rule 10).
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.

1 participant