myetv-player 1.6.2 → 1.6.4
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 +295 -15
- package/css/myetv-player.min.css +1 -1
- package/dist/myetv-player.js +353 -180
- package/dist/myetv-player.min.js +275 -159
- package/package.json +3 -1
- package/plugins/youtube/myetv-player-youtube-plugin.js +52 -45
package/dist/myetv-player.js
CHANGED
|
@@ -1253,13 +1253,34 @@ markPlayerReady() {
|
|
|
1253
1253
|
|
|
1254
1254
|
// Autoplay
|
|
1255
1255
|
if (this.options.autoplay) {
|
|
1256
|
-
if (this.options.debug) console.log('
|
|
1256
|
+
if (this.options.debug) console.log('Autoplay enabled');
|
|
1257
1257
|
setTimeout(() => {
|
|
1258
|
-
this.video.play()
|
|
1259
|
-
|
|
1260
|
-
|
|
1258
|
+
this.video.play()
|
|
1259
|
+
.then(() => {
|
|
1260
|
+
// Autoplay succeeded
|
|
1261
|
+
if (this.options.debug) console.log('Autoplay started successfully');
|
|
1262
|
+
})
|
|
1263
|
+
.catch(error => {
|
|
1264
|
+
// Autoplay blocked by browser
|
|
1265
|
+
if (this.options.debug) console.warn('Autoplay blocked', error);
|
|
1266
|
+
|
|
1267
|
+
// Start auto-hide timer even if autoplay is blocked
|
|
1268
|
+
// This ensures controls hide after delay when video is paused
|
|
1269
|
+
if (this.options.autoHide && this.autoHideInitialized) {
|
|
1270
|
+
// Show controls initially (user needs to see play button)
|
|
1271
|
+
this.showControlsNow();
|
|
1272
|
+
|
|
1273
|
+
// Start timer to hide controls
|
|
1274
|
+
this.resetAutoHideTimer();
|
|
1275
|
+
|
|
1276
|
+
if (this.options.debug) {
|
|
1277
|
+
console.log('Auto-hide timer started (autoplay blocked - video paused)');
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
});
|
|
1261
1281
|
}, 100);
|
|
1262
1282
|
}
|
|
1283
|
+
|
|
1263
1284
|
}, 200);
|
|
1264
1285
|
|
|
1265
1286
|
}, 100);
|
|
@@ -1283,10 +1304,7 @@ createPlayerStructure() {
|
|
|
1283
1304
|
this.createControls();
|
|
1284
1305
|
this.createBrandLogo();
|
|
1285
1306
|
this.detectPlaylist();
|
|
1286
|
-
|
|
1287
|
-
if (this.options.showTitleOverlay) {
|
|
1288
|
-
this.createTitleOverlay();
|
|
1289
|
-
}
|
|
1307
|
+
this.createTopBar();
|
|
1290
1308
|
}
|
|
1291
1309
|
|
|
1292
1310
|
createInitialLoading() {
|
|
@@ -1310,52 +1328,31 @@ createLoadingOverlay() {
|
|
|
1310
1328
|
this.loadingOverlay = overlay;
|
|
1311
1329
|
}
|
|
1312
1330
|
|
|
1313
|
-
createTitleOverlay() {
|
|
1314
|
-
const overlay = document.createElement('div');
|
|
1315
|
-
overlay.className = 'title-overlay';
|
|
1316
|
-
overlay.id = 'titleOverlay-' + this.getUniqueId();
|
|
1317
|
-
|
|
1318
|
-
const titleText = document.createElement('h2');
|
|
1319
|
-
titleText.className = 'title-text';
|
|
1320
|
-
titleText.textContent = this.decodeHTMLEntities(this.options.videoTitle) || '';
|
|
1321
|
-
overlay.appendChild(titleText);
|
|
1322
|
-
|
|
1323
|
-
// add subtitles
|
|
1324
|
-
if (this.options.videoSubtitle) {
|
|
1325
|
-
const subtitleText = document.createElement('p');
|
|
1326
|
-
subtitleText.className = 'subtitle-text';
|
|
1327
|
-
subtitleText.textContent = this.decodeHTMLEntities(this.options.videoSubtitle);
|
|
1328
|
-
overlay.appendChild(subtitleText);
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
|
-
if (this.controls) {
|
|
1332
|
-
this.container.insertBefore(overlay, this.controls);
|
|
1333
|
-
} else {
|
|
1334
|
-
this.container.appendChild(overlay);
|
|
1335
|
-
}
|
|
1336
|
-
|
|
1337
|
-
this.titleOverlay = overlay;
|
|
1338
|
-
|
|
1339
|
-
if (this.options.persistentTitle && this.options.videoTitle) {
|
|
1340
|
-
this.showTitleOverlay();
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
1331
|
updateTooltips() {
|
|
1345
1332
|
if (!this.controls) return;
|
|
1346
1333
|
|
|
1347
1334
|
try {
|
|
1335
|
+
// Update tooltips in controls
|
|
1348
1336
|
this.controls.querySelectorAll('[data-tooltip]').forEach(element => {
|
|
1349
1337
|
const key = element.getAttribute('data-tooltip');
|
|
1350
1338
|
element.title = this.t(key);
|
|
1351
1339
|
});
|
|
1352
1340
|
|
|
1341
|
+
// Update tooltips in top bar
|
|
1342
|
+
if (this.topBar) {
|
|
1343
|
+
this.topBar.querySelectorAll('[data-tooltip]').forEach(element => {
|
|
1344
|
+
const key = element.getAttribute('data-tooltip');
|
|
1345
|
+
element.title = this.t(key);
|
|
1346
|
+
});
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
// Update "Auto" option in quality menu
|
|
1353
1350
|
const autoOption = this.controls.querySelector('.quality-option[data-quality="auto"]');
|
|
1354
1351
|
if (autoOption) {
|
|
1355
1352
|
autoOption.textContent = this.t('auto');
|
|
1356
1353
|
}
|
|
1357
1354
|
} catch (error) {
|
|
1358
|
-
if (this.options.debug) console.warn('
|
|
1355
|
+
if (this.options.debug) console.warn('Tooltip update error', error);
|
|
1359
1356
|
}
|
|
1360
1357
|
}
|
|
1361
1358
|
|
|
@@ -1373,27 +1370,44 @@ setLanguage(lang) {
|
|
|
1373
1370
|
return false;
|
|
1374
1371
|
}
|
|
1375
1372
|
|
|
1373
|
+
/**
|
|
1374
|
+
* Set video title
|
|
1375
|
+
* @param {string} title - Video title
|
|
1376
|
+
* @returns {Object} this
|
|
1377
|
+
*/
|
|
1376
1378
|
setVideoTitle(title) {
|
|
1377
|
-
this.options.videoTitle = title
|
|
1379
|
+
this.options.videoTitle = title;
|
|
1378
1380
|
|
|
1379
|
-
if (this.
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1381
|
+
if (this.topBarTitle) {
|
|
1382
|
+
this.topBarTitle.textContent = this.decodeHTMLEntities(title);
|
|
1383
|
+
|
|
1384
|
+
// show top bar if title overlay is enabled
|
|
1385
|
+
if (title && this.options.showTitleOverlay) {
|
|
1386
|
+
const titleSection = this.topBar.querySelector('.top-bar-title');
|
|
1387
|
+
if (titleSection) {
|
|
1388
|
+
titleSection.style.display = '';
|
|
1389
|
+
}
|
|
1383
1390
|
}
|
|
1391
|
+
} else if (this.topBar && title) {
|
|
1392
|
+
// create title section
|
|
1393
|
+
const titleSection = this.topBar.querySelector('.top-bar-title');
|
|
1394
|
+
if (!titleSection) {
|
|
1395
|
+
const newTitleSection = document.createElement('div');
|
|
1396
|
+
newTitleSection.className = 'top-bar-title';
|
|
1384
1397
|
|
|
1385
|
-
|
|
1386
|
-
|
|
1398
|
+
const titleElement = document.createElement('h3');
|
|
1399
|
+
titleElement.className = 'video-title';
|
|
1400
|
+
titleElement.textContent = this.decodeHTMLEntities(title);
|
|
1401
|
+
newTitleSection.appendChild(titleElement);
|
|
1387
1402
|
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
}, 3000);
|
|
1393
|
-
}
|
|
1403
|
+
const settingsControl = this.topBar.querySelector('.settings-control');
|
|
1404
|
+
this.topBar.insertBefore(newTitleSection, settingsControl);
|
|
1405
|
+
|
|
1406
|
+
this.topBarTitle = titleElement;
|
|
1394
1407
|
}
|
|
1395
1408
|
}
|
|
1396
1409
|
|
|
1410
|
+
if (this.options.debug) console.log('Video title set:', title);
|
|
1397
1411
|
return this;
|
|
1398
1412
|
}
|
|
1399
1413
|
|
|
@@ -1402,23 +1416,23 @@ getVideoTitle() {
|
|
|
1402
1416
|
}
|
|
1403
1417
|
|
|
1404
1418
|
setVideoSubtitle(subtitle) {
|
|
1405
|
-
this.options.videoSubtitle = subtitle
|
|
1419
|
+
this.options.videoSubtitle = subtitle;
|
|
1406
1420
|
|
|
1407
|
-
if (this.
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
subtitleElement.remove();
|
|
1421
|
+
if (this.topBarSubtitle) {
|
|
1422
|
+
this.topBarSubtitle.textContent = subtitle;
|
|
1423
|
+
} else if (subtitle && this.topBar) {
|
|
1424
|
+
// Create subtitle element
|
|
1425
|
+
const titleSection = this.topBar.querySelector('.top-bar-title');
|
|
1426
|
+
if (titleSection) {
|
|
1427
|
+
const subtitleEl = document.createElement('span');
|
|
1428
|
+
subtitleEl.className = 'video-subtitle';
|
|
1429
|
+
subtitleEl.textContent = subtitle;
|
|
1430
|
+
titleSection.appendChild(subtitleEl);
|
|
1431
|
+
this.topBarSubtitle = subtitleEl;
|
|
1419
1432
|
}
|
|
1420
1433
|
}
|
|
1421
1434
|
|
|
1435
|
+
if (this.options.debug) console.log('Video subtitle set:', subtitle);
|
|
1422
1436
|
return this;
|
|
1423
1437
|
}
|
|
1424
1438
|
|
|
@@ -1426,41 +1440,65 @@ getVideoSubtitle() {
|
|
|
1426
1440
|
return this.options.videoSubtitle;
|
|
1427
1441
|
}
|
|
1428
1442
|
|
|
1443
|
+
/**
|
|
1444
|
+
* Set persistent title (always visible)
|
|
1445
|
+
* @param {boolean} persistent - If true, title stays visible
|
|
1446
|
+
* @returns {Object} this
|
|
1447
|
+
*/
|
|
1429
1448
|
setPersistentTitle(persistent) {
|
|
1430
1449
|
this.options.persistentTitle = persistent;
|
|
1431
1450
|
|
|
1432
|
-
if (this.
|
|
1451
|
+
if (this.topBar) {
|
|
1433
1452
|
if (persistent) {
|
|
1434
|
-
this.
|
|
1435
|
-
this.clearTitleTimeout();
|
|
1453
|
+
this.topBar.classList.add('persistent');
|
|
1436
1454
|
} else {
|
|
1437
|
-
this.
|
|
1438
|
-
if (this.titleOverlay.classList.contains('show')) {
|
|
1439
|
-
this.clearTitleTimeout();
|
|
1440
|
-
this.titleTimeout = setTimeout(() => {
|
|
1441
|
-
this.hideTitleOverlay();
|
|
1442
|
-
}, 3000);
|
|
1443
|
-
}
|
|
1455
|
+
this.topBar.classList.remove('persistent');
|
|
1444
1456
|
}
|
|
1445
1457
|
}
|
|
1446
1458
|
|
|
1447
1459
|
return this;
|
|
1448
1460
|
}
|
|
1449
1461
|
|
|
1462
|
+
/**
|
|
1463
|
+
* Enable title overlay (shows top bar with title)
|
|
1464
|
+
* @returns {Object} this
|
|
1465
|
+
*/
|
|
1450
1466
|
enableTitleOverlay() {
|
|
1451
|
-
if (!this.
|
|
1452
|
-
this.options.
|
|
1453
|
-
this
|
|
1467
|
+
if (!this.topBar) {
|
|
1468
|
+
if (this.options.debug) console.warn('Top bar not available');
|
|
1469
|
+
return this;
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
this.options.showTitleOverlay = true;
|
|
1473
|
+
|
|
1474
|
+
// show top bar
|
|
1475
|
+
if (this.options.videoTitle) {
|
|
1476
|
+
const titleSection = this.topBar.querySelector('.top-bar-title');
|
|
1477
|
+
if (titleSection) {
|
|
1478
|
+
titleSection.style.display = '';
|
|
1479
|
+
}
|
|
1454
1480
|
}
|
|
1481
|
+
|
|
1482
|
+
if (this.options.debug) console.log('Title overlay enabled');
|
|
1455
1483
|
return this;
|
|
1456
1484
|
}
|
|
1457
1485
|
|
|
1486
|
+
/**
|
|
1487
|
+
* Disable title overlay (hides top bar)
|
|
1488
|
+
* @returns {Object} this
|
|
1489
|
+
*/
|
|
1458
1490
|
disableTitleOverlay() {
|
|
1459
|
-
if (this.
|
|
1460
|
-
|
|
1461
|
-
this.titleOverlay = null;
|
|
1462
|
-
}
|
|
1491
|
+
if (!this.topBar) return this;
|
|
1492
|
+
|
|
1463
1493
|
this.options.showTitleOverlay = false;
|
|
1494
|
+
|
|
1495
|
+
// hide top bar
|
|
1496
|
+
const titleSection = this.topBar.querySelector('.top-bar-title');
|
|
1497
|
+
if (titleSection) {
|
|
1498
|
+
titleSection.style.display = 'none';
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
if (this.options.debug) console.log('Title overlay disabled');
|
|
1464
1502
|
return this;
|
|
1465
1503
|
}
|
|
1466
1504
|
|
|
@@ -1501,6 +1539,10 @@ initializeElements() {
|
|
|
1501
1539
|
this.speedMenu = this.controls?.querySelector('.speed-menu');
|
|
1502
1540
|
this.qualityMenu = this.controls?.querySelector('.quality-menu');
|
|
1503
1541
|
this.subtitlesMenu = this.controls?.querySelector('.subtitles-menu');
|
|
1542
|
+
|
|
1543
|
+
this.settingsBtn = this.container?.querySelector('.settings-btn');
|
|
1544
|
+
this.settingsMenu = this.container?.querySelector('.settings-menu');
|
|
1545
|
+
|
|
1504
1546
|
// Apply seek handle shape from options
|
|
1505
1547
|
if (this.progressHandle && this.options.seekHandleShape) {
|
|
1506
1548
|
this.setSeekHandleShape(this.options.seekHandleShape);
|
|
@@ -1581,6 +1623,88 @@ setupMenuToggles() {
|
|
|
1581
1623
|
}
|
|
1582
1624
|
}
|
|
1583
1625
|
|
|
1626
|
+
/**
|
|
1627
|
+
* Create integrated top bar with settings menu
|
|
1628
|
+
* Respects showTitleOverlay, videoTitle, videoSubtitle, persistentTitle options
|
|
1629
|
+
* @returns {void}
|
|
1630
|
+
*/
|
|
1631
|
+
createTopBar() {
|
|
1632
|
+
if (!this.container) return;
|
|
1633
|
+
|
|
1634
|
+
// Create top bar element
|
|
1635
|
+
const topBar = document.createElement('div');
|
|
1636
|
+
topBar.className = 'player-top-bar';
|
|
1637
|
+
topBar.id = `topBar${this.getUniqueId()}`;
|
|
1638
|
+
|
|
1639
|
+
// Left section - Title (ALWAYS create structure)
|
|
1640
|
+
const titleSection = document.createElement('div');
|
|
1641
|
+
titleSection.className = 'top-bar-title';
|
|
1642
|
+
|
|
1643
|
+
// Main title
|
|
1644
|
+
const titleElement = document.createElement('h3');
|
|
1645
|
+
titleElement.className = 'video-title';
|
|
1646
|
+
titleElement.textContent = this.options.videoTitle ? this.decodeHTMLEntities(this.options.videoTitle) : '';
|
|
1647
|
+
titleSection.appendChild(titleElement);
|
|
1648
|
+
|
|
1649
|
+
// Optional subtitle (if present)
|
|
1650
|
+
if (this.options.videoSubtitle) {
|
|
1651
|
+
const subtitleElement = document.createElement('span');
|
|
1652
|
+
subtitleElement.className = 'video-subtitle';
|
|
1653
|
+
subtitleElement.textContent = this.decodeHTMLEntities(this.options.videoSubtitle);
|
|
1654
|
+
titleSection.appendChild(subtitleElement);
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
// Hide title section if showTitleOverlay is false
|
|
1658
|
+
if (!this.options.showTitleOverlay || !this.options.videoTitle) {
|
|
1659
|
+
titleSection.style.display = 'none';
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
topBar.appendChild(titleSection);
|
|
1663
|
+
|
|
1664
|
+
// Right section - Settings control
|
|
1665
|
+
const settingsControl = document.createElement('div');
|
|
1666
|
+
settingsControl.className = 'settings-control settings-top-bar';
|
|
1667
|
+
|
|
1668
|
+
// Settings button
|
|
1669
|
+
const settingsBtn = document.createElement('button');
|
|
1670
|
+
settingsBtn.className = 'control-btn settings-btn';
|
|
1671
|
+
settingsBtn.setAttribute('data-tooltip', 'settingsmenu');
|
|
1672
|
+
|
|
1673
|
+
const icon = document.createElement('span');
|
|
1674
|
+
icon.className = 'icon';
|
|
1675
|
+
icon.innerHTML = `<svg viewBox="0 0 24 24" width="20" height="20" 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>`;
|
|
1676
|
+
settingsBtn.appendChild(icon);
|
|
1677
|
+
|
|
1678
|
+
// Settings menu
|
|
1679
|
+
const settingsMenu = document.createElement('div');
|
|
1680
|
+
settingsMenu.className = 'settings-menu';
|
|
1681
|
+
|
|
1682
|
+
settingsControl.appendChild(settingsBtn);
|
|
1683
|
+
settingsControl.appendChild(settingsMenu);
|
|
1684
|
+
topBar.appendChild(settingsControl);
|
|
1685
|
+
|
|
1686
|
+
// Add persistent class if persistentTitle is enabled
|
|
1687
|
+
if (this.options.persistentTitle) {
|
|
1688
|
+
topBar.classList.add('persistent');
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
// Insert top bar as first child in container
|
|
1692
|
+
this.container.insertBefore(topBar, this.container.firstChild);
|
|
1693
|
+
|
|
1694
|
+
// Save references
|
|
1695
|
+
this.topBar = topBar;
|
|
1696
|
+
this.topBarTitle = topBar.querySelector('.video-title');
|
|
1697
|
+
this.topBarSubtitle = topBar.querySelector('.video-subtitle');
|
|
1698
|
+
|
|
1699
|
+
if (this.options.debug) {
|
|
1700
|
+
console.log('Top bar created with integrated settings', {
|
|
1701
|
+
showTitle: this.options.showTitleOverlay,
|
|
1702
|
+
persistent: this.options.persistentTitle,
|
|
1703
|
+
opacity: this.options.titleOverlayOpacity
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1584
1708
|
/**
|
|
1585
1709
|
* Restart video from beginning - Works with HTML5 video and ALL plugins
|
|
1586
1710
|
* @returns {this} Returns this for method chaining
|
|
@@ -2165,7 +2289,7 @@ createBrandLogo() {
|
|
|
2165
2289
|
if (this.options.brandLogoLinkUrl) {
|
|
2166
2290
|
// Use custom tooltip text if provided, otherwise fallback to URL
|
|
2167
2291
|
logo.title = this.options.brandLogoTooltipText || this.options.brandLogoLinkUrl;
|
|
2168
|
-
//
|
|
2292
|
+
// do not use data-tooltip to not be overwritten
|
|
2169
2293
|
}
|
|
2170
2294
|
|
|
2171
2295
|
// Handle loading error
|
|
@@ -2860,6 +2984,13 @@ addEventListener(eventType, callback) {
|
|
|
2860
2984
|
this.pauseIcon.classList.remove('hidden');
|
|
2861
2985
|
}
|
|
2862
2986
|
|
|
2987
|
+
// Reset auto-hide timer when video starts playing
|
|
2988
|
+
if (this.options.autoHide && this.autoHideInitialized) {
|
|
2989
|
+
if (this.options.debug) console.log('Video playing - reset auto-hide timer');
|
|
2990
|
+
this.showControlsNow();
|
|
2991
|
+
this.resetAutoHideTimer();
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2863
2994
|
// Trigger playing event - video is now actually playing
|
|
2864
2995
|
this.triggerEvent('playing', {
|
|
2865
2996
|
currentTime: this.getCurrentTime(),
|
|
@@ -2867,6 +2998,20 @@ addEventListener(eventType, callback) {
|
|
|
2867
2998
|
});
|
|
2868
2999
|
});
|
|
2869
3000
|
|
|
3001
|
+
// Show controls and cancel timer when video is paused
|
|
3002
|
+
this.video.addEventListener('pause', () => {
|
|
3003
|
+
if (this.options.autoHide && this.autoHideInitialized) {
|
|
3004
|
+
if (this.options.debug) console.log('Video paused - show controls and cancel timer');
|
|
3005
|
+
this.showControlsNow();
|
|
3006
|
+
|
|
3007
|
+
// Cancel timer so controls stay visible while paused
|
|
3008
|
+
if (this.autoHideTimer) {
|
|
3009
|
+
clearTimeout(this.autoHideTimer);
|
|
3010
|
+
this.autoHideTimer = null;
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
});
|
|
3014
|
+
|
|
2870
3015
|
this.video.addEventListener('waiting', () => {
|
|
2871
3016
|
if (!this.isChangingQuality) {
|
|
2872
3017
|
this.showLoading();
|
|
@@ -3359,30 +3504,37 @@ resetAutoHideTimer() {
|
|
|
3359
3504
|
this.autoHideTimer = null;
|
|
3360
3505
|
}
|
|
3361
3506
|
|
|
3362
|
-
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
|
3507
|
+
const isTouchDevice = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0);
|
|
3508
|
+
|
|
3363
3509
|
if (this.mouseOverControls && !isTouchDevice) {
|
|
3364
|
-
if (this.autoHideDebug)
|
|
3365
|
-
if (this.options.debug) console.log('Not starting timer - mouse on controls');
|
|
3366
|
-
}
|
|
3510
|
+
if (this.autoHideDebug && this.options.debug) console.log('Not starting timer - mouse on controls');
|
|
3367
3511
|
return;
|
|
3368
3512
|
}
|
|
3369
3513
|
|
|
3514
|
+
// Allow timer if video is paused at start (autoplay blocked)
|
|
3370
3515
|
if (this.video && this.video.paused) {
|
|
3371
|
-
|
|
3372
|
-
|
|
3516
|
+
const isInitialPause = this.video.currentTime === 0 && !this.video.ended;
|
|
3517
|
+
|
|
3518
|
+
if (!isInitialPause) {
|
|
3519
|
+
if (this.autoHideDebug && this.options.debug) console.log('Not starting timer - video paused by user');
|
|
3520
|
+
return;
|
|
3521
|
+
}
|
|
3522
|
+
|
|
3523
|
+
if (this.autoHideDebug && this.options.debug) {
|
|
3524
|
+
console.log('Video paused but at start - allowing timer (autoplay blocked)');
|
|
3373
3525
|
}
|
|
3374
|
-
return;
|
|
3375
3526
|
}
|
|
3376
3527
|
|
|
3528
|
+
// Start timer
|
|
3377
3529
|
this.autoHideTimer = setTimeout(() => {
|
|
3378
|
-
if (this.autoHideDebug) {
|
|
3379
|
-
|
|
3530
|
+
if (this.autoHideDebug && this.options.debug) {
|
|
3531
|
+
console.log(`Timer expired after ${this.options.autoHideDelay}ms - hiding controls`);
|
|
3380
3532
|
}
|
|
3381
3533
|
this.hideControlsNow();
|
|
3382
3534
|
}, this.options.autoHideDelay);
|
|
3383
3535
|
|
|
3384
|
-
if (this.autoHideDebug) {
|
|
3385
|
-
|
|
3536
|
+
if (this.autoHideDebug && this.options.debug) {
|
|
3537
|
+
console.log(`Auto-hide timer started (${this.options.autoHideDelay}ms)`);
|
|
3386
3538
|
}
|
|
3387
3539
|
}
|
|
3388
3540
|
|
|
@@ -3410,7 +3562,7 @@ showControlsNow() {
|
|
|
3410
3562
|
// *show cursor when controls are shown*
|
|
3411
3563
|
this.showCursor();
|
|
3412
3564
|
|
|
3413
|
-
if (this.autoHideDebug && this.options.debug) console.log('
|
|
3565
|
+
if (this.autoHideDebug && this.options.debug) console.log('Controls shown');
|
|
3414
3566
|
}
|
|
3415
3567
|
}
|
|
3416
3568
|
|
|
@@ -3451,7 +3603,7 @@ hideControlsNow() {
|
|
|
3451
3603
|
// *hide cursor after controls are hidden*
|
|
3452
3604
|
this.hideCursor();
|
|
3453
3605
|
|
|
3454
|
-
if (this.autoHideDebug && this.options.debug) console.log('
|
|
3606
|
+
if (this.autoHideDebug && this.options.debug) console.log('Controls hidden');
|
|
3455
3607
|
}
|
|
3456
3608
|
}
|
|
3457
3609
|
|
|
@@ -3477,9 +3629,7 @@ clearControlsTimeout() {
|
|
|
3477
3629
|
|
|
3478
3630
|
// Default controlbar styles injection
|
|
3479
3631
|
injectDefaultControlbarStyles() {
|
|
3480
|
-
if (document.getElementById('default-controlbar-styles'))
|
|
3481
|
-
return;
|
|
3482
|
-
}
|
|
3632
|
+
if (document.getElementById('default-controlbar-styles')) return;
|
|
3483
3633
|
|
|
3484
3634
|
const controlBarOpacity = Math.max(0, Math.min(1, this.options.controlBarOpacity));
|
|
3485
3635
|
const titleOverlayOpacity = Math.max(0, Math.min(1, this.options.titleOverlayOpacity));
|
|
@@ -3501,7 +3651,7 @@ injectDefaultControlbarStyles() {
|
|
|
3501
3651
|
min-height: 60px;
|
|
3502
3652
|
padding-bottom: 10px;
|
|
3503
3653
|
}
|
|
3504
|
-
|
|
3654
|
+
|
|
3505
3655
|
.video-wrapper:not(.youtube-active):not(.vimeo-active):not(.facebook-active) .title-overlay {
|
|
3506
3656
|
background: linear-gradient(
|
|
3507
3657
|
to bottom,
|
|
@@ -3516,8 +3666,12 @@ injectDefaultControlbarStyles() {
|
|
|
3516
3666
|
min-height: 80px;
|
|
3517
3667
|
padding-top: 20px;
|
|
3518
3668
|
}
|
|
3669
|
+
|
|
3670
|
+
/* ✅ NEW: Set CSS custom property for top bar opacity */
|
|
3671
|
+
.video-wrapper {
|
|
3672
|
+
--player-topbar-opacity: ${titleOverlayOpacity};
|
|
3673
|
+
}
|
|
3519
3674
|
`;
|
|
3520
|
-
|
|
3521
3675
|
document.head.appendChild(style);
|
|
3522
3676
|
}
|
|
3523
3677
|
|
|
@@ -3699,10 +3853,9 @@ createControls() {
|
|
|
3699
3853
|
</div>
|
|
3700
3854
|
|
|
3701
3855
|
<div class="time-display">
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
</div>
|
|
3856
|
+
<span class="current-time">00:00</span>
|
|
3857
|
+
<span class="duration">00:00</span>
|
|
3858
|
+
</div>
|
|
3706
3859
|
</div>
|
|
3707
3860
|
|
|
3708
3861
|
<div class="controls-right">
|
|
@@ -3713,13 +3866,6 @@ createControls() {
|
|
|
3713
3866
|
<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>
|
|
3714
3867
|
</button>
|
|
3715
3868
|
|
|
3716
|
-
<div class="settings-control">
|
|
3717
|
-
<button class="control-btn settings-btn" data-tooltip="settings_menu">
|
|
3718
|
-
<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>
|
|
3719
|
-
</button>
|
|
3720
|
-
<div class="settings-menu"></div>
|
|
3721
|
-
</div>
|
|
3722
|
-
|
|
3723
3869
|
${(this.options.showQualitySelector && this.originalSources && this.originalSources.length > 1) || this.options.adaptiveQualityControl ? `
|
|
3724
3870
|
<div class="quality-control">
|
|
3725
3871
|
<button class="control-btn quality-btn" data-tooltip="video_quality">
|
|
@@ -3842,18 +3988,21 @@ checkScreenSize() {
|
|
|
3842
3988
|
|
|
3843
3989
|
/* Update settings menu visibility */
|
|
3844
3990
|
updateSettingsMenuVisibility() {
|
|
3845
|
-
|
|
3991
|
+
// SEARCH IN CONTAINER
|
|
3992
|
+
const settingsControl = this.container?.querySelector('.settings-control');
|
|
3993
|
+
|
|
3846
3994
|
if (!settingsControl) return;
|
|
3847
3995
|
|
|
3848
|
-
//
|
|
3996
|
+
// Always show settings
|
|
3849
3997
|
settingsControl.style.display = 'block';
|
|
3850
3998
|
|
|
3851
3999
|
// Populate settings menu
|
|
3852
4000
|
this.populateSettingsMenu();
|
|
3853
4001
|
|
|
3854
|
-
//
|
|
4002
|
+
// Hide speed and subtitles controls in bottom bar
|
|
3855
4003
|
const speedControl = this.controls.querySelector('.speed-control');
|
|
3856
4004
|
const subtitlesControl = this.controls.querySelector('.subtitles-control');
|
|
4005
|
+
|
|
3857
4006
|
if (speedControl) speedControl.style.display = 'none';
|
|
3858
4007
|
if (subtitlesControl) subtitlesControl.style.display = 'none';
|
|
3859
4008
|
}
|
|
@@ -3862,44 +4011,52 @@ updateSettingsMenuVisibility() {
|
|
|
3862
4011
|
* Populate settings menu with controls
|
|
3863
4012
|
*/
|
|
3864
4013
|
populateSettingsMenu() {
|
|
3865
|
-
|
|
4014
|
+
// SEARCH IN CONTAINER
|
|
4015
|
+
const settingsMenu = this.container?.querySelector('.settings-menu');
|
|
4016
|
+
|
|
3866
4017
|
if (!settingsMenu) return;
|
|
3867
4018
|
|
|
3868
4019
|
let menuHTML = '';
|
|
3869
4020
|
|
|
3870
4021
|
// SPEED - always included
|
|
3871
4022
|
if (this.options.showSpeedControl) {
|
|
3872
|
-
const speedLabel = this.t('playback_speed')
|
|
4023
|
+
const speedLabel = this.t('playback_speed');
|
|
3873
4024
|
const currentSpeed = this.video ? this.video.playbackRate : 1;
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
<
|
|
3878
|
-
|
|
3879
|
-
|
|
4025
|
+
|
|
4026
|
+
menuHTML += `
|
|
4027
|
+
<div class="settings-expandable-wrapper">
|
|
4028
|
+
<div class="settings-option expandable-trigger" data-action="speed_expand">
|
|
4029
|
+
<span class="settings-option-label">${speedLabel} <strong>${currentSpeed}x</strong></span>
|
|
4030
|
+
<span class="expand-arrow">▼</span>
|
|
4031
|
+
</div>
|
|
4032
|
+
<div class="settings-expandable-content" style="display: none;">`;
|
|
3880
4033
|
|
|
3881
4034
|
const speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
|
|
3882
4035
|
speeds.forEach(speed => {
|
|
3883
4036
|
const isActive = Math.abs(speed - currentSpeed) < 0.01;
|
|
3884
4037
|
menuHTML += `<div class="settings-suboption ${isActive ? 'active' : ''}" data-speed="${speed}">${speed}x</div>`;
|
|
3885
4038
|
});
|
|
4039
|
+
|
|
3886
4040
|
menuHTML += `</div></div>`;
|
|
3887
4041
|
}
|
|
3888
4042
|
|
|
3889
4043
|
// SUBTITLES - always included
|
|
3890
4044
|
if (this.options.showSubtitles && this.textTracks && this.textTracks.length > 0) {
|
|
3891
|
-
const subtitlesLabel = this.t('subtitles')
|
|
4045
|
+
const subtitlesLabel = this.t('subtitles');
|
|
3892
4046
|
const currentTrack = this.currentSubtitleTrack;
|
|
3893
|
-
const currentLabel = this.subtitlesEnabled ?
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
4047
|
+
const currentLabel = this.subtitlesEnabled ?
|
|
4048
|
+
(currentTrack ? currentTrack.label : 'Unknown') :
|
|
4049
|
+
this.t('subtitles_off'); //
|
|
4050
|
+
|
|
4051
|
+
menuHTML += `
|
|
4052
|
+
<div class="settings-expandable-wrapper">
|
|
4053
|
+
<div class="settings-option expandable-trigger" data-action="subtitles_expand">
|
|
4054
|
+
<span class="settings-option-label">${subtitlesLabel} <strong>${currentLabel}</strong></span>
|
|
4055
|
+
<span class="expand-arrow">▼</span>
|
|
4056
|
+
</div>
|
|
4057
|
+
<div class="settings-expandable-content" style="display: none;">`;
|
|
3901
4058
|
|
|
3902
|
-
menuHTML += `<div class="settings-suboption ${!this.subtitlesEnabled ? 'active' : ''}" data-track="off">${this.t('
|
|
4059
|
+
menuHTML += `<div class="settings-suboption ${!this.subtitlesEnabled ? 'active' : ''}" data-track="off">${this.t('subtitles_off')}</div>`;
|
|
3903
4060
|
|
|
3904
4061
|
this.textTracks.forEach((trackData, index) => {
|
|
3905
4062
|
const isActive = this.currentSubtitleTrack === trackData.track;
|
|
@@ -3972,43 +4129,50 @@ addSettingsMenuScrollbar() {
|
|
|
3972
4129
|
* Bind settings menu events
|
|
3973
4130
|
*/
|
|
3974
4131
|
bindSettingsMenuEvents() {
|
|
3975
|
-
|
|
3976
|
-
const
|
|
4132
|
+
// Search in container instead of controls (for top bar)
|
|
4133
|
+
const settingsBtn = this.container?.querySelector('.settings-btn');
|
|
4134
|
+
const settingsMenu = this.container?.querySelector('.settings-menu');
|
|
4135
|
+
|
|
3977
4136
|
if (!settingsMenu || !settingsBtn) return;
|
|
3978
4137
|
|
|
3979
|
-
//
|
|
4138
|
+
// Toggle menu on button click
|
|
3980
4139
|
settingsBtn.addEventListener('click', (e) => {
|
|
3981
4140
|
e.stopPropagation();
|
|
3982
4141
|
settingsMenu.classList.toggle('active');
|
|
3983
4142
|
|
|
3984
|
-
//
|
|
4143
|
+
// When menu is opened, set max height and overflow
|
|
3985
4144
|
if (settingsMenu.classList.contains('active')) {
|
|
3986
|
-
const
|
|
3987
|
-
const containerRect = settingsMenu.parentElement.parentElement.getBoundingClientRect();
|
|
4145
|
+
const containerRect = this.container.getBoundingClientRect();
|
|
3988
4146
|
const btnRect = settingsBtn.getBoundingClientRect();
|
|
3989
|
-
|
|
3990
|
-
|
|
4147
|
+
|
|
4148
|
+
// Calculate available space below the button
|
|
4149
|
+
const spaceBelow = containerRect.bottom - btnRect.bottom - 30; // 30px margin
|
|
4150
|
+
|
|
4151
|
+
// Minimum 300px, maximum 600px or available space
|
|
4152
|
+
const maxMenuHeight = Math.max(300, Math.min(600, spaceBelow));
|
|
3991
4153
|
|
|
3992
4154
|
settingsMenu.style.maxHeight = `${maxMenuHeight}px`;
|
|
3993
4155
|
settingsMenu.style.overflowY = 'auto';
|
|
3994
4156
|
settingsMenu.style.overflowX = 'hidden';
|
|
4157
|
+
|
|
4158
|
+
if (this.options.debug) {
|
|
4159
|
+
console.log(`Settings menu opened: height=${maxMenuHeight}px (available=${spaceBelow}px)`);
|
|
4160
|
+
}
|
|
3995
4161
|
} else {
|
|
3996
|
-
|
|
3997
|
-
settingsMenu.style.
|
|
4162
|
+
// Reset when closing
|
|
4163
|
+
settingsMenu.style.maxHeight = '600px'; // Default max height
|
|
4164
|
+
settingsMenu.style.overflowY = 'auto';
|
|
3998
4165
|
}
|
|
3999
|
-
|
|
4000
4166
|
});
|
|
4001
4167
|
|
|
4002
|
-
//
|
|
4168
|
+
// Close menu when clicking outside
|
|
4003
4169
|
document.addEventListener('click', (e) => {
|
|
4004
4170
|
if (!settingsBtn?.contains(e.target) && !settingsMenu?.contains(e.target)) {
|
|
4005
4171
|
settingsMenu?.classList.remove('active');
|
|
4006
|
-
settingsMenu.style.maxHeight = 'none';
|
|
4007
|
-
settingsMenu.style.overflowY = 'visible';
|
|
4008
4172
|
}
|
|
4009
4173
|
});
|
|
4010
4174
|
|
|
4011
|
-
//
|
|
4175
|
+
// Manage clicks inside the menu
|
|
4012
4176
|
settingsMenu.addEventListener('click', (e) => {
|
|
4013
4177
|
e.stopPropagation();
|
|
4014
4178
|
|
|
@@ -4048,7 +4212,7 @@ bindSettingsMenuEvents() {
|
|
|
4048
4212
|
const trigger = wrapper.querySelector('.expandable-trigger');
|
|
4049
4213
|
const action = trigger.getAttribute('data-action');
|
|
4050
4214
|
|
|
4051
|
-
if (action === '
|
|
4215
|
+
if (action === 'speed_expand') {
|
|
4052
4216
|
const speed = parseFloat(e.target.getAttribute('data-speed'));
|
|
4053
4217
|
if (speed && speed > 0 && this.video && !this.isChangingQuality) {
|
|
4054
4218
|
this.video.playbackRate = speed;
|
|
@@ -4061,13 +4225,13 @@ bindSettingsMenuEvents() {
|
|
|
4061
4225
|
const label = trigger.querySelector('.settings-option-label');
|
|
4062
4226
|
if (label) {
|
|
4063
4227
|
const speedLabel = this.t('playback_speed') || 'Playback Speed';
|
|
4064
|
-
label.
|
|
4228
|
+
label.innerHTML = `${speedLabel} <strong>${speed}x</strong>`;
|
|
4065
4229
|
}
|
|
4066
4230
|
|
|
4067
4231
|
// Trigger event
|
|
4068
4232
|
this.triggerEvent('speedchange', { speed, previousSpeed: this.video.playbackRate });
|
|
4069
4233
|
}
|
|
4070
|
-
} else if (action === '
|
|
4234
|
+
} else if (action === 'subtitles_expand') {
|
|
4071
4235
|
const trackData = e.target.getAttribute('data-track');
|
|
4072
4236
|
if (trackData === 'off') {
|
|
4073
4237
|
this.disableSubtitles();
|
|
@@ -4084,7 +4248,7 @@ bindSettingsMenuEvents() {
|
|
|
4084
4248
|
const label = trigger.querySelector('.settings-option-label');
|
|
4085
4249
|
if (label) {
|
|
4086
4250
|
const subtitlesLabel = this.t('subtitles') || 'Subtitles';
|
|
4087
|
-
label.
|
|
4251
|
+
label.innerHTML = `${subtitlesLabel} <strong>${e.target.textContent}</strong>`;
|
|
4088
4252
|
}
|
|
4089
4253
|
}
|
|
4090
4254
|
}
|
|
@@ -6470,35 +6634,35 @@ bindChapterEvents() {
|
|
|
6470
6634
|
}
|
|
6471
6635
|
|
|
6472
6636
|
/**
|
|
6473
|
-
* Update chapter name in
|
|
6637
|
+
* Update chapter name in top bar subtitle dynamically
|
|
6638
|
+
* Shows current chapter title as subtitle in the top bar
|
|
6474
6639
|
*/
|
|
6475
6640
|
updateChapterInTitleOverlay() {
|
|
6476
6641
|
if (!this.video || !this.chapters || this.chapters.length === 0) return;
|
|
6477
6642
|
|
|
6478
|
-
|
|
6479
|
-
if (!
|
|
6480
|
-
|
|
6481
|
-
// Find or create
|
|
6482
|
-
let
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
`;
|
|
6496
|
-
titleOverlay.appendChild(chapterElement);
|
|
6643
|
+
// Use topBar instead of old titleOverlay
|
|
6644
|
+
if (!this.topBar) return;
|
|
6645
|
+
|
|
6646
|
+
// Find or create subtitle element in top bar
|
|
6647
|
+
let subtitleElement = this.topBar.querySelector('.video-subtitle');
|
|
6648
|
+
|
|
6649
|
+
if (!subtitleElement) {
|
|
6650
|
+
// Create subtitle element if it doesn't exist
|
|
6651
|
+
const titleSection = this.topBar.querySelector('.top-bar-title');
|
|
6652
|
+
if (!titleSection) return;
|
|
6653
|
+
|
|
6654
|
+
subtitleElement = document.createElement('span');
|
|
6655
|
+
subtitleElement.className = 'video-subtitle';
|
|
6656
|
+
titleSection.appendChild(subtitleElement);
|
|
6657
|
+
|
|
6658
|
+
// Save reference
|
|
6659
|
+
this.topBarSubtitle = subtitleElement;
|
|
6497
6660
|
}
|
|
6498
6661
|
|
|
6499
6662
|
// Find current chapter
|
|
6500
6663
|
const currentTime = this.video.currentTime;
|
|
6501
6664
|
let currentChapter = null;
|
|
6665
|
+
|
|
6502
6666
|
for (let i = this.chapters.length - 1; i >= 0; i--) {
|
|
6503
6667
|
if (currentTime >= this.chapters[i].time) {
|
|
6504
6668
|
currentChapter = this.chapters[i];
|
|
@@ -6506,12 +6670,22 @@ updateChapterInTitleOverlay() {
|
|
|
6506
6670
|
}
|
|
6507
6671
|
}
|
|
6508
6672
|
|
|
6509
|
-
// Update or hide chapter
|
|
6673
|
+
// Update subtitle with chapter title or hide if no chapter
|
|
6510
6674
|
if (currentChapter) {
|
|
6511
|
-
|
|
6512
|
-
|
|
6675
|
+
subtitleElement.textContent = currentChapter.title;
|
|
6676
|
+
subtitleElement.style.display = 'block';
|
|
6513
6677
|
} else {
|
|
6514
|
-
|
|
6678
|
+
// Se non c'è un capitolo attivo, mostra il sottotitolo originale o nascondi
|
|
6679
|
+
if (this.options.videoSubtitle) {
|
|
6680
|
+
subtitleElement.textContent = this.options.videoSubtitle;
|
|
6681
|
+
subtitleElement.style.display = 'block';
|
|
6682
|
+
} else {
|
|
6683
|
+
subtitleElement.style.display = 'none';
|
|
6684
|
+
}
|
|
6685
|
+
}
|
|
6686
|
+
|
|
6687
|
+
if (this.options.debug) {
|
|
6688
|
+
console.log('Chapter overlay updated:', currentChapter ? currentChapter.title : 'No chapter');
|
|
6515
6689
|
}
|
|
6516
6690
|
}
|
|
6517
6691
|
|
|
@@ -8439,8 +8613,7 @@ updateTimeDisplay() {
|
|
|
8439
8613
|
}
|
|
8440
8614
|
}
|
|
8441
8615
|
const fallback = {
|
|
8442
|
-
'loading': 'Loading...'
|
|
8443
|
-
'encodinginprogress': 'Encoding in progress...'
|
|
8616
|
+
'loading': 'Loading...'
|
|
8444
8617
|
};
|
|
8445
8618
|
return fallback[key] || key;
|
|
8446
8619
|
};
|
|
@@ -8453,7 +8626,7 @@ updateTimeDisplay() {
|
|
|
8453
8626
|
this.durationEl.classList.add('loading-state');
|
|
8454
8627
|
} else if (isDurationInvalid) {
|
|
8455
8628
|
// CHANGED: Move text to center overlay
|
|
8456
|
-
this.updateLoadingText(t('
|
|
8629
|
+
this.updateLoadingText(t('loading'));
|
|
8457
8630
|
// Optional: you might want to keep encoding text in bar OR move it too.
|
|
8458
8631
|
// If you want it ONLY in center:
|
|
8459
8632
|
this.durationEl.textContent = "--:--";
|