unified-video-framework 1.4.248 → 1.4.249

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.
@@ -1242,6 +1242,9 @@ export class WebPlayer extends BasePlayer {
1242
1242
  if (this.config.muted) {
1243
1243
  this.youtubePlayer.mute();
1244
1244
  }
1245
+
1246
+ // Extract available YouTube qualities
1247
+ this.extractYouTubeAvailableQualities();
1245
1248
  }
1246
1249
 
1247
1250
  // Start time tracking
@@ -1337,6 +1340,114 @@ export class WebPlayer extends BasePlayer {
1337
1340
  }
1338
1341
 
1339
1342
  private youtubeTimeTrackingInterval: NodeJS.Timeout | null = null;
1343
+ private youtubeAvailableQualities: any[] = [];
1344
+ private youtubeCurrentQuality: any = null;
1345
+
1346
+ /**
1347
+ * Extract available YouTube video qualities
1348
+ */
1349
+ private extractYouTubeAvailableQualities(): void {
1350
+ if (!this.youtubePlayer) return;
1351
+
1352
+ try {
1353
+ const availableQualityLevels = this.youtubePlayer.getAvailableQualityLevels();
1354
+ this.debugLog('YouTube available quality levels:', availableQualityLevels);
1355
+
1356
+ // Map YouTube quality levels to standard labels
1357
+ const qualityMap: Record<string, any> = {
1358
+ 'hd1080': { label: '1080p', value: 'hd1080', height: 1080 },
1359
+ 'hd720': { label: '720p', value: 'hd720', height: 720 },
1360
+ 'large': { label: '480p', value: 'large', height: 480 },
1361
+ 'medium': { label: '360p', value: 'medium', height: 360 },
1362
+ 'small': { label: '240p', value: 'small', height: 240 },
1363
+ 'tiny': { label: '144p', value: 'tiny', height: 144 },
1364
+ 'auto': { label: 'Auto', value: 'auto', height: 0 }
1365
+ };
1366
+
1367
+ this.youtubeAvailableQualities = [];
1368
+ availableQualityLevels.forEach((qualityLevel: string) => {
1369
+ if (qualityMap[qualityLevel]) {
1370
+ this.youtubeAvailableQualities.push(qualityMap[qualityLevel]);
1371
+ }
1372
+ });
1373
+
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
+ }
1378
+
1379
+ this.debugLog('Mapped YouTube qualities:', this.youtubeAvailableQualities);
1380
+
1381
+ // Get current quality
1382
+ try {
1383
+ const currentQuality = this.youtubePlayer.getPlaybackQuality();
1384
+ this.youtubeCurrentQuality = qualityMap[currentQuality] || qualityMap['auto'];
1385
+ this.debugLog('Current YouTube quality:', this.youtubeCurrentQuality);
1386
+ } catch (e) {
1387
+ this.debugWarn('Could not get current YouTube quality:', e);
1388
+ this.youtubeCurrentQuality = qualityMap['auto'];
1389
+ }
1390
+
1391
+ // Update settings menu to show YouTube qualities
1392
+ this.updateSettingsMenu();
1393
+
1394
+ } catch (error) {
1395
+ this.debugWarn('Could not extract YouTube qualities:', error);
1396
+ }
1397
+ }
1398
+
1399
+ /**
1400
+ * Set YouTube video quality
1401
+ */
1402
+ private setYouTubeQuality(qualityLevel: string): void {
1403
+ if (!this.youtubePlayer) return;
1404
+
1405
+ try {
1406
+ const qualityMap: Record<string, any> = {
1407
+ 'hd1080': { label: '1080p', value: 'hd1080', height: 1080 },
1408
+ 'hd720': { label: '720p', value: 'hd720', height: 720 },
1409
+ 'large': { label: '480p', value: 'large', height: 480 },
1410
+ 'medium': { label: '360p', value: 'medium', height: 360 },
1411
+ 'small': { label: '240p', value: 'small', height: 240 },
1412
+ 'tiny': { label: '144p', value: 'tiny', height: 144 },
1413
+ 'auto': { label: 'Auto', value: 'auto', height: 0 }
1414
+ };
1415
+
1416
+ this.debugLog('📊 Attempting to set YouTube quality to:', qualityLevel);
1417
+
1418
+ // Try to set the quality
1419
+ this.youtubePlayer.setPlaybackQuality(qualityLevel);
1420
+ this.debugLog('✅ setPlaybackQuality called for:', qualityLevel);
1421
+
1422
+ // Verify quality was changed after a delay
1423
+ setTimeout(() => {
1424
+ try {
1425
+ const currentQuality = this.youtubePlayer.getPlaybackQuality();
1426
+ this.youtubeCurrentQuality = qualityMap[currentQuality] || qualityMap['auto'];
1427
+
1428
+ this.debugLog('📊 Current quality after set:', currentQuality, '(', this.youtubeCurrentQuality?.label, ')');
1429
+
1430
+ // Show notification with result
1431
+ if (currentQuality === qualityLevel) {
1432
+ this.showNotification(`Quality changed to ${qualityMap[currentQuality]?.label || 'requested quality'}`);
1433
+ this.debugLog('✅ Quality successfully changed to:', qualityLevel);
1434
+ } else {
1435
+ this.showNotification(`Quality set to ${qualityMap[currentQuality]?.label || currentQuality} (YouTube optimized)`);
1436
+ this.debugLog('⚠️ Requested quality:', qualityLevel, '| Actual quality:', currentQuality, '(YouTube may have optimized)');
1437
+ }
1438
+
1439
+ // Update settings menu UI
1440
+ this.updateSettingsMenu();
1441
+ } catch (verifyError) {
1442
+ this.debugWarn('Could not verify YouTube quality:', verifyError);
1443
+ }
1444
+ }, 1000);
1445
+
1446
+ } catch (error) {
1447
+ this.debugWarn('❌ Could not set YouTube quality:', error);
1448
+ this.showNotification('Quality control limited on YouTube');
1449
+ }
1450
+ }
1340
1451
 
