myetv-player 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -1
- package/css/myetv-player.css +7 -2
- package/css/myetv-player.min.css +1 -1
- package/dist/myetv-player.js +669 -79
- package/dist/myetv-player.min.js +579 -42
- package/package.json +4 -2
- package/plugins/google-adsense-ads/README.md +230 -0
- package/plugins/google-adsense-ads/g-adsense-ads-plugin.js +75 -8
- package/plugins/google-ima-ads/README.md +258 -0
- package/plugins/google-ima-ads/g-ima-ads-plugin.js +2 -2
- package/plugins/soundcloud/myetv-player-soundcloud-plugin.js +927 -0
- package/plugins/soundcloud/readme.md +89 -0
- package/plugins/youtube/myetv-player-youtube-plugin.js +155 -164
package/dist/myetv-player.min.js
CHANGED
|
@@ -23,7 +23,9 @@ class VideoPlayerI18n {
|
|
|
23
23
|
'prev_video': 'Video precedente (P)',
|
|
24
24
|
'playlist_next': 'Avanti',
|
|
25
25
|
'playlist_prev': 'Indietro',
|
|
26
|
-
'settings_menu': 'Impostazioni'
|
|
26
|
+
'settings_menu': 'Impostazioni',
|
|
27
|
+
'loading': 'Caricamento...',
|
|
28
|
+
'encoding_in_progress': 'Encoding in corso'
|
|
27
29
|
},
|
|
28
30
|
|
|
29
31
|
'en': {
|
|
@@ -44,7 +46,9 @@ class VideoPlayerI18n {
|
|
|
44
46
|
'prev_video': 'Previous video (P)',
|
|
45
47
|
'playlist_next': 'Next',
|
|
46
48
|
'playlist_prev': 'Previous',
|
|
47
|
-
'settings_menu': 'Settings'
|
|
49
|
+
'settings_menu': 'Settings',
|
|
50
|
+
'loading': 'Loading...',
|
|
51
|
+
'encoding_in_progress': 'Encoding in progress'
|
|
48
52
|
},
|
|
49
53
|
|
|
50
54
|
'es': {
|
|
@@ -65,7 +69,9 @@ class VideoPlayerI18n {
|
|
|
65
69
|
'prev_video': 'Vídeo anterior (P)',
|
|
66
70
|
'playlist_next': 'Siguiente',
|
|
67
71
|
'playlist_prev': 'Anterior',
|
|
68
|
-
'settings_menu': 'Configuración'
|
|
72
|
+
'settings_menu': 'Configuración',
|
|
73
|
+
'loading': 'Cargando...',
|
|
74
|
+
'encoding_in_progress': 'Codificación en curso'
|
|
69
75
|
},
|
|
70
76
|
|
|
71
77
|
'fr': {
|
|
@@ -78,7 +84,7 @@ class VideoPlayerI18n {
|
|
|
78
84
|
'volume': 'Volume',
|
|
79
85
|
'playback_speed': 'Vitesse de lecture',
|
|
80
86
|
'video_quality': 'Qualité vidéo',
|
|
81
|
-
'picture_in_picture': 'Image dans l
|
|
87
|
+
'picture_in_picture': 'Image dans l\'image(P)',
|
|
82
88
|
'fullscreen': 'Plein écran (F)',
|
|
83
89
|
'auto': 'Auto',
|
|
84
90
|
'brand_logo': 'Logo de marque',
|
|
@@ -86,7 +92,9 @@ class VideoPlayerI18n {
|
|
|
86
92
|
'prev_video': 'Vidéo précédente (P)',
|
|
87
93
|
'playlist_next': 'Suivant',
|
|
88
94
|
'playlist_prev': 'Précédent',
|
|
89
|
-
'settings_menu': 'Paramètres'
|
|
95
|
+
'settings_menu': 'Paramètres',
|
|
96
|
+
'loading': 'Chargement...',
|
|
97
|
+
'encoding_in_progress': 'Encodage en cours'
|
|
90
98
|
},
|
|
91
99
|
|
|
92
100
|
'de': {
|
|
@@ -107,7 +115,9 @@ class VideoPlayerI18n {
|
|
|
107
115
|
'prev_video': 'Vorheriges Video (P)',
|
|
108
116
|
'playlist_next': 'Weiter',
|
|
109
117
|
'playlist_prev': 'Zurück',
|
|
110
|
-
'settings_menu': 'Einstellungen'
|
|
118
|
+
'settings_menu': 'Einstellungen',
|
|
119
|
+
'loading': 'Laden...',
|
|
120
|
+
'encoding_in_progress': 'Kodierung läuft'
|
|
111
121
|
},
|
|
112
122
|
|
|
113
123
|
'pt': {
|
|
@@ -128,7 +138,9 @@ class VideoPlayerI18n {
|
|
|
128
138
|
'prev_video': 'Vídeo anterior (P)',
|
|
129
139
|
'playlist_next': 'Próximo',
|
|
130
140
|
'playlist_prev': 'Anterior',
|
|
131
|
-
'settings_menu': 'Configurações'
|
|
141
|
+
'settings_menu': 'Configurações',
|
|
142
|
+
'loading': 'Carregando...',
|
|
143
|
+
'encoding_in_progress': 'Codificação em andamento'
|
|
132
144
|
},
|
|
133
145
|
|
|
134
146
|
'zh': {
|
|
@@ -149,7 +161,9 @@ class VideoPlayerI18n {
|
|
|
149
161
|
'prev_video': '上一个视频 (P)',
|
|
150
162
|
'playlist_next': '下一个',
|
|
151
163
|
'playlist_prev': '上一个',
|
|
152
|
-
'settings_menu': '设置'
|
|
164
|
+
'settings_menu': '设置',
|
|
165
|
+
'loading': '加载中...',
|
|
166
|
+
'encoding_in_progress': '编码中'
|
|
153
167
|
},
|
|
154
168
|
|
|
155
169
|
'ja': {
|
|
@@ -170,7 +184,9 @@ class VideoPlayerI18n {
|
|
|
170
184
|
'prev_video': '前の動画 (P)',
|
|
171
185
|
'playlist_next': '次へ',
|
|
172
186
|
'playlist_prev': '前へ',
|
|
173
|
-
'settings_menu': '設定'
|
|
187
|
+
'settings_menu': '設定',
|
|
188
|
+
'loading': '読み込み中...',
|
|
189
|
+
'encoding_in_progress': 'エンコード中'
|
|
174
190
|
},
|
|
175
191
|
|
|
176
192
|
'ru': {
|
|
@@ -191,7 +207,9 @@ class VideoPlayerI18n {
|
|
|
191
207
|
'prev_video': 'Предыдущее видео (P)',
|
|
192
208
|
'playlist_next': 'Далее',
|
|
193
209
|
'playlist_prev': 'Назад',
|
|
194
|
-
'settings_menu': 'Настройки'
|
|
210
|
+
'settings_menu': 'Настройки',
|
|
211
|
+
'loading': 'Загрузка...',
|
|
212
|
+
'encoding_in_progress': 'Кодирование'
|
|
195
213
|
},
|
|
196
214
|
|
|
197
215
|
'ar': {
|
|
@@ -212,7 +230,9 @@ class VideoPlayerI18n {
|
|
|
212
230
|
'prev_video': 'الفيديو السابق (P)',
|
|
213
231
|
'playlist_next': 'التالي',
|
|
214
232
|
'playlist_prev': 'السابق',
|
|
215
|
-
'settings_menu': 'الإعدادات'
|
|
233
|
+
'settings_menu': 'الإعدادات',
|
|
234
|
+
'loading': 'جاري التحميل...',
|
|
235
|
+
'encoding_in_progress': 'الترميز جارٍ'
|
|
216
236
|
},
|
|
217
237
|
|
|
218
238
|
'ko': {
|
|
@@ -233,7 +253,9 @@ class VideoPlayerI18n {
|
|
|
233
253
|
'prev_video': '이전 비디오 (P)',
|
|
234
254
|
'playlist_next': '다음',
|
|
235
255
|
'playlist_prev': '이전',
|
|
236
|
-
'settings_menu': '설정'
|
|
256
|
+
'settings_menu': '설정',
|
|
257
|
+
'loading': '로딩 중...',
|
|
258
|
+
'encoding_in_progress': '인코딩 진행 중'
|
|
237
259
|
},
|
|
238
260
|
|
|
239
261
|
'pl': {
|
|
@@ -254,7 +276,9 @@ class VideoPlayerI18n {
|
|
|
254
276
|
'prev_video': 'Poprzednie wideo (P)',
|
|
255
277
|
'playlist_next': 'Dalej',
|
|
256
278
|
'playlist_prev': 'Wstecz',
|
|
257
|
-
'settings_menu': 'Ustawienia'
|
|
279
|
+
'settings_menu': 'Ustawienia',
|
|
280
|
+
'loading': 'Ładowanie...',
|
|
281
|
+
'encoding_in_progress': 'Kodowanie w toku'
|
|
258
282
|
},
|
|
259
283
|
|
|
260
284
|
'hu': {
|
|
@@ -275,7 +299,9 @@ class VideoPlayerI18n {
|
|
|
275
299
|
'prev_video': 'Előző videó (P)',
|
|
276
300
|
'playlist_next': 'Következő',
|
|
277
301
|
'playlist_prev': 'Előző',
|
|
278
|
-
'settings_menu': 'Beállítások'
|
|
302
|
+
'settings_menu': 'Beállítások',
|
|
303
|
+
'loading': 'Betöltés...',
|
|
304
|
+
'encoding_in_progress': 'Kódolás folyamatban'
|
|
279
305
|
},
|
|
280
306
|
|
|
281
307
|
'tr': {
|
|
@@ -296,7 +322,9 @@ class VideoPlayerI18n {
|
|
|
296
322
|
'prev_video': 'Önceki video (P)',
|
|
297
323
|
'playlist_next': 'Sonraki',
|
|
298
324
|
'playlist_prev': 'Önceki',
|
|
299
|
-
'settings_menu': 'Ayarlar'
|
|
325
|
+
'settings_menu': 'Ayarlar',
|
|
326
|
+
'loading': 'Yükleniyor...',
|
|
327
|
+
'encoding_in_progress': 'Kodlama devam ediyor'
|
|
300
328
|
},
|
|
301
329
|
|
|
302
330
|
'nl': {
|
|
@@ -317,7 +345,9 @@ class VideoPlayerI18n {
|
|
|
317
345
|
'prev_video': 'Vorige video (P)',
|
|
318
346
|
'playlist_next': 'Volgende',
|
|
319
347
|
'playlist_prev': 'Vorige',
|
|
320
|
-
'settings_menu': 'Instellingen'
|
|
348
|
+
'settings_menu': 'Instellingen',
|
|
349
|
+
'loading': 'Laden...',
|
|
350
|
+
'encoding_in_progress': 'Codering bezig'
|
|
321
351
|
},
|
|
322
352
|
|
|
323
353
|
'hi': {
|
|
@@ -338,7 +368,9 @@ class VideoPlayerI18n {
|
|
|
338
368
|
'prev_video': 'पिछला वीडियो (P)',
|
|
339
369
|
'playlist_next': 'अगला',
|
|
340
370
|
'playlist_prev': 'पिछला',
|
|
341
|
-
'settings_menu': 'सेटिंग्स'
|
|
371
|
+
'settings_menu': 'सेटिंग्स',
|
|
372
|
+
'loading': 'लोड हो रहा है...',
|
|
373
|
+
'encoding_in_progress': 'एन्कोडिंग प्रगति में'
|
|
342
374
|
},
|
|
343
375
|
|
|
344
376
|
'sv': {
|
|
@@ -359,7 +391,9 @@ class VideoPlayerI18n {
|
|
|
359
391
|
'prev_video': 'Föregående video (P)',
|
|
360
392
|
'playlist_next': 'Nästa',
|
|
361
393
|
'playlist_prev': 'Föregående',
|
|
362
|
-
'settings_menu': 'Inställningar'
|
|
394
|
+
'settings_menu': 'Inställningar',
|
|
395
|
+
'loading': 'Laddar...',
|
|
396
|
+
'encoding_in_progress': 'Kodning pågår'
|
|
363
397
|
},
|
|
364
398
|
|
|
365
399
|
'id': {
|
|
@@ -380,7 +414,9 @@ class VideoPlayerI18n {
|
|
|
380
414
|
'prev_video': 'Video sebelumnya (P)',
|
|
381
415
|
'playlist_next': 'Berikutnya',
|
|
382
416
|
'playlist_prev': 'Sebelumnya',
|
|
383
|
-
'settings_menu': 'Pengaturan'
|
|
417
|
+
'settings_menu': 'Pengaturan',
|
|
418
|
+
'loading': 'Memuat...',
|
|
419
|
+
'encoding_in_progress': 'Encoding sedang berlangsung'
|
|
384
420
|
}
|
|
385
421
|
};
|
|
386
422
|
|
|
@@ -493,7 +529,9 @@ try {
|
|
|
493
529
|
'fullscreen': 'Fullscreen (F)',
|
|
494
530
|
'auto': 'Auto',
|
|
495
531
|
'brand_logo': 'Brand logo',
|
|
496
|
-
'settings_menu': 'Settings'
|
|
532
|
+
'settings_menu': 'Settings',
|
|
533
|
+
'loading': 'Loading...',
|
|
534
|
+
'encoding_in_progress': 'Encoding in progress'
|
|
497
535
|
};
|
|
498
536
|
return fallback[key] || key;
|
|
499
537
|
},
|
|
@@ -802,6 +840,49 @@ constructor(videoElement, options = {}) {
|
|
|
802
840
|
}
|
|
803
841
|
}
|
|
804
842
|
|
|
843
|
+
decodeHTMLEntities(text) {
|
|
844
|
+
if (!text) return '';
|
|
845
|
+
const textarea = document.createElement('textarea');
|
|
846
|
+
textarea.innerHTML = text;
|
|
847
|
+
return textarea.value;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
isFireTV() {
|
|
851
|
+
const ua = navigator.userAgent.toLowerCase();
|
|
852
|
+
return ua.includes('aftm') ||
|
|
853
|
+
ua.includes('aftb') ||
|
|
854
|
+
ua.includes('afts') ||
|
|
855
|
+
ua.includes('aftmm') ||
|
|
856
|
+
ua.includes('aftt');
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
optimizeVideoForFireTV() {
|
|
860
|
+
if (!this.isFireTV() || !this.video) return;
|
|
861
|
+
|
|
862
|
+
if (this.options.debug) {
|
|
863
|
+
console.log('Fire TV detected - applying optimizations');
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
this.video.setAttribute('playsinline', '');
|
|
867
|
+
this.video.setAttribute('webkit-playsinline', '');
|
|
868
|
+
|
|
869
|
+
this.video.style.transform = 'translateZ(0)';
|
|
870
|
+
this.video.style.webkitTransform = 'translateZ(0)';
|
|
871
|
+
this.video.style.backfaceVisibility = 'hidden';
|
|
872
|
+
this.video.style.webkitBackfaceVisibility = 'hidden';
|
|
873
|
+
this.video.style.willChange = 'transform';
|
|
874
|
+
|
|
875
|
+
this.video.addEventListener('loadeddata', () => {
|
|
876
|
+
if (this.options.debug) {
|
|
877
|
+
console.log('Fire TV: Video loaded, forcing repaint');
|
|
878
|
+
}
|
|
879
|
+
this.video.style.display = 'none';
|
|
880
|
+
setTimeout(() => {
|
|
881
|
+
this.video.style.display = 'block';
|
|
882
|
+
}, 10);
|
|
883
|
+
}, { once: true });
|
|
884
|
+
}
|
|
885
|
+
|
|
805
886
|
getPlayerState() {
|
|
806
887
|
return {
|
|
807
888
|
isPlaying: !this.isPaused(),
|
|
@@ -1091,6 +1172,7 @@ createPlayerStructure() {
|
|
|
1091
1172
|
|
|
1092
1173
|
this.container = wrapper;
|
|
1093
1174
|
|
|
1175
|
+
this.optimizeVideoForFireTV();
|
|
1094
1176
|
this.createInitialLoading();
|
|
1095
1177
|
this.createLoadingOverlay();
|
|
1096
1178
|
this.collectVideoQualities();
|
|
@@ -1131,13 +1213,13 @@ createTitleOverlay() {
|
|
|
1131
1213
|
|
|
1132
1214
|
const titleText = document.createElement('h2');
|
|
1133
1215
|
titleText.className = 'title-text';
|
|
1134
|
-
titleText.textContent = this.options.videoTitle || '';
|
|
1216
|
+
titleText.textContent = this.decodeHTMLEntities(this.options.videoTitle) || '';
|
|
1135
1217
|
overlay.appendChild(titleText);
|
|
1136
1218
|
|
|
1137
1219
|
if (this.options.videoSubtitle) {
|
|
1138
1220
|
const subtitleText = document.createElement('p');
|
|
1139
1221
|
subtitleText.className = 'subtitle-text';
|
|
1140
|
-
subtitleText.textContent = this.options.videoSubtitle;
|
|
1222
|
+
subtitleText.textContent = this.decodeHTMLEntities(this.options.videoSubtitle);
|
|
1141
1223
|
overlay.appendChild(subtitleText);
|
|
1142
1224
|
}
|
|
1143
1225
|
|
|
@@ -1192,7 +1274,7 @@ setVideoTitle(title) {
|
|
|
1192
1274
|
if (this.titleOverlay) {
|
|
1193
1275
|
const titleElement = this.titleOverlay.querySelector('.title-text');
|
|
1194
1276
|
if (titleElement) {
|
|
1195
|
-
titleElement.textContent = this.options.videoTitle;
|
|
1277
|
+
titleElement.textContent = this.decodeHTMLEntities(this.options.videoTitle);
|
|
1196
1278
|
}
|
|
1197
1279
|
|
|
1198
1280
|
if (title) {
|
|
@@ -1727,6 +1809,8 @@ updateDuration() {
|
|
|
1727
1809
|
if (this.durationEl && this.video && this.video.duration && !isNaN(this.video.duration)) {
|
|
1728
1810
|
this.durationEl.textContent = this.formatTime(this.video.duration);
|
|
1729
1811
|
}
|
|
1812
|
+
|
|
1813
|
+
this.updateTimeDisplay();
|
|
1730
1814
|
}
|
|
1731
1815
|
|
|
1732
1816
|
changeSpeed(e) {
|
|
@@ -1992,7 +2076,7 @@ switchToVideo(newVideoElement, shouldPlay = false) {
|
|
|
1992
2076
|
if (newTitle && this.options.showTitleOverlay) {
|
|
1993
2077
|
this.options.videoTitle = newTitle;
|
|
1994
2078
|
if (this.titleText) {
|
|
1995
|
-
this.titleText.textContent = newTitle;
|
|
2079
|
+
this.titleText.textContent = this.decodeHTMLEntities(newTitle);
|
|
1996
2080
|
}
|
|
1997
2081
|
}
|
|
1998
2082
|
|
|
@@ -2482,12 +2566,16 @@ addEventListener(eventType, callback) {
|
|
|
2482
2566
|
this.showLoading();
|
|
2483
2567
|
}
|
|
2484
2568
|
|
|
2569
|
+
this.updateTimeDisplay();
|
|
2570
|
+
|
|
2485
2571
|
this.triggerEvent('loadstart');
|
|
2486
2572
|
});
|
|
2487
2573
|
|
|
2488
2574
|
this.video.addEventListener('loadedmetadata', () => {
|
|
2489
2575
|
this.updateDuration();
|
|
2490
2576
|
|
|
2577
|
+
this.updateTimeDisplay();
|
|
2578
|
+
|
|
2491
2579
|
this.triggerEvent('loadedmetadata', {
|
|
2492
2580
|
duration: this.getDuration(),
|
|
2493
2581
|
videoWidth: this.video.videoWidth,
|
|
@@ -2504,6 +2592,8 @@ addEventListener(eventType, callback) {
|
|
|
2504
2592
|
this.hideLoading();
|
|
2505
2593
|
}
|
|
2506
2594
|
|
|
2595
|
+
this.updateTimeDisplay();
|
|
2596
|
+
|
|
2507
2597
|
this.triggerEvent('loadeddata', {
|
|
2508
2598
|
currentTime: this.getCurrentTime()
|
|
2509
2599
|
});
|
|
@@ -2514,12 +2604,26 @@ addEventListener(eventType, callback) {
|
|
|
2514
2604
|
this.hideLoading();
|
|
2515
2605
|
}
|
|
2516
2606
|
|
|
2607
|
+
this.updateTimeDisplay();
|
|
2608
|
+
|
|
2517
2609
|
this.triggerEvent('canplay', {
|
|
2518
2610
|
currentTime: this.getCurrentTime(),
|
|
2519
2611
|
duration: this.getDuration()
|
|
2520
2612
|
});
|
|
2521
2613
|
});
|
|
2522
2614
|
|
|
2615
|
+
this.video.addEventListener('waiting', () => {
|
|
2616
|
+
if (!this.isChangingQuality) {
|
|
2617
|
+
this.showLoading();
|
|
2618
|
+
|
|
2619
|
+
this.updateTimeDisplay();
|
|
2620
|
+
|
|
2621
|
+
this.triggerEvent('waiting', {
|
|
2622
|
+
currentTime: this.getCurrentTime()
|
|
2623
|
+
});
|
|
2624
|
+
}
|
|
2625
|
+
});
|
|
2626
|
+
|
|
2523
2627
|
this.video.addEventListener('progress', () => {
|
|
2524
2628
|
this.updateBuffer();
|
|
2525
2629
|
|
|
@@ -3219,7 +3323,7 @@ createControls() {
|
|
|
3219
3323
|
<div class="settings-menu"></div>
|
|
3220
3324
|
</div>
|
|
3221
3325
|
|
|
3222
|
-
|
|
3326
|
+
${(this.options.showQualitySelector && this.originalSources && this.originalSources.length > 1) || this.options.adaptiveQualityControl ? `
|
|
3223
3327
|
<div class="quality-control">
|
|
3224
3328
|
<button class="control-btn quality-btn" data-tooltip="video_quality">
|
|
3225
3329
|
<div class="quality-btn-text">
|
|
@@ -4011,6 +4115,11 @@ updateQualityDisplay() {
|
|
|
4011
4115
|
}
|
|
4012
4116
|
|
|
4013
4117
|
updateQualityButton() {
|
|
4118
|
+
if (this.isAdaptiveStream) {
|
|
4119
|
+
if (this.options.debug) console.log('🔒 Adaptive streaming active - quality button managed by streaming.js');
|
|
4120
|
+
return;
|
|
4121
|
+
}
|
|
4122
|
+
|
|
4014
4123
|
const qualityBtn = this.controls?.querySelector('.quality-btn');
|
|
4015
4124
|
if (!qualityBtn) return;
|
|
4016
4125
|
|
|
@@ -4057,6 +4166,11 @@ updateQualityMenu() {
|
|
|
4057
4166
|
const qualityMenu = this.controls?.querySelector('.quality-menu');
|
|
4058
4167
|
if (!qualityMenu) return;
|
|
4059
4168
|
|
|
4169
|
+
if (this.isAdaptiveStream) {
|
|
4170
|
+
if (this.options.debug) console.log('🔒 Adaptive streaming active - quality menu managed by streaming.js');
|
|
4171
|
+
return;
|
|
4172
|
+
}
|
|
4173
|
+
|
|
4060
4174
|
let menuHTML = '';
|
|
4061
4175
|
|
|
4062
4176
|
if (this.isAdaptiveStream && this.adaptiveQualities && this.adaptiveQualities.length > 0) {
|
|
@@ -6391,6 +6505,13 @@ async loadAdaptiveLibraries() {
|
|
|
6391
6505
|
|
|
6392
6506
|
try {
|
|
6393
6507
|
|
|
6508
|
+
this.selectedQuality = 'auto';
|
|
6509
|
+
this.qualityEventsInitialized = false;
|
|
6510
|
+
|
|
6511
|
+
if (this.options.debug) {
|
|
6512
|
+
console.log('🔍 initializeDash - FORCED selectedQuality to:', this.selectedQuality);
|
|
6513
|
+
}
|
|
6514
|
+
|
|
6394
6515
|
if (this.dashPlayer) {
|
|
6395
6516
|
this.dashPlayer.destroy();
|
|
6396
6517
|
}
|
|
@@ -6542,17 +6663,67 @@ disableDashTextTracks() {
|
|
|
6542
6663
|
}
|
|
6543
6664
|
}
|
|
6544
6665
|
|
|
6545
|
-
|
|
6666
|
+
updateAdaptiveQualities() {
|
|
6546
6667
|
this.adaptiveQualities = [];
|
|
6547
6668
|
|
|
6548
6669
|
if (this.adaptiveStreamingType === 'dash' && this.dashPlayer) {
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6670
|
+
try {
|
|
6671
|
+
|
|
6672
|
+
const videoTracks = this.dashPlayer.getTracksFor('video');
|
|
6673
|
+
|
|
6674
|
+
if (this.options.debug) {
|
|
6675
|
+
console.log('✅ DASH getTracksFor result:', videoTracks);
|
|
6676
|
+
}
|
|
6677
|
+
|
|
6678
|
+
if (videoTracks && videoTracks.length > 0) {
|
|
6679
|
+
|
|
6680
|
+
const allQualities = [];
|
|
6681
|
+
|
|
6682
|
+
videoTracks.forEach((track, trackIndex) => {
|
|
6683
|
+
const bitrateList = track.bitrateList || [];
|
|
6684
|
+
|
|
6685
|
+
if (this.options.debug) {
|
|
6686
|
+
console.log(`✅ Track ${trackIndex} (${track.codec}):`, bitrateList);
|
|
6687
|
+
}
|
|
6688
|
+
|
|
6689
|
+
bitrateList.forEach((bitrate, index) => {
|
|
6690
|
+
allQualities.push({
|
|
6691
|
+
trackIndex: trackIndex,
|
|
6692
|
+
bitrateIndex: index,
|
|
6693
|
+
label: `${bitrate.height}p`,
|
|
6553
6694
|
height: bitrate.height,
|
|
6554
|
-
|
|
6555
|
-
|
|
6695
|
+
width: bitrate.width,
|
|
6696
|
+
bandwidth: bitrate.bandwidth,
|
|
6697
|
+
codec: track.codec
|
|
6698
|
+
});
|
|
6699
|
+
});
|
|
6700
|
+
});
|
|
6701
|
+
|
|
6702
|
+
const uniqueHeights = [...new Set(allQualities.map(q => q.height))];
|
|
6703
|
+
uniqueHeights.sort((a, b) => b - a);
|
|
6704
|
+
|
|
6705
|
+
this.adaptiveQualities = uniqueHeights.map((height, index) => {
|
|
6706
|
+
const quality = allQualities.find(q => q.height === height);
|
|
6707
|
+
return {
|
|
6708
|
+
index: index,
|
|
6709
|
+
label: `${height}p`,
|
|
6710
|
+
height: height,
|
|
6711
|
+
trackIndex: quality.trackIndex,
|
|
6712
|
+
bitrateIndex: quality.bitrateIndex,
|
|
6713
|
+
bandwidth: quality.bandwidth,
|
|
6714
|
+
codec: quality.codec
|
|
6715
|
+
};
|
|
6716
|
+
});
|
|
6717
|
+
|
|
6718
|
+
if (this.options.debug) {
|
|
6719
|
+
console.log('✅ All DASH qualities merged:', this.adaptiveQualities);
|
|
6720
|
+
}
|
|
6721
|
+
}
|
|
6722
|
+
} catch (error) {
|
|
6723
|
+
if (this.options.debug) {
|
|
6724
|
+
console.error('❌ Error getting DASH qualities:', error);
|
|
6725
|
+
}
|
|
6726
|
+
}
|
|
6556
6727
|
} else if (this.adaptiveStreamingType === 'hls' && this.hlsPlayer) {
|
|
6557
6728
|
const levels = this.hlsPlayer.levels;
|
|
6558
6729
|
this.adaptiveQualities = levels.map((level, index) => ({
|
|
@@ -6569,8 +6740,360 @@ disableDashTextTracks() {
|
|
|
6569
6740
|
|
|
6570
6741
|
if (this.options.debug) {
|
|
6571
6742
|
console.log('📡 Adaptive qualities available:', this.adaptiveQualities);
|
|
6743
|
+
console.log('📡 Selected quality mode:', this.selectedQuality);
|
|
6744
|
+
}
|
|
6745
|
+
}
|
|
6746
|
+
|
|
6747
|
+
updateAdaptiveQualityMenu() {
|
|
6748
|
+
const qualityMenu = this.controls?.querySelector('.quality-menu');
|
|
6749
|
+
if (!qualityMenu) {
|
|
6750
|
+
if (this.options.debug) console.log('❌ Quality menu not found in DOM');
|
|
6751
|
+
return;
|
|
6752
|
+
}
|
|
6753
|
+
|
|
6754
|
+
if (this.adaptiveQualities.length === 0) {
|
|
6755
|
+
if (this.options.debug) console.log('❌ No adaptive qualities to display');
|
|
6756
|
+
return;
|
|
6757
|
+
}
|
|
6758
|
+
|
|
6759
|
+
const isAutoActive = this.selectedQuality === 'auto';
|
|
6760
|
+
let menuHTML = `<div class="quality-option ${isAutoActive ? 'active' : ''}" data-quality="auto">Auto</div>`;
|
|
6761
|
+
|
|
6762
|
+
this.adaptiveQualities.forEach((quality) => {
|
|
6763
|
+
const isActive = this.selectedQuality === quality.height;
|
|
6764
|
+
|
|
6765
|
+
if (this.options.debug) {
|
|
6766
|
+
console.log('🔍 Quality item:', quality.label, 'height:', quality.height, 'active:', isActive);
|
|
6767
|
+
}
|
|
6768
|
+
|
|
6769
|
+
menuHTML += `<div class="quality-option ${isActive ? 'active' : ''}" data-quality="${quality.height}">
|
|
6770
|
+
${quality.label}
|
|
6771
|
+
<span class="quality-playing" style="display: none; color: #4CAF50; margin-left: 8px; font-size: 0.85em;">● Playing</span>
|
|
6772
|
+
</div>`;
|
|
6773
|
+
});
|
|
6774
|
+
|
|
6775
|
+
qualityMenu.innerHTML = menuHTML;
|
|
6776
|
+
|
|
6777
|
+
if (this.options.debug) {
|
|
6778
|
+
console.log('✅ Quality menu populated with', this.adaptiveQualities.length, 'options');
|
|
6779
|
+
}
|
|
6780
|
+
|
|
6781
|
+
if (!this.qualityEventsInitialized) {
|
|
6782
|
+
this.bindAdaptiveQualityEvents();
|
|
6783
|
+
this.qualityEventsInitialized = true;
|
|
6784
|
+
}
|
|
6785
|
+
|
|
6786
|
+
this.updateAdaptiveQualityDisplay();
|
|
6787
|
+
}
|
|
6788
|
+
|
|
6789
|
+
updateAdaptiveQualityDisplay() {
|
|
6790
|
+
if (!this.dashPlayer && !this.hlsPlayer) return;
|
|
6791
|
+
|
|
6792
|
+
let currentHeight = null;
|
|
6793
|
+
|
|
6794
|
+
try {
|
|
6795
|
+
if (this.adaptiveStreamingType === 'dash' && this.dashPlayer) {
|
|
6796
|
+
|
|
6797
|
+
if (this.video && this.video.videoHeight) {
|
|
6798
|
+
currentHeight = this.video.videoHeight;
|
|
6799
|
+
}
|
|
6800
|
+
|
|
6801
|
+
if (this.options.debug) {
|
|
6802
|
+
console.log('📊 Current video height:', currentHeight, 'Selected mode:', this.selectedQuality);
|
|
6803
|
+
}
|
|
6804
|
+
} else if (this.adaptiveStreamingType === 'hls' && this.hlsPlayer) {
|
|
6805
|
+
const currentLevel = this.hlsPlayer.currentLevel;
|
|
6806
|
+
if (currentLevel >= 0 && this.hlsPlayer.levels[currentLevel]) {
|
|
6807
|
+
currentHeight = this.hlsPlayer.levels[currentLevel].height;
|
|
6808
|
+
}
|
|
6809
|
+
}
|
|
6810
|
+
|
|
6811
|
+
const qualityBtnText = this.controls?.querySelector('.quality-btn .selected-quality');
|
|
6812
|
+
if (qualityBtnText) {
|
|
6813
|
+
if (this.selectedQuality === 'auto') {
|
|
6814
|
+
qualityBtnText.textContent = 'Auto';
|
|
6815
|
+
} else {
|
|
6816
|
+
qualityBtnText.textContent = `${this.selectedQuality}p`;
|
|
6817
|
+
}
|
|
6818
|
+
}
|
|
6819
|
+
|
|
6820
|
+
const currentQualityText = this.controls?.querySelector('.quality-btn .current-quality');
|
|
6821
|
+
if (currentQualityText) {
|
|
6822
|
+
if (this.selectedQuality === 'auto' && currentHeight) {
|
|
6823
|
+
currentQualityText.textContent = `${currentHeight}p`;
|
|
6824
|
+
currentQualityText.style.display = 'block';
|
|
6825
|
+
} else {
|
|
6826
|
+
currentQualityText.textContent = '';
|
|
6827
|
+
currentQualityText.style.display = 'none';
|
|
6828
|
+
}
|
|
6829
|
+
}
|
|
6830
|
+
|
|
6831
|
+
const qualityMenu = this.controls?.querySelector('.quality-menu');
|
|
6832
|
+
if (qualityMenu) {
|
|
6833
|
+
|
|
6834
|
+
qualityMenu.querySelectorAll('.quality-option').forEach(opt => {
|
|
6835
|
+
opt.classList.remove('active');
|
|
6836
|
+
});
|
|
6837
|
+
|
|
6838
|
+
if (this.selectedQuality === 'auto') {
|
|
6839
|
+
const autoOption = qualityMenu.querySelector('[data-quality="auto"]');
|
|
6840
|
+
if (autoOption) autoOption.classList.add('active');
|
|
6841
|
+
} else {
|
|
6842
|
+
const selectedOption = qualityMenu.querySelector(`[data-quality="${this.selectedQuality}"]`);
|
|
6843
|
+
if (selectedOption) selectedOption.classList.add('active');
|
|
6844
|
+
}
|
|
6845
|
+
|
|
6846
|
+
qualityMenu.querySelectorAll('.quality-playing').forEach(el => {
|
|
6847
|
+
el.style.display = 'none';
|
|
6848
|
+
});
|
|
6849
|
+
|
|
6850
|
+
if (this.selectedQuality === 'auto' && currentHeight) {
|
|
6851
|
+
const playingOption = qualityMenu.querySelector(`[data-quality="${currentHeight}"] .quality-playing`);
|
|
6852
|
+
if (playingOption) {
|
|
6853
|
+
playingOption.style.display = 'inline';
|
|
6854
|
+
}
|
|
6855
|
+
}
|
|
6856
|
+
}
|
|
6857
|
+
|
|
6858
|
+
} catch (error) {
|
|
6859
|
+
if (this.options.debug) console.error('❌ Error updating quality display:', error);
|
|
6860
|
+
}
|
|
6861
|
+
}
|
|
6862
|
+
|
|
6863
|
+
updateQualityButtonText() {
|
|
6864
|
+
const qualityBtn = this.controls?.querySelector('.quality-btn .selected-quality');
|
|
6865
|
+
if (!qualityBtn) return;
|
|
6866
|
+
|
|
6867
|
+
if (this.selectedQuality === 'auto' || !this.selectedQuality) {
|
|
6868
|
+
qualityBtn.textContent = this.t('auto');
|
|
6869
|
+
} else {
|
|
6870
|
+
const quality = this.adaptiveQualities.find(q => q.index === parseInt(this.selectedQuality));
|
|
6871
|
+
qualityBtn.textContent = quality ? quality.label : 'Auto';
|
|
6872
|
+
}
|
|
6873
|
+
}
|
|
6874
|
+
|
|
6875
|
+
bindAdaptiveQualityEvents() {
|
|
6876
|
+
const qualityMenu = this.controls?.querySelector('.quality-menu');
|
|
6877
|
+
const qualityBtn = this.controls?.querySelector('.quality-btn');
|
|
6878
|
+
|
|
6879
|
+
if (!qualityMenu || !qualityBtn) return;
|
|
6880
|
+
|
|
6881
|
+
qualityBtn.addEventListener('click', (e) => {
|
|
6882
|
+
e.stopPropagation();
|
|
6883
|
+
qualityMenu.classList.toggle('active');
|
|
6884
|
+
|
|
6885
|
+
if (qualityMenu.classList.contains('active')) {
|
|
6886
|
+
this.updateAdaptiveQualityDisplay();
|
|
6887
|
+
}
|
|
6888
|
+
});
|
|
6889
|
+
|
|
6890
|
+
const closeMenuHandler = (e) => {
|
|
6891
|
+
if (!qualityBtn.contains(e.target) && !qualityMenu.contains(e.target)) {
|
|
6892
|
+
qualityMenu.classList.remove('active');
|
|
6893
|
+
}
|
|
6894
|
+
};
|
|
6895
|
+
document.addEventListener('click', closeMenuHandler);
|
|
6896
|
+
|
|
6897
|
+
qualityMenu.addEventListener('click', (e) => {
|
|
6898
|
+
const option = e.target.closest('.quality-option');
|
|
6899
|
+
if (!option) return;
|
|
6900
|
+
|
|
6901
|
+
e.stopPropagation();
|
|
6902
|
+
|
|
6903
|
+
const qualityData = option.getAttribute('data-quality');
|
|
6904
|
+
|
|
6905
|
+
if (this.options.debug) {
|
|
6906
|
+
console.log('🎬 Quality clicked - raw data:', qualityData, 'type:', typeof qualityData);
|
|
6907
|
+
}
|
|
6908
|
+
|
|
6909
|
+
if (qualityData === 'auto') {
|
|
6910
|
+
|
|
6911
|
+
this.selectedQuality = 'auto';
|
|
6912
|
+
|
|
6913
|
+
if (this.adaptiveStreamingType === 'dash' && this.dashPlayer) {
|
|
6914
|
+
this.dashPlayer.updateSettings({
|
|
6915
|
+
streaming: {
|
|
6916
|
+
abr: {
|
|
6917
|
+
autoSwitchBitrate: { video: true }
|
|
6918
|
+
}
|
|
6919
|
+
}
|
|
6920
|
+
});
|
|
6921
|
+
if (this.options.debug) console.log('✅ Auto quality enabled');
|
|
6922
|
+
} else if (this.adaptiveStreamingType === 'hls' && this.hlsPlayer) {
|
|
6923
|
+
this.hlsPlayer.currentLevel = -1;
|
|
6924
|
+
}
|
|
6925
|
+
|
|
6926
|
+
} else {
|
|
6927
|
+
|
|
6928
|
+
const selectedHeight = parseInt(qualityData, 10);
|
|
6929
|
+
|
|
6930
|
+
if (isNaN(selectedHeight)) {
|
|
6931
|
+
if (this.options.debug) console.error('❌ Invalid quality data:', qualityData);
|
|
6932
|
+
return;
|
|
6933
|
+
}
|
|
6934
|
+
|
|
6935
|
+
if (this.options.debug) {
|
|
6936
|
+
console.log('🎬 Setting manual quality to height:', selectedHeight);
|
|
6937
|
+
}
|
|
6938
|
+
|
|
6939
|
+
this.selectedQuality = selectedHeight;
|
|
6940
|
+
|
|
6941
|
+
if (this.adaptiveStreamingType === 'dash') {
|
|
6942
|
+
this.setDashQualityByHeight(selectedHeight);
|
|
6943
|
+
} else if (this.adaptiveStreamingType === 'hls') {
|
|
6944
|
+
const levelIndex = this.hlsPlayer.levels.findIndex(l => l.height === selectedHeight);
|
|
6945
|
+
if (levelIndex >= 0) {
|
|
6946
|
+
this.hlsPlayer.currentLevel = levelIndex;
|
|
6947
|
+
}
|
|
6948
|
+
}
|
|
6949
|
+
}
|
|
6950
|
+
|
|
6951
|
+
this.updateAdaptiveQualityDisplay();
|
|
6952
|
+
|
|
6953
|
+
qualityMenu.classList.remove('active');
|
|
6954
|
+
});
|
|
6955
|
+
|
|
6956
|
+
if (this.options.debug) {
|
|
6957
|
+
console.log('✅ Quality events bound');
|
|
6958
|
+
}
|
|
6959
|
+
}
|
|
6960
|
+
|
|
6961
|
+
setDashQualityByHeight(targetHeight) {
|
|
6962
|
+
if (!this.dashPlayer) return;
|
|
6963
|
+
|
|
6964
|
+
try {
|
|
6965
|
+
const targetQuality = this.adaptiveQualities.find(q => q.height === targetHeight);
|
|
6966
|
+
if (!targetQuality) {
|
|
6967
|
+
if (this.options.debug) console.error('❌ Quality not found for height:', targetHeight);
|
|
6968
|
+
return;
|
|
6969
|
+
}
|
|
6970
|
+
|
|
6971
|
+
if (this.options.debug) {
|
|
6972
|
+
console.log('🎬 Setting quality:', targetQuality);
|
|
6973
|
+
}
|
|
6974
|
+
|
|
6975
|
+
this.dashPlayer.updateSettings({
|
|
6976
|
+
streaming: {
|
|
6977
|
+
abr: {
|
|
6978
|
+
autoSwitchBitrate: { video: false }
|
|
6979
|
+
}
|
|
6980
|
+
}
|
|
6981
|
+
});
|
|
6982
|
+
|
|
6983
|
+
const currentTrack = this.dashPlayer.getCurrentTrackFor('video');
|
|
6984
|
+
|
|
6985
|
+
if (!currentTrack) {
|
|
6986
|
+
if (this.options.debug) console.error('❌ No current video track');
|
|
6987
|
+
return;
|
|
6988
|
+
}
|
|
6989
|
+
|
|
6990
|
+
const allTracks = this.dashPlayer.getTracksFor('video');
|
|
6991
|
+
let targetTrack = null;
|
|
6992
|
+
|
|
6993
|
+
for (const track of allTracks) {
|
|
6994
|
+
if (track.bitrateList && track.bitrateList[targetQuality.bitrateIndex]) {
|
|
6995
|
+
const bitrate = track.bitrateList[targetQuality.bitrateIndex];
|
|
6996
|
+
if (bitrate.height === targetHeight) {
|
|
6997
|
+
targetTrack = track;
|
|
6998
|
+
break;
|
|
6999
|
+
}
|
|
7000
|
+
}
|
|
7001
|
+
}
|
|
7002
|
+
|
|
7003
|
+
if (!targetTrack) {
|
|
7004
|
+
if (this.options.debug) console.error('❌ Target track not found');
|
|
7005
|
+
return;
|
|
7006
|
+
}
|
|
7007
|
+
|
|
7008
|
+
if (currentTrack.index !== targetTrack.index) {
|
|
7009
|
+
this.dashPlayer.setCurrentTrack(targetTrack);
|
|
7010
|
+
if (this.options.debug) {
|
|
7011
|
+
console.log('✅ Switched to track:', targetTrack.index);
|
|
7012
|
+
}
|
|
7013
|
+
}
|
|
7014
|
+
|
|
7015
|
+
setTimeout(() => {
|
|
7016
|
+
try {
|
|
7017
|
+
|
|
7018
|
+
this.dashPlayer.updateSettings({
|
|
7019
|
+
streaming: {
|
|
7020
|
+
abr: {
|
|
7021
|
+
initialBitrate: { video: targetQuality.bandwidth / 1000 },
|
|
7022
|
+
maxBitrate: { video: targetQuality.bandwidth / 1000 },
|
|
7023
|
+
minBitrate: { video: targetQuality.bandwidth / 1000 }
|
|
7024
|
+
}
|
|
7025
|
+
}
|
|
7026
|
+
});
|
|
7027
|
+
|
|
7028
|
+
if (this.options.debug) {
|
|
7029
|
+
console.log('✅ Quality locked to:', targetHeight + 'p', 'bandwidth:', targetQuality.bandwidth);
|
|
7030
|
+
}
|
|
7031
|
+
|
|
7032
|
+
const qualityBtnText = this.controls?.querySelector('.quality-btn .selected-quality');
|
|
7033
|
+
if (qualityBtnText) {
|
|
7034
|
+
qualityBtnText.textContent = `${targetHeight}p`;
|
|
7035
|
+
}
|
|
7036
|
+
|
|
7037
|
+
const currentTime = this.video.currentTime;
|
|
7038
|
+
this.dashPlayer.seek(currentTime + 0.1);
|
|
7039
|
+
setTimeout(() => {
|
|
7040
|
+
this.dashPlayer.seek(currentTime);
|
|
7041
|
+
}, 100);
|
|
7042
|
+
|
|
7043
|
+
} catch (innerError) {
|
|
7044
|
+
if (this.options.debug) console.error('❌ Error setting quality:', innerError);
|
|
7045
|
+
}
|
|
7046
|
+
}, 100);
|
|
7047
|
+
|
|
7048
|
+
} catch (error) {
|
|
7049
|
+
if (this.options.debug) console.error('❌ Error in setDashQualityByHeight:', error);
|
|
7050
|
+
}
|
|
7051
|
+
}
|
|
7052
|
+
|
|
7053
|
+
setDashQuality(qualityIndex) {
|
|
7054
|
+
if (!this.dashPlayer) return;
|
|
7055
|
+
|
|
7056
|
+
try {
|
|
7057
|
+
const selectedQuality = this.adaptiveQualities[qualityIndex];
|
|
7058
|
+
if (!selectedQuality) {
|
|
7059
|
+
if (this.options.debug) console.error('❌ Quality not found at index:', qualityIndex);
|
|
7060
|
+
return;
|
|
7061
|
+
}
|
|
7062
|
+
|
|
7063
|
+
if (this.options.debug) {
|
|
7064
|
+
console.log('🎬 Setting DASH quality:', selectedQuality);
|
|
7065
|
+
}
|
|
7066
|
+
|
|
7067
|
+
this.dashPlayer.updateSettings({
|
|
7068
|
+
streaming: {
|
|
7069
|
+
abr: {
|
|
7070
|
+
autoSwitchBitrate: { video: false }
|
|
7071
|
+
}
|
|
7072
|
+
}
|
|
7073
|
+
});
|
|
7074
|
+
|
|
7075
|
+
setTimeout(() => {
|
|
7076
|
+
try {
|
|
7077
|
+
this.dashPlayer.setQualityFor('video', selectedQuality.bitrateIndex);
|
|
7078
|
+
|
|
7079
|
+
if (this.options.debug) {
|
|
7080
|
+
console.log('✅ DASH quality set to bitrateIndex:', selectedQuality.bitrateIndex, 'height:', selectedQuality.height);
|
|
7081
|
+
}
|
|
7082
|
+
|
|
7083
|
+
const qualityBtnText = this.controls?.querySelector('.quality-btn .selected-quality');
|
|
7084
|
+
if (qualityBtnText) {
|
|
7085
|
+
qualityBtnText.textContent = selectedQuality.label;
|
|
7086
|
+
}
|
|
7087
|
+
|
|
7088
|
+
} catch (innerError) {
|
|
7089
|
+
if (this.options.debug) console.error('❌ Error setting quality:', innerError);
|
|
6572
7090
|
}
|
|
7091
|
+
}, 100);
|
|
7092
|
+
|
|
7093
|
+
} catch (error) {
|
|
7094
|
+
if (this.options.debug) console.error('❌ Error in setDashQuality:', error);
|
|
6573
7095
|
}
|
|
7096
|
+
}
|
|
6574
7097
|
|
|
6575
7098
|
handleAdaptiveError(data) {
|
|
6576
7099
|
if (this.options.debug) console.error('📡 Fatal adaptive streaming error:', data);
|
|
@@ -6901,20 +7424,20 @@ getBufferedTime() {
|
|
|
6901
7424
|
} catch (error) {
|
|
6902
7425
|
return 0;
|
|
6903
7426
|
}
|
|
6904
|
-
|
|
7427
|
+
}
|
|
6905
7428
|
|
|
6906
|
-
|
|
7429
|
+
clearTitleTimeout() {
|
|
6907
7430
|
if (this.titleTimeout) {
|
|
6908
7431
|
clearTimeout(this.titleTimeout);
|
|
6909
7432
|
this.titleTimeout = null;
|
|
6910
7433
|
}
|
|
6911
|
-
|
|
7434
|
+
}
|
|
6912
7435
|
|
|
6913
|
-
|
|
7436
|
+
skipTime(seconds) {
|
|
6914
7437
|
if (!this.video || !this.video.duration || this.isChangingQuality) return;
|
|
6915
7438
|
|
|
6916
7439
|
this.video.currentTime = Math.max(0, Math.min(this.video.duration, this.video.currentTime + seconds));
|
|
6917
|
-
|
|
7440
|
+
}
|
|
6918
7441
|
|
|
6919
7442
|
updateTimeDisplay() {
|
|
6920
7443
|
|
|
@@ -6924,20 +7447,34 @@ updateTimeDisplay() {
|
|
|
6924
7447
|
|
|
6925
7448
|
if (this.durationEl && this.video) {
|
|
6926
7449
|
const duration = this.video.duration;
|
|
7450
|
+
const readyState = this.video.readyState;
|
|
7451
|
+
const currentTime = this.video.currentTime;
|
|
7452
|
+
const networkState = this.video.networkState;
|
|
7453
|
+
|
|
7454
|
+
const isInitialBuffering = (readyState < 2 && currentTime === 0) ||
|
|
7455
|
+
(currentTime === 0 && (!duration || duration === 0) && networkState === 2);
|
|
7456
|
+
|
|
7457
|
+
const isDurationInvalid = !duration || isNaN(duration) || !isFinite(duration);
|
|
6927
7458
|
|
|
6928
|
-
if (
|
|
7459
|
+
if (isInitialBuffering) {
|
|
6929
7460
|
|
|
6930
|
-
this.durationEl.
|
|
7461
|
+
this.durationEl.textContent = t('loading');
|
|
7462
|
+
this.durationEl.classList.remove('encoding-state');
|
|
7463
|
+
this.durationEl.classList.add('loading-state');
|
|
7464
|
+
} else if (isDurationInvalid) {
|
|
7465
|
+
|
|
7466
|
+
this.durationEl.textContent = t('encoding_in_progress');
|
|
7467
|
+
this.durationEl.classList.remove('loading-state');
|
|
6931
7468
|
this.durationEl.classList.add('encoding-state');
|
|
6932
7469
|
} else {
|
|
6933
7470
|
|
|
6934
7471
|
this.durationEl.textContent = this.formatTime(duration);
|
|
6935
|
-
this.durationEl.classList.remove('encoding-state');
|
|
7472
|
+
this.durationEl.classList.remove('encoding-state', 'loading-state');
|
|
6936
7473
|
}
|
|
6937
7474
|
}
|
|
6938
7475
|
}
|
|
6939
7476
|
|
|
6940
|
-
|
|
7477
|
+
formatTime(seconds) {
|
|
6941
7478
|
if (isNaN(seconds) || seconds < 0) return '0:00';
|
|
6942
7479
|
|
|
6943
7480
|
const hours = Math.floor(seconds / 3600);
|
|
@@ -6948,7 +7485,7 @@ updateTimeDisplay() {
|
|
|
6948
7485
|
return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
|
|
6949
7486
|
}
|
|
6950
7487
|
return `${minutes}:${secs.toString().padStart(2, '0')}`;
|
|
6951
|
-
|
|
7488
|
+
}
|
|
6952
7489
|
|
|
6953
7490
|
}
|
|
6954
7491
|
|