myetv-player 1.6.1 → 1.6.3
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/css/myetv-player.css +317 -4
- package/css/myetv-player.min.css +1 -1
- package/dist/myetv-player.js +263 -85
- package/dist/myetv-player.min.js +214 -64
- package/package.json +3 -1
- package/plugins/iframe-ads/myetv-iframe-banner-ads.js +127 -16
package/dist/myetv-player.min.js
CHANGED
|
@@ -1170,13 +1170,31 @@ markPlayerReady() {
|
|
|
1170
1170
|
}
|
|
1171
1171
|
|
|
1172
1172
|
if (this.options.autoplay) {
|
|
1173
|
-
if (this.options.debug) console.log('
|
|
1173
|
+
if (this.options.debug) console.log('Autoplay enabled');
|
|
1174
1174
|
setTimeout(() => {
|
|
1175
|
-
this.video.play()
|
|
1176
|
-
|
|
1175
|
+
this.video.play()
|
|
1176
|
+
.then(() => {
|
|
1177
|
+
|
|
1178
|
+
if (this.options.debug) console.log('Autoplay started successfully');
|
|
1179
|
+
})
|
|
1180
|
+
.catch(error => {
|
|
1181
|
+
|
|
1182
|
+
if (this.options.debug) console.warn('Autoplay blocked', error);
|
|
1183
|
+
|
|
1184
|
+
if (this.options.autoHide && this.autoHideInitialized) {
|
|
1185
|
+
|
|
1186
|
+
this.showControlsNow();
|
|
1187
|
+
|
|
1188
|
+
this.resetAutoHideTimer();
|
|
1189
|
+
|
|
1190
|
+
if (this.options.debug) {
|
|
1191
|
+
console.log('Auto-hide timer started (autoplay blocked - video paused)');
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1177
1194
|
});
|
|
1178
1195
|
}, 100);
|
|
1179
1196
|
}
|
|
1197
|
+
|
|
1180
1198
|
}, 200);
|
|
1181
1199
|
|
|
1182
1200
|
}, 100);
|
|
@@ -1204,12 +1222,13 @@ createPlayerStructure() {
|
|
|
1204
1222
|
if (this.options.showTitleOverlay) {
|
|
1205
1223
|
this.createTitleOverlay();
|
|
1206
1224
|
}
|
|
1225
|
+
this.createTopBar();
|
|
1207
1226
|
}
|
|
1208
1227
|
|
|
1209
1228
|
createInitialLoading() {
|
|
1210
1229
|
const initialLoader = document.createElement('div');
|
|
1211
1230
|
initialLoader.className = 'initial-loading';
|
|
1212
|
-
initialLoader.innerHTML = '<div class="loading-spinner"></div>';
|
|
1231
|
+
initialLoader.innerHTML = '<div class="loading-spinner"></div><div class="loading-text"></div>';
|
|
1213
1232
|
this.container.appendChild(initialLoader);
|
|
1214
1233
|
this.initialLoading = initialLoader;
|
|
1215
1234
|
}
|
|
@@ -1222,7 +1241,7 @@ createLoadingOverlay() {
|
|
|
1222
1241
|
const overlay = document.createElement('div');
|
|
1223
1242
|
overlay.className = 'loading-overlay';
|
|
1224
1243
|
overlay.id = 'loadingOverlay-' + this.getUniqueId();
|
|
1225
|
-
overlay.innerHTML = '<div class="loading-spinner"></div>';
|
|
1244
|
+
overlay.innerHTML = '<div class="loading-spinner"></div><div class="loading-text"></div>';
|
|
1226
1245
|
this.container.appendChild(overlay);
|
|
1227
1246
|
this.loadingOverlay = overlay;
|
|
1228
1247
|
}
|
|
@@ -1261,17 +1280,25 @@ updateTooltips() {
|
|
|
1261
1280
|
if (!this.controls) return;
|
|
1262
1281
|
|
|
1263
1282
|
try {
|
|
1283
|
+
|
|
1264
1284
|
this.controls.querySelectorAll('[data-tooltip]').forEach(element => {
|
|
1265
1285
|
const key = element.getAttribute('data-tooltip');
|
|
1266
1286
|
element.title = this.t(key);
|
|
1267
1287
|
});
|
|
1268
1288
|
|
|
1289
|
+
if (this.topBar) {
|
|
1290
|
+
this.topBar.querySelectorAll('[data-tooltip]').forEach(element => {
|
|
1291
|
+
const key = element.getAttribute('data-tooltip');
|
|
1292
|
+
element.title = this.t(key);
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1269
1296
|
const autoOption = this.controls.querySelector('.quality-option[data-quality="auto"]');
|
|
1270
1297
|
if (autoOption) {
|
|
1271
1298
|
autoOption.textContent = this.t('auto');
|
|
1272
1299
|
}
|
|
1273
1300
|
} catch (error) {
|
|
1274
|
-
if (this.options.debug) console.warn('
|
|
1301
|
+
if (this.options.debug) console.warn('Tooltip update error', error);
|
|
1275
1302
|
}
|
|
1276
1303
|
}
|
|
1277
1304
|
|
|
@@ -1418,6 +1445,9 @@ initializeElements() {
|
|
|
1418
1445
|
this.qualityMenu = this.controls?.querySelector('.quality-menu');
|
|
1419
1446
|
this.subtitlesMenu = this.controls?.querySelector('.subtitles-menu');
|
|
1420
1447
|
|
|
1448
|
+
this.settingsBtn = this.container?.querySelector('.settings-btn');
|
|
1449
|
+
this.settingsMenu = this.container?.querySelector('.settings-menu');
|
|
1450
|
+
|
|
1421
1451
|
if (this.progressHandle && this.options.seekHandleShape) {
|
|
1422
1452
|
this.setSeekHandleShape(this.options.seekHandleShape);
|
|
1423
1453
|
}
|
|
@@ -1495,6 +1525,69 @@ setupMenuToggles() {
|
|
|
1495
1525
|
}
|
|
1496
1526
|
}
|
|
1497
1527
|
|
|
1528
|
+
createTopBar() {
|
|
1529
|
+
if (!this.container) return;
|
|
1530
|
+
|
|
1531
|
+
const topBar = document.createElement('div');
|
|
1532
|
+
topBar.className = 'player-top-bar';
|
|
1533
|
+
topBar.id = `topBar_${this.getUniqueId()}`;
|
|
1534
|
+
|
|
1535
|
+
if (this.options.showTitleOverlay && this.options.videoTitle) {
|
|
1536
|
+
const titleSection = document.createElement('div');
|
|
1537
|
+
titleSection.className = 'top-bar-title';
|
|
1538
|
+
|
|
1539
|
+
const titleElement = document.createElement('h3');
|
|
1540
|
+
titleElement.className = 'video-title';
|
|
1541
|
+
titleElement.textContent = this.decodeHTMLEntities(this.options.videoTitle);
|
|
1542
|
+
titleSection.appendChild(titleElement);
|
|
1543
|
+
|
|
1544
|
+
if (this.options.videoSubtitle) {
|
|
1545
|
+
const subtitleElement = document.createElement('span');
|
|
1546
|
+
subtitleElement.className = 'video-subtitle';
|
|
1547
|
+
subtitleElement.textContent = this.decodeHTMLEntities(this.options.videoSubtitle);
|
|
1548
|
+
titleSection.appendChild(subtitleElement);
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
topBar.appendChild(titleSection);
|
|
1552
|
+
} else {
|
|
1553
|
+
|
|
1554
|
+
const spacer = document.createElement('div');
|
|
1555
|
+
spacer.className = 'top-bar-spacer';
|
|
1556
|
+
topBar.appendChild(spacer);
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
const settingsControl = document.createElement('div');
|
|
1560
|
+
settingsControl.className = 'settings-control settings-top-bar';
|
|
1561
|
+
|
|
1562
|
+
const settingsBtn = document.createElement('button');
|
|
1563
|
+
settingsBtn.className = 'control-btn settings-btn';
|
|
1564
|
+
settingsBtn.setAttribute('data-tooltip', 'settings_menu'); // ✅ Correct: underscore
|
|
1565
|
+
|
|
1566
|
+
const icon = document.createElement('span');
|
|
1567
|
+
icon.className = 'icon';
|
|
1568
|
+
icon.innerHTML = `<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
|
|
1569
|
+
<path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/>
|
|
1570
|
+
</svg>`;
|
|
1571
|
+
settingsBtn.appendChild(icon);
|
|
1572
|
+
|
|
1573
|
+
const settingsMenu = document.createElement('div');
|
|
1574
|
+
settingsMenu.className = 'settings-menu';
|
|
1575
|
+
|
|
1576
|
+
settingsControl.appendChild(settingsBtn);
|
|
1577
|
+
settingsControl.appendChild(settingsMenu);
|
|
1578
|
+
topBar.appendChild(settingsControl);
|
|
1579
|
+
|
|
1580
|
+
this.container.insertBefore(topBar, this.container.firstChild);
|
|
1581
|
+
|
|
1582
|
+
this.topBar = topBar;
|
|
1583
|
+
this.topBarTitle = topBar.querySelector('.video-title');
|
|
1584
|
+
this.topBarSubtitle = topBar.querySelector('.video-subtitle');
|
|
1585
|
+
|
|
1586
|
+
if (this.options.debug) {
|
|
1587
|
+
console.log('✅ Top bar created with integrated settings');
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1498
1591
|
restartVideo() {
|
|
1499
1592
|
if (!this.video) return this;
|
|
1500
1593
|
|
|
@@ -1801,6 +1894,17 @@ updateProgress() {
|
|
|
1801
1894
|
}
|
|
1802
1895
|
}
|
|
1803
1896
|
|
|
1897
|
+
updateLoadingText(text) {
|
|
1898
|
+
if (this.initialLoading) {
|
|
1899
|
+
const textEl = this.initialLoading.querySelector('.loading-text');
|
|
1900
|
+
if (textEl) textEl.textContent = text;
|
|
1901
|
+
}
|
|
1902
|
+
if (this.loadingOverlay) {
|
|
1903
|
+
const textEl = this.loadingOverlay.querySelector('.loading-text');
|
|
1904
|
+
if (textEl) textEl.textContent = text;
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1804
1908
|
updateBuffer() {
|
|
1805
1909
|
if (!this.video || !this.progressBuffer) return;
|
|
1806
1910
|
|
|
@@ -2595,12 +2699,30 @@ addEventListener(eventType, callback) {
|
|
|
2595
2699
|
this.pauseIcon.classList.remove('hidden');
|
|
2596
2700
|
}
|
|
2597
2701
|
|
|
2702
|
+
if (this.options.autoHide && this.autoHideInitialized) {
|
|
2703
|
+
if (this.options.debug) console.log('Video playing - reset auto-hide timer');
|
|
2704
|
+
this.showControlsNow();
|
|
2705
|
+
this.resetAutoHideTimer();
|
|
2706
|
+
}
|
|
2707
|
+
|
|
2598
2708
|
this.triggerEvent('playing', {
|
|
2599
2709
|
currentTime: this.getCurrentTime(),
|
|
2600
2710
|
duration: this.getDuration()
|
|
2601
2711
|
});
|
|
2602
2712
|
});
|
|
2603
2713
|
|
|
2714
|
+
this.video.addEventListener('pause', () => {
|
|
2715
|
+
if (this.options.autoHide && this.autoHideInitialized) {
|
|
2716
|
+
if (this.options.debug) console.log('Video paused - show controls and cancel timer');
|
|
2717
|
+
this.showControlsNow();
|
|
2718
|
+
|
|
2719
|
+
if (this.autoHideTimer) {
|
|
2720
|
+
clearTimeout(this.autoHideTimer);
|
|
2721
|
+
this.autoHideTimer = null;
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
});
|
|
2725
|
+
|
|
2604
2726
|
this.video.addEventListener('waiting', () => {
|
|
2605
2727
|
if (!this.isChangingQuality) {
|
|
2606
2728
|
this.showLoading();
|
|
@@ -3050,31 +3172,33 @@ resetAutoHideTimer() {
|
|
|
3050
3172
|
this.autoHideTimer = null;
|
|
3051
3173
|
}
|
|
3052
3174
|
|
|
3053
|
-
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
|
3175
|
+
const isTouchDevice = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0);
|
|
3176
|
+
|
|
3054
3177
|
if (this.mouseOverControls && !isTouchDevice) {
|
|
3055
|
-
if (this.autoHideDebug)
|
|
3056
|
-
if (this.options.debug) console.log('Not starting timer - mouse on controls');
|
|
3057
|
-
}
|
|
3178
|
+
if (this.autoHideDebug && this.options.debug) console.log('Not starting timer - mouse on controls');
|
|
3058
3179
|
return;
|
|
3059
3180
|
}
|
|
3060
3181
|
|
|
3061
3182
|
if (this.video && this.video.paused) {
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3183
|
+
|
|
3184
|
+
const isInitialPause = this.video.currentTime === 0 && !this.video.ended;
|
|
3185
|
+
|
|
3186
|
+
if (!isInitialPause) {
|
|
3187
|
+
if (this.autoHideDebug && this.options.debug) console.log('Not starting timer - video paused by user');
|
|
3065
3188
|
return;
|
|
3066
3189
|
}
|
|
3067
3190
|
|
|
3068
|
-
this.
|
|
3069
|
-
|
|
3070
|
-
if (this.options.debug) console.log(`Timer expired after ${this.options.autoHideDelay}ms - nascondo controlli`);
|
|
3191
|
+
if (this.autoHideDebug && this.options.debug) {
|
|
3192
|
+
console.log('Video paused but at start - allowing timer (autoplay blocked scenario)');
|
|
3071
3193
|
}
|
|
3194
|
+
}
|
|
3195
|
+
|
|
3196
|
+
this.autoHideTimer = setTimeout(() => {
|
|
3197
|
+
if (this.autoHideDebug && this.options.debug) console.log(`Timer expired after ${this.options.autoHideDelay}ms - hiding controls`);
|
|
3072
3198
|
this.hideControlsNow();
|
|
3073
3199
|
}, this.options.autoHideDelay);
|
|
3074
3200
|
|
|
3075
|
-
if (this.autoHideDebug) {
|
|
3076
|
-
if (this.options.debug) console.log(`Auto-hide timer started: ${this.options.autoHideDelay}ms`);
|
|
3077
|
-
}
|
|
3201
|
+
if (this.autoHideDebug && this.options.debug) console.log(`Auto-hide timer started (${this.options.autoHideDelay}ms)`);
|
|
3078
3202
|
}
|
|
3079
3203
|
|
|
3080
3204
|
showControlsNow() {
|
|
@@ -3097,7 +3221,7 @@ showControlsNow() {
|
|
|
3097
3221
|
|
|
3098
3222
|
this.showCursor();
|
|
3099
3223
|
|
|
3100
|
-
if (this.autoHideDebug && this.options.debug) console.log('
|
|
3224
|
+
if (this.autoHideDebug && this.options.debug) console.log('Controls shown');
|
|
3101
3225
|
}
|
|
3102
3226
|
}
|
|
3103
3227
|
|
|
@@ -3133,7 +3257,7 @@ hideControlsNow() {
|
|
|
3133
3257
|
|
|
3134
3258
|
this.hideCursor();
|
|
3135
3259
|
|
|
3136
|
-
if (this.autoHideDebug && this.options.debug) console.log('
|
|
3260
|
+
if (this.autoHideDebug && this.options.debug) console.log('Controls hidden');
|
|
3137
3261
|
}
|
|
3138
3262
|
}
|
|
3139
3263
|
|
|
@@ -3377,10 +3501,9 @@ createControls() {
|
|
|
3377
3501
|
</div>
|
|
3378
3502
|
|
|
3379
3503
|
<div class="time-display">
|
|
3380
|
-
<span class="current-time">
|
|
3381
|
-
<span
|
|
3382
|
-
|
|
3383
|
-
</div>
|
|
3504
|
+
<span class="current-time">00:00</span>
|
|
3505
|
+
<span class="duration">00:00</span>
|
|
3506
|
+
</div>
|
|
3384
3507
|
</div>
|
|
3385
3508
|
|
|
3386
3509
|
<div class="controls-right">
|
|
@@ -3391,13 +3514,6 @@ createControls() {
|
|
|
3391
3514
|
<span class="icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path d="M12.5 4v8l-7-4zm-8 0v8l7-4z"/></svg></span>
|
|
3392
3515
|
</button>
|
|
3393
3516
|
|
|
3394
|
-
<div class="settings-control">
|
|
3395
|
-
<button class="control-btn settings-btn" data-tooltip="settings_menu">
|
|
3396
|
-
<span class="icon"><svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/></svg></span>
|
|
3397
|
-
</button>
|
|
3398
|
-
<div class="settings-menu"></div>
|
|
3399
|
-
</div>
|
|
3400
|
-
|
|
3401
3517
|
${(this.options.showQualitySelector && this.originalSources && this.originalSources.length > 1) || this.options.adaptiveQualityControl ? `
|
|
3402
3518
|
<div class="quality-control">
|
|
3403
3519
|
<button class="control-btn quality-btn" data-tooltip="video_quality">
|
|
@@ -3508,7 +3624,9 @@ checkScreenSize() {
|
|
|
3508
3624
|
}
|
|
3509
3625
|
|
|
3510
3626
|
updateSettingsMenuVisibility() {
|
|
3511
|
-
|
|
3627
|
+
|
|
3628
|
+
const settingsControl = this.container?.querySelector('.settings-control');
|
|
3629
|
+
|
|
3512
3630
|
if (!settingsControl) return;
|
|
3513
3631
|
|
|
3514
3632
|
settingsControl.style.display = 'block';
|
|
@@ -3517,23 +3635,28 @@ updateSettingsMenuVisibility() {
|
|
|
3517
3635
|
|
|
3518
3636
|
const speedControl = this.controls.querySelector('.speed-control');
|
|
3519
3637
|
const subtitlesControl = this.controls.querySelector('.subtitles-control');
|
|
3638
|
+
|
|
3520
3639
|
if (speedControl) speedControl.style.display = 'none';
|
|
3521
3640
|
if (subtitlesControl) subtitlesControl.style.display = 'none';
|
|
3522
3641
|
}
|
|
3523
3642
|
|
|
3524
3643
|
populateSettingsMenu() {
|
|
3525
|
-
|
|
3644
|
+
|
|
3645
|
+
const settingsMenu = this.container?.querySelector('.settings-menu');
|
|
3646
|
+
|
|
3526
3647
|
if (!settingsMenu) return;
|
|
3527
3648
|
|
|
3528
3649
|
let menuHTML = '';
|
|
3529
3650
|
|
|
3530
3651
|
if (this.options.showSpeedControl) {
|
|
3531
|
-
const speedLabel = this.t('playback_speed')
|
|
3652
|
+
const speedLabel = this.t('playback_speed');
|
|
3532
3653
|
const currentSpeed = this.video ? this.video.playbackRate : 1;
|
|
3533
|
-
|
|
3534
|
-
|
|
3654
|
+
|
|
3655
|
+
menuHTML += `
|
|
3656
|
+
<div class="settings-expandable-wrapper">
|
|
3657
|
+
<div class="settings-option expandable-trigger" data-action="speed_expand">
|
|
3535
3658
|
<span class="settings-option-label">${speedLabel} <strong>${currentSpeed}x</strong></span>
|
|
3536
|
-
<span class="expand-arrow"
|
|
3659
|
+
<span class="expand-arrow">▼</span>
|
|
3537
3660
|
</div>
|
|
3538
3661
|
<div class="settings-expandable-content" style="display: none;">`;
|
|
3539
3662
|
|
|
@@ -3542,22 +3665,26 @@ populateSettingsMenu() {
|
|
|
3542
3665
|
const isActive = Math.abs(speed - currentSpeed) < 0.01;
|
|
3543
3666
|
menuHTML += `<div class="settings-suboption ${isActive ? 'active' : ''}" data-speed="${speed}">${speed}x</div>`;
|
|
3544
3667
|
});
|
|
3668
|
+
|
|
3545
3669
|
menuHTML += `</div></div>`;
|
|
3546
3670
|
}
|
|
3547
3671
|
|
|
3548
3672
|
if (this.options.showSubtitles && this.textTracks && this.textTracks.length > 0) {
|
|
3549
|
-
const subtitlesLabel = this.t('subtitles')
|
|
3673
|
+
const subtitlesLabel = this.t('subtitles');
|
|
3550
3674
|
const currentTrack = this.currentSubtitleTrack;
|
|
3551
|
-
const currentLabel = this.subtitlesEnabled ?
|
|
3675
|
+
const currentLabel = this.subtitlesEnabled ?
|
|
3676
|
+
(currentTrack ? currentTrack.label : 'Unknown') :
|
|
3677
|
+
this.t('subtitles_off'); //
|
|
3552
3678
|
|
|
3553
|
-
menuHTML +=
|
|
3554
|
-
<div class="settings-
|
|
3679
|
+
menuHTML += `
|
|
3680
|
+
<div class="settings-expandable-wrapper">
|
|
3681
|
+
<div class="settings-option expandable-trigger" data-action="subtitles_expand">
|
|
3555
3682
|
<span class="settings-option-label">${subtitlesLabel} <strong>${currentLabel}</strong></span>
|
|
3556
|
-
<span class="expand-arrow"
|
|
3683
|
+
<span class="expand-arrow">▼</span>
|
|
3557
3684
|
</div>
|
|
3558
3685
|
<div class="settings-expandable-content" style="display: none;">`;
|
|
3559
3686
|
|
|
3560
|
-
menuHTML += `<div class="settings-suboption ${!this.subtitlesEnabled ? 'active' : ''}" data-track="off">${this.t('
|
|
3687
|
+
menuHTML += `<div class="settings-suboption ${!this.subtitlesEnabled ? 'active' : ''}" data-track="off">${this.t('subtitles_off')}</div>`;
|
|
3561
3688
|
|
|
3562
3689
|
this.textTracks.forEach((trackData, index) => {
|
|
3563
3690
|
const isActive = this.currentSubtitleTrack === trackData.track;
|
|
@@ -3620,8 +3747,10 @@ addSettingsMenuScrollbar() {
|
|
|
3620
3747
|
}
|
|
3621
3748
|
|
|
3622
3749
|
bindSettingsMenuEvents() {
|
|
3623
|
-
|
|
3624
|
-
const
|
|
3750
|
+
|
|
3751
|
+
const settingsBtn = this.container?.querySelector('.settings-btn');
|
|
3752
|
+
const settingsMenu = this.container?.querySelector('.settings-menu');
|
|
3753
|
+
|
|
3625
3754
|
if (!settingsMenu || !settingsBtn) return;
|
|
3626
3755
|
|
|
3627
3756
|
settingsBtn.addEventListener('click', (e) => {
|
|
@@ -3629,27 +3758,30 @@ bindSettingsMenuEvents() {
|
|
|
3629
3758
|
settingsMenu.classList.toggle('active');
|
|
3630
3759
|
|
|
3631
3760
|
if (settingsMenu.classList.contains('active')) {
|
|
3632
|
-
const
|
|
3633
|
-
const containerRect = settingsMenu.parentElement.parentElement.getBoundingClientRect();
|
|
3761
|
+
const containerRect = this.container.getBoundingClientRect();
|
|
3634
3762
|
const btnRect = settingsBtn.getBoundingClientRect();
|
|
3635
|
-
|
|
3636
|
-
const
|
|
3763
|
+
|
|
3764
|
+
const spaceBelow = containerRect.bottom - btnRect.bottom - 30; // 30px margin
|
|
3765
|
+
|
|
3766
|
+
const maxMenuHeight = Math.max(300, Math.min(600, spaceBelow));
|
|
3637
3767
|
|
|
3638
3768
|
settingsMenu.style.maxHeight = `${maxMenuHeight}px`;
|
|
3639
3769
|
settingsMenu.style.overflowY = 'auto';
|
|
3640
3770
|
settingsMenu.style.overflowX = 'hidden';
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3771
|
+
|
|
3772
|
+
if (this.options.debug) {
|
|
3773
|
+
console.log(`Settings menu opened: height=${maxMenuHeight}px (available=${spaceBelow}px)`);
|
|
3644
3774
|
}
|
|
3775
|
+
} else {
|
|
3645
3776
|
|
|
3777
|
+
settingsMenu.style.maxHeight = '600px'; // Default max height
|
|
3778
|
+
settingsMenu.style.overflowY = 'auto';
|
|
3779
|
+
}
|
|
3646
3780
|
});
|
|
3647
3781
|
|
|
3648
3782
|
document.addEventListener('click', (e) => {
|
|
3649
3783
|
if (!settingsBtn?.contains(e.target) && !settingsMenu?.contains(e.target)) {
|
|
3650
3784
|
settingsMenu?.classList.remove('active');
|
|
3651
|
-
settingsMenu.style.maxHeight = 'none';
|
|
3652
|
-
settingsMenu.style.overflowY = 'visible';
|
|
3653
3785
|
}
|
|
3654
3786
|
});
|
|
3655
3787
|
|
|
@@ -3689,7 +3821,7 @@ bindSettingsMenuEvents() {
|
|
|
3689
3821
|
const trigger = wrapper.querySelector('.expandable-trigger');
|
|
3690
3822
|
const action = trigger.getAttribute('data-action');
|
|
3691
3823
|
|
|
3692
|
-
if (action === '
|
|
3824
|
+
if (action === 'speed_expand') {
|
|
3693
3825
|
const speed = parseFloat(e.target.getAttribute('data-speed'));
|
|
3694
3826
|
if (speed && speed > 0 && this.video && !this.isChangingQuality) {
|
|
3695
3827
|
this.video.playbackRate = speed;
|
|
@@ -3700,12 +3832,12 @@ bindSettingsMenuEvents() {
|
|
|
3700
3832
|
const label = trigger.querySelector('.settings-option-label');
|
|
3701
3833
|
if (label) {
|
|
3702
3834
|
const speedLabel = this.t('playback_speed') || 'Playback Speed';
|
|
3703
|
-
label.
|
|
3835
|
+
label.innerHTML = `${speedLabel} <strong>${speed}x</strong>`;
|
|
3704
3836
|
}
|
|
3705
3837
|
|
|
3706
3838
|
this.triggerEvent('speedchange', { speed, previousSpeed: this.video.playbackRate });
|
|
3707
3839
|
}
|
|
3708
|
-
} else if (action === '
|
|
3840
|
+
} else if (action === 'subtitles_expand') {
|
|
3709
3841
|
const trackData = e.target.getAttribute('data-track');
|
|
3710
3842
|
if (trackData === 'off') {
|
|
3711
3843
|
this.disableSubtitles();
|
|
@@ -3720,7 +3852,7 @@ bindSettingsMenuEvents() {
|
|
|
3720
3852
|
const label = trigger.querySelector('.settings-option-label');
|
|
3721
3853
|
if (label) {
|
|
3722
3854
|
const subtitlesLabel = this.t('subtitles') || 'Subtitles';
|
|
3723
|
-
label.
|
|
3855
|
+
label.innerHTML = `${subtitlesLabel} <strong>${e.target.textContent}</strong>`;
|
|
3724
3856
|
}
|
|
3725
3857
|
}
|
|
3726
3858
|
}
|
|
@@ -7515,7 +7647,6 @@ skipTime(seconds) {
|
|
|
7515
7647
|
}
|
|
7516
7648
|
|
|
7517
7649
|
updateTimeDisplay() {
|
|
7518
|
-
|
|
7519
7650
|
if (this.currentTimeEl && this.video) {
|
|
7520
7651
|
this.currentTimeEl.textContent = this.formatTime(this.video.currentTime || 0);
|
|
7521
7652
|
}
|
|
@@ -7526,25 +7657,44 @@ updateTimeDisplay() {
|
|
|
7526
7657
|
const currentTime = this.video.currentTime;
|
|
7527
7658
|
const networkState = this.video.networkState;
|
|
7528
7659
|
|
|
7529
|
-
const isInitialBuffering = (readyState < 2 && currentTime === 0) ||
|
|
7530
|
-
(currentTime === 0 && (!duration || duration === 0) && networkState === 2);
|
|
7660
|
+
const isInitialBuffering = (readyState < 2 && currentTime === 0) || (currentTime === 0 && !duration) || (duration === 0 && networkState === 2);
|
|
7531
7661
|
|
|
7532
7662
|
const isDurationInvalid = !duration || isNaN(duration) || !isFinite(duration);
|
|
7533
7663
|
|
|
7664
|
+
const t = (key) => {
|
|
7665
|
+
if (this.isI18nAvailable()) {
|
|
7666
|
+
try {
|
|
7667
|
+
return VideoPlayerTranslations.t(key);
|
|
7668
|
+
} catch (error) {
|
|
7669
|
+
return key;
|
|
7670
|
+
}
|
|
7671
|
+
}
|
|
7672
|
+
const fallback = {
|
|
7673
|
+
'loading': 'Loading...'
|
|
7674
|
+
};
|
|
7675
|
+
return fallback[key] || key;
|
|
7676
|
+
};
|
|
7677
|
+
|
|
7534
7678
|
if (isInitialBuffering) {
|
|
7535
7679
|
|
|
7536
|
-
this.
|
|
7680
|
+
this.updateLoadingText(t('loading'));
|
|
7681
|
+
this.durationEl.textContent = this.formatTime(0); // Just show 00:00 or empty
|
|
7537
7682
|
this.durationEl.classList.remove('encoding-state');
|
|
7538
7683
|
this.durationEl.classList.add('loading-state');
|
|
7539
7684
|
} else if (isDurationInvalid) {
|
|
7540
7685
|
|
|
7541
|
-
this.
|
|
7686
|
+
this.updateLoadingText(t('loading'));
|
|
7687
|
+
|
|
7688
|
+
this.durationEl.textContent = "--:--";
|
|
7689
|
+
|
|
7542
7690
|
this.durationEl.classList.remove('loading-state');
|
|
7543
7691
|
this.durationEl.classList.add('encoding-state');
|
|
7544
7692
|
} else {
|
|
7545
7693
|
|
|
7546
7694
|
this.durationEl.textContent = this.formatTime(duration);
|
|
7547
7695
|
this.durationEl.classList.remove('encoding-state', 'loading-state');
|
|
7696
|
+
|
|
7697
|
+
this.updateLoadingText('');
|
|
7548
7698
|
}
|
|
7549
7699
|
}
|
|
7550
7700
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myetv-player",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.3",
|
|
4
4
|
"description": "MYETV Video Player - Modular HTML5 video player with plugin support for YouTube, Vimeo, Twitch, Facebook, Cloudflare Stream and streaming protocols (HLS/DASH)",
|
|
5
5
|
"main": "dist/myetv-player.js",
|
|
6
6
|
"files": [
|
|
@@ -62,3 +62,5 @@
|
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
|
|
65
|
+
|
|
66
|
+
|