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.
@@ -372,22 +372,25 @@ constructor(videoElement, options = {}) {
372
372
  }
373
373
 
374
374
  this.options = {
375
- showQualitySelector: true,
376
- showSpeedControl: true,
377
- showFullscreen: true,
378
- showPictureInPicture: true,
379
- showSubtitles: true,
380
- subtitlesEnabled: false,
381
- autoHide: true,
382
- autoHideDelay: 3000,
375
+ showQualitySelector: true, // Enable quality selector button
376
+ showSpeedControl: true, // Enable speed control button
377
+ showFullscreen: true, // Enable fullscreen button
378
+ showPictureInPicture: true, // Enable PiP button
379
+ showSubtitles: true, // Enable subtitles button
380
+ subtitlesEnabled: false, // Enable subtitles by default if available
381
+ autoHide: true, // auto-hide controls when idle
382
+ autoHideDelay: 3000, // hide controls after ... seconds of inactivity (specificed in milliseconds)
383
+ hideCursor: true, // hide mouse cursor when idle
383
384
  poster: null, // URL of poster image
384
385
  showPosterOnEnd: false, // Show poster again when video ends
385
- keyboardControls: true,
386
- showSeekTooltip: true,
387
- showTitleOverlay: false,
388
- videoTitle: '',
389
- videoSubtitle: '',
390
- persistentTitle: false,
386
+ keyboardControls: true, // Enable keyboard controls
387
+ showSeekTooltip: true, // Show tooltip on seek bar at mouse hover
388
+ showTitleOverlay: false, // Show video title overlay
389
+ videoTitle: '', // Title text to show in overlay
390
+ videoSubtitle: '', // Subtitle text to show in overlay
391
+ persistentTitle: false, // If true, title overlay stays visible
392
+ controlBarOpacity: options.controlBarOpacity !== undefined ? options.controlBarOpacity : 0.95, // Opacity of control bar (0.0 to 1.0)
393
+ titleOverlayOpacity: options.titleOverlayOpacity !== undefined ? options.titleOverlayOpacity : 0.95, // Opacity of title overlay (0.0 to 1.0)
391
394
  debug: false, // Enable/disable debug logging
392
395
  autoplay: false, // if video should autoplay at start
393
396
  defaultQuality: 'auto', // 'auto', '1080p', '720p', '480p', etc.
@@ -417,8 +420,8 @@ constructor(videoElement, options = {}) {
417
420
 
418
421
  seekHandleShape: 'circle', // Available shape: none, circle, square, diamond, arrow, triangle, heart, star
419
422
 
420
- audiofile: false,
421
- audiowave: false,
423
+ audiofile: false, // if true, adapt player to audio file (hide video element)
424
+ audiowave: false, // if true, show audio wave visualization (Web Audio API)
422
425
 
423
426
  resolution: "normal", // "normal", "4:3", "16:9", "stretched", "fit-to-screen", "scale-to-fit"
424
427
  ...options
@@ -513,6 +516,8 @@ constructor(videoElement, options = {}) {
513
516
 
514
517
  this.lastTimeUpdate = 0; // For throttling timeupdate events
515
518
 
519
+ this.injectDefaultControlbarStyles();
520
+
516
521
  if (this.options.language && this.isI18nAvailable()) {
517
522
  VideoPlayerTranslations.setLanguage(this.options.language);
518
523
  }
@@ -2598,6 +2603,7 @@ initAutoHide() {
2598
2603
 
2599
2604
  onMouseMoveInPlayer(e) {
2600
2605
  this.showControlsNow();
2606
+ this.showCursor();
2601
2607
  this.resetAutoHideTimer();
2602
2608
  }
2603
2609
 
@@ -2655,39 +2661,37 @@ resetAutoHideTimer() {
2655
2661
  showControlsNow() {
2656
2662
  if (this.controls) {
2657
2663
  this.controls.classList.add('show');
2658
- }
2659
2664
 
2660
2665
  if (this.container) {
2661
2666
  this.container.classList.add('has-controls');
2667
+ }
2668
+
2662
2669
  this.updateControlbarHeight();
2663
2670
 
2664
2671
  if (this.updateWatermarkPosition) {
2665
2672
  this.updateWatermarkPosition();
2666
2673
  }
2667
- }
2668
2674
 
2669
2675
  if (this.options.showTitleOverlay && !this.options.persistentTitle && this.options.videoTitle) {
2670
2676
  this.showTitleOverlay();
2671
2677
  }
2672
2678
 
2679
+ this.showCursor();
2680
+
2673
2681
  if (this.autoHideDebug && this.options.debug) console.log('✅ Controls shown');
2682
+ }
2674
2683
  }
2675
2684
 
2676
2685
  hideControlsNow() {
2677
2686
 
2678
2687
  const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
2679
-
2680
2688
  if (this.mouseOverControls && !isTouchDevice) {
2681
- if (this.autoHideDebug && this.options.debug) {
2682
- console.log('🚫 Not hiding - mouse still over controls');
2683
- }
2689
+ if (this.autoHideDebug && this.options.debug) console.log('❌ Not hiding - mouse still over controls');
2684
2690
  return;
2685
2691
  }
2686
2692
 
2687
2693
  if (this.video && this.video.paused) {
2688
- if (this.autoHideDebug && this.options.debug) {
2689
- console.log('🚫 Not hiding - video is paused');
2690
- }
2694
+ if (this.autoHideDebug && this.options.debug) console.log('❌ Not hiding - video is paused');
2691
2695
  return;
2692
2696
  }
2693
2697
 
@@ -2696,20 +2700,21 @@ hideControlsNow() {
2696
2700
 
2697
2701
  if (this.container) {
2698
2702
  this.container.classList.remove('has-controls');
2703
+ }
2704
+
2699
2705
  this.updateControlbarHeight();
2700
2706
 
2701
2707
  if (this.updateWatermarkPosition) {
2702
2708
  this.updateWatermarkPosition();
2703
2709
  }
2704
- }
2705
- }
2706
2710
 
2707
2711
  if (this.options.showTitleOverlay && !this.options.persistentTitle) {
2708
2712
  this.hideTitleOverlay();
2709
2713
  }
2710
2714
 
2711
- if (this.autoHideDebug && this.options.debug) {
2712
- console.log('👁️ Controls hidden');
2715
+ this.hideCursor();
2716
+
2717
+ if (this.autoHideDebug && this.options.debug) console.log('✅ Controls hidden');
2713
2718
  }
2714
2719
  }
2715
2720
 
@@ -2733,6 +2738,51 @@ clearControlsTimeout() {
2733
2738
  }
2734
2739
  }
2735
2740
 
2741
+ injectDefaultControlbarStyles() {
2742
+ if (document.getElementById('default-controlbar-styles')) {
2743
+ return;
2744
+ }
2745
+
2746
+ const controlBarOpacity = Math.max(0, Math.min(1, this.options.controlBarOpacity));
2747
+ const titleOverlayOpacity = Math.max(0, Math.min(1, this.options.titleOverlayOpacity));
2748
+
2749
+ const style = document.createElement('style');
2750
+ style.id = 'default-controlbar-styles';
2751
+ style.textContent = `
2752
+ .video-wrapper:not(.youtube-active):not(.vimeo-active):not(.facebook-active) .controls {
2753
+ background: linear-gradient(
2754
+ to top,
2755
+ rgba(0, 0, 0, ${controlBarOpacity}) 0%,
2756
+ rgba(0, 0, 0, ${controlBarOpacity * 0.89}) 20%,
2757
+ rgba(0, 0, 0, ${controlBarOpacity * 0.74}) 40%,
2758
+ rgba(0, 0, 0, ${controlBarOpacity * 0.53}) 60%,
2759
+ rgba(0, 0, 0, ${controlBarOpacity * 0.32}) 80%,
2760
+ rgba(0, 0, 0, ${controlBarOpacity * 0.21}) 100%
2761
+ );
2762
+ backdrop-filter: blur(3px);
2763
+ min-height: 60px;
2764
+ padding-bottom: 10px;
2765
+ }
2766
+
2767
+ .video-wrapper:not(.youtube-active):not(.vimeo-active):not(.facebook-active) .title-overlay {
2768
+ background: linear-gradient(
2769
+ to bottom,
2770
+ rgba(0, 0, 0, ${titleOverlayOpacity}) 0%,
2771
+ rgba(0, 0, 0, ${titleOverlayOpacity * 0.89}) 20%,
2772
+ rgba(0, 0, 0, ${titleOverlayOpacity * 0.74}) 40%,
2773
+ rgba(0, 0, 0, ${titleOverlayOpacity * 0.53}) 60%,
2774
+ rgba(0, 0, 0, ${titleOverlayOpacity * 0.32}) 80%,
2775
+ rgba(0, 0, 0, ${titleOverlayOpacity * 0.21}) 100%
2776
+ );
2777
+ backdrop-filter: blur(3px);
2778
+ min-height: 80px;
2779
+ padding-top: 20px;
2780
+ }
2781
+ `;
2782
+
2783
+ document.head.appendChild(style);
2784
+ }
2785
+
2736
2786
  enableAutoHideDebug() {
2737
2787
  this.autoHideDebug = true;
2738
2788
  if (this.options.debug) console.log('AUTO-HIDE DEBUG ENABLED');
@@ -3523,6 +3573,41 @@ isAutoHideInitialized() {
3523
3573
  return this.autoHideInitialized;
3524
3574
  }
3525
3575
 
3576
+ hideCursor() {
3577
+ if (!this.options.hideCursor) {
3578
+ return; // Do not hide cursor if option is disabled
3579
+ }
3580
+
3581
+ if (this.container) {
3582
+ this.container.classList.add('hide-cursor');
3583
+ if (this.options.debug) console.log('🖱️ Cursor hidden');
3584
+ }
3585
+ }
3586
+
3587
+ showCursor() {
3588
+ if (this.container) {
3589
+ this.container.classList.remove('hide-cursor');
3590
+ if (this.options.debug) console.log('🖱️ Cursor shown');
3591
+ }
3592
+ }
3593
+
3594
+ enableCursorHiding() {
3595
+ this.options.hideCursor = true;
3596
+ if (this.options.debug) console.log('Cursor hiding enabled');
3597
+ return this;
3598
+ }
3599
+
3600
+ disableCursorHiding() {
3601
+ this.options.hideCursor = false;
3602
+ this.showCursor(); // Ensure cursor is shown immediately
3603
+ if (this.options.debug) console.log('Cursor hiding disabled');
3604
+ return this;
3605
+ }
3606
+
3607
+ isCursorHidingEnabled() {
3608
+ return this.options.hideCursor;
3609
+ }
3610
+
3526
3611
  showPlaylistControls() {
3527
3612
  if (!this.playlistPrevBtn || !this.playlistNextBtn) return;
3528
3613
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myetv-player",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "MYETV Video Player - Modular JavaScript and SCSS Build System",
5
5
  "main": "dist/myetv-player.js",
6
6
  "scripts": {
@@ -37,3 +37,5 @@
37
37
 
38
38
 
39
39
 
40
+
41
+
@@ -119,6 +119,9 @@ const player = new MYETVPlayer('myVideo', {
119
119
  showCaptions: true, // Show captions if available
120
120
 
121
121
  // ========== Plugin Options ==========
122
+ showNativeControlsButton: true, // Show the button on the controlbar to enable the Facebook native controls temporarily
123
+ controlBarOpacity: 0.95, // The controlbar opacity or semi-transparency or transparency - values: from 0 to 1
124
+ titleOverlayOpacity: 0.95, // The overlay title opacity or semi-transparency or transparency - values: from 0 to 1
122
125
  debug: false, // Enable debug logging
123
126
  replaceNativePlayer: true, // Replace native video element
124
127
  autoLoadFromData: true // Auto-detect from data attributes
@@ -24,6 +24,13 @@
24
24
  showText: options.showText !== false,
25
25
  showCaptions: options.showCaptions !== false,
26
26
  // Plugin options
27
+ showNativeControlsButton: options.showNativeControlsButton !== undefined ? options.showNativeControlsButton : true,
28
+ controlBarOpacity: options.controlBarOpacity !== undefined
29
+ ? options.controlBarOpacity
30
+ : (player.options.controlBarOpacity !== undefined ? player.options.controlBarOpacity : 0.95),
31
+ titleOverlayOpacity: options.titleOverlayOpacity !== undefined
32
+ ? options.titleOverlayOpacity
33
+ : (player.options.titleOverlayOpacity !== undefined ? player.options.titleOverlayOpacity : 0.95),
27
34
  debug: options.debug || false,
28
35
  replaceNativePlayer: options.replaceNativePlayer !== false,
29
36
  autoLoadFromData: options.autoLoadFromData !== false,
@@ -456,9 +463,15 @@
456
463
  }
457
464
  }
458
465
 
466
+ // Create Facebook controls button
467
+ this.createFacebookControlsButton();
468
+
459
469
  // Setup event listeners
460
470
  this.setupEventListeners();
461
471
 
472
+ // inject controlbar gradient styles
473
+ this.injectControlbarGradientStyles();
474
+
462
475
  // Start time update
463
476
  this.startTimeUpdate();
464
477
 
@@ -724,12 +737,29 @@
724
737
  // Started playing - marks successful user interaction
725
738
  this.fbPlayer.subscribe('startedPlaying', () => {
726
739
  if (this.api.player.options.debug) {
727
- console.log('FB Plugin: Video started playing');
740
+ console.log('🎬 FB Plugin: Video started playing');
728
741
  }
742
+
729
743
  this.isPlaying = true;
730
744
  this.userHasInteracted = true; // Video playing = user clicked FB player
731
745
  this.waitingForUserClick = false;
732
746
 
747
+ // Rimuovi classe paused
748
+ if (this.player.container) {
749
+ this.player.container.classList.remove('video-paused');
750
+ }
751
+
752
+ // Riattiva l'auto-hide quando riprende la riproduzione
753
+ if (this.player.options.autoHide && this.player.autoHideInitialized) {
754
+ if (this.player.resetAutoHideTimer) {
755
+ this.player.resetAutoHideTimer();
756
+ }
757
+
758
+ if (this.options.debug) {
759
+ console.log('🎬 FB Plugin: Video playing - auto-hide reactivated');
760
+ }
761
+ }
762
+
733
763
  // Update play/pause icons
734
764
  const playIcon = this.api.container.querySelector('.play-icon');
735
765
  const pauseIcon = this.api.container.querySelector('.pause-icon');
@@ -740,7 +770,6 @@
740
770
  currentTime: this.getCurrentTime(),
741
771
  duration: this.getDuration()
742
772
  });
743
-
744
773
  this.api.triggerEvent('play', {});
745
774
  this.api.triggerEvent('playing', {});
746
775
  this.hideLoadingOverlay();
@@ -749,10 +778,47 @@
749
778
  // Paused
750
779
  this.fbPlayer.subscribe('paused', () => {
751
780
  if (this.api.player.options.debug) {
752
- console.log('FB Plugin: Video paused');
781
+ console.log('🎬 FB Plugin: Video paused');
753
782
  }
783
+
754
784
  this.isPlaying = false;
755
785
 
786
+ // Aggiungi classe per identificare lo stato di pausa
787
+ if (this.player.container) {
788
+ this.player.container.classList.add('video-paused');
789
+ }
790
+
791
+ // Mantieni la controlbar visibile SOLO se autoHide è abilitato
792
+ if (this.player.options.autoHide && this.player.autoHideInitialized) {
793
+ // Mostra controlli
794
+ if (this.player.controls) {
795
+ this.player.controls.classList.add('show');
796
+ }
797
+
798
+ // Mostra anche il title overlay se è abilitato e non è persistent
799
+ if (this.player.options.showTitleOverlay &&
800
+ !this.player.options.persistentTitle &&
801
+ this.player.titleOverlay) {
802
+ this.player.titleOverlay.classList.add('show');
803
+ }
804
+
805
+ // Cancella il timer di auto-hide
806
+ if (this.player.autoHideTimer) {
807
+ clearTimeout(this.player.autoHideTimer);
808
+ this.player.autoHideTimer = null;
809
+ }
810
+
811
+ // Cancella anche il timer del title overlay
812
+ if (this.player.titleTimeout) {
813
+ clearTimeout(this.player.titleTimeout);
814
+ this.player.titleTimeout = null;
815
+ }
816
+
817
+ if (this.options.debug) {
818
+ console.log('🎬 FB Plugin: Video paused - controls and title locked visible');
819
+ }
820
+ }
821
+
756
822
  // Update play/pause icons
757
823
  const playIcon = this.api.container.querySelector('.play-icon');
758
824
  const pauseIcon = this.api.container.querySelector('.pause-icon');
@@ -763,15 +829,15 @@
763
829
  currentTime: this.getCurrentTime(),
764
830
  duration: this.getDuration()
765
831
  });
766
-
767
832
  this.api.triggerEvent('pause', {});
768
833
  });
769
834
 
770
835
  // Finished playing
771
836
  this.fbPlayer.subscribe('finishedPlaying', () => {
772
837
  if (this.api.player.options.debug) {
773
- console.log('FB Plugin: Video finished');
838
+ console.log('🎬 FB Plugin: Video finished');
774
839
  }
840
+
775
841
  this.isPlaying = false;
776
842
 
777
843
  // Update play/pause icons
@@ -789,7 +855,7 @@
789
855
  // Started buffering
790
856
  this.fbPlayer.subscribe('startedBuffering', () => {
791
857
  if (this.api.player.options.debug) {
792
- console.log('FB Plugin: Video buffering started');
858
+ console.log('🎬 FB Plugin: Video buffering started');
793
859
  }
794
860
  this.api.triggerEvent('waiting', {});
795
861
  this.showLoadingOverlay();
@@ -798,7 +864,7 @@
798
864
  // Finished buffering
799
865
  this.fbPlayer.subscribe('finishedBuffering', () => {
800
866
  if (this.api.player.options.debug) {
801
- console.log('FB Plugin: Video buffering finished');
867
+ console.log('🎬 FB Plugin: Video buffering finished');
802
868
  }
803
869
  this.api.triggerEvent('canplay', {});
804
870
  this.hideLoadingOverlay();
@@ -806,13 +872,13 @@
806
872
 
807
873
  // Error
808
874
  this.fbPlayer.subscribe('error', (error) => {
809
- console.error('FB Plugin: Facebook player error:', error);
875
+ console.error('🎬 FB Plugin: Facebook player error:', error);
810
876
  this.api.triggerEvent('error', error);
811
877
  this.api.triggerEvent('facebookplugin:error', error);
812
878
  });
813
879
 
814
880
  if (this.api.player.options.debug) {
815
- console.log('FB Plugin: Event listeners setup completed');
881
+ console.log('🎬 FB Plugin: Event listeners setup completed');
816
882
  }
817
883
  }
818
884
 
@@ -824,7 +890,6 @@
824
890
  this.timeUpdateInterval = setInterval(() => {
825
891
  if (this.fbPlayer && this.fbPlayer.getCurrentPosition !== undefined && this.fbPlayer.getDuration !== undefined) {
826
892
  try {
827
- // CRITICAL FIX: These are properties, not methods
828
893
  const currentTime = this.fbPlayer.getCurrentPosition();
829
894
  const duration = this.fbPlayer.getDuration();
830
895
 
@@ -852,13 +917,10 @@
852
917
  // Create tooltip if it doesn't exist
853
918
  this.createProgressTooltip();
854
919
 
855
- // CRITICAL: Update progress bar tooltip with current duration
920
+ // Update progress bar tooltip with current duration
856
921
  this.updateProgressTooltip(duration);
857
922
  }
858
923
 
859
- // REMOVED: Volume monitoring - Facebook API doesn't have volume events
860
- // Volume is only updated via setupVolumeSlider() when user changes it
861
-
862
924
  } catch (error) {
863
925
  // Ignore timing errors
864
926
  }
@@ -867,7 +929,84 @@
867
929
  }
868
930
 
869
931
  /**
870
- * CRITICAL: Update progress bar tooltip with correct time
932
+ * Inject CSS styles for controlbar and title overlay gradients
933
+ * Uses Facebook-specific selectors to avoid conflicts with other plugins
934
+ */
935
+ injectControlbarGradientStyles() {
936
+ // Check if styles are already injected
937
+ if (document.getElementById('facebook-controlbar-gradient-styles')) {
938
+ return;
939
+ }
940
+
941
+ // Validate opacity values (must be between 0 and 1)
942
+ const controlBarOpacity = Math.max(0, Math.min(1, this.options.controlBarOpacity));
943
+ const titleOverlayOpacity = Math.max(0, Math.min(1, this.options.titleOverlayOpacity));
944
+
945
+ // Create style element
946
+ const style = document.createElement('style');
947
+ style.id = 'facebook-controlbar-gradient-styles';
948
+
949
+ // CSS with Facebook-specific selectors to avoid conflicts
950
+ style.textContent = `
951
+ /* Controlbar gradient - dark opaque at bottom, semi-transparent at top */
952
+ /* ONLY applied when Facebook plugin is active */
953
+ .video-wrapper.facebook-active .controls {
954
+ background: linear-gradient(
955
+ to top,
956
+ rgba(0, 0, 0, ${controlBarOpacity}) 0%, /* Maximum opacity at bottom */
957
+ rgba(0, 0, 0, ${controlBarOpacity * 0.89}) 20%, /* 89% of max opacity */
958
+ rgba(0, 0, 0, ${controlBarOpacity * 0.74}) 40%, /* 74% */
959
+ rgba(0, 0, 0, ${controlBarOpacity * 0.53}) 60%, /* 53% */
960
+ rgba(0, 0, 0, ${controlBarOpacity * 0.32}) 80%, /* 32% */
961
+ rgba(0, 0, 0, ${controlBarOpacity * 0.21}) 100% /* 21% at top */
962
+ ) !important;
963
+ backdrop-filter: blur(3px);
964
+ min-height: 60px;
965
+ padding-bottom: 10px;
966
+ }
967
+
968
+ /* Title overlay gradient - dark opaque at top, semi-transparent at bottom */
969
+ /* ONLY applied when Facebook plugin is active */
970
+ .video-wrapper.facebook-active .title-overlay {
971
+ background: linear-gradient(
972
+ to bottom,
973
+ rgba(0, 0, 0, ${titleOverlayOpacity}) 0%, /* Maximum opacity at top */
974
+ rgba(0, 0, 0, ${titleOverlayOpacity * 0.89}) 20%, /* 89% of max opacity */
975
+ rgba(0, 0, 0, ${titleOverlayOpacity * 0.74}) 40%, /* 74% */
976
+ rgba(0, 0, 0, ${titleOverlayOpacity * 0.53}) 60%, /* 53% */
977
+ rgba(0, 0, 0, ${titleOverlayOpacity * 0.32}) 80%, /* 32% */
978
+ rgba(0, 0, 0, ${titleOverlayOpacity * 0.21}) 100% /* 21% at bottom */
979
+ ) !important;
980
+ backdrop-filter: blur(3px);
981
+ min-height: 80px;
982
+ padding-top: 20px;
983
+ }
984
+
985
+ /* Keep controlbar visible when video is paused */
986
+ .video-wrapper.facebook-active.video-paused .controls.show {
987
+ opacity: 1 !important;
988
+ visibility: visible !important;
989
+ }
990
+
991
+ /* Keep title overlay visible when video is paused */
992
+ .video-wrapper.facebook-active.video-paused .title-overlay.show {
993
+ opacity: 1 !important;
994
+ visibility: visible !important;
995
+ }
996
+ `;
997
+
998
+ // Append style to document head
999
+ document.head.appendChild(style);
1000
+
1001
+ // Debug logging
1002
+ if (this.options.debug) {
1003
+ console.log('🎬 Facebook Plugin: Controlbar and title overlay gradient styles injected');
1004
+ console.log(`🎬 Facebook Plugin: ControlBar opacity: ${controlBarOpacity}, TitleOverlay opacity: ${titleOverlayOpacity}`);
1005
+ }
1006
+ }
1007
+
1008
+ /**
1009
+ * Update progress bar tooltip with correct time
871
1010
  */
872
1011
  updateProgressTooltip() {
873
1012
  const progContainer = this.api.container.querySelector('.progress-container');
@@ -908,8 +1047,8 @@
908
1047
  }
909
1048
 
910
1049
  /**
911
- * Create progress tooltip element if it doesn't exist
912
- */
1050
+ * Create progress tooltip element if it doesn't exist
1051
+ */
913
1052
  createProgressTooltip() {
914
1053
  const progContainer = this.api.container.querySelector('.progress-container');
915
1054
  if (!progContainer) return;
@@ -1259,6 +1398,127 @@
1259
1398
 
1260
1399
  }
1261
1400
 
1401
+ // Create button to show Facebook native controls
1402
+ createFacebookControlsButton() {
1403
+ // Verify option enabled
1404
+ if (!this.options.showNativeControlsButton) {
1405
+ if (this.options.debug) {
1406
+ console.log('🎬 FB Plugin: Native controls button disabled by option');
1407
+ }
1408
+ return;
1409
+ }
1410
+
1411
+ // Check if button already exists
1412
+ if (this.player.container.querySelector('.facebook-controls-btn')) {
1413
+ return;
1414
+ }
1415
+
1416
+ const controlsRight = this.player.container.querySelector('.controls-right');
1417
+ if (!controlsRight) return;
1418
+
1419
+ const buttonHTML = `
1420
+ <button class="control-btn facebook-controls-btn" title="Show Facebook Controls">
1421
+ <svg viewBox="0 0 24 24" fill="currentColor" width="24" height="24">
1422
+ <path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>
1423
+ </svg>
1424
+ </button>
1425
+ `;
1426
+
1427
+ // Insert before quality control
1428
+ const qualityControl = controlsRight.querySelector('.quality-control');
1429
+ if (qualityControl) {
1430
+ qualityControl.insertAdjacentHTML('beforebegin', buttonHTML);
1431
+ } else {
1432
+ const fullscreenBtn = controlsRight.querySelector('.fullscreen-btn');
1433
+ if (fullscreenBtn) {
1434
+ fullscreenBtn.insertAdjacentHTML('beforebegin', buttonHTML);
1435
+ } else {
1436
+ controlsRight.insertAdjacentHTML('beforeend', buttonHTML);
1437
+ }
1438
+ }
1439
+
1440
+ // Add click listener
1441
+ const btn = this.player.container.querySelector('.facebook-controls-btn');
1442
+ if (btn) {
1443
+ btn.addEventListener('click', () => {
1444
+ if (this.options.debug) {
1445
+ console.log('🎬 FB Plugin: Native controls button clicked');
1446
+ }
1447
+ this.showFacebookControls();
1448
+ });
1449
+
1450
+ // Add custom styling (Facebook blue color)
1451
+ btn.style.color = '#1877f2';
1452
+
1453
+ if (this.options.debug) {
1454
+ console.log('🎬 FB Plugin: Native controls button created');
1455
+ }
1456
+ }
1457
+ }
1458
+
1459
+ // Show Facebook native controls
1460
+ showFacebookControls() {
1461
+ if (this.options.debug) {
1462
+ console.log('🎬 FB Plugin: Showing Facebook native controls');
1463
+ }
1464
+
1465
+ const iframe = this.player.container.querySelector('iframe');
1466
+ const controlbar = this.player.container.querySelector('.controls');
1467
+ const titleOverlay = this.player.container.querySelector('.title-overlay');
1468
+
1469
+ if (iframe) {
1470
+ // Bring iframe to front
1471
+ iframe.style.pointerEvents = 'auto';
1472
+ iframe.style.zIndex = '9999';
1473
+
1474
+ // Hide controlbar and title
1475
+ if (controlbar) controlbar.style.display = 'none';
1476
+ if (titleOverlay) titleOverlay.style.display = 'none';
1477
+
1478
+ // Auto-restore after 10 seconds
1479
+ this.facebookControlsTimeout = setTimeout(() => {
1480
+ if (this.options.debug) {
1481
+ console.log('🎬 FB Plugin: Restoring custom controls after 10 seconds');
1482
+ }
1483
+ this.hideFacebookControls();
1484
+ }, 10000);
1485
+ }
1486
+ }
1487
+
1488
+ // Hide Facebook native controls
1489
+ hideFacebookControls() {
1490
+ if (this.options.debug) {
1491
+ console.log('🎬 FB Plugin: Hiding Facebook native controls');
1492
+ }
1493
+
1494
+ // Clear timeout if exists
1495
+ if (this.facebookControlsTimeout) {
1496
+ clearTimeout(this.facebookControlsTimeout);
1497
+ this.facebookControlsTimeout = null;
1498
+ }
1499
+
1500
+ const iframe = this.player.container.querySelector('iframe');
1501
+ const controlbar = this.player.container.querySelector('.controls');
1502
+ const titleOverlay = this.player.container.querySelector('.title-overlay');
1503
+
1504
+ if (iframe) {
1505
+ // Disable clicks on Facebook controls
1506
+ iframe.style.pointerEvents = 'none';
1507
+ iframe.style.zIndex = '1';
1508
+
1509
+ // Restore controlbar and title
1510
+ if (controlbar) {
1511
+ controlbar.style.display = '';
1512
+ controlbar.style.zIndex = '10';
1513
+ }
1514
+ if (titleOverlay) titleOverlay.style.display = '';
1515
+
1516
+ if (this.options.debug) {
1517
+ console.log('🎬 FB Plugin: Custom controls restored');
1518
+ }
1519
+ }
1520
+ }
1521
+
1262
1522
  /**
1263
1523
  * CRITICAL: Setup volume slider event listeners
1264
1524
  */
@@ -1537,6 +1797,12 @@
1537
1797
  this.styleObserver = null;
1538
1798
  }
1539
1799
 
1800
+ // Clear Facebook controls timeout
1801
+ if (this.facebookControlsTimeout) {
1802
+ clearTimeout(this.facebookControlsTimeout);
1803
+ this.facebookControlsTimeout = null;
1804
+ }
1805
+
1540
1806
  if (this.fbPlayer) {
1541
1807
  this.fbPlayer = null;
1542
1808
  }