[ci skip] Add native HLS playback for VIPLeague/DaddyLive streams (v1.3.1)
- Add HLS proxy (hlsproxy) for rewriting m3u8 playlists and proxying segments with correct Referer/Origin headers (uses ?domain= param) - Add playerconfig service for detecting stream types (VIPLeague, DaddyLive, HLS) and extracting auth params from ksohls pages - Add VIPLeague URL resolution: extract slug from URL path, match against DaddyLive 24/7 channel index with token-based scoring - Replace Clappr with direct HLS.js player for better compatibility - Add CryptoJS CDN for DaddyLive auth module support - Disable CrowdSec on f1-stream ingress to prevent false positives - Bump image to v1.3.1
This commit is contained in:
parent
a5f9c1595f
commit
0ff2aaec60
10 changed files with 1049 additions and 51 deletions
|
|
@ -317,9 +317,9 @@ function closeRedditViewer() {
|
|||
contentEl.querySelectorAll(':scope > :not(#reddit-viewer-loader)').forEach(el => el.remove());
|
||||
}
|
||||
|
||||
// --- Browser Session Viewer (Iframe Proxy) ---
|
||||
// --- Browser Session Viewer (Iframe Proxy + Native Player) ---
|
||||
|
||||
function openBrowserSession(streamId, streamTitle, streamURL) {
|
||||
async function openBrowserSession(streamId, streamTitle, streamURL) {
|
||||
const viewer = document.getElementById('browser-viewer');
|
||||
const statusEl = viewer.querySelector('.browser-viewer-status');
|
||||
const contentEl = viewer.querySelector('.browser-viewer-content');
|
||||
|
|
@ -331,7 +331,41 @@ function openBrowserSession(streamId, streamTitle, streamURL) {
|
|||
statusEl.classList.remove('connected');
|
||||
loader.classList.remove('hidden');
|
||||
|
||||
// Parse the stream URL to extract origin and path
|
||||
if (urlText) urlText.textContent = streamURL;
|
||||
if (openOriginal) openOriginal.href = streamURL;
|
||||
|
||||
// Hide all tab content sections and show the viewer
|
||||
document.querySelectorAll('.tab-content').forEach(s => s.classList.remove('active'));
|
||||
viewer.classList.remove('hidden');
|
||||
viewer.classList.add('active');
|
||||
|
||||
// Remove any existing iframe or player
|
||||
contentEl.querySelectorAll('.browser-iframe').forEach(el => el.remove());
|
||||
contentEl.querySelectorAll('#clappr-player').forEach(el => el.remove());
|
||||
destroyNativePlayer();
|
||||
|
||||
// Fetch player config to determine stream type
|
||||
const config = await getPlayerConfig(streamId);
|
||||
|
||||
if (config.type === 'hls' || config.type === 'daddylive') {
|
||||
// Native player mode
|
||||
const playerDiv = document.createElement('div');
|
||||
playerDiv.id = 'clappr-player';
|
||||
contentEl.appendChild(playerDiv);
|
||||
|
||||
loader.classList.add('hidden');
|
||||
statusEl.textContent = 'Playing';
|
||||
statusEl.classList.add('connected');
|
||||
|
||||
if (config.type === 'daddylive') {
|
||||
createDaddyLivePlayer('#clappr-player', config);
|
||||
} else {
|
||||
createHLSPlayer('#clappr-player', config.hls_url);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Fallback: iframe proxy mode
|
||||
let parsed;
|
||||
try {
|
||||
parsed = new URL(streamURL);
|
||||
|
|
@ -344,25 +378,9 @@ function openBrowserSession(streamId, streamTitle, streamURL) {
|
|||
|
||||
const origin = parsed.origin;
|
||||
const pathAndSearch = parsed.pathname + parsed.search + parsed.hash;
|
||||
|
||||
// Base64-encode the origin (URL-safe, no padding)
|
||||
const b64Origin = btoa(origin).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
||||
|
||||
// Build proxy URL
|
||||
const proxyURL = '/proxy/' + b64Origin + pathAndSearch;
|
||||
|
||||
if (urlText) urlText.textContent = streamURL;
|
||||
if (openOriginal) openOriginal.href = streamURL;
|
||||
|
||||
// Hide all tab content sections and show the viewer
|
||||
document.querySelectorAll('.tab-content').forEach(s => s.classList.remove('active'));
|
||||
viewer.classList.remove('hidden');
|
||||
viewer.classList.add('active');
|
||||
|
||||
// Remove any existing iframe
|
||||
contentEl.querySelectorAll('.browser-iframe').forEach(el => el.remove());
|
||||
|
||||
// Create iframe with sandbox to prevent frame-busting and top-navigation
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = proxyURL;
|
||||
iframe.className = 'browser-iframe';
|
||||
|
|
@ -378,11 +396,13 @@ function openBrowserSession(streamId, streamTitle, streamURL) {
|
|||
}
|
||||
|
||||
function closeBrowserSession() {
|
||||
destroyNativePlayer();
|
||||
const viewer = document.getElementById('browser-viewer');
|
||||
viewer.classList.add('hidden');
|
||||
viewer.classList.remove('active');
|
||||
const contentEl = viewer.querySelector('.browser-viewer-content');
|
||||
contentEl.querySelectorAll('.browser-iframe').forEach(el => el.remove());
|
||||
contentEl.querySelectorAll('#clappr-player').forEach(el => el.remove());
|
||||
const statusEl = viewer.querySelector('.browser-viewer-status');
|
||||
statusEl.textContent = '';
|
||||
statusEl.classList.remove('connected');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue