unified-video-framework 1.4.455 → 1.4.457

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.
@@ -216,6 +216,9 @@ export class WebPlayer extends BasePlayer {
216
216
  private currentThumbnailUrl: string | null = null;
217
217
  private thumbnailPreviewEnabled: boolean = false;
218
218
 
219
+ // YouTube custom controls mode tracking
220
+ private isYouTubeCustomControlsMode: boolean = false;
221
+
219
222
  // Debug logging helper
220
223
  private debugLog(message: string, ...args: any[]): void {
221
224
  if (this.config.debug) {
@@ -1646,6 +1649,9 @@ export class WebPlayer extends BasePlayer {
1646
1649
 
1647
1650
  private async loadYouTube(url: string, source: any): Promise<void> {
1648
1651
  try {
1652
+ // Reset YouTube custom controls mode flag when loading new video
1653
+ this.isYouTubeCustomControlsMode = false;
1654
+
1649
1655
  this.debugLog('Loading YouTube video:', url);
1650
1656
 
1651
1657
  // Extract video ID and fetch metadata
@@ -1737,22 +1743,30 @@ export class WebPlayer extends BasePlayer {
1737
1743
 
1738
1744
  // Different behavior based on mode
1739
1745
  if (!this.youtubeNativeControls) {
1740
- // Full blocking mode - block all YouTube controls
1741
- // Note: Don't set height inline - let CSS class .uvf-youtube-overlay handle it
1742
- // CSS sets height: calc(100% - 60px) normally, and 100% when not hovered
1746
+ // Custom controls mode - overlay doesn't cover controls area
1743
1747
  overlay.style.cssText = `
1744
1748
  position: absolute;
1745
1749
  top: 0;
1746
1750
  left: 0;
1747
1751
  width: 100%;
1752
+ height: calc(100% - 120px);
1748
1753
  z-index: 2;
1749
- pointer-events: auto;
1754
+ background: transparent;
1755
+ pointer-events: none;
1750
1756
  cursor: pointer;
1751
1757
  `;
1752
1758
 
1753
- // Handle click to toggle play/pause
1759
+ // Add click handler directly to the overlay since pointer-events is none
1760
+ // This allows video clicks while controls remain interactive
1754
1761
  overlay.addEventListener('click', () => {
1755
- this.togglePlayPause();
1762
+ if (this.youtubePlayer && this.youtubePlayerReady) {
1763
+ const state = this.youtubePlayer.getPlayerState();
1764
+ if (state === 1) { // Playing
1765
+ this.youtubePlayer.pauseVideo();
1766
+ } else {
1767
+ this.youtubePlayer.playVideo();
1768
+ }
1769
+ }
1756
1770
  });
1757
1771
 
1758
1772
  // Handle double-click for fullscreen
@@ -1894,11 +1908,38 @@ export class WebPlayer extends BasePlayer {
1894
1908
  this.debugLog('[YouTube] Hybrid mode - both YouTube native controls and custom controls enabled');
1895
1909
  } else if (!this.youtubeNativeControls && this.useCustomControls && this.playerWrapper) {
1896
1910
  // Custom controls only mode - ensure custom controls are visible
1897
- this.debugLog('[YouTube] Custom controls only mode - showing custom controls, hiding YouTube native controls');
1911
+ this.debugLog('[YouTube] Custom controls only mode - ensuring controls are visible');
1898
1912
  this.playerWrapper.classList.remove('youtube-native-controls-mode');
1899
1913
  this.playerWrapper.classList.add('youtube-custom-controls-mode');
1900
1914
  this.playerWrapper.classList.add('controls-visible');
1915
+
1916
+ // Prevent auto-hide from interfering
1917
+ this.isYouTubeCustomControlsMode = true;
1918
+
1919
+ // Force show controls with explicit visibility
1901
1920
  this.showCustomControls();
1921
+
1922
+ // Additionally, force controls visibility with inline styles for YouTube
1923
+ const controlsBar = document.getElementById('uvf-controls') as HTMLElement;
1924
+ if (controlsBar) {
1925
+ controlsBar.style.display = 'flex';
1926
+ controlsBar.style.visibility = 'visible';
1927
+ controlsBar.style.opacity = '1';
1928
+ controlsBar.style.pointerEvents = 'auto';
1929
+ controlsBar.style.zIndex = '100';
1930
+ controlsBar.style.position = 'relative'; // Ensure proper stacking context
1931
+ }
1932
+
1933
+ const topBar = document.querySelector('.uvf-top-bar') as HTMLElement;
1934
+ if (topBar) {
1935
+ topBar.style.display = 'flex';
1936
+ topBar.style.visibility = 'visible';
1937
+ topBar.style.opacity = '1';
1938
+ topBar.style.pointerEvents = 'auto';
1939
+ topBar.style.zIndex = '100';
1940
+ }
1941
+
1942
+ this.debugLog('[YouTube] Custom controls forced visible, auto-hide disabled');
1902
1943
  } else if (!this.youtubeNativeControls && !this.useCustomControls && this.playerWrapper) {
1903
1944
  // No controls mode - both YouTube native and custom controls are hidden
1904
1945
  this.debugLog('[YouTube] No controls mode - all controls hidden');
@@ -1906,6 +1947,48 @@ export class WebPlayer extends BasePlayer {
1906
1947
  this.hideCustomControls();
1907
1948
  }
1908
1949
 
1950
+ // Debug: Log control visibility state after YouTube loads
1951
+ setTimeout(() => {
1952
+ const controlsBar = document.getElementById('uvf-controls');
1953
+ const wrapper = this.playerWrapper;
1954
+ const overlay = wrapper?.querySelector('.uvf-youtube-overlay') as HTMLElement;
1955
+
1956
+ if (this.config.debug) {
1957
+ console.log('[YouTube Debug] Control visibility check:');
1958
+ console.log('- youtubeNativeControls:', this.youtubeNativeControls);
1959
+ console.log('- useCustomControls:', this.useCustomControls);
1960
+ console.log('- isYouTubeCustomControlsMode:', this.isYouTubeCustomControlsMode);
1961
+
1962
+ if (wrapper) {
1963
+ console.log('- Wrapper classes:', wrapper.className);
1964
+ }
1965
+
1966
+ if (controlsBar) {
1967
+ const rect = controlsBar.getBoundingClientRect();
1968
+ const style = window.getComputedStyle(controlsBar);
1969
+ console.log('- Controls bar:');
1970
+ console.log(' - Display:', style.display);
1971
+ console.log(' - Visibility:', style.visibility);
1972
+ console.log(' - Opacity:', style.opacity);
1973
+ console.log(' - Z-index:', style.zIndex);
1974
+ console.log(' - Pointer-events:', style.pointerEvents);
1975
+ console.log(' - Position:', style.position);
1976
+ console.log(' - Dimensions:', { width: rect.width, height: rect.height });
1977
+ console.log(' - Position:', { top: rect.top, left: rect.left, bottom: rect.bottom });
1978
+ }
1979
+
1980
+ if (overlay) {
1981
+ const overlayRect = overlay.getBoundingClientRect();
1982
+ const overlayStyle = window.getComputedStyle(overlay);
1983
+ console.log('- YouTube overlay:');
1984
+ console.log(' - Height:', overlayStyle.height);
1985
+ console.log(' - Pointer-events:', overlayStyle.pointerEvents);
1986
+ console.log(' - Z-index:', overlayStyle.zIndex);
1987
+ console.log(' - Bottom position:', overlayRect.bottom);
1988
+ }
1989
+ }
1990
+ }, 500);
1991
+
1909
1992
  // Set initial volume
1910
1993
  if (this.youtubePlayer) {
1911
1994
  const volume = this.config.volume ? this.config.volume * 100 : 100;
@@ -8863,6 +8946,86 @@ export class WebPlayer extends BasePlayer {
8863
8946
  transform: scale(1) !important;
8864
8947
  }
8865
8948
 
8949
+ /* Force YouTube custom controls visible even with no-cursor class */
8950
+ .uvf-player-wrapper.youtube-custom-controls-mode.no-cursor .uvf-controls-bar,
8951
+ .uvf-player-wrapper.youtube-custom-controls-mode .uvf-controls-bar {
8952
+ display: flex !important;
8953
+ visibility: visible !important;
8954
+ pointer-events: auto !important;
8955
+ opacity: 1 !important;
8956
+ transform: translateY(0) !important;
8957
+ }
8958
+
8959
+ .uvf-player-wrapper.youtube-custom-controls-mode.no-cursor .uvf-top-bar,
8960
+ .uvf-player-wrapper.youtube-custom-controls-mode .uvf-top-bar {
8961
+ display: flex !important;
8962
+ visibility: visible !important;
8963
+ pointer-events: auto !important;
8964
+ opacity: 1 !important;
8965
+ transform: translateY(0) !important;
8966
+ }
8967
+
8968
+ .uvf-player-wrapper.youtube-custom-controls-mode.no-cursor .uvf-top-gradient,
8969
+ .uvf-player-wrapper.youtube-custom-controls-mode .uvf-top-gradient {
8970
+ opacity: 1 !important;
8971
+ }
8972
+
8973
+ .uvf-player-wrapper.youtube-custom-controls-mode.no-cursor .uvf-controls-gradient,
8974
+ .uvf-player-wrapper.youtube-custom-controls-mode .uvf-controls-gradient {
8975
+ opacity: 1 !important;
8976
+ }
8977
+
8978
+ .uvf-player-wrapper.youtube-custom-controls-mode.no-cursor .uvf-center-play-container,
8979
+ .uvf-player-wrapper.youtube-custom-controls-mode .uvf-center-play-container {
8980
+ display: flex !important;
8981
+ visibility: visible !important;
8982
+ pointer-events: auto !important;
8983
+ opacity: 1 !important;
8984
+ transform: scale(1) !important;
8985
+ }
8986
+
8987
+ .uvf-player-wrapper.youtube-custom-controls-mode.no-cursor {
8988
+ cursor: default !important;
8989
+ }
8990
+
8991
+ /* Ensure YouTube overlay doesn't block controls in custom mode */
8992
+ .uvf-player-wrapper.youtube-custom-controls-mode .uvf-youtube-overlay {
8993
+ height: calc(100% - 120px) !important;
8994
+ pointer-events: none !important;
8995
+ }
8996
+
8997
+ /* Ensure controls bar is positioned correctly and visible */
8998
+ .uvf-player-wrapper.youtube-custom-controls-mode .uvf-controls-bar {
8999
+ position: relative !important;
9000
+ bottom: 0 !important;
9001
+ left: 0 !important;
9002
+ right: 0 !important;
9003
+ z-index: 100 !important;
9004
+ display: flex !important;
9005
+ visibility: visible !important;
9006
+ pointer-events: auto !important;
9007
+ opacity: 1 !important;
9008
+ transform: translateY(0) !important;
9009
+ }
9010
+
9011
+ /* Ensure top bar is visible in YouTube custom mode */
9012
+ .uvf-player-wrapper.youtube-custom-controls-mode .uvf-top-bar {
9013
+ position: relative !important;
9014
+ z-index: 100 !important;
9015
+ display: flex !important;
9016
+ visibility: visible !important;
9017
+ pointer-events: auto !important;
9018
+ opacity: 1 !important;
9019
+ transform: translateY(0) !important;
9020
+ }
9021
+
9022
+ /* Force all control buttons to be interactive */
9023
+ .uvf-player-wrapper.youtube-custom-controls-mode .uvf-control-btn {
9024
+ pointer-events: auto !important;
9025
+ cursor: pointer !important;
9026
+ z-index: 101 !important;
9027
+ }
9028
+
8866
9029
  /* Override any inline styles */
8867
9030
  .controls-disabled .uvf-controls-bar,
8868
9031
  .controls-disabled .uvf-top-bar,
@@ -10755,6 +10918,11 @@ export class WebPlayer extends BasePlayer {
10755
10918
  private hideControls(): void {
10756
10919
  if (!this.state.isPlaying) return;
10757
10920
 
10921
+ // Don't hide controls in YouTube custom mode
10922
+ if (this.isYouTubeCustomControlsMode) {
10923
+ return;
10924
+ }
10925
+
10758
10926
  const wrapper = this.container?.querySelector('.uvf-player-wrapper');
10759
10927
  if (wrapper) {
10760
10928
  wrapper.classList.remove('controls-visible');
@@ -10765,6 +10933,11 @@ export class WebPlayer extends BasePlayer {
10765
10933
  private scheduleHideControls(): void {
10766
10934
  if (!this.state.isPlaying) return;
10767
10935
 
10936
+ // Don't auto-hide in YouTube custom controls mode
10937
+ if (this.isYouTubeCustomControlsMode) {
10938
+ return;
10939
+ }
10940
+
10768
10941
  if (this.hideControlsTimeout) clearTimeout(this.hideControlsTimeout);
10769
10942
  // Use longer timeout in fullscreen for better UX
10770
10943
  const timeout = this.isFullscreen() ? 4000 : 3000;