fix(playback): apply saved player changes to mounted web players (#1437)

* fix(playback): apply saved player changes to mounted web players

WebPlayerViewComponent resolved the saved engine from a one-shot
StorageMap snapshot taken at mount, so a player switch from the command
palette or settings page confirmed via snackbar and persisted the
setting while an already-mounted Xtream/Stalker player silently kept
the previous engine. The same snapshot also made first play mount the
default Video.js engine and swap to the saved one once the async read
landed.

Resolve the player (and recording folder) from the live SettingsStore
signal instead and drop the snapshot entirely. Precedence is unchanged:
temporary recovery override -> host playerOverride -> saved player ->
Video.js. Hosts passing no override (Xtream/Stalker live layouts, the
portal inline detail player) now track saved changes in place; first
mount reads the already-loaded store, so the default engine no longer
flashes.

Regression coverage (all verified to fail with the fix reverted):
three unit tests on the component and two Xtream live-route e2e tests —
a palette switch reaching the mounted player without a layout remount,
and a MutationObserver engines-ever-seen assertion that the saved
engine mounts first time.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(playback): retain mounted engine when saved player becomes MPV/VLC

With the saved player now live-tracked, a mid-session palette switch to
managed MPV/VLC cleared the inline binding on hosts without a
playerOverride and left a blank viewport — the web player view can
neither render nor launch external players. resolveRenderableWebPlayer
keeps the mounted engine in that case; the external choice applies when
the host starts the next playback. Renderable players, including
Embedded MPV, still apply live. Raised by Codex review (P2).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Fable 5 authored and GitHub committed 2026-08-13 18:57:55 +02:00
1 parent 61fca6f016
commit 3103eba083
6 files changed
+314 -29

No files matched your search

+17 -1
View File
@@ -364,7 +364,23 @@ Current contract:
The shared `WebPlayerViewComponent` is the central browser-player viewport for
M3U, Xtream, and Stalker inline playback, including live streams opened from
favorites and recently viewed collections. Video.js, HTML5, and ArtPlayer
favorites and recently viewed collections.
The mounted engine resolves in a fixed order: temporary recovery override →
host `playerOverride` input → the saved player read from the live
`SettingsStore` signal (Video.js as the last-resort default). The saved player
is deliberately NOT a mount-time storage snapshot: persisting a different
player — from the settings page or the command palette — re-applies to every
mounted `WebPlayerViewComponent` in place as a new playback application, and a
first mount reads the already-loaded store value so the default engine never
flashes before the saved one. Hosts that pass no `playerOverride` (the Xtream
and Stalker live layouts, the portal inline detail player) rely on this live
tracking. A saved switch to managed MPV/VLC is the one exception
(`resolveRenderableWebPlayer`): the viewport can neither render nor launch an
external player, so the mounted engine is retained and the external choice
applies when the host starts the next playback.
Video.js, HTML5, and ArtPlayer
report native media errors, hls.js errors, Video.js/VHS errors, Shaka errors,
mpegts.js errors, and HLS manifest codec metadata into the DOM-free classifiers
exported by `@iptvnator/playback/util`.