myetv-player 1.2.0 → 1.3.0
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 +131 -0
- package/css/myetv-player.min.css +1 -1
- package/dist/myetv-player.js +547 -102
- package/dist/myetv-player.min.js +486 -93
- package/package.json +35 -17
- package/plugins/twitch/myetv-player-twitch-plugin.js +125 -11
- package/plugins/vimeo/myetv-player-vimeo.js +80 -49
- package/plugins/youtube/README.md +5 -2
- package/plugins/youtube/myetv-player-youtube-plugin.js +766 -6
- package/.github/workflows/codeql.yml +0 -100
- package/.github/workflows/npm-publish.yml +0 -30
- package/SECURITY.md +0 -50
- package/build.js +0 -195
- package/scss/README.md +0 -161
- package/scss/_audio-player.scss +0 -21
- package/scss/_base.scss +0 -116
- package/scss/_controls.scss +0 -204
- package/scss/_loading.scss +0 -111
- package/scss/_menus.scss +0 -432
- package/scss/_mixins.scss +0 -112
- package/scss/_poster.scss +0 -8
- package/scss/_progress-bar.scss +0 -319
- package/scss/_resolution.scss +0 -68
- package/scss/_responsive.scss +0 -1368
- package/scss/_themes.scss +0 -30
- package/scss/_title-overlay.scss +0 -60
- package/scss/_tooltips.scss +0 -7
- package/scss/_variables.scss +0 -49
- package/scss/_video.scss +0 -221
- package/scss/_volume.scss +0 -122
- package/scss/_watermark.scss +0 -128
- package/scss/myetv-player.scss +0 -51
- package/scss/package.json +0 -16
- package/src/README.md +0 -560
- package/src/chapters.js +0 -521
- package/src/controls.js +0 -1242
- package/src/core.js +0 -1922
- package/src/events.js +0 -537
- package/src/fullscreen.js +0 -82
- package/src/i18n.js +0 -374
- package/src/playlist.js +0 -177
- package/src/plugins.js +0 -384
- package/src/quality.js +0 -963
- package/src/streaming.js +0 -346
- package/src/subtitles.js +0 -524
- package/src/utils.js +0 -65
- package/src/watermark.js +0 -246
package/src/streaming.js
DELETED
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
// Streaming Module for MYETV Video Player
|
|
2
|
-
// Conservative modularization - original code preserved exactly
|
|
3
|
-
// Created by https://www.myetv.tv https://oskarcosimo.com
|
|
4
|
-
|
|
5
|
-
async loadAdaptiveLibraries() {
|
|
6
|
-
if (!this.options.adaptiveStreaming) return false;
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
// Load DASH library if not already loaded
|
|
10
|
-
if (!this.librariesLoaded.dash && !window.dashjs) {
|
|
11
|
-
await this.loadScript(this.options.dashLibUrl);
|
|
12
|
-
this.librariesLoaded.dash = true;
|
|
13
|
-
if (this.options.debug) console.log('📡 Dash.js library loaded');
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Load HLS library if not already loaded
|
|
17
|
-
if (!this.librariesLoaded.hls && !window.Hls) {
|
|
18
|
-
await this.loadScript(this.options.hlsLibUrl);
|
|
19
|
-
this.librariesLoaded.hls = true;
|
|
20
|
-
if (this.options.debug) console.log('📡 HLS.js library loaded');
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return true;
|
|
24
|
-
} catch (error) {
|
|
25
|
-
if (this.options.debug) console.error('Failed to load adaptive streaming libraries:', error);
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
detectStreamType(src) {
|
|
31
|
-
if (!src) return null;
|
|
32
|
-
|
|
33
|
-
const url = src.toLowerCase();
|
|
34
|
-
if (url.includes('.mpd') || url.includes('dash')) {
|
|
35
|
-
return 'dash';
|
|
36
|
-
} else if (url.includes('.m3u8') || url.includes('hls')) {
|
|
37
|
-
return 'hls';
|
|
38
|
-
}
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async initializeAdaptiveStreaming(src) {
|
|
43
|
-
if (!this.options.adaptiveStreaming) return false;
|
|
44
|
-
|
|
45
|
-
this.adaptiveStreamingType = this.detectStreamType(src);
|
|
46
|
-
|
|
47
|
-
if (!this.adaptiveStreamingType) {
|
|
48
|
-
if (this.options.debug) console.log('📡 No adaptive streaming detected');
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Load libraries first
|
|
53
|
-
const librariesLoaded = await this.loadAdaptiveLibraries();
|
|
54
|
-
if (!librariesLoaded) {
|
|
55
|
-
if (this.options.debug) console.error('📡 Failed to load adaptive libraries');
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
if (this.adaptiveStreamingType === 'dash') {
|
|
61
|
-
return await this.initializeDash(src);
|
|
62
|
-
} else if (this.adaptiveStreamingType === 'hls') {
|
|
63
|
-
return await this.initializeHls(src);
|
|
64
|
-
}
|
|
65
|
-
} catch (error) {
|
|
66
|
-
if (this.options.debug) console.error('📡 Adaptive streaming initialization failed:', error);
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async initializeDash(src) {
|
|
74
|
-
if (!window.dashjs) {
|
|
75
|
-
if (this.options.debug) console.error('📡 Dash.js not available');
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
// Destroy existing DASH player
|
|
81
|
-
if (this.dashPlayer) {
|
|
82
|
-
this.dashPlayer.destroy();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Create new DASH player
|
|
86
|
-
this.dashPlayer = window.dashjs.MediaPlayer().create();
|
|
87
|
-
|
|
88
|
-
// Configure DASH settings
|
|
89
|
-
this.dashPlayer.updateSettings({
|
|
90
|
-
streaming: {
|
|
91
|
-
abr: {
|
|
92
|
-
autoSwitchBitrate: {
|
|
93
|
-
video: this.selectedQuality === 'auto'
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
text: {
|
|
97
|
-
defaultEnabled: false // Always disable by default
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
debug: {
|
|
101
|
-
logLevel: this.options.debug ? window.dashjs.Debug.LOG_LEVEL_DEBUG : window.dashjs.Debug.LOG_LEVEL_ERROR
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// Set up event listeners
|
|
106
|
-
this.dashPlayer.on(window.dashjs.MediaPlayer.events.STREAM_INITIALIZED, () => {
|
|
107
|
-
if (this.options.debug) console.log('📡 DASH stream initialized');
|
|
108
|
-
|
|
109
|
-
// Disable text tracks unconditionally unless debug is enabled
|
|
110
|
-
this.disableDashTextTracks();
|
|
111
|
-
|
|
112
|
-
this.updateAdaptiveQualities();
|
|
113
|
-
this.isAdaptiveStream = true;
|
|
114
|
-
this.hideLoading();
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
this.dashPlayer.on(window.dashjs.MediaPlayer.events.TEXT_TRACKS_ADDED, (e) => {
|
|
118
|
-
if (this.options.debug) {
|
|
119
|
-
console.log('📡 DASH text tracks added:', e);
|
|
120
|
-
// Enable text tracks only in debug mode
|
|
121
|
-
if (e.tracks && e.tracks.length > 0) {
|
|
122
|
-
this.dashPlayer.setTextTrack(0);
|
|
123
|
-
}
|
|
124
|
-
} else {
|
|
125
|
-
// Disable all text tracks if not in debug mode
|
|
126
|
-
this.disableDashTextTracks();
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
this.dashPlayer.on(window.dashjs.MediaPlayer.events.QUALITY_CHANGE_RENDERED, (e) => {
|
|
131
|
-
if (this.options.debug) console.log('📡 DASH quality changed:', e.newQuality);
|
|
132
|
-
this.updateAdaptiveQualityDisplay();
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
// Initialize player
|
|
136
|
-
this.dashPlayer.initialize(this.video, src, this.options.autoplay);
|
|
137
|
-
|
|
138
|
-
// Ensure text tracks remain disabled after initialization
|
|
139
|
-
setTimeout(() => {
|
|
140
|
-
this.disableDashTextTracks();
|
|
141
|
-
}, 500);
|
|
142
|
-
|
|
143
|
-
if (this.options.debug) console.log('📡 DASH player initialized with:', src);
|
|
144
|
-
return true;
|
|
145
|
-
|
|
146
|
-
} catch (error) {
|
|
147
|
-
if (this.options.debug) console.error('📡 DASH initialization error:', error);
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Helper method to disable DASH text tracks
|
|
153
|
-
disableDashTextTracks() {
|
|
154
|
-
if (!this.dashPlayer) return;
|
|
155
|
-
|
|
156
|
-
try {
|
|
157
|
-
// Disable text rendering completely unless debug is enabled
|
|
158
|
-
if (!this.options.debug) {
|
|
159
|
-
this.dashPlayer.enableText(false);
|
|
160
|
-
this.dashPlayer.setTextTrack(-1);
|
|
161
|
-
|
|
162
|
-
// Also disable native video text tracks
|
|
163
|
-
if (this.video && this.video.textTracks) {
|
|
164
|
-
for (let i = 0; i < this.video.textTracks.length; i++) {
|
|
165
|
-
this.video.textTracks[i].mode = 'disabled';
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
} else {
|
|
169
|
-
// Enable text tracks only in debug mode
|
|
170
|
-
this.dashPlayer.enableText(true);
|
|
171
|
-
}
|
|
172
|
-
} catch (error) {
|
|
173
|
-
if (this.options.debug) console.error('📡 Error disabling text tracks:', error);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
async initializeHls(src) {
|
|
178
|
-
if (!window.Hls) {
|
|
179
|
-
if (this.options.debug) console.error('📡 HLS.js not available');
|
|
180
|
-
return false;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Check if HLS is supported
|
|
184
|
-
if (!window.Hls.isSupported()) {
|
|
185
|
-
// Fallback to native HLS (Safari)
|
|
186
|
-
if (this.video.canPlayType('application/vnd.apple.mpegurl')) {
|
|
187
|
-
this.video.src = src;
|
|
188
|
-
this.isAdaptiveStream = true;
|
|
189
|
-
if (this.options.debug) console.log('📡 Using native HLS support');
|
|
190
|
-
return true;
|
|
191
|
-
} else {
|
|
192
|
-
if (this.options.debug) console.error('📡 HLS not supported');
|
|
193
|
-
return false;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
try {
|
|
198
|
-
// Destroy existing HLS player
|
|
199
|
-
if (this.hlsPlayer) {
|
|
200
|
-
this.hlsPlayer.destroy();
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Create new HLS player
|
|
204
|
-
this.hlsPlayer = new window.Hls({
|
|
205
|
-
debug: this.options.debug,
|
|
206
|
-
enableWorker: true,
|
|
207
|
-
lowLatencyMode: true,
|
|
208
|
-
backBufferLength: 90
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
// Set up event listeners
|
|
212
|
-
this.hlsPlayer.on(window.Hls.Events.MANIFEST_PARSED, () => {
|
|
213
|
-
if (this.options.debug) console.log('📡 HLS manifest parsed');
|
|
214
|
-
this.updateAdaptiveQualities();
|
|
215
|
-
this.isAdaptiveStream = true;
|
|
216
|
-
this.hideLoading();
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
this.hlsPlayer.on(window.Hls.Events.LEVEL_SWITCHED, (event, data) => {
|
|
220
|
-
if (this.options.debug) console.log('📡 HLS level switched:', data.level);
|
|
221
|
-
this.updateAdaptiveQualityDisplay();
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
this.hlsPlayer.on(window.Hls.Events.ERROR, (event, data) => {
|
|
225
|
-
if (this.options.debug) console.error('📡 HLS error:', data);
|
|
226
|
-
if (data.fatal) {
|
|
227
|
-
this.handleAdaptiveError(data);
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
// Load source
|
|
232
|
-
this.hlsPlayer.loadSource(src);
|
|
233
|
-
this.hlsPlayer.attachMedia(this.video);
|
|
234
|
-
|
|
235
|
-
if (this.options.debug) console.log('📡 HLS player initialized with:', src);
|
|
236
|
-
return true;
|
|
237
|
-
|
|
238
|
-
} catch (error) {
|
|
239
|
-
if (this.options.debug) console.error('📡 HLS initialization error:', error);
|
|
240
|
-
return false;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
updateAdaptiveQualities() {
|
|
245
|
-
this.adaptiveQualities = [];
|
|
246
|
-
|
|
247
|
-
if (this.adaptiveStreamingType === 'dash' && this.dashPlayer) {
|
|
248
|
-
const bitrates = this.dashPlayer.getBitrateInfoListFor('video');
|
|
249
|
-
this.adaptiveQualities = bitrates.map((bitrate, index) => ({
|
|
250
|
-
index: index,
|
|
251
|
-
label: this.getQualityLabel(bitrate.height, bitrate.width),
|
|
252
|
-
height: bitrate.height,
|
|
253
|
-
bandwidth: bitrate.bandwidth
|
|
254
|
-
}));
|
|
255
|
-
} else if (this.adaptiveStreamingType === 'hls' && this.hlsPlayer) {
|
|
256
|
-
const levels = this.hlsPlayer.levels;
|
|
257
|
-
this.adaptiveQualities = levels.map((level, index) => ({
|
|
258
|
-
index: index,
|
|
259
|
-
label: this.getQualityLabel(level.height, level.width),
|
|
260
|
-
height: level.height,
|
|
261
|
-
bandwidth: level.bitrate
|
|
262
|
-
}));
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (this.options.adaptiveQualityControl) {
|
|
266
|
-
this.updateAdaptiveQualityMenu();
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (this.options.debug) {
|
|
270
|
-
console.log('📡 Adaptive qualities available:', this.adaptiveQualities);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
handleAdaptiveError(data) {
|
|
275
|
-
if (this.options.debug) console.error('📡 Fatal adaptive streaming error:', data);
|
|
276
|
-
|
|
277
|
-
// Try to recover
|
|
278
|
-
if (this.adaptiveStreamingType === 'hls' && this.hlsPlayer) {
|
|
279
|
-
try {
|
|
280
|
-
this.hlsPlayer.startLoad();
|
|
281
|
-
} catch (error) {
|
|
282
|
-
if (this.options.debug) console.error('📡 Failed to recover from HLS error:', error);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
destroyAdaptivePlayer() {
|
|
288
|
-
try {
|
|
289
|
-
if (this.dashPlayer) {
|
|
290
|
-
this.dashPlayer.destroy();
|
|
291
|
-
this.dashPlayer = null;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (this.hlsPlayer) {
|
|
295
|
-
this.hlsPlayer.destroy();
|
|
296
|
-
this.hlsPlayer = null;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
this.isAdaptiveStream = false;
|
|
300
|
-
this.adaptiveStreamingType = null;
|
|
301
|
-
this.adaptiveQualities = [];
|
|
302
|
-
|
|
303
|
-
if (this.options.debug) console.log('📡 Adaptive player destroyed');
|
|
304
|
-
|
|
305
|
-
} catch (error) {
|
|
306
|
-
if (this.options.debug) console.error('📡 Error destroying adaptive player:', error);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
getAdaptiveStreamingInfo() {
|
|
311
|
-
return {
|
|
312
|
-
isActive: this.isAdaptiveStream,
|
|
313
|
-
type: this.adaptiveStreamingType,
|
|
314
|
-
currentQuality: this.getCurrentAdaptiveQuality(),
|
|
315
|
-
currentQualityLabel: this.getCurrentAdaptiveQualityLabel(),
|
|
316
|
-
availableQualities: this.adaptiveQualities,
|
|
317
|
-
isAuto: this.isAutoQuality()
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
setAdaptiveStreamingOptions(options = {}) {
|
|
322
|
-
if (options.enabled !== undefined) {
|
|
323
|
-
this.options.adaptiveStreaming = options.enabled;
|
|
324
|
-
}
|
|
325
|
-
if (options.qualityControl !== undefined) {
|
|
326
|
-
this.options.adaptiveQualityControl = options.qualityControl;
|
|
327
|
-
}
|
|
328
|
-
if (options.dashLibUrl) {
|
|
329
|
-
this.options.dashLibUrl = options.dashLibUrl;
|
|
330
|
-
}
|
|
331
|
-
if (options.hlsLibUrl) {
|
|
332
|
-
this.options.hlsLibUrl = options.hlsLibUrl;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
if (this.options.debug) {
|
|
336
|
-
console.log('📡 Adaptive streaming options updated:', {
|
|
337
|
-
enabled: this.options.adaptiveStreaming,
|
|
338
|
-
qualityControl: this.options.adaptiveQualityControl
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
return this;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Streaming methods for main class
|
|
346
|
-
// All original functionality preserved exactly
|