Spaces:
Running
Running
Restore static/yt_live.js from 0cc342c
Browse files- static/yt_live.js +17 -100
static/yt_live.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
// === VNEWS — VTV LIVE + Inline Recorder v6 ===
|
| 4 |
// Features: PiP, mini-player, INLINE RECORDER with ratio crop + AI title + Short AI upload
|
| 5 |
// FIX v6: audio from captureStream (unmute during record), video.ended for crop, AI title generation
|
|
@@ -750,7 +748,7 @@
|
|
| 750 |
function activateMiniPlayer(){
|
| 751 |
if(!_currentCh) return; createMiniPlayer(); _miniActive=true;
|
| 752 |
const mini=document.getElementById('vtv-mini'); const mv=document.getElementById('vtv-mini-vid'); const v=document.getElementById('vtv-player');
|
| 753 |
-
if(_hls){const h=new Hls({enableWorker:
|
| 754 |
else if(v&&v.src){mv.src=v.src; mv.play().catch(()=>{});}
|
| 755 |
const ch=CHANNELS.find(c=>c.id===_currentCh); if(ch) document.getElementById('vtv-mini-ch').textContent=ch.name;
|
| 756 |
fetch('/api/vtv/epg/'+_currentCh).then(r=>r.json()).then(d=>{const p=d.programs||[]; const n=p.find(x=>x.now); document.getElementById('vtv-mini-epg').textContent=n?n.time+' '+n.title:(p[0]?p[0].time+' '+p[0].title:'');}).catch(()=>{});
|
|
@@ -761,9 +759,8 @@
|
|
| 761 |
async function loadAllStreams(){
|
| 762 |
if(_loading) return; _loading=true;
|
| 763 |
const el=document.getElementById('vtv-load'); if(el) el.innerHTML='<div class="vtv-spinner"></div>Đang tải kênh...';
|
| 764 |
-
|
| 765 |
-
|
| 766 |
-
CHANNELS.forEach(ch=>{const t=document.getElementById('vtvt-'+ch.id); if(t){const data=d[ch.id]; if(STREAMS[ch.id]&&STREAMS[ch.id].length>0){t.classList.remove('off'); t.textContent=ch.name;}else if(data&&data.status==='unavailable'){t.style.opacity='0.35'; t.textContent=ch.name+' 🔒';}else{t.style.opacity='0.35'; t.textContent=ch.name+' ✕';}}});
|
| 767 |
_loading=false; _streamsLoaded=true;
|
| 768 |
}
|
| 769 |
|
|
@@ -772,7 +769,7 @@
|
|
| 772 |
let tabs=''; CHANNELS.forEach(ch=>{tabs+='<button class="vtv-tab off" id="vtvt-'+ch.id+'" onclick="window._vtvPlay(\''+ch.id+'\')">'+ch.name+'</button>';});
|
| 773 |
w.innerHTML='<div class="vtv-head"><span class="vtv-title">📺 VTV Trực Tuyến</span><span class="vtv-badge">● LIVE</span></div>'+
|
| 774 |
'<div class="vtv-tabs">'+tabs+'</div>'+
|
| 775 |
-
'<div class="vtv-frame"><div class="vtv-load" id="vtv-load"><div class="vtv-spinner"></div>Đang tải kênh...</div><video id="vtv-player" playsinline muted controls preload="auto" style="display:
|
| 776 |
'<div class="vtv-controls"><button class="vtv-pip-btn" id="vtv-pip-btn" onclick="window._vtvTogglePiP()"><svg viewBox="0 0 24 24"><rect x="2" y="4" width="20" height="16" rx="2" fill="none" stroke="currentColor" stroke-width="2"/><rect x="12" y="10" width="8" height="6" rx="1" fill="currentColor"/></svg>PiP</button><span style="flex:1"></span><span style="font-size:9px;color:#666" id="vtv-status"></span></div>'+
|
| 777 |
'<div class="vtv-epg" id="vtv-epg"><div class="vtv-epg-header"><span class="vtv-epg-title">📋 Lịch phát sóng</span><button class="vtv-epg-toggle" id="vtv-epg-toggle" onclick="window._vtvToggleEpg()">Ẩn</button></div><div class="vtv-epg-list" id="vtv-epg-list"><div class="vtv-epg-loading"><div class="vtv-epg-sp"></div>Đang tải...</div></div></div>';
|
| 778 |
return w;
|
|
@@ -796,79 +793,28 @@
|
|
| 796 |
|
| 797 |
window._vtvRetry=function(){if(_currentCh)window._vtvPlay(_currentCh);};
|
| 798 |
|
| 799 |
-
window._vtvPlay=function(chId){
|
| 800 |
const ch=CHANNELS.find(c=>c.id===chId); if(!ch) return; _currentCh=chId;
|
| 801 |
document.querySelectorAll('.vtv-tab').forEach(t=>t.classList.remove('on'));
|
| 802 |
const tab=document.getElementById('vtvt-'+chId); if(tab) tab.classList.add('on');
|
| 803 |
const video=document.getElementById('vtv-player'); const errEl=document.getElementById('vtv-err'); const loadEl=document.getElementById('vtv-load'); const errMsg=document.getElementById('vtv-err-msg');
|
| 804 |
-
video.style.display='
|
| 805 |
loadEl.innerHTML='<div class="vtv-spinner"></div>Đang kết nối '+ch.name+'...';
|
| 806 |
if(_hls){_hls.destroy();_hls=null;}
|
| 807 |
const urls=STREAMS[chId]||[];
|
| 808 |
-
if(!urls.length
|
| 809 |
_tryPlay(video,urls,0,ch.name,loadEl,errEl,errMsg);
|
| 810 |
loadEpg(chId);
|
| 811 |
-
|
| 812 |
};
|
| 813 |
|
| 814 |
-
function _tryPlay(video,urls,idx,name,loadEl,errEl,errMsg){
|
| 815 |
if(idx>=urls.length){loadEl.style.display='none';errEl.style.display='flex';errMsg.textContent=name+': Tất cả nguồn lỗi.';return;}
|
| 816 |
const src=urls[idx]; loadEl.innerHTML='<div class="vtv-spinner"></div>Kết nối '+name+' ('+(idx+1)+'/'+urls.length+')...';
|
| 817 |
if(typeof Hls!=='undefined'&&Hls.isSupported()){
|
| 818 |
-
const hls=new Hls({enableWorker:
|
| 819 |
-
|
| 820 |
-
hls.on(Hls.Events.
|
| 821 |
-
hls.on(Hls.Events.MEDIA_ATTACHED,()=>console.log('[VTV] MEDIA_ATTACHED'));
|
| 822 |
-
hls.on(Hls.Events.MANIFEST_LOADING,()=>console.log('[VTV] MANIFEST_LOADING',src));
|
| 823 |
-
hls.on(Hls.Events.MANIFEST_LOADED,()=>console.log('[VTV] MANIFEST_LOADED'));
|
| 824 |
-
hls.on(Hls.Events.MANIFEST_PARSED,(ev,data)=>{
|
| 825 |
-
const st=document.getElementById('vtv-status');
|
| 826 |
-
if(st) st.textContent='✅ Manifest OK | '+data.levels.length+' levels | '+(data.levels[0]?data.levels[0].width+'x'+data.levels[0].height:'?');
|
| 827 |
-
console.log('[VTV] MANIFEST_PARSED levels:',data.levels.length);
|
| 828 |
-
loadEl.style.display='none';video.style.opacity='1';video.style.display='block';setTimeout(()=>{
|
| 829 |
-
video.play().then(()=>{
|
| 830 |
-
if(st) st.textContent+=' | ▶ Playing';
|
| 831 |
-
console.log('[VTV] play OK');
|
| 832 |
-
}).catch(e=>{
|
| 833 |
-
if(st) st.textContent+=' | ⚠️ Play blocked: '+e;
|
| 834 |
-
console.log('[VTV] play:',e);
|
| 835 |
-
});
|
| 836 |
-
},100);
|
| 837 |
-
});
|
| 838 |
-
hls.on(Hls.Events.LEVEL_LOADING,(ev,l)=>console.log('[VTV] LEVEL_LOADING',l));
|
| 839 |
-
hls.on(Hls.Events.LEVEL_LOADED,(ev,l)=>console.log('[VTV] LEVEL_LOADED',l));
|
| 840 |
-
hls.on(Hls.Events.FRAG_LOADING,(ev,f)=>console.log('[VTV] FRAG_LOADING',f&&f.url&&f.url.substring(0,80)));
|
| 841 |
-
hls.on(Hls.Events.FRAG_LOADED,(ev,f)=>console.log('[VTV] FRAG_LOADED size:',f&&f.frag&&f.frag.data&&f.frag.data.length));
|
| 842 |
-
hls.on(Hls.Events.FRAG_BUFFERED,(ev,f)=>{
|
| 843 |
-
try{
|
| 844 |
-
const _n=f&&f.frag&&f.frag.sn;
|
| 845 |
-
const _st2=document.getElementById('vtv-status');
|
| 846 |
-
if(_st2&&_n) _st2.textContent='📦 Buffered frag #'+_n;
|
| 847 |
-
console.log('[VTV] FRAG_BUFFERED',f&&f.frag&&f.frag.url&&f.frag.url.substring(0,60));
|
| 848 |
-
}catch(e){}});
|
| 849 |
-
hls.on(Hls.Events.FRAG_PARSING_INIT_SEGMENT,()=>console.log('[VTV] FRAG_PARSING_INIT_SEGMENT'));
|
| 850 |
-
hls.on(Hls.Events.FRAG_PARSING_DATA,()=>console.log('[VTV] FRAG_PARSING_DATA'));
|
| 851 |
-
hls.on(Hls.Events.FRAG_PARSED,()=>console.log('[VTV] FRAG_PARSED'));
|
| 852 |
-
hls.on(Hls.Events.BUFFER_CREATED,()=>console.log('[VTV] BUFFER_CREATED'));
|
| 853 |
-
hls.on(Hls.Events.BUFFER_APPENDING,()=>console.log('[VTV] BUFFER_APPENDING'));
|
| 854 |
-
hls.on(Hls.Events.BUFFER_APPENDED,()=>console.log('[VTV] BUFFER_APPENDED'));
|
| 855 |
-
hls.on(Hls.Events.BUFFER_EOS,()=>console.log('[VTV] BUFFER_EOS'));
|
| 856 |
-
hls.on(Hls.Events.BUFFER_FLUSHING,()=>console.log('[VTV] BUFFER_FLUSHING'));
|
| 857 |
-
hls.on(Hls.Events.LEVEL_SWITCHING,(ev,d)=>console.log('[VTV] LEVEL_SWITCHING',d));
|
| 858 |
-
hls.on(Hls.Events.LEVEL_SWITCHED,(ev,d)=>console.log('[VTV] LEVEL_SWITCHED',d));
|
| 859 |
-
let rec=0; hls.on(Hls.Events.ERROR,(ev,data)=>{
|
| 860 |
-
const _st=document.getElementById('vtv-status');
|
| 861 |
-
if(_st) _st.textContent='❌ '+data.type+' | '+data.details+(data.fatal?' [FATAL]':'');
|
| 862 |
-
console.log('[VTV] ERROR type:',data.type,'details:',data.details,'fatal:',data.fatal,'reason:',data.reason,'url:',data.url&&data.url.substring(0,80));
|
| 863 |
-
if(data.fatal){
|
| 864 |
-
if(data.type===Hls.ErrorTypes.NETWORK_ERROR){
|
| 865 |
-
rec++;if(rec<=3){console.log('[VTV] retry',rec);setTimeout(()=>hls.startLoad(),2000);}
|
| 866 |
-
else{hls.destroy();_hls=null;_tryPlay(video,urls,idx+1,name,loadEl,errEl,errMsg);}
|
| 867 |
-
}else if(data.type===Hls.ErrorTypes.MEDIA_ERROR){
|
| 868 |
-
console.log('[VTV] MEDIA_ERROR, trying recover');
|
| 869 |
-
try{hls.recoverMediaError();}catch(e){console.log('[VTV] recover failed',e);hls.destroy();_hls=null;}
|
| 870 |
-
}else{console.log('[VTV] other fatal error');hls.destroy();_hls=null;_tryPlay(video,urls,idx+1,name,loadEl,errEl,errMsg);}
|
| 871 |
-
}});
|
| 872 |
}else if(video.canPlayType('application/vnd.apple.mpegurl')){
|
| 873 |
video.src=src;
|
| 874 |
video.addEventListener('loadedmetadata',()=>{video.play().catch(()=>{});loadEl.style.display='none';video.style.display='block';},{once:true});
|
|
@@ -876,44 +822,15 @@
|
|
| 876 |
}else{loadEl.style.display='none';errEl.style.display='flex';errMsg.textContent='Không hỗ trợ HLS';}
|
| 877 |
}
|
| 878 |
|
| 879 |
-
}catch(e){console.log('[VTV] _tryPlay error:',e);}
|
| 880 |
-
|
| 881 |
// ===== NAV HOOKS =====
|
| 882 |
const _origShowView=window.showView;
|
| 883 |
window.showView=function(id){if(id==='view-home'&&_miniActive)closeMiniPlayer();else if(id!=='view-home'&&_currentCh&&STREAMS[_currentCh]&&STREAMS[_currentCh].length>0&&!_miniActive)activateMiniPlayer();return _origShowView.apply(this,arguments);};
|
| 884 |
const _origReadArticle=window.readArticle; if(_origReadArticle){window.readArticle=function(url){if(_currentCh&&STREAMS[_currentCh]&&STREAMS[_currentCh].length>0&&!_miniActive)activateMiniPlayer();return _origReadArticle.apply(this,arguments);};}
|
| 885 |
-
const _origSwitchCat=window.switchCat;
|
| 886 |
-
if(_origSwitchCat){
|
| 887 |
-
window.switchCat=function(id){
|
| 888 |
-
if(id==='home'){if(_miniActive)closeMiniPlayer();}
|
| 889 |
-
else if(_currentCh&&STREAMS[_currentCh]&&STREAMS[_currentCh].length>0&&!_miniActive)activateMiniPlayer();
|
| 890 |
-
const r=_origSwitchCat.apply(this,arguments);
|
| 891 |
-
// Pin VTV block whenever home tab becomes active
|
| 892 |
-
if(id==='home'){setTimeout(()=>pinBlock(),100);}
|
| 893 |
-
return r;
|
| 894 |
-
};
|
| 895 |
-
}
|
| 896 |
|
| 897 |
-
|
| 898 |
-
|
| 899 |
-
|
| 900 |
-
|
| 901 |
-
if(_blockInserted) return;
|
| 902 |
-
_pinAttempts++;
|
| 903 |
-
if(_pinAttempts>30) return; // give up after ~15s
|
| 904 |
-
const h=document.getElementById('view-home');
|
| 905 |
-
if(h && h.children.length>0 && document.getElementById('vtv-block')){
|
| 906 |
-
_blockInserted=true; return; // already pinned
|
| 907 |
-
}
|
| 908 |
-
if(h && h.children.length>0){
|
| 909 |
-
pinBlock();
|
| 910 |
-
} else {
|
| 911 |
-
setTimeout(_tryPin, 500);
|
| 912 |
-
}
|
| 913 |
-
}
|
| 914 |
-
if(document.readyState==='loading'){
|
| 915 |
-
document.addEventListener('DOMContentLoaded', _tryPin);
|
| 916 |
-
} else {
|
| 917 |
-
_tryPin();
|
| 918 |
}
|
| 919 |
})();
|
|
|
|
|
|
|
|
|
|
| 1 |
// === VNEWS — VTV LIVE + Inline Recorder v6 ===
|
| 2 |
// Features: PiP, mini-player, INLINE RECORDER with ratio crop + AI title + Short AI upload
|
| 3 |
// FIX v6: audio from captureStream (unmute during record), video.ended for crop, AI title generation
|
|
|
|
| 748 |
function activateMiniPlayer(){
|
| 749 |
if(!_currentCh) return; createMiniPlayer(); _miniActive=true;
|
| 750 |
const mini=document.getElementById('vtv-mini'); const mv=document.getElementById('vtv-mini-vid'); const v=document.getElementById('vtv-player');
|
| 751 |
+
if(_hls){const h=new Hls({enableWorker:true,lowLatencyMode:true,startLevel:-1,capLevelToPlayerSize:true,maxBufferLength:10}); h.loadSource(STREAMS[_currentCh][0]); h.attachMedia(mv); mv.play().catch(()=>{});}
|
| 752 |
else if(v&&v.src){mv.src=v.src; mv.play().catch(()=>{});}
|
| 753 |
const ch=CHANNELS.find(c=>c.id===_currentCh); if(ch) document.getElementById('vtv-mini-ch').textContent=ch.name;
|
| 754 |
fetch('/api/vtv/epg/'+_currentCh).then(r=>r.json()).then(d=>{const p=d.programs||[]; const n=p.find(x=>x.now); document.getElementById('vtv-mini-epg').textContent=n?n.time+' '+n.title:(p[0]?p[0].time+' '+p[0].title:'');}).catch(()=>{});
|
|
|
|
| 759 |
async function loadAllStreams(){
|
| 760 |
if(_loading) return; _loading=true;
|
| 761 |
const el=document.getElementById('vtv-load'); if(el) el.innerHTML='<div class="vtv-spinner"></div>Đang tải kênh...';
|
| 762 |
+
try{const r=await fetch('/api/vtv/streams',{signal:AbortSignal.timeout(10000)}); if(r.ok){const d=await r.json(); CHANNELS.forEach(ch=>{const i=d[ch.id]; if(i&&i.stream_url){let u=i.stream_url; if(NEEDS_PROXY.test(u)) u='/api/proxy/m3u8/vtv?url='+encodeURIComponent(u); STREAMS[ch.id]=[u];} else STREAMS[ch.id]=[];});}}catch(e){}
|
| 763 |
+
CHANNELS.forEach(ch=>{const t=document.getElementById('vtvt-'+ch.id); if(t){if(STREAMS[ch.id]&&STREAMS[ch.id].length>0){t.classList.remove('off'); t.textContent=ch.name;}else{t.style.opacity='0.35'; t.textContent=ch.name+' ✕';}}});
|
|
|
|
| 764 |
_loading=false; _streamsLoaded=true;
|
| 765 |
}
|
| 766 |
|
|
|
|
| 769 |
let tabs=''; CHANNELS.forEach(ch=>{tabs+='<button class="vtv-tab off" id="vtvt-'+ch.id+'" onclick="window._vtvPlay(\''+ch.id+'\')">'+ch.name+'</button>';});
|
| 770 |
w.innerHTML='<div class="vtv-head"><span class="vtv-title">📺 VTV Trực Tuyến</span><span class="vtv-badge">● LIVE</span></div>'+
|
| 771 |
'<div class="vtv-tabs">'+tabs+'</div>'+
|
| 772 |
+
'<div class="vtv-frame"><div class="vtv-load" id="vtv-load"><div class="vtv-spinner"></div>Đang tải kênh...</div><video id="vtv-player" playsinline muted controls preload="auto" style="display:none"></video><div class="vtv-err" id="vtv-err" style="display:none"><span id="vtv-err-msg">Không thể tải kênh</span><button onclick="window._vtvRetry()">Thử lại</button></div></div>'+
|
| 773 |
'<div class="vtv-controls"><button class="vtv-pip-btn" id="vtv-pip-btn" onclick="window._vtvTogglePiP()"><svg viewBox="0 0 24 24"><rect x="2" y="4" width="20" height="16" rx="2" fill="none" stroke="currentColor" stroke-width="2"/><rect x="12" y="10" width="8" height="6" rx="1" fill="currentColor"/></svg>PiP</button><span style="flex:1"></span><span style="font-size:9px;color:#666" id="vtv-status"></span></div>'+
|
| 774 |
'<div class="vtv-epg" id="vtv-epg"><div class="vtv-epg-header"><span class="vtv-epg-title">📋 Lịch phát sóng</span><button class="vtv-epg-toggle" id="vtv-epg-toggle" onclick="window._vtvToggleEpg()">Ẩn</button></div><div class="vtv-epg-list" id="vtv-epg-list"><div class="vtv-epg-loading"><div class="vtv-epg-sp"></div>Đang tải...</div></div></div>';
|
| 775 |
return w;
|
|
|
|
| 793 |
|
| 794 |
window._vtvRetry=function(){if(_currentCh)window._vtvPlay(_currentCh);};
|
| 795 |
|
| 796 |
+
window._vtvPlay=function(chId){
|
| 797 |
const ch=CHANNELS.find(c=>c.id===chId); if(!ch) return; _currentCh=chId;
|
| 798 |
document.querySelectorAll('.vtv-tab').forEach(t=>t.classList.remove('on'));
|
| 799 |
const tab=document.getElementById('vtvt-'+chId); if(tab) tab.classList.add('on');
|
| 800 |
const video=document.getElementById('vtv-player'); const errEl=document.getElementById('vtv-err'); const loadEl=document.getElementById('vtv-load'); const errMsg=document.getElementById('vtv-err-msg');
|
| 801 |
+
video.style.display='none'; errEl.style.display='none'; loadEl.style.display='flex';
|
| 802 |
loadEl.innerHTML='<div class="vtv-spinner"></div>Đang kết nối '+ch.name+'...';
|
| 803 |
if(_hls){_hls.destroy();_hls=null;}
|
| 804 |
const urls=STREAMS[chId]||[];
|
| 805 |
+
if(!urls.length){loadEl.style.display='none';errEl.style.display='flex';errMsg.textContent=chId==='vtvprime'?'VTVPrime: Kênh trả phí.':ch.name+': Không có luồng.';return;}
|
| 806 |
_tryPlay(video,urls,0,ch.name,loadEl,errEl,errMsg);
|
| 807 |
loadEpg(chId);
|
| 808 |
+
if(_miniActive){document.getElementById('vtv-mini-ch').textContent=ch.name;fetch('/api/vtv/epg/'+_currentCh).then(r=>r.json()).then(d=>{const p=d.programs||[];const n=p.find(x=>x.now);document.getElementById('vtv-mini-epg').textContent=n?n.time+' '+n.title:(p[0]?p[0].time+' '+p[0].title:'');}).catch(()=>{});}
|
| 809 |
};
|
| 810 |
|
| 811 |
+
function _tryPlay(video,urls,idx,name,loadEl,errEl,errMsg){
|
| 812 |
if(idx>=urls.length){loadEl.style.display='none';errEl.style.display='flex';errMsg.textContent=name+': Tất cả nguồn lỗi.';return;}
|
| 813 |
const src=urls[idx]; loadEl.innerHTML='<div class="vtv-spinner"></div>Kết nối '+name+' ('+(idx+1)+'/'+urls.length+')...';
|
| 814 |
if(typeof Hls!=='undefined'&&Hls.isSupported()){
|
| 815 |
+
const hls=new Hls({enableWorker:true,lowLatencyMode:true,startLevel:-1,capLevelToPlayerSize:true,maxBufferLength:20}); _hls=hls; hls.loadSource(src); hls.attachMedia(video);
|
| 816 |
+
hls.on(Hls.Events.MANIFEST_PARSED,()=>{video.play().catch(()=>{});loadEl.style.display='none';video.style.display='block';});
|
| 817 |
+
let rec=0; hls.on(Hls.Events.ERROR,(ev,data)=>{if(data.fatal){if(data.type===Hls.ErrorTypes.NETWORK_ERROR){rec++;if(rec<=3)setTimeout(()=>hls.startLoad(),2000);else{hls.destroy();_hls=null;_tryPlay(video,urls,idx+1,name,loadEl,errEl,errMsg);}}else if(data.type===Hls.ErrorTypes.MEDIA_ERROR){try{hls.recoverMediaError();}catch(e){}}else{hls.destroy();_hls=null;_tryPlay(video,urls,idx+1,name,loadEl,errEl,errMsg);}}});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 818 |
}else if(video.canPlayType('application/vnd.apple.mpegurl')){
|
| 819 |
video.src=src;
|
| 820 |
video.addEventListener('loadedmetadata',()=>{video.play().catch(()=>{});loadEl.style.display='none';video.style.display='block';},{once:true});
|
|
|
|
| 822 |
}else{loadEl.style.display='none';errEl.style.display='flex';errMsg.textContent='Không hỗ trợ HLS';}
|
| 823 |
}
|
| 824 |
|
|
|
|
|
|
|
| 825 |
// ===== NAV HOOKS =====
|
| 826 |
const _origShowView=window.showView;
|
| 827 |
window.showView=function(id){if(id==='view-home'&&_miniActive)closeMiniPlayer();else if(id!=='view-home'&&_currentCh&&STREAMS[_currentCh]&&STREAMS[_currentCh].length>0&&!_miniActive)activateMiniPlayer();return _origShowView.apply(this,arguments);};
|
| 828 |
const _origReadArticle=window.readArticle; if(_origReadArticle){window.readArticle=function(url){if(_currentCh&&STREAMS[_currentCh]&&STREAMS[_currentCh].length>0&&!_miniActive)activateMiniPlayer();return _origReadArticle.apply(this,arguments);};}
|
| 829 |
+
const _origSwitchCat=window.switchCat; if(_origSwitchCat){window.switchCat=function(id){if(id==='home'){if(_miniActive)closeMiniPlayer();}else if(_currentCh&&STREAMS[_currentCh]&&STREAMS[_currentCh].length>0&&!_miniActive)activateMiniPlayer();return _origSwitchCat.apply(this,arguments);};}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 830 |
|
| 831 |
+
const _origLoadHome=window.loadHome;
|
| 832 |
+
if(_origLoadHome&&!_origLoadHome.__vtvWrapped){
|
| 833 |
+
window.loadHome=async function(){const old=document.getElementById('vtv-block');if(old)old.remove();_blockInserted=false;const r=await _origLoadHome.apply(this,arguments);try{pinBlock();}catch(e){}return r;};
|
| 834 |
+
window.loadHome.__vtvWrapped=true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 835 |
}
|
| 836 |
})();
|