Add Enigma2/OpenWebif M3U support: program mapping and zap-before-streaming
- 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>
This commit is contained in:
@ -33,7 +33,9 @@ transcodeSession.startCleanupInterval();
|
||||
* Body: { url: string, seekOffset?: number }
|
||||
*/
|
||||
router.post('/session', startupLimit, async (req, res) => {
|
||||
const { url, seekOffset, videoMode, videoCodec, audioCodec, audioChannels, videoHeight, playbackLeaseId, requestSequence, isLive } = req.body;
|
||||
const { url, seekOffset, videoMode, videoCodec, audioCodec, audioChannels, videoHeight, playbackLeaseId, requestSequence, isLive, program } = req.body;
|
||||
// MPEG-TS program number (Enigma2 multi-program streams); digits only
|
||||
const programNumber = /^\d+$/.test(String(program ?? '')) ? String(program) : null;
|
||||
const normalizedSeek = Number(seekOffset ?? 0);
|
||||
if (!Number.isFinite(normalizedSeek) || normalizedSeek < 0) return res.status(400).json({ error: "Invalid seek offset" });
|
||||
let session = null, disconnected = false;
|
||||
@ -72,7 +74,8 @@ router.post('/session', startupLimit, async (req, res) => {
|
||||
videoCodec: videoCodec, // 'h264', 'hevc', etc.
|
||||
audioCodec: audioCodec, // 'aac', 'ac3', etc.
|
||||
audioChannels: audioChannels, // number of channels (2=stereo)
|
||||
videoHeight: videoHeight // source height from probe; used to cap max-resolution in JS
|
||||
videoHeight: videoHeight, // source height from probe; used to cap max-resolution in JS
|
||||
program: programNumber
|
||||
});
|
||||
|
||||
if (disconnected) { await transcodeSession.removeSession(session.id, req.user.id); return; }
|
||||
|
||||
Reference in New Issue
Block a user