unified-video-framework 1.4.256 → 1.4.258

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.
@@ -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.youtubeAvailableQualities = [];
98
- this.youtubeCurrentQuality = null;
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 === true ? 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.extractYouTubeAvailableQualities();
956
+ this.detectYouTubeLiveStatus();
957
957
  this.getYouTubeVideoTitle();
958
958
  setTimeout(() => {
959
959
  this.updateMetadataUI();
960
- this.updateSettingsMenu();
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.getYouTubeVideoTitle();
1006
- }, 100);
999
+ this.detectYouTubeLiveStatus();
1000
+ this.updateControlsVisibility();
1001
+ }, 500);
1007
1002
  break;
1008
1003
  }
1009
1004
  }
@@ -1072,258 +1067,202 @@ export class WebPlayer extends BasePlayer {
1072
1067
  this.getYouTubeVideoTitleFromOEmbed();
1073
1068
  }
1074
1069
  }
1075
- async getYouTubeVideoTitleFromOEmbed() {
1076
- if (!this.source?.metadata?.videoId)
1070
+ detectYouTubeLiveStatus() {
1071
+ if (!this.youtubePlayer || !this.youtubePlayerReady)
1077
1072
  return;
1078
1073
  try {
1079
- const videoId = this.source.metadata.videoId;
1080
- const oembedUrl = `https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=${videoId}&format=json`;
1081
- const response = await fetch(oembedUrl);
1082
- if (response.ok) {
1083
- const data = await response.json();
1084
- if (data.title) {
1085
- this.debugLog('Got YouTube title from oembed API:', data.title);
1086
- if (this.source && this.source.metadata) {
1087
- this.source.metadata.title = data.title;
1088
- }
1089
- this.updateMetadataUI();
1090
- }
1091
- }
1074
+ const videoData = this.youtubePlayer.getVideoData();
1075
+ this.isYouTubeLive = videoData?.isLive || false;
1076
+ this.useYouTubeNativeControls = this.config.youtubeNativeControls === true;
1077
+ this.debugLog('YouTube Live status:', {
1078
+ isLive: this.isYouTubeLive,
1079
+ useNativeControls: this.useYouTubeNativeControls,
1080
+ videoId: videoData?.video_id
1081
+ });
1092
1082
  }
1093
1083
  catch (error) {
1094
- this.debugWarn('Could not get YouTube title from oembed API:', error);
1095
- }
1096
- }
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);
1084
+ this.debugWarn('Could not detect YouTube Live status:', error);
1139
1085
  try {
1140
- const currentQuality = this.youtubePlayer.getPlaybackQuality();
1141
- this.youtubeCurrentQuality = qualityMap[currentQuality] || qualityMap['auto'];
1142
- this.debugLog('Current YouTube quality:', this.youtubeCurrentQuality);
1086
+ const duration = this.youtubePlayer.getDuration();
1087
+ this.isYouTubeLive = !duration || duration === 0;
1088
+ this.useYouTubeNativeControls = this.config.youtubeNativeControls === true;
1089
+ this.debugLog('YouTube Live detected via duration check:', {
1090
+ duration,
1091
+ isLive: this.isYouTubeLive,
1092
+ useNativeControls: this.useYouTubeNativeControls
1093
+ });
1143
1094
  }
1144
1095
  catch (e) {
1145
- this.debugWarn('Could not get current YouTube quality:', e);
1146
- this.youtubeCurrentQuality = qualityMap['auto'];
1096
+ this.debugWarn('Could not check YouTube duration for Live detection:', e);
1147
1097
  }
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
1098
  }
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);
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 === false) {
1107
+ this.recreateYouTubePlayerWithNativeControls();
1108
+ }
1109
+ this.debugLog('✅ YouTube native controls enabled', {
1110
+ isLive: this.isYouTubeLive,
1111
+ reason: this.config.youtubeNativeControls === true ? 'Explicitly enabled in config' : 'Live stream detected'
1112
+ });
1113
+ }
1114
+ else {
1115
+ controlsContainer.style.display = 'flex';
1116
+ if (this.config.youtubeNativeControls === true) {
1117
+ this.recreateYouTubePlayerWithoutNativeControls();
1162
1118
  }
1119
+ this.debugLog('✅ Custom controls enabled for YouTube video');
1163
1120
  }
1164
1121
  }
