myetv-player 1.1.4 → 1.1.6
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 +16 -0
- package/css/myetv-player.css +21 -0
- package/css/myetv-player.min.css +1 -1
- package/dist/myetv-player.js +158 -49
- package/dist/myetv-player.min.js +114 -29
- package/package.json +3 -1
- package/plugins/facebook/README.md +3 -0
- package/plugins/facebook/myetv-player-facebook-plugin.js +283 -17
- package/plugins/vimeo/README.md +3 -0
- package/plugins/vimeo/myetv-player-vimeo.js +556 -39
- package/plugins/youtube/README.md +7 -0
- package/plugins/youtube/myetv-player-youtube-plugin.js +817 -288
- package/scss/_controls.scss +21 -0
- package/src/controls.js +136 -32
- package/src/core.js +22 -17
|
@@ -4,10 +4,6 @@
|
|
|
4
4
|
* Created by https://www.myetv.tv https://oskarcosimo.com
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
// ===================================================================
|
|
8
|
-
// GLOBAL CODE - Will be placed OUTSIDE the class by build script
|
|
9
|
-
// ===================================================================
|
|
10
|
-
|
|
11
7
|
/* GLOBAL_START */
|
|
12
8
|
(function () {
|
|
13
9
|
'use strict';
|
|
@@ -46,6 +42,13 @@
|
|
|
46
42
|
transparent: options.transparent !== false,
|
|
47
43
|
|
|
48
44
|
// Plugin options
|
|
45
|
+
showNativeControlsButton: options.showNativeControlsButton !== undefined ? options.showNativeControlsButton : true,
|
|
46
|
+
controlBarOpacity: options.controlBarOpacity !== undefined
|
|
47
|
+
? options.controlBarOpacity
|
|
48
|
+
: (player.options.controlBarOpacity !== undefined ? player.options.controlBarOpacity : 0.95),
|
|
49
|
+
titleOverlayOpacity: options.titleOverlayOpacity !== undefined
|
|
50
|
+
? options.titleOverlayOpacity
|
|
51
|
+
: (player.options.titleOverlayOpacity !== undefined ? player.options.titleOverlayOpacity : 0.95),
|
|
49
52
|
debug: options.debug || false,
|
|
50
53
|
replaceNativePlayer: options.replaceNativePlayer !== false,
|
|
51
54
|
syncControls: options.syncControls !== false,
|
|
@@ -204,33 +207,58 @@
|
|
|
204
207
|
}
|
|
205
208
|
|
|
206
209
|
/**
|
|
207
|
-
|
|
208
|
-
|
|
210
|
+
* Create Vimeo player
|
|
211
|
+
*/
|
|
209
212
|
createVimeoPlayer() {
|
|
213
|
+
// Save original controls setting BEFORE modifying
|
|
214
|
+
this.originalControlsSetting = this.options.controls;
|
|
215
|
+
|
|
216
|
+
// If controls were originally false, force them to true (we'll hide via CSS)
|
|
217
|
+
if (!this.originalControlsSetting) {
|
|
218
|
+
this.options.controls = true;
|
|
219
|
+
if (this.options.debug) {
|
|
220
|
+
console.log('[Vimeo Plugin] Controls forced to true, will hide via CSS');
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
210
224
|
// Create container for Vimeo player
|
|
211
225
|
this.vimeoContainer = document.createElement('div');
|
|
212
226
|
this.vimeoContainer.className = 'vimeo-player-container';
|
|
213
227
|
|
|
228
|
+
// Add class if we need to hide controls via CSS
|
|
229
|
+
if (!this.originalControlsSetting) {
|
|
230
|
+
this.vimeoContainer.classList.add('vimeo-container-no-controls');
|
|
231
|
+
}
|
|
232
|
+
|
|
214
233
|
// Add CSS to ensure iframe fills container properly
|
|
215
234
|
const style = document.createElement('style');
|
|
216
235
|
style.textContent = `
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
236
|
+
.vimeo-player-container {
|
|
237
|
+
position: absolute !important;
|
|
238
|
+
top: 0 !important;
|
|
239
|
+
left: 0 !important;
|
|
240
|
+
width: 100% !important;
|
|
241
|
+
height: 100% !important;
|
|
242
|
+
z-index: 1 !important;
|
|
243
|
+
}
|
|
244
|
+
.vimeo-player-container iframe {
|
|
245
|
+
position: absolute !important;
|
|
246
|
+
top: 0 !important;
|
|
247
|
+
left: 0 !important;
|
|
248
|
+
width: 100% !important;
|
|
249
|
+
height: 100% !important;
|
|
250
|
+
border: none !important;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.vimeo-container-no-controls iframe {
|
|
254
|
+
pointer-events: none !important;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.vimeo-container-no-controls.vimeo-show-controls iframe {
|
|
258
|
+
pointer-events: auto !important;
|
|
259
|
+
z-index: 999999 !important;
|
|
260
|
+
}
|
|
261
|
+
`;
|
|
234
262
|
if (!document.querySelector('#vimeo-plugin-styles')) {
|
|
235
263
|
style.id = 'vimeo-plugin-styles';
|
|
236
264
|
document.head.appendChild(style);
|
|
@@ -240,18 +268,21 @@
|
|
|
240
268
|
|
|
241
269
|
// Prevent default Vimeo click behavior and sync with MYETV
|
|
242
270
|
this.vimeoContainer.addEventListener('click', (e) => {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
271
|
+
// Only prevent default if controls are hidden
|
|
272
|
+
if (!this.originalControlsSetting && !this.vimeoContainer.classList.contains('show-vimeo-controls')) {
|
|
273
|
+
e.preventDefault();
|
|
274
|
+
e.stopPropagation();
|
|
275
|
+
|
|
276
|
+
// Toggle play/pause through MYETV player
|
|
277
|
+
if (this.player.video) {
|
|
278
|
+
this.vimeoPlayer.getPaused().then(paused => {
|
|
279
|
+
if (paused) {
|
|
280
|
+
this.player.video.play();
|
|
281
|
+
} else {
|
|
282
|
+
this.player.video.pause();
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
}
|
|
255
286
|
}
|
|
256
287
|
});
|
|
257
288
|
|
|
@@ -264,6 +295,15 @@
|
|
|
264
295
|
// Setup event listeners
|
|
265
296
|
this.setupEventListeners();
|
|
266
297
|
|
|
298
|
+
// inject controlbar gradient styles
|
|
299
|
+
this.injectControlbarGradientStyles();
|
|
300
|
+
|
|
301
|
+
//create overlay for mouse detection
|
|
302
|
+
this.createMouseMoveOverlay();
|
|
303
|
+
|
|
304
|
+
// Create Vimeo controls button (only if controls were originally false)
|
|
305
|
+
this.createVimeoControlsButton();
|
|
306
|
+
|
|
267
307
|
// Load available qualities
|
|
268
308
|
this.loadQualities();
|
|
269
309
|
|
|
@@ -276,7 +316,7 @@
|
|
|
276
316
|
this.isVimeoLoaded = true;
|
|
277
317
|
|
|
278
318
|
if (this.options.debug) {
|
|
279
|
-
console.log('🎬 Vimeo player created');
|
|
319
|
+
console.log('🎬 Vimeo player created with originalControlsSetting:', this.originalControlsSetting);
|
|
280
320
|
}
|
|
281
321
|
}
|
|
282
322
|
|
|
@@ -304,7 +344,8 @@
|
|
|
304
344
|
if (this.options.byline !== undefined) vimeoOptions.byline = this.options.byline;
|
|
305
345
|
if (this.options.color) vimeoOptions.color = this.options.color;
|
|
306
346
|
|
|
307
|
-
|
|
347
|
+
// Use the modified controls value (which was set to true if originalControlsSetting was false)
|
|
348
|
+
vimeoOptions.controls = true;
|
|
308
349
|
|
|
309
350
|
if (this.options.dnt) vimeoOptions.dnt = this.options.dnt;
|
|
310
351
|
if (this.options.loop) vimeoOptions.loop = this.options.loop;
|
|
@@ -351,6 +392,23 @@
|
|
|
351
392
|
// Play event
|
|
352
393
|
this.vimeoPlayer.on('play', (data) => {
|
|
353
394
|
this.player.triggerEvent('play', data);
|
|
395
|
+
|
|
396
|
+
// remove class paused
|
|
397
|
+
if (this.player.container) {
|
|
398
|
+
this.player.container.classList.remove('video-paused');
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// reenable auto-hide
|
|
402
|
+
if (this.player.options.autoHide && this.player.autoHideInitialized) {
|
|
403
|
+
if (this.player.resetAutoHideTimer) {
|
|
404
|
+
this.player.resetAutoHideTimer();
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (this.options.debug) {
|
|
408
|
+
console.log('🎬 Vimeo: Video playing - auto-hide reactivated');
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
354
412
|
if (this.options.debug) {
|
|
355
413
|
console.log('🎬 Vimeo: play', data);
|
|
356
414
|
}
|
|
@@ -359,6 +417,42 @@
|
|
|
359
417
|
// Pause event
|
|
360
418
|
this.vimeoPlayer.on('pause', (data) => {
|
|
361
419
|
this.player.triggerEvent('pause', data);
|
|
420
|
+
|
|
421
|
+
// add class paused
|
|
422
|
+
if (this.player.container) {
|
|
423
|
+
this.player.container.classList.add('video-paused');
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// controlbar and title overlay stay visible when paused
|
|
427
|
+
if (this.player.options.autoHide && this.player.autoHideInitialized) {
|
|
428
|
+
if (this.player.controls) {
|
|
429
|
+
this.player.controls.classList.add('show');
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// show title overlay if enabled
|
|
433
|
+
if (this.player.options.showTitleOverlay &&
|
|
434
|
+
!this.player.options.persistentTitle &&
|
|
435
|
+
this.player.titleOverlay) {
|
|
436
|
+
this.player.titleOverlay.classList.add('show');
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// delete timer for auto-hide
|
|
440
|
+
if (this.player.autoHideTimer) {
|
|
441
|
+
clearTimeout(this.player.autoHideTimer);
|
|
442
|
+
this.player.autoHideTimer = null;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// delete title timeout
|
|
446
|
+
if (this.player.titleTimeout) {
|
|
447
|
+
clearTimeout(this.player.titleTimeout);
|
|
448
|
+
this.player.titleTimeout = null;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (this.options.debug) {
|
|
452
|
+
console.log('🎬 Vimeo: Video paused - controls and title locked visible');
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
362
456
|
if (this.options.debug) {
|
|
363
457
|
console.log('🎬 Vimeo: pause', data);
|
|
364
458
|
}
|
|
@@ -429,6 +523,301 @@
|
|
|
429
523
|
});
|
|
430
524
|
}
|
|
431
525
|
|
|
526
|
+
/**
|
|
527
|
+
* Create transparent overlay for click detection
|
|
528
|
+
*/
|
|
529
|
+
createMouseMoveOverlay() {
|
|
530
|
+
if (this.mouseMoveOverlay) return;
|
|
531
|
+
|
|
532
|
+
this.mouseMoveOverlay = document.createElement('div');
|
|
533
|
+
this.mouseMoveOverlay.className = 'vimeo-mousemove-overlay';
|
|
534
|
+
this.mouseMoveOverlay.style.cssText = `
|
|
535
|
+
position: absolute;
|
|
536
|
+
top: 0;
|
|
537
|
+
left: 0;
|
|
538
|
+
width: 100%;
|
|
539
|
+
height: 100%;
|
|
540
|
+
z-index: 2;
|
|
541
|
+
background: transparent;
|
|
542
|
+
pointer-events: auto;
|
|
543
|
+
cursor: default;
|
|
544
|
+
`;
|
|
545
|
+
|
|
546
|
+
// Insert before controls
|
|
547
|
+
this.player.container.insertBefore(this.mouseMoveOverlay, this.player.controls);
|
|
548
|
+
|
|
549
|
+
// Setup mouse detection
|
|
550
|
+
this.setupMouseMoveDetection();
|
|
551
|
+
|
|
552
|
+
// Click handler for play/pause
|
|
553
|
+
this.mouseMoveOverlay.addEventListener('click', (e) => {
|
|
554
|
+
e.preventDefault();
|
|
555
|
+
e.stopPropagation();
|
|
556
|
+
|
|
557
|
+
const doubleTap = this.player.options.doubleTapPause;
|
|
558
|
+
const pauseClick = this.player.options.pauseClick;
|
|
559
|
+
|
|
560
|
+
if (doubleTap) {
|
|
561
|
+
// Check if controls are hidden
|
|
562
|
+
let controlsHidden = false;
|
|
563
|
+
if (this.player.controls) {
|
|
564
|
+
controlsHidden = this.player.controls.classList.contains('hide');
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if (!controlsHidden) {
|
|
568
|
+
const controls = this.player.container.querySelector('.controls');
|
|
569
|
+
if (controls) {
|
|
570
|
+
controlsHidden = controls.classList.contains('hide');
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
if (!controlsHidden && this.player.controls) {
|
|
575
|
+
const style = window.getComputedStyle(this.player.controls);
|
|
576
|
+
controlsHidden = (style.opacity === '0' || style.visibility === 'hidden');
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
if (controlsHidden) {
|
|
580
|
+
// Show controls
|
|
581
|
+
if (this.player.showControlsNow) {
|
|
582
|
+
this.player.showControlsNow();
|
|
583
|
+
}
|
|
584
|
+
if (this.player.resetAutoHideTimer) {
|
|
585
|
+
this.player.resetAutoHideTimer();
|
|
586
|
+
}
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
this.togglePlayPause();
|
|
591
|
+
} else if (pauseClick) {
|
|
592
|
+
this.togglePlayPause();
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
// Mouse move handler
|
|
597
|
+
this.mouseMoveOverlay.addEventListener('mousemove', (e) => {
|
|
598
|
+
if (this.player.onMouseMove) {
|
|
599
|
+
this.player.onMouseMove(e);
|
|
600
|
+
}
|
|
601
|
+
if (this.player.resetAutoHideTimer) {
|
|
602
|
+
this.player.resetAutoHideTimer();
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
if (this.options.debug) {
|
|
607
|
+
console.log('[Vimeo] Mouse overlay created');
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Setup mouse move detection
|
|
613
|
+
*/
|
|
614
|
+
setupMouseMoveDetection() {
|
|
615
|
+
// Track last mouse position
|
|
616
|
+
this.lastMouseX = null;
|
|
617
|
+
this.lastMouseY = null;
|
|
618
|
+
this.mouseCheckInterval = null;
|
|
619
|
+
|
|
620
|
+
// Mouse enter
|
|
621
|
+
this.player.container.addEventListener('mouseenter', () => {
|
|
622
|
+
if (this.options.debug) {
|
|
623
|
+
console.log('[Vimeo] Mouse entered - show controls');
|
|
624
|
+
}
|
|
625
|
+
if (this.player.showControlsNow) {
|
|
626
|
+
this.player.showControlsNow();
|
|
627
|
+
}
|
|
628
|
+
if (this.player.resetAutoHideTimer) {
|
|
629
|
+
this.player.resetAutoHideTimer();
|
|
630
|
+
}
|
|
631
|
+
this.startMousePositionTracking();
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
// Mouse leave
|
|
635
|
+
this.player.container.addEventListener('mouseleave', () => {
|
|
636
|
+
if (this.options.debug) {
|
|
637
|
+
console.log('[Vimeo] Mouse left');
|
|
638
|
+
}
|
|
639
|
+
this.stopMousePositionTracking();
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
// Mouse move
|
|
643
|
+
this.player.container.addEventListener('mousemove', (e) => {
|
|
644
|
+
this.lastMouseX = e.clientX;
|
|
645
|
+
this.lastMouseY = e.clientY;
|
|
646
|
+
if (this.player.onMouseMove) {
|
|
647
|
+
this.player.onMouseMove(e);
|
|
648
|
+
}
|
|
649
|
+
if (this.player.resetAutoHideTimer) {
|
|
650
|
+
this.player.resetAutoHideTimer();
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Start mouse position tracking
|
|
657
|
+
*/
|
|
658
|
+
startMousePositionTracking() {
|
|
659
|
+
if (this.mouseCheckInterval) return;
|
|
660
|
+
|
|
661
|
+
this.mouseCheckInterval = setInterval(() => {
|
|
662
|
+
// Track mouse position over iframe
|
|
663
|
+
const handleGlobalMove = (e) => {
|
|
664
|
+
const newX = e.clientX;
|
|
665
|
+
const newY = e.clientY;
|
|
666
|
+
|
|
667
|
+
if (this.lastMouseX !== newX || this.lastMouseY !== newY) {
|
|
668
|
+
this.lastMouseX = newX;
|
|
669
|
+
this.lastMouseY = newY;
|
|
670
|
+
|
|
671
|
+
const rect = this.player.container.getBoundingClientRect();
|
|
672
|
+
const isInside = (
|
|
673
|
+
newX >= rect.left &&
|
|
674
|
+
newX <= rect.right &&
|
|
675
|
+
newY >= rect.top &&
|
|
676
|
+
newY <= rect.bottom
|
|
677
|
+
);
|
|
678
|
+
|
|
679
|
+
if (isInside) {
|
|
680
|
+
if (this.player.showControlsNow) {
|
|
681
|
+
this.player.showControlsNow();
|
|
682
|
+
}
|
|
683
|
+
if (this.player.resetAutoHideTimer) {
|
|
684
|
+
this.player.resetAutoHideTimer();
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
document.addEventListener('mousemove', handleGlobalMove, { once: true, passive: true });
|
|
691
|
+
}, 100);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* Stop mouse position tracking
|
|
696
|
+
*/
|
|
697
|
+
stopMousePositionTracking() {
|
|
698
|
+
if (this.mouseCheckInterval) {
|
|
699
|
+
clearInterval(this.mouseCheckInterval);
|
|
700
|
+
this.mouseCheckInterval = null;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Toggle play/pause
|
|
706
|
+
*/
|
|
707
|
+
togglePlayPause() {
|
|
708
|
+
if (!this.vimeoPlayer) return;
|
|
709
|
+
|
|
710
|
+
this.vimeoPlayer.getPaused().then(paused => {
|
|
711
|
+
if (paused) {
|
|
712
|
+
// Use player's play method to trigger UI update
|
|
713
|
+
if (this.player.play) {
|
|
714
|
+
this.player.play();
|
|
715
|
+
} else if (this.player.video && this.player.video.play) {
|
|
716
|
+
this.player.video.play();
|
|
717
|
+
}
|
|
718
|
+
} else {
|
|
719
|
+
// Use player's pause method to trigger UI update
|
|
720
|
+
if (this.player.pause) {
|
|
721
|
+
this.player.pause();
|
|
722
|
+
} else if (this.player.video && this.player.video.pause) {
|
|
723
|
+
this.player.video.pause();
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
}).catch(err => {
|
|
727
|
+
if (this.options.debug) {
|
|
728
|
+
console.error('[Vimeo] GetPaused error:', err);
|
|
729
|
+
}
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Remove mouse overlay
|
|
735
|
+
*/
|
|
736
|
+
removeMouseMoveOverlay() {
|
|
737
|
+
if (this.mouseMoveOverlay) {
|
|
738
|
+
this.mouseMoveOverlay.remove();
|
|
739
|
+
this.mouseMoveOverlay = null;
|
|
740
|
+
}
|
|
741
|
+
this.stopMousePositionTracking();
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Inject CSS styles for controlbar and title overlay gradients
|
|
746
|
+
* Uses Vimeo-specific selectors to avoid conflicts with other plugins
|
|
747
|
+
*/
|
|
748
|
+
injectControlbarGradientStyles() {
|
|
749
|
+
// Check if styles are already injected
|
|
750
|
+
if (document.getElementById('vimeo-controlbar-gradient-styles')) {
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// Validate opacity values (must be between 0 and 1)
|
|
755
|
+
const controlBarOpacity = Math.max(0, Math.min(1, this.options.controlBarOpacity));
|
|
756
|
+
const titleOverlayOpacity = Math.max(0, Math.min(1, this.options.titleOverlayOpacity));
|
|
757
|
+
|
|
758
|
+
// Create style element
|
|
759
|
+
const style = document.createElement('style');
|
|
760
|
+
style.id = 'vimeo-controlbar-gradient-styles';
|
|
761
|
+
|
|
762
|
+
// CSS with Vimeo-specific selectors to avoid conflicts
|
|
763
|
+
style.textContent = `
|
|
764
|
+
/* Controlbar gradient - dark opaque at bottom, semi-transparent at top */
|
|
765
|
+
/* ONLY applied when Vimeo plugin is active */
|
|
766
|
+
.video-wrapper.vimeo-active .controls {
|
|
767
|
+
background: linear-gradient(
|
|
768
|
+
to top,
|
|
769
|
+
rgba(0, 0, 0, ${controlBarOpacity}) 0%, /* Maximum opacity at bottom */
|
|
770
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.89}) 20%, /* 89% of max opacity */
|
|
771
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.74}) 40%, /* 74% */
|
|
772
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.53}) 60%, /* 53% */
|
|
773
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.32}) 80%, /* 32% */
|
|
774
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.21}) 100% /* 21% at top */
|
|
775
|
+
) !important;
|
|
776
|
+
backdrop-filter: blur(3px);
|
|
777
|
+
min-height: 60px;
|
|
778
|
+
padding-bottom: 10px;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/* Title overlay gradient - dark opaque at top, semi-transparent at bottom */
|
|
782
|
+
/* ONLY applied when Vimeo plugin is active */
|
|
783
|
+
.video-wrapper.vimeo-active .title-overlay {
|
|
784
|
+
background: linear-gradient(
|
|
785
|
+
to bottom,
|
|
786
|
+
rgba(0, 0, 0, ${titleOverlayOpacity}) 0%, /* Maximum opacity at top */
|
|
787
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.89}) 20%, /* 89% of max opacity */
|
|
788
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.74}) 40%, /* 74% */
|
|
789
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.53}) 60%, /* 53% */
|
|
790
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.32}) 80%, /* 32% */
|
|
791
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.21}) 100% /* 21% at bottom */
|
|
792
|
+
) !important;
|
|
793
|
+
backdrop-filter: blur(3px);
|
|
794
|
+
min-height: 80px;
|
|
795
|
+
padding-top: 20px;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/* Keep controlbar visible when video is paused */
|
|
799
|
+
.video-wrapper.vimeo-active.video-paused .controls.show {
|
|
800
|
+
opacity: 1 !important;
|
|
801
|
+
visibility: visible !important;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/* Keep title overlay visible when video is paused */
|
|
805
|
+
.video-wrapper.vimeo-active.video-paused .title-overlay.show {
|
|
806
|
+
opacity: 1 !important;
|
|
807
|
+
visibility: visible !important;
|
|
808
|
+
}
|
|
809
|
+
`;
|
|
810
|
+
|
|
811
|
+
// Append style to document head
|
|
812
|
+
document.head.appendChild(style);
|
|
813
|
+
|
|
814
|
+
// Debug logging
|
|
815
|
+
if (this.options.debug) {
|
|
816
|
+
console.log('🎬 Vimeo Plugin: Controlbar and title overlay gradient styles injected');
|
|
817
|
+
console.log(`🎬 Vimeo Plugin: ControlBar opacity: ${controlBarOpacity}, TitleOverlay opacity: ${titleOverlayOpacity}`);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
|
|
432
821
|
/**
|
|
433
822
|
* Load available qualities and sync with MYETV player
|
|
434
823
|
*/
|
|
@@ -493,9 +882,129 @@
|
|
|
493
882
|
});
|
|
494
883
|
}
|
|
495
884
|
|
|
885
|
+
createVimeoControlsButton() {
|
|
886
|
+
// verify option enabled
|
|
887
|
+
if (!this.options.showNativeControlsButton) {
|
|
888
|
+
if (this.options.debug) {
|
|
889
|
+
console.log('🎬 Vimeo Plugin: Native controls button disabled by option');
|
|
890
|
+
}
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
// Check if button already exists
|
|
895
|
+
if (this.player.container.querySelector('.vimeo-controls-btn')) {
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
const controlsRight = this.player.container.querySelector('.controls-right');
|
|
900
|
+
if (!controlsRight) return;
|
|
901
|
+
|
|
902
|
+
const buttonHTML = `
|
|
903
|
+
<button class="control-btn vimeo-controls-btn" title="Show Vimeo Controls">
|
|
904
|
+
<svg viewBox="0 0 24 24" fill="currentColor" width="24" height="24">
|
|
905
|
+
<path d="M23.977 6.416c-.105 2.338-1.739 5.543-4.894 9.609-3.268 4.247-6.026 6.37-8.29 6.37-1.409 0-2.578-1.294-3.553-3.881L5.322 11.4C4.603 8.816 3.834 7.522 3.01 7.522c-.179 0-.806.378-1.881 1.132L0 7.197c1.185-1.044 2.351-2.084 3.501-3.128C5.08 2.701 6.266 1.984 7.055 1.91c1.867-.18 3.016 1.1 3.447 3.838.465 2.953.789 4.789.971 5.507.539 2.45 1.131 3.674 1.776 3.674.502 0 1.256-.796 2.265-2.385 1.004-1.589 1.54-2.797 1.612-3.628.144-1.371-.395-2.061-1.614-2.061-.574 0-1.167.121-1.777.391 1.186-3.868 3.434-5.757 6.762-5.637 2.473.06 3.628 1.664 3.493 4.797l-.013.01z"/>
|
|
906
|
+
</svg>
|
|
907
|
+
</button>
|
|
908
|
+
`;
|
|
909
|
+
|
|
910
|
+
// Insert before quality control
|
|
911
|
+
const qualityControl = controlsRight.querySelector('.quality-control');
|
|
912
|
+
if (qualityControl) {
|
|
913
|
+
qualityControl.insertAdjacentHTML('beforebegin', buttonHTML);
|
|
914
|
+
} else {
|
|
915
|
+
const fullscreenBtn = controlsRight.querySelector('.fullscreen-btn');
|
|
916
|
+
if (fullscreenBtn) {
|
|
917
|
+
fullscreenBtn.insertAdjacentHTML('beforebegin', buttonHTML);
|
|
918
|
+
} else {
|
|
919
|
+
controlsRight.insertAdjacentHTML('beforeend', buttonHTML);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
// Add click listener
|
|
924
|
+
const btn = this.player.container.querySelector('.vimeo-controls-btn');
|
|
925
|
+
if (btn) {
|
|
926
|
+
btn.addEventListener('click', () => {
|
|
927
|
+
if (this.options.debug) {
|
|
928
|
+
console.log('🎬 Vimeo Plugin: Native controls button clicked');
|
|
929
|
+
}
|
|
930
|
+
this.showVimeoControls();
|
|
931
|
+
});
|
|
932
|
+
|
|
933
|
+
// Add custom styling (Vimeo blue color)
|
|
934
|
+
btn.style.color = '#1ab7ea';
|
|
935
|
+
|
|
936
|
+
if (this.options.debug) {
|
|
937
|
+
console.log('🎬 Vimeo Plugin: Native controls button created');
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// Show Vimeo native controls
|
|
943
|
+
showVimeoControls() {
|
|
944
|
+
if (this.options.debug) {
|
|
945
|
+
console.log('🎬 Vimeo Plugin: Showing Vimeo native controls');
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
const iframe = this.player.container.querySelector('iframe');
|
|
949
|
+
const controlbar = this.player.container.querySelector('.controls');
|
|
950
|
+
const titleOverlay = this.player.container.querySelector('.title-overlay');
|
|
951
|
+
|
|
952
|
+
if (iframe) {
|
|
953
|
+
// Bring iframe to front
|
|
954
|
+
iframe.style.pointerEvents = 'auto';
|
|
955
|
+
iframe.style.zIndex = '9999';
|
|
956
|
+
|
|
957
|
+
// Hide controlbar and title
|
|
958
|
+
if (controlbar) controlbar.style.display = 'none';
|
|
959
|
+
if (titleOverlay) titleOverlay.style.display = 'none';
|
|
960
|
+
|
|
961
|
+
// Auto-restore after 10 seconds
|
|
962
|
+
this.vimeoControlsTimeout = setTimeout(() => {
|
|
963
|
+
if (this.options.debug) {
|
|
964
|
+
console.log('🎬 Vimeo Plugin: Restoring custom controls after 10 seconds');
|
|
965
|
+
}
|
|
966
|
+
this.hideVimeoControls();
|
|
967
|
+
}, 10000);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
// Hide Vimeo native controls
|
|
972
|
+
hideVimeoControls() {
|
|
973
|
+
if (this.options.debug) {
|
|
974
|
+
console.log('🎬 Vimeo Plugin: Hiding Vimeo native controls');
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// Clear timeout if exists
|
|
978
|
+
if (this.vimeoControlsTimeout) {
|
|
979
|
+
clearTimeout(this.vimeoControlsTimeout);
|
|
980
|
+
this.vimeoControlsTimeout = null;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
const iframe = this.player.container.querySelector('iframe');
|
|
984
|
+
const controlbar = this.player.container.querySelector('.controls');
|
|
985
|
+
const titleOverlay = this.player.container.querySelector('.title-overlay');
|
|
986
|
+
|
|
987
|
+
if (iframe) {
|
|
988
|
+
// Disable clicks on Vimeo controls
|
|
989
|
+
iframe.style.pointerEvents = 'none';
|
|
990
|
+
iframe.style.zIndex = '1';
|
|
991
|
+
|
|
992
|
+
// Restore controlbar and title
|
|
993
|
+
if (controlbar) {
|
|
994
|
+
controlbar.style.display = '';
|
|
995
|
+
controlbar.style.zIndex = '10';
|
|
996
|
+
}
|
|
997
|
+
if (titleOverlay) titleOverlay.style.display = '';
|
|
998
|
+
|
|
999
|
+
if (this.options.debug) {
|
|
1000
|
+
console.log('🎬 Vimeo Plugin: Custom controls restored');
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
496
1005
|
/**
|
|
497
|
-
|
|
498
|
-
|
|
1006
|
+
* Update native player quality menu with Vimeo-specific handlers
|
|
1007
|
+
*/
|
|
499
1008
|
updatePlayerQualityMenu() {
|
|
500
1009
|
const qualityMenu = this.player.container.querySelector('.quality-menu');
|
|
501
1010
|
if (!qualityMenu) {
|
|
@@ -912,6 +1421,8 @@
|
|
|
912
1421
|
* Dispose plugin
|
|
913
1422
|
*/
|
|
914
1423
|
dispose() {
|
|
1424
|
+
this.removeMouseMoveOverlay();
|
|
1425
|
+
|
|
915
1426
|
// Cleanup PIP observers and listeners
|
|
916
1427
|
if (this.pipObserver) {
|
|
917
1428
|
this.pipObserver.disconnect();
|
|
@@ -921,6 +1432,12 @@
|
|
|
921
1432
|
this.pipCleanup();
|
|
922
1433
|
}
|
|
923
1434
|
|
|
1435
|
+
// Clear Vimeo controls timeout
|
|
1436
|
+
if (this.vimeoControlsTimeout) {
|
|
1437
|
+
clearTimeout(this.vimeoControlsTimeout);
|
|
1438
|
+
this.vimeoControlsTimeout = null;
|
|
1439
|
+
}
|
|
1440
|
+
|
|
924
1441
|
if (this.vimeoPlayer) {
|
|
925
1442
|
this.vimeoPlayer.destroy().then(() => {
|
|
926
1443
|
if (this.options.debug) {
|