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:
|
|
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
|
-
|
|
6883
|
-
|
|
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
|
-
|
|
6888
|
-
|
|
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
|
-
|
|
7349
|
-
|
|
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
|
-
|
|
7357
|
-
|
|
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
|
-
|
|
7365
|
-
|
|
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
|
-
|
|
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
|
-
|
|
7374
|
-
|
|
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
|
-
|
|
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
|
-
|
|
7383
|
-
|
|
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
|
-
|
|
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
|
-
|
|
7470
|
+
const durationForSeek = this.getDuration();
|
|
7471
|
+
if (!isNaN(durationForSeek) && durationForSeek > 0) {
|
|
7426
7472
|
const percent = parseInt(e.key) * 10;
|
|
7427
|
-
|
|
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
|
-
|
|
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
|
|
7998
|
-
|
|
7999
|
-
|
|
8000
|
-
|
|
8001
|
-
|
|
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 {
|