1165
- setYouTubeQuality(qualityLevel) {
1166
- if (!this.youtubePlayer)
1122
+ recreateYouTubePlayerWithNativeControls() {
1123
+ if (!this.source?.metadata?.videoId)
1167
1124
  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 currentTime = this.youtubePlayer.getCurrentTime();
1203
- const wasPlaying = this.youtubePlayer.getPlayerState() === window.YT.PlayerState.PLAYING;
1204
- this.youtubePlayer.seekTo(currentTime + 0.1, true);
1205
- setTimeout(() => {
1206
- this.youtubePlayer.setPlaybackQuality(qualityLevel);
1207
- setTimeout(() => {
1208
- this.youtubePlayer.seekTo(currentTime, true);
1209
- if (!wasPlaying) {
1210
- this.youtubePlayer.pauseVideo();
1211
- }
1212
- }, 100);
1213
- }, 50);
1214
- this.debugLog('🔄 Applied seekTo trick for quality change');
1215
- }
1216
- catch (e) {
1217
- this.debugWarn('Force quality change with seekTo trick failed:', e);
1218
- }
1219
- }
1220
- this.verifyYouTubeQualityChange(qualityLevel, qualityMap, 0);
1125
+ const videoId = this.source.metadata.videoId;
1126
+ const currentTime = this.youtubePlayer?.getCurrentTime() || 0;
1127
+ const container = this.playerWrapper || this.video?.parentElement;
1128
+ if (!container)
1129
+ return;
1130
+ if (this.youtubePlayer) {
1131
+ this.youtubePlayer.destroy();
1221
1132
  }
