Commit Graph
14 Commits
Author SHA1 Message Date
4gray 877d632255 fix(playback): structure Video.js diagnostics 2026-07-31 08:40:33 +02:00
4gray 9ae53e4515 fix(playback): make the "Show subtitles" setting reach the web players (#1269)
The persisted subtitle preference only ever had an owner behind the default-off
shared web-controls flag, so with the shipping controls it did nothing: Video.js
never read it, ArtPlayer declared the input but never used it, and the HTML5
player only ran a one-shot pass after play() resolved — before hls.js had added
its text tracks. No portal host bound the input at all, so it never reached
Xtream or Stalker pages either.

Extract the source-local track controllers into the adapter-free
WebVideoSourceTracks and have WebVideoSourceControlsBridge wrap it, so both
controls modes apply the preference through the same code. The preference-off
players bind it directly (VjsLegacyTracks for Video.js), and
WebPlayerViewComponent reads the preference from SettingsStore instead of an
input so every host inherits it.

The preference means different things depending on who renders the caption UI:
shared controls stay authoritative for the session, while vendor chrome is
source-default — the preference seeds each new source and is released once the
media reports playing, so the engine own caption menu keeps working. Mode
selection is an optional playbackStarted probe passed to the HLS, native and
Shaka helpers; in that mode the HLS helper deselects the track rather than
hiding it, since subtitleDisplay would silently override the vendor menu.

Closes #1155
2026-07-26 09:26:40 +02:00
4grayandClaude Fable 5 6dc8a10d52 feat(playback): show media title overlay in fullscreen shared controls (#1228)
* feat(playback): show media title overlay in fullscreen shared controls

In fullscreen with the shared player-controls layer, a pointer-transparent
overlay at the top of the player now names the content while controls are
revealed: one line for movies and live channels, two lines for series
(series name + S01E03 label). The overlay follows the bar's auto-hide
transition and stays hidden outside fullscreen, where page chrome already
names the content.

Data flows top-down: the Xtream/Stalker series detail views pass the series
name via a new PortalInlinePlayerComponent.seriesTitle input (Xtream episode
playback titles carry the episode name, not the series), the inline player
builds the two-line form from the episode metadata label, and
WebPlayerViewComponent falls back to playback.title for movies/channels
while skipping raw stream-URL fallbacks. All four shared-controls hosts
(HTML5, Video.js, ArtPlayer, Embedded MPV frame-copy) forward the value.

To stay under the max-lines limit, scrub/timeline state is extracted into
ControlsTimeline and the playback-diagnostics display helpers into
web-player-view-diagnostics.utils.ts, with behavior unchanged.

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

* docs: mirror fullscreen media-title contract into AGENTS.md

Addresses Codex review: the Shared Player Controls section in AGENTS.md
must stay in sync with the CLAUDE.md description of the new mediaTitle
input, fullscreen overlay behavior, and series-title wiring.

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 18:41:52 +02:00
4grayandLars Emig 4e572c60ca feat(videojs): add feature-flagged shared controls (#1195)
* feat(videojs): add feature-flagged shared controls

Rebuild the Video.js shared-controls integration on the current player lifecycle with Tech rebinds, source-scoped tracks, reset ordering, volume preservation, diagnostics gating, and default-off compatibility.

Credits and supersedes the stacked implementation proposed in #1153.

Co-authored-by: Lars Emig <lars.emig@pickware.de>

* fix(videojs): harden MPEG-TS reset lifecycle

---------

Co-authored-by: Lars Emig <lars.emig@pickware.de>
2026-07-16 23:08:18 +02:00
4gray 8d672f8b81 feat(playback): add web player series navigation (#1049) 2026-06-13 10:19:57 +02:00
4gray 4ab8915483 chore(web): enable strict TypeScript mode 2026-05-22 02:58:12 +03:00
4gray 118d4fce32 fix(playback): improve inline stream diagnostics (#952)
* fix(playback): improve inline stream diagnostics

* fix(playback): preserve headers in diagnostics wrapper

* fix(portal): align unified live player imports
2026-05-18 23:59:20 +02:00
4gray 2d5c4fa4f9 chore: tighten validation and runtime logging
* chore: tighten validation and runtime logging

* fix(i18n): localize new settings labels
2026-05-15 17:43:42 +02:00
4gray 8f79b25f52 fix(playback): treat portal mpeg-ts vod as non-live 2026-05-15 01:07:23 +02:00
4gray 4a4334cb64 feat(playback): improve browser-player diagnostics (#939)
* feat(playback): diagnose browser stream access errors
Entire-Checkpoint: f957cd9849e0

* feat(playback): expose browser-player diagnostic details
Entire-Checkpoint: f957cd9849e0

* fix(playback): keep media path extensions authoritative
Entire-Checkpoint: f957cd9849e0

* fix(playback): tighten browser access diagnostics
Entire-Checkpoint: f957cd9849e0

* fix(playback): align diagnostic followups
Entire-Checkpoint: f957cd9849e0

* fix(playback): narrow declared stream metadata
Entire-Checkpoint: f957cd9849e0

* fix(playback): preserve explicit extension overrides
Entire-Checkpoint: f957cd9849e0

* fix(playback): keep mpeg-ts out of unsupported containers
Entire-Checkpoint: f957cd9849e0

* refactor(playback): split diagnostics utilities
Entire-Checkpoint: f957cd9849e0

* fix(playback): treat mpegts early eof as media fallback
Entire-Checkpoint: f957cd9849e0
2026-05-15 00:55:23 +02:00
Toni Orioland4gray 2f9aef1578 fix(playback): handle IPTV proxy URLs without file extensions (#934)
* fix(playback): handle IPTV proxy URLs without file extensions

IPTV proxy servers (Acexy, Xtream Codes, etc.) use query-string URLs
like `https://proxy.example.com/ace/getstream?infohash=abc` that return
raw MPEG-TS streams without a file extension in the path.

`getExtensionFromUrl()` was returning garbage for these URLs (e.g.
`com/ace/getstream` from splitting on dots across path segments). All
four player backends then misrouted the stream — typically to HLS.js
which failed because the response is raw MPEG-TS, not an HLS manifest.

Root fix: rewrite `getExtensionFromUrl()` to extract the extension from
the last path segment only, returning `undefined` when there is no
dot-separated extension.

Player adjustments: treat `undefined` extension as MPEG-TS (the most
common format for live IPTV proxy streams) across all four backends
(HTML5, ArtPlayer, VideoJs, web-player-view).

* test(m3u-utils): cover URL extension parsing

* fix(playback): preserve query-declared stream extensions

---------

Co-authored-by: 4gray <serega05@gmail.com>
2026-05-14 00:13:08 +02:00
4gray 6305dcf00e Add browser playback diagnostics and MPV/VLC fallback (#921)
* feat(playback): add codec diagnostics fallback
Entire-Checkpoint: f957cd9849e0

* fix(playback): address diagnostics review feedback
Entire-Checkpoint: f957cd9849e0

* fix(playback): ignore recoverable hls diagnostics
Entire-Checkpoint: f957cd9849e0

* fix(playback): polish diagnostic fallback banner
Entire-Checkpoint: f957cd9849e0

* fix(xtream): preserve live category search scope
Entire-Checkpoint: f957cd9849e0
2026-05-10 17:27:54 +02:00
4gray 5f4cf01467 fix(playback): avoid redundant VideoJS source resets (#920)
* fix(playback): avoid redundant VideoJS source resets

* fix(playback): clean up cleared VideoJS sources

* refactor(playback): use signal APIs in VideoJS player

closes #608
2026-05-10 15:32:00 +02:00
4gray 7ac2fd66b8 refactor: update nx monorepo structure 2026-03-09 23:24:34 +01:00