bugfix-5
All checks were successful
release-tag / release-image (push) Successful in 2m2s

This commit is contained in:
2025-09-21 19:41:55 +02:00
parent f62d7e62c5
commit 0df6795da2

View File

@@ -5,27 +5,34 @@
const viewersEl = document.getElementById('viewers'); const viewersEl = document.getElementById('viewers');
const srcEl = document.getElementById('hlssrc'); const srcEl = document.getElementById('hlssrc');
const manifest = '/hls/' + encodeURIComponent(name) + '/index.m3u8'; function setLive(on){
liveEl.className = 'pill ' + (on ? 'live' : 'off');
function setLive(on){
liveEl.className = 'pill ' + (on ? 'live' : 'off');
liveEl.textContent = on ? 'LIVE' : 'Offline'; liveEl.textContent = on ? 'LIVE' : 'Offline';
} }
async function head(u){ async function chooseManifest() {
try { const r = await fetch(u, {method:'HEAD', cache:'no-store'}); return r.ok; } const enc = encodeURIComponent(name);
catch { return false; } const candidates = [
`/hls/${enc}/index.m3u8`,
`/hls/${enc}/main_stream.m3u8`, // Fallback, wenn es keinen Master gibt
];
for (const url of candidates) {
try {
const r = await fetch(url, { cache: 'no-store' });
if (r.ok) return url; // WICHTIG: GET statt HEAD
} catch (_) {}
}
return null;
} }
async function initPlayer() { async function initPlayer() {
srcEl.textContent = manifest; const url = await chooseManifest();
const ok = await head(manifest); if (!url) { setLive(false); return false; }
setLive(ok);
if (!ok) return false;
// Autoplay-Chance verbessern srcEl.textContent = url;
try { v.muted = true; } catch(_) {} setLive(true);
try { v.playsInline = true; } catch(_) {}
try { v.muted = true; v.playsInline = true; } catch(_) {}
if (window.Hls && Hls.isSupported()) { if (window.Hls && Hls.isSupported()) {
if (!window._hls) { if (!window._hls) {
@@ -38,23 +45,21 @@
}); });
window._hls.attachMedia(v); window._hls.attachMedia(v);
} }
window._hls.loadSource(manifest); window._hls.loadSource(url);
} else if (v.canPlayType('application/vnd.apple.mpegurl')) { } else if (v.canPlayType('application/vnd.apple.mpegurl')) {
v.src = manifest; // Safari / iOS v.src = url; // Safari / iOS
} else { } else {
console.warn('HLS nicht unterstützt'); console.warn('HLS nicht unterstützt');
return false; return false;
} }
// Autoplay versuchen (wird bei Desktop-Browsern oft blockiert; Controls bleiben) try { await v.play(); } catch(e){ console.log('autoplay blockiert (ok):', e?.name||e); }
try { await v.play(); } catch(e) { console.log('autoplay blockiert (ok):', e?.name||e); }
return true; return true;
} }
async function refreshMeta(){ async function refreshMeta(){
try { try {
const r = await fetch('/api/streams', {cache:'no-store'}); const r = await fetch('/api/streams', { cache: 'no-store' });
if (!r.ok) return; if (!r.ok) return;
const d = await r.json(); const d = await r.json();
const it = d.items.find(x => x.name === name); const it = d.items.find(x => x.name === name);
@@ -62,7 +67,7 @@
setLive(!!it.live); setLive(!!it.live);
viewersEl.textContent = 'Zuschauer: ' + it.viewers; viewersEl.textContent = 'Zuschauer: ' + it.viewers;
} }
} catch {} } catch (_) {}
} }
v.addEventListener('error', e => console.warn('video error', e)); v.addEventListener('error', e => console.warn('video error', e));
@@ -70,7 +75,7 @@
v.addEventListener('playing', () => console.log('playing')); v.addEventListener('playing', () => console.log('playing'));
(async function boot(){ (async function boot(){
for (let i=0; i<10; i++) { for (let i=0; i<10; i++){
const ok = await initPlayer(); const ok = await initPlayer();
if (ok) break; if (ok) break;
await new Promise(r => setTimeout(r, 1500)); await new Promise(r => setTimeout(r, 1500));