unified-video-framework 1.4.249 → 1.4.251

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.
@@ -1115,11 +1115,20 @@ export class WebPlayer extends BasePlayer {
1115
1115
  if (this.video && metadata.thumbnail) {
1116
1116
  this.video.poster = metadata.thumbnail;
1117
1117
  }
1118
+
1119
+ // Update metadata UI immediately with YouTube title and thumbnail
1120
+ this.updateMetadataUI();
1118
1121
 
1119
1122
  // Create YouTube iframe player with custom controls integration
1120
1123
  await this.createYouTubePlayer(videoId);
1121
1124
 
1125
+ // Force another metadata update after player creation
1126
+ setTimeout(() => {
1127
+ this.updateMetadataUI();
1128
+ }, 1000);
1129
+
1122
1130
  this.debugLog('✅ YouTube video loaded successfully');
1131
+ this.debugLog('YouTube video title:', metadata.title);
1123
1132
  } catch (error) {
1124
1133
  this.debugError('Failed to load YouTube video:', error);
1125
1134
  throw new Error(`YouTube video loading failed: ${error}`);
@@ -1245,6 +1254,12 @@ export class WebPlayer extends BasePlayer {
1245
1254
 
1246
1255
  // Extract available YouTube qualities
1247
1256
  this.extractYouTubeAvailableQualities();
1257
+
1258
+ // Update metadata UI and settings after player is ready
1259
+ setTimeout(() => {
1260
+ this.updateMetadataUI();
1261
+ this.updateSettingsMenu();
1262
+ }, 500);
1248
1263
  }
1249
1264
 
1250
1265
  // Start time tracking
@@ -1366,15 +1381,15 @@ export class WebPlayer extends BasePlayer {
1366
1381
 
1367
1382
  this.youtubeAvailableQualities = [];
1368
1383
  availableQualityLevels.forEach((qualityLevel: string) => {
1384
+ // Skip 'auto' from YouTube API - we'll add it explicitly
1385
+ if (qualityLevel === 'auto') return;
1369
1386
  if (qualityMap[qualityLevel]) {
1370
1387
  this.youtubeAvailableQualities.push(qualityMap[qualityLevel]);
1371
1388
  }
1372
1389
  });
1373
1390
 
1374
- // Add auto quality option if not present
1375
- if (!this.youtubeAvailableQualities.find(q => q.value === 'auto')) {
1376
- this.youtubeAvailableQualities.unshift({ label: 'Auto', value: 'auto', height: 0 });
1377
- }
1391
+ // Always add auto quality option as the first item (exactly once)
1392
+ this.youtubeAvailableQualities.unshift({ label: 'Auto', value: 'auto', height: 0 });
1378
1393
 
1379
1394
  this.debugLog('Mapped YouTube qualities:', this.youtubeAvailableQualities);
1380
1395
 
@@ -1482,16 +1497,18 @@ export class WebPlayer extends BasePlayer {
1482
1497
 
1483
1498
  const percent = (currentTime / duration) * 100;
1484
1499
 
1485
- // Update progress filled
1500
+ // Update progress filled (only if not dragging)
1486
1501
  const progressFilled = document.getElementById('uvf-progress-filled') as HTMLElement;
1487
1502
  if (progressFilled && !this.isDragging) {
1488
1503
  progressFilled.style.width = percent + '%';
1489
1504
  }
1490
1505
 
1491
- // Update progress handle
1506
+ // Update progress handle (only if not dragging)
1492
1507
  const progressHandle = document.getElementById('uvf-progress-handle') as HTMLElement;
1493
1508
  if (progressHandle && !this.isDragging) {
1494
1509
  progressHandle.style.left = percent + '%';
1510
+ // Remove dragging class if it was set
1511
+ progressHandle.classList.remove('dragging');
1495
1512
  }
1496
1513
 
1497
1514
  // Update buffered progress
@@ -1500,8 +1517,13 @@ export class WebPlayer extends BasePlayer {
1500
1517
  progressBuffered.style.width = buffered + '%';
1501
1518
  }
1502
1519
 
1503
- // Update time display
1504
- this.updateTimeDisplay();
1520
+ // Update time display with YouTube-specific times
1521
+ const timeDisplay = document.getElementById('uvf-time-display');
1522
+ if (timeDisplay) {
1523
+ const currentTimeStr = this.formatTime(currentTime);
1524
+ const durationStr = this.formatTime(duration);
1525
+ timeDisplay.textContent = `${currentTimeStr} / ${durationStr}`;
1526
+ }
1505
1527
  }
1506
1528
 
1507
1529
 
@@ -8124,12 +8146,27 @@ export class WebPlayer extends BasePlayer {
8124
8146
  const progressBar = document.querySelector('.uvf-progress-bar') as HTMLElement;
8125
8147
  const progressFilled = document.getElementById('uvf-progress-filled') as HTMLElement;
8126
8148
  const progressHandle = document.getElementById('uvf-progress-handle') as HTMLElement;
8127
- if (!progressBar || !this.video) return;
8149
+ if (!progressBar) return;
8150
+
8151
+ // Get duration from appropriate source
8152
+ let duration = 0;
8153
+ if (this.youtubePlayer && this.youtubePlayerReady) {
8154
+ try {
8155
+ duration = this.youtubePlayer.getDuration() || 0;
8156
+ } catch (error) {
8157
+ this.debugWarn('Error getting YouTube duration for seeking:', error);
8158
+ return;
8159
+ }
8160
+ } else if (this.video) {
8161
+ duration = this.video.duration;
8162
+ } else {
8163
+ this.debugWarn('No video source available for seeking');
8164
+ return;
8165
+ }
8128
8166
 
8129
- const duration = this.video.duration;
8130
8167
  // Validate duration before calculating seek time
8131
8168
  if (!isFinite(duration) || isNaN(duration) || duration <= 0) {
8132
- this.debugWarn('Invalid video duration, cannot seek via progress bar');
8169
+ this.debugWarn('Invalid video duration, cannot seek via progress bar:', duration);
8133
8170
  return;
8134
8171
  }
8135
8172
 
@@ -8144,21 +8181,24 @@ export class WebPlayer extends BasePlayer {
8144
8181
  return;
8145
8182
  }
8146
8183
 
8184
+ this.debugLog('Seeking to position:', time, 'seconds (', Math.round(percent), '%)');
8185
+
8147
8186
  // Update UI immediately for responsive feedback
8148
- if (progressFilled) {
8187
+ if (progressFilled && !this.isDragging) {
8149
8188
  progressFilled.style.width = percent + '%';
8150
8189
  }
8151
- if (progressHandle) {
8190
+ if (progressHandle && !this.isDragging) {
8152
8191
  progressHandle.style.left = percent + '%';
8153
- // Add dragging class for visual feedback
8154
- if (this.isDragging) {
8155
- progressHandle.classList.add('dragging');
8156
- } else {
8157
- progressHandle.classList.remove('dragging');
8158
- }
8192
+ progressHandle.classList.add('dragging');
8159
8193
  }
8160
8194
 
8195
+ // Perform the actual seek
8161
8196
  this.seek(time);
8197
+
8198
+ // For YouTube, provide immediate visual feedback since API might be delayed
8199
+ if (this.youtubePlayer && this.youtubePlayerReady) {
8200
+ this.emit('onSeeking');
8201
+ }
8162
8202
  }
8163
8203
 
8164
8204
  private formatTime(seconds: number): string {
@@ -9192,6 +9232,13 @@ export class WebPlayer extends BasePlayer {
9192
9232
  option.classList.add('active');
9193
9233
  }
9194
9234
  });
9235
+
9236
+ // Update quality badge
9237
+ const qualityBadge = document.getElementById('uvf-quality-badge');
9238
+ if (qualityBadge) {
9239
+ const qualityOption = this.youtubeAvailableQualities.find(q => q.value === quality);
9240
+ qualityBadge.textContent = qualityOption ? qualityOption.label : 'AUTO';
9241
+ }
9195
9242
  return;
9196
9243
  }
9197
9244
 
@@ -9588,17 +9635,21 @@ export class WebPlayer extends BasePlayer {
9588
9635
  * Detect available video qualities from different sources
9589
9636
  */
9590
9637
  private detectAvailableQualities(): void {
9591
- this.availableQualities = [{ value: 'auto', label: 'Auto' }];
9638
+ // Check if we're using YouTube and have detected qualities
9639
+ const isYouTube = this.youtubePlayer && this.youtubePlayerReady && this.youtubeAvailableQualities.length > 0;
9640
+ this.availableQualities = [];
9592
9641
  let detectedQualities: Array<{ value: string; label: string; height?: number }> = [];
9593
9642
 
9594
9643
  // YouTube qualities
9595
- if (this.youtubePlayer && this.youtubePlayerReady && this.youtubeAvailableQualities.length > 0) {
9644
+ if (isYouTube) {
9596
9645
  detectedQualities = this.youtubeAvailableQualities.map(q => ({
9597
9646
  value: q.value,
9598
9647
  label: q.label,
9599
9648
  height: q.height
9600
9649
  }));
9601
9650
  this.debugLog('Using YouTube qualities:', detectedQualities);
9651
+ this.availableQualities = detectedQualities;
9652
+ return; // Early return for YouTube
9602
9653
  } else if (this.hls && this.hls.levels) {
9603
9654
  // HLS qualities
9604
9655
  this.hls.levels.forEach((level: any, index: number) => {