Adiciona env vars de defaults de UI e melhora compatibilidade mobile dos players
--- - Adicionado endpoint GET /api/config que expõe as env vars de defaults para o frontend; - Adicionadas env vars DEFAULT_PURE_MODE, DEFAULT_OPEN_NEW_TAB, DEFAULT_RELOAD_CLIENT e DEFAULT_RELOAD_CLIENT_TIME ao docker-compose.yml e README.md; - Na primeira sessão sem global-prefs em localStorage, a UI busca os defaults do servidor via /api/config; - Adicionado fallback de HLS nativo para iOS Safari em todos os players HTML (Hls.isSupported() → v.src + v.play()); - Substituído AbortSignal.timeout() por AbortController + setTimeout para compatibilidade com iOS ≤ 15; - Corrigido stall detection falso-positivo: verificação só dispara após currentTime > 0 (vídeo realmente iniciado); - Adicionado height: 100dvh nos players para corrigir clipping do iOS causado pelo 100vh incluir a chrome bar do browser; - Adicionado atributo muted no <video> do player /static/[id] para permitir autoplay mobile; - Adicionado listener de touchstart nos botões flutuantes de Back e Mute para exibição em touch; - Botão Back do player React ampliado no mobile (px-5 py-3 text-[1.1rem]) para paridade visual com o player HTML; - Comentários do docker-compose.yml traduzidos para inglês e reorganizados inline; ---
This commit is contained in:
+25
-8
@@ -2,10 +2,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
*{margin:0;padding:0;box-sizing:border-box}
|
||||
html,body{background:#000;overflow:hidden;width:100%;height:100%}
|
||||
video{width:100vw;height:100vh;display:block;object-fit:contain}
|
||||
video{width:100vw;height:100vh;height:100dvh;display:block;object-fit:contain}
|
||||
#msg{
|
||||
position:fixed;top:16px;left:50%;transform:translateX(-50%);
|
||||
background:rgba(0,0,0,0.75);color:#fff;padding:8px 20px;
|
||||
@@ -34,30 +35,46 @@
|
||||
|
||||
function load(src){
|
||||
activeSrc=src;
|
||||
var v=document.getElementById('v');
|
||||
if(hls)hls.destroy();
|
||||
if(!Hls.isSupported()){
|
||||
if(v.canPlayType('application/vnd.apple.mpegurl')){
|
||||
v.src=src;
|
||||
var p=v.play();
|
||||
if(p)p.catch(function(){v.muted=true;v.play();});
|
||||
}
|
||||
return;
|
||||
}
|
||||
hls=new Hls({
|
||||
liveSyncDurationCount:2,liveMaxLatencyDurationCount:4,
|
||||
manifestLoadingTimeOut:10000,manifestLoadingMaxRetry:10,
|
||||
fragLoadingTimeOut:10000,fragLoadingMaxRetry:10
|
||||
});
|
||||
hls.loadSource(src);
|
||||
hls.attachMedia(document.getElementById('v'));
|
||||
hls.on(Hls.Events.MANIFEST_PARSED,function(){document.getElementById('v').play();});
|
||||
hls.attachMedia(v);
|
||||
hls.on(Hls.Events.MANIFEST_PARSED,function(){v.play();});
|
||||
hls.on(Hls.Events.ERROR,function(e,d){
|
||||
if(d.fatal){showMsg('Error: '+d.type+' — reconnecting...');setTimeout(function(){load(activeSrc);},3000);}
|
||||
});
|
||||
}
|
||||
|
||||
var last=0;
|
||||
var last=0,started=false;
|
||||
setInterval(function(){
|
||||
var v=document.getElementById('v');
|
||||
if(v.currentTime===last&&!v.paused){showMsg('Stream stalled — reloading...');load(activeSrc);}
|
||||
if(!started&&v.currentTime>0)started=true;
|
||||
if(started&&v.currentTime===last&&!v.paused){
|
||||
showMsg('Stream stalled — reloading...');
|
||||
if(hls)load(activeSrc);
|
||||
else{var s=v.src;v.src='';v.src=s;v.play().catch(function(){});}
|
||||
}
|
||||
last=v.currentTime;
|
||||
},10000);
|
||||
|
||||
fetch(directUrl,{method:'HEAD',signal:AbortSignal.timeout(2000)})
|
||||
.then(function(){load(directUrl);})
|
||||
.catch(function(){load(proxyUrl);});
|
||||
var ctrl=new AbortController();
|
||||
var fetchTimer=setTimeout(function(){ctrl.abort();},2000);
|
||||
fetch(directUrl,{method:'HEAD',signal:ctrl.signal})
|
||||
.then(function(){clearTimeout(fetchTimer);load(directUrl);})
|
||||
.catch(function(){clearTimeout(fetchTimer);load(proxyUrl);});
|
||||
|
||||
// Auto-reload — reads global-prefs written by the main UI
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user