fix(plex): play subtitles as WebVTT tracks (external sidecar subs no longer crash)

Selecting a subtitle restarted the HLS session with `-map 0:s:{ord}`, assuming an
EMBEDDED stream. Films whose subs are external sidecar .srt files (Plex reports
them, but they aren't in the mkv) matched no stream; the master-playlist's
declared subtitle group then made ffmpeg fail → "Playback couldn't start".

Subtitles now go through a new GET /api/plex/subtitle/{rk}/{ord} → text/vtt
(external subs fetched from Plex via the stream key + SRT→VTT; embedded text subs
extracted with ffmpeg; image subs → 415), served as native <video><track> that
the browser overlays. So choosing/switching a subtitle is instant with NO session
restart, and stream.py drops all subtitle muxing (`-sn`, no master playlist).
Image-based subs (PGS/VobSub) are marked text=false and hidden in the picker.
Verified on prod's Nymphomaniac Vol. II: HU sidecar → 1693 WebVTT cues, no crash.
This commit is contained in:
npeter83 2026-07-06 08:45:30 +02:00
parent 335e4d7c76
commit c8c027d0fc
7 changed files with 206 additions and 89 deletions

View file

@ -113,6 +113,16 @@ class PlexClient:
items = mc.get("Metadata", []) or []
return items[0] if items else None
def raw_get(self, path: str) -> bytes:
"""Raw bytes of an arbitrary Plex resource path (e.g. an external subtitle stream `key` like
``/library/streams/553184``). Keeps the admin token server-side."""
try:
r = self._http.get(f"{self.base}{path}")
r.raise_for_status()
except httpx.HTTPError as e:
raise PlexError(str(e)) from e
return r.content
def image_bytes(
self, image_path: str, width: int | None = None, height: int | None = None
) -> tuple[bytes, str]: