Keep server-side search and cursor pagination for Home and Guide while allowing Live to load the complete filtered catalogue.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Avoid repeated category scans while filtering the paginated Live catalog, and keep the search timing and query-plan reproductions in the regression suite.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Load Live channels from a filtered SQLite cursor API, keep navigation and guide consumers working across pages, and retain the QA reproduction coverage.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Parse #EXTVLCOPT:program=N from M3U playlists (both full and streaming
parsers, per channel, strict mode) and store it on playlist items
- Transcode multi-program MPEG-TS streams by mapping only the selected
program's first video and audio stream (DVB teletext/subtitles in the
program otherwise make FFmpeg fail to produce HLS)
- Optional per-source "zap before streaming" with configurable delay:
POST /api/openwebif/zap takes sourceId + streamId, requires an enabled,
zap-enabled M3U source containing that channel, derives the receiver
from the configured source URL (never from the client), validates the
Enigma2 service reference, uses a timeout without redirects and does
not echo the receiver response
- Live TV: Stop button, and stop playback when leaving the page
- Tests for ordinary and program-tagged playlists and the zap endpoint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adapted from MikaelKW/nodecast-tv-plus playback lease work beginning at 43a58c7685f541498663b827c4b9d6b3753e7202. Reject superseded requests, release on cancellation, bound live restart attempts and await FFmpeg close before deleting cache.
Co-authored-by: Mikael <mikaelkwessel@gmail.com>
Adapted cookie, origin, URL validation and secret handling from MikaelKW/nodecast-tv-plus. Protect API roles, revoke logins across restart, preserve existing accounts, and isolate transcode sessions by account.
Co-authored-by: Mikael <mikaelkwessel@gmail.com>
Adapted from MikaelKW/nodecast-tv-plus commits c267d98d734753a09b08d267c8ec2c3fa11c33f5, b761690bac7626a3cc5ddf754d96b14a02f506fe, and 5524fdaffed5c6a44ae69474e7eaa2f18d428c75. Preserve every parser batch, decode gzip once, and retain live channel metadata.
Co-authored-by: Mikael <mikaelkwessel@gmail.com>
Adapted from MikaelKW/nodecast-tv-plus commit 011b634417b2ecd2a2844df9808b42de831ba194. Use awaited pipeline, abort upstream on disconnect, avoid retries after headers, preserve real range support, and rewrite bounded manifests using relative proxy paths. Cover interrupted streams, first-byte delivery, ranges, redirects, split signatures, and invalid inputs.
Co-authored-by: Mikael <mikaelkwessel@gmail.com>
Adapted from MikaelKW/nodecast-tv-plus commit 55cb8de23a37eb5683459bffed9b64c6c5dd73ae. Queue reads, validations, and writes together; return write errors to callers; preserve existing IDs and metadata; route source/user edits through the atomic operations. Cover concurrent writes, stale edits, queue recovery, and administrator races.
Co-authored-by: Mikael <mikaelkwessel@gmail.com>
Allow nested crypto for encrypted HTTP HLS while rejecting top-level protocol wrappers and local-file access. Replace the HLS-only http_persistent option with HTTP multiple_requests across probe/remux/transcode paths, fixing the raw HTTP regression introduced by #124. Add real FFmpeg regression tests and PR CI.
The /api/remux endpoint passed the user-supplied 'url' query parameter
straight to 'ffmpeg -i <url>'. spawn() with an argv array prevented shell
injection, but ffmpeg itself accepts a wide set of protocol handlers
(file://, concat:, subfile:, data:, pipe:, crypto:, async:, cache:, ...)
that read from the local filesystem or compose existing protocols.
Because the resulting ffmpeg stdout is piped directly back to the
response, an attacker who could call /api/remux could read arbitrary
local files (e.g. ?url=file:///etc/passwd, concat:file://...).
Apply two layers of defence at the entry point only:
1. validateStreamUrl(): reject anything that is not a syntactically valid
http:// or https:// URL, and reject any string containing control
characters before parsing (so CR/LF/NUL cannot be silently stripped).
2. Pass -protocol_whitelist http,https,tls,tcp,hls to ffmpeg so that even
if a future code path forwarded a different URL, ffmpeg would refuse
to open file/concat/subfile/pipe/data/crypto/async/cache inputs.
Legitimate http/https stream URLs (including ports, userinfo, queries,
and HLS playlists) continue to work; only non-network schemes and
malformed inputs are rejected with HTTP 400.
Was running into an issue where epg wouldn't process passed the first batch. Refactored the batching to use an array and added backpressure to keep memory usage low.