unified-video-framework 1.4.255 → 1.4.257
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.
- package/package.json +1 -1
- package/packages/core/dist/interfaces/IVideoPlayer.d.ts +1 -0
- package/packages/core/dist/interfaces/IVideoPlayer.d.ts.map +1 -1
- package/packages/core/dist/interfaces.d.ts +1 -0
- package/packages/core/dist/interfaces.d.ts.map +1 -1
- package/packages/core/src/interfaces/IVideoPlayer.ts +3 -0
- package/packages/core/src/interfaces.ts +1 -0
- package/packages/web/dist/WebPlayer.d.ts +6 -5
- package/packages/web/dist/WebPlayer.d.ts.map +1 -1
- package/packages/web/dist/WebPlayer.js +128 -216
- package/packages/web/dist/WebPlayer.js.map +1 -1
- package/packages/web/src/WebPlayer.ts +196 -312
|
@@ -94,8 +94,8 @@ export class WebPlayer extends BasePlayer {
|
|
|
94
94
|
this.youtubePlayerReady = false;
|
|
95
95
|
this.youtubeIframe = null;
|
|
96
96
|
this.youtubeTimeTrackingInterval = null;
|
|
97
|
-
this.
|
|
98
|
-
this.
|
|
97
|
+
this.isYouTubeLive = false;
|
|
98
|
+
this.useYouTubeNativeControls = false;
|
|
99
99
|
this.clickToUnmuteHandler = null;
|
|
100
100
|
}
|
|
101
101
|
debugLog(message, ...args) {
|
|
@@ -896,7 +896,7 @@ export class WebPlayer extends BasePlayer {
|
|
|
896
896
|
width: '100%',
|
|
897
897
|
height: '100%',
|
|
898
898
|
playerVars: {
|
|
899
|
-
controls: 0,
|
|
899
|
+
controls: this.config.youtubeNativeControls !== false ? 1 : 0,
|
|
900
900
|
disablekb: 0,
|
|
901
901
|
fs: 0,
|
|
902
902
|
iv_load_policy: 3,
|
|
@@ -953,11 +953,11 @@ export class WebPlayer extends BasePlayer {
|
|
|
953
953
|
if (this.config.muted) {
|
|
954
954
|
this.youtubePlayer.mute();
|
|
955
955
|
}
|
|
956
|
-
this.
|
|
956
|
+
this.detectYouTubeLiveStatus();
|
|
957
957
|
this.getYouTubeVideoTitle();
|
|
958
958
|
setTimeout(() => {
|
|
959
959
|
this.updateMetadataUI();
|
|
960
|
-
this.
|
|
960
|
+
this.updateControlsVisibility();
|
|
961
961
|
}, 500);
|
|
962
962
|
}
|
|
963
963
|
this.startYouTubeTimeTracking();
|
|
@@ -971,9 +971,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
971
971
|
this.state.isPaused = false;
|
|
972
972
|
this.state.isBuffering = false;
|
|
973
973
|
this.updateYouTubeUI('playing');
|
|
974
|
-
setTimeout(() => {
|
|
975
|
-
this.extractYouTubeAvailableQualities();
|
|
976
|
-
}, 1000);
|
|
977
974
|
this.emit('onPlay');
|
|
978
975
|
break;
|
|
979
976
|
case window.YT.PlayerState.PAUSED:
|
|
@@ -986,9 +983,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
986
983
|
case window.YT.PlayerState.BUFFERING:
|
|
987
984
|
this.state.isBuffering = true;
|
|
988
985
|
this.updateYouTubeUI('buffering');
|
|
989
|
-
setTimeout(() => {
|
|
990
|
-
this.extractYouTubeAvailableQualities();
|
|
991
|
-
}, 500);
|
|
992
986
|
this.emit('onBuffering', true);
|
|
993
987
|
break;
|
|
994
988
|
case window.YT.PlayerState.ENDED:
|
|
@@ -1002,8 +996,9 @@ export class WebPlayer extends BasePlayer {
|
|
|
1002
996
|
this.state.duration = this.youtubePlayer.getDuration();
|
|
1003
997
|
this.updateYouTubeUI('cued');
|
|
1004
998
|
setTimeout(() => {
|
|
1005
|
-
this.
|
|
1006
|
-
|
|
999
|
+
this.detectYouTubeLiveStatus();
|
|
1000
|
+
this.updateControlsVisibility();
|
|
1001
|
+
}, 500);
|
|
1007
1002
|
break;
|
|
1008
1003
|
}
|
|
1009
1004
|
}
|
|
@@ -1072,6 +1067,120 @@ export class WebPlayer extends BasePlayer {
|
|
|
1072
1067
|
this.getYouTubeVideoTitleFromOEmbed();
|
|
1073
1068
|
}
|
|
1074
1069
|
}
|
|
1070
|
+
detectYouTubeLiveStatus() {
|
|
1071
|
+
if (!this.youtubePlayer || !this.youtubePlayerReady)
|
|
1072
|
+
return;
|
|
1073
|
+
try {
|
|
1074
|
+
const videoData = this.youtubePlayer.getVideoData();
|
|
1075
|
+
this.isYouTubeLive = videoData?.isLive || false;
|
|
1076
|
+
this.useYouTubeNativeControls = this.config.youtubeNativeControls !== false;
|
|
1077
|
+
this.debugLog('YouTube Live status:', {
|
|
1078
|
+
isLive: this.isYouTubeLive,
|
|
1079
|
+
useNativeControls: this.useYouTubeNativeControls,
|
|
1080
|
+
videoId: videoData?.video_id
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
catch (error) {
|
|
1084
|
+
this.debugWarn('Could not detect YouTube Live status:', error);
|
|
1085
|
+
try {
|
|
1086
|
+
const duration = this.youtubePlayer.getDuration();
|
|
1087
|
+
this.isYouTubeLive = !duration || duration === 0;
|
|
1088
|
+
this.useYouTubeNativeControls = this.config.youtubeNativeControls !== false;
|
|
1089
|
+
this.debugLog('YouTube Live detected via duration check:', {
|
|
1090
|
+
duration,
|
|
1091
|
+
isLive: this.isYouTubeLive,
|
|
1092
|
+
useNativeControls: this.useYouTubeNativeControls
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
catch (e) {
|
|
1096
|
+
this.debugWarn('Could not check YouTube duration for Live detection:', e);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
updateControlsVisibility() {
|
|
1101
|
+
const controlsContainer = document.getElementById('uvf-controls-container');
|
|
1102
|
+
if (!controlsContainer)
|
|
1103
|
+
return;
|
|
1104
|
+
if (this.youtubePlayer && this.useYouTubeNativeControls) {
|
|
1105
|
+
controlsContainer.style.display = 'none';
|
|
1106
|
+
if (!this.config.youtubeNativeControls) {
|
|
1107
|
+
this.recreateYouTubePlayerWithNativeControls();
|
|
1108
|
+
}
|
|
1109
|
+
this.debugLog('✅ YouTube native controls enabled', {
|
|
1110
|
+
isLive: this.isYouTubeLive,
|
|
1111
|
+
reason: this.config.youtubeNativeControls !== false ? 'Default behavior (all YouTube content)' : 'Live stream detected'
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
else {
|
|
1115
|
+
controlsContainer.style.display = 'flex';
|
|
1116
|
+
this.debugLog('✅ Custom controls enabled for YouTube video');
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
recreateYouTubePlayerWithNativeControls() {
|
|
1120
|
+
if (!this.source?.metadata?.videoId)
|
|
1121
|
+
return;
|
|
1122
|
+
const videoId = this.source.metadata.videoId;
|
|
1123
|
+
const currentTime = this.youtubePlayer?.getCurrentTime() || 0;
|
|
1124
|
+
const container = this.playerWrapper || this.video?.parentElement;
|
|
1125
|
+
if (!container)
|
|
1126
|
+
return;
|
|
1127
|
+
if (this.youtubePlayer) {
|
|
1128
|
+
this.youtubePlayer.destroy();
|
|
1129
|
+
}
|
|
1130
|
+
const existingContainer = container.querySelector(`#youtube-player-${videoId}`);
|
|
1131
|
+
if (existingContainer) {
|
|
1132
|
+
existingContainer.remove();
|
|
1133
|
+
}
|
|
1134
|
+
const iframeContainer = document.createElement('div');
|
|
1135
|
+
iframeContainer.id = `youtube-player-${videoId}`;
|
|
1136
|
+
iframeContainer.style.cssText = `
|
|
1137
|
+
position: absolute;
|
|
1138
|
+
top: 0;
|
|
1139
|
+
left: 0;
|
|
1140
|
+
width: 100%;
|
|
1141
|
+
height: 100%;
|
|
1142
|
+
z-index: 1;
|
|
1143
|
+
`;
|
|
1144
|
+
container.appendChild(iframeContainer);
|
|
1145
|
+
this.youtubePlayer = new window.YT.Player(iframeContainer.id, {
|
|
1146
|
+
videoId: videoId,
|
|
1147
|
+
width: '100%',
|
|
1148
|
+
height: '100%',
|
|
1149
|
+
playerVars: {
|
|
1150
|
+
autoplay: this.config.autoPlay ? 1 : 0,
|
|
1151
|
+
controls: 1,
|
|
1152
|
+
modestbranding: 1,
|
|
1153
|
+
rel: 0,
|
|
1154
|
+
showinfo: 0,
|
|
1155
|
+
iv_load_policy: 3,
|
|
1156
|
+
playsinline: 1,
|
|
1157
|
+
start: Math.floor(currentTime)
|
|
1158
|
+
},
|
|
1159
|
+
events: {
|
|
1160
|
+
onReady: () => {
|
|
1161
|
+
this.youtubePlayerReady = true;
|
|
1162
|
+
this.debugLog('YouTube player with native controls ready');
|
|
1163
|
+
this.emit('onReady');
|
|
1164
|
+
},
|
|
1165
|
+
onStateChange: (event) => this.onYouTubePlayerStateChange(event),
|
|
1166
|
+
onError: (event) => this.onYouTubePlayerError(event)
|
|
1167
|
+
}
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1170
|
+
toggleYouTubeControls(useNative = !this.useYouTubeNativeControls) {
|
|
1171
|
+
if (!this.youtubePlayer) {
|
|
1172
|
+
this.debugWarn('Cannot toggle YouTube controls - no YouTube player active');
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
this.useYouTubeNativeControls = useNative;
|
|
1176
|
+
this.config.youtubeNativeControls = useNative;
|
|
1177
|
+
this.updateControlsVisibility();
|
|
1178
|
+
this.debugLog('YouTube controls toggled:', {
|
|
1179
|
+
useNative: this.useYouTubeNativeControls,
|
|
1180
|
+
isLive: this.isYouTubeLive
|
|
1181
|
+
});
|
|
1182
|
+
this.showNotification(`YouTube Controls: ${this.useYouTubeNativeControls ? 'Native' : 'Custom'}`);
|
|
1183
|
+
}
|
|
1075
1184
|
async getYouTubeVideoTitleFromOEmbed() {
|
|
1076
1185
|
if (!this.source?.metadata?.videoId)
|
|
1077
1186
|
return;
|
|
@@ -1094,172 +1203,10 @@ export class WebPlayer extends BasePlayer {
|
|
|
1094
1203
|
this.debugWarn('Could not get YouTube title from oembed API:', error);
|
|
1095
1204
|
}
|
|
1096
1205
|
}
|
|
1097
|
-
extractYouTubeAvailableQualities(retryCount = 0) {
|
|
1098
|
-
if (!this.youtubePlayer || !this.youtubePlayerReady) {
|
|
1099
|
-
this.debugLog('YouTube player not ready for quality extraction');
|
|
1100
|
-
return;
|
|
1101
|
-
}
|
|
1102
|
-
try {
|
|
1103
|
-
const availableQualityLevels = this.youtubePlayer.getAvailableQualityLevels();
|
|
1104
|
-
this.debugLog('🔍 YouTube quality detection attempt', retryCount + 1, '- Found levels:', availableQualityLevels);
|
|
1105
|
-
this.debugLog('🔍 YouTube player state:', this.youtubePlayer.getPlayerState());
|
|
1106
|
-
this.debugLog('🔍 Current YouTube quality:', this.youtubePlayer.getPlaybackQuality());
|
|
1107
|
-
if ((!availableQualityLevels || availableQualityLevels.length === 0 || (availableQualityLevels.length === 1 && availableQualityLevels[0] === 'auto')) && retryCount < 5) {
|
|
1108
|
-
this.debugLog('No meaningful qualities detected, retrying in', (retryCount + 1) * 1000, 'ms...');
|
|
1109
|
-
setTimeout(() => {
|
|
1110
|
-
this.extractYouTubeAvailableQualities(retryCount + 1);
|
|
1111
|
-
}, (retryCount + 1) * 1000);
|
|
1112
|
-
return;
|
|
1113
|
-
}
|
|
1114
|
-
const qualityMap = {
|
|
1115
|
-
'hd2160': { label: '4K', value: 'hd2160', height: 2160 },
|
|
1116
|
-
'hd1440': { label: '1440p', value: 'hd1440', height: 1440 },
|
|
1117
|
-
'hd1080': { label: '1080p', value: 'hd1080', height: 1080 },
|
|
1118
|
-
'hd720': { label: '720p', value: 'hd720', height: 720 },
|
|
1119
|
-
'large': { label: '480p', value: 'large', height: 480 },
|
|
1120
|
-
'medium': { label: '360p', value: 'medium', height: 360 },
|
|
1121
|
-
'small': { label: '240p', value: 'small', height: 240 },
|
|
1122
|
-
'tiny': { label: '144p', value: 'tiny', height: 144 },
|
|
1123
|
-
'auto': { label: 'Auto', value: 'auto', height: 0 }
|
|
1124
|
-
};
|
|
1125
|
-
this.youtubeAvailableQualities = [];
|
|
1126
|
-
this.youtubeAvailableQualities.push({ label: 'Auto', value: 'auto', height: 0 });
|
|
1127
|
-
if (availableQualityLevels && availableQualityLevels.length > 0) {
|
|
1128
|
-
availableQualityLevels.forEach((qualityLevel) => {
|
|
1129
|
-
if (qualityLevel !== 'auto' && qualityMap[qualityLevel]) {
|
|
1130
|
-
this.youtubeAvailableQualities.push(qualityMap[qualityLevel]);
|
|
1131
|
-
}
|
|
1132
|
-
});
|
|
1133
|
-
const autoQuality = this.youtubeAvailableQualities.shift();
|
|
1134
|
-
this.youtubeAvailableQualities.sort((a, b) => (b.height || 0) - (a.height || 0));
|
|
1135
|
-
if (autoQuality)
|
|
1136
|
-
this.youtubeAvailableQualities.unshift(autoQuality);
|
|
1137
|
-
}
|
|
1138
|
-
this.debugLog('✅ Successfully mapped YouTube qualities:', this.youtubeAvailableQualities);
|
|
1139
|
-
try {
|
|
1140
|
-
const currentQuality = this.youtubePlayer.getPlaybackQuality();
|
|
1141
|
-
this.youtubeCurrentQuality = qualityMap[currentQuality] || qualityMap['auto'];
|
|
1142
|
-
this.debugLog('Current YouTube quality:', this.youtubeCurrentQuality);
|
|
1143
|
-
}
|
|
1144
|
-
catch (e) {
|
|
1145
|
-
this.debugWarn('Could not get current YouTube quality:', e);
|
|
1146
|
-
this.youtubeCurrentQuality = qualityMap['auto'];
|
|
1147
|
-
}
|
|
1148
|
-
this.detectAvailableQualities();
|
|
1149
|
-
this.debugLog('🚀 YouTube qualities successfully detected! Available qualities now:', this.availableQualities.length);
|
|
1150
|
-
this.updateQualityBadge();
|
|
1151
|
-
setTimeout(() => {
|
|
1152
|
-
this.debugLog('🔄 Force refreshing settings menu with YouTube qualities');
|
|
1153
|
-
this.updateSettingsMenu();
|
|
1154
|
-
}, 100);
|
|
1155
|
-
}
|
|
1156
|
-
catch (error) {
|
|
1157
|
-
this.debugWarn('Could not extract YouTube qualities:', error);
|
|
1158
|
-
if (retryCount < 3) {
|
|
1159
|
-
setTimeout(() => {
|
|
1160
|
-
this.extractYouTubeAvailableQualities(retryCount + 1);
|
|
1161
|
-
}, 2000);
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
setYouTubeQuality(qualityLevel) {
|
|
1166
|
-
if (!this.youtubePlayer)
|
|
1167
|
-
return;
|
|
1168
|
-
try {
|
|
1169
|
-
const qualityMap = {
|
|
1170
|
-
'hd2160': { label: '4K', value: 'hd2160', height: 2160 },
|
|
1171
|
-
'hd1440': { label: '1440p', value: 'hd1440', height: 1440 },
|
|
1172
|
-
'hd1080': { label: '1080p', value: 'hd1080', height: 1080 },
|
|
1173
|
-
'hd720': { label: '720p', value: 'hd720', height: 720 },
|
|
1174
|
-
'large': { label: '480p', value: 'large', height: 480 },
|
|
1175
|
-
'medium': { label: '360p', value: 'medium', height: 360 },
|
|
1176
|
-
'small': { label: '240p', value: 'small', height: 240 },
|
|
1177
|
-
'tiny': { label: '144p', value: 'tiny', height: 144 },
|
|
1178
|
-
'auto': { label: 'Auto', value: 'auto', height: 0 }
|
|
1179
|
-
};
|
|
1180
|
-
this.debugLog('📊 Attempting to set YouTube quality to:', qualityLevel);
|
|
1181
|
-
if (qualityLevel === 'auto') {
|
|
1182
|
-
this.youtubePlayer.setPlaybackQuality(qualityLevel);
|
|
1183
|
-
}
|
|
1184
|
-
else {
|
|
1185
|
-
try {
|
|
1186
|
-
if (typeof this.youtubePlayer.setPlaybackQualityRange === 'function') {
|
|
1187
|
-
this.youtubePlayer.setPlaybackQualityRange(qualityLevel, qualityLevel);
|
|
1188
|
-
this.debugLog('✅ setPlaybackQualityRange called for:', qualityLevel);
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
catch (e) {
|
|
1192
|
-
this.debugWarn('setPlaybackQualityRange failed:', e);
|
|
1193
|
-
}
|
|
1194
|
-
try {
|
|
1195
|
-
this.youtubePlayer.setPlaybackQuality(qualityLevel);
|
|
1196
|
-
this.debugLog('✅ setPlaybackQuality called for:', qualityLevel);
|
|
1197
|
-
}
|
|
1198
|
-
catch (e) {
|
|
1199
|
-
this.debugWarn('setPlaybackQuality failed:', e);
|
|
1200
|
-
}
|
|
1201
|
-
try {
|
|
1202
|
-
const wasPlaying = this.youtubePlayer.getPlayerState() === window.YT.PlayerState.PLAYING;
|
|
1203
|
-
if (wasPlaying) {
|
|
1204
|
-
this.youtubePlayer.pauseVideo();
|
|
1205
|
-
setTimeout(() => {
|
|
1206
|
-
this.youtubePlayer.setPlaybackQuality(qualityLevel);
|
|
1207
|
-
this.youtubePlayer.playVideo();
|
|
1208
|
-
}, 100);
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
catch (e) {
|
|
1212
|
-
this.debugWarn('Force quality change with pause/play failed:', e);
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
setTimeout(() => {
|
|
1216
|
-
try {
|
|
1217
|
-
const currentQuality = this.youtubePlayer.getPlaybackQuality();
|
|
1218
|
-
this.youtubeCurrentQuality = qualityMap[currentQuality] || qualityMap['auto'];
|
|
1219
|
-
this.debugLog('📊 Current quality after set:', currentQuality, '(', this.youtubeCurrentQuality?.label, ')');
|
|
1220
|
-
if (currentQuality === qualityLevel) {
|
|
1221
|
-
this.showNotification(`Quality: ${qualityMap[currentQuality]?.label || 'requested quality'}`);
|
|
1222
|
-
this.debugLog('✅ Quality successfully changed to:', qualityLevel);
|
|
1223
|
-
}
|
|
1224
|
-
else {
|
|
1225
|
-
this.showNotification(`Quality: ${qualityMap[currentQuality]?.label || currentQuality}`);
|
|
1226
|
-
this.debugLog('⚠️ Requested quality:', qualityLevel, '| Actual quality:', currentQuality, '(YouTube may have optimized)');
|
|
1227
|
-
}
|
|
1228
|
-
this.updateQualityBadge();
|
|
1229
|
-
this.updateSettingsMenu();
|
|
1230
|
-
}
|
|
1231
|
-
catch (verifyError) {
|
|
1232
|
-
this.debugWarn('Could not verify YouTube quality:', verifyError);
|
|
1233
|
-
}
|
|
1234
|
-
}, 1000);
|
|
1235
|
-
}
|
|
1236
|
-
catch (error) {
|
|
1237
|
-
this.debugWarn('❌ Could not set YouTube quality:', error);
|
|
1238
|
-
this.showNotification('Quality control limited on YouTube');
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
updateQualityBadge() {
|
|
1242
|
-
const qualityBadge = document.getElementById('uvf-quality-badge');
|
|
1243
|
-
if (!qualityBadge)
|
|
1244
|
-
return;
|
|
1245
|
-
if (this.youtubePlayer && this.youtubePlayerReady && this.youtubeCurrentQuality) {
|
|
1246
|
-
qualityBadge.textContent = this.youtubeCurrentQuality.label || 'AUTO';
|
|
1247
|
-
this.debugLog('Updated quality badge for YouTube:', this.youtubeCurrentQuality.label);
|
|
1248
|
-
}
|
|
1249
|
-
else if (this.currentQualityIndex >= 0 && this.qualities[this.currentQualityIndex]) {
|
|
1250
|
-
const quality = this.qualities[this.currentQualityIndex];
|
|
1251
|
-
qualityBadge.textContent = quality.label || 'HD';
|
|
1252
|
-
this.debugLog('Updated quality badge for standard video:', quality.label);
|
|
1253
|
-
}
|
|
1254
|
-
else {
|
|
1255
|
-
qualityBadge.textContent = 'AUTO';
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
1206
|
startYouTubeTimeTracking() {
|
|
1259
1207
|
if (this.youtubeTimeTrackingInterval) {
|
|
1260
1208
|
clearInterval(this.youtubeTimeTrackingInterval);
|
|
1261
1209
|
}
|
|
1262
|
-
let qualityCheckCounter = 0;
|
|
1263
1210
|
this.youtubeTimeTrackingInterval = setInterval(() => {
|
|
1264
1211
|
if (this.youtubePlayer && this.youtubePlayerReady) {
|
|
1265
1212
|
try {
|
|
@@ -1269,12 +1216,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
1269
1216
|
this.state.currentTime = currentTime || 0;
|
|
1270
1217
|
this.state.duration = duration || 0;
|
|
1271
1218
|
this.state.bufferedPercentage = buffered || 0;
|
|
1272
|
-
qualityCheckCounter++;
|
|
1273
|
-
if (qualityCheckCounter >= 40 && this.youtubeAvailableQualities.length <= 1) {
|
|
1274
|
-
this.debugLog('Periodic YouTube quality check triggered');
|
|
1275
|
-
this.extractYouTubeAvailableQualities();
|
|
1276
|
-
qualityCheckCounter = 0;
|
|
1277
|
-
}
|
|
1278
1219
|
this.updateYouTubeProgressBar(currentTime, duration, buffered);
|
|
1279
1220
|
this.emit('onTimeUpdate', this.state.currentTime);
|
|
1280
1221
|
this.emit('onProgress', this.state.bufferedPercentage);
|
|
@@ -8136,18 +8077,13 @@ export class WebPlayer extends BasePlayer {
|
|
|
8136
8077
|
}
|
|
8137
8078
|
setQualityByLabel(quality) {
|
|
8138
8079
|
if (this.youtubePlayer && this.youtubePlayerReady) {
|
|
8139
|
-
this.
|
|
8080
|
+
this.showShortcutIndicator('Quality control not available for YouTube');
|
|
8140
8081
|
document.querySelectorAll('.quality-option').forEach(option => {
|
|
8141
8082
|
option.classList.remove('active');
|
|
8142
|
-
if (option.dataset.quality ===
|
|
8083
|
+
if (option.dataset.quality === 'auto') {
|
|
8143
8084
|
option.classList.add('active');
|
|
8144
8085
|
}
|
|
8145
8086
|
});
|
|
8146
|
-
const qualityBadge = document.getElementById('uvf-quality-badge');
|
|
8147
|
-
if (qualityBadge) {
|
|
8148
|
-
const qualityOption = this.youtubeAvailableQualities.find(q => q.value === quality);
|
|
8149
|
-
qualityBadge.textContent = qualityOption ? qualityOption.label : 'AUTO';
|
|
8150
|
-
}
|
|
8151
8087
|
return;
|
|
8152
8088
|
}
|
|
8153
8089
|
const qualityBadge = document.getElementById('uvf-quality-badge');
|
|
@@ -8448,13 +8384,8 @@ export class WebPlayer extends BasePlayer {
|
|
|
8448
8384
|
</div>`;
|
|
8449
8385
|
}
|
|
8450
8386
|
if (this.settingsConfig.quality && this.availableQualities.length > 0) {
|
|
8451
|
-
|
|
8452
|
-
const qualityForDisplay = this.youtubePlayer && this.youtubePlayerReady && this.youtubeCurrentQuality
|
|
8453
|
-
? this.youtubeCurrentQuality.value
|
|
8454
|
-
: this.currentQuality;
|
|
8455
|
-
const currentQuality = this.availableQualities.find(q => q.value === qualityForDisplay);
|
|
8387
|
+
const currentQuality = this.availableQualities.find(q => q.value === this.currentQuality);
|
|
8456
8388
|
const currentQualityLabel = currentQuality ? currentQuality.label : 'Auto';
|
|
8457
|
-
this.debugLog('🎛️ Current quality for display:', qualityForDisplay, '(', currentQualityLabel, ')');
|
|
8458
8389
|
menuHTML += `
|
|
8459
8390
|
<div class="uvf-accordion-item">
|
|
8460
8391
|
<div class="uvf-accordion-header" data-section="quality">
|
|
@@ -8471,10 +8402,7 @@ export class WebPlayer extends BasePlayer {
|
|
|
8471
8402
|
</div>
|
|
8472
8403
|
<div class="uvf-accordion-content" data-section="quality">`;
|
|
8473
8404
|
this.availableQualities.forEach(quality => {
|
|
8474
|
-
const
|
|
8475
|
-
? this.youtubeCurrentQuality.value
|
|
8476
|
-
: this.currentQuality;
|
|
8477
|
-
const isActive = quality.value === qualityValue ? 'active' : '';
|
|
8405
|
+
const isActive = quality.value === this.currentQuality ? 'active' : '';
|
|
8478
8406
|
const isPremium = this.isQualityPremium(quality);
|
|
8479
8407
|
const isLocked = isPremium && !this.isPremiumUser();
|
|
8480
8408
|
const qualityHeight = quality.height || 0;
|
|
@@ -8524,20 +8452,9 @@ export class WebPlayer extends BasePlayer {
|
|
|
8524
8452
|
this.debugLog('Settings event listeners setup complete');
|
|
8525
8453
|
}
|
|
8526
8454
|
detectAvailableQualities() {
|
|
8527
|
-
|
|
8528
|
-
this.availableQualities = [];
|
|
8455
|
+
this.availableQualities = [{ value: 'auto', label: 'Auto' }];
|
|
8529
8456
|
let detectedQualities = [];
|
|
8530
|
-
if (
|
|
8531
|
-
detectedQualities = this.youtubeAvailableQualities.map(q => ({
|
|
8532
|
-
value: q.value,
|
|
8533
|
-
label: q.label,
|
|
8534
|
-
height: q.height
|
|
8535
|
-
}));
|
|
8536
|
-
this.debugLog('Using YouTube qualities:', detectedQualities);
|
|
8537
|
-
this.availableQualities = detectedQualities;
|
|
8538
|
-
return;
|
|
8539
|
-
}
|
|
8540
|
-
else if (this.hls && this.hls.levels) {
|
|
8457
|
+
if (this.hls && this.hls.levels) {
|
|
8541
8458
|
this.hls.levels.forEach((level, index) => {
|
|
8542
8459
|
if (level.height) {
|
|
8543
8460
|
detectedQualities.push({
|
|
@@ -8782,11 +8699,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
8782
8699
|
}
|
|
8783
8700
|
setQualityFromSettings(quality) {
|
|
8784
8701
|
this.currentQuality = quality;
|
|
8785
|
-
if (this.youtubePlayer && this.youtubePlayerReady) {
|
|
8786
|
-
this.setYouTubeQuality(quality);
|
|
8787
|
-
this.debugLog(`YouTube quality set to ${quality}`);
|
|
8788
|
-
return;
|
|
8789
|
-
}
|
|
8790
8702
|
if (quality === 'auto') {
|
|
8791
8703
|
if (this.hls) {
|
|
8792
8704
|
if (this.qualityFilter) {
|