(function(){ const name = document.documentElement.dataset.stream; const v = document.getElementById('v'); const liveEl = document.getElementById('live'); const viewersEl = document.getElementById('viewers'); const srcEl = document.getElementById('hlssrc'); const manifest = '/hls/' + encodeURIComponent(name) + '/index.m3u8'; function setLive(l){ liveEl.className = 'pill ' + (l ? 'live' : 'off'); liveEl.textContent = l ? 'LIVE' : 'Offline'; } async function head(url){ try { const r = await fetch(url, { method: 'HEAD', cache:'no-store' }); return r.ok; } catch (_) { return false; } } async function tryInitPlayer(){ // 1) Manifest erreichbar? const ok = await head(manifest); srcEl.textContent = manifest; setLive(ok); if (!ok) return false; // 2) Player initialisieren try { if (window.Hls && Hls.isSupported()) { if (!window._hls) { window._hls = new Hls({ maxLiveSyncPlaybackRate: 1.0 }); window._hls.on(Hls.Events.ERROR, (_, data)=>console.warn('hls.js error', data)); window._hls.attachMedia(v); } window._hls.loadSource(manifest); } else if (v.canPlayType('application/vnd.apple.mpegurl')) { v.src = manifest; // Safari / iOS } else { console.warn('HLS nicht unterstützt'); return false; } return true; } catch (e) { console.warn('Player init fail', e); return false; } } async function refreshMeta(){ // UI-Infos (viewer count etc.) optional, darf nie Player blockieren try { const r = await fetch('/api/streams', { cache:'no-store' }); if (!r.ok) return; const d = await r.json(); const it = d.items.find(x=>x.name===name); if (it) { setLive(!!it.live); viewersEl.textContent = 'Zuschauer: ' + it.viewers; } } catch (_) {} } // Video-Fehler sichtbar loggen v.addEventListener('error', (e)=>console.warn('video error', e)); v.addEventListener('loadedmetadata', ()=>console.log('metadata loaded')); v.addEventListener('playing', ()=>console.log('playing')); // Boot-Sequenz mit Retries (async function boot(){ for (let i=0; i<10; i++) { const ok = await tryInitPlayer(); if (ok) break; await new Promise(r=>setTimeout(r, 1500)); // kurz warten, bis HLS bereit ist } refreshMeta(); setInterval(refreshMeta, 2500); })(); })();