unified-video-framework 1.4.244 → 1.4.246

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.
@@ -1176,14 +1176,15 @@ export class WebPlayer extends BasePlayer {
1176
1176
  height: '100%',
1177
1177
  playerVars: {
1178
1178
  controls: 0, // Hide YouTube controls
1179
- disablekb: 1, // Disable keyboard controls
1179
+ disablekb: 0, // Allow keyboard controls
1180
1180
  fs: 0, // Hide fullscreen button
1181
1181
  iv_load_policy: 3, // Hide annotations
1182
1182
  modestbranding: 1, // Minimal YouTube branding
1183
1183
  rel: 0, // Don't show related videos
1184
1184
  showinfo: 0, // Hide video info
1185
1185
  autoplay: this.config.autoPlay ? 1 : 0,
1186
- mute: this.config.muted ? 1 : 0
1186
+ mute: this.config.muted ? 1 : 0,
1187
+ widget_referrer: window.location.href // Hide YouTube recommendations
1187
1188
  },
1188
1189
  events: {
1189
1190
  onReady: () => this.onYouTubePlayerReady(),
@@ -6222,6 +6223,28 @@ export class WebPlayer extends BasePlayer {
6222
6223
  }
6223
6224
  }
6224
6225
 
6226
+ /* Hide YouTube UI elements */
6227
+ iframe[src*="youtube.com"] {
6228
+ pointer-events: auto !important;
6229
+ }
6230
+
6231
+ /* Hide YouTube title, logo, and controls overlay */
6232
+ .ytp-chrome-top,
6233
+ .ytp-chrome-bottom,
6234
+ .ytp-watermark,
6235
+ .ytp-gradient-top,
6236
+ .ytp-gradient-bottom,
6237
+ .ytp-show-cards-title,
6238
+ .ytp-cards-teaser,
6239
+ .ytp-endscreen-element,
6240
+ .ytp-ce-element,
6241
+ .ytp-suggested-action,
6242
+ .ytp-pause-overlay {
6243
+ display: none !important;
6244
+ visibility: hidden !important;
6245
+ opacity: 0 !important;
6246
+ }
6247
+
6225
6248
  /* Ultra-wide screens */
6226
6249
  @media screen and (min-width: 1440px) {
6227
6250
  .uvf-video-title {
@@ -6877,15 +6900,21 @@ export class WebPlayer extends BasePlayer {
6877
6900
  }
6878
6901
  });
6879
6902
 
6880
- // Skip buttons with null safety
6903
+ // Skip buttons with null safety - works with both video and YouTube
6881
6904
  skipBackBtn?.addEventListener('click', () => {
6882
- if (this.video && !isNaN(this.video.duration)) {
6883
- this.seek(Math.max(0, this.video.currentTime - 10));
6905
+ const currentTime = this.getCurrentTime();
6906
+ const duration = this.getDuration();
6907
+ if (!isNaN(duration) && duration > 0) {
6908
+ this.seek(Math.max(0, currentTime - 10));
6909
+ this.showShortcutIndicator('-10s');
6884
6910
  }
6885
6911
  });
6886
6912
  skipForwardBtn?.addEventListener('click', () => {
6887
- if (this.video && !isNaN(this.video.duration)) {
6888
- this.seek(Math.min(this.video.duration, this.video.currentTime + 10));
6913
+ const currentTime = this.getCurrentTime();
6914
+ const duration = this.getDuration();
6915
+ if (!isNaN(duration) && duration > 0) {
6916
+ this.seek(Math.min(duration, currentTime + 10));
6917
+ this.showShortcutIndicator('+10s');
6889
6918
  }
6890
6919
  });
6891
6920
 
@@ -7345,45 +7374,61 @@ export class WebPlayer extends BasePlayer {
7345
7374
  case 'ArrowLeft':
7346
7375
  e.preventDefault();
7347
7376
  e.stopImmediatePropagation(); // Prevent duplicate handler triggers
7348
- if (this.video && !isNaN(this.video.duration)) {
7349
- this.seek(Math.max(0, this.video.currentTime - 10));
7377
+ const currentTime = this.getCurrentTime();
7378
+ const duration = this.getDuration();
7379
+ if (!isNaN(duration) && duration > 0) {
7380
+ this.seek(Math.max(0, currentTime - 10));
7350
7381
  shortcutText = '-10s';
7351
7382
  }
7352
7383
  break;
7353
7384
  case 'ArrowRight':
7354
7385
  e.preventDefault();
7355
7386
  e.stopImmediatePropagation(); // Prevent duplicate handler triggers
7356
- if (this.video && !isNaN(this.video.duration)) {
7357
- this.seek(Math.min(this.video.duration, this.video.currentTime + 10));
7387
+ const currentTimeRight = this.getCurrentTime();
7388
+ const durationRight = this.getDuration();
7389
+ if (!isNaN(durationRight) && durationRight > 0) {
7390
+ this.seek(Math.min(durationRight, currentTimeRight + 10));
7358
7391
  shortcutText = '+10s';
7359
7392
  }
7360
7393
  break;
7361
7394
  case 'ArrowUp':
7362
7395
  e.preventDefault();
7363
7396
  this.changeVolume(0.1);
7364
- if (this.isCasting && this.remotePlayer) {
7365
- shortcutText = `Volume ${Math.round(((this.remotePlayer.volumeLevel || 0) * 100))}%`;
7397
+ let volumeUp = 0;
7398
+ if (this.youtubePlayer && this.youtubePlayerReady) {
7399
+ volumeUp = this.youtubePlayer.getVolume();
7400
+ } else if (this.isCasting && this.remotePlayer) {
7401
+ volumeUp = (this.remotePlayer.volumeLevel || 0) * 100;
7366
7402
  } else {
7367
- shortcutText = `Volume ${Math.round((this.video?.volume || 0) * 100)}%`;
7403
+ volumeUp = (this.video?.volume || 0) * 100;
7368
7404
  }
7405
+ shortcutText = `Volume ${Math.round(volumeUp)}%`;
7369
7406
  break;
7370
7407
  case 'ArrowDown':
7371
7408
  e.preventDefault();
7372
7409
  this.changeVolume(-0.1);
7373
- if (this.isCasting && this.remotePlayer) {
7374
- shortcutText = `Volume ${Math.round(((this.remotePlayer.volumeLevel || 0) * 100))}%`;
7410
+ let volumeDown = 0;
7411
+ if (this.youtubePlayer && this.youtubePlayerReady) {
7412
+ volumeDown = this.youtubePlayer.getVolume();
7413
+ } else if (this.isCasting && this.remotePlayer) {
7414
+ volumeDown = (this.remotePlayer.volumeLevel || 0) * 100;
7375
7415
  } else {
7376
- shortcutText = `Volume ${Math.round((this.video?.volume || 0) * 100)}%`;
7416
+ volumeDown = (this.video?.volume || 0) * 100;
7377
7417
  }
7418
+ shortcutText = `Volume ${Math.round(volumeDown)}%`;
7378
7419
  break;
7379
7420
  case 'm':
7380
7421
  e.preventDefault();
7381
7422
  this.toggleMuteAction();
7382
- if (this.isCasting && this.remotePlayer) {
7383
- shortcutText = this.remotePlayer.isMuted ? 'Muted' : 'Unmuted';
7423
+ let isMuted = false;
7424
+ if (this.youtubePlayer && this.youtubePlayerReady) {
7425
+ isMuted = this.youtubePlayer.isMuted();
7426
+ } else if (this.isCasting && this.remotePlayer) {
7427
+ isMuted = this.remotePlayer.isMuted;
7384
7428
  } else {
7385
- shortcutText = this.video?.muted ? 'Muted' : 'Unmuted';
7429
+ isMuted = this.video?.muted || false;
7386
7430
  }
7431
+ shortcutText = isMuted ? 'Muted' : 'Unmuted';
7387
7432
  break;
7388
7433
  case 'f':
7389
7434
  e.preventDefault();
@@ -7422,9 +7467,11 @@ export class WebPlayer extends BasePlayer {
7422
7467
  case '9':
7423
7468
  e.preventDefault();
7424
7469
  // Only jump to position if video is loaded and duration is valid
7425
- if (this.video && !isNaN(this.video.duration) && this.video.duration > 0) {
7470
+ const durationForSeek = this.getDuration();
7471
+ if (!isNaN(durationForSeek) && durationForSeek > 0) {
7426
7472
  const percent = parseInt(e.key) * 10;
7427
- this.video.currentTime = (this.video.duration * percent) / 100;
7473
+ const seekTime = (durationForSeek * percent) / 100;
7474
+ this.seek(seekTime);
7428
7475
  shortcutText = `${percent}%`;
7429
7476
  }
7430
7477
  break;
@@ -7685,12 +7732,29 @@ export class WebPlayer extends BasePlayer {
7685
7732
  private togglePlayPause(): void {
7686
7733
  this.debugLog('togglePlayPause called, video state:', {
7687
7734
  videoExists: !!this.video,
7688
- videoPaused: this.video?.paused,
7735
+ youtubePlayerExists: !!this.youtubePlayer,
7736
+ youtubePlayerReady: this.youtubePlayerReady,
7689
7737
  playerState: this.state
7690
7738
  });
7691
7739
 
7740
+ // Handle YouTube player
7741
+ if (this.youtubePlayer && this.youtubePlayerReady) {
7742
+ const playerState = this.youtubePlayer.getPlayerState();
7743
+ this.debugLog('YouTube player state:', playerState);
7744
+
7745
+ if (playerState === window.YT.PlayerState.PLAYING) {
7746
+ this.debugLog('YouTube video is playing, calling pause()');
7747
+ this.pause();
7748
+ } else {
7749
+ this.debugLog('YouTube video is paused, calling play()');
7750
+ this.play();
7751
+ }
7752
+ return;
7753
+ }
7754
+
7755
+ // Handle regular video element
7692
7756
  if (!this.video) {
7693
- this.debugError('No video element available for toggle');
7757
+ this.debugError('No video element or YouTube player available for toggle');
7694
7758
  return;
7695
7759
  }
7696
7760
 
@@ -7994,12 +8058,28 @@ export class WebPlayer extends BasePlayer {
7994
8058
 
7995
8059
  private updateTimeDisplay(): void {
7996
8060
  const timeDisplay = document.getElementById('uvf-time-display');
7997
- if (timeDisplay && this.video) {
7998
- const current = this.formatTime(this.video.currentTime || 0);
7999
- const duration = this.formatTime(this.video.duration || 0);
8000
- timeDisplay.textContent = `${current} / ${duration}`;
8001
- this.debugLog('Time display updated:', `${current} / ${duration}`);
8061
+ if (!timeDisplay) return;
8062
+
8063
+ let current = 0;
8064
+ let duration = 0;
8065
+
8066
+ // Get time from YouTube player if available
8067
+ if (this.youtubePlayer && this.youtubePlayerReady) {
8068
+ try {
8069
+ current = this.youtubePlayer.getCurrentTime() || 0;
8070
+ duration = this.youtubePlayer.getDuration() || 0;
8071
+ } catch (error) {
8072
+ this.debugWarn('Error getting YouTube player time:', error);
8073
+ }
8074
+ } else if (this.video) {
8075
+ current = this.video.currentTime || 0;
8076
+ duration = this.video.duration || 0;
8002
8077
  }
8078
+
8079
+ const currentFormatted = this.formatTime(current);
8080
+ const durationFormatted = this.formatTime(duration);
8081
+ timeDisplay.textContent = `${currentFormatted} / ${durationFormatted}`;
8082
+ this.debugLog('Time display updated:', `${currentFormatted} / ${durationFormatted}`);
8003
8083
  }
8004
8084
 
8005
8085
  private showControls(): void {