From 781f58cb38c4331110b6c74ac747e14563c8339a Mon Sep 17 00:00:00 2001 From: Michael SCHAL Date: Sun, 14 Dec 2025 16:24:20 +0100 Subject: [PATCH] feat: Add IPTV player HTML pages with HLS/MPEG-TS support and parent communication. --- web/player.html | 46 ++++++++++++++++++++++++++++---------------- web/player_lite.html | 46 ++++++++++++++++++++++++++------------------ 2 files changed, 56 insertions(+), 36 deletions(-) diff --git a/web/player.html b/web/player.html index 197d413..c3c07b6 100644 --- a/web/player.html +++ b/web/player.html @@ -511,28 +511,40 @@ log('Stream URL: ' + streamUrl.substring(0, 80) + '...'); - // SPECIAL: /api/stream/ returns JSON with HLS playlist URL + // SPECIAL: /api/stream/ endpoint - differentiate Live vs VOD if (streamUrl.includes('/api/stream/')) { - log('Detected /api/stream/ - fetching HLS playlist...'); - showLoading('Initializing stream (transcoding audio)...'); + // Check if this is a live stream (URL param check since player.html doesn't have type param by default) + const isLiveStream = streamUrl.includes('live') || urlParams.get('type') === 'live'; - try { - const response = await fetch(streamUrl); - const data = await response.json(); + if (isLiveStream) { + // LIVE TV: Use MPEG-TS direct streaming + log('Live TV via /api/stream/ - using MPEG-TS'); + showLoading('Connecting to live stream...'); + await playWithMpegTS(streamUrl); + return; + } else { + // VOD: Fetch JSON to get HLS playlist (transcoding mode) + log('VOD via /api/stream/ - fetching HLS...'); + showLoading('Initializing stream (transcoding audio)...'); - if (data.playlist) { - const playlistUrl = window.location.origin + data.playlist; - log('Playing HLS: ' + playlistUrl); - await playWithHLS(playlistUrl); - return; - } else { - showError('Invalid stream response'); + try { + const response = await fetch(streamUrl); + const data = await response.json(); + + if (data.playlist) { + const playlistUrl = window.location.origin + data.playlist; + log('Playing HLS: ' + playlistUrl); + await playWithHLS(playlistUrl); + return; + } else { + showError('Invalid stream response'); + return; + } + } catch (err) { + log('Error: ' + err); + showError('Stream init failed'); return; } - } catch (err) { - log('Error: ' + err); - showError('Stream init failed'); - return; } } diff --git a/web/player_lite.html b/web/player_lite.html index 45ec16f..1173b73 100644 --- a/web/player_lite.html +++ b/web/player_lite.html @@ -361,30 +361,38 @@ log('Stream type: ' + streamType); const lowerUrl = streamUrl.toLowerCase(); - // SPECIAL: /api/stream/ endpoint returns JSON with HLS playlist URL + // SPECIAL: /api/stream/ endpoint handling - differentiate Live vs VOD if (streamUrl.includes('/api/stream/')) { - log('Detected /api/stream/ - fetching HLS playlist URL...'); - showLoading('Initializing stream (transcoding audio)...'); + if (streamType === 'live') { + // LIVE TV: Use MPEG-TS direct streaming + log('Live TV via /api/stream/ - using MPEG-TS direct'); + showLoading('Connecting to live stream...'); + await playWithMpegTS(streamUrl, true); // isLive=true + return; + } else { + // VOD: Fetch JSON to get HLS playlist URL (transcoding mode) + log('VOD via /api/stream/ - fetching HLS playlist...'); + showLoading('Initializing stream (transcoding audio)...'); - try { - // Fetch JSON response to get playlist URL - const response = await fetch(streamUrl); - const data = await response.json(); + try { + const response = await fetch(streamUrl); + const data = await response.json(); - if (data.playlist) { - const playlistUrl = window.location.origin + data.playlist; - log('Got HLS playlist: ' + playlistUrl); - showLoading('Loading HLS stream...'); - await playWithHLS(playlistUrl); - return; - } else { - showError('Invalid stream response'); + if (data.playlist) { + const playlistUrl = window.location.origin + data.playlist; + log('Got HLS playlist: ' + playlistUrl); + showLoading('Loading HLS stream...'); + await playWithHLS(playlistUrl); + return; + } else { + showError('Invalid stream response'); + return; + } + } catch (err) { + log('Error fetching playlist: ' + err); + showError('Failed to initialize stream'); return; } - } catch (err) { - log('Error fetching playlist: ' + err); - showError('Failed to initialize stream'); - return; } }