feat(plex): P2 player — rich full-page HLS/direct player + watch-state
- backend: GET /api/plex/item/{rk} detail (metadata, cast + intro/credit markers
from Plex, episode prev/next, per-user resume+status); POST /item/{rk}/progress
(resume checkpoint, near-end→watched) + /state (new|watched|hidden).
- frontend PlexPlayer.tsx (lazy, pulls hls.js): full-page player over the Plex
module. Direct files stream raw <video>; remux via hls.js on the seek-restart
session — custom controls map the ABSOLUTE timeline over the session offset, and a
seek beyond the loaded region restarts the session at the target. Play/pause/resume
/restart, ±10s seek, prev/next episode (Shift+←/→), volume, windowed/fullscreen,
full keyboard, Skip intro/Skip credits from markers (shaded on the seekbar),
auto-advance + watched-on-end, resume from saved position, 10s progress checkpoints.
- PlexBrowse: card/episode click opens the player as a history subview (browser Back
returns to the grid/show). api client (plexItem/plexSession/plexProgress/plexSetState)
+ types; plex.player.* i18n en/hu/de. hls.js@^1.6.16.
- Verified over HTTP: detail w/ markers+cast+episode-nav, progress persist. Video
playback itself is pending browser UAT. Subtitle/audio track SELECTION deferred.
This commit is contained in:
parent
4e9b18cda9
commit
86b86cb260
9 changed files with 726 additions and 11 deletions
|
|
@ -27,6 +27,18 @@
|
|||
"watched": "Angesehen",
|
||||
"seasons": "{{count}} Staffeln",
|
||||
"playerSoon": "Player kommt bald — „{{title}}“",
|
||||
"player": {
|
||||
"loading": "Wird geladen…",
|
||||
"back": "Zurück",
|
||||
"skipIntro": "Intro überspringen",
|
||||
"skipCredits": "Abspann überspringen",
|
||||
"playPause": "Wiedergabe / Pause (Leertaste)",
|
||||
"restart": "Von vorn beginnen",
|
||||
"prev": "Vorherige Folge",
|
||||
"next": "Nächste Folge",
|
||||
"mute": "Stumm (m)",
|
||||
"fullscreen": "Vollbild (f)"
|
||||
},
|
||||
"playable": {
|
||||
"direct": "Spielt direkt im Browser",
|
||||
"remux": "Braucht ein leichtes Remux (keine Video-Neucodierung)",
|
||||
|
|
|
|||
|
|
@ -27,6 +27,18 @@
|
|||
"watched": "Watched",
|
||||
"seasons": "{{count}} seasons",
|
||||
"playerSoon": "Player coming soon — “{{title}}”",
|
||||
"player": {
|
||||
"loading": "Loading…",
|
||||
"back": "Back",
|
||||
"skipIntro": "Skip intro",
|
||||
"skipCredits": "Skip credits",
|
||||
"playPause": "Play / pause (space)",
|
||||
"restart": "Restart from beginning",
|
||||
"prev": "Previous episode",
|
||||
"next": "Next episode",
|
||||
"mute": "Mute (m)",
|
||||
"fullscreen": "Fullscreen (f)"
|
||||
},
|
||||
"playable": {
|
||||
"direct": "Plays directly in the browser",
|
||||
"remux": "Needs a light remux (no video re-encode)",
|
||||
|
|
|
|||
|
|
@ -27,6 +27,18 @@
|
|||
"watched": "Megnézve",
|
||||
"seasons": "{{count}} évad",
|
||||
"playerSoon": "A lejátszó hamarosan jön — „{{title}}”",
|
||||
"player": {
|
||||
"loading": "Betöltés…",
|
||||
"back": "Vissza",
|
||||
"skipIntro": "Intro átugrása",
|
||||
"skipCredits": "Stáblista átugrása",
|
||||
"playPause": "Lejátszás / szünet (szóköz)",
|
||||
"restart": "Újra az elejéről",
|
||||
"prev": "Előző rész",
|
||||
"next": "Következő rész",
|
||||
"mute": "Némítás (m)",
|
||||
"fullscreen": "Teljes képernyő (f)"
|
||||
},
|
||||
"playable": {
|
||||
"direct": "Közvetlenül játszható a böngészőben",
|
||||
"remux": "Könnyű remux kell (nincs videó-újrakódolás)",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue