unified-video-framework 1.4.251 → 1.4.252

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.
@@ -1255,6 +1255,9 @@ export class WebPlayer extends BasePlayer {
1255
1255
  // Extract available YouTube qualities
1256
1256
  this.extractYouTubeAvailableQualities();
1257
1257
 
1258
+ // Try to get video title from YouTube API
1259
+ this.getYouTubeVideoTitle();
1260
+
1258
1261
  // Update metadata UI and settings after player is ready
1259
1262
  setTimeout(() => {
1260
1263
  this.updateMetadataUI();
@@ -1305,6 +1308,11 @@ export class WebPlayer extends BasePlayer {
1305
1308
  case window.YT.PlayerState.CUED:
1306
1309
  this.state.duration = this.youtubePlayer.getDuration();
1307
1310
  this.updateYouTubeUI('cued');
1311
+
1312
+ // Try to get video title when video is cued
1313
+ setTimeout(() => {
1314
+ this.getYouTubeVideoTitle();
1315
+ }, 100);
1308
1316
  break;
1309
1317
  }
1310
1318
  }
@@ -1354,6 +1362,64 @@ export class WebPlayer extends BasePlayer {
1354
1362
  });
1355
1363
  }
1356
1364
 
1365
+ /**
1366
+ * Get YouTube video title from the player API
1367
+ */
1368
+ private getYouTubeVideoTitle(): void {
1369
+ if (!this.youtubePlayer || !this.youtubePlayerReady) return;
1370
+
1371
+ try {
1372
+ // Try to get video data from YouTube player
1373
+ const videoData = this.youtubePlayer.getVideoData();
1374
+ if (videoData && videoData.title) {
1375
+ this.debugLog('Got YouTube title from player API:', videoData.title);
1376
+
1377
+ // Update source metadata with the correct title
1378
+ if (this.source && this.source.metadata) {
1379
+ this.source.metadata.title = videoData.title;
1380
+ }
1381
+
1382
+ // Update UI immediately
1383
+ this.updateMetadataUI();
1384
+ }
1385
+ } catch (error) {
1386
+ this.debugWarn('Could not get YouTube video title from API:', error);
1387
+
1388
+ // Fallback: Try to get from oembed API
1389
+ this.getYouTubeVideoTitleFromOEmbed();
1390
+ }
1391
+ }
1392
+
1393
+ /**
1394
+ * Fallback method to get title from YouTube oembed API
1395
+ */
1396
+ private async getYouTubeVideoTitleFromOEmbed(): Promise<void> {
1397
+ if (!this.source?.metadata?.videoId) return;
1398
+
1399
+ try {
1400
+ const videoId = this.source.metadata.videoId;
1401
+ const oembedUrl = `https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=${videoId}&format=json`;
1402
+
1403
+ const response = await fetch(oembedUrl);
1404
+ if (response.ok) {
1405
+ const data = await response.json();
1406
+ if (data.title) {
1407
+ this.debugLog('Got YouTube title from oembed API:', data.title);
1408
+
1409
+ // Update source metadata
1410
+ if (this.source && this.source.metadata) {
1411
+ this.source.metadata.title = data.title;
1412
+ }
1413
+
1414
+ // Update UI
1415
+ this.updateMetadataUI();
1416
+ }
1417
+ }
1418
+ } catch (error) {
1419
+ this.debugWarn('Could not get YouTube title from oembed API:', error);
1420
+ }
1421
+ }
1422
+
1357
1423
  private youtubeTimeTrackingInterval: NodeJS.Timeout | null = null;
1358
1424
  private youtubeAvailableQualities: any[] = [];
1359
1425
  private youtubeCurrentQuality: any = null;
@@ -1403,6 +1469,9 @@ export class WebPlayer extends BasePlayer {
1403
1469
  this.youtubeCurrentQuality = qualityMap['auto'];
1404
1470
  }
1405
1471
 
1472
+ // Update quality badge with current YouTube quality
1473
+ this.updateQualityBadge();
1474
+
1406
1475
  // Update settings menu to show YouTube qualities
1407
1476
  this.updateSettingsMenu();
