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
|
|
9075
|
-
this.
|
|
9076
|
-
|
|
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 ===
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) {
|