Spaces:
Running
Running
egoSample viewers: fix autoplay in WeChat/iOS in-app WebViews (no canplay wait, retry on WeixinJSBridgeReady/first tap)
Browse files- egoSample/ego-legacy/demo02/viewer.html +16 -3
- egoSample/ego-legacy/demo05/viewer.html +16 -3
- egoSample/ego-legacy/demo07/viewer.html +16 -3
- egoSample/ego-legacy/demo08/viewer.html +16 -3
- egoSample/ego-legacy/demo09/viewer.html +16 -3
- egoSample/ego-legacy/demo10/viewer.html +16 -3
- egoSample/faberu.html +26 -1
- egoSample/jizhi.html +26 -2
- egoSample/mego.html +26 -3
egoSample/ego-legacy/demo02/viewer.html
CHANGED
|
@@ -286,22 +286,35 @@ window.addEventListener('load',update);update();
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
-
|
|
|
|
| 290 |
if(started||playing)return;
|
| 291 |
var vs=vlist();
|
| 292 |
-
if(!vs.length||!vs.every(function(v){return v.readyState>=2;}))return;
|
| 293 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 294 |
vs.forEach(function(v){v.muted=true;});
|
| 295 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 296 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 297 |
}).catch(function(){
|
| 298 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
|
|
|
| 299 |
});
|
| 300 |
}
|
| 301 |
vlist().forEach(function(v){
|
| 302 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 303 |
});
|
| 304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
iv=setInterval(autoStart,400);
|
| 306 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 307 |
})();
|
|
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
+
var t0=Date.now(), armed=false;
|
| 290 |
+
function autoStart(force){
|
| 291 |
if(started||playing)return;
|
| 292 |
var vs=vlist();
|
| 293 |
+
if(!vs.length||(!vs.every(function(v){return v.readyState>=2;})&&!(force||Date.now()-t0>1500&&vs.every(function(v){return v.readyState>=1||v.src;}))))return;
|
| 294 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 295 |
vs.forEach(function(v){v.muted=true;});
|
| 296 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 297 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 298 |
}).catch(function(){
|
| 299 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
| 300 |
+
started=false; arm();
|
| 301 |
});
|
| 302 |
}
|
| 303 |
vlist().forEach(function(v){
|
| 304 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 305 |
});
|
| 306 |
+
/* in-app WebViews (WeChat) ignore preload and may refuse autoplay: don't wait for
|
| 307 |
+
readyState>=2 forever, and retry on WeixinJSBridgeReady / the first tap */
|
| 308 |
+
function arm(){
|
| 309 |
+
if(armed)return; armed=true;
|
| 310 |
+
function once(ev){ if(ev&&ev.target&&ev.target.closest&&ev.target.closest('#play'))return;
|
| 311 |
+
document.removeEventListener('touchend',once,true); document.removeEventListener('click',once,true);
|
| 312 |
+
armed=false; autoStart(true); }
|
| 313 |
+
document.addEventListener('touchend',once,true); document.addEventListener('click',once,true);
|
| 314 |
+
if(window.WeixinJSBridge&&WeixinJSBridge.invoke) WeixinJSBridge.invoke('getNetworkType',{},function(){autoStart(true);});
|
| 315 |
+
}
|
| 316 |
+
document.addEventListener('WeixinJSBridgeReady',function(){autoStart(true);},false);
|
| 317 |
+
window.addEventListener('load',function(){autoStart();});
|
| 318 |
iv=setInterval(autoStart,400);
|
| 319 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 320 |
})();
|
egoSample/ego-legacy/demo05/viewer.html
CHANGED
|
@@ -286,22 +286,35 @@ window.addEventListener('load',update);update();
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
-
|
|
|
|
| 290 |
if(started||playing)return;
|
| 291 |
var vs=vlist();
|
| 292 |
-
if(!vs.length||!vs.every(function(v){return v.readyState>=2;}))return;
|
| 293 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 294 |
vs.forEach(function(v){v.muted=true;});
|
| 295 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 296 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 297 |
}).catch(function(){
|
| 298 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
|
|
|
| 299 |
});
|
| 300 |
}
|
| 301 |
vlist().forEach(function(v){
|
| 302 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 303 |
});
|
| 304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
iv=setInterval(autoStart,400);
|
| 306 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 307 |
})();
|
|
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
+
var t0=Date.now(), armed=false;
|
| 290 |
+
function autoStart(force){
|
| 291 |
if(started||playing)return;
|
| 292 |
var vs=vlist();
|
| 293 |
+
if(!vs.length||(!vs.every(function(v){return v.readyState>=2;})&&!(force||Date.now()-t0>1500&&vs.every(function(v){return v.readyState>=1||v.src;}))))return;
|
| 294 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 295 |
vs.forEach(function(v){v.muted=true;});
|
| 296 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 297 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 298 |
}).catch(function(){
|
| 299 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
| 300 |
+
started=false; arm();
|
| 301 |
});
|
| 302 |
}
|
| 303 |
vlist().forEach(function(v){
|
| 304 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 305 |
});
|
| 306 |
+
/* in-app WebViews (WeChat) ignore preload and may refuse autoplay: don't wait for
|
| 307 |
+
readyState>=2 forever, and retry on WeixinJSBridgeReady / the first tap */
|
| 308 |
+
function arm(){
|
| 309 |
+
if(armed)return; armed=true;
|
| 310 |
+
function once(ev){ if(ev&&ev.target&&ev.target.closest&&ev.target.closest('#play'))return;
|
| 311 |
+
document.removeEventListener('touchend',once,true); document.removeEventListener('click',once,true);
|
| 312 |
+
armed=false; autoStart(true); }
|
| 313 |
+
document.addEventListener('touchend',once,true); document.addEventListener('click',once,true);
|
| 314 |
+
if(window.WeixinJSBridge&&WeixinJSBridge.invoke) WeixinJSBridge.invoke('getNetworkType',{},function(){autoStart(true);});
|
| 315 |
+
}
|
| 316 |
+
document.addEventListener('WeixinJSBridgeReady',function(){autoStart(true);},false);
|
| 317 |
+
window.addEventListener('load',function(){autoStart();});
|
| 318 |
iv=setInterval(autoStart,400);
|
| 319 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 320 |
})();
|
egoSample/ego-legacy/demo07/viewer.html
CHANGED
|
@@ -286,22 +286,35 @@ window.addEventListener('load',update);update();
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
-
|
|
|
|
| 290 |
if(started||playing)return;
|
| 291 |
var vs=vlist();
|
| 292 |
-
if(!vs.length||!vs.every(function(v){return v.readyState>=2;}))return;
|
| 293 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 294 |
vs.forEach(function(v){v.muted=true;});
|
| 295 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 296 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 297 |
}).catch(function(){
|
| 298 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
|
|
|
| 299 |
});
|
| 300 |
}
|
| 301 |
vlist().forEach(function(v){
|
| 302 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 303 |
});
|
| 304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
iv=setInterval(autoStart,400);
|
| 306 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 307 |
})();
|
|
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
+
var t0=Date.now(), armed=false;
|
| 290 |
+
function autoStart(force){
|
| 291 |
if(started||playing)return;
|
| 292 |
var vs=vlist();
|
| 293 |
+
if(!vs.length||(!vs.every(function(v){return v.readyState>=2;})&&!(force||Date.now()-t0>1500&&vs.every(function(v){return v.readyState>=1||v.src;}))))return;
|
| 294 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 295 |
vs.forEach(function(v){v.muted=true;});
|
| 296 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 297 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 298 |
}).catch(function(){
|
| 299 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
| 300 |
+
started=false; arm();
|
| 301 |
});
|
| 302 |
}
|
| 303 |
vlist().forEach(function(v){
|
| 304 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 305 |
});
|
| 306 |
+
/* in-app WebViews (WeChat) ignore preload and may refuse autoplay: don't wait for
|
| 307 |
+
readyState>=2 forever, and retry on WeixinJSBridgeReady / the first tap */
|
| 308 |
+
function arm(){
|
| 309 |
+
if(armed)return; armed=true;
|
| 310 |
+
function once(ev){ if(ev&&ev.target&&ev.target.closest&&ev.target.closest('#play'))return;
|
| 311 |
+
document.removeEventListener('touchend',once,true); document.removeEventListener('click',once,true);
|
| 312 |
+
armed=false; autoStart(true); }
|
| 313 |
+
document.addEventListener('touchend',once,true); document.addEventListener('click',once,true);
|
| 314 |
+
if(window.WeixinJSBridge&&WeixinJSBridge.invoke) WeixinJSBridge.invoke('getNetworkType',{},function(){autoStart(true);});
|
| 315 |
+
}
|
| 316 |
+
document.addEventListener('WeixinJSBridgeReady',function(){autoStart(true);},false);
|
| 317 |
+
window.addEventListener('load',function(){autoStart();});
|
| 318 |
iv=setInterval(autoStart,400);
|
| 319 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 320 |
})();
|
egoSample/ego-legacy/demo08/viewer.html
CHANGED
|
@@ -286,22 +286,35 @@ window.addEventListener('load',update);update();
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
-
|
|
|
|
| 290 |
if(started||playing)return;
|
| 291 |
var vs=vlist();
|
| 292 |
-
if(!vs.length||!vs.every(function(v){return v.readyState>=2;}))return;
|
| 293 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 294 |
vs.forEach(function(v){v.muted=true;});
|
| 295 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 296 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 297 |
}).catch(function(){
|
| 298 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
|
|
|
| 299 |
});
|
| 300 |
}
|
| 301 |
vlist().forEach(function(v){
|
| 302 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 303 |
});
|
| 304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
iv=setInterval(autoStart,400);
|
| 306 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 307 |
})();
|
|
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
+
var t0=Date.now(), armed=false;
|
| 290 |
+
function autoStart(force){
|
| 291 |
if(started||playing)return;
|
| 292 |
var vs=vlist();
|
| 293 |
+
if(!vs.length||(!vs.every(function(v){return v.readyState>=2;})&&!(force||Date.now()-t0>1500&&vs.every(function(v){return v.readyState>=1||v.src;}))))return;
|
| 294 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 295 |
vs.forEach(function(v){v.muted=true;});
|
| 296 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 297 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 298 |
}).catch(function(){
|
| 299 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
| 300 |
+
started=false; arm();
|
| 301 |
});
|
| 302 |
}
|
| 303 |
vlist().forEach(function(v){
|
| 304 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 305 |
});
|
| 306 |
+
/* in-app WebViews (WeChat) ignore preload and may refuse autoplay: don't wait for
|
| 307 |
+
readyState>=2 forever, and retry on WeixinJSBridgeReady / the first tap */
|
| 308 |
+
function arm(){
|
| 309 |
+
if(armed)return; armed=true;
|
| 310 |
+
function once(ev){ if(ev&&ev.target&&ev.target.closest&&ev.target.closest('#play'))return;
|
| 311 |
+
document.removeEventListener('touchend',once,true); document.removeEventListener('click',once,true);
|
| 312 |
+
armed=false; autoStart(true); }
|
| 313 |
+
document.addEventListener('touchend',once,true); document.addEventListener('click',once,true);
|
| 314 |
+
if(window.WeixinJSBridge&&WeixinJSBridge.invoke) WeixinJSBridge.invoke('getNetworkType',{},function(){autoStart(true);});
|
| 315 |
+
}
|
| 316 |
+
document.addEventListener('WeixinJSBridgeReady',function(){autoStart(true);},false);
|
| 317 |
+
window.addEventListener('load',function(){autoStart();});
|
| 318 |
iv=setInterval(autoStart,400);
|
| 319 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 320 |
})();
|
egoSample/ego-legacy/demo09/viewer.html
CHANGED
|
@@ -286,22 +286,35 @@ window.addEventListener('load',update);update();
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
-
|
|
|
|
| 290 |
if(started||playing)return;
|
| 291 |
var vs=vlist();
|
| 292 |
-
if(!vs.length||!vs.every(function(v){return v.readyState>=2;}))return;
|
| 293 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 294 |
vs.forEach(function(v){v.muted=true;});
|
| 295 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 296 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 297 |
}).catch(function(){
|
| 298 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
|
|
|
| 299 |
});
|
| 300 |
}
|
| 301 |
vlist().forEach(function(v){
|
| 302 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 303 |
});
|
| 304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
iv=setInterval(autoStart,400);
|
| 306 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 307 |
})();
|
|
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
+
var t0=Date.now(), armed=false;
|
| 290 |
+
function autoStart(force){
|
| 291 |
if(started||playing)return;
|
| 292 |
var vs=vlist();
|
| 293 |
+
if(!vs.length||(!vs.every(function(v){return v.readyState>=2;})&&!(force||Date.now()-t0>1500&&vs.every(function(v){return v.readyState>=1||v.src;}))))return;
|
| 294 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 295 |
vs.forEach(function(v){v.muted=true;});
|
| 296 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 297 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 298 |
}).catch(function(){
|
| 299 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
| 300 |
+
started=false; arm();
|
| 301 |
});
|
| 302 |
}
|
| 303 |
vlist().forEach(function(v){
|
| 304 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 305 |
});
|
| 306 |
+
/* in-app WebViews (WeChat) ignore preload and may refuse autoplay: don't wait for
|
| 307 |
+
readyState>=2 forever, and retry on WeixinJSBridgeReady / the first tap */
|
| 308 |
+
function arm(){
|
| 309 |
+
if(armed)return; armed=true;
|
| 310 |
+
function once(ev){ if(ev&&ev.target&&ev.target.closest&&ev.target.closest('#play'))return;
|
| 311 |
+
document.removeEventListener('touchend',once,true); document.removeEventListener('click',once,true);
|
| 312 |
+
armed=false; autoStart(true); }
|
| 313 |
+
document.addEventListener('touchend',once,true); document.addEventListener('click',once,true);
|
| 314 |
+
if(window.WeixinJSBridge&&WeixinJSBridge.invoke) WeixinJSBridge.invoke('getNetworkType',{},function(){autoStart(true);});
|
| 315 |
+
}
|
| 316 |
+
document.addEventListener('WeixinJSBridgeReady',function(){autoStart(true);},false);
|
| 317 |
+
window.addEventListener('load',function(){autoStart();});
|
| 318 |
iv=setInterval(autoStart,400);
|
| 319 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 320 |
})();
|
egoSample/ego-legacy/demo10/viewer.html
CHANGED
|
@@ -286,22 +286,35 @@ window.addEventListener('load',update);update();
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
-
|
|
|
|
| 290 |
if(started||playing)return;
|
| 291 |
var vs=vlist();
|
| 292 |
-
if(!vs.length||!vs.every(function(v){return v.readyState>=2;}))return;
|
| 293 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 294 |
vs.forEach(function(v){v.muted=true;});
|
| 295 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 296 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 297 |
}).catch(function(){
|
| 298 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
|
|
|
| 299 |
});
|
| 300 |
}
|
| 301 |
vlist().forEach(function(v){
|
| 302 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 303 |
});
|
| 304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
iv=setInterval(autoStart,400);
|
| 306 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 307 |
})();
|
|
|
|
| 286 |
(function(){
|
| 287 |
var started=false, iv=null;
|
| 288 |
function vlist(){try{return Object.values(videos);}catch(e){return [];}}
|
| 289 |
+
var t0=Date.now(), armed=false;
|
| 290 |
+
function autoStart(force){
|
| 291 |
if(started||playing)return;
|
| 292 |
var vs=vlist();
|
| 293 |
+
if(!vs.length||(!vs.every(function(v){return v.readyState>=2;})&&!(force||Date.now()-t0>1500&&vs.every(function(v){return v.readyState>=1||v.src;}))))return;
|
| 294 |
started=true; if(iv){clearInterval(iv);iv=null;}
|
| 295 |
vs.forEach(function(v){v.muted=true;});
|
| 296 |
Promise.all(vs.map(function(v){return Promise.resolve(v.play());})).then(function(){
|
| 297 |
playing=true; playBtn.innerHTML='❙❙'; requestAnimationFrame(loop);
|
| 298 |
}).catch(function(){
|
| 299 |
vs.forEach(function(v){try{v.pause();}catch(e){}}); playing=false; playBtn.innerHTML='▶';
|
| 300 |
+
started=false; arm();
|
| 301 |
});
|
| 302 |
}
|
| 303 |
vlist().forEach(function(v){
|
| 304 |
v.addEventListener('canplay',autoStart); v.addEventListener('loadeddata',autoStart);
|
| 305 |
});
|
| 306 |
+
/* in-app WebViews (WeChat) ignore preload and may refuse autoplay: don't wait for
|
| 307 |
+
readyState>=2 forever, and retry on WeixinJSBridgeReady / the first tap */
|
| 308 |
+
function arm(){
|
| 309 |
+
if(armed)return; armed=true;
|
| 310 |
+
function once(ev){ if(ev&&ev.target&&ev.target.closest&&ev.target.closest('#play'))return;
|
| 311 |
+
document.removeEventListener('touchend',once,true); document.removeEventListener('click',once,true);
|
| 312 |
+
armed=false; autoStart(true); }
|
| 313 |
+
document.addEventListener('touchend',once,true); document.addEventListener('click',once,true);
|
| 314 |
+
if(window.WeixinJSBridge&&WeixinJSBridge.invoke) WeixinJSBridge.invoke('getNetworkType',{},function(){autoStart(true);});
|
| 315 |
+
}
|
| 316 |
+
document.addEventListener('WeixinJSBridgeReady',function(){autoStart(true);},false);
|
| 317 |
+
window.addEventListener('load',function(){autoStart();});
|
| 318 |
iv=setInterval(autoStart,400);
|
| 319 |
setTimeout(function(){if(iv){clearInterval(iv);iv=null;}},90000);
|
| 320 |
})();
|
egoSample/faberu.html
CHANGED
|
@@ -90,6 +90,31 @@ const esc=s=>String(s??'').replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'&g
|
|
| 90 |
const fmt=t=>{t=Math.max(0,t);const m=Math.floor(t/60),s=t%60;return m+':'+s.toFixed(2).padStart(5,'0');};
|
| 91 |
const skc=s=>SKC[s]||'#666';
|
| 92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
function select(i){ EP=EPS[i]; SIG=null; cancelAnimationFrame(raf); clearInterval(syncT); playing=false; render(); loadSig(EP.slug); }
|
| 94 |
function loadSig(slug){ window.EPDATA=window.EPDATA||{};
|
| 95 |
// start every download at once; core first-priority, map next, scans next, depth-hover grid last
|
|
@@ -101,7 +126,7 @@ function loadSig(slug){ window.EPDATA=window.EPDATA||{};
|
|
| 101 |
scansP.then(merge('scans',F=>{ let c=0; SIG.clouds={}; Object.entries(F.hdr.clouds).forEach(([k,fr])=>{ SIG.clouds[k]=fr.map(f=>Object.assign({t:f.t},decPts(F,c++,f.n))); }); }))
|
| 102 |
.then(()=>fetchBin(P('dgrid'),null,'low')).then(b=>{ if(!b||!SIG) return; const F=parseFUP(b), n=F.hdr.w*F.hdr.h; SIG.depthGrid=F.hdr.offs.map((o,k)=>new Uint16Array(F.buf.buffer,F.base+o,n)); });
|
| 103 |
updateUI(master.currentTime||0);
|
| 104 |
-
|
| 105 |
if(window.EPDATA[slug]){ done(); return; }
|
| 106 |
fetchBin(P('core'),null).then(b=>{ window.EPDATA[slug]=JSON.parse(new TextDecoder().decode(b)); done(); })
|
| 107 |
.catch(()=>{ const s=document.createElement('script'); s.src='epdata/'+slug+'.js'; s.onload=done; document.body.appendChild(s); }); }
|
|
|
|
| 90 |
const fmt=t=>{t=Math.max(0,t);const m=Math.floor(t/60),s=t%60;return m+':'+s.toFixed(2).padStart(5,'0');};
|
| 91 |
const skc=s=>SKC[s]||'#666';
|
| 92 |
|
| 93 |
+
/* autoplay for in-app WebViews (WeChat iOS/Android X5): they ignore preload, so
|
| 94 |
+
canplay never fires until play() is called — don't wait on it forever. If play()
|
| 95 |
+
is refused, roll back to paused and retry on WeixinJSBridgeReady / first tap. */
|
| 96 |
+
let _autoArmed=false;
|
| 97 |
+
function _autoStart(){
|
| 98 |
+
if(!master||!_toggle) return;
|
| 99 |
+
if(!playing) _toggle();
|
| 100 |
+
const m=master; Promise.resolve(m.play()).catch(()=>{ if(playing && master===m) _toggle(); _armRetry(); });
|
| 101 |
+
}
|
| 102 |
+
function _armRetry(){
|
| 103 |
+
if(_autoArmed) return; _autoArmed=true;
|
| 104 |
+
const once=ev=>{ if(ev && ev.target && ev.target.closest && ev.target.closest('#play')) return;
|
| 105 |
+
document.removeEventListener('touchend',once,true); document.removeEventListener('click',once,true);
|
| 106 |
+
_autoArmed=false; if(!playing) _autoStart(); };
|
| 107 |
+
document.addEventListener('touchend',once,true); document.addEventListener('click',once,true);
|
| 108 |
+
const wx=()=>{ if(!playing) _autoStart(); };
|
| 109 |
+
if(window.WeixinJSBridge && WeixinJSBridge.invoke) WeixinJSBridge.invoke('getNetworkType',{},wx);
|
| 110 |
+
}
|
| 111 |
+
document.addEventListener('WeixinJSBridgeReady',()=>{ if(master && !playing) _autoStart(); },false);
|
| 112 |
+
function _whenReady(go){
|
| 113 |
+
if(master.readyState>=3){ go(); return; }
|
| 114 |
+
let fired=false; const f=()=>{ if(fired) return; fired=true; go(); };
|
| 115 |
+
master.addEventListener('canplay',f,{once:true}); setTimeout(f,1200);
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
function select(i){ EP=EPS[i]; SIG=null; cancelAnimationFrame(raf); clearInterval(syncT); playing=false; render(); loadSig(EP.slug); }
|
| 119 |
function loadSig(slug){ window.EPDATA=window.EPDATA||{};
|
| 120 |
// start every download at once; core first-priority, map next, scans next, depth-hover grid last
|
|
|
|
| 126 |
scansP.then(merge('scans',F=>{ let c=0; SIG.clouds={}; Object.entries(F.hdr.clouds).forEach(([k,fr])=>{ SIG.clouds[k]=fr.map(f=>Object.assign({t:f.t},decPts(F,c++,f.n))); }); }))
|
| 127 |
.then(()=>fetchBin(P('dgrid'),null,'low')).then(b=>{ if(!b||!SIG) return; const F=parseFUP(b), n=F.hdr.w*F.hdr.h; SIG.depthGrid=F.hdr.offs.map((o,k)=>new Uint16Array(F.buf.buffer,F.base+o,n)); });
|
| 128 |
updateUI(master.currentTime||0);
|
| 129 |
+
if(!playing) _whenReady(_autoStart); };
|
| 130 |
if(window.EPDATA[slug]){ done(); return; }
|
| 131 |
fetchBin(P('core'),null).then(b=>{ window.EPDATA[slug]=JSON.parse(new TextDecoder().decode(b)); done(); })
|
| 132 |
.catch(()=>{ const s=document.createElement('script'); s.src='epdata/'+slug+'.js'; s.onload=done; document.body.appendChild(s); }); }
|
egoSample/jizhi.html
CHANGED
|
@@ -98,6 +98,31 @@ const AXR = ['#ff0000','#00ff00','#0000ff'];
|
|
| 98 |
let cur=-1, vids=[], master=null, playing=false, EP=null, SIG=null, raf=0, syncTimer=0, _toggle=null, _lastCi=-2;
|
| 99 |
let orbO={yaw:0.6,pitch:-0.45,drag:0};
|
| 100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
const esc = s => (s||'').replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'>','"':'"'}[c]));
|
| 102 |
const fmt = t => { t=Math.max(0,t); const m=Math.floor(t/60), s=t%60; return m+":"+s.toFixed(2).padStart(5,'0'); };
|
| 103 |
const skc = s => SKC[s]||'#666';
|
|
@@ -115,8 +140,7 @@ function loadSig(slug){
|
|
| 115 |
window.EPDATA=window.EPDATA||{};
|
| 116 |
const done=()=>{ SIG=window.EPDATA[slug]; if(!SIG) return; SIG._fw=null; sizeCanvases(); drawCharts();
|
| 117 |
updateUI(master?master.currentTime:0);
|
| 118 |
-
|
| 119 |
-
if(!master){} else if(master.readyState>=3) go(); else master.addEventListener('canplay',go,{once:true}); };
|
| 120 |
if(window.EPDATA[slug]){ done(); return; }
|
| 121 |
const s=document.createElement('script'); s.id='sigjs'; s.src='epdata/'+slug+'.js';
|
| 122 |
s.onload=done; s.onerror=()=>{ SIG=null; }; document.body.appendChild(s);
|
|
|
|
| 98 |
let cur=-1, vids=[], master=null, playing=false, EP=null, SIG=null, raf=0, syncTimer=0, _toggle=null, _lastCi=-2;
|
| 99 |
let orbO={yaw:0.6,pitch:-0.45,drag:0};
|
| 100 |
|
| 101 |
+
/* autoplay for in-app WebViews (WeChat iOS/Android X5): they ignore preload, so
|
| 102 |
+
canplay never fires until play() is called — don't wait on it forever. If play()
|
| 103 |
+
is refused, roll back to paused and retry on WeixinJSBridgeReady / first tap. */
|
| 104 |
+
let _autoArmed=false;
|
| 105 |
+
function _autoStart(){
|
| 106 |
+
if(!master||!_toggle) return;
|
| 107 |
+
if(!playing) _toggle();
|
| 108 |
+
const m=master; Promise.resolve(m.play()).catch(()=>{ if(playing && master===m) _toggle(); _armRetry(); });
|
| 109 |
+
}
|
| 110 |
+
function _armRetry(){
|
| 111 |
+
if(_autoArmed) return; _autoArmed=true;
|
| 112 |
+
const once=ev=>{ if(ev && ev.target && ev.target.closest && ev.target.closest('#play')) return;
|
| 113 |
+
document.removeEventListener('touchend',once,true); document.removeEventListener('click',once,true);
|
| 114 |
+
_autoArmed=false; if(!playing) _autoStart(); };
|
| 115 |
+
document.addEventListener('touchend',once,true); document.addEventListener('click',once,true);
|
| 116 |
+
const wx=()=>{ if(!playing) _autoStart(); };
|
| 117 |
+
if(window.WeixinJSBridge && WeixinJSBridge.invoke) WeixinJSBridge.invoke('getNetworkType',{},wx);
|
| 118 |
+
}
|
| 119 |
+
document.addEventListener('WeixinJSBridgeReady',()=>{ if(master && !playing) _autoStart(); },false);
|
| 120 |
+
function _whenReady(go){
|
| 121 |
+
if(master.readyState>=3){ go(); return; }
|
| 122 |
+
let fired=false; const f=()=>{ if(fired) return; fired=true; go(); };
|
| 123 |
+
master.addEventListener('canplay',f,{once:true}); setTimeout(f,1200);
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
const esc = s => (s||'').replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'>','"':'"'}[c]));
|
| 127 |
const fmt = t => { t=Math.max(0,t); const m=Math.floor(t/60), s=t%60; return m+":"+s.toFixed(2).padStart(5,'0'); };
|
| 128 |
const skc = s => SKC[s]||'#666';
|
|
|
|
| 140 |
window.EPDATA=window.EPDATA||{};
|
| 141 |
const done=()=>{ SIG=window.EPDATA[slug]; if(!SIG) return; SIG._fw=null; sizeCanvases(); drawCharts();
|
| 142 |
updateUI(master?master.currentTime:0);
|
| 143 |
+
if(master && !playing) _whenReady(_autoStart); };
|
|
|
|
| 144 |
if(window.EPDATA[slug]){ done(); return; }
|
| 145 |
const s=document.createElement('script'); s.id='sigjs'; s.src='epdata/'+slug+'.js';
|
| 146 |
s.onload=done; s.onerror=()=>{ SIG=null; }; document.body.appendChild(s);
|
egoSample/mego.html
CHANGED
|
@@ -117,6 +117,31 @@ const AX = {x:"#e0616f", y:"#41c76b", z:"#4f8ff7"};
|
|
| 117 |
let cur=-1, vids=[], master=null, playing=false, EP=null, SIG=null, raf=0, syncTimer=0, _toggle=null, _lastCi=-2;
|
| 118 |
let orbH={yaw:0,pitch:-0.28,drag:0}, orbP={yaw:0,pitch:-0.28,drag:0};
|
| 119 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
const esc = s => (s||'').replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'>','"':'"'}[c]));
|
| 121 |
const fmt = t => { t=Math.max(0,t); const m=Math.floor(t/60), s=t%60; return m+":"+s.toFixed(2).padStart(5,'0'); };
|
| 122 |
|
|
@@ -173,9 +198,7 @@ function loadSig(slug){
|
|
| 173 |
if(master && fv>0 && master.currentTime<fv-0.01) setTime(fv); else if(master){ updateUI(master.currentTime||0); blitMain(); }
|
| 174 |
// start playback only once the master tile can actually play, so the per-frame
|
| 175 |
// slave sync chases a real timestamp instead of hammering seeks against t=0
|
| 176 |
-
|
| 177 |
-
if(!master) {} else if(master.readyState>=3) go();
|
| 178 |
-
else master.addEventListener('canplay', go, {once:true}); };
|
| 179 |
if(window.EPDATA[slug]){ done(); return; }
|
| 180 |
const s=document.createElement('script'); s.id='sigjs'; s.src='epdata/'+slug+'.js';
|
| 181 |
s.onload=done; s.onerror=()=>{ SIG=null; };
|
|
|
|
| 117 |
let cur=-1, vids=[], master=null, playing=false, EP=null, SIG=null, raf=0, syncTimer=0, _toggle=null, _lastCi=-2;
|
| 118 |
let orbH={yaw:0,pitch:-0.28,drag:0}, orbP={yaw:0,pitch:-0.28,drag:0};
|
| 119 |
|
| 120 |
+
/* autoplay for in-app WebViews (WeChat iOS/Android X5): they ignore preload, so
|
| 121 |
+
canplay never fires until play() is called — don't wait on it forever. If play()
|
| 122 |
+
is refused, roll back to paused and retry on WeixinJSBridgeReady / first tap. */
|
| 123 |
+
let _autoArmed=false;
|
| 124 |
+
function _autoStart(){
|
| 125 |
+
if(!master||!_toggle) return;
|
| 126 |
+
if(!playing) _toggle();
|
| 127 |
+
const m=master; Promise.resolve(m.play()).catch(()=>{ if(playing && master===m) _toggle(); _armRetry(); });
|
| 128 |
+
}
|
| 129 |
+
function _armRetry(){
|
| 130 |
+
if(_autoArmed) return; _autoArmed=true;
|
| 131 |
+
const once=ev=>{ if(ev && ev.target && ev.target.closest && ev.target.closest('#play')) return;
|
| 132 |
+
document.removeEventListener('touchend',once,true); document.removeEventListener('click',once,true);
|
| 133 |
+
_autoArmed=false; if(!playing) _autoStart(); };
|
| 134 |
+
document.addEventListener('touchend',once,true); document.addEventListener('click',once,true);
|
| 135 |
+
const wx=()=>{ if(!playing) _autoStart(); };
|
| 136 |
+
if(window.WeixinJSBridge && WeixinJSBridge.invoke) WeixinJSBridge.invoke('getNetworkType',{},wx);
|
| 137 |
+
}
|
| 138 |
+
document.addEventListener('WeixinJSBridgeReady',()=>{ if(master && !playing) _autoStart(); },false);
|
| 139 |
+
function _whenReady(go){
|
| 140 |
+
if(master.readyState>=3){ go(); return; }
|
| 141 |
+
let fired=false; const f=()=>{ if(fired) return; fired=true; go(); };
|
| 142 |
+
master.addEventListener('canplay',f,{once:true}); setTimeout(f,1200);
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
const esc = s => (s||'').replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'>','"':'"'}[c]));
|
| 146 |
const fmt = t => { t=Math.max(0,t); const m=Math.floor(t/60), s=t%60; return m+":"+s.toFixed(2).padStart(5,'0'); };
|
| 147 |
|
|
|
|
| 198 |
if(master && fv>0 && master.currentTime<fv-0.01) setTime(fv); else if(master){ updateUI(master.currentTime||0); blitMain(); }
|
| 199 |
// start playback only once the master tile can actually play, so the per-frame
|
| 200 |
// slave sync chases a real timestamp instead of hammering seeks against t=0
|
| 201 |
+
if(master && !playing) _whenReady(_autoStart); };
|
|
|
|
|
|
|
| 202 |
if(window.EPDATA[slug]){ done(); return; }
|
| 203 |
const s=document.createElement('script'); s.id='sigjs'; s.src='epdata/'+slug+'.js';
|
| 204 |
s.onload=done; s.onerror=()=>{ SIG=null; };
|