1408
1477
 
@@ -1451,6 +1520,9 @@ export class WebPlayer extends BasePlayer {
1451
1520
  this.debugLog('⚠️ Requested quality:', qualityLevel, '| Actual quality:', currentQuality, '(YouTube may have optimized)');
1452
1521
  }
1453
1522
 
1523
+ // Update quality badge
1524
+ this.updateQualityBadge();
1525
+
1454
1526
  // Update settings menu UI
1455
1527
  this.updateSettingsMenu();
1456
1528
  } catch (verifyError) {
@@ -1463,6 +1535,28 @@ export class WebPlayer extends BasePlayer {
1463
1535
  this.showNotification('Quality control limited on YouTube');
1464
1536
  }
1465
1537
  }
1538
+
1539
+ /**
1540
+ * Update quality badge with current quality
1541
+ */
1542
+ private updateQualityBadge(): void {
1543
+ const qualityBadge = document.getElementById('uvf-quality-badge');
1544
+ if (!qualityBadge) return;
1545
+
1546
+ // For YouTube, use YouTube current quality
1547
+ if (this.youtubePlayer && this.youtubePlayerReady && this.youtubeCurrentQuality) {
1548
+ qualityBadge.textContent = this.youtubeCurrentQuality.label || 'AUTO';
1549
+ this.debugLog('Updated quality badge for YouTube:', this.youtubeCurrentQuality.label);
1550
+ } else if (this.currentQualityIndex >= 0 && this.qualities[this.currentQualityIndex]) {
1551
+ // For other sources, use current quality
1552
+ const quality = this.qualities[this.currentQualityIndex];
1553
+ qualityBadge.textContent = quality.label || 'HD';
1554
+ this.debugLog('Updated quality badge for standard video:', quality.label);
1555
+ } else {
1556
+ // Default
1557
+ qualityBadge.textContent = 'AUTO';
1558
+ }
1559
+ }
1466
1560
 
1467
1561
  private startYouTubeTimeTracking(): void {
1468
1562
  if (this.youtubeTimeTrackingInterval) {
@@ -1968,12 +2062,27 @@ export class WebPlayer extends BasePlayer {
1968
2062
  private updateTimeTooltip(e: MouseEvent): void {
1969
2063
  const progressBar = document.getElementById('uvf-progress-bar');
1970
2064
  const tooltip = document.getElementById('uvf-time-tooltip');
1971
- if (!progressBar || !tooltip || !this.video) return;
2065
+ if (!progressBar || !tooltip) return;
2066
+
2067
+ // Get duration from appropriate source
2068
+ let duration = 0;
2069
+ if (this.youtubePlayer && this.youtubePlayerReady) {
2070
+ try {
2071
+ duration = this.youtubePlayer.getDuration() || 0;
2072
+ } catch (error) {
2073
+ this.debugWarn('Error getting YouTube duration for tooltip:', error);
2074
+ return;
2075
+ }
2076
+ } else if (this.video) {
2077
+ duration = this.video.duration || 0;
2078
+ }
2079
+
2080
+ if (!duration || !isFinite(duration)) return;
1972
2081
 
1973
2082
  const rect = progressBar.getBoundingClientRect();
1974
2083
  const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
1975
2084
  const percent = (x / rect.width);
1976
- const time = percent * this.video.duration;
2085
+ const time = percent * duration;
1977
2086
 
1978
2087
  // Update tooltip content and position
1979
2088
  tooltip.textContent = this.formatTime(time);
@@ -6789,7 +6898,7 @@ export class WebPlayer extends BasePlayer {
6789
6898
  const qualityBadge = document.createElement('div');
6790
6899
  qualityBadge.className = 'uvf-quality-badge';
6791
6900
  qualityBadge.id = 'uvf-quality-badge';
6792
- qualityBadge.textContent = 'HD';
6901
+ qualityBadge.textContent = 'AUTO'; // Default to AUTO for better UX
6793
6902
  rightControls.appendChild(qualityBadge);
6794
6903
 
6795
6904
  // Settings button with menu (show only if enabled)