1341
1452
  private startYouTubeTimeTracking(): void {
1342
1453
  if (this.youtubeTimeTrackingInterval) {
@@ -9071,12 +9182,13 @@ export class WebPlayer extends BasePlayer {
9071
9182
  private setQualityByLabel(quality: string): void {
9072
9183
  // Handle YouTube player
9073
9184
  if (this.youtubePlayer && this.youtubePlayerReady) {
9074
- // YouTube quality is limited - show notification
9075
- this.showShortcutIndicator('Quality control not available for YouTube');
9076
- // Update UI to reflect current quality
9185
+ // Set YouTube quality directly
9186
+ this.setYouTubeQuality(quality);
9187
+
9188
+ // Update UI to reflect selection
9077
9189
  document.querySelectorAll('.quality-option').forEach(option => {
9078
9190
  option.classList.remove('active');
9079
- if ((option as HTMLElement).dataset.quality === 'auto') {
9191
+ if ((option as HTMLElement).dataset.quality === quality) {
9080
9192
  option.classList.add('active');
9081
9193
  }
9082
9194
  });
@@ -9380,7 +9492,11 @@ export class WebPlayer extends BasePlayer {
9380
9492
 
9381
9493
  // Quality Accordion Section (only if enabled in config and qualities detected)
9382
9494
  if (this.settingsConfig.quality && this.availableQualities.length > 0) {
9383
- const currentQuality = this.availableQualities.find(q => q.value === this.currentQuality);
9495
+ // For YouTube, use youtubeCurrentQuality; otherwise use currentQuality
9496
+ const qualityForDisplay = this.youtubePlayer && this.youtubePlayerReady && this.youtubeCurrentQuality
9497
+ ? this.youtubeCurrentQuality.value
9498
+ : this.currentQuality;
9499
+ const currentQuality = this.availableQualities.find(q => q.value === qualityForDisplay);
9384
9500
  const currentQualityLabel = currentQuality ? currentQuality.label : 'Auto';
9385
9501
 
9386
9502
  menuHTML += `
@@ -9400,7 +9516,11 @@ export class WebPlayer extends BasePlayer {
9400
9516
  <div class="uvf-accordion-content" data-section="quality">`;
9401
9517
 
9402
9518
  this.availableQualities.forEach(quality => {
9403
- const isActive = quality.value === this.currentQuality ? 'active' : '';
9519
+ // For YouTube, compare against youtubeCurrentQuality
9520
+ const qualityValue = this.youtubePlayer && this.youtubePlayerReady && this.youtubeCurrentQuality
9521
+ ? this.youtubeCurrentQuality.value
9522
+ : this.currentQuality;
9523
+ const isActive = quality.value === qualityValue ? 'active' : '';
9404
9524
  const isPremium = this.isQualityPremium(quality);
9405
9525
  const isLocked = isPremium && !this.isPremiumUser();
9406
9526
  const qualityHeight = (quality as any).height || 0;
@@ -9471,7 +9591,15 @@ export class WebPlayer extends BasePlayer {
9471
9591
  this.availableQualities = [{ value: 'auto', label: 'Auto' }];
9472
9592
  let detectedQualities: Array<{ value: string; label: string; height?: number }> = [];
9473
9593
 
9474
- if (this.hls && this.hls.levels) {
9594
+ // YouTube qualities
9595
+ if (this.youtubePlayer && this.youtubePlayerReady && this.youtubeAvailableQualities.length > 0) {
9596
+ detectedQualities = this.youtubeAvailableQualities.map(q => ({
9597
+ value: q.value,
9598
+ label: q.label,
9599
+ height: q.height
9600
+ }));
9601
+ this.debugLog('Using YouTube qualities:', detectedQualities);
9602
+ } else if (this.hls && this.hls.levels) {
9475
9603
  // HLS qualities
9476
9604
  this.hls.levels.forEach((level: any, index: number) => {
9477
9605
  if (level.height) {
@@ -9843,6 +9971,13 @@ export class WebPlayer extends BasePlayer {
9843
9971
  private setQualityFromSettings(quality: string): void {
9844
9972
  this.currentQuality = quality;
9845
9973
 
9974
+ // Handle YouTube quality
9975
+ if (this.youtubePlayer && this.youtubePlayerReady) {
9976
+ this.setYouTubeQuality(quality);
9977
+ this.debugLog(`YouTube quality set to ${quality}`);
9978
+ return;
9979
+ }
9980
+
9846
9981
  if (quality === 'auto') {
9847
9982
  // Enable auto quality with filter consideration
9848
9983
  if (this.hls) {