bep40 commited on
Commit
24f2ba0
·
verified ·
1 Parent(s): 47db7d6

Fix VTV: auto-play VTV6, single-source fast fail (4s), no duplicate function

Browse files
Files changed (1) hide show
  1. static/app_v2.js +56 -36
static/app_v2.js CHANGED
@@ -119,6 +119,11 @@ async function loadVTVStreams(){
119
  });
120
 
121
  hideLoader();
 
 
 
 
 
122
  }
123
 
124
  function _vtvRetry(){
@@ -140,7 +145,7 @@ function _vtvPlay(chId){
140
  errEl.style.display = 'none';
141
  loadEl.style.display = 'flex';
142
  loadEl.innerHTML = '<div class="vtv-spinner"></div>Đang kết nối ' + ch.name + '...';
143
- if(_vtvHls){ _vtvHls.destroy(); _vtvHls = null; }
144
  const urls = _vtvStreams[chId] || [];
145
  if(urls.length === 0){
146
  loadEl.style.display = 'none';
@@ -150,55 +155,70 @@ function _vtvPlay(chId){
150
  }
151
  const epgWrap = document.getElementById('vtv-epg-wrap');
152
  if(epgWrap) epgWrap.innerHTML = buildVTVEPG(chId);
153
- _vtvTryPlay(video, urls, 0, ch.name, loadEl, errEl, errMsg);
 
154
  }
155
 
156
- function _vtvTryPlay(video, urls, idx, name, loadEl, errEl, errMsg){
157
  if(idx >= urls.length){
158
  loadEl.style.display = 'none';
159
  errEl.style.display = 'flex';
160
- errMsg.textContent = name + ': Tất cả nguồn đều lỗi. Thử lại sau.';
161
  return;
162
  }
163
  const src = urls[idx];
164
- loadEl.innerHTML = '<div class="vtv-spinner"></div>Đang kết nối ' + name + ' (' + (idx+1) + '/' + urls.length + ')...';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  if(typeof Hls !== 'undefined' && Hls.isSupported()){
166
- const hls = new Hls({enableWorker:true,lowLatencyMode:true,startLevel:-1,capLevelToPlayerSize:true,maxBufferLength:8,maxMaxBufferLength:15,maxFragLookUpTolerance:0.5});
167
- _vtvHls = hls;
168
-
169
- // Timeout: if not loaded in 8s, try next source
170
- const loadTimeout = setTimeout(() => {
171
- if(_vtvHls === hls) {
172
- console.warn(`VTV ${name} source ${idx+1} timeout, trying next...`);
173
- hls.destroy();
174
- _vtvHls = null;
175
- _vtvTryPlay(video, urls, idx+1, name, loadEl, errEl, errMsg);
176
- }
177
- }, 8000);
178
-
179
  hls.loadSource(src);
180
  hls.attachMedia(video);
181
- hls.on(Hls.Events.MANIFEST_PARSED, () => {
182
- clearTimeout(loadTimeout);
183
- video.play().catch(()=>{});
184
- loadEl.style.display='none';
185
- video.style.display='block';
186
- });
187
- hls.on(Hls.Events.ERROR, (ev, data) => {
188
- if(data.fatal){
189
- clearTimeout(loadTimeout);
190
- // For any fatal error, try next source immediately
191
- hls.destroy();
192
- _vtvHls = null;
193
- _vtvTryPlay(video, urls, idx+1, name, loadEl, errEl, errMsg);
194
- }
195
- });
196
  } else if(video.canPlayType('application/vnd.apple.mpegurl')){
197
  video.src = src;
198
- video.addEventListener('loadedmetadata', () => { video.play().catch(()=>{}); loadEl.style.display='none'; video.style.display='block'; }, {once:true});
199
- video.addEventListener('error', () => { _vtvTryPlay(video, urls, idx+1, name, loadEl, errEl, errMsg); }, {once:true});
200
  } else {
201
- loadEl.style.display = 'none'; errEl.style.display = 'flex'; errMsg.textContent = 'Trình duyệt không hỗ trợ HLS';
 
 
202
  }
203
  }
204
 
 
119
  });
