mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-14 05:06:16 -08:00
fix(portals): keep external playback, the pin and the resume point honest
Five findings from the round-5 review. An external player launched for an alternative carries that playlist's ids, so the page disowned its own session: the primary button never became Stop, stopping found nothing to stop, and another click opened a second player. Multi-source now tells playback which source is actually active, and the matcher accepts either that or the route's own stream. Stop also has to beat the pin. The primary action consults the pin first — that is what makes a pin decide where playback starts — but while a session is running the same button reads Stop, and consulting the pin there made the control do the opposite of its label. A pinned source started from the Resume button resolved at zero, because nothing reports a live position until the first timeupdate. The controller is now seeded from the persisted position, one-way: a live value always wins, since the stored one lags it and applying it would rewind. A pin whose write failed was still shown as pinned, promising a preference that reopening the movie would not have. Portal failures in this path logged raw errors. An Xtream error message carries the stream URL, and that URL is built out of the username and password, so they now go through the redacting logger. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d3e337261e
commit
df30262f24
16 files changed
+453
-34
No files matched your search
@@ -125,6 +125,11 @@ landed is stored under its title key and prefers a `tmdb:` key afterwards;
|
||||
reading both means the id arriving later does not orphan the pin, and unpinning
|
||||
clears every alias so a stale row cannot resurrect it.
|
||||
|
||||
The row only changes once the write lands. A pin the database refused is worse
|
||||
than no pin at all — the icon promises the preference will be there next time,
|
||||
and it will not be — so `togglePinnedSource` reports "nothing happened" and the
|
||||
controller is left exactly as it was.
|
||||
|
||||
### Rediscovery vs. a new session
|
||||
|
||||
Two keys, deliberately, because the host has two different questions to answer
|
||||
@@ -214,6 +219,13 @@ Three details make the position survive:
|
||||
a switch changes the key. The resolved playback carries the **new** source's
|
||||
`contentInfo`, and that source's row takes over.
|
||||
|
||||
The position also has to exist *before* anything plays. Nothing reports a live
|
||||
one until the first `timeupdate`, so a pinned source started straight off the
|
||||
Resume button would resolve at zero and restart the film. The controller is
|
||||
therefore seeded from the persisted position (`seedResumeSeconds`), one-way:
|
||||
once a live position exists it wins, because the stored one lags it by up to
|
||||
the save throttle and applying it would visibly rewind.
|
||||
|
||||
A resuming engine can emit a `timeupdate` at ~0 before it finishes seeking.
|
||||
`VodDetailsPlaybackService` guards this with a one-shot `resumeSettled` latch —
|
||||
a filter would have broken deliberate seek-backwards. `handleInlineTimeUpdate`
|
||||
@@ -259,6 +271,22 @@ Web engines only (HTML5/hls.js, Video.js, ArtPlayer). Embedded MPV suppresses
|
||||
shared diagnostics and owns its own error block; external MPV/VLC are
|
||||
fire-and-forget with no error channel back.
|
||||
|
||||
## External players and an alternative source
|
||||
|
||||
A switch goes through the same inline-vs-external fork a normal Play takes, so
|
||||
with MPV or VLC configured the alternative opens in the external player — and
|
||||
that session carries the OTHER playlist's ids. `matchedExternalPlayback` would
|
||||
disown it: the primary button never became Stop, stopping found no session, and
|
||||
another click opened a second player. The page therefore claims a session that
|
||||
matches either the route's own stream or the alternative multi-source says is
|
||||
active (`VodDetailsPlaybackBindings.activeSource`).
|
||||
|
||||
Stop then has to win over the pin. The primary action consults the pin first —
|
||||
that is what makes "make this the main source" decide where playback starts —
|
||||
but when a session is already running the same button reads Stop, and doing
|
||||
anything other than stopping would launch a second player while the first kept
|
||||
going.
|
||||
|
||||
## PWA
|
||||
|
||||
Discovery, foreign-playlist reads, the pin table and the probe are all
|
||||
|
||||
Reference in new issue
Block a user