mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
fd96b85c19e4bf21caaff818b607e4fa70d2bd9b
8
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
65f81b7110 |
fix(pwa): bring the Stalker transport to parity with Electron (#1348)
* fix(pwa): bring the Stalker transport to parity with Electron The self-hosted PWA's /stalker proxy now derives its portal requests from the same shared identity and URL builders as the Electron main process: MAG User-Agent/X-User-Agent, full STB cookie (mac + stb_lang + timezone + serial-derived __cfduid), SN header, JsHttpRequest=1-xml defaulting, and the sn-only-on-get_profile rule. macAddress/token/serialNumber are control params consumed into headers and never echoed into the portal's query string (handshake keeps its candidate token — protocol content). The stalker-mock-server /stalker route mirrors the new contract through the same shared builder. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(stalker): forward the full identity header set in the mock /stalker mirror Greptile review: the synthetic portal request kept only the cookie and Authorization from the generated identity, so mock handlers could never validate the SN/MAG-UA/Accept/Language/Connection headers the real proxy sends. Forward the complete set, lowercased the way Express normalizes incoming headers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
297e9fbef8 |
fix(stalker): send cmd in the reference MAG wire format (#1334)
* fix(stalker): send cmd in the reference MAG wire format
A real MAG sends cmd unencoded and the portal decodes its query exactly
once, so a cmd that already contains percent sequences (%3A tokens,
pre-encoded path segments) must pass through untouched. The previous
encodeURIComponent transport (
|
||
|
|
0ee73f2d0f |
feat(m3u): support #KODIPROP lines placed before #EXTINF (#1234)
* feat(m3u): support #KODIPROP lines placed before #EXTINF Bumps the iptv-playlist-parser fork pin to v0.15.2-iptvnator.2: Kodi property lines apply to the next list entry, so #KODIPROP lines placed above the #EXTINF are now preserved in item.raw (previously the parser dropped them and ClearKey config in that layout was lost). The DASH + ClearKey feature (#1225) extracts license config from item.raw, so both KODIPROP layouts now work on every import path. Covered by a parser contract case and an extended web-backend /parse regression (before-EXTINF + between-EXTINF-and-URL + plain channel). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: reflect before-#EXTINF KODIPROP support in the M3U architecture doc Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: list the KODIPROP delta in the parser-fork inventory Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
bd07e17857 |
feat(m3u): DASH + ClearKey playback via Shaka Player (#1225)
* feat(m3u): extract ClearKey DRM from #KODIPROP playlist lines Adds the typed ChannelDrm model (shared interfaces) and a KODIPROP post-processing step in createPlaylistObject() — the single funnel for all four playlist import paths. Parses inputstream.adaptive.license_type, license_key and drm_legacy; ClearKey keys accepted as kid:key hex pairs, W3C ClearKey license JSON, or a plain kid→key JSON map. Unsupported license types (Widevine/PlayReady/license URLs) are preserved with supported=false so playback can surface a DRM diagnostic instead of failing silently. Also adds isDashStreamUrl/isDashChannel helpers for DASH routing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(playback): add Shaka DASH source engine with ClearKey support Introduces ShakaVideoSession (libs/ui/playback/src/lib/shaka-engine/): a lazily imported shaka-player engine (separate lazy chunk, ~217 KB transfer) owning attach/configure/load with an operation queue and generation guard against channel-switch races. Channel ClearKey config maps to drm.clearKeys; channels with an unsupported license type emit a DrmOrEncryption diagnostic without starting an engine. Shaka errors are classified into the existing playback diagnostics (PlaybackDiagnosticSource.Shaka). Wires the engine into both built-in players like hls.js/mpegts.js: - HTML5: extension === 'mpd' branch in playChannel(); hls/mpegts/native glue extracted to helpers to keep the component within the size budget - ArtPlayer: customType 'mpd' in ArtPlayerSourceSession (+ getDrm seam) - Shared controls: WebVideoControlsSource kind 'shaka' + WebVideoShakaControls using the Shaka 5 text model (selectTextTrack(null) hides subtitles; Player.setTextTrackVisibility no longer exists) Adds a CJS shaka-player jest stub (video.js precedent) for web specs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(m3u): route DASH channels to the inline Shaka-capable player DASH (.mpd) channels always play in a built-in web engine (radio precedent): external MPV/VLC cannot receive KODIPROP ClearKey configuration (VLC upstream #29465) and Video.js has no DASH bridge yet. - shouldShowInlinePlayer() bypasses the external-player setting for DASH - new shouldAutoLaunchExternalPlayer() guard consolidates the MPV/VLC auto-launch conditions in the m3u-state effects (incl. catch-up path) - the M3U page overrides the player for DASH channels: ArtPlayer stays ArtPlayer, everything else falls back to the HTML5 player - ChannelDrm is passed through ResolvedPortalPlayback into the synthetic player-view channel Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(e2e): add offline DASH ClearKey fixtures and e2e coverage Fixtures (apps/web-e2e/src/fixtures/dash/): ~4s VP9+Opus DASH, clear and CENC-encrypted variants with fixed synthetic ClearKey credentials. Content synthesized by ffmpeg; encryption done by Shaka Packager because ffmpeg's mp4 muxer writes senc-only metadata (Chromium needs saiz/saio) and cannot produce the subsample encryption the VP9 CENC binding requires. Generation script + README document regeneration. web-e2e (Chromium): import an M3U with KODIPROP ClearKey via raw text, verify encrypted and clear DASH actually play (currentTime advances, no diagnostic banner) and that an unsupported license type (Widevine) surfaces the DRM diagnostic. Fixtures are served through Playwright route interception with HTTP Range support; the Angular service worker is blocked since SW-routed requests bypass interception. electron-backend-e2e: the same happy path + negative against a local Range-aware fixture server — the automated proof that ClearKey EME works in the real Electron runtime (file:// secure context). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: document DASH + ClearKey playback architecture Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(pwa): extract KODIPROP DRM on the web-backend /parse import path The web-backend keeps its own playlist builder for the PWA URL-import path, so the shared createPlaylistObject() DRM hook never ran there and encrypted DASH channels imported by URL reached Shaka without keys. Apply extractDrmFromRaw() in that builder too and cover the path with a regression test. Addresses Codex review on PR #1225. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(playback): interrupt stalled Shaka loads and destroy failed engines Two review findings on the ShakaVideoSession lifecycle: - stop()/start() now tear the current player down immediately instead of queueing the destroy behind the in-flight operation. Shaka's destroy() interrupts a pending load() (LOAD_INTERRUPTED), so a stalled manifest fetch can no longer wedge the operation chain and block the next channel start (Codex P1). - A rejected attach()/load() now destroys the failed player after emitting the diagnostic, so a non-functional engine never stays attached to the media element or exposed to the shared-controls bridge (Greptile P1). Regression tests cover both paths. The Shaka fakes are consolidated into a shared jest-free test double that mirrors the destroy-interrupts-load semantic, and the ArtPlayer source-session spec is split (fixtures + DASH cases) to stay within the max-lines lint budget. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(m3u): unify DASH URL detection with playback extension normalization isDashStreamUrl() used the simpler getStreamExtensionFromUrl(), so URLs the player engines classify as DASH (stream.MPD, ?ext=mpd, ?format=mpd) were not routed to the Shaka-capable inline player and lost their ClearKey metadata with Video.js or external players configured (Codex P2). The normalized getPlaybackMediaExtensionFromUrl() now lives in @iptvnator/shared/m3u-utils (re-exported unchanged from the playback lib) and both routing and engine selection share it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(lint): satisfy CI lint and CodeQL in DASH support files - replace shell-built tar/npm commands with execFileSync arg arrays in the fixture generator (CodeQL: uncontrolled shell command) - give jest stub methods explicit bodies (no-empty-function) - compact the diagnostic label switches in WebPlayerViewComponent to stay under the max-lines budget Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(playback): tear down the Shaka engine on critical error events too A non-recoverable Shaka error emitted after a successful load left the dead engine attached to the media element and exposed to the shared-controls bridge (Greptile P1, round 2). Critical error events now destroy the player right after the diagnostic is emitted, matching the load-failure path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(m3u): honor DASH catch-up URLs and drop unusable DRM fallbacks Two Codex round-2 findings: - The inline-playback DASH gate only examined the channel URL, while the external-player guard checks the resolved catch-up URL — a replay that resolves to an .mpd manifest with MPV/VLC configured ended up with no player at all. The gate now uses the effective playback URL (activePlaybackUrl ?? channel.url). - The unsupported-DRM diagnostic advertised MPV/VLC fallback actions, but external players cannot receive the KODIPROP license config either — the diagnostic no longer recommends them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(playback): suppress unusable external fallback for ClearKey DRM failures Runtime DRM errors on channels that carry KODIPROP ClearKey config (wrong or rotated keys) advertised MPV/VLC fallback actions, but external players never receive the license config — the fallback could only fail differently. DRM-classified diagnostics from such channels no longer recommend external players; clear channels keep the hint. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(m3u): symmetric DASH inline gate and lazy DRM for pre-upgrade playlists - The inline DASH gate is now true when either the channel or the resolved catch-up URL is DASH, mirroring the external-player guard — a .mpd channel whose catch-up resolves to .m3u8 no longer ends up with no player at all. - Playlists imported before the DRM feature carry no drm field, but the raw KODIPROP block survived in the stored items; the M3U page now falls back to extractDrmFromRaw(channel.raw) at playback time, so encrypted channels work without a re-import (Channel gains raw?). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: sync the DASH/Shaka contract across agent docs Mirrors the DASH/Shaka source-engine contract into AGENTS.md and adds Shaka to the shared web-video bridge descriptions in CLAUDE.md and the player-controls contract; documents the lazy raw-KODIPROP DRM fallback for pre-upgrade playlists in the M3U architecture doc. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(playback): reset the media element for rejected DRM and widen ClearKey fallback suppression - Switching from a playing stream to an unsupported-DRM DASH channel loads no new source, but play() still ran and the un-loaded element could resume the previous stream underneath the diagnostic banner. The HTML5 player now resets the element instead of playing. - Any inline failure on a KODIPROP ClearKey channel (manifest, codec, media, network — not just DRM-category errors) is unsolvable in MPV/VLC, which never receive the license config; the external fallback hint is now suppressed for all diagnostics of such channels. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(playback): restore suppressed DASH captions when the preference re-enables The Shaka bridge dropped the auto-selected text track with selectTextTrack(null) when showCaptions was off, but did not remember it — re-enabling the preference mid-session left captions permanently off (HLS/native bridges already restore). The session now remembers the suppressed track id and reselects it via the bridge's caption-state pass; suppression is also skipped when no track is active. Covered by session and new WebVideoShakaControls specs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore: retrigger CI GitHub Actions created no check suites for the last three pushes to this branch (third-party apps received the webhooks); an empty commit re-fires the push and pull_request events. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor(playback): split oversized Shaka session and HTML5 spec files CI lint enforces max-lines 400: extract ShakaTextTrackSuppression and the shaka-error helpers out of ShakaVideoSession, and move the DASH-specific HTML5 player test into its own spec. No behavior change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: allow manual dispatch of the cross-platform E2E workflow GitHub stopped delivering push/pull_request events for this branch; workflow_dispatch provides a manual escape hatch (CI and build-and-make already have one). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
5dbf205935 |
fix(lint): quote eslint globs in web-backend and database lint targets (#1177)
The unquoted globs in these two nx:run-commands lint targets are expanded by the POSIX shell on Linux CI, which matches only a shallow subset of files, while on Windows the literal pattern reaches ESLint and the full tree is linted. Quoting the glob (as tools/packaging already does) makes both platforms lint the same complete file set. Full-tree lint of both projects passes on Windows, so the widened Linux coverage introduces no new errors. Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
20d0f01428 | fix(xtream): address portal review feedback | ||
|
|
254879f92b | fix(xtream): improve portal compatibility | ||
|
|
32cc0b74e8 |
feat: add self-hosted PWA backend runtime (#944)
* feat(web-backend): add self-hosted proxy app * feat(web): enable runtime PWA configuration * test(web-e2e): cover self-hosted backend proxy * test(web-e2e): clean self-hosted lint warnings * fix(web-backend): validate proxied provider URLs * fix(web-backend): proxy through registered provider targets * fix(web-backend): document CodeQL SSRF validation boundary * test(web-e2e): mock provider target registration * fix(web): address self-hosted review feedback |