From 92adb593c8312bde0375deedebadebd8e7cbd4fc Mon Sep 17 00:00:00 2001 From: npeter83 Date: Sun, 30 Aug 2026 20:09:00 +0200 Subject: [PATCH 1/2] fix(plex): start hls.js at position 0 for the transcode/remux HLS session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Our HLS is a growing EVENT playlist with no ENDLIST, which hls.js reads as LIVE. Its default startPosition (-1) then starts at the live edge and hugs it (no forward buffer → rebuffer spinners), and on a resume/seek session the segments' absolute PTS (-copyts, offset by the server's -ss) don't line up with the live-edge timeline → 0 fragments load → permanent stall. The seek-restart model makes fragment 0 the requested content position, so start VOD-style at 0 and buffer forward. Fixes the transcode playback stall/rebuffer found in 0.78.2 UAT. --- frontend/src/components/PlexPlayer.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/PlexPlayer.tsx b/frontend/src/components/PlexPlayer.tsx index 4fc7663b..61124c86 100644 --- a/frontend/src/components/PlexPlayer.tsx +++ b/frontend/src/components/PlexPlayer.tsx @@ -261,7 +261,15 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) { hlsRef.current = null; } if (sess.mode === "hls" && Hls.isSupported()) { - const hls = new Hls({ maxBufferLength: 30, enableWorker: true }); + // startPosition: 0 — our HLS is a growing EVENT playlist with no ENDLIST (see _HLS_TAIL in + // stream.py), which hls.js classifies as LIVE. Its default (startPosition: -1) then starts + // playback at the live edge and hugs it, so it never builds a forward buffer (rebuffer + // spinners), and on a resume/seek session the segments' absolute PTS (-copyts, offset by the + // server's -ss) don't line up with the live-edge timeline → 0 fragments load → permanent + // stall. But the seek-restart model means fragment 0 IS the requested content position + // (`?t=` positioned the server ffmpeg there), so we always want to start VOD-style at 0 and + // buffer forward up to maxBufferLength. Applies to remux + transcode alike (both use copyts). + const hls = new Hls({ maxBufferLength: 30, enableWorker: true, startPosition: 0 }); hlsRef.current = hls; hls.loadSource(`${sess.url}?t=${Math.floor(startAt)}`); hls.attachMedia(video); From ba00b50deac2a4168ec8da21688ff6cb104b7d18 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Sun, 30 Aug 2026 20:32:56 +0200 Subject: [PATCH 2/2] =?UTF-8?q?release:=200.78.4=20=E2=80=94=20fix=20Plex?= =?UTF-8?q?=20transcode=20playback=20stall/rebuffer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hls.js startPosition:0 so the transcode/remux HLS session starts VOD-style at the requested position instead of chasing the live edge of the growing EVENT playlist. --- VERSION | 2 +- frontend/src/lib/releaseNotes.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6903c5ba..1458c369 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.78.3 \ No newline at end of file +0.78.4 \ No newline at end of file diff --git a/frontend/src/lib/releaseNotes.ts b/frontend/src/lib/releaseNotes.ts index 30d323e2..b09d95a6 100644 --- a/frontend/src/lib/releaseNotes.ts +++ b/frontend/src/lib/releaseNotes.ts @@ -14,6 +14,18 @@ export interface ReleaseEntry { } export const RELEASE_NOTES: ReleaseEntry[] = [ + { + version: "0.78.4", + date: "2026-08-30", + summary: + "A fix for stuttering and stalling when the Plex player transcodes a video — playback now starts cleanly and keeps a healthy buffer, whether you play from the start or resume/seek partway through.", + fixes: [ + "A transcoded Plex video (any format your browser can't play natively) no longer rebuffers every second, and resuming or seeking into one no longer leaves it stuck on “Loading…” forever. The player now starts the stream at the position you asked for and buffers ahead, instead of chasing the live edge of an in-progress transcode.", + ], + chores: [ + "The player builds its HLS client to start at the requested position (the transcode session already begins encoding there), which fixes both the every-second rebuffer and the resume/seek stall in one change. Verified against the HLS library's live-vs-VOD start logic and put through a multi-agent deep-review (correctness, player behaviour, test coverage) that came back clean.", + ], + }, { version: "0.78.3", date: "2026-08-30",