myetv-player 1.2.0 → 1.4.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 +242 -168
- package/css/myetv-player.min.css +1 -1
- package/dist/myetv-player.js +638 -203
- package/dist/myetv-player.min.js +548 -170
- 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 +766 -6
- 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 -204
- 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 -1368
- 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 -1242
- package/src/core.js +0 -1922
- package/src/events.js +0 -537
- 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/package.json
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myetv-player",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "MYETV Video Player - Modular
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "MYETV Video Player - Modular HTML5 video player with plugin support for YouTube, Vimeo, Twitch, Facebook, and streaming protocols (HLS/DASH)",
|
|
5
5
|
"main": "dist/myetv-player.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist/",
|
|
8
|
+
"css/",
|
|
9
|
+
"plugins/",
|
|
10
|
+
"LICENSE",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"video",
|
|
15
|
+
"player",
|
|
16
|
+
"html5",
|
|
17
|
+
"video-player",
|
|
18
|
+
"media-player",
|
|
19
|
+
"streaming",
|
|
20
|
+
"hls",
|
|
21
|
+
"dash",
|
|
22
|
+
"plugin",
|
|
23
|
+
"youtube",
|
|
24
|
+
"vimeo",
|
|
25
|
+
"twitch",
|
|
26
|
+
"facebook",
|
|
27
|
+
"cloudflare-stream",
|
|
28
|
+
"subtitles",
|
|
29
|
+
"webvtt",
|
|
30
|
+
"picture-in-picture",
|
|
31
|
+
"responsive",
|
|
32
|
+
"open-source"
|
|
33
|
+
],
|
|
6
34
|
"scripts": {
|
|
7
35
|
"build": "node build.js",
|
|
8
36
|
"build:js": "node build.js",
|
|
@@ -23,20 +51,11 @@
|
|
|
23
51
|
"repository": {
|
|
24
52
|
"type": "git",
|
|
25
53
|
"url": "https://github.com/OskarCosimo/myetv-video-player-opensource"
|
|
26
|
-
}
|
|
54
|
+
},
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/OskarCosimo/myetv-video-player-opensource/issues"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://oskarcosimo.com/myetv-video-player/myetv-player-demo.html"
|
|
27
59
|
}
|
|
28
60
|
|
|
29
61
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
this.isPausedState = true; // Track state manually
|
|
37
37
|
this.extractedBrandLogo = null; // Store reference to extracted brand logo
|
|
38
38
|
this.brandLogoHideTimer = null; // Timer for auto-hide
|
|
39
|
+
this.containerHeightObserver = null; // MutationObserver for container height
|
|
39
40
|
|
|
40
41
|
this.api = player.getPluginAPI ? player.getPluginAPI() : {
|
|
41
42
|
player: player,
|
|
@@ -196,16 +197,104 @@
|
|
|
196
197
|
this.api.video.style.display = 'none';
|
|
197
198
|
}
|
|
198
199
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
position:
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
`;
|
|
200
|
+
// Detect if we're inside an iframe
|
|
201
|
+
const isInIframe = window.self !== window.top;
|
|
202
|
+
|
|
203
|
+
// Set position: relative to container
|
|
204
|
+
this.api.container.style.position = 'relative';
|
|
205
|
+
|
|
206
|
+
if (isInIframe) {
|
|
207
|
+
// Inside iframe: use original system (no MutationObserver needed)
|
|
208
|
+
this.twitchContainer = document.createElement('div');
|
|
209
|
+
this.twitchContainer.id = `twitch-player-${Date.now()}`;
|
|
210
|
+
|
|
211
|
+
this.twitchContainer.style.cssText = `
|
|
212
|
+
position: absolute !important;
|
|
213
|
+
top: 0 !important;
|
|
214
|
+
left: 0 !important;
|
|
215
|
+
width: 100% !important;
|
|
216
|
+
height: 100% !important;
|
|
217
|
+
z-index: 1 !important;
|
|
218
|
+
`;
|
|
219
|
+
|
|
220
|
+
if (this.api.player.options.debug) {
|
|
221
|
+
console.log('🎮 Twitch Plugin: Inside iframe - using absolute positioning');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
} else {
|
|
225
|
+
// Outside iframe: lock height with MutationObserver
|
|
226
|
+
const containerHeight = this.api.container.offsetHeight;
|
|
227
|
+
if (containerHeight > 0) {
|
|
228
|
+
this.api.container.style.height = containerHeight + 'px';
|
|
229
|
+
if (this.api.player.options.debug) {
|
|
230
|
+
console.log('🎮 Twitch Plugin: Container height locked to', containerHeight + 'px');
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
// Fallback if offsetHeight is 0
|
|
234
|
+
this.api.container.style.height = '500px';
|
|
235
|
+
if (this.api.player.options.debug) {
|
|
236
|
+
console.log('🎮 Twitch Plugin: Container height fallback to 500px');
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// MutationObserver to protect container height from being reset
|
|
241
|
+
const lockedHeight = this.api.container.style.height; // Save locked height
|
|
242
|
+
|
|
243
|
+
this.containerHeightObserver = new MutationObserver((mutations) => {
|
|
244
|
+
mutations.forEach((mutation) => {
|
|
245
|
+
if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
|
|
246
|
+
const currentHeight = this.api.container.style.height;
|
|
247
|
+
|
|
248
|
+
// Check if we're in fullscreen
|
|
249
|
+
const isFullscreen = document.fullscreenElement ||
|
|
250
|
+
document.webkitFullscreenElement ||
|
|
251
|
+
document.mozFullScreenElement ||
|
|
252
|
+
document.msFullscreenElement;
|
|
253
|
+
|
|
254
|
+
// If in fullscreen, allow height: 100%
|
|
255
|
+
if (isFullscreen) {
|
|
256
|
+
if (currentHeight !== '100%') {
|
|
257
|
+
this.api.container.style.height = '100%';
|
|
258
|
+
if (this.api.player.options.debug) {
|
|
259
|
+
console.log('🎮 Twitch Plugin: Fullscreen mode - height set to 100%');
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
} else {
|
|
263
|
+
// If NOT in fullscreen and height was changed to 100% or removed, restore locked height
|
|
264
|
+
if (currentHeight !== lockedHeight && (currentHeight === '100%' || currentHeight === '' || currentHeight === 'auto')) {
|
|
265
|
+
this.api.container.style.height = lockedHeight;
|
|
266
|
+
|
|
267
|
+
if (this.api.player.options.debug) {
|
|
268
|
+
console.log('🎮 Twitch Plugin: Container height restored to', lockedHeight);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// Observe changes to container's style attribute
|
|
277
|
+
this.containerHeightObserver.observe(this.api.container, {
|
|
278
|
+
attributes: true,
|
|
279
|
+
attributeFilter: ['style']
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
if (this.api.player.options.debug) {
|
|
283
|
+
console.log('🎮 Twitch Plugin: MutationObserver active on container');
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
this.twitchContainer = document.createElement('div');
|
|
287
|
+
this.twitchContainer.id = `twitch-player-${Date.now()}`;
|
|
288
|
+
|
|
289
|
+
this.twitchContainer.style.cssText = `
|
|
290
|
+
position: absolute !important;
|
|
291
|
+
top: 0 !important;
|
|
292
|
+
left: 0 !important;
|
|
293
|
+
width: 100% !important;
|
|
294
|
+
height: 100% !important;
|
|
295
|
+
z-index: 1 !important;
|
|
296
|
+
`;
|
|
297
|
+
}
|
|
209
298
|
|
|
210
299
|
this.api.container.appendChild(this.twitchContainer);
|
|
211
300
|
|
|
@@ -231,9 +320,26 @@ z-index: 1;
|
|
|
231
320
|
}
|
|
232
321
|
|
|
233
322
|
this.twitchPlayer = new Twitch.Player(this.twitchContainer.id, playerOptions);
|
|
323
|
+
|
|
324
|
+
setTimeout(() => {
|
|
325
|
+
const twitchIframe = this.twitchContainer.querySelector('iframe');
|
|
326
|
+
if (twitchIframe) {
|
|
327
|
+
twitchIframe.style.cssText = `
|
|
328
|
+
position: absolute !important;
|
|
329
|
+
top: 0 !important;
|
|
330
|
+
left: 0 !important;
|
|
331
|
+
width: 100% !important;
|
|
332
|
+
height: 100% !important;
|
|
333
|
+
`;
|
|
334
|
+
if (this.api.player.options.debug) {
|
|
335
|
+
console.log('🎮 Twitch Plugin: Iframe dimensions forced to 100%');
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}, 200);
|
|
339
|
+
|
|
234
340
|
this.setupEventListeners();
|
|
235
341
|
|
|
236
|
-
if (this.api.player.options.debug) console.log('🎮 Twitch Plugin: Player created');
|
|
342
|
+
if (this.api.player.options.debug) console.log('🎮 Twitch Plugin: Player created (iframe: ' + isInIframe + ')');
|
|
237
343
|
|
|
238
344
|
this.api.triggerEvent('twitchplugin:playerready', {
|
|
239
345
|
channel: this.options.channel,
|
|
@@ -436,6 +542,7 @@ bottom: 35px !important;
|
|
|
436
542
|
right: 20px !important;
|
|
437
543
|
z-index: 2000 !important;
|
|
438
544
|
pointer-events: auto !important;
|
|
545
|
+
cursor: pointer !important;
|
|
439
546
|
display: block !important;
|
|
440
547
|
opacity: 0 !important;
|
|
441
548
|
transition: opacity 0.3s ease !important;
|
|
@@ -760,6 +867,13 @@ transition: opacity 0.3s ease !important;
|
|
|
760
867
|
this.brandLogoHideTimer = null;
|
|
761
868
|
}
|
|
762
869
|
|
|
870
|
+
// Disconnect MutationObserver
|
|
871
|
+
if (this.containerHeightObserver) {
|
|
872
|
+
this.containerHeightObserver.disconnect();
|
|
873
|
+
this.containerHeightObserver = null;
|
|
874
|
+
if (this.api.player.options.debug) console.log('🎮 Twitch Plugin: MutationObserver disconnected');
|
|
875
|
+
}
|
|
876
|
+
|
|
763
877
|
// Remove mouse event listeners for brand logo auto-hide
|
|
764
878
|
if (this.api.container._brandLogoMouseHandler) {
|
|
765
879
|
this.api.container.removeEventListener('mousemove', this.api.container._brandLogoMouseHandler);
|
|
@@ -65,6 +65,8 @@
|
|
|
65
65
|
console.error('🎬 Vimeo Plugin: videoId or videoUrl is required');
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
|
+
// Ensure video wrapper has 100% height for proper fullscreen positioning
|
|
69
|
+
this.player.container.style.height = '100%';
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
/**
|
|
@@ -764,43 +766,52 @@
|
|
|
764
766
|
/* Controlbar gradient - dark opaque at bottom, semi-transparent at top */
|
|
765
767
|
/* ONLY applied when Vimeo plugin is active */
|
|
766
768
|
.video-wrapper.vimeo-active .controls {
|
|
767
|
-
background: linear-gradient(
|
|
768
|
-
|
|
769
|
-
rgba(0, 0, 0, ${controlBarOpacity})
|
|
770
|
-
rgba(0, 0, 0, ${controlBarOpacity * 0.
|
|
771
|
-
rgba(0, 0, 0, ${controlBarOpacity * 0.
|
|
772
|
-
rgba(0, 0, 0, ${controlBarOpacity * 0.
|
|
773
|
-
rgba(0, 0, 0, ${controlBarOpacity * 0.
|
|
774
|
-
rgba(0, 0, 0, ${controlBarOpacity * 0.21}) 100% /* 21% at top */
|
|
769
|
+
background: linear-gradient(to top,
|
|
770
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0}) 0%,
|
|
771
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.89}) 20%,
|
|
772
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.74}) 40%,
|
|
773
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.53}) 60%,
|
|
774
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.32}) 80%,
|
|
775
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.21}) 100%
|
|
775
776
|
) !important;
|
|
776
777
|
backdrop-filter: blur(3px);
|
|
777
778
|
min-height: 60px;
|
|
778
779
|
padding-bottom: 10px;
|
|
779
780
|
}
|
|
780
|
-
|
|
781
|
+
|
|
782
|
+
/* FIX: Ensure controlbar stays at bottom in fullscreen */
|
|
783
|
+
.video-wrapper.vimeo-active:-webkit-full-screen .controls,
|
|
784
|
+
.video-wrapper.vimeo-active:-moz-full-screen .controls,
|
|
785
|
+
.video-wrapper.vimeo-active:fullscreen .controls {
|
|
786
|
+
position: fixed !important;
|
|
787
|
+
bottom: 0 !important;
|
|
788
|
+
left: 0 !important;
|
|
789
|
+
right: 0 !important;
|
|
790
|
+
z-index: 999999 !important;
|
|
791
|
+
}
|
|
792
|
+
|
|
781
793
|
/* Title overlay gradient - dark opaque at top, semi-transparent at bottom */
|
|
782
794
|
/* ONLY applied when Vimeo plugin is active */
|
|
783
795
|
.video-wrapper.vimeo-active .title-overlay {
|
|
784
|
-
background: linear-gradient(
|
|
785
|
-
|
|
786
|
-
rgba(0, 0, 0, ${titleOverlayOpacity})
|
|
787
|
-
rgba(0, 0, 0, ${titleOverlayOpacity * 0.
|
|
788
|
-
rgba(0, 0, 0, ${titleOverlayOpacity * 0.
|
|
789
|
-
rgba(0, 0, 0, ${titleOverlayOpacity * 0.
|
|
790
|
-
rgba(0, 0, 0, ${titleOverlayOpacity * 0.
|
|
791
|
-
rgba(0, 0, 0, ${titleOverlayOpacity * 0.21}) 100% /* 21% at bottom */
|
|
796
|
+
background: linear-gradient(to bottom,
|
|
797
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0}) 0%,
|
|
798
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.89}) 20%,
|
|
799
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.74}) 40%,
|
|
800
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.53}) 60%,
|
|
801
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.32}) 80%,
|
|
802
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.21}) 100%
|
|
792
803
|
) !important;
|
|
793
804
|
backdrop-filter: blur(3px);
|
|
794
805
|
min-height: 80px;
|
|
795
806
|
padding-top: 20px;
|
|
796
807
|
}
|
|
797
|
-
|
|
808
|
+
|
|
798
809
|
/* Keep controlbar visible when video is paused */
|
|
799
810
|
.video-wrapper.vimeo-active.video-paused .controls.show {
|
|
800
811
|
opacity: 1 !important;
|
|
801
812
|
visibility: visible !important;
|
|
802
813
|
}
|
|
803
|
-
|
|
814
|
+
|
|
804
815
|
/* Keep title overlay visible when video is paused */
|
|
805
816
|
.video-wrapper.vimeo-active.video-paused .title-overlay.show {
|
|
806
817
|
opacity: 1 !important;
|
|
@@ -945,26 +956,40 @@
|
|
|
945
956
|
console.log('🎬 Vimeo Plugin: Showing Vimeo native controls');
|
|
946
957
|
}
|
|
947
958
|
|
|
948
|
-
const iframe = this.player.container.querySelector('iframe');
|
|
949
959
|
const controlbar = this.player.container.querySelector('.controls');
|
|
950
960
|
const titleOverlay = this.player.container.querySelector('.title-overlay');
|
|
961
|
+
const mouseMoveOverlay = this.player.container.querySelector('.vimeo-mousemove-overlay');
|
|
962
|
+
const vimeoContainer = this.player.container.querySelector('.vimeo-player-container');
|
|
951
963
|
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
964
|
+
// Remove inline styles from mousemove overlay
|
|
965
|
+
if (mouseMoveOverlay) {
|
|
966
|
+
this.savedMouseMoveStyle = mouseMoveOverlay.getAttribute('style');
|
|
967
|
+
mouseMoveOverlay.removeAttribute('style');
|
|
968
|
+
}
|
|
956
969
|
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
970
|
+
// Remove "vimeo-container-no-controls" class from vimeo container
|
|
971
|
+
if (vimeoContainer) {
|
|
972
|
+
vimeoContainer.classList.remove('vimeo-container-no-controls');
|
|
973
|
+
}
|
|
960
974
|
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
975
|
+
// Hide MYETV controls
|
|
976
|
+
if (controlbar) {
|
|
977
|
+
controlbar.style.display = 'none';
|
|
978
|
+
}
|
|
979
|
+
if (titleOverlay) {
|
|
980
|
+
titleOverlay.style.display = 'none';
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
// Auto-restore after 10 seconds
|
|
984
|
+
this.vimeoControlsTimeout = setTimeout(() => {
|
|
985
|
+
if (this.options.debug) {
|
|
986
|
+
console.log('🎬 Vimeo Plugin: Restoring custom controls after 10 seconds');
|
|
987
|
+
}
|
|
988
|
+
this.hideVimeoControls();
|
|
989
|
+
}, 10000);
|
|
990
|
+
|
|
991
|
+
if (this.options.debug) {
|
|
992
|
+
console.log('🎬 Vimeo Plugin: Vimeo native controls enabled');
|
|
968
993
|
}
|
|
969
994
|
}
|
|
970
995
|
|
|
@@ -974,31 +999,37 @@
|
|
|
974
999
|
console.log('🎬 Vimeo Plugin: Hiding Vimeo native controls');
|
|
975
1000
|
}
|
|
976
1001
|
|
|
977
|
-
// Clear timeout if exists
|
|
978
1002
|
if (this.vimeoControlsTimeout) {
|
|
979
1003
|
clearTimeout(this.vimeoControlsTimeout);
|
|
980
1004
|
this.vimeoControlsTimeout = null;
|
|
981
1005
|
}
|
|
982
1006
|
|
|
983
|
-
const iframe = this.player.container.querySelector('iframe');
|
|
984
1007
|
const controlbar = this.player.container.querySelector('.controls');
|
|
985
1008
|
const titleOverlay = this.player.container.querySelector('.title-overlay');
|
|
1009
|
+
const mouseMoveOverlay = this.player.container.querySelector('.vimeo-mousemove-overlay');
|
|
1010
|
+
const vimeoContainer = this.player.container.querySelector('.vimeo-player-container');
|
|
986
1011
|
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1012
|
+
// Restore inline styles to mousemove overlay
|
|
1013
|
+
if (mouseMoveOverlay && this.savedMouseMoveStyle) {
|
|
1014
|
+
mouseMoveOverlay.setAttribute('style', this.savedMouseMoveStyle);
|
|
1015
|
+
this.savedMouseMoveStyle = null;
|
|
1016
|
+
}
|
|
991
1017
|
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
}
|
|
997
|
-
if (titleOverlay) titleOverlay.style.display = '';
|
|
1018
|
+
// Add back "vimeo-container-no-controls" class
|
|
1019
|
+
if (vimeoContainer) {
|
|
1020
|
+
vimeoContainer.classList.add('vimeo-container-no-controls');
|
|
1021
|
+
}
|
|
998
1022
|
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1023
|
+
// Show MYETV controls
|
|
1024
|
+
if (controlbar) {
|
|
1025
|
+
controlbar.style.display = '';
|
|
1026
|
+
}
|
|
1027
|
+
if (titleOverlay) {
|
|
1028
|
+
titleOverlay.style.display = '';
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
if (this.options.debug) {
|
|
1032
|
+
console.log('🎬 Vimeo Plugin: Custom controls restored');
|
|
1002
1033
|
}
|
|
1003
1034
|
}
|
|
1004
1035
|
|
|
@@ -101,7 +101,7 @@ const player = new MYETVPlayer('myVideo', {
|
|
|
101
101
|
// YouTube video ID (required if not using auto-detection)
|
|
102
102
|
videoId: 'dQw4w9WgXcQ',
|
|
103
103
|
|
|
104
|
-
// YouTube Data API key (optional, for
|
|
104
|
+
// YouTube Data API key (optional, for improved features)
|
|
105
105
|
apiKey: null,
|
|
106
106
|
|
|
107
107
|
// Auto-play video on load
|
|
@@ -113,6 +113,9 @@ const player = new MYETVPlayer('myVideo', {
|
|
|
113
113
|
// Show the button on the controlbar to enable the YouTube native controls temporarily
|
|
114
114
|
showNativeControlsButton: true,
|
|
115
115
|
|
|
116
|
+
// Extract and show the Youtube chapters (API Key is required)
|
|
117
|
+
showYoutubeChapters : true,
|
|
118
|
+
|
|
116
119
|
controlBarOpacity: 0.95, // The controlbar opacity or semi-transparency or transparency - values: from 0 to 1
|
|
117
120
|
|
|
118
121
|
titleOverlayOpacity: 0.95, // The overlay title opacity or semi-transparency or transparency - values: from 0 to 1
|
|
@@ -129,7 +132,7 @@ const player = new MYETVPlayer('myVideo', {
|
|
|
129
132
|
// Enable quality control in player UI
|
|
130
133
|
enableQualityControl: true,
|
|
131
134
|
|
|
132
|
-
// enable channel information retrieval (
|
|
135
|
+
// enable channel information retrieval (API key is required)
|
|
133
136
|
enableChannelWatermark: false,
|
|
134
137
|
|
|
135
138
|
// Set the default language for auto subtitles
|