myetv-player 1.1.6 → 1.3.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/css/myetv-player.css +153 -0
- package/css/myetv-player.min.css +1 -1
- package/dist/myetv-player.js +654 -129
- package/dist/myetv-player.min.js +579 -115
- package/package.json +35 -16
- package/plugins/twitch/myetv-player-twitch-plugin.js +125 -11
- package/plugins/vimeo/myetv-player-vimeo.js +80 -49
- package/plugins/youtube/README.md +5 -2
- package/plugins/youtube/myetv-player-youtube-plugin.js +891 -14
- package/.github/workflows/codeql.yml +0 -100
- package/.github/workflows/npm-publish.yml +0 -30
- package/SECURITY.md +0 -50
- package/build.js +0 -195
- package/scss/README.md +0 -161
- package/scss/_audio-player.scss +0 -21
- package/scss/_base.scss +0 -116
- package/scss/_controls.scss +0 -188
- package/scss/_loading.scss +0 -111
- package/scss/_menus.scss +0 -432
- package/scss/_mixins.scss +0 -112
- package/scss/_poster.scss +0 -8
- package/scss/_progress-bar.scss +0 -319
- package/scss/_resolution.scss +0 -68
- package/scss/_responsive.scss +0 -1360
- package/scss/_themes.scss +0 -30
- package/scss/_title-overlay.scss +0 -60
- package/scss/_tooltips.scss +0 -7
- package/scss/_variables.scss +0 -49
- package/scss/_video.scss +0 -221
- package/scss/_volume.scss +0 -122
- package/scss/_watermark.scss +0 -128
- package/scss/myetv-player.scss +0 -51
- package/scss/package.json +0 -16
- package/src/README.md +0 -560
- package/src/chapters.js +0 -521
- package/src/controls.js +0 -1243
- package/src/core.js +0 -1922
- package/src/events.js +0 -456
- package/src/fullscreen.js +0 -82
- package/src/i18n.js +0 -374
- package/src/playlist.js +0 -177
- package/src/plugins.js +0 -384
- package/src/quality.js +0 -963
- package/src/streaming.js +0 -346
- package/src/subtitles.js +0 -524
- package/src/utils.js +0 -65
- package/src/watermark.js +0 -246
package/dist/myetv-player.js
CHANGED
|
@@ -9,14 +9,15 @@ class VideoPlayerI18n {
|
|
|
9
9
|
// Italiano
|
|
10
10
|
'it': {
|
|
11
11
|
'subtitles': 'Sottotitoli (C)',
|
|
12
|
-
'
|
|
13
|
-
'
|
|
12
|
+
'subtitlesoff': 'Disattivati',
|
|
13
|
+
'subtitlesdisable': 'Disabilita sottotitoli',
|
|
14
|
+
'subtitlesenable': 'Abilita sottotitoli',
|
|
14
15
|
'play_pause': 'Play/Pausa (Spazio)',
|
|
15
16
|
'mute_unmute': 'Muta/Smuta (M)',
|
|
16
17
|
'volume': 'Volume',
|
|
17
18
|
'playback_speed': 'Velocità riproduzione',
|
|
18
19
|
'video_quality': 'Qualità video',
|
|
19
|
-
'picture_in_picture': '
|
|
20
|
+
'picture_in_picture': 'Finestra sovrapposta (P)',
|
|
20
21
|
'fullscreen': 'Schermo intero (F)',
|
|
21
22
|
'auto': 'Auto',
|
|
22
23
|
'brand_logo': 'Logo',
|
|
@@ -30,6 +31,7 @@ class VideoPlayerI18n {
|
|
|
30
31
|
// English
|
|
31
32
|
'en': {
|
|
32
33
|
'subtitles': 'Subtitles (C)',
|
|
34
|
+
'subtitlesoff': 'Off',
|
|
33
35
|
'subtitlesdisable': 'Disable Subtitles',
|
|
34
36
|
'subtitlesenable': 'Enable Subtitles',
|
|
35
37
|
'play_pause': 'Play/Pause (Space)',
|
|
@@ -45,24 +47,21 @@ class VideoPlayerI18n {
|
|
|
45
47
|
'prev_video': 'Previous video (P)',
|
|
46
48
|
'playlist_next': 'Next',
|
|
47
49
|
'playlist_prev': 'Previous',
|
|
48
|
-
'next_video': 'Next video (N)',
|
|
49
|
-
'prev_video': 'Previous video (P)',
|
|
50
|
-
'playlist_next': 'Next',
|
|
51
|
-
'playlist_prev': 'Previous',
|
|
52
50
|
'settings_menu': 'Settings'
|
|
53
51
|
},
|
|
54
52
|
|
|
55
53
|
// Español
|
|
56
54
|
'es': {
|
|
57
55
|
'subtitles': 'Subtítulos (C)',
|
|
58
|
-
'
|
|
59
|
-
'
|
|
56
|
+
'subtitlesoff': 'Desactivados',
|
|
57
|
+
'subtitlesdisable': 'Desactivar subtítulos',
|
|
58
|
+
'subtitlesenable': 'Activar subtítulos',
|
|
60
59
|
'play_pause': 'Reproducir/Pausar (Espacio)',
|
|
61
60
|
'mute_unmute': 'Silenciar (M)',
|
|
62
61
|
'volume': 'Volumen',
|
|
63
62
|
'playback_speed': 'Velocidad de reproducción',
|
|
64
63
|
'video_quality': 'Calidad de vídeo',
|
|
65
|
-
'picture_in_picture': '
|
|
64
|
+
'picture_in_picture': 'Imagen en imagen (P)',
|
|
66
65
|
'fullscreen': 'Pantalla completa (F)',
|
|
67
66
|
'auto': 'Auto',
|
|
68
67
|
'brand_logo': 'Logo de marca',
|
|
@@ -70,20 +69,21 @@ class VideoPlayerI18n {
|
|
|
70
69
|
'prev_video': 'Vídeo anterior (P)',
|
|
71
70
|
'playlist_next': 'Siguiente',
|
|
72
71
|
'playlist_prev': 'Anterior',
|
|
73
|
-
'settings_menu': '
|
|
72
|
+
'settings_menu': 'Configuración'
|
|
74
73
|
},
|
|
75
74
|
|
|
76
75
|
// Français
|
|
77
76
|
'fr': {
|
|
78
77
|
'subtitles': 'Sous-titres (C)',
|
|
79
|
-
'
|
|
80
|
-
'
|
|
78
|
+
'subtitlesoff': 'Désactivés',
|
|
79
|
+
'subtitlesdisable': 'Désactiver les sous-titres',
|
|
80
|
+
'subtitlesenable': 'Activer les sous-titres',
|
|
81
81
|
'play_pause': 'Lecture/Pause (Espace)',
|
|
82
82
|
'mute_unmute': 'Muet (M)',
|
|
83
83
|
'volume': 'Volume',
|
|
84
84
|
'playback_speed': 'Vitesse de lecture',
|
|
85
85
|
'video_quality': 'Qualité vidéo',
|
|
86
|
-
'picture_in_picture': '
|
|
86
|
+
'picture_in_picture': 'Image dans l’image (P)',
|
|
87
87
|
'fullscreen': 'Plein écran (F)',
|
|
88
88
|
'auto': 'Auto',
|
|
89
89
|
'brand_logo': 'Logo de marque',
|
|
@@ -91,20 +91,21 @@ class VideoPlayerI18n {
|
|
|
91
91
|
'prev_video': 'Vidéo précédente (P)',
|
|
92
92
|
'playlist_next': 'Suivant',
|
|
93
93
|
'playlist_prev': 'Précédent',
|
|
94
|
-
'settings_menu': '
|
|
94
|
+
'settings_menu': 'Paramètres'
|
|
95
95
|
},
|
|
96
96
|
|
|
97
97
|
// Deutsch
|
|
98
98
|
'de': {
|
|
99
99
|
'subtitles': 'Untertitel (C)',
|
|
100
|
-
'
|
|
101
|
-
'
|
|
100
|
+
'subtitlesoff': 'Aus',
|
|
101
|
+
'subtitlesdisable': 'Untertitel deaktivieren',
|
|
102
|
+
'subtitlesenable': 'Untertitel aktivieren',
|
|
102
103
|
'play_pause': 'Abspielen/Pausieren (Leertaste)',
|
|
103
104
|
'mute_unmute': 'Stumm (M)',
|
|
104
105
|
'volume': 'Lautstärke',
|
|
105
106
|
'playback_speed': 'Wiedergabegeschwindigkeit',
|
|
106
107
|
'video_quality': 'Videoqualität',
|
|
107
|
-
'picture_in_picture': '
|
|
108
|
+
'picture_in_picture': 'Bild-in-Bild (P)',
|
|
108
109
|
'fullscreen': 'Vollbild (F)',
|
|
109
110
|
'auto': 'Auto',
|
|
110
111
|
'brand_logo': 'Markenlogo',
|
|
@@ -112,20 +113,21 @@ class VideoPlayerI18n {
|
|
|
112
113
|
'prev_video': 'Vorheriges Video (P)',
|
|
113
114
|
'playlist_next': 'Weiter',
|
|
114
115
|
'playlist_prev': 'Zurück',
|
|
115
|
-
'settings_menu': '
|
|
116
|
+
'settings_menu': 'Einstellungen'
|
|
116
117
|
},
|
|
117
118
|
|
|
118
119
|
// Português
|
|
119
120
|
'pt': {
|
|
120
121
|
'subtitles': 'Legendas (C)',
|
|
121
|
-
'
|
|
122
|
-
'
|
|
122
|
+
'subtitlesoff': 'Desativadas',
|
|
123
|
+
'subtitlesdisable': 'Desativar legendas',
|
|
124
|
+
'subtitlesenable': 'Ativar legendas',
|
|
123
125
|
'play_pause': 'Reproduzir/Pausar (Espaço)',
|
|
124
126
|
'mute_unmute': 'Silenciar (M)',
|
|
125
127
|
'volume': 'Volume',
|
|
126
128
|
'playback_speed': 'Velocidade de reprodução',
|
|
127
129
|
'video_quality': 'Qualidade do vídeo',
|
|
128
|
-
'picture_in_picture': '
|
|
130
|
+
'picture_in_picture': 'Imagem em imagem (P)',
|
|
129
131
|
'fullscreen': 'Tela cheia (F)',
|
|
130
132
|
'auto': 'Auto',
|
|
131
133
|
'brand_logo': 'Logo da marca',
|
|
@@ -133,14 +135,15 @@ class VideoPlayerI18n {
|
|
|
133
135
|
'prev_video': 'Vídeo anterior (P)',
|
|
134
136
|
'playlist_next': 'Próximo',
|
|
135
137
|
'playlist_prev': 'Anterior',
|
|
136
|
-
'settings_menu': '
|
|
138
|
+
'settings_menu': 'Configurações'
|
|
137
139
|
},
|
|
138
140
|
|
|
139
141
|
// 中文
|
|
140
142
|
'zh': {
|
|
141
143
|
'subtitles': '字幕 (C)',
|
|
142
|
-
'
|
|
143
|
-
'
|
|
144
|
+
'subtitlesoff': '关闭',
|
|
145
|
+
'subtitlesdisable': '禁用字幕',
|
|
146
|
+
'subtitlesenable': '启用字幕',
|
|
144
147
|
'play_pause': '播放/暂停 (空格)',
|
|
145
148
|
'mute_unmute': '静音 (M)',
|
|
146
149
|
'volume': '音量',
|
|
@@ -154,14 +157,15 @@ class VideoPlayerI18n {
|
|
|
154
157
|
'prev_video': '上一个视频 (P)',
|
|
155
158
|
'playlist_next': '下一个',
|
|
156
159
|
'playlist_prev': '上一个',
|
|
157
|
-
'settings_menu': '
|
|
160
|
+
'settings_menu': '设置'
|
|
158
161
|
},
|
|
159
162
|
|
|
160
163
|
// 日本語
|
|
161
164
|
'ja': {
|
|
162
165
|
'subtitles': '字幕 (C)',
|
|
163
|
-
'
|
|
164
|
-
'
|
|
166
|
+
'subtitlesoff': 'オフ',
|
|
167
|
+
'subtitlesdisable': '字幕を無効にする',
|
|
168
|
+
'subtitlesenable': '字幕を有効にする',
|
|
165
169
|
'play_pause': '再生/一時停止 (スペース)',
|
|
166
170
|
'mute_unmute': 'ミュート (M)',
|
|
167
171
|
'volume': '音量',
|
|
@@ -175,14 +179,15 @@ class VideoPlayerI18n {
|
|
|
175
179
|
'prev_video': '前の動画 (P)',
|
|
176
180
|
'playlist_next': '次へ',
|
|
177
181
|
'playlist_prev': '前へ',
|
|
178
|
-
'settings_menu': '
|
|
182
|
+
'settings_menu': '設定'
|
|
179
183
|
},
|
|
180
184
|
|
|
181
185
|
// Русский
|
|
182
186
|
'ru': {
|
|
183
187
|
'subtitles': 'Субтитры (C)',
|
|
184
|
-
'
|
|
185
|
-
'
|
|
188
|
+
'subtitlesoff': 'Выкл',
|
|
189
|
+
'subtitlesdisable': 'Отключить субтитры',
|
|
190
|
+
'subtitlesenable': 'Включить субтитры',
|
|
186
191
|
'play_pause': 'Воспроизведение/Пауза (Пробел)',
|
|
187
192
|
'mute_unmute': 'Звук (M)',
|
|
188
193
|
'volume': 'Громкость',
|
|
@@ -196,14 +201,15 @@ class VideoPlayerI18n {
|
|
|
196
201
|
'prev_video': 'Предыдущее видео (P)',
|
|
197
202
|
'playlist_next': 'Далее',
|
|
198
203
|
'playlist_prev': 'Назад',
|
|
199
|
-
'settings_menu': '
|
|
204
|
+
'settings_menu': 'Настройки'
|
|
200
205
|
},
|
|
201
206
|
|
|
202
207
|
// العربية
|
|
203
208
|
'ar': {
|
|
204
209
|
'subtitles': 'الترجمة (C)',
|
|
205
|
-
'
|
|
206
|
-
'
|
|
210
|
+
'subtitlesoff': 'إيقاف',
|
|
211
|
+
'subtitlesdisable': 'تعطيل الترجمة',
|
|
212
|
+
'subtitlesenable': 'تفعيل الترجمة',
|
|
207
213
|
'play_pause': 'تشغيل/إيقاف مؤقت (مسافة)',
|
|
208
214
|
'mute_unmute': 'كتم الصوت (M)',
|
|
209
215
|
'volume': 'مستوى الصوت',
|
|
@@ -217,10 +223,187 @@ class VideoPlayerI18n {
|
|
|
217
223
|
'prev_video': 'الفيديو السابق (P)',
|
|
218
224
|
'playlist_next': 'التالي',
|
|
219
225
|
'playlist_prev': 'السابق',
|
|
220
|
-
'settings_menu': '
|
|
226
|
+
'settings_menu': 'الإعدادات'
|
|
227
|
+
},
|
|
228
|
+
|
|
229
|
+
// 한국어 (Korean)
|
|
230
|
+
'ko': {
|
|
231
|
+
'subtitles': '자막 (C)',
|
|
232
|
+
'subtitlesoff': '끄기',
|
|
233
|
+
'subtitlesdisable': '자막 비활성화',
|
|
234
|
+
'subtitlesenable': '자막 활성화',
|
|
235
|
+
'play_pause': '재생/일시정지 (스페이스)',
|
|
236
|
+
'mute_unmute': '음소거 (M)',
|
|
237
|
+
'volume': '음량',
|
|
238
|
+
'playback_speed': '재생 속도',
|
|
239
|
+
'video_quality': '비디오 품질',
|
|
240
|
+
'picture_in_picture': '화면 속 화면 (P)',
|
|
241
|
+
'fullscreen': '전체 화면 (F)',
|
|
242
|
+
'auto': '자동',
|
|
243
|
+
'brand_logo': '브랜드 로고',
|
|
244
|
+
'next_video': '다음 비디오 (N)',
|
|
245
|
+
'prev_video': '이전 비디오 (P)',
|
|
246
|
+
'playlist_next': '다음',
|
|
247
|
+
'playlist_prev': '이전',
|
|
248
|
+
'settings_menu': '설정'
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
// Polski
|
|
252
|
+
'pl': {
|
|
253
|
+
'subtitles': 'Napisy (C)',
|
|
254
|
+
'subtitlesoff': 'Wyłączone',
|
|
255
|
+
'subtitlesdisable': 'Wyłącz napisy',
|
|
256
|
+
'subtitlesenable': 'Włącz napisy',
|
|
257
|
+
'play_pause': 'Odtwarzaj/Pauza (Spacja)',
|
|
258
|
+
'mute_unmute': 'Wycisz (M)',
|
|
259
|
+
'volume': 'Głośność',
|
|
260
|
+
'playback_speed': 'Prędkość odtwarzania',
|
|
261
|
+
'video_quality': 'Jakość wideo',
|
|
262
|
+
'picture_in_picture': 'Obraz w obrazie (P)',
|
|
263
|
+
'fullscreen': 'Pełny ekran (F)',
|
|
264
|
+
'auto': 'Auto',
|
|
265
|
+
'brand_logo': 'Logo marki',
|
|
266
|
+
'next_video': 'Następne wideo (N)',
|
|
267
|
+
'prev_video': 'Poprzednie wideo (P)',
|
|
268
|
+
'playlist_next': 'Dalej',
|
|
269
|
+
'playlist_prev': 'Wstecz',
|
|
270
|
+
'settings_menu': 'Ustawienia'
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
// Magyar
|
|
274
|
+
'hu': {
|
|
275
|
+
'subtitles': 'Feliratok (C)',
|
|
276
|
+
'subtitlesoff': 'Kikapcsolva',
|
|
277
|
+
'subtitlesdisable': 'Feliratok kikapcsolása',
|
|
278
|
+
'subtitlesenable': 'Feliratok bekapcsolása',
|
|
279
|
+
'play_pause': 'Lejátszás/Szünet (Szóköz)',
|
|
280
|
+
'mute_unmute': 'Némítás (M)',
|
|
281
|
+
'volume': 'Hangerő',
|
|
282
|
+
'playback_speed': 'Lejátszási sebesség',
|
|
283
|
+
'video_quality': 'Videó minősége',
|
|
284
|
+
'picture_in_picture': 'Kép a képben (P)',
|
|
285
|
+
'fullscreen': 'Teljes képernyő (F)',
|
|
286
|
+
'auto': 'Auto',
|
|
287
|
+
'brand_logo': 'Márka logó',
|
|
288
|
+
'next_video': 'Következő videó (N)',
|
|
289
|
+
'prev_video': 'Előző videó (P)',
|
|
290
|
+
'playlist_next': 'Következő',
|
|
291
|
+
'playlist_prev': 'Előző',
|
|
292
|
+
'settings_menu': 'Beállítások'
|
|
293
|
+
},
|
|
294
|
+
|
|
295
|
+
// Türkçe
|
|
296
|
+
'tr': {
|
|
297
|
+
'subtitles': 'Altyazılar (C)',
|
|
298
|
+
'subtitlesoff': 'Kapalı',
|
|
299
|
+
'subtitlesdisable': 'Altyazıları kapat',
|
|
300
|
+
'subtitlesenable': 'Altyazıları aç',
|
|
301
|
+
'play_pause': 'Oynat/Duraklat (Boşluk)',
|
|
302
|
+
'mute_unmute': 'Sessize al (M)',
|
|
303
|
+
'volume': 'Ses düzeyi',
|
|
304
|
+
'playback_speed': 'Oynatma hızı',
|
|
305
|
+
'video_quality': 'Video kalitesi',
|
|
306
|
+
'picture_in_picture': 'Resim içinde resim (P)',
|
|
307
|
+
'fullscreen': 'Tam ekran (F)',
|
|
308
|
+
'auto': 'Otomatik',
|
|
309
|
+
'brand_logo': 'Marka logosu',
|
|
310
|
+
'next_video': 'Sonraki video (N)',
|
|
311
|
+
'prev_video': 'Önceki video (P)',
|
|
312
|
+
'playlist_next': 'Sonraki',
|
|
313
|
+
'playlist_prev': 'Önceki',
|
|
314
|
+
'settings_menu': 'Ayarlar'
|
|
315
|
+
},
|
|
316
|
+
|
|
317
|
+
// Nederlands
|
|
318
|
+
'nl': {
|
|
319
|
+
'subtitles': 'Ondertitels (C)',
|
|
320
|
+
'subtitlesoff': 'Uit',
|
|
321
|
+
'subtitlesdisable': 'Ondertitels uitschakelen',
|
|
322
|
+
'subtitlesenable': 'Ondertitels inschakelen',
|
|
323
|
+
'play_pause': 'Afspelen/Pauzeren (Spatie)',
|
|
324
|
+
'mute_unmute': 'Dempen (M)',
|
|
325
|
+
'volume': 'Volume',
|
|
326
|
+
'playback_speed': 'Afspeelsnelheid',
|
|
327
|
+
'video_quality': 'Videokwaliteit',
|
|
328
|
+
'picture_in_picture': 'Beeld-in-beeld (P)',
|
|
329
|
+
'fullscreen': 'Volledig scherm (F)',
|
|
330
|
+
'auto': 'Auto',
|
|
331
|
+
'brand_logo': 'Merklogo',
|
|
332
|
+
'next_video': 'Volgende video (N)',
|
|
333
|
+
'prev_video': 'Vorige video (P)',
|
|
334
|
+
'playlist_next': 'Volgende',
|
|
335
|
+
'playlist_prev': 'Vorige',
|
|
336
|
+
'settings_menu': 'Instellingen'
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
// हिन्दी (Hindi)
|
|
340
|
+
'hi': {
|
|
341
|
+
'subtitles': 'उपशीर्षक (C)',
|
|
342
|
+
'subtitlesoff': 'बंद',
|
|
343
|
+
'subtitlesdisable': 'उपशीर्षक अक्षम करें',
|
|
344
|
+
'subtitlesenable': 'उपशीर्षक सक्षम करें',
|
|
345
|
+
'play_pause': 'चलाएं/रोकें (स्पेस)',
|
|
346
|
+
'mute_unmute': 'म्यूट (M)',
|
|
347
|
+
'volume': 'वॉल्यूम',
|
|
348
|
+
'playback_speed': 'प्लेबैक गति',
|
|
349
|
+
'video_quality': 'वीडियो गुणवत्ता',
|
|
350
|
+
'picture_in_picture': 'चित्र-में-चित्र (P)',
|
|
351
|
+
'fullscreen': 'पूर्ण स्क्रीन (F)',
|
|
352
|
+
'auto': 'स्वतः',
|
|
353
|
+
'brand_logo': 'ब्रांड लोगो',
|
|
354
|
+
'next_video': 'अगला वीडियो (N)',
|
|
355
|
+
'prev_video': 'पिछला वीडियो (P)',
|
|
356
|
+
'playlist_next': 'अगला',
|
|
357
|
+
'playlist_prev': 'पिछला',
|
|
358
|
+
'settings_menu': 'सेटिंग्स'
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
// Svenska
|
|
362
|
+
'sv': {
|
|
363
|
+
'subtitles': 'Undertexter (C)',
|
|
364
|
+
'subtitlesoff': 'Av',
|
|
365
|
+
'subtitlesdisable': 'Inaktivera undertexter',
|
|
366
|
+
'subtitlesenable': 'Aktivera undertexter',
|
|
367
|
+
'play_pause': 'Spela/Pausa (Blanksteg)',
|
|
368
|
+
'mute_unmute': 'Stäng av ljud (M)',
|
|
369
|
+
'volume': 'Volym',
|
|
370
|
+
'playback_speed': 'Uppspelningshastighet',
|
|
371
|
+
'video_quality': 'Videokvalitet',
|
|
372
|
+
'picture_in_picture': 'Bild i bild (P)',
|
|
373
|
+
'fullscreen': 'Fullskärm (F)',
|
|
374
|
+
'auto': 'Auto',
|
|
375
|
+
'brand_logo': 'Varumärkeslogotyp',
|
|
376
|
+
'next_video': 'Nästa video (N)',
|
|
377
|
+
'prev_video': 'Föregående video (P)',
|
|
378
|
+
'playlist_next': 'Nästa',
|
|
379
|
+
'playlist_prev': 'Föregående',
|
|
380
|
+
'settings_menu': 'Inställningar'
|
|
381
|
+
},
|
|
382
|
+
|
|
383
|
+
// Bahasa Indonesia
|
|
384
|
+
'id': {
|
|
385
|
+
'subtitles': 'Teks (C)',
|
|
386
|
+
'subtitlesoff': 'Mati',
|
|
387
|
+
'subtitlesdisable': 'Nonaktifkan teks',
|
|
388
|
+
'subtitlesenable': 'Aktifkan teks',
|
|
389
|
+
'play_pause': 'Putar/Jeda (Spasi)',
|
|
390
|
+
'mute_unmute': 'Bisu (M)',
|
|
391
|
+
'volume': 'Volume',
|
|
392
|
+
'playback_speed': 'Kecepatan pemutaran',
|
|
393
|
+
'video_quality': 'Kualitas video',
|
|
394
|
+
'picture_in_picture': 'Gambar-dalam-gambar (P)',
|
|
395
|
+
'fullscreen': 'Layar penuh (F)',
|
|
396
|
+
'auto': 'Otomatis',
|
|
397
|
+
'brand_logo': 'Logo merek',
|
|
398
|
+
'next_video': 'Video berikutnya (N)',
|
|
399
|
+
'prev_video': 'Video sebelumnya (P)',
|
|
400
|
+
'playlist_next': 'Berikutnya',
|
|
401
|
+
'playlist_prev': 'Sebelumnya',
|
|
402
|
+
'settings_menu': 'Pengaturan'
|
|
221
403
|
}
|
|
222
404
|
};
|
|
223
405
|
|
|
406
|
+
|
|
224
407
|
// THEN detect language (after defining translations)
|
|
225
408
|
this.currentLanguage = this.detectLanguage();
|
|
226
409
|
}
|
|
@@ -2483,6 +2666,13 @@ addEventListener(eventType, callback) {
|
|
|
2483
2666
|
this.video.addEventListener('playing', () => {
|
|
2484
2667
|
this.hideLoading();
|
|
2485
2668
|
this.closeAllMenus();
|
|
2669
|
+
|
|
2670
|
+
// Update play/pause button when video actually starts playing
|
|
2671
|
+
if (this.playIcon && this.pauseIcon) {
|
|
2672
|
+
this.playIcon.classList.add('hidden');
|
|
2673
|
+
this.pauseIcon.classList.remove('hidden');
|
|
2674
|
+
}
|
|
2675
|
+
|
|
2486
2676
|
// Trigger playing event - video is now actually playing
|
|
2487
2677
|
this.triggerEvent('playing', {
|
|
2488
2678
|
currentTime: this.getCurrentTime(),
|
|
@@ -2691,17 +2881,91 @@ addEventListener(eventType, callback) {
|
|
|
2691
2881
|
this.pipBtn.addEventListener('click', () => this.togglePictureInPicture());
|
|
2692
2882
|
}
|
|
2693
2883
|
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2884
|
+
if (this.volumeSlider) {
|
|
2885
|
+
let isDraggingVolume = false;
|
|
2886
|
+
|
|
2887
|
+
// Input event
|
|
2888
|
+
this.volumeSlider.addEventListener('input', (e) => {
|
|
2889
|
+
this.updateVolume(e.target.value);
|
|
2890
|
+
this.updateVolumeSliderVisual();
|
|
2891
|
+
this.initVolumeTooltip();
|
|
2892
|
+
});
|
|
2893
|
+
|
|
2894
|
+
// MOUSE DRAG - Start
|
|
2895
|
+
this.volumeSlider.addEventListener('mousedown', (e) => {
|
|
2896
|
+
isDraggingVolume = true;
|
|
2897
|
+
if (this.volumeTooltip) {
|
|
2898
|
+
this.volumeTooltip.classList.add('visible');
|
|
2899
|
+
}
|
|
2900
|
+
});
|
|
2697
2901
|
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2902
|
+
// MOUSE DRAG - Move
|
|
2903
|
+
document.addEventListener('mousemove', (e) => {
|
|
2904
|
+
if (isDraggingVolume && this.volumeSlider) {
|
|
2905
|
+
const rect = this.volumeSlider.getBoundingClientRect();
|
|
2906
|
+
const clickX = e.clientX - rect.left;
|
|
2907
|
+
const percentage = Math.max(0, Math.min(1, clickX / rect.width));
|
|
2908
|
+
const value = Math.round(percentage * 100);
|
|
2909
|
+
|
|
2910
|
+
this.volumeSlider.value = value;
|
|
2911
|
+
this.updateVolume(value);
|
|
2701
2912
|
this.updateVolumeSliderVisual();
|
|
2702
|
-
this.
|
|
2703
|
-
|
|
2704
|
-
|
|
2913
|
+
if (this.volumeTooltip) {
|
|
2914
|
+
this.updateVolumeTooltipPosition(value / 100);
|
|
2915
|
+
}
|
|
2916
|
+
}
|
|
2917
|
+
});
|
|
2918
|
+
|
|
2919
|
+
// MOUSE DRAG - End
|
|
2920
|
+
document.addEventListener('mouseup', () => {
|
|
2921
|
+
if (isDraggingVolume) {
|
|
2922
|
+
isDraggingVolume = false;
|
|
2923
|
+
if (this.volumeTooltip) {
|
|
2924
|
+
setTimeout(() => {
|
|
2925
|
+
this.volumeTooltip.classList.remove('visible');
|
|
2926
|
+
}, 300);
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2929
|
+
});
|
|
2930
|
+
|
|
2931
|
+
// TOUCH DRAG - Start
|
|
2932
|
+
this.volumeSlider.addEventListener('touchstart', (e) => {
|
|
2933
|
+
isDraggingVolume = true;
|
|
2934
|
+
if (this.volumeTooltip) {
|
|
2935
|
+
this.volumeTooltip.classList.add('visible');
|
|
2936
|
+
}
|
|
2937
|
+
}, { passive: true });
|
|
2938
|
+
|
|
2939
|
+
// TOUCH DRAG - Move
|
|
2940
|
+
this.volumeSlider.addEventListener('touchmove', (e) => {
|
|
2941
|
+
if (isDraggingVolume) {
|
|
2942
|
+
const touch = e.touches[0];
|
|
2943
|
+
const rect = this.volumeSlider.getBoundingClientRect();
|
|
2944
|
+
const touchX = touch.clientX - rect.left;
|
|
2945
|
+
const percentage = Math.max(0, Math.min(1, touchX / rect.width));
|
|
2946
|
+
const value = Math.round(percentage * 100);
|
|
2947
|
+
|
|
2948
|
+
this.volumeSlider.value = value;
|
|
2949
|
+
this.updateVolume(value);
|
|
2950
|
+
this.updateVolumeSliderVisual();
|
|
2951
|
+
if (this.volumeTooltip) {
|
|
2952
|
+
this.updateVolumeTooltipPosition(value / 100);
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
}, { passive: true });
|
|
2956
|
+
|
|
2957
|
+
// TOUCH DRAG - End
|
|
2958
|
+
this.volumeSlider.addEventListener('touchend', () => {
|
|
2959
|
+
if (isDraggingVolume) {
|
|
2960
|
+
isDraggingVolume = false;
|
|
2961
|
+
if (this.volumeTooltip) {
|
|
2962
|
+
setTimeout(() => {
|
|
2963
|
+
this.volumeTooltip.classList.remove('visible');
|
|
2964
|
+
}, 300);
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
}, { passive: true });
|
|
2968
|
+
}
|
|
2705
2969
|
|
|
2706
2970
|
if (this.progressContainer) {
|
|
2707
2971
|
// Mouse events (desktop)
|
|
@@ -3187,20 +3451,20 @@ createControls() {
|
|
|
3187
3451
|
<div class="progress-buffer"></div>
|
|
3188
3452
|
<div class="progress-filled"></div>
|
|
3189
3453
|
</div>
|
|
3190
|
-
<div class="progress-handle progress-handle-${this.options.seekHandleShape}"></div>
|
|
3454
|
+
<div class="progress-handle progress-handle-${this.options.seekHandleShape}"></div>
|
|
3191
3455
|
${this.options.showSeekTooltip ? '<div class="seek-tooltip">0:00</div>' : ''}
|
|
3192
3456
|
</div>
|
|
3193
3457
|
|
|
3194
3458
|
<div class="controls-main">
|
|
3195
3459
|
<div class="controls-left">
|
|
3196
3460
|
<button class="control-btn play-pause-btn" data-tooltip="play_pause">
|
|
3197
|
-
<span class="icon play-icon"
|
|
3198
|
-
<span class="icon pause-icon hidden"
|
|
3461
|
+
<span class="icon play-icon"><svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M8 5v14l11-7z"/></svg></span>
|
|
3462
|
+
<span class="icon pause-icon hidden"><svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M6 4h4v16H6zm8 0h4v16h-4z"/></svg></span>
|
|
3199
3463
|
</button>
|
|
3200
3464
|
|
|
3201
3465
|
<button class="control-btn mute-btn" data-tooltip="mute_unmute">
|
|
3202
|
-
<span class="icon volume-icon"
|
|
3203
|
-
<span class="icon mute-icon hidden"
|
|
3466
|
+
<span class="icon volume-icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M11.536 14.01A8.473 8.473 0 0 0 14.026 8a8.473 8.473 0 0 0-2.49-6.01l-.708.707A7.476 7.476 0 0 1 13.025 8c0 2.071-.84 3.946-2.197 5.303z"/><path d="M10.121 12.596A6.48 6.48 0 0 0 12.025 8a6.48 6.48 0 0 0-1.904-4.596l-.707.707A5.483 5.483 0 0 1 11.025 8a5.483 5.483 0 0 1-1.61 3.89z"/><path d="M10.025 8a4.486 4.486 0 0 1-1.318 3.182L8 10.475A3.489 3.489 0 0 0 9.025 8c0-.966-.392-1.841-1.025-2.475l.707-.707A4.486 4.486 0 0 1 10.025 8M7 4a.5.5 0 0 0-.812-.39L3.825 5.5H1.5A.5.5 0 0 0 1 6v4a.5.5 0 0 0 .5.5h2.325l2.363 1.89A.5.5 0 0 0 7 12z"/></svg></span>
|
|
3467
|
+
<span class="icon mute-icon hidden"><svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M6.717 3.55A.5.5 0 0 1 7 4v8a.5.5 0 0 1-.812.39L3.825 10.5H1.5A.5.5 0 0 1 1 10V6a.5.5 0 0 1 .5-.5h2.325l2.363-1.89a.5.5 0 0 1 .529-.06m7.137 2.096a.5.5 0 0 1 0 .708L12.207 8l1.647 1.646a.5.5 0 0 1-.708.708L11.5 8.707l-1.646 1.647a.5.5 0 0 1-.708-.708L10.793 8 9.146 6.354a.5.5 0 1 1 .708-.708L11.5 7.293l1.646-1.647a.5.5 0 0 1 .708 0"/></svg></span>
|
|
3204
3468
|
</button>
|
|
3205
3469
|
|
|
3206
3470
|
<div class="volume-container" data-mobile-slider="${this.options.volumeSlider}">
|
|
@@ -3215,18 +3479,17 @@ createControls() {
|
|
|
3215
3479
|
</div>
|
|
3216
3480
|
|
|
3217
3481
|
<div class="controls-right">
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
</button>
|
|
3482
|
+
<button class="control-btn playlist-prev-btn" data-tooltip="prevvideo" style="display: none;">
|
|
3483
|
+
<span class="icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M3.5 12V4l7 4zm8-8v8l-7-4z"/></svg></span>
|
|
3484
|
+
</button>
|
|
3485
|
+
<button class="control-btn playlist-next-btn" data-tooltip="nextvideo" style="display: none;">
|
|
3486
|
+
<span class="icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M12.5 4v8l-7-4zm-8 0v8l7-4z"/></svg></span>
|
|
3487
|
+
</button>
|
|
3225
3488
|
|
|
3226
3489
|
${this.options.showSubtitles ? `
|
|
3227
3490
|
<div class="subtitles-control" style="display: none;">
|
|
3228
3491
|
<button class="control-btn subtitles-btn" data-tooltip="subtitles">
|
|
3229
|
-
|
|
3492
|
+
<span class="icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1z"/><path d="M6.096 4.972c.234 0 .44.05.617.152.177.1.312.235.405.403.093.169.14.36.14.577 0 .216-.047.406-.14.572a1.03 1.03 0 0 1-.405.403 1.2 1.2 0 0 1-.617.152 1.2 1.2 0 0 1-.615-.152 1.03 1.03 0 0 1-.406-.403 1.28 1.28 0 0 1-.14-.572c0-.216.046-.408.14-.577.093-.168.228-.303.406-.403.177-.101.383-.152.615-.152m4.915 0c.234 0 .44.05.617.152.177.1.312.235.405.403.093.169.14.36.14.577 0 .216-.047.406-.14.572a1.03 1.03 0 0 1-.405.403 1.2 1.2 0 0 1-.617.152 1.2 1.2 0 0 1-.615-.152 1.03 1.03 0 0 1-.406-.403 1.28 1.28 0 0 1-.14-.572c0-.216.046-.408.14-.577.093-.168.228-.303.406-.403.177-.101.383-.152.615-.152M6.096 9.972c.234 0 .44.05.617.152.177.1.312.235.405.403.093.169.14.36.14.577 0 .216-.047.406-.14.572a1.03 1.03 0 0 1-.405.403 1.2 1.2 0 0 1-.617.152 1.2 1.2 0 0 1-.615-.152 1.03 1.03 0 0 1-.406-.403 1.28 1.28 0 0 1-.14-.572c0-.216.046-.408.14-.577.093-.168.228-.303.406-.403.177-.101.383-.152.615-.152m4.915 0c.234 0 .44.05.617.152.177.1.312.235.405.403.093.169.14.36.14.577 0 .216-.047.406-.14.572a1.03 1.03 0 0 1-.405.403 1.2 1.2 0 0 1-.617.152 1.2 1.2 0 0 1-.615-.152 1.03 1.03 0 0 1-.406-.403 1.28 1.28 0 0 1-.14-.572c0-.216.046-.408.14-.577.093-.168.228-.303.406-.403.177-.101.383-.152.615-.152"/></svg></span>
|
|
3230
3493
|
</button>
|
|
3231
3494
|
<div class="subtitles-menu">
|
|
3232
3495
|
<div class="subtitles-option active" data-track="off">Off</div>
|
|
@@ -3267,22 +3530,22 @@ createControls() {
|
|
|
3267
3530
|
|
|
3268
3531
|
${this.options.showPictureInPicture && this.isPiPSupported ? `
|
|
3269
3532
|
<button class="control-btn pip-btn" data-tooltip="picture_in_picture">
|
|
3270
|
-
<span class="icon pip-icon"
|
|
3271
|
-
<span class="icon pip-exit-icon hidden"
|
|
3533
|
+
<span class="icon pip-icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M0 3.5A1.5 1.5 0 0 1 1.5 2h13A1.5 1.5 0 0 1 16 3.5v9a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 0 12.5zM1.5 3a.5.5 0 0 0-.5.5v9a.5.5 0 0 0 .5.5h13a.5.5 0 0 0 .5-.5v-9a.5.5 0 0 0-.5-.5z"/><path d="M8 8.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5h-5a.5.5 0 0 1-.5-.5z"/></svg></span>
|
|
3534
|
+
<span class="icon pip-exit-icon hidden"><svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M0 3.5A1.5 1.5 0 0 1 1.5 2h13A1.5 1.5 0 0 1 16 3.5v9a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 0 12.5zM1.5 3a.5.5 0 0 0-.5.5v9a.5.5 0 0 0 .5.5h13a.5.5 0 0 0 .5-.5v-9a.5.5 0 0 0-.5-.5z"/></svg></span>
|
|
3272
3535
|
</button>
|
|
3273
3536
|
` : ''}
|
|
3274
3537
|
|
|
3275
3538
|
<div class="settings-control">
|
|
3276
3539
|
<button class="control-btn settings-btn" data-tooltip="settings_menu">
|
|
3277
|
-
<span class=""
|
|
3540
|
+
<span class="icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492M5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0"/><path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52z"/></svg></span>
|
|
3278
3541
|
</button>
|
|
3279
3542
|
<div class="settings-menu"></div>
|
|
3280
3543
|
</div>
|
|
3281
3544
|
|
|
3282
3545
|
${this.options.showFullscreen ? `
|
|
3283
3546
|
<button class="control-btn fullscreen-btn" data-tooltip="fullscreen">
|
|
3284
|
-
<span class="icon fullscreen-icon"
|
|
3285
|
-
<span class="icon exit-fullscreen-icon hidden"
|
|
3547
|
+
<span class="icon fullscreen-icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M1.5 1a.5.5 0 0 0-.5.5v4a.5.5 0 0 1-1 0v-4A1.5 1.5 0 0 1 1.5 0h4a.5.5 0 0 1 0 1zM10 .5a.5.5 0 0 1 .5-.5h4A1.5 1.5 0 0 1 16 1.5v4a.5.5 0 0 1-1 0v-4a.5.5 0 0 0-.5-.5h-4a.5.5 0 0 1-.5-.5M.5 10a.5.5 0 0 1 .5.5v4a.5.5 0 0 0 .5.5h4a.5.5 0 0 1 0 1h-4A1.5 1.5 0 0 1 0 14.5v-4a.5.5 0 0 1 .5-.5m15 0a.5.5 0 0 1 .5.5v4a1.5 1.5 0 0 1-1.5 1.5h-4a.5.5 0 0 1 0-1h4a.5.5 0 0 0 .5-.5v-4a.5.5 0 0 1 .5-.5"/></svg></span>
|
|
3548
|
+
<span class="icon exit-fullscreen-icon hidden"><svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M5.5 0a.5.5 0 0 1 .5.5v4A1.5 1.5 0 0 1 4.5 6h-4a.5.5 0 0 1 0-1h4a.5.5 0 0 0 .5-.5v-4a.5.5 0 0 1 .5-.5m5 0a.5.5 0 0 1 .5.5v4a.5.5 0 0 0 .5.5h4a.5.5 0 0 1 0 1h-4A1.5 1.5 0 0 1 10 4.5v-4a.5.5 0 0 1 .5-.5M0 10.5a.5.5 0 0 1 .5-.5h4A1.5 1.5 0 0 1 6 11.5v4a.5.5 0 0 1-1 0v-4a.5.5 0 0 0-.5-.5h-4a.5.5 0 0 1-.5-.5m10 1a1.5 1.5 0 0 1 1.5-1.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 0-.5.5v4a.5.5 0 0 1-1 0z"/></svg></span>
|
|
3286
3549
|
</button>
|
|
3287
3550
|
` : ''}
|
|
3288
3551
|
</div>
|
|
@@ -5639,46 +5902,99 @@ parseTimeToSeconds(timeStr) {
|
|
|
5639
5902
|
* Create visual chapter markers on the progress bar
|
|
5640
5903
|
*/
|
|
5641
5904
|
createChapterMarkers() {
|
|
5642
|
-
if (!this.progressContainer || !this.video || !this.chapters)
|
|
5905
|
+
if (!this.progressContainer || !this.video || !this.chapters) return;
|
|
5906
|
+
|
|
5907
|
+
const duration = this.video.duration;
|
|
5908
|
+
if (!duration || isNaN(duration)) {
|
|
5909
|
+
// Wait for metadata
|
|
5910
|
+
const loadedMetadataHandler = () => {
|
|
5911
|
+
this.createChapterMarkers();
|
|
5912
|
+
this.video.removeEventListener('loadedmetadata', loadedMetadataHandler);
|
|
5913
|
+
};
|
|
5914
|
+
this.video.addEventListener('loadedmetadata', loadedMetadataHandler);
|
|
5643
5915
|
return;
|
|
5644
5916
|
}
|
|
5645
5917
|
|
|
5646
|
-
//
|
|
5918
|
+
// Remove existing markers
|
|
5919
|
+
const existingMarkers = this.progressContainer.querySelector('.chapter-markers-container');
|
|
5920
|
+
if (existingMarkers) {
|
|
5921
|
+
existingMarkers.remove();
|
|
5922
|
+
}
|
|
5923
|
+
|
|
5924
|
+
// Create container for chapter segments
|
|
5647
5925
|
const markersContainer = document.createElement('div');
|
|
5648
5926
|
markersContainer.className = 'chapter-markers-container';
|
|
5649
5927
|
|
|
5928
|
+
// Create segments for each chapter
|
|
5650
5929
|
this.chapters.forEach((chapter, index) => {
|
|
5651
|
-
const
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5930
|
+
const nextChapter = this.chapters[index + 1];
|
|
5931
|
+
const startPercent = (chapter.time / duration) * 100;
|
|
5932
|
+
const endPercent = nextChapter ? (nextChapter.time / duration) * 100 : 100;
|
|
5933
|
+
|
|
5934
|
+
// Calculate segment width minus the gap
|
|
5935
|
+
const gapSize = nextChapter ? 6 : 0; // 6px gap between segments
|
|
5936
|
+
const widthPercent = endPercent - startPercent;
|
|
5937
|
+
|
|
5938
|
+
// Create segment container
|
|
5939
|
+
const segment = document.createElement('div');
|
|
5940
|
+
segment.className = 'chapter-segment';
|
|
5941
|
+
segment.style.cssText = `
|
|
5942
|
+
position: absolute;
|
|
5943
|
+
left: ${startPercent}%;
|
|
5944
|
+
top: 0;
|
|
5945
|
+
width: calc(${widthPercent}% - ${gapSize}px);
|
|
5946
|
+
height: 100%;
|
|
5947
|
+
background: rgba(255, 255, 255, 0.3);
|
|
5948
|
+
cursor: pointer;
|
|
5949
|
+
z-index: 3;
|
|
5950
|
+
transition: background 0.2s;
|
|
5951
|
+
pointer-events: none;
|
|
5952
|
+
`;
|
|
5953
|
+
|
|
5954
|
+
segment.setAttribute('data-chapter-index', index);
|
|
5955
|
+
segment.setAttribute('data-chapter-time', chapter.time);
|
|
5956
|
+
segment.setAttribute('data-chapter-title', chapter.title);
|
|
5957
|
+
|
|
5958
|
+
markersContainer.appendChild(segment);
|
|
5959
|
+
|
|
5960
|
+
// Add marker at the START of next segment (transparent divider)
|
|
5961
|
+
if (nextChapter) {
|
|
5962
|
+
const marker = document.createElement('div');
|
|
5963
|
+
marker.className = 'chapter-marker';
|
|
5964
|
+
marker.style.cssText = `
|
|
5965
|
+
position: absolute !important;
|
|
5966
|
+
left: ${endPercent}% !important;
|
|
5967
|
+
top: 0 !important;
|
|
5968
|
+
width: 6px !important;
|
|
5969
|
+
height: 100% !important;
|
|
5970
|
+
background: transparent !important;
|
|
5971
|
+
border: none !important;
|
|
5972
|
+
box-shadow: none !important;
|
|
5973
|
+
margin-left: -3px !important;
|
|
5974
|
+
cursor: pointer !important;
|
|
5975
|
+
z-index: 10 !important;
|
|
5976
|
+
`;
|
|
5977
|
+
|
|
5978
|
+
marker.setAttribute('data-chapter-time', nextChapter.time);
|
|
5979
|
+
marker.setAttribute('data-chapter-title', nextChapter.title);
|
|
5980
|
+
|
|
5981
|
+
// Click on marker to jump to chapter start
|
|
5982
|
+
marker.addEventListener('click', (e) => {
|
|
5983
|
+
e.stopPropagation();
|
|
5984
|
+
this.jumpToChapter(index + 1);
|
|
5985
|
+
});
|
|
5986
|
+
|
|
5987
|
+
markersContainer.appendChild(marker);
|
|
5660
5988
|
}
|
|
5661
|
-
|
|
5662
|
-
markersContainer.appendChild(marker);
|
|
5663
5989
|
});
|
|
5664
5990
|
|
|
5665
5991
|
// Insert markers container into progress container
|
|
5666
5992
|
this.progressContainer.appendChild(markersContainer);
|
|
5667
5993
|
this.chapterMarkersContainer = markersContainer;
|
|
5668
5994
|
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
this.updateChapterMarkerPositions();
|
|
5672
|
-
} else {
|
|
5673
|
-
// Wait for metadata to be loaded
|
|
5674
|
-
const loadedMetadataHandler = () => {
|
|
5675
|
-
this.updateChapterMarkerPositions();
|
|
5676
|
-
this.video.removeEventListener('loadedmetadata', loadedMetadataHandler);
|
|
5677
|
-
};
|
|
5678
|
-
this.video.addEventListener('loadedmetadata', loadedMetadataHandler);
|
|
5995
|
+
if (this.options.debug) {
|
|
5996
|
+
console.log(`Chapter markers created: ${this.chapters.length} segments`);
|
|
5679
5997
|
}
|
|
5680
|
-
|
|
5681
|
-
if (this.options.debug) console.log('📚 Chapter markers created on timeline');
|
|
5682
5998
|
}
|
|
5683
5999
|
|
|
5684
6000
|
/**
|
|
@@ -5703,70 +6019,278 @@ updateChapterMarkerPositions() {
|
|
|
5703
6019
|
}
|
|
5704
6020
|
|
|
5705
6021
|
/**
|
|
5706
|
-
* Create chapter tooltip
|
|
6022
|
+
* Create chapter tooltip with title and image
|
|
5707
6023
|
*/
|
|
5708
6024
|
createChapterTooltip() {
|
|
5709
|
-
if (!this.progressContainer)
|
|
5710
|
-
|
|
6025
|
+
if (!this.progressContainer) return;
|
|
6026
|
+
|
|
6027
|
+
// Remove existing chapter tooltip
|
|
6028
|
+
let chapterTooltip = this.progressContainer.querySelector('.chapter-tooltip');
|
|
6029
|
+
if (chapterTooltip) {
|
|
6030
|
+
chapterTooltip.remove();
|
|
5711
6031
|
}
|
|
5712
6032
|
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
6033
|
+
// Create chapter tooltip container (positioned ABOVE the time tooltip)
|
|
6034
|
+
chapterTooltip = document.createElement('div');
|
|
6035
|
+
chapterTooltip.className = 'chapter-tooltip';
|
|
6036
|
+
chapterTooltip.style.cssText = `
|
|
6037
|
+
position: absolute;
|
|
6038
|
+
bottom: calc(100% + 35px);
|
|
6039
|
+
left: 0;
|
|
6040
|
+
background: rgba(28, 28, 28, 0.95);
|
|
6041
|
+
color: #fff;
|
|
6042
|
+
border-radius: 4px;
|
|
6043
|
+
pointer-events: none;
|
|
6044
|
+
visibility: hidden;
|
|
6045
|
+
opacity: 0;
|
|
6046
|
+
z-index: 100001;
|
|
6047
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
6048
|
+
max-width: 300px;
|
|
6049
|
+
overflow: hidden;
|
|
6050
|
+
transform: translateX(-50%);
|
|
6051
|
+
transition: opacity 0.15s, visibility 0.15s;
|
|
6052
|
+
display: flex;
|
|
6053
|
+
flex-direction: column;
|
|
6054
|
+
`;
|
|
5717
6055
|
|
|
5718
|
-
//
|
|
5719
|
-
|
|
5720
|
-
<div class="chapter-tooltip-
|
|
5721
|
-
|
|
5722
|
-
|
|
6056
|
+
// Create inner content structure
|
|
6057
|
+
chapterTooltip.innerHTML = `
|
|
6058
|
+
<div class="chapter-tooltip-content" style="display: flex; flex-direction: column; gap: 8px; padding: 8px;">
|
|
6059
|
+
<div class="chapter-tooltip-image" style="
|
|
6060
|
+
width: 100%;
|
|
6061
|
+
height: 120px;
|
|
6062
|
+
background-size: cover;
|
|
6063
|
+
background-position: center;
|
|
6064
|
+
border-radius: 3px;
|
|
6065
|
+
display: none;
|
|
6066
|
+
"></div>
|
|
6067
|
+
<div class="chapter-tooltip-info" style="display: flex; flex-direction: column; gap: 4px;">
|
|
6068
|
+
<div class="chapter-tooltip-title" style="
|
|
6069
|
+
font-size: 13px;
|
|
6070
|
+
font-weight: 600;
|
|
6071
|
+
color: #fff;
|
|
6072
|
+
max-width: 280px;
|
|
6073
|
+
overflow: hidden;
|
|
6074
|
+
text-overflow: ellipsis;
|
|
6075
|
+
white-space: nowrap;
|
|
6076
|
+
"></div>
|
|
6077
|
+
<div class="chapter-tooltip-time" style="
|
|
6078
|
+
font-size: 12px;
|
|
6079
|
+
font-weight: 400;
|
|
6080
|
+
color: rgba(255, 255, 255, 0.8);
|
|
6081
|
+
"></div>
|
|
6082
|
+
</div>
|
|
6083
|
+
</div>
|
|
5723
6084
|
`;
|
|
5724
6085
|
|
|
5725
|
-
this.progressContainer.appendChild(
|
|
5726
|
-
this.chapterTooltip =
|
|
6086
|
+
this.progressContainer.appendChild(chapterTooltip);
|
|
6087
|
+
this.chapterTooltip = chapterTooltip;
|
|
5727
6088
|
|
|
5728
|
-
if (this.options.debug)
|
|
6089
|
+
if (this.options.debug) {
|
|
6090
|
+
console.log('Chapter tooltip created');
|
|
6091
|
+
}
|
|
5729
6092
|
}
|
|
5730
6093
|
|
|
5731
6094
|
/**
|
|
5732
|
-
* Bind chapter-related events
|
|
6095
|
+
* Bind chapter-related events - tooltip on progressbar mousemove
|
|
5733
6096
|
*/
|
|
5734
6097
|
bindChapterEvents() {
|
|
5735
|
-
if (!this.
|
|
5736
|
-
|
|
6098
|
+
if (!this.progressContainer) return;
|
|
6099
|
+
|
|
6100
|
+
// Remove existing chapter tooltip if present
|
|
6101
|
+
let chapterTooltip = this.progressContainer.querySelector('.chapter-tooltip-hover');
|
|
6102
|
+
if (chapterTooltip) {
|
|
6103
|
+
chapterTooltip.remove();
|
|
5737
6104
|
}
|
|
5738
6105
|
|
|
5739
|
-
//
|
|
5740
|
-
|
|
6106
|
+
// Create chapter tooltip
|
|
6107
|
+
chapterTooltip = document.createElement('div');
|
|
6108
|
+
chapterTooltip.className = 'chapter-tooltip-hover';
|
|
6109
|
+
chapterTooltip.style.cssText = `
|
|
6110
|
+
position: absolute;
|
|
6111
|
+
bottom: calc(100% + 35px);
|
|
6112
|
+
left: 0;
|
|
6113
|
+
background: rgba(28, 28, 28, 0.95);
|
|
6114
|
+
color: #fff;
|
|
6115
|
+
border-radius: 4px;
|
|
6116
|
+
padding: 8px;
|
|
6117
|
+
pointer-events: none;
|
|
6118
|
+
visibility: hidden;
|
|
6119
|
+
opacity: 0;
|
|
6120
|
+
z-index: 100001;
|
|
6121
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
6122
|
+
max-width: 300px;
|
|
6123
|
+
transform: translateX(-50%);
|
|
6124
|
+
transition: opacity 0.15s, visibility 0.15s;
|
|
6125
|
+
`;
|
|
5741
6126
|
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
this.showChapterTooltip(index, e);
|
|
5745
|
-
});
|
|
6127
|
+
this.progressContainer.appendChild(chapterTooltip);
|
|
6128
|
+
this.chapterTooltip = chapterTooltip;
|
|
5746
6129
|
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
6130
|
+
// Get player container for edge detection
|
|
6131
|
+
const getPlayerBounds = () => {
|
|
6132
|
+
return this.container ? this.container.getBoundingClientRect() : null;
|
|
6133
|
+
};
|
|
5750
6134
|
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
6135
|
+
// Mousemove handler to show tooltip with title and image
|
|
6136
|
+
this.progressContainer.addEventListener('mousemove', (e) => {
|
|
6137
|
+
if (!this.video || !this.video.duration || !this.chapters || this.chapters.length === 0) {
|
|
6138
|
+
return;
|
|
6139
|
+
}
|
|
5754
6140
|
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
6141
|
+
const rect = this.progressContainer.getBoundingClientRect();
|
|
6142
|
+
const playerRect = getPlayerBounds();
|
|
6143
|
+
const mouseX = e.clientX - rect.left;
|
|
6144
|
+
const percentage = Math.max(0, Math.min(1, mouseX / rect.width));
|
|
6145
|
+
const time = percentage * this.video.duration;
|
|
6146
|
+
|
|
6147
|
+
// Find chapter at current time
|
|
6148
|
+
let currentChapter = null;
|
|
6149
|
+
for (let i = this.chapters.length - 1; i >= 0; i--) {
|
|
6150
|
+
if (time >= this.chapters[i].time) {
|
|
6151
|
+
currentChapter = this.chapters[i];
|
|
6152
|
+
break;
|
|
6153
|
+
}
|
|
6154
|
+
}
|
|
6155
|
+
|
|
6156
|
+
if (currentChapter) {
|
|
6157
|
+
// Build tooltip HTML
|
|
6158
|
+
let tooltipHTML = '<div style="display: flex; flex-direction: column; gap: 6px;">';
|
|
6159
|
+
|
|
6160
|
+
// Add image if available
|
|
6161
|
+
if (currentChapter.image) {
|
|
6162
|
+
tooltipHTML += `
|
|
6163
|
+
<div style="
|
|
6164
|
+
width: 100%;
|
|
6165
|
+
height: 120px;
|
|
6166
|
+
background-image: url('${currentChapter.image}');
|
|
6167
|
+
background-size: cover;
|
|
6168
|
+
background-position: center;
|
|
6169
|
+
border-radius: 3px;
|
|
6170
|
+
"></div>
|
|
6171
|
+
`;
|
|
6172
|
+
}
|
|
6173
|
+
|
|
6174
|
+
// Add title
|
|
6175
|
+
tooltipHTML += `
|
|
6176
|
+
<div style="
|
|
6177
|
+
font-size: 13px;
|
|
6178
|
+
font-weight: 600;
|
|
6179
|
+
max-width: 280px;
|
|
6180
|
+
overflow: hidden;
|
|
6181
|
+
text-overflow: ellipsis;
|
|
6182
|
+
white-space: nowrap;
|
|
6183
|
+
">
|
|
6184
|
+
${currentChapter.title}
|
|
6185
|
+
</div>
|
|
6186
|
+
`;
|
|
6187
|
+
|
|
6188
|
+
// Add time
|
|
6189
|
+
tooltipHTML += `
|
|
6190
|
+
<div style="
|
|
6191
|
+
font-size: 12px;
|
|
6192
|
+
font-weight: 400;
|
|
6193
|
+
color: rgba(255, 255, 255, 0.8);
|
|
6194
|
+
">
|
|
6195
|
+
${this.formatTime(currentChapter.time)}
|
|
6196
|
+
</div>
|
|
6197
|
+
`;
|
|
6198
|
+
|
|
6199
|
+
tooltipHTML += '</div>';
|
|
6200
|
+
|
|
6201
|
+
chapterTooltip.innerHTML = tooltipHTML;
|
|
6202
|
+
chapterTooltip.style.visibility = 'visible';
|
|
6203
|
+
chapterTooltip.style.opacity = '1';
|
|
6204
|
+
|
|
6205
|
+
// Position tooltip with edge detection
|
|
6206
|
+
setTimeout(() => {
|
|
6207
|
+
const tooltipWidth = chapterTooltip.offsetWidth;
|
|
6208
|
+
const tooltipHalfWidth = tooltipWidth / 2;
|
|
6209
|
+
const absoluteX = e.clientX;
|
|
6210
|
+
|
|
6211
|
+
if (playerRect) {
|
|
6212
|
+
// Left edge
|
|
6213
|
+
if (absoluteX - tooltipHalfWidth < playerRect.left) {
|
|
6214
|
+
chapterTooltip.style.left = `${playerRect.left - rect.left + tooltipHalfWidth}px`;
|
|
6215
|
+
}
|
|
6216
|
+
// Right edge
|
|
6217
|
+
else if (absoluteX + tooltipHalfWidth > playerRect.right) {
|
|
6218
|
+
chapterTooltip.style.left = `${playerRect.right - rect.left - tooltipHalfWidth}px`;
|
|
6219
|
+
}
|
|
6220
|
+
// Normal center
|
|
6221
|
+
else {
|
|
6222
|
+
chapterTooltip.style.left = `${mouseX}px`;
|
|
6223
|
+
}
|
|
6224
|
+
} else {
|
|
6225
|
+
chapterTooltip.style.left = `${mouseX}px`;
|
|
6226
|
+
}
|
|
6227
|
+
}, 0);
|
|
6228
|
+
} else {
|
|
6229
|
+
chapterTooltip.style.visibility = 'hidden';
|
|
6230
|
+
chapterTooltip.style.opacity = '0';
|
|
6231
|
+
}
|
|
6232
|
+
});
|
|
6233
|
+
|
|
6234
|
+
// Mouseleave handler
|
|
6235
|
+
this.progressContainer.addEventListener('mouseleave', () => {
|
|
6236
|
+
chapterTooltip.style.visibility = 'hidden';
|
|
6237
|
+
chapterTooltip.style.opacity = '0';
|
|
5760
6238
|
});
|
|
5761
6239
|
|
|
5762
6240
|
// Update active chapter during playback
|
|
5763
6241
|
if (this.video) {
|
|
5764
|
-
this.video.addEventListener('timeupdate', () =>
|
|
5765
|
-
this.updateActiveChapter();
|
|
5766
|
-
});
|
|
6242
|
+
this.video.addEventListener('timeupdate', () => this.updateActiveChapter());
|
|
5767
6243
|
}
|
|
5768
6244
|
|
|
5769
|
-
if (this.options.debug)
|
|
6245
|
+
if (this.options.debug) {
|
|
6246
|
+
console.log('Chapter events bound with tooltip');
|
|
6247
|
+
}
|
|
6248
|
+
}
|
|
6249
|
+
|
|
6250
|
+
/**
|
|
6251
|
+
* Update chapter name in title overlay dynamically
|
|
6252
|
+
*/
|
|
6253
|
+
updateChapterInTitleOverlay() {
|
|
6254
|
+
if (!this.video || !this.chapters || this.chapters.length === 0) return;
|
|
6255
|
+
|
|
6256
|
+
const titleOverlay = this.container ? this.container.querySelector('.title-overlay') : null;
|
|
6257
|
+
if (!titleOverlay) return;
|
|
6258
|
+
|
|
6259
|
+
// Find or create chapter name element
|
|
6260
|
+
let chapterElement = titleOverlay.querySelector('.chapter-name');
|
|
6261
|
+
if (!chapterElement) {
|
|
6262
|
+
chapterElement = document.createElement('div');
|
|
6263
|
+
chapterElement.className = 'chapter-name';
|
|
6264
|
+
chapterElement.style.cssText = `
|
|
6265
|
+
font-size: 13px;
|
|
6266
|
+
font-weight: 500;
|
|
6267
|
+
color: rgba(255, 255, 255, 0.9);
|
|
6268
|
+
margin-top: 6px;
|
|
6269
|
+
max-width: 400px;
|
|
6270
|
+
overflow: hidden;
|
|
6271
|
+
text-overflow: ellipsis;
|
|
6272
|
+
white-space: nowrap;
|
|
6273
|
+
`;
|
|
6274
|
+
titleOverlay.appendChild(chapterElement);
|
|
6275
|
+
}
|
|
6276
|
+
|
|
6277
|
+
// Find current chapter
|
|
6278
|
+
const currentTime = this.video.currentTime;
|
|
6279
|
+
let currentChapter = null;
|
|
6280
|
+
for (let i = this.chapters.length - 1; i >= 0; i--) {
|
|
6281
|
+
if (currentTime >= this.chapters[i].time) {
|
|
6282
|
+
currentChapter = this.chapters[i];
|
|
6283
|
+
break;
|
|
6284
|
+
}
|
|
6285
|
+
}
|
|
6286
|
+
|
|
6287
|
+
// Update or hide chapter name
|
|
6288
|
+
if (currentChapter) {
|
|
6289
|
+
chapterElement.textContent = currentChapter.title;
|
|
6290
|
+
chapterElement.style.display = 'block';
|
|
6291
|
+
} else {
|
|
6292
|
+
chapterElement.style.display = 'none';
|
|
6293
|
+
}
|
|
5770
6294
|
}
|
|
5771
6295
|
|
|
5772
6296
|
/**
|
|
@@ -5870,9 +6394,7 @@ jumpToChapter(chapterIndex) {
|
|
|
5870
6394
|
* Update active chapter marker during playback
|
|
5871
6395
|
*/
|
|
5872
6396
|
updateActiveChapter() {
|
|
5873
|
-
if (!this.video || !this.chapterMarkersContainer || !this.chapters)
|
|
5874
|
-
return;
|
|
5875
|
-
}
|
|
6397
|
+
if (!this.video || !this.chapterMarkersContainer || !this.chapters) return;
|
|
5876
6398
|
|
|
5877
6399
|
const currentTime = this.video.currentTime;
|
|
5878
6400
|
const markers = this.chapterMarkersContainer.querySelectorAll('.chapter-marker');
|
|
@@ -5894,6 +6416,9 @@ updateActiveChapter() {
|
|
|
5894
6416
|
marker.classList.remove('active');
|
|
5895
6417
|
}
|
|
5896
6418
|
});
|
|
6419
|
+
|
|
6420
|
+
// Update chapter name in title overlay
|
|
6421
|
+
this.updateChapterInTitleOverlay();
|
|
5897
6422
|
}
|
|
5898
6423
|
|
|
5899
6424
|
/**
|