1222
- catch (error) {
1223
- this.debugWarn('❌ Could not set YouTube quality:', error);
1224
- this.showNotification('Quality control limited on YouTube');
1133
+ const existingContainer = container.querySelector(`#youtube-player-${videoId}`);
1134
+ if (existingContainer) {
1135
+ existingContainer.remove();
1225
1136
  }
1226
- }
1227
- verifyYouTubeQualityChange(requestedQuality, qualityMap, attempt) {
1228
- const maxAttempts = 3;
1229
- const delays = [500, 1500, 3000];
1230
- setTimeout(() => {
1231
- try {
1232
- const currentQuality = this.youtubePlayer.getPlaybackQuality();
1233
- this.youtubeCurrentQuality = qualityMap[currentQuality] || qualityMap['auto'];
1234
- this.debugLog('🔍 Quality verification attempt', attempt + 1, '- Requested:', requestedQuality, '| Current:', currentQuality);
1235
- if (currentQuality === requestedQuality || attempt >= maxAttempts - 1) {
1236
- if (currentQuality === requestedQuality) {
1237
- this.showNotification(`Quality: ${qualityMap[currentQuality]?.label || 'requested quality'}`);
1238
- this.debugLog('✅ Quality successfully changed to:', requestedQuality);
1239
- }
1240
- else {
1241
- if (attempt === maxAttempts - 1) {
1242
- this.debugLog('🔥 Final attempt: Trying loadVideoById method');
1243
- try {
1244
- const videoData = this.youtubePlayer.getVideoData();
1245
- const currentTime = this.youtubePlayer.getCurrentTime();
1246
- this.youtubePlayer.loadVideoById({
1247
- videoId: videoData.video_id,
1248
- startSeconds: currentTime,
1249
- suggestedQuality: requestedQuality
1250
- });
1251
- this.debugLog('🔄 Video reloaded with suggested quality:', requestedQuality);
1252
- }
1253
- catch (e) {
1254
- this.debugWarn('loadVideoById method failed:', e);
1255
- }
1256
- }
1257
- this.showNotification(`Quality: ${qualityMap[currentQuality]?.label || currentQuality}`);
1258
- this.debugLog('⚠️ Quality change may not have worked. Requested:', requestedQuality, '| Current:', currentQuality);
1259
- }
1260
- this.updateQualityBadge();
1261
- this.updateSettingsMenu();
1262
- }
1263
- else {
1264
- this.debugLog('🔁 Quality not changed, retrying with method', attempt + 2);
1265
- this.retryYouTubeQualityChange(requestedQuality, qualityMap, attempt + 1);
1266
- this.verifyYouTubeQualityChange(requestedQuality, qualityMap, attempt + 1);
1267
- }
1268
- }
1269
- catch (verifyError) {
1270
- this.debugWarn('Could not verify YouTube quality:', verifyError);
1271
- if (attempt === maxAttempts - 1) {
1272
- this.showNotification('Quality change attempted');
1273
- this.updateQualityBadge();
1274
- this.updateSettingsMenu();
1275
- }
1137
+ const iframeContainer = document.createElement('div');
1138
+ iframeContainer.id = `youtube-player-${videoId}`;
1139
+ iframeContainer.style.cssText = `
1140
+ position: absolute;
1141
+ top: 0;
1142
+ left: 0;
1143
+ width: 100%;
1144
+ height: 100%;
1145
+ z-index: 1;
1146
+ `;
1147
+ container.appendChild(iframeContainer);
1148
+ this.youtubePlayer = new window.YT.Player(iframeContainer.id, {
1149
+ videoId: videoId,
1150
+ width: '100%',
1151
+ height: '100%',
1152
+ playerVars: {
1153
+ autoplay: this.config.autoPlay ? 1 : 0,
1154
+ controls: 1,
1155
+ modestbranding: 1,
1156
+ rel: 0,
1157
+ showinfo: 0,
1158
+ iv_load_policy: 3,
1159
+ playsinline: 1,
1160
+ start: Math.floor(currentTime)
1161
+ },
1162
+ events: {
1163
+ onReady: () => {
1164
+ this.youtubePlayerReady = true;
1165
+ this.debugLog('YouTube player with native controls ready');
1166
+ this.emit('onReady');
1167
+ },
1168
+ onStateChange: (event) => this.onYouTubePlayerStateChange(event),
1169
+ onError: (event) => this.onYouTubePlayerError(event)
1276
1170
  }
1277
- }, delays[attempt] || 1000);
1171
+ });
1278
1172
  }
1279
- retryYouTubeQualityChange(qualityLevel, qualityMap, attempt) {
1280
- try {
1281
- if (attempt === 1) {
1282
- this.debugLog('🔄 Retry attempt 1: Using cueVideoById');
1283
- const videoData = this.youtubePlayer.getVideoData();
1284
- const currentTime = this.youtubePlayer.getCurrentTime();
1285
- this.youtubePlayer.cueVideoById({
1286
- videoId: videoData.video_id,
1287
- startSeconds: currentTime,
1288
- suggestedQuality: qualityLevel
1289
- });
1290
- setTimeout(() => this.youtubePlayer.playVideo(), 100);
1291
- }
1292
- else if (attempt === 2) {
1293
- this.debugLog('🔄 Retry attempt 2: Multiple sequential calls');
1294
- for (let i = 0; i < 3; i++) {
1295
- setTimeout(() => {
1296
- this.youtubePlayer.setPlaybackQuality(qualityLevel);
1297
- }, i * 100);
1298
- }
1299
- }
1173
+ recreateYouTubePlayerWithoutNativeControls() {
1174
+ if (!this.source?.metadata?.videoId)
1175
+ return;
1176
+ const videoId = this.source.metadata.videoId;
1177
+ const currentTime = this.youtubePlayer?.getCurrentTime() || 0;
1178
+ const container = this.playerWrapper || this.video?.parentElement;
1179
+ if (!container)
1180
+ return;
1181
+ if (this.youtubePlayer) {
1182
+ this.youtubePlayer.destroy();
1300
1183
  }
1301
- catch (e) {
1302
- this.debugWarn('Retry attempt', attempt, 'failed:', e);
1184
+ const existingContainer = container.querySelector(`#youtube-player-${videoId}`);
1185
+ if (existingContainer) {
1186
+ existingContainer.remove();
1303
1187
  }
1188
+ const iframeContainer = document.createElement('div');
1189
+ iframeContainer.id = `youtube-player-${videoId}`;
1190
+ iframeContainer.style.cssText = `
1191
+ position: absolute;
1192
+ top: 0;
1193
+ left: 0;
1194
+ width: 100%;
1195
+ height: 100%;
1196
+ z-index: 1;
1197
+ `;
1198
+ container.appendChild(iframeContainer);
1199
+ this.youtubePlayer = new window.YT.Player(iframeContainer.id, {
1200
+ videoId: videoId,
1201
+ width: '100%',
1202
+ height: '100%',
1203
+ playerVars: {
1204
+ autoplay: this.config.autoPlay ? 1 : 0,
1205
+ controls: 0,
1206
+ disablekb: 0,
1207
+ fs: 0,
1208
+ iv_load_policy: 3,
1209
+ modestbranding: 1,
1210
+ rel: 0,
1211
+ showinfo: 0,
1212
+ playsinline: 1,
1213
+ start: Math.floor(currentTime)
1214
+ },
1215
+ events: {
1216
+ onReady: () => {
1217
+ this.youtubePlayerReady = true;
1218
+ this.debugLog('YouTube player without native controls ready');
1219
+ this.emit('onReady');
1220
+ },
1221
+ onStateChange: (event) => this.onYouTubePlayerStateChange(event),
1222
+ onError: (event) => this.onYouTubePlayerError(event)
1223
+ }
1224
+ });
1304
1225
  }
1305
- updateQualityBadge() {
1306
- const qualityBadge = document.getElementById('uvf-quality-badge');
1307
- if (!qualityBadge)
1226
+ toggleYouTubeControls(useNative = !this.useYouTubeNativeControls) {
1227
+ if (!this.youtubePlayer) {
1228
+ this.debugWarn('Cannot toggle YouTube controls - no YouTube player active');
1308
1229
  return;
1309
- if (this.youtubePlayer && this.youtubePlayerReady && this.youtubeCurrentQuality) {
1310
- qualityBadge.textContent = this.youtubeCurrentQuality.label || 'AUTO';
1311
- this.debugLog('Updated quality badge for YouTube:', this.youtubeCurrentQuality.label);
1312
1230
  }
1313
- else if (this.currentQualityIndex >= 0 && this.qualities[this.currentQualityIndex]) {
1314
- const quality = this.qualities[this.currentQualityIndex];
1315
- qualityBadge.textContent = quality.label || 'HD';
1316
- this.debugLog('Updated quality badge for standard video:', quality.label);
1231
+ this.useYouTubeNativeControls = useNative;
1232
+ this.config.youtubeNativeControls = useNative;
1233
+ this.updateControlsVisibility();
1234
+ this.debugLog('YouTube controls toggled:', {
1235
+ useNative: this.useYouTubeNativeControls,
1236
+ isLive: this.isYouTubeLive
1237
+ });
1238
+ this.showNotification(`YouTube Controls: ${this.useYouTubeNativeControls ? 'Native' : 'Custom'}`);
1239
+ }
1240
+ async getYouTubeVideoTitleFromOEmbed() {
1241
+ if (!this.source?.metadata?.videoId)
1242
+ return;
1243
+ try {
1244
+ const videoId = this.source.metadata.videoId;
1245
+ const oembedUrl = `https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=${videoId}&format=json`;
1246
+ const response = await fetch(oembedUrl);
1247
+ if (response.ok) {
1248
+ const data = await response.json();
1249
+ if (data.title) {
1250
+ this.debugLog('Got YouTube title from oembed API:', data.title);
1251
+ if (this.source && this.source.metadata) {
1252
+ this.source.metadata.title = data.title;
1253
+ }
1254
+ this.updateMetadataUI();
1255
+ }
1256
+ }
1317
1257
  }
1318
- else {
1319
- qualityBadge.textContent = 'AUTO';
1258
+ catch (error) {
1259
+ this.debugWarn('Could not get YouTube title from oembed API:', error);
1320
1260
  }
1321
1261
  }
1322
1262
  startYouTubeTimeTracking() {
1323
1263
  if (this.youtubeTimeTrackingInterval) {
1324
1264
  clearInterval(this.youtubeTimeTrackingInterval);
1325
1265
  }
1326
- let qualityCheckCounter = 0;
1327
1266
  this.youtubeTimeTrackingInterval = setInterval(() => {
1328
1267
  if (this.youtubePlayer && this.youtubePlayerReady) {
1329
1268
  try {
@@ -1333,12 +1272,6 @@ export class WebPlayer extends BasePlayer {
1333
1272
  this.state.currentTime = currentTime || 0;
1334
1273
  this.state.duration = duration || 0;
1335
1274
  this.state.bufferedPercentage = buffered || 0;
1336
- qualityCheckCounter++;
1337
- if (qualityCheckCounter >= 40 && this.youtubeAvailableQualities.length <= 1) {
1338
- this.debugLog('Periodic YouTube quality check triggered');
1339
- this.extractYouTubeAvailableQualities();
1340
- qualityCheckCounter = 0;
1341
- }
1342
1275
  this.updateYouTubeProgressBar(currentTime, duration, buffered);
1343
1276
  this.emit('onTimeUpdate', this.state.currentTime);
1344
1277
  this.emit('onProgress', this.state.bufferedPercentage);
@@ -8200,18 +8133,13 @@ export class WebPlayer extends BasePlayer {
8200
8133
  }
8201
8134
  setQualityByLabel(quality) {
8202
8135
  if (this.youtubePlayer && this.youtubePlayerReady) {
8203
- this.setYouTubeQuality(quality);
8136
+ this.showShortcutIndicator('Quality control not available for YouTube');
8204
8137
  document.querySelectorAll('.quality-option').forEach(option => {
8205
8138
  option.classList.remove('active');
8206
- if (option.dataset.quality === quality) {
8139
+ if (option.dataset.quality === 'auto') {
8207
8140
  option.classList.add('active');
8208
8141
  }
8209
8142
  });
8210
- const qualityBadge = document.getElementById('uvf-quality-badge');
8211
- if (qualityBadge) {
8212
- const qualityOption = this.youtubeAvailableQualities.find(q => q.value === quality);
8213
- qualityBadge.textContent = qualityOption ? qualityOption.label : 'AUTO';
8214
- }
8215
8143
  return;
8216
8144
  }
8217
8145
  const qualityBadge = document.getElementById('uvf-quality-badge');
@@ -8512,13 +8440,8 @@ export class WebPlayer extends BasePlayer {
8512
8440
  </div>`;
8513
8441
  }
8514
8442
  if (this.settingsConfig.quality && this.availableQualities.length > 0) {
8515
- this.debugLog('🎛️ Building quality menu with', this.availableQualities.length, 'qualities:', this.availableQualities.map(q => q.label));
8516
- const qualityForDisplay = this.youtubePlayer && this.youtubePlayerReady && this.youtubeCurrentQuality
8517
- ? this.youtubeCurrentQuality.value
8518
- : this.currentQuality;
8519
- const currentQuality = this.availableQualities.find(q => q.value === qualityForDisplay);
8443
+ const currentQuality = this.availableQualities.find(q => q.value === this.currentQuality);
8520
8444
  const currentQualityLabel = currentQuality ? currentQuality.label : 'Auto';
8521
- this.debugLog('🎛️ Current quality for display:', qualityForDisplay, '(', currentQualityLabel, ')');
8522
8445
  menuHTML += `
8523
8446
  <div class="uvf-accordion-item">
8524
8447
  <div class="uvf-accordion-header" data-section="quality">
@@ -8535,10 +8458,7 @@ export class WebPlayer extends BasePlayer {
8535
8458
  </div>
8536
8459
  <div class="uvf-accordion-content" data-section="quality">`;
8537
8460
  this.availableQualities.forEach(quality => {
8538
- const qualityValue = this.youtubePlayer && this.youtubePlayerReady && this.youtubeCurrentQuality
8539
- ? this.youtubeCurrentQuality.value
8540
- : this.currentQuality;
8541
- const isActive = quality.value === qualityValue ? 'active' : '';
8461
+ const isActive = quality.value === this.currentQuality ? 'active' : '';
8542
8462
  const isPremium = this.isQualityPremium(quality);
8543
8463
  const isLocked = isPremium && !this.isPremiumUser();
8544
8464
  const qualityHeight = quality.height || 0;
@@ -8588,20 +8508,9 @@ export class WebPlayer extends BasePlayer {
8588
8508
  this.debugLog('Settings event listeners setup complete');
8589
8509
  }
8590
8510
  detectAvailableQualities() {
8591
- const isYouTube = this.youtubePlayer && this.youtubePlayerReady && this.youtubeAvailableQualities.length > 0;
8592
- this.availableQualities = [];
8511
+ this.availableQualities = [{ value: 'auto', label: 'Auto' }];
8593
8512
  let detectedQualities = [];
8594
- if (isYouTube) {
8595
- detectedQualities = this.youtubeAvailableQualities.map(q => ({
8596
- value: q.value,
8597
- label: q.label,
8598
- height: q.height
8599
- }));
8600
- this.debugLog('Using YouTube qualities:', detectedQualities);
8601
- this.availableQualities = detectedQualities;
8602
- return;
8603
- }
8604
- else if (this.hls && this.hls.levels) {
8513
+ if (this.hls && this.hls.levels) {
8605
8514
  this.hls.levels.forEach((level, index) => {
8606
8515
  if (level.height) {
8607
8516
  detectedQualities.push({
@@ -8846,11 +8755,6 @@ export class WebPlayer extends BasePlayer {
8846
8755
  }
8847
8756
  setQualityFromSettings(quality) {
8848
8757
  this.currentQuality = quality;
8849
- if (this.youtubePlayer && this.youtubePlayerReady) {
8850
- this.setYouTubeQuality(quality);
8851
- this.debugLog(`YouTube quality set to ${quality}`);
8852
- return;
8853
- }
8854
8758
  if (quality === 'auto') {
8855
8759
  if (this.hls) {
8856
8760
  if (this.qualityFilter) {