120
 
121
  hideLoader();
122
+
123
+ // Auto-play VTV6 on first load (default channel)
124
+ if(!_vtvCurrentCh){
125
+ _vtvPlay('vtv6');
126
+ }
127
  }
128
 
129
  function _vtvRetry(){
 
145
  errEl.style.display = 'none';
146
  loadEl.style.display = 'flex';
147
  loadEl.innerHTML = '<div class="vtv-spinner"></div>Đang kết nối ' + ch.name + '...';
148
+ if(_vtvHls){ try{_vtvHls.destroy();}catch(e){} _vtvHls = null; }
149
  const urls = _vtvStreams[chId] || [];
150
  if(urls.length === 0){
151
  loadEl.style.display = 'none';
 
155
  }
156
  const epgWrap = document.getElementById('vtv-epg-wrap');
157
  if(epgWrap) epgWrap.innerHTML = buildVTVEPG(chId);
158
+ // Single source strategy: load primary, fail fast 4s, then try next
159
+ _vtvLoadOne(video, urls, 0, ch.name, loadEl, errEl, errMsg);
160
  }
161
 
162
+ function _vtvLoadOne(video, urls, idx, name, loadEl, errEl, errMsg){
163
  if(idx >= urls.length){
164
  loadEl.style.display = 'none';
165
  errEl.style.display = 'flex';
166
+ errMsg.textContent = name + ': Tất cả nguồn đều lỗi.';
167
  return;
168
  }
169
  const src = urls[idx];
170
+ loadEl.innerHTML = '<div class="vtv-spinner"></div>' + name + (urls.length > 1 ? ' (' + (idx+1) + '/' + urls.length + ')' : '') + '...';
171
+
172
+ let failTimer = null;
173
+ let hlsInst = null;
174
+ let done = false;
175
+
176
+ const next = () => {
177
+ if(done) return;
178
+ done = true;
179
+ if(failTimer) clearTimeout(failTimer);
180
+ if(hlsInst){ try{hlsInst.destroy();}catch(e){} }
181
+ if(_vtvHls === hlsInst) _vtvHls = null;
182
+ if(idx + 1 < urls.length){
183
+ _vtvLoadOne(video, urls, idx+1, name, loadEl, errEl, errMsg);
184
+ } else {
185
+ loadEl.style.display = 'none';
186
+ errEl.style.display = 'flex';
187
+ errMsg.textContent = name + ': Tất cả nguồn đều lỗi.';
188
+ }
189
+ };
190
+
191
+ const ok = () => {
192
+ if(done) return;
193
+ done = true;
194
+ if(failTimer) clearTimeout(failTimer);
195
+ _vtvHls = hlsInst;
196
+ video.play().catch(()=>{});
197
+ loadEl.style.display='none';
198
+ video.style.display='block';
199
+ };
200
+
201
+ // Fast fail: 4s per source
202
+ failTimer = setTimeout(next, 4000);
203
+
204
  if(typeof Hls !== 'undefined' && Hls.isSupported()){
205
+ const hls = new Hls({
206
+ enableWorker:true, lowLatencyMode:true, startLevel:-1,
207
+ capLevelToPlayerSize:true, maxBufferLength:3, maxMaxBufferLength:6
208
+ });
209
+ hlsInst = hls;
 
 
 
 
 
 
 
 
210
  hls.loadSource(src);
211
  hls.attachMedia(video);
212
+ hls.on(Hls.Events.MANIFEST_PARSED, ok);
213
+ hls.on(Hls.Events.ERROR, (ev, data) => { if(data.fatal) next(); });
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  } else if(video.canPlayType('application/vnd.apple.mpegurl')){
215
  video.src = src;
216
+ video.addEventListener('loadedmetadata', ok, {once:true});
217
+ video.addEventListener('error', next, {once:true});
218
  } else {
219
+ clearTimeout(failTimer);
220
+ loadEl.style.display = 'none'; errEl.style.display = 'flex';
221
+ errMsg.textContent = 'Trình duyệt không hỗ trợ HLS';
222
  }
223
  }
224