unified-video-framework 1.4.254 → 1.4.256
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.
|
@@ -1550,40 +1550,162 @@ export class WebPlayer extends BasePlayer {
|
|
|
1550
1550
|
|
|
1551
1551
|
this.debugLog('📊 Attempting to set YouTube quality to:', qualityLevel);
|
|
1552
1552
|
|
|
1553
|
-
//
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1553
|
+
// Multiple approaches to force YouTube quality change
|
|
1554
|
+
if (qualityLevel === 'auto') {
|
|
1555
|
+
// For auto, just use setPlaybackQuality
|
|
1556
|
+
this.youtubePlayer.setPlaybackQuality(qualityLevel);
|
|
1557
|
+
} else {
|
|
1558
|
+
// For specific qualities, try multiple methods
|
|
1559
|
+
try {
|
|
1560
|
+
// Method 1: Set quality range (most effective for forcing specific quality)
|
|
1561
|
+
if (typeof this.youtubePlayer.setPlaybackQualityRange === 'function') {
|
|
1562
|
+
this.youtubePlayer.setPlaybackQualityRange(qualityLevel, qualityLevel);
|
|
1563
|
+
this.debugLog('✅ setPlaybackQualityRange called for:', qualityLevel);
|
|
1564
|
+
}
|
|
1565
|
+
} catch (e) {
|
|
1566
|
+
this.debugWarn('setPlaybackQualityRange failed:', e);
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1559
1569
|
try {
|
|
1560
|
-
|
|
1561
|
-
this.
|
|
1570
|
+
// Method 2: Standard quality setting
|
|
1571
|
+
this.youtubePlayer.setPlaybackQuality(qualityLevel);
|
|
1572
|
+
this.debugLog('✅ setPlaybackQuality called for:', qualityLevel);
|
|
1573
|
+
} catch (e) {
|
|
1574
|
+
this.debugWarn('setPlaybackQuality failed:', e);
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
// Method 3: Force quality with seekTo trick (most aggressive)
|
|
1578
|
+
try {
|
|
1579
|
+
const currentTime = this.youtubePlayer.getCurrentTime();
|
|
1580
|
+
const wasPlaying = this.youtubePlayer.getPlayerState() === window.YT.PlayerState.PLAYING;
|
|
1562
1581
|
|
|
1563
|
-
|
|
1582
|
+
// Seek to current time + 0.1 seconds to force reload with new quality
|
|
1583
|
+
this.youtubePlayer.seekTo(currentTime + 0.1, true);
|
|
1564
1584
|
|
|
1565
|
-
//
|
|
1566
|
-
|
|
1567
|
-
this.
|
|
1568
|
-
|
|
1585
|
+
// Set quality immediately after seek
|
|
1586
|
+
setTimeout(() => {
|
|
1587
|
+
this.youtubePlayer.setPlaybackQuality(qualityLevel);
|
|
1588
|
+
|
|
1589
|
+
// Seek back to original time
|
|
1590
|
+
setTimeout(() => {
|
|
1591
|
+
this.youtubePlayer.seekTo(currentTime, true);
|
|
1592
|
+
if (!wasPlaying) {
|
|
1593
|
+
this.youtubePlayer.pauseVideo();
|
|
1594
|
+
}
|
|
1595
|
+
}, 100);
|
|
1596
|
+
}, 50);
|
|
1597
|
+
|
|
1598
|
+
this.debugLog('🔄 Applied seekTo trick for quality change');
|
|
1599
|
+
} catch (e) {
|
|
1600
|
+
this.debugWarn('Force quality change with seekTo trick failed:', e);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
// Verify quality was changed after multiple delays with retry logic
|
|
1605
|
+
this.verifyYouTubeQualityChange(qualityLevel, qualityMap, 0);
|
|
1606
|
+
} catch (error) {
|
|
1607
|
+
this.debugWarn('❌ Could not set YouTube quality:', error);
|
|
1608
|
+
this.showNotification('Quality control limited on YouTube');
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
/**
|
|
1613
|
+
* Verify YouTube quality change with retry logic
|
|
1614
|
+
*/
|
|
1615
|
+
private verifyYouTubeQualityChange(requestedQuality: string, qualityMap: Record<string, any>, attempt: number): void {
|
|
1616
|
+
const maxAttempts = 3;
|
|
1617
|
+
const delays = [500, 1500, 3000]; // Progressive delays
|
|
1618
|
+
|
|
1619
|
+
setTimeout(() => {
|
|
1620
|
+
try {
|
|
1621
|
+
const currentQuality = this.youtubePlayer.getPlaybackQuality();
|
|
1622
|
+
this.youtubeCurrentQuality = qualityMap[currentQuality] || qualityMap['auto'];
|
|
1623
|
+
|
|
1624
|
+
this.debugLog('🔍 Quality verification attempt', attempt + 1, '- Requested:', requestedQuality, '| Current:', currentQuality);
|
|
1625
|
+
|
|
1626
|
+
if (currentQuality === requestedQuality || attempt >= maxAttempts - 1) {
|
|
1627
|
+
// Success or final attempt
|
|
1628
|
+
if (currentQuality === requestedQuality) {
|
|
1629
|
+
this.showNotification(`Quality: ${qualityMap[currentQuality]?.label || 'requested quality'}`);
|
|
1630
|
+
this.debugLog('✅ Quality successfully changed to:', requestedQuality);
|
|
1569
1631
|
} else {
|
|
1570
|
-
|
|
1571
|
-
|
|
1632
|
+
// Try one more aggressive method on final attempt
|
|
1633
|
+
if (attempt === maxAttempts - 1) {
|
|
1634
|
+
this.debugLog('🔥 Final attempt: Trying loadVideoById method');
|
|
1635
|
+
try {
|
|
1636
|
+
const videoData = this.youtubePlayer.getVideoData();
|
|
1637
|
+
const currentTime = this.youtubePlayer.getCurrentTime();
|
|
1638
|
+
|
|
1639
|
+
// Reload video at current time with suggested quality
|
|
1640
|
+
this.youtubePlayer.loadVideoById({
|
|
1641
|
+
videoId: videoData.video_id,
|
|
1642
|
+
startSeconds: currentTime,
|
|
1643
|
+
suggestedQuality: requestedQuality
|
|
1644
|
+
});
|
|
1645
|
+
|
|
1646
|
+
this.debugLog('🔄 Video reloaded with suggested quality:', requestedQuality);
|
|
1647
|
+
} catch (e) {
|
|
1648
|
+
this.debugWarn('loadVideoById method failed:', e);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
this.showNotification(`Quality: ${qualityMap[currentQuality]?.label || currentQuality}`);
|
|
1653
|
+
this.debugLog('⚠️ Quality change may not have worked. Requested:', requestedQuality, '| Current:', currentQuality);
|
|
1572
1654
|
}
|
|
1573
1655
|
|
|
1574
|
-
// Update
|
|
1656
|
+
// Update UI regardless
|
|
1575
1657
|
this.updateQualityBadge();
|
|
1658
|
+
this.updateSettingsMenu();
|
|
1659
|
+
} else {
|
|
1660
|
+
// Retry with more aggressive method
|
|
1661
|
+
this.debugLog('🔁 Quality not changed, retrying with method', attempt + 2);
|
|
1662
|
+
this.retryYouTubeQualityChange(requestedQuality, qualityMap, attempt + 1);
|
|
1576
1663
|
|
|
1577
|
-
//
|
|
1664
|
+
// Still verify after delay
|
|
1665
|
+
this.verifyYouTubeQualityChange(requestedQuality, qualityMap, attempt + 1);
|
|
1666
|
+
}
|
|
1667
|
+
} catch (verifyError) {
|
|
1668
|
+
this.debugWarn('Could not verify YouTube quality:', verifyError);
|
|
1669
|
+
if (attempt === maxAttempts - 1) {
|
|
1670
|
+
this.showNotification('Quality change attempted');
|
|
1671
|
+
this.updateQualityBadge();
|
|
1578
1672
|
this.updateSettingsMenu();
|
|
1579
|
-
} catch (verifyError) {
|
|
1580
|
-
this.debugWarn('Could not verify YouTube quality:', verifyError);
|
|
1581
1673
|
}
|
|
1582
|
-
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1674
|
+
}
|
|
1675
|
+
}, delays[attempt] || 1000);
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
/**
|
|
1679
|
+
* Retry YouTube quality change with alternative methods
|
|
1680
|
+
*/
|
|
1681
|
+
private retryYouTubeQualityChange(qualityLevel: string, qualityMap: Record<string, any>, attempt: number): void {
|
|
1682
|
+
try {
|
|
1683
|
+
if (attempt === 1) {
|
|
1684
|
+
// Second attempt: Try with video restart
|
|
1685
|
+
this.debugLog('🔄 Retry attempt 1: Using cueVideoById');
|
|
1686
|
+
const videoData = this.youtubePlayer.getVideoData();
|
|
1687
|
+
const currentTime = this.youtubePlayer.getCurrentTime();
|
|
1688
|
+
|
|
1689
|
+
this.youtubePlayer.cueVideoById({
|
|
1690
|
+
videoId: videoData.video_id,
|
|
1691
|
+
startSeconds: currentTime,
|
|
1692
|
+
suggestedQuality: qualityLevel
|
|
1693
|
+
});
|
|
1694
|
+
|
|
1695
|
+
setTimeout(() => this.youtubePlayer.playVideo(), 100);
|
|
1696
|
+
|
|
1697
|
+
} else if (attempt === 2) {
|
|
1698
|
+
// Third attempt: Multiple sequential calls
|
|
1699
|
+
this.debugLog('🔄 Retry attempt 2: Multiple sequential calls');
|
|
1700
|
+
|
|
1701
|
+
for (let i = 0; i < 3; i++) {
|
|
1702
|
+
setTimeout(() => {
|
|
1703
|
+
this.youtubePlayer.setPlaybackQuality(qualityLevel);
|
|
1704
|
+
}, i * 100);
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
} catch (e) {
|
|
1708
|
+
this.debugWarn('Retry attempt', attempt, 'failed:', e);
|
|
1587
1709
|
}
|
|
1588
1710
|
}
|
|
1589
1711
|
|
|
@@ -4798,7 +4920,29 @@ export class WebPlayer extends BasePlayer {
|
|
|
4798
4920
|
}
|
|
4799
4921
|
|
|
4800
4922
|
.uvf-accordion-item.expanded .uvf-accordion-content {
|
|
4801
|
-
max-height:
|
|
4923
|
+
max-height: 350px;
|
|
4924
|
+
overflow-y: auto;
|
|
4925
|
+
-webkit-overflow-scrolling: touch;
|
|
4926
|
+
}
|
|
4927
|
+
|
|
4928
|
+
/* Special handling for quality accordion with many options */
|
|
4929
|
+
.uvf-accordion-item.expanded .uvf-accordion-content[data-section="quality"] {
|
|
4930
|
+
max-height: 400px;
|
|
4931
|
+
}
|
|
4932
|
+
|
|
4933
|
+
/* Scrollbar styling for accordion content */
|
|
4934
|
+
.uvf-accordion-content::-webkit-scrollbar {
|
|
4935
|
+
width: 4px;
|
|
4936
|
+
}
|
|
4937
|
+
.uvf-accordion-content::-webkit-scrollbar-track {
|
|
4938
|
+
background: transparent;
|
|
4939
|
+
}
|
|
4940
|
+
.uvf-accordion-content::-webkit-scrollbar-thumb {
|
|
4941
|
+
background: rgba(255,255,255,0.3);
|
|
4942
|
+
border-radius: 2px;
|
|
4943
|
+
}
|
|
4944
|
+
.uvf-accordion-content::-webkit-scrollbar-thumb:hover {
|
|
4945
|
+
background: rgba(255,255,255,0.5);
|
|
4802
4946
|
}
|
|
4803
4947
|
|
|
4804
4948
|
/* Settings options within accordion */
|