myetv-player 1.1.5 → 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.
@@ -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
- * Create Vimeo player
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
- .vimeo-player-container {
218
- position: absolute !important;
219
- top: 0 !important;
220
- left: 0 !important;
221
- width: 100% !important;
222
- height: 100% !important;
223
- z-index: 1 !important;
224
- }
225
- .vimeo-player-container iframe {
226
- position: absolute !important;
227
- top: 0 !important;
228
- left: 0 !important;
229
- width: 100% !important;
230
- height: 100% !important;
231
- border: none !important;
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
- e.preventDefault();
244
- e.stopPropagation();
245
-
246
- // Toggle play/pause through MYETV player
247
- if (this.player.video) {
248
- this.vimeoPlayer.getPaused().then(paused => {
249
- if (paused) {
250
- this.player.video.play();
251
- } else {
252
- this.player.video.pause();
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,9 +295,15 @@
264
295
  // Setup event listeners
265
296
  this.setupEventListeners();
266
297
 
298
+ // inject controlbar gradient styles
299
+ this.injectControlbarGradientStyles();
300
+
267
301
  //create overlay for mouse detection
268
302
  this.createMouseMoveOverlay();
269
303
 
304
+ // Create Vimeo controls button (only if controls were originally false)
305
+ this.createVimeoControlsButton();
306
+
270
307
  // Load available qualities
271
308
  this.loadQualities();
272
309
 
@@ -279,7 +316,7 @@
279
316
  this.isVimeoLoaded = true;
280
317
 
281
318
  if (this.options.debug) {
282
- console.log('🎬 Vimeo player created');
319
+ console.log('🎬 Vimeo player created with originalControlsSetting:', this.originalControlsSetting);
283
320
  }
284
321
  }
285
322
 
@@ -307,7 +344,8 @@
307
344
  if (this.options.byline !== undefined) vimeoOptions.byline = this.options.byline;
308
345
  if (this.options.color) vimeoOptions.color = this.options.color;
309
346
 
310
- vimeoOptions.controls = false; // ALWAYS FALSE - use MYETV controls
347
+ // Use the modified controls value (which was set to true if originalControlsSetting was false)
348
+ vimeoOptions.controls = true;
311
349
 
312
350
  if (this.options.dnt) vimeoOptions.dnt = this.options.dnt;
313
351
  if (this.options.loop) vimeoOptions.loop = this.options.loop;
@@ -354,6 +392,23 @@
354
392
  // Play event
355
393
  this.vimeoPlayer.on('play', (data) => {
356
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
+
357
412
  if (this.options.debug) {
358
413
  console.log('🎬 Vimeo: play', data);
359
414
  }
@@ -362,6 +417,42 @@
362
417
  // Pause event
363
418
  this.vimeoPlayer.on('pause', (data) => {
364
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
+
365
456
  if (this.options.debug) {
366
457
  console.log('🎬 Vimeo: pause', data);
367
458
  }
@@ -650,6 +741,83 @@
650
741
  this.stopMousePositionTracking();
651
742
  }
652
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
+
653
821
  /**
654
822
  * Load available qualities and sync with MYETV player
655
823
  */
@@ -714,9 +882,129 @@
714
882
  });
715
883
  }
716
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
+
717
1005
  /**
718
- * Update native player quality menu with Vimeo-specific handlers
719
- */
1006
+ * Update native player quality menu with Vimeo-specific handlers
1007
+ */
720
1008
  updatePlayerQualityMenu() {
721
1009
  const qualityMenu = this.player.container.querySelector('.quality-menu');
722
1010
  if (!qualityMenu) {
@@ -1144,6 +1432,12 @@
1144
1432
  this.pipCleanup();
1145
1433
  }
1146
1434
 
1435
+ // Clear Vimeo controls timeout
1436
+ if (this.vimeoControlsTimeout) {
1437
+ clearTimeout(this.vimeoControlsTimeout);
1438
+ this.vimeoControlsTimeout = null;
1439
+ }
1440
+
1147
1441
  if (this.vimeoPlayer) {
1148
1442
  this.vimeoPlayer.destroy().then(() => {
1149
1443
  if (this.options.debug) {
@@ -110,6 +110,13 @@ const player = new MYETVPlayer('myVideo', {
110
110
  // Show YouTube native controls (true) or use player controls (false)
111
111
  showYouTubeUI: false,
112
112
 
113
+ // Show the button on the controlbar to enable the YouTube native controls temporarily
114
+ showNativeControlsButton: true,
115
+
116
+ controlBarOpacity: 0.95, // The controlbar opacity or semi-transparency or transparency - values: from 0 to 1
117
+
118
+ titleOverlayOpacity: 0.95, // The overlay title opacity or semi-transparency or transparency - values: from 0 to 1
119
+
113
120
  // enable or disable the mouse click over the Youtube player also if showYouTubeUI is false
114
121
  mouseClick: false,
115
122