siftlode/backend/app/plex
npeter83 4e9b18cda9 feat(plex): P2 streaming backend — direct 206 + seek-restart HLS remux
Validated end-to-end on a real remux file (h264+ac3 mkv). The riskiest part of the
Plex epic — on-the-fly playback from the local file — now proven.

- app/plex/stream.py: seek-restart HLS session model (one ffmpeg per item, restarted
  at a seek offset via -ss). Video stream-COPY (I/O-bound, CPU-light — fine on the
  GPU-less prod host) + audio→aac only when not already aac. Maps first video+audio,
  drops subtitles (no VTT rendition clutter). Session cap + idle reaper.
- routes: POST /stream/{rk}/session?start= (direct→raw url, remux→HLS session,
  transcode→501 P3), GET /stream/{rk}/file (206 range, direct), /index.m3u8, /seg_n.ts.
- KEY FINDINGS (hard-won): (1) ffmpeg -hls_playlist_type VOD does NOT write the
  playlist mid-run (only at finalize) → use EVENT (append-only, appears immediately),
  which suits the seek-restart model; (2) naive per-segment copy + keyframe-indexed
  extraction are both unreliable (non-uniform/imprecise segments) — ffmpeg's own HLS
  muxer is the only correct segmenter; (3) dev slowness was the Windows /downloads
  bind-mount write + SMB read → PLEX_HLS_DIR env points scratch at fast container-local
  /var/tmp on dev (prod keeps download_root, fast local disk).
2026-07-05 04:16:45 +02:00
..
__init__.py feat(plex): P0 backend foundations — catalog model, config, client 2026-07-05 01:35:08 +02:00
client.py feat(plex): P0 backend foundations — catalog model, config, client 2026-07-05 01:35:08 +02:00
paths.py feat(plex): P0 backend foundations — catalog model, config, client 2026-07-05 01:35:08 +02:00
stream.py feat(plex): P2 streaming backend — direct 206 + seek-restart HLS remux 2026-07-05 04:16:45 +02:00
sync.py feat(plex): P1 backend — catalog sync + browse/search/show/image API 2026-07-05 02:20:23 +02:00