myetv-player 1.7.0 → 1.7.2
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/README.md +461 -154
- package/css/myetv-player.css +36 -0
- package/css/myetv-player.min.css +1 -1
- package/dist/myetv-player.js +415 -89
- package/dist/myetv-player.min.js +338 -60
- package/package.json +2 -1
- package/plugins/autosub/myetv-autosub-plugin.js +545 -188
- package/plugins/autosub/readme.md +156 -66
- package/plugins/radio/api.php +154 -0
- package/plugins/radio/icons/bolt-lightning-solid.png +0 -0
- package/plugins/radio/icons/compact-disc-solid.png +0 -0
- package/plugins/radio/icons/guitar-solid.png +0 -0
- package/plugins/radio/icons/headphones-solid.png +0 -0
- package/plugins/radio/icons/medal-solid.png +0 -0
- package/plugins/radio/icons/music-solid.png +0 -0
- package/plugins/radio/icons/newspaper-solid.png +0 -0
- package/plugins/radio/icons/radio-solid.png +0 -0
- package/plugins/radio/icons/readme.md +1 -0
- package/plugins/radio/myetv-radio-plugin.js +1655 -0
- package/plugins/radio/php/data/readme.md +1 -0
- package/plugins/radio/php/radio_stats.php +203 -0
- package/plugins/radio/proxy.php +26 -0
- package/plugins/radio/readme.md +176 -0
- package/plugins/radio/station_example.json +47 -0
- package/plugins/video-loading/myetv-video-loading-plugin.js +157 -0
- package/plugins/video-loading/readme.md +87 -0
package/dist/myetv-player.min.js
CHANGED
|
@@ -629,6 +629,9 @@ constructor(videoElement, options = {}) {
|
|
|
629
629
|
showPictureInPicture: true, // Enable PiP button
|
|
630
630
|
showSubtitles: true, // Enable subtitles button
|
|
631
631
|
subtitlesEnabled: false, // Enable subtitles by default if available
|
|
632
|
+
externalSubtitleTracks: [],// external subtitles track from url
|
|
633
|
+
externalSubtitleLabel: 'Default Subtitles', //label for the subtitle track url
|
|
634
|
+
externalSubtitleLang: 'en', // language of the subtitles track url
|
|
632
635
|
showSettingsMenu: true, // Show settings menu in top bar
|
|
633
636
|
autoHide: true, // auto-hide controls when idle
|
|
634
637
|
autoHideDelay: 3000, // hide controls after ... seconds of inactivity (specificed in milliseconds)
|
|
@@ -655,6 +658,7 @@ constructor(videoElement, options = {}) {
|
|
|
655
658
|
brandLogoUrl: '', // URL for brand logo image
|
|
656
659
|
brandLogoLinkUrl: '', // Optional URL to open when clicking the logo
|
|
657
660
|
brandLogoTooltipText: '', // Tooltip text for brand logo
|
|
661
|
+
loadingLogo: null, // URL image to show inside the loading circle
|
|
658
662
|
playlistEnabled: true, // Enable/disable playlist detection
|
|
659
663
|
playlistAutoPlay: true, // Auto-play next video when current ends
|
|
660
664
|
playlistLoop: false, // Loop playlist when reaching the end
|
|
@@ -780,8 +784,31 @@ constructor(videoElement, options = {}) {
|
|
|
780
784
|
VideoPlayerTranslations.setLanguage(this.options.language);
|
|
781
785
|
}
|
|
782
786
|
|
|
783
|
-
|
|
784
|
-
this.
|
|
787
|
+
this.savedAutoplayIntent = options.autoplay || false;
|
|
788
|
+
this.options.autoplay = false;
|
|
789
|
+
|
|
790
|
+
if (this.video) {
|
|
791
|
+
if (this.video.hasAttribute('autoplay')) {
|
|
792
|
+
this.savedAutoplayIntent = true;
|
|
793
|
+
this.video.removeAttribute('autoplay');
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
this.video.pause();
|
|
797
|
+
this.video.preload = 'none';
|
|
798
|
+
|
|
799
|
+
if (this.video.hasAttribute('poster')) {
|
|
800
|
+
this.savedPoster = this.video.getAttribute('poster');
|
|
801
|
+
this.video.setAttribute('poster', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
this.video.pause();
|
|
805
|
+
this.video.preload = 'none';
|
|
806
|
+
|
|
807
|
+
this.video.removeAttribute('src');
|
|
808
|
+
this.video.load();
|
|
809
|
+
|
|
810
|
+
this.video.style.opacity = '0';
|
|
811
|
+
this.video.style.visibility = 'hidden';
|
|
785
812
|
}
|
|
786
813
|
|
|
787
814
|
try {
|
|
@@ -871,17 +898,8 @@ constructor(videoElement, options = {}) {
|
|
|
871
898
|
this.updateVolumeSliderVisual();
|
|
872
899
|
this.initVolumeTooltip();
|
|
873
900
|
this.updateTooltips();
|
|
874
|
-
this.markPlayerReady();
|
|
875
|
-
this.initializePluginSystem();
|
|
876
|
-
this.restoreSourcesAsync();
|
|
877
901
|
|
|
878
|
-
this.
|
|
879
|
-
this.initializeQualityMonitoring();
|
|
880
|
-
|
|
881
|
-
this.initializeResolution();
|
|
882
|
-
this.initializeChapters();
|
|
883
|
-
this.initializePoster();
|
|
884
|
-
this.initializeWatermark();
|
|
902
|
+
this.initializePluginSystem();
|
|
885
903
|
|
|
886
904
|
} catch (error) {
|
|
887
905
|
if (this.options.debug) console.error('Video player initialization error:', error);
|
|
@@ -1004,6 +1022,8 @@ interceptAutoLoading() {
|
|
|
1004
1022
|
|
|
1005
1023
|
this.hideNativePlayer();
|
|
1006
1024
|
|
|
1025
|
+
this.video.load();
|
|
1026
|
+
|
|
1007
1027
|
if (this.options.debug) console.log('📁 Sources temporarily disabled to prevent blocking');
|
|
1008
1028
|
}
|
|
1009
1029
|
|
|
@@ -1166,6 +1186,7 @@ markPlayerReady() {
|
|
|
1166
1186
|
this.video.style.visibility = '';
|
|
1167
1187
|
this.video.style.opacity = '';
|
|
1168
1188
|
this.video.style.pointerEvents = '';
|
|
1189
|
+
this.video.style.display = '';
|
|
1169
1190
|
}
|
|
1170
1191
|
|
|
1171
1192
|
if (typeof this.updateSettingsMenuVisibility === 'function') {
|
|
@@ -1251,24 +1272,40 @@ createPlayerStructure() {
|
|
|
1251
1272
|
createInitialLoading() {
|
|
1252
1273
|
const initialLoader = document.createElement('div');
|
|
1253
1274
|
initialLoader.className = 'initial-loading';
|
|
1254
|
-
initialLoader.innerHTML =
|
|
1275
|
+
initialLoader.innerHTML = `
|
|
1276
|
+
<div class="loading-spinner-wrap">
|
|
1277
|
+
<div class="loading-spinner"></div>
|
|
1278
|
+
${this.options.loadingLogo
|
|
1279
|
+
? `<img class="loading-spinner-logo" src="${this.options.loadingLogo}" alt="" />`
|
|
1280
|
+
: ''}
|
|
1281
|
+
</div>
|
|
1282
|
+
<div class="loading-text"></div>
|
|
1283
|
+
`;
|
|
1255
1284
|
this.container.appendChild(initialLoader);
|
|
1256
1285
|
this.initialLoading = initialLoader;
|
|
1257
1286
|
}
|
|
1258
1287
|
|
|
1259
|
-
collectVideoQualities() {
|
|
1260
|
-
if (this.options.debug) console.log('📁 Video qualities will be loaded with restored sources');
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
1288
|
createLoadingOverlay() {
|
|
1264
1289
|
const overlay = document.createElement('div');
|
|
1265
1290
|
overlay.className = 'loading-overlay';
|
|
1266
|
-
overlay.id =
|
|
1267
|
-
overlay.innerHTML =
|
|
1291
|
+
overlay.id = `loadingOverlay-${this.getUniqueId()}`;
|
|
1292
|
+
overlay.innerHTML = `
|
|
1293
|
+
<div class="loading-spinner-wrap">
|
|
1294
|
+
<div class="loading-spinner"></div>
|
|
1295
|
+
${this.options.loadingLogo
|
|
1296
|
+
? `<img class="loading-spinner-logo" src="${this.options.loadingLogo}" alt="" />`
|
|
1297
|
+
: ''}
|
|
1298
|
+
</div>
|
|
1299
|
+
<div class="loading-text"></div>
|
|
1300
|
+
`;
|
|
1268
1301
|
this.container.appendChild(overlay);
|
|
1269
1302
|
this.loadingOverlay = overlay;
|
|
1270
1303
|
}
|
|
1271
1304
|
|
|
1305
|
+
collectVideoQualities() {
|
|
1306
|
+
if (this.options.debug) console.log('📁 Video qualities will be loaded with restored sources');
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1272
1309
|
updateTooltips() {
|
|
1273
1310
|
if (!this.controls) return;
|
|
1274
1311
|
|
|
@@ -1850,6 +1887,12 @@ updateSeekTooltip(e) {
|
|
|
1850
1887
|
}
|
|
1851
1888
|
|
|
1852
1889
|
play() {
|
|
1890
|
+
if (!this.isPlayerReady) {
|
|
1891
|
+
this.savedAutoplayIntent = true;
|
|
1892
|
+
if (this.options.debug) console.log('🛑 Play requested but player is booting. Intent saved for later.');
|
|
1893
|
+
return Promise ? Promise.resolve() : undefined;
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1853
1896
|
if (!this.video || this.isChangingQuality) return;
|
|
1854
1897
|
|
|
1855
1898
|
this.video.play().catch(err => {
|
|
@@ -1866,6 +1909,11 @@ play() {
|
|
|
1866
1909
|
}
|
|
1867
1910
|
|
|
1868
1911
|
pause() {
|
|
1912
|
+
if (!this.isPlayerReady) {
|
|
1913
|
+
this.savedAutoplayIntent = false;
|
|
1914
|
+
return;
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1869
1917
|
if (!this.video) return;
|
|
1870
1918
|
|
|
1871
1919
|
this.video.pause();
|
|
@@ -3962,6 +4010,48 @@ populateSettingsMenu() {
|
|
|
3962
4010
|
settingsMenu.innerHTML = menuHTML;
|
|
3963
4011
|
}
|
|
3964
4012
|
|
|
4013
|
+
updateSettingsMenuUI() {
|
|
4014
|
+
const settingsMenu = this.container?.querySelector('.settings-menu');
|
|
4015
|
+
if (!settingsMenu) return;
|
|
4016
|
+
|
|
4017
|
+
if (this.options.showSubtitles) {
|
|
4018
|
+
const subtitlesTrigger = settingsMenu.querySelector('[data-action="subtitles_expand"]');
|
|
4019
|
+
|
|
4020
|
+
if (subtitlesTrigger) {
|
|
4021
|
+
|
|
4022
|
+
const label = subtitlesTrigger.querySelector('.settings-option-label');
|
|
4023
|
+
if (label) {
|
|
4024
|
+
const subtitlesLabel = this.t('subtitles') || 'Subtitles';
|
|
4025
|
+
const currentTrack = this.currentSubtitleTrack;
|
|
4026
|
+
|
|
4027
|
+
let currentLabelText = this.t('subtitlesoff') || 'Off';
|
|
4028
|
+
if (this.subtitlesEnabled && currentTrack) {
|
|
4029
|
+
currentLabelText = currentTrack.label || 'Unknown';
|
|
4030
|
+
}
|
|
4031
|
+
|
|
4032
|
+
label.innerHTML = `${subtitlesLabel} <strong>${currentLabelText}</strong>`;
|
|
4033
|
+
}
|
|
4034
|
+
|
|
4035
|
+
const submenuContent = subtitlesTrigger.nextElementSibling;
|
|
4036
|
+
if (submenuContent && submenuContent.classList.contains('settings-expandable-content')) {
|
|
4037
|
+
submenuContent.querySelectorAll('.settings-suboption').forEach(opt => {
|
|
4038
|
+
const trackData = opt.getAttribute('data-track');
|
|
4039
|
+
opt.classList.remove('active');
|
|
4040
|
+
|
|
4041
|
+
if (trackData === 'off' && !this.subtitlesEnabled) {
|
|
4042
|
+
opt.classList.add('active');
|
|
4043
|
+
} else if (this.subtitlesEnabled && trackData !== 'off') {
|
|
4044
|
+
const trackIndex = parseInt(trackData);
|
|
4045
|
+
if (this.textTracks[trackIndex] && this.textTracks[trackIndex].track === this.currentSubtitleTrack) {
|
|
4046
|
+
opt.classList.add('active');
|
|
4047
|
+
}
|
|
4048
|
+
}
|
|
4049
|
+
});
|
|
4050
|
+
}
|
|
4051
|
+
}
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
|
|
3965
4055
|
addSettingsMenuScrollbar() {
|
|
3966
4056
|
const settingsMenu = this.controls?.querySelector('.settings-menu');
|
|
3967
4057
|
if (!settingsMenu) return;
|
|
@@ -5517,6 +5607,31 @@ createCustomSubtitleOverlay() {
|
|
|
5517
5607
|
if (this.options.debug) console.log('✅ Custom subtitle overlay created with responsive settings');
|
|
5518
5608
|
}
|
|
5519
5609
|
|
|
5610
|
+
parseTimeToSecondsUniversal(timeString) {
|
|
5611
|
+
if (!timeString) return 0;
|
|
5612
|
+
|
|
5613
|
+
let normalized = timeString.replace(',', '.');
|
|
5614
|
+
let parts = normalized.split('.');
|
|
5615
|
+
|
|
5616
|
+
let timeParts = parts[0].split(':');
|
|
5617
|
+
let ms = parts[1] ? parseInt(parts[1], 10) / 1000 : 0;
|
|
5618
|
+
|
|
5619
|
+
let hours = 0, minutes = 0, seconds = 0;
|
|
5620
|
+
|
|
5621
|
+
if (timeParts.length === 3) {
|
|
5622
|
+
|
|
5623
|
+
hours = parseInt(timeParts[0], 10);
|
|
5624
|
+
minutes = parseInt(timeParts[1], 10);
|
|
5625
|
+
seconds = parseInt(timeParts[2], 10);
|
|
5626
|
+
} else if (timeParts.length === 2) {
|
|
5627
|
+
|
|
5628
|
+
minutes = parseInt(timeParts[0], 10);
|
|
5629
|
+
seconds = parseInt(timeParts[1], 10);
|
|
5630
|
+
}
|
|
5631
|
+
|
|
5632
|
+
return (hours * 3600) + (minutes * 60) + seconds + ms;
|
|
5633
|
+
}
|
|
5634
|
+
|
|
5520
5635
|
customTimeToSeconds(timeString) {
|
|
5521
5636
|
if (!timeString) return 0;
|
|
5522
5637
|
|
|
@@ -5542,6 +5657,31 @@ customTimeToSeconds(timeString) {
|
|
|
5542
5657
|
return hours * 3600 + minutes * 60 + seconds + milliseconds / 1000;
|
|
5543
5658
|
}
|
|
5544
5659
|
|
|
5660
|
+
parseTimeToSecondsUniversal(timeString) {
|
|
5661
|
+
if (!timeString) return 0;
|
|
5662
|
+
|
|
5663
|
+
const normalized = timeString.replace(',', '.');
|
|
5664
|
+
const parts = normalized.split('.');
|
|
5665
|
+
|
|
5666
|
+
const timeParts = parts[0].split(':');
|
|
5667
|
+
const ms = parts[1] ? parseInt(parts[1], 10) / 1000 : 0;
|
|
5668
|
+
|
|
5669
|
+
let hours = 0, minutes = 0, seconds = 0;
|
|
5670
|
+
|
|
5671
|
+
if (timeParts.length === 3) {
|
|
5672
|
+
|
|
5673
|
+
hours = parseInt(timeParts[0], 10);
|
|
5674
|
+
minutes = parseInt(timeParts[1], 10);
|
|
5675
|
+
seconds = parseInt(timeParts[2], 10);
|
|
5676
|
+
} else if (timeParts.length === 2) {
|
|
5677
|
+
|
|
5678
|
+
minutes = parseInt(timeParts[0], 10);
|
|
5679
|
+
seconds = parseInt(timeParts[1], 10);
|
|
5680
|
+
}
|
|
5681
|
+
|
|
5682
|
+
return (hours * 3600) + (minutes * 60) + seconds + ms;
|
|
5683
|
+
}
|
|
5684
|
+
|
|
5545
5685
|
parseCustomSRT(srtText) {
|
|
5546
5686
|
var subtitles = [];
|
|
5547
5687
|
var normalizedText = srtText.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
@@ -5575,6 +5715,57 @@ parseCustomSRT(srtText) {
|
|
|
5575
5715
|
return subtitles;
|
|
5576
5716
|
}
|
|
5577
5717
|
|
|
5718
|
+
injectExternalSubtitleTracks(tracksArray) {
|
|
5719
|
+
|
|
5720
|
+
if (!this.video || !Array.isArray(tracksArray) || tracksArray.length === 0) return;
|
|
5721
|
+
|
|
5722
|
+
this.video.crossOrigin = "anonymous";
|
|
5723
|
+
let loadedCount = 0;
|
|
5724
|
+
|
|
5725
|
+
tracksArray.forEach(trackData => {
|
|
5726
|
+
const trackEl = document.createElement('track');
|
|
5727
|
+
trackEl.kind = 'subtitles';
|
|
5728
|
+
trackEl.label = trackData.label;
|
|
5729
|
+
trackEl.srclang = trackData.lang;
|
|
5730
|
+
trackEl.src = trackData.src;
|
|
5731
|
+
|
|
5732
|
+
if (trackData.default) {
|
|
5733
|
+
trackEl.default = true;
|
|
5734
|
+
trackEl.setAttribute('default', 'default');
|
|
5735
|
+
trackEl.setAttribute('data-default', 'true');
|
|
5736
|
+
}
|
|
5737
|
+
|
|
5738
|
+
trackEl.addEventListener('load', () => {
|
|
5739
|
+
if (trackEl.track) {
|
|
5740
|
+
|
|
5741
|
+
trackEl.track.mode = trackData.default ? 'showing' : 'hidden';
|
|
5742
|
+
}
|
|
5743
|
+
|
|
5744
|
+
loadedCount++;
|
|
5745
|
+
|
|
5746
|
+
if (loadedCount === tracksArray.length) {
|
|
5747
|
+
console.log(`MYETV Player: ${loadedCount} external subtitle tracks loaded.`);
|
|
5748
|
+
|
|
5749
|
+
if (typeof this.initializeSubtitles === 'function') {
|
|
5750
|
+
this.initializeSubtitles();
|
|
5751
|
+
} else if (typeof this.initializeCustomSubtitles === 'function') {
|
|
5752
|
+
this.initializeCustomSubtitles();
|
|
5753
|
+
} else if (typeof this.loadCustomSubtitleTracks === 'function') {
|
|
5754
|
+
this.loadCustomSubtitleTracks();
|
|
5755
|
+
}
|
|
5756
|
+
}
|
|
5757
|
+
});
|
|
5758
|
+
|
|
5759
|
+
trackEl.addEventListener('error', () => {
|
|
5760
|
+
console.warn(`MYETV Player: Failed to load track ${trackData.lang}`);
|
|
5761
|
+
|
|
5762
|
+
loadedCount++;
|
|
5763
|
+
});
|
|
5764
|
+
|
|
5765
|
+
this.video.appendChild(trackEl);
|
|
5766
|
+
});
|
|
5767
|
+
}
|
|
5768
|
+
|
|
5578
5769
|
loadCustomSubtitleTracks() {
|
|
5579
5770
|
var self = this;
|
|
5580
5771
|
var tracks = this.video.querySelectorAll('track[kind="subtitles"]');
|
|
@@ -5585,6 +5776,8 @@ loadCustomSubtitleTracks() {
|
|
|
5585
5776
|
var label = track.getAttribute('label') || 'Unknown';
|
|
5586
5777
|
var srclang = track.getAttribute('srclang') || '';
|
|
5587
5778
|
|
|
5779
|
+
var isDefault = track.default || track.hasAttribute('default');
|
|
5780
|
+
|
|
5588
5781
|
var trackObj = {
|
|
5589
5782
|
label: label,
|
|
5590
5783
|
language: srclang,
|
|
@@ -5598,30 +5791,45 @@ loadCustomSubtitleTracks() {
|
|
|
5598
5791
|
return response.text();
|
|
5599
5792
|
})
|
|
5600
5793
|
.then(function (srtText) {
|
|
5794
|
+
|
|
5601
5795
|
var normalizedText = srtText.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
5796
|
+
|
|
5602
5797
|
var blocks = normalizedText.trim().split('\n\n');
|
|
5603
5798
|
|
|
5604
5799
|
for (var i = 0; i < blocks.length; i++) {
|
|
5605
5800
|
var block = blocks[i].trim();
|
|
5606
|
-
if (!block) continue;
|
|
5801
|
+
if (!block || block.toUpperCase().startsWith('WEBVTT')) continue;
|
|
5802
|
+
|
|
5607
5803
|
var lines = block.split('\n');
|
|
5804
|
+
var timeMatch = null;
|
|
5805
|
+
var textLines = [];
|
|
5608
5806
|
|
|
5609
|
-
|
|
5610
|
-
var
|
|
5611
|
-
var timeMatch = timeLine.match(/(\d{2}:\d{2}:\d{2},\d{3})\s*-->\s*(\d{2}:\d{2}:\d{2},\d{3})/);
|
|
5807
|
+
for (var j = 0; j < lines.length; j++) {
|
|
5808
|
+
var line = lines[j].trim();
|
|
5612
5809
|
|
|
5613
|
-
if (timeMatch) {
|
|
5614
|
-
var
|
|
5615
|
-
|
|
5616
|
-
|
|
5810
|
+
if (!timeMatch) {
|
|
5811
|
+
var match = line.match(/(\d{2,}:\d{2}:\d{2}[.,]\d{3}|\d{2}:\d{2}[.,]\d{3})\s*-->\s*(\d{2,}:\d{2}:\d{2}[.,]\d{3}|\d{2}:\d{2}[.,]\d{3})/);
|
|
5812
|
+
if (match) {
|
|
5813
|
+
timeMatch = match;
|
|
5814
|
+
continue;
|
|
5815
|
+
}
|
|
5816
|
+
}
|
|
5617
5817
|
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5818
|
+
if (!timeMatch && /^\d+$/.test(line)) {
|
|
5819
|
+
continue;
|
|
5820
|
+
}
|
|
5621
5821
|
|
|
5622
|
-
|
|
5822
|
+
if (timeMatch) {
|
|
5823
|
+
textLines.push(line);
|
|
5824
|
+
}
|
|
5825
|
+
}
|
|
5623
5826
|
|
|
5624
|
-
if (
|
|
5827
|
+
if (timeMatch && textLines.length > 0) {
|
|
5828
|
+
var startTime = self.parseTimeToSecondsUniversal(timeMatch[1]);
|
|
5829
|
+
var endTime = self.parseTimeToSecondsUniversal(timeMatch[2]);
|
|
5830
|
+
var text = textLines.join('\n').trim().replace(/<[^>]*>/g, '');
|
|
5831
|
+
|
|
5832
|
+
if (text && !isNaN(startTime) && !isNaN(endTime) && startTime < endTime) {
|
|
5625
5833
|
trackObj.subtitles.push({
|
|
5626
5834
|
start: startTime,
|
|
5627
5835
|
end: endTime,
|
|
@@ -5630,11 +5838,26 @@ loadCustomSubtitleTracks() {
|
|
|
5630
5838
|
}
|
|
5631
5839
|
}
|
|
5632
5840
|
}
|
|
5841
|
+
|
|
5842
|
+
if (self.options.debug) {
|
|
5843
|
+
console.log('✅ Custom parser loaded ' + trackObj.subtitles.length + ' subtitles for ' + label);
|
|
5633
5844
|
}
|
|
5634
5845
|
|
|
5846
|
+
var isDefault = track.default || track.hasAttribute('default') || track.getAttribute('data-default') === 'true';
|
|
5847
|
+
|
|
5848
|
+
if (isDefault) {
|
|
5849
|
+
if (self.options.debug) {
|
|
5850
|
+
console.log('⏳ Waiting 500ms for UI alignment... track:', label);
|
|
5851
|
+
}
|
|
5852
|
+
|
|
5853
|
+
setTimeout(function () {
|
|
5635
5854
|
if (self.options.debug) {
|
|
5636
|
-
console.log('
|
|
5855
|
+
console.log('🎯 Forced auto-enable triggered now!');
|
|
5637
5856
|
}
|
|
5857
|
+
self.enableSubtitleTrack(index);
|
|
5858
|
+
}, 500); // 500 milliseconds of delay
|
|
5859
|
+
}
|
|
5860
|
+
|
|
5638
5861
|
})
|
|
5639
5862
|
.catch(function (error) {
|
|
5640
5863
|
console.error('❌ Error loading ' + label + ':', error);
|
|
@@ -5758,14 +5981,18 @@ enableSubtitleTrack(trackIndex) {
|
|
|
5758
5981
|
this.subtitlesEnabled = true;
|
|
5759
5982
|
|
|
5760
5983
|
if (this.video.textTracks && this.video.textTracks[trackIndex]) {
|
|
5761
|
-
this.video.textTracks[trackIndex].mode = 'disabled';
|
|
5984
|
+
this.video.textTracks[trackIndex].mode = 'disabled';
|
|
5762
5985
|
}
|
|
5763
5986
|
|
|
5764
5987
|
this.updateSubtitlesButton();
|
|
5765
5988
|
this.populateSubtitlesMenu();
|
|
5766
5989
|
|
|
5990
|
+
if (typeof this.updateSettingsMenuUI === 'function') {
|
|
5991
|
+
this.updateSettingsMenuUI();
|
|
5992
|
+
}
|
|
5993
|
+
|
|
5767
5994
|
if (this.options.debug) {
|
|
5768
|
-
console.log('✅ Custom subtitles
|
|
5995
|
+
console.log('✅ Custom UI subtitles strictly enforced for track', trackIndex);
|
|
5769
5996
|
}
|
|
5770
5997
|
|
|
5771
5998
|
this.triggerEvent('subtitlechange', {
|
|
@@ -5774,10 +6001,6 @@ enableSubtitleTrack(trackIndex) {
|
|
|
5774
6001
|
trackLabel: this.textTracks[trackIndex].label,
|
|
5775
6002
|
trackLanguage: this.textTracks[trackIndex].language
|
|
5776
6003
|
});
|
|
5777
|
-
} else {
|
|
5778
|
-
if (this.options.debug) {
|
|
5779
|
-
console.error('❌ Failed to enable custom subtitles for track', trackIndex);
|
|
5780
|
-
}
|
|
5781
6004
|
}
|
|
5782
6005
|
}
|
|
5783
6006
|
|
|
@@ -5791,6 +6014,10 @@ disableSubtitles() {
|
|
|
5791
6014
|
this.updateSubtitlesButton();
|
|
5792
6015
|
this.populateSubtitlesMenu();
|
|
5793
6016
|
|
|
6017
|
+
if (typeof this.updateSettingsMenuUI === 'function') {
|
|
6018
|
+
this.updateSettingsMenuUI();
|
|
6019
|
+
}
|
|
6020
|
+
|
|
5794
6021
|
if (this.options.debug) console.log('📝 Subtitles disabled');
|
|
5795
6022
|
|
|
5796
6023
|
this.triggerEvent('subtitlechange', {
|
|
@@ -7693,35 +7920,86 @@ setDashQuality(qualityIndex) {
|
|
|
7693
7920
|
return this;
|
|
7694
7921
|
}
|
|
7695
7922
|
|
|
7696
|
-
initializePluginSystem() {
|
|
7697
|
-
this.plugins = {};
|
|
7923
|
+
initializePluginSystem() {
|
|
7924
|
+
this.plugins = {};
|
|
7698
7925
|
this.pluginHooks = {
|
|
7699
|
-
'beforeInit': [],
|
|
7700
|
-
'
|
|
7701
|
-
'
|
|
7702
|
-
'afterPlay': [],
|
|
7703
|
-
'beforePause': [],
|
|
7704
|
-
'afterPause': [],
|
|
7705
|
-
'beforeQualityChange': [],
|
|
7706
|
-
'afterQualityChange': [],
|
|
7707
|
-
'beforeDestroy': [],
|
|
7708
|
-
'afterDestroy': []
|
|
7926
|
+
'beforeInit': [], 'afterInit': [], 'beforePlay': [], 'afterPlay': [],
|
|
7927
|
+
'beforePause': [], 'afterPause': [], 'beforeQualityChange': [],
|
|
7928
|
+
'afterQualityChange': [], 'beforeDestroy': [], 'afterDestroy': []
|
|
7709
7929
|
};
|
|
7710
7930
|
|
|
7711
|
-
if (this.options.debug)
|
|
7712
|
-
console.log('🔌 Plugin system initialized');
|
|
7713
|
-
}
|
|
7931
|
+
if (this.options.debug) console.log('🔌 Plugin system initialized');
|
|
7714
7932
|
if (this.options.plugins && typeof this.options.plugins === 'object') {
|
|
7715
|
-
this.
|
|
7933
|
+
this.loadPluginsSequentially(this.options.plugins);
|
|
7934
|
+
} else {
|
|
7935
|
+
this.finalizePlayerSetup();
|
|
7936
|
+
}
|
|
7937
|
+
}
|
|
7938
|
+
|
|
7939
|
+
async loadPluginsSequentially(pluginsConfig) {
|
|
7940
|
+
const pluginList = Object.keys(pluginsConfig).map(pluginName => {
|
|
7941
|
+
return {
|
|
7942
|
+
name: pluginName,
|
|
7943
|
+
config: pluginsConfig[pluginName],
|
|
7944
|
+
order: pluginsConfig[pluginName] && pluginsConfig[pluginName].order !== undefined
|
|
7945
|
+
? pluginsConfig[pluginName].order : 99
|
|
7946
|
+
};
|
|
7947
|
+
}).sort((a, b) => a.order - b.order);
|
|
7948
|
+
for (const pluginData of pluginList) {
|
|
7949
|
+
if (this.options.debug) console.log(`🔌 Loading plugin: ${pluginData.name} (order: ${pluginData.order})`);
|
|
7950
|
+
const pluginInstance = this.usePlugin(pluginData.name, pluginData.config);
|
|
7951
|
+
if (pluginInstance && typeof pluginInstance.waitForCompletion === 'function') {
|
|
7952
|
+
if (this.options.debug) console.log(`🔌 Pausing queue. Waiting for ${pluginData.name} to complete...`);
|
|
7953
|
+
await pluginInstance.waitForCompletion();
|
|
7954
|
+
if (this.options.debug) console.log(`🔌 ${pluginData.name} completed. Resuming queue.`);
|
|
7716
7955
|
}
|
|
7956
|
+
}
|
|
7957
|
+
this.finalizePlayerSetup();
|
|
7717
7958
|
}
|
|
7718
7959
|
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
this.
|
|
7960
|
+
finalizePlayerSetup() {
|
|
7961
|
+
if (this.options.debug) {
|
|
7962
|
+
console.log('🚀 Finalizing main player setup...');
|
|
7963
|
+
}
|
|
7964
|
+
if (this.savedAutoplayIntent) {
|
|
7965
|
+
this.options.autoplay = true;
|
|
7966
|
+
}
|
|
7967
|
+
this.markPlayerReady();
|
|
7968
|
+
|
|
7969
|
+
this.restoreSourcesAsync();
|
|
7970
|
+
this.initializeSubtitles();
|
|
7971
|
+
this.initializeQualityMonitoring();
|
|
7972
|
+
this.initializeResolution();
|
|
7973
|
+
this.initializeChapters();
|
|
7974
|
+
const hasExternalIframe = this.options.plugins && (
|
|
7975
|
+
this.options.plugins.youtube ||
|
|
7976
|
+
this.options.plugins.vimeo ||
|
|
7977
|
+
this.options.plugins.twitch
|
|
7978
|
+
);
|
|
7979
|
+
|
|
7980
|
+
if (!hasExternalIframe) {
|
|
7981
|
+
this.initializePoster();
|
|
7982
|
+
}
|
|
7983
|
+
|
|
7984
|
+
this.initializeWatermark();
|
|
7985
|
+
if (this.options.externalSubtitleTracks && this.options.externalSubtitleTracks.length > 0) {
|
|
7986
|
+
this.injectExternalSubtitleTracks(this.options.externalSubtitleTracks);
|
|
7987
|
+
}
|
|
7988
|
+
if (this.savedAutoplayIntent) {
|
|
7989
|
+
if (this.options.debug) console.log('🚀 Triggering delayed autoplay...');
|
|
7990
|
+
|
|
7991
|
+
if (this.video) {
|
|
7992
|
+
this.video.setAttribute('autoplay', '');
|
|
7993
|
+
this.video.style.opacity = '1';
|
|
7994
|
+
this.video.style.visibility = '';
|
|
7724
7995
|
}
|
|
7996
|
+
|
|
7997
|
+
setTimeout(() => {
|
|
7998
|
+
this.play();
|
|
7999
|
+
}, 300);
|
|
8000
|
+
} else if (this.video) {
|
|
8001
|
+
this.video.style.opacity = '1';
|
|
8002
|
+
this.video.style.visibility = '';
|
|
7725
8003
|
}
|
|
7726
8004
|
}
|
|
7727
8005
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myetv-player",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
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": [
|
|
@@ -71,3 +71,4 @@
|
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
|
|
74
|
+
|