unified-video-framework 1.4.119 → 1.4.120

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.
@@ -739,87 +739,26 @@ export class WebPlayer extends BasePlayer {
739
739
  this.debugWarn('Failed to exit fullscreen:', error.message);
740
740
  }
741
741
  }
742
- isPictureInPictureSupported() {
743
- if (!this.video)
744
- return false;
745
- const hasStandardPiP = 'requestPictureInPicture' in this.video &&
746
- 'pictureInPictureEnabled' in document;
747
- const hasSafariPiP = 'webkitSupportsPresentationMode' in this.video &&
748
- typeof this.video.webkitSupportsPresentationMode === 'function' &&
749
- this.video.webkitSupportsPresentationMode('picture-in-picture');
750
- const userAgent = navigator.userAgent.toLowerCase();
751
- const isIOS = /iphone|ipad|ipod/.test(userAgent);
752
- const isAndroid = /android/.test(userAgent);
753
- const isChrome = /chrome/.test(userAgent) && !/edge/.test(userAgent);
754
- const isSafari = /safari/.test(userAgent) && !/chrome/.test(userAgent);
755
- const isFirefox = /firefox/.test(userAgent);
756
- const iosSupport = isIOS && isSafari && hasSafariPiP;
757
- const androidChromeSupport = isAndroid && isChrome && hasStandardPiP;
758
- const firefoxSupport = isFirefox && hasStandardPiP && !this.isMobileDevice();
759
- this.debugLog('PiP Support Detection:', {
760
- hasStandardPiP,
761
- hasSafariPiP,
762
- isIOS,
763
- isAndroid,
764
- isChrome,
765
- isSafari,
766
- isFirefox,
767
- iosSupport,
768
- androidChromeSupport,
769
- firefoxSupport,
770
- overall: hasStandardPiP || iosSupport || androidChromeSupport || firefoxSupport
771
- });
772
- return hasStandardPiP || iosSupport || androidChromeSupport || firefoxSupport;
773
- }
774
- isMobileDevice() {
775
- const userAgent = navigator.userAgent.toLowerCase();
776
- return /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/.test(userAgent) ||
777
- (!!(navigator.maxTouchPoints && navigator.maxTouchPoints > 2) && /macintosh/.test(userAgent));
778
- }
779
742
  async enterPictureInPicture() {
780
- if (!this.video) {
781
- throw new Error('Video element not available');
782
- }
783
- if (!this.isPictureInPictureSupported()) {
784
- throw new Error('Picture-in-Picture not supported on this device/browser');
785
- }
743
+ if (!this.video)
744
+ return;
786
745
  try {
787
- if ('requestPictureInPicture' in this.video) {
746
+ if (this.video.requestPictureInPicture) {
788
747
  await this.video.requestPictureInPicture();
789
- this.debugLog('PiP entered using standard API');
790
- return;
791
748
  }
792
- if ('webkitSetPresentationMode' in this.video) {
793
- this.video.webkitSetPresentationMode('picture-in-picture');
794
- this.debugLog('PiP entered using WebKit API');
795
- return;
749
+ else {
750
+ throw new Error('Picture-in-Picture not supported');
796
751
  }
797
- throw new Error('No supported PiP API available');
798
752
  }
799
753
  catch (error) {
800
- this.debugError('Failed to enter PiP:', error.message);
754
+ console.error('Failed to enter PiP:', error);
801
755
  throw error;
802
756
  }
803
757
  }
804
758
  async exitPictureInPicture() {
805
759
  try {
806
- const inStandardPiP = document.pictureInPictureElement;
807
- const inWebkitPiP = this.video &&
808
- 'webkitPresentationMode' in this.video &&
809
- this.video.webkitPresentationMode === 'picture-in-picture';
810
- if (!inStandardPiP && !inWebkitPiP) {
811
- this.debugLog('Not currently in PiP mode');
812
- return;
813
- }
814
- if (inStandardPiP && 'exitPictureInPicture' in document) {
760
+ if (document.exitPictureInPicture) {
815
761
  await document.exitPictureInPicture();
816
- this.debugLog('PiP exited using standard API');
817
- return;
818
- }
819
- if (inWebkitPiP && this.video && 'webkitSetPresentationMode' in this.video) {
820
- this.video.webkitSetPresentationMode('inline');
821
- this.debugLog('PiP exited using WebKit API');
822
- return;
823
762
  }
824
763
  }
825
764
  catch (error) {
@@ -1529,44 +1468,16 @@ export class WebPlayer extends BasePlayer {
1529
1468
  }
1530
1469
 
1531
1470
  .uvf-video {
1532
- position: absolute;
1533
- top: 50%;
1534
- left: 50%;
1535
- transform: translate(-50%, -50%);
1471
+ display: block;
1536
1472
  max-width: 100%;
1537
1473
  max-height: 100%;
1538
- width: auto;
1539
- height: auto;
1474
+ width: 100%;
1475
+ height: 100%;
1540
1476
  background: #000;
1541
1477
  object-fit: contain;
1542
- /* Ensure proper centering and scaling */
1543
1478
  object-position: center;
1544
1479
  }
1545
1480
 
1546
- /* Mobile-specific video centering improvements */
1547
- @media screen and (max-width: 767px) {
1548
- .uvf-video {
1549
- /* Force full width/height on mobile for better centering */
1550
- width: 100%;
1551
- height: 100%;
1552
- top: 0;
1553
- left: 0;
1554
- transform: none;
1555
- object-fit: contain;
1556
- object-position: center;
1557
- }
1558
-
1559
- .uvf-video-container {
1560
- /* Remove aspect ratio constraint on mobile for full height usage */
1561
- aspect-ratio: unset;
1562
- min-height: 100%;
1563
- height: 100%;
1564
- display: flex;
1565
- align-items: center;
1566
- justify-content: center;
1567
- }
1568
- }
1569
-
1570
1481
  .uvf-watermark-layer {
1571
1482
  position: absolute;
1572
1483
  top: 0;
@@ -2687,10 +2598,6 @@ export class WebPlayer extends BasePlayer {
2687
2598
  @media screen and (max-width: 767px) {
2688
2599
  html, body {
2689
2600
  overflow-x: hidden;
2690
- /* Prevent iOS Safari address bar bounce */
2691
- position: fixed;
2692
- height: 100%;
2693
- width: 100%;
2694
2601
  }
2695
2602
 
2696
2603
  .uvf-player-wrapper {
@@ -2700,23 +2607,6 @@ export class WebPlayer extends BasePlayer {
2700
2607
 
2701
2608
  /* Prevent zoom on double tap */
2702
2609
  touch-action: manipulation;
2703
-
2704
- /* Ensure full viewport usage */
2705
- position: relative;
2706
- width: 100vw;
2707
- height: 100vh;
2708
-
2709
- /* iOS Safari fix for viewport height */
2710
- min-height: -webkit-fill-available;
2711
- }
2712
-
2713
- .uvf-video-container {
2714
- /* Full viewport container */
2715
- width: 100vw;
2716
- height: 100vh;
2717
- min-height: -webkit-fill-available;
2718
- position: relative;
2719
- overflow: hidden;
2720
2610
  }
2721
2611
 
2722
2612
  .uvf-video {
@@ -2729,38 +2619,12 @@ export class WebPlayer extends BasePlayer {
2729
2619
  /* Ensure hardware acceleration */
2730
2620
  -webkit-transform: translateZ(0);
2731
2621
  transform: translateZ(0);
2732
-
2733
- /* Full viewport video with proper centering */
2734
- width: 100%;
2735
- height: 100%;
2736
- object-fit: contain;
2737
- object-position: center center;
2738
2622
  }
2739
2623
 
2740
2624
  /* Fix for controls being cut off by virtual keyboard */
2741
2625
  .uvf-controls-bar {
2742
2626
  position: fixed !important;
2743
2627
  bottom: var(--uvf-safe-area-bottom, 0) !important;
2744
- left: var(--uvf-safe-area-left, 0) !important;
2745
- right: var(--uvf-safe-area-right, 0) !important;
2746
- width: auto !important;
2747
- z-index: 9999;
2748
- }
2749
-
2750
- /* Top controls safe area positioning */
2751
- .uvf-top-controls {
2752
- position: fixed !important;
2753
- top: var(--uvf-safe-area-top, 10px) !important;
2754
- right: var(--uvf-safe-area-right, 10px) !important;
2755
- z-index: 9999;
2756
- }
2757
-
2758
- .uvf-title-bar {
2759
- position: fixed !important;
2760
- top: var(--uvf-safe-area-top, 10px) !important;
2761
- left: var(--uvf-safe-area-left, 10px) !important;
2762
- right: calc(120px + var(--uvf-safe-area-right, 10px)) !important; /* Leave space for top controls */
2763
- z-index: 9999;
2764
2628
  }
2765
2629
 
2766
2630
  /* Ensure controls stay above virtual keyboards */
@@ -2769,127 +2633,160 @@ export class WebPlayer extends BasePlayer {
2769
2633
  bottom: max(var(--uvf-safe-area-bottom, 0), env(keyboard-inset-height, 0)) !important;
2770
2634
  }
2771
2635
  }
2772
-
2773
- /* Enhanced safe area support for newer devices */
2774
- @supports (padding: max(0px)) {
2775
- .uvf-controls-bar {
2776
- padding-bottom: max(16px, calc(16px + var(--uvf-safe-area-bottom, 0)));
2777
- padding-left: max(12px, calc(12px + var(--uvf-safe-area-left, 0)));
2778
- padding-right: max(12px, calc(12px + var(--uvf-safe-area-right, 0)));
2779
- }
2780
-
2781
- .uvf-top-controls {
2782
- top: max(10px, calc(10px + var(--uvf-safe-area-top, 0))) !important;
2783
- right: max(10px, calc(10px + var(--uvf-safe-area-right, 0))) !important;
2784
- }
2785
-
2786
- .uvf-title-bar {
2787
- top: max(10px, calc(10px + var(--uvf-safe-area-top, 0))) !important;
2788
- left: max(10px, calc(10px + var(--uvf-safe-area-left, 0))) !important;
2789
- }
2790
- }
2791
2636
  }
2792
2637
 
2793
- /* Specific fixes for iPhone X series and newer with notches */
2794
- @media screen and (max-width: 767px) and (orientation: portrait) {
2795
- @supports (top: env(safe-area-inset-top)) {
2796
- .uvf-responsive-container,
2797
- .uvf-player-wrapper,
2798
- .uvf-video-container {
2799
- height: 100vh;
2800
- height: calc(100vh - env(safe-area-inset-top) - env(safe-area-inset-bottom));
2801
- }
2802
- }
2803
- }
2804
-
2805
- /* Landscape orientation fixes for mobile */
2806
- @media screen and (max-width: 767px) and (orientation: landscape) {
2807
- html, body {
2808
- height: 100vh;
2809
- overflow: hidden;
2810
- }
2811
-
2812
- .uvf-responsive-container,
2813
- .uvf-player-wrapper,
2814
- .uvf-video-container {
2815
- height: 100vh;
2816
- width: 100vw;
2817
- }
2818
-
2819
- @supports (height: 100dvh) {
2820
- .uvf-responsive-container,
2821
- .uvf-player-wrapper,
2822
- .uvf-video-container {
2823
- height: 100dvh;
2824
- width: 100dvw;
2825
- }
2826
- }
2827
- }
2638
+ /* Mobile-First Responsive Video Player Layout */
2828
2639
 
2829
- /* Enhanced Responsive Media Queries with UX Best Practices */
2830
- /* Mobile devices (portrait) - Enhanced UX with Safe Areas */
2831
- @media screen and (max-width: 767px) and (orientation: portrait) {
2640
+ /* Mobile devices (all orientations) - Base mobile styles */
2641
+ @media screen and (max-width: 767px) {
2642
+ /* Force full viewport usage with proper safe area handling */
2832
2643
  .uvf-responsive-container {
2833
- padding: 0;
2644
+ position: fixed !important;
2645
+ top: 0;
2646
+ left: 0;
2834
2647
  width: 100vw !important;
2835
- height: calc(100vh - var(--uvf-safe-area-top) - var(--uvf-safe-area-bottom));
2648
+ height: 100vh !important;
2649
+ height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
2836
2650
  margin: 0;
2837
- position: relative;
2651
+ padding: 0;
2838
2652
  overflow: hidden;
2653
+ z-index: 1000;
2839
2654
  }
2840
2655
 
2656
+ /* Modern viewport support */
2841
2657
  @supports (height: 100dvh) {
2842
2658
  .uvf-responsive-container {
2843
- height: calc(100dvh - var(--uvf-safe-area-top) - var(--uvf-safe-area-bottom));
2659
+ height: 100dvh !important;
2660
+ height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
2844
2661
  }
2845
2662
  }
2846
2663
 
2664
+ /* Player wrapper fills container completely */
2847
2665
  .uvf-responsive-container .uvf-player-wrapper {
2848
- width: 100vw !important;
2666
+ position: absolute;
2667
+ top: 0;
2668
+ left: 0;
2669
+ width: 100% !important;
2849
2670
  height: 100% !important;
2850
- min-height: calc(100vh - var(--uvf-safe-area-top) - var(--uvf-safe-area-bottom));
2851
- }
2852
-
2853
- @supports (height: 100dvh) {
2854
- .uvf-responsive-container .uvf-player-wrapper {
2855
- min-height: calc(100dvh - var(--uvf-safe-area-top) - var(--uvf-safe-area-bottom));
2856
- }
2671
+ max-width: none;
2672
+ max-height: none;
2673
+ display: flex;
2674
+ flex-direction: column;
2857
2675
  }
2858
2676
 
2677
+ /* Video container optimized for mobile centering */
2859
2678
  .uvf-responsive-container .uvf-video-container {
2860
- width: 100vw !important;
2679
+ position: relative;
2680
+ width: 100% !important;
2861
2681
  height: 100% !important;
2682
+ flex: 1;
2862
2683
  aspect-ratio: unset !important;
2863
- min-height: inherit;
2684
+ display: flex;
2685
+ align-items: center;
2686
+ justify-content: center;
2687
+ background: #000;
2688
+ overflow: hidden;
2689
+ }
2690
+
2691
+ /* Perfectly centered mobile video */
2692
+ .uvf-responsive-container .uvf-video {
2693
+ position: relative;
2694
+ display: block;
2695
+ width: 100%;
2696
+ height: 100%;
2697
+ max-width: 100%;
2698
+ max-height: 100%;
2699
+ object-fit: contain;
2700
+ object-position: center center;
2701
+ background: transparent;
2864
2702
  }
2865
2703
 
2866
- /* Enhanced mobile controls bar with safe area padding */
2704
+ /* Mobile controls positioned with safe areas */
2867
2705
  .uvf-controls-bar {
2868
- position: absolute;
2869
- bottom: 0;
2870
- left: 0;
2871
- right: 0;
2872
- padding: 16px 12px;
2873
- padding-bottom: calc(16px + var(--uvf-safe-area-bottom));
2874
- padding-left: calc(12px + var(--uvf-safe-area-left));
2875
- padding-right: calc(12px + var(--uvf-safe-area-right));
2876
- background: linear-gradient(to top, var(--uvf-overlay-strong) 0%, var(--uvf-overlay-medium) 80%, var(--uvf-overlay-transparent) 100%);
2706
+ position: absolute !important;
2707
+ bottom: env(safe-area-inset-bottom, 0px);
2708
+ left: env(safe-area-inset-left, 0px);
2709
+ right: env(safe-area-inset-right, 0px);
2710
+ width: auto;
2711
+ padding: 16px;
2712
+ padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
2713
+ padding-left: calc(16px + env(safe-area-inset-left, 0px));
2714
+ padding-right: calc(16px + env(safe-area-inset-right, 0px));
2715
+ background: linear-gradient(to top, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.6) 70%, transparent 100%);
2716
+ backdrop-filter: blur(10px);
2717
+ -webkit-backdrop-filter: blur(10px);
2877
2718
  box-sizing: border-box;
2878
- z-index: 1000;
2719
+ z-index: 2000;
2720
+ opacity: 1;
2721
+ transform: none;
2722
+ }
2723
+
2724
+ /* Top controls with safe area */
2725
+ .uvf-top-controls {
2726
+ position: absolute !important;
2727
+ top: calc(16px + env(safe-area-inset-top, 0px));
2728
+ right: calc(16px + env(safe-area-inset-right, 0px));
2729
+ z-index: 2000;
2730
+ }
2731
+
2732
+ /* Title bar with safe area */
2733
+ .uvf-title-bar {
2734
+ position: absolute !important;
2735
+ top: calc(16px + env(safe-area-inset-top, 0px));
2736
+ left: calc(16px + env(safe-area-inset-left, 0px));
2737
+ right: calc(120px + env(safe-area-inset-right, 0px));
2738
+ z-index: 2000;
2879
2739
  }
2740
+ }
2741
+
2742
+ /* Mobile Portrait - Optimized vertical layout */
2743
+ @media screen and (max-width: 767px) and (orientation: portrait) {
2880
2744
 
2881
2745
  .uvf-progress-section {
2882
2746
  margin-bottom: 16px;
2883
2747
  }
2884
2748
 
2885
- /* Mobile-first responsive controls layout */
2749
+ /* Mobile-optimized controls layout */
2886
2750
  .uvf-controls-row {
2887
- gap: 8px;
2888
- flex-wrap: nowrap;
2751
+ display: flex;
2889
2752
  align-items: center;
2890
2753
  justify-content: space-between;
2891
- position: relative;
2892
2754
  width: 100%;
2755
+ gap: 12px;
2756
+ flex-wrap: nowrap;
2757
+ position: relative;
2758
+ min-height: 52px;
2759
+ }
2760
+
2761
+ /* Ensure controls are always visible */
2762
+ .uvf-controls-row > * {
2763
+ flex-shrink: 0;
2764
+ display: flex;
2765
+ align-items: center;
2766
+ }
2767
+
2768
+ /* Control groups with proper flex behavior */
2769
+ .uvf-left-controls {
2770
+ display: flex;
2771
+ align-items: center;
2772
+ gap: 8px;
2773
+ flex: 0 0 auto;
2774
+ }
2775
+
2776
+ .uvf-center-controls {
2777
+ display: flex;
2778
+ align-items: center;
2779
+ gap: 8px;
2780
+ flex: 1 1 auto;
2781
+ justify-content: center;
2782
+ min-width: 0;
2783
+ }
2784
+
2785
+ .uvf-right-controls {
2786
+ display: flex !important;
2787
+ align-items: center;
2788
+ gap: 8px;
2789
+ flex: 0 0 auto;
2893
2790
  }
2894
2791
 
2895
2792
  /* Left side controls group */
@@ -3017,26 +2914,68 @@ export class WebPlayer extends BasePlayer {
3017
2914
  display: none !important;
3018
2915
  }
3019
2916
 
3020
- /* Settings menu - hidden by default, accessible via menu */
2917
+ /* Enhanced mobile settings menu */
3021
2918
  .uvf-settings-menu {
3022
- min-width: 160px;
3023
- bottom: 60px;
3024
- right: 12px;
2919
+ position: fixed !important;
2920
+ bottom: calc(80px + env(safe-area-inset-bottom, 0px));
2921
+ right: calc(16px + env(safe-area-inset-right, 0px));
2922
+ min-width: 200px;
2923
+ max-width: 280px;
2924
+ max-height: 60vh;
2925
+ background: rgba(0,0,0,0.95);
2926
+ backdrop-filter: blur(20px);
2927
+ -webkit-backdrop-filter: blur(20px);
2928
+ border: 1px solid rgba(255,255,255,0.2);
2929
+ border-radius: 12px;
2930
+ box-shadow: 0 10px 40px rgba(0,0,0,0.3);
2931
+ z-index: 3000;
2932
+ overflow: hidden;
3025
2933
  font-size: 14px;
3026
- max-height: 50vh;
2934
+ opacity: 0;
2935
+ transform: translateY(10px) scale(0.95);
2936
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
2937
+ pointer-events: none;
2938
+ }
2939
+
2940
+ .uvf-settings-menu.active {
2941
+ opacity: 1;
2942
+ transform: translateY(0) scale(1);
2943
+ pointer-events: auto;
3027
2944
  }
3028
2945
 
2946
+ /* Touch-optimized settings options */
3029
2947
  .uvf-settings-option {
3030
- padding: 12px 16px;
3031
- font-size: 14px;
3032
- min-height: 44px;
2948
+ padding: 16px 20px;
2949
+ font-size: 16px;
2950
+ min-height: 56px;
3033
2951
  display: flex;
3034
2952
  align-items: center;
2953
+ cursor: pointer;
2954
+ transition: all 0.2s ease;
2955
+ border: none;
2956
+ background: transparent;
2957
+ color: #fff;
2958
+ width: 100%;
2959
+ text-align: left;
3035
2960
  }
3036
2961
 
3037
- .uvf-settings-option:hover {
2962
+ .uvf-settings-option:hover,
2963
+ .uvf-settings-option:focus {
3038
2964
  background: rgba(255,255,255,0.15);
3039
- padding-left: 20px;
2965
+ }
2966
+
2967
+ .uvf-settings-option.active {
2968
+ background: rgba(255,77,79,0.2);
2969
+ color: #ff4d4f;
2970
+ }
2971
+
2972
+ /* Settings groups with proper spacing */
2973
+ .uvf-settings-group {
2974
+ border-bottom: 1px solid rgba(255,255,255,0.1);
2975
+ }
2976
+
2977
+ .uvf-settings-group:last-child {
2978
+ border-bottom: none;
3040
2979
  }
3041
2980
 
3042
2981
  /* Simplified settings - hide complex options */
@@ -3177,11 +3116,46 @@ export class WebPlayer extends BasePlayer {
3177
3116
  display: block;
3178
3117
  }
3179
3118
 
3119
+ /* Ensure settings button is always visible and functional */
3120
+ #uvf-settings-btn {
3121
+ display: flex !important;
3122
+ align-items: center;
3123
+ justify-content: center;
3124
+ width: 44px;
3125
+ height: 44px;
3126
+ min-width: 44px;
3127
+ min-height: 44px;
3128
+ background: rgba(255,255,255,0.15);
3129
+ backdrop-filter: blur(8px);
3130
+ border: 1px solid rgba(255,255,255,0.2);
3131
+ border-radius: 22px;
3132
+ transition: all 0.2s ease;
3133
+ }
3134
+
3135
+ #uvf-settings-btn:hover {
3136
+ background: rgba(255,255,255,0.25);
3137
+ transform: scale(1.05);
3138
+ }
3139
+
3140
+ #uvf-settings-btn svg {
3141
+ width: 20px;
3142
+ height: 20px;
3143
+ fill: #fff;
3144
+ }
3145
+
3180
3146
  /* Essential controls in right section - Settings, PiP, and Fullscreen only */
3181
3147
  .uvf-right-controls > *:not(#uvf-settings-btn):not(#uvf-fullscreen-btn):not(#uvf-pip-btn) {
3182
3148
  display: none;
3183
3149
  }
3184
3150
 
3151
+ /* Make sure right controls are properly spaced */
3152
+ .uvf-right-controls {
3153
+ display: flex;
3154
+ align-items: center;
3155
+ gap: 8px;
3156
+ flex-shrink: 0;
3157
+ }
3158
+
3185
3159
  /* Hide skip buttons on small mobile devices to save space */
3186
3160
  @media screen and (max-width: 480px) {
3187
3161
  #uvf-skip-back,
@@ -4136,13 +4110,7 @@ export class WebPlayer extends BasePlayer {
4136
4110
  pipBtn.id = 'uvf-pip-btn';
4137
4111
  pipBtn.title = 'Picture-in-Picture';
4138
4112
  pipBtn.innerHTML = '<svg viewBox="0 0 24 24"><path d="M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h18v14z"/></svg>';
4139
- if (this.isPictureInPictureSupported()) {
4140
- rightControls.appendChild(pipBtn);
4141
- this.debugLog('PiP button added - support detected');
4142
- }
4143
- else {
4144
- this.debugLog('PiP button not added - no support detected');
4145
- }
4113
+ rightControls.appendChild(pipBtn);
4146
4114
  const fullscreenBtn = document.createElement('button');
4147
4115
  fullscreenBtn.className = 'uvf-control-btn';
4148
4116
  fullscreenBtn.id = 'uvf-fullscreen-btn';
@@ -5255,41 +5223,17 @@ export class WebPlayer extends BasePlayer {
5255
5223
  this.setAutoQuality(true);
5256
5224
  }
5257
5225
  }
5258
- isPictureInPictureActive() {
5259
- const inStandardPiP = !!document.pictureInPictureElement;
5260
- const inWebkitPiP = !!(this.video &&
5261
- 'webkitPresentationMode' in this.video &&
5262
- this.video.webkitPresentationMode === 'picture-in-picture');
5263
- return inStandardPiP || inWebkitPiP;
5264
- }
5265
5226
  async togglePiP() {
5266
- if (!this.isPictureInPictureSupported()) {
5267
- this.showShortcutIndicator('PiP not supported');
5268
- this.debugWarn('PiP not supported on this device/browser');
5269
- return;
5270
- }
5271
5227
  try {
5272
- if (this.isPictureInPictureActive()) {
5228
+ if (document.pictureInPictureElement) {
5273
5229
  await this.exitPictureInPicture();
5274
- this.showShortcutIndicator('Exit PiP');
5275
- this.debugLog('PiP deactivated');
5276
5230
  }
5277
5231
  else {
5278
5232
  await this.enterPictureInPicture();
5279
- this.showShortcutIndicator('Enter PiP');
5280
- this.debugLog('PiP activated');
5281
5233
  }
5282
5234
  }
5283
5235
  catch (error) {
5284
- const errorMessage = error.message;
5285
- this.showShortcutIndicator(`PiP Error: ${errorMessage}`);
5286
- this.debugError('PiP toggle failed:', errorMessage);
5287
- if (errorMessage.includes('not supported')) {
5288
- this.showShortcutIndicator('PiP not supported');
5289
- }
5290
- else if (errorMessage.includes('user gesture')) {
5291
- this.showShortcutIndicator('PiP requires user interaction');
5292
- }
5236
+ console.error('PiP toggle failed:', error);
5293
5237
  }
5294
5238
  }
5295
5239
  setupCastContextSafe() {