myetv-player 1.7.1 → 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 CHANGED
@@ -66,27 +66,30 @@ A modern and complete HTML5 + JavaScript + css video player with custom controls
66
66
 
67
67
  ### Include Required Files
68
68
 
69
- ```
70
- <!-- Player CSS -->
69
+ ```html
71
70
  <link rel="stylesheet" href="css/myetv-player.min.css">
72
- <!-- Player JavaScript -->
73
71
  <script src="dist/myetv-player.min.js"></script>
72
+
73
+
74
74
  ```
75
75
 
76
76
  ## Basic Usage
77
77
 
78
78
  ### HTML
79
79
 
80
- ```
80
+ ```html
81
81
  <video id="my-video" width="800" height="450">
82
82
  <source src="video-480p.mp4" type="video/mp4" data-quality="480p">
83
83
  <source src="video-720p.mp4" type="video/mp4" data-quality="720p">
84
84
  <source src="video-1080p.mp4" type="video/mp4" data-quality="1080p">
85
- <!-- Optional subtitles -->
86
85
  <track kind="subtitles" src="subtitles-en.vtt" srclang="en" label="English">
87
86
  <track kind="subtitles" src="subtitles-it.vtt" srclang="it" label="Italiano">
88
87
  </video>
89
88
 
89
+
90
+ ```
91
+
92
+ ```javascript
90
93
  // Basic initialization
91
94
  const player = new MYETVvideoplayer('my-video');
92
95
 
@@ -97,14 +100,17 @@ const player = new MYETVvideoplayer('my-video', {
97
100
  showTitleOverlay: true,
98
101
  videoTitle: 'My Video',
99
102
  language: 'en',
103
+ subtitlesEnabled: true,
100
104
  debug: false
101
105
  });
106
+
107
+
102
108
  ```
103
109
 
104
110
  ## Initialization Options
105
111
 
106
112
  | Option | Type | Default | Description |
107
- |--------|------|---------|-------------|
113
+ | --- | --- | --- | --- |
108
114
  | `poster` | string | `''` | URL of a cover image (optional) |
109
115
  | `showPosterOnEnd` | boolean | `false` | Show the cover image when the video ends |
110
116
  | `playFromStartButton` | boolean | `false` | Show/hide play from start button (restart video) |
@@ -114,20 +120,21 @@ const player = new MYETVvideoplayer('my-video', {
114
120
  | `showPictureInPicture` | boolean | `true` | Show Picture-in-Picture button |
115
121
  | `showSubtitles` | boolean | `true` | Show subtitles controls (the button) - it is automatically true only if subtitles track are detected |
116
122
  | `subtitlesEnabled` | boolean | `false` | Enable/Disable subtitles at player ready |
123
+ | `externalSubtitleTracks` | array | `[]` | Array of objects to load external WebVTT or SRT subtitle tracks dynamically (supports src, lang, label, and default properties) |
117
124
  | `showSettingsMenu` | boolean | `true` | Show/Hide the settings menu in the top-bar |
118
- | `moreinfoTitle` | string | `''` | Title for the modal window (if present, the button "more information" in the settings menu will be visible)
119
- | `moreinfoDescription` | string | `''` | Description for the modal window (if present, the button "more information" in the settings menu will be visible)
125
+ | `moreinfoTitle` | string | `''` | Title for the modal window (if present, the button "more information" in the settings menu will be visible) |
126
+ | `moreinfoDescription` | string | `''` | Description for the modal window (if present, the button "more information" in the settings menu will be visible) |
120
127
  | `chapters` | string | json | Enable/Disable chapters: chapter can be in json format or string format (see below) |
121
128
  | `plugins` | string | json | Add a customized plugin to the player to extend its functionality (see below) |
122
129
  | `seekHandleShape` | string | `true` | Edit the shape of the seek controlbar. Shape type: none, circle, square, diamond, arrow, triangle, heart, star |
123
130
  | `showSeekTooltip` | boolean | `true` | Show tooltip during seek |
124
131
  | `volumeSlider` | string | `show` | Volume slider 'show' or 'hide': with "show" the volume slider is always visible and have the automatic fallback to "hide" under 550px of width; with "hide" the volume slider is visible only at mouse over |
125
132
  | `autoplay` | boolean | `false` | Start video automatically |
126
- | `loop` | boolean | `false` | Optional if the video should loop
133
+ | `loop` | boolean | `false` | Optional if the video should loop |
127
134
  | `resolution` | string | `normal` | resolution type: "normal" same resolution of the native video; "4:3"; "16:9"; "stretched" the video will be stretched in all the container; "fit-to-screen" the video will fit the screen but can be cutted; "scale-to-fit" fit the screen but preserve aspect ration and not cut |
128
135
  | `autoHide` | boolean | `true` | Auto-hide controls |
129
136
  | `autoHideDelay` | number | `3000` | Auto-hide delay in milliseconds |
130
- | `hideCursor ` | boolean | `true` | Auto-hide the mouse cursor with the controlbar |
137
+ | `hideCursor` | boolean | `true` | Auto-hide the mouse cursor with the controlbar |
131
138
  | `pauseClick` | boolean | `true` | Enable or disable the click on the video to pause/resume |
132
139
  | `doubleTapPause` | boolean | `true` | First touch shows controls, second touch pauses (usefull on touch devices) |
133
140
  | `keyboardControls` | boolean | `true` | Enable keyboard controls |
@@ -141,51 +148,60 @@ const player = new MYETVvideoplayer('my-video', {
141
148
  | `language` | string | `en` | Interface language code |
142
149
  | `brandLogoEnabled` | boolean | `false` | Show/hide the brand logo in the controlbar |
143
150
  | `brandLogoUrl` | string | `''` | Brand logo url in the controlbar (png, jpg, gif) - image height 44px - image width 120px |
144
- | `brandLogoLinkUrl` | string | `''` | Optional URL to open in a new page when clicking the brand logo in the controlbar
145
- | `brandLogoTooltipText` | string | `''` | Optional Custom tooltip of the brand logo (the default is the url of the brand logo, if present)
146
- | `loadingLogo` | string | `''` | Optional Custom image logo url to show it inside the loading spinner
147
- | `watermarkUrl` | string | `''` | Optional URL of the image watermark over the video, reccomended dimension: width: 180px, height: 100px
148
- | `watermarkLink` | string | `''` | Optional URL to open in a new page when clicking the watermark logo in the video
149
- | `watermarkPosition` | string | `''` | Optional where to show the watermark logo in the video (values are: top-left, top-right, bottom-left, bottom-right)
150
- | `watermarkTitle` | string | `''` | Optional title to show when the mouse is over the watermark logo in the video
151
- | `hideWatermark` | boolean | `true` | Optional hide watermark logo with the controlbar or show the watermark logo always visible
152
- | `playlistEnabled` | boolean | `false` | Optional if the playlist of video is enabled (html structured)
153
- | `playlistAutoPlay` | boolean | `false` | Optional if the playlist should autoplay
154
- | `playlistLoop` | boolean | `false` | Optional if the playlist should loop
155
- | `adaptiveStreaming` | boolean | `false` | Enable HLS/DASH adaptive streaming
156
- | `adaptiveQualityControl` | boolean | `false` | Enable the menu quality with adaptive streaming
151
+ | `brandLogoLinkUrl` | string | `''` | Optional URL to open in a new page when clicking the brand logo in the controlbar |
152
+ | `brandLogoTooltipText` | string | `''` | Optional Custom tooltip of the brand logo (the default is the url of the brand logo, if present) |
153
+ | `loadingLogo` | string | `''` | Optional Custom image logo url to show it inside the loading spinner |
154
+ | `watermarkUrl` | string | `''` | Optional URL of the image watermark over the video, reccomended dimension: width: 180px, height: 100px |
155
+ | `watermarkLink` | string | `''` | Optional URL to open in a new page when clicking the watermark logo in the video |
156
+ | `watermarkPosition` | string | `''` | Optional where to show the watermark logo in the video (values are: top-left, top-right, bottom-left, bottom-right) |
157
+ | `watermarkTitle` | string | `''` | Optional title to show when the mouse is over the watermark logo in the video |
158
+ | `hideWatermark` | boolean | `true` | Optional hide watermark logo with the controlbar or show the watermark logo always visible |
159
+ | `playlistEnabled` | boolean | `false` | Optional if the playlist of video is enabled (html structured) |
160
+ | `playlistAutoPlay` | boolean | `false` | Optional if the playlist should autoplay |
161
+ | `playlistLoop` | boolean | `false` | Optional if the playlist should loop |
162
+ | `adaptiveStreaming` | boolean | `false` | Enable HLS/DASH adaptive streaming |
163
+ | `adaptiveQualityControl` | boolean | `false` | Enable the menu quality with adaptive streaming |
157
164
  | `audiofile` | boolean | `false` | Optional if the file is only audio (no video) |
158
165
  | `audiowave` | boolean | `false` | Optional if the file is only audio, show the audio wave as video (with the browser Web Audio API) |
159
166
  | `debug` | boolean | `false` | Enable debug logs |
160
167
 
161
-
162
168
  ## API Methods
169
+
163
170
  ### Basic Controls
164
- ```
171
+
172
+ ```javascript
165
173
  // Playback
166
174
  player.play(); // Start playback
167
175
  player.pause(); // Pause playback
168
176
  player.togglePlayPause(); // Toggle play/pause
169
177
 
170
178
  // Volume
171
- player.setVolume(0.8); // Set volume (0-1)
172
- player.getVolume(); // Get current volume
173
- player.toggleMute(); // Toggle mute
174
- player.setMuted(true); // Set mute
179
+ player.setVolume(0.8); // Set volume (0-1)
180
+ player.getVolume(); // Get current volume
181
+ player.toggleMute(); // Toggle mute
182
+ player.setMuted(true); // Set mute
183
+
184
+
175
185
  ```
186
+
176
187
  ### Time Controls
177
- ```
188
+
189
+ ```javascript
178
190
  // Position
179
- player.setCurrentTime(120); // Go to second 120
180
- player.getCurrentTime(); // Current position
181
- player.getDuration(); // Total duration
182
- player.skipTime(10); // Skip 10 seconds forward
183
- player.skipTime(-10); // Skip 10 seconds backward
191
+ player.setCurrentTime(120); // Go to second 120
192
+ player.getCurrentTime(); // Current position
193
+ player.getDuration(); // Total duration
194
+ player.skipTime(10); // Skip 10 seconds forward
195
+ player.skipTime(-10); // Skip 10 seconds backward
196
+
197
+
184
198
  ```
199
+
185
200
  ### Poster Image (cover image)
186
- ```
201
+
202
+ ```javascript
187
203
  // Set poster after initialization
188
- player.setPoster('https://example.com/poster.jpg');
204
+ player.setPoster('[https://example.com/poster.jpg](https://example.com/poster.jpg)');
189
205
 
190
206
  // Get current poster
191
207
  const currentPoster = player.getPoster();
@@ -201,26 +217,57 @@ player.togglePoster(false); // Hide
201
217
  if (player.isPosterVisible()) {
202
218
  console.log('Poster is visible');
203
219
  }
220
+
221
+
204
222
  ```
223
+
205
224
  ### Quality Controls
206
- ```
225
+
226
+ ```javascript
207
227
  // Video quality
208
- player.setDefaultQuality('720p'); // Set default quality
209
- player.setQuality('1080p'); // Change quality
210
- player.getSelectedQuality(); // Selected quality
228
+ player.setDefaultQuality('720p'); // Set default quality
229
+ player.setQuality('1080p'); // Change quality
230
+ player.getSelectedQuality(); // Selected quality
211
231
  player.getCurrentPlayingQuality(); // Actual playing quality
212
- player.enableAutoQuality(); // Enable automatic selection
232
+ player.enableAutoQuality(); // Enable automatic selection
233
+
234
+
213
235
  ```
236
+
214
237
  ### Subtitles Controls
215
- ```
238
+
239
+ ```javascript
216
240
  // Subtitles
217
- player.toggleSubtitles(); // Toggle subtitles
218
- player.enableSubtitleTrack(0); // Enable subtitle track
219
- player.disableSubtitles(); // Disable subtitles
220
- player.getAvailableSubtitles(); // List available subtitles
241
+ player.toggleSubtitles(); // Toggle subtitles
242
+ player.enableSubtitleTrack(0); // Enable subtitle track
243
+ player.disableSubtitles(); // Disable subtitles
244
+ player.getAvailableSubtitles(); // List available subtitles
245
+
246
+ // Initialize with external subtitle tracks (JSON array of WebVTT/SRT)
247
+ const playerWithSubs = new MYETVvideoplayer('my-video', {
248
+ subtitlesEnabled: true,
249
+ showSubtitles: true,
250
+ externalSubtitleTracks: [
251
+ {
252
+ src: '[https://example.com/subtitles/en.vtt](https://example.com/subtitles/en.vtt)', // WebVTT format
253
+ lang: 'en',
254
+ label: 'English (Server)',
255
+ default: true
256
+ },
257
+ {
258
+ src: '[https://example.com/subtitles/it.srt](https://example.com/subtitles/it.srt)', // SRT format
259
+ lang: 'it',
260
+ label: 'Italiano (Server)',
261
+ default: false
262
+ }
263
+ ]
264
+ });
265
+
221
266
  ```
267
+
222
268
  ### Chapters Controls
223
- ```
269
+
270
+ ```javascript
224
271
  // Get current chapter
225
272
  const current = player.getCurrentChapter();
226
273
 
@@ -237,29 +284,43 @@ player.setChapters([...]);
237
284
 
238
285
  // Clear chapters
239
286
  player.clearChapters();
287
+
288
+
240
289
  ```
290
+
241
291
  ### Plugins Controls
292
+
242
293
  [Plugins Help: https://github.com/OskarCosimo/myetv-video-player-opensource/blob/main/plugins/README.md](https://github.com/OskarCosimo/myetv-video-player-opensource/blob/main/plugins/README.md)
294
+
243
295
  ### Screen Controls
244
- ```
296
+
297
+ ```javascript
245
298
  // Fullscreen and Picture-in-Picture
246
- player.toggleFullscreen(); // Toggle fullscreen
247
- player.enterFullscreen(); // Enter fullscreen
248
- player.exitFullscreen(); // Exit fullscreen
249
- player.togglePictureInPicture(); // Toggle Picture-in-Picture
299
+ player.toggleFullscreen(); // Toggle fullscreen
300
+ player.enterFullscreen(); // Enter fullscreen
301
+ player.exitFullscreen(); // Exit fullscreen
302
+ player.togglePictureInPicture(); // Toggle Picture-in-Picture
303
+
304
+
250
305
  ```
306
+
251
307
  ### Brand Logo Controls
252
- ```
308
+
309
+ ```javascript
253
310
  // Brand Logo in controlbar
254
311
  player.setBrandLogo(enabled, url, linkUrl) //change brand logo dynamically
255
312
  player.getBrandLogoSettings() //get current brand logo settings
313
+
314
+
256
315
  ```
316
+
257
317
  ### Watermark Logo Controls
258
- ```
318
+
319
+ ```javascript
259
320
  // Change watermark dynamically
260
321
  player.setWatermark(
261
- 'https://example.com/new-logo.png',
262
- 'https://example.com/promo',
322
+ '[https://example.com/new-logo.png](https://example.com/new-logo.png)',
323
+ '[https://example.com/promo](https://example.com/promo)',
263
324
  'topleft',
264
325
  'Special promotion'
265
326
  );
@@ -276,9 +337,13 @@ player.removeWatermark();
276
337
 
277
338
  //hide with the controlbar or always show the watermark logo
278
339
  player.setWatermarkAutoHide(false);
340
+
341
+
279
342
  ```
343
+
280
344
  ### Controlbar seek shape
281
- ```
345
+
346
+ ```javascript
282
347
  // Change dynamically
283
348
  player.setSeekHandleShape('heart');
284
349
 
@@ -288,9 +353,13 @@ console.log(player.getSeekHandleShape()); // "heart"
288
353
  // Show all available shape
289
354
  console.log(player.getAvailableSeekHandleShapes());
290
355
  // ["none", "circle", "square", "diamond", "arrow", "triangle", "heart", "star"]
356
+
357
+
291
358
  ```
359
+
292
360
  ### Auto-hide mouse cursor (works only when autohide controlbar is true)
293
- ```
361
+
362
+ ```javascript
294
363
  // Disable auto-hide mouse
295
364
  player.disableCursorHiding();
296
365
 
@@ -301,118 +370,178 @@ player.enableCursorHiding();
301
370
  if (player.isCursorHidingEnabled()) {
302
371
  console.log('Cursor hiding is active');
303
372
  }
373
+
374
+
304
375
  ```
376
+
305
377
  ### Playlist Controls
306
- ```
378
+
379
+ ```javascript
307
380
  player.nextVideo(); // Next Video
308
381
  player.prevVideo(); // Previous Video
309
- player.goToPlaylistIndex(2); // Go to the specific video
382
+ player.goToPlaylistIndex(2); // Go to the specific video
310
383
  player.getPlaylistInfo(); // Info Playlist
311
384
  player.setPlaylistOptions({loop:true}); // Playlist Options
385
+
386
+
312
387
  ```
388
+
313
389
  ### Resolution Controls
314
- ```
390
+
391
+ ```javascript
315
392
  player.setResolution("4:3"); // Change to 4:3
316
393
  player.setResolution("16:9"); // Change to 16:9
317
394
  player.setResolution("stretched"); // Change to stretched: Stretch the video to the entire container
318
395
  player.setResolution("fit-to-screen"); // Change to fit to screen: It fits the screen, can cut parts of the video
319
396
  player.setResolution("scale-to-fit"); // Intelligently fit to screen without cut video parts
320
397
  console.log(player.getCurrentResolution()); // Get current resolution
398
+
399
+
321
400
  ```
401
+
322
402
  ## API Events
403
+
323
404
  The MYETV Video Player includes a comprehensive custom event system that allows you to monitor all player state changes in real-time.
405
+
324
406
  ### on player ready
407
+
325
408
  Description: Triggered when the video player is ready
326
409
 
327
410
  When: Player is ready to receive other events
328
- ```
411
+
412
+ ```javascript
329
413
  player.addEventListener('playerready', (event) => {
330
414
  console.log('Player is ready!', event);
331
415
  //now it's secure to call other apis method
332
416
  player.setVolume(0.8);
333
417
  player.play();
334
418
  });
419
+
420
+
335
421
  ```
422
+
336
423
  ### on played
424
+
337
425
  Description: Triggered when the video starts playing
338
426
 
339
427
  When: User presses play or video starts automatically
340
- ```
428
+
429
+ ```javascript
341
430
  player.addEventListener('played', (event) => {
342
431
  console.log('Video started!', {
343
432
  currentTime: event.currentTime,
344
433
  duration: event.duration
345
434
  });
346
435
  });
436
+
437
+
347
438
  ```
439
+
348
440
  ### on playing
441
+
349
442
  Description: Triggered when the video is playing
350
443
 
351
444
  When: Video is effectively playing
352
- ```
445
+
446
+ ```javascript
353
447
  player.addEventListener('playing', (event) => {
354
448
  console.log('Video is playing at', event.currentTime);
355
449
  });
450
+
451
+
356
452
  ```
453
+
357
454
  ### on paused
455
+
358
456
  Description: Triggered when the video is pause
359
457
 
360
458
  When: User presses pause or video stops
361
- ```
459
+
460
+ ```javascript
362
461
  player.addEventListener('paused', (event) => {
363
462
  console.log('Video paused at:', event.currentTime + 's');
364
463
  });
464
+
465
+
365
466
  ```
467
+
366
468
  ### on waiting
469
+
367
470
  Description: Triggered when the video is buffering
368
471
 
369
472
  When: Video is buffering and is waiting
370
- ```
473
+
474
+ ```javascript
371
475
  player.addEventListener('waiting', (event) => {
372
476
  console.log('Video is buffering...');
373
477
  });
478
+
479
+
374
480
  ```
481
+
375
482
  ### on seeking
483
+
376
484
  Description: Triggered when the video is being seeking
377
485
 
378
486
  When: The user is seeking over the video
379
- ```
487
+
488
+ ```javascript
380
489
  player.addEventListener('seeking', (event) => {
381
490
  console.log('User is seeking to', event.targetTime);
382
491
  });
492
+
493
+
383
494
  ```
495
+
384
496
  ### on seeked
497
+
385
498
  Description: Triggered when the video is finished seeked
386
499
 
387
500
  When: The user have finished seeking and seeked the video
388
- ```
501
+
502
+ ```javascript
389
503
  player.addEventListener('seeked', (event) => {
390
504
  console.log('Seek completed at', event.currentTime);
391
505
  });
506
+
507
+
392
508
  ```
509
+
393
510
  ### on ended
511
+
394
512
  Description: Triggered when the video is ended
395
513
 
396
514
  When: Video is ended
397
- ```
515
+
516
+ ```javascript
398
517
  player.addEventListener('ended', (e) => {
399
518
  console.log('Video terminato!', e.currentTime, e.duration, e.playlistInfo);
400
519
  });
520
+
521
+
401
522
  ```
523
+
402
524
  ### on error
525
+
403
526
  Description: Triggered when the video have some error
404
527
 
405
528
  When: Video have some error on load
406
- ```
529
+
530
+ ```javascript
407
531
  player.addEventListener('error', (event) => {
408
532
  console.error('Playback error:', event.message);
409
533
  });
534
+
535
+
410
536
  ```
537
+
411
538
  ### on subtitle change
539
+
412
540
  Description: Triggered when subtitles are enabled/disabled or track changes
413
541
 
414
542
  When: User toggles subtitles or switches subtitle tracks
415
- ```
543
+
544
+ ```javascript
416
545
  player.addEventListener('subtitlechange', (event) => {
417
546
  if (event.enabled) {
418
547
  console.log('Subtitles enabled:', event.trackLabel);
@@ -420,59 +549,89 @@ player.addEventListener('subtitlechange', (event) => {
420
549
  console.log('Subtitles disabled');
421
550
  }
422
551
  });
552
+
553
+
423
554
  ```
555
+
424
556
  ### on chapters change
557
+
425
558
  Description: Triggered when chapters are changes
426
559
 
427
560
  When: User switches chapters tracks
428
- ```
561
+
562
+ ```javascript
429
563
  player.on('chapterchange', (data) => {
430
564
  console.log('Chapter changed:', data.chapter.title);
431
565
  });
566
+
567
+
432
568
  ```
569
+
433
570
  ### on pip change
571
+
434
572
  Description: Triggered when Picture-in-Picture mode changes
435
573
 
436
574
  When: Video enters or exits PiP mode
437
- ```
575
+
576
+ ```javascript
438
577
  player.addEventListener('pipchange', (event) => {
439
578
  console.log('Picture-in-Picture:', event.active ? 'Activated' : 'Deactivated');
440
579
  });
580
+
581
+
441
582
  ```
583
+
442
584
  ### on fullscreen change
585
+
443
586
  Description: Triggered when fullscreen mode changes
444
587
 
445
588
  When: Player enters or exits fullscreen mode
446
- ```
589
+
590
+ ```javascript
447
591
  player.addEventListener('fullscreenchange', (event) => {
448
592
  console.log('Fullscreen:', event.active ? 'Activated' : 'Deactivated');
449
593
  });
594
+
595
+
450
596
  ```
597
+
451
598
  ### on speed change
599
+
452
600
  Description: Triggered when playback speed changes
453
601
 
454
602
  When: User modifies playback speed (0.5x, 1x, 1.5x, 2x, etc.)
455
- ```
603
+
604
+ ```javascript
456
605
  player.addEventListener('speedchange', (event) => {
457
606
  console.log('Speed changed to:', event.speed + 'x');
458
607
  });
608
+
609
+
459
610
  ```
611
+
460
612
  ### on time update
613
+
461
614
  Description: Triggered during playback to update progress
462
615
 
463
616
  When: Every 250ms during playback (throttled for performance)
464
- ```
617
+
618
+ ```javascript
465
619
  player.addEventListener('timeupdate', (event) => {
466
620
  console.log('Progress:', event.progress.toFixed(1) + '%');
467
621
  // Update custom progress bar
468
622
  updateProgressBar(event.progress);
469
623
  });
624
+
625
+
470
626
  ```
627
+
471
628
  ### on volumechange
629
+
472
630
  Description: Triggered when volume or mute state changes
473
631
 
474
632
  When: User modifies volume or toggles mute
475
- ```
633
+
634
+ ```javascript
476
635
  player.addEventListener('volumechange', (event) => {
477
636
  if (event.muted) {
478
637
  console.log('Audio muted');
@@ -480,18 +639,27 @@ player.addEventListener('volumechange', (event) => {
480
639
  console.log('Volume:', Math.round(event.volume * 100) + '%');
481
640
  }
482
641
  });
642
+
643
+
483
644
  ```
645
+
484
646
  ### Playlist API
485
- ```
647
+
648
+ ```javascript
486
649
  player.addEventListener('playlistchange', (e) => {
487
650
  console.log(`From "${e.fromTitle}" to "${e.toTitle}"`);
488
651
  });
652
+
653
+
489
654
  ```
655
+
490
656
  ### Main APIs
657
+
491
658
  getEventData()
492
659
 
493
660
  Returns all requested state data in a single object:
494
- ```
661
+
662
+ ```javascript
495
663
  const state = player.getEventData();
496
664
  console.log(state);
497
665
  /* Output:
@@ -510,9 +678,13 @@ console.log(state);
510
678
  buffered: 120.5
511
679
  }
512
680
  */
681
+
682
+
513
683
  ```
684
+
514
685
  ### Event Listener Management
515
- ```
686
+
687
+ ```javascript
516
688
  // Add listener
517
689
  player.addEventListener('played', callback);
518
690
 
@@ -527,9 +699,13 @@ const onVideoPlay = (event) => {
527
699
  player.addEventListener('played', onVideoPlay);
528
700
  // ... later
529
701
  player.removeEventListener('played', onVideoPlay);
702
+
703
+
530
704
  ```
705
+
531
706
  ### Complete Example
532
- ```
707
+
708
+ ```javascript
533
709
  // Initialize the player
534
710
  const player = new MYETVvideoplayer('myVideo', {
535
711
  debug: true,
@@ -560,8 +736,12 @@ function updateUI(state, time) {
560
736
  document.getElementById('player-status').textContent =
561
737
  `Status: ${state} at ${time.toFixed(1)}s`;
562
738
  }
739
+
740
+
563
741
  ```
742
+
564
743
  ### Technical Notes
744
+
565
745
  Performance: The timeupdate event is throttled to 250ms to avoid overload
566
746
 
567
747
  Compatibility: All events maintain compatibility with existing code
@@ -573,7 +753,7 @@ Error Handling: Errors in callbacks don't interrupt the player
573
753
  ### Event Data Reference
574
754
 
575
755
  | Property | Type | Description |
576
- |:---------|:----:|:------------|
756
+ | --- | --- | --- |
577
757
  | `played` | `boolean` | Video is currently playing |
578
758
  | `paused` | `boolean` | Video is currently paused |
579
759
  | `subtitleEnabled` | `boolean` | Subtitles are enabled |
@@ -590,7 +770,7 @@ Error Handling: Errors in callbacks don't interrupt the player
590
770
  ## Keyboard Controls
591
771
 
592
772
  | Key | Action |
593
- |-----|--------|
773
+ | --- | --- |
594
774
  | `Space` | Play/Pause |
595
775
  | `M` | Mute/Unmute |
596
776
  | `F` | Fullscreen |
@@ -612,7 +792,8 @@ The MYETV Video Player is fully customizable using CSS variables and themes. The
612
792
  ### CSS Variables
613
793
 
614
794
  The player uses CSS custom properties (variables) for easy theming:
615
- ```
795
+
796
+ ```css
616
797
  .video-wrapper {
617
798
  /* Primary Colors */
618
799
  --player-primary-color: goldenrod;
@@ -643,53 +824,78 @@ The player uses CSS custom properties (variables) for easy theming:
643
824
  --player-transition-fast: 0.2s ease;
644
825
  --player-transition-normal: 0.3s ease;
645
826
  }
827
+
828
+
646
829
  ```
830
+
647
831
  ### Pre-built Themes
648
832
 
649
833
  The player includes several pre-built themes that you can apply:
650
834
 
651
835
  #### Blue Theme
652
- ```
836
+
837
+ ```css
653
838
  .video-wrapper.player-theme-blue {
654
839
  /* Automatically uses blue color scheme */
655
840
  }
841
+
842
+
656
843
  ```
844
+
657
845
  #### Green Theme
658
- ```
846
+
847
+ ```css
659
848
  .video-wrapper.player-theme-green {
660
849
  /* Automatically uses green color scheme */
661
850
  }
851
+
852
+
662
853
  ```
854
+
663
855
  #### Red Theme
664
- ```
856
+
857
+ ```css
665
858
  .video-wrapper.player-theme-red {
666
859
  /* Automatically uses red color scheme */
667
860
  }
668
- ```
861
+
669
862
  #### Dark Theme
670
- ```
863
+
864
+ ```css
671
865
  .video-wrapper.player-theme-dark {
672
866
  /* Enhanced dark mode with improved contrast */
673
867
  }
868
+
869
+
674
870
  ```
871
+
675
872
  ### Control Size Variants
676
873
 
677
874
  #### Large Controls
678
- ```
875
+
876
+ ```css
679
877
  .video-wrapper.player-large-controls {
680
878
  /* Bigger buttons and controls for better accessibility */
681
879
  }
880
+
881
+
682
882
  ```
883
+
683
884
  #### Compact Controls
684
- ```
885
+
886
+ ```css
685
887
  .video-wrapper.player-compact-controls {
686
888
  /* Smaller, space-efficient controls */
687
889
  }
890
+
891
+
688
892
  ```
893
+
689
894
  ### Custom Theme Examples
690
895
 
691
896
  #### Custom Purple Theme
692
- ```
897
+
898
+ ```css
693
899
  .video-wrapper.my-purple-theme {
694
900
  --player-primary-color: #9c27b0;
695
901
  --player-primary-hover: #7b1fa2;
@@ -697,9 +903,13 @@ The player includes several pre-built themes that you can apply:
697
903
  --player-bg-primary: #1a0d1a;
698
904
  --player-bg-controls: linear-gradient(180deg, transparent 0%, rgba(26, 13, 26, 0.9) 100%);
699
905
  }
906
+
907
+
700
908
  ```
909
+
701
910
  #### High Contrast Theme
702
- ```
911
+
912
+ ```css
703
913
  .video-wrapper.high-contrast-theme {
704
914
  --player-primary-color: #ffff00;
705
915
  --player-primary-hover: #ffeb3b;
@@ -708,9 +918,13 @@ The player includes several pre-built themes that you can apply:
708
918
  --player-bg-controls: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.95) 100%);
709
919
  --player-border-radius: 0; /* Sharp corners for accessibility */
710
920
  }
921
+
922
+
711
923
  ```
924
+
712
925
  #### Minimal Theme
713
- ```
926
+
927
+ ```css
714
928
  .video-wrapper.minimal-theme {
715
929
  --player-bg-controls: rgba(0, 0, 0, 0.3);
716
930
  --player-bg-title-overlay: rgba(0, 0, 0, 0.3);
@@ -719,31 +933,39 @@ The player includes several pre-built themes that you can apply:
719
933
  --player-volume-height: 2px;
720
934
  --player-button-padding: 4px;
721
935
  }
936
+
937
+
722
938
  ```
939
+
723
940
  ### Responsive Customization
724
941
 
725
942
  The player automatically adapts to different screen sizes. You can customize the responsive behavior:
726
- ```
727
- /* Custom mobile adjustments /
943
+
944
+ ```css
945
+ /* Custom mobile adjustments */
728
946
  @media (max-width: 768px) {
729
- .video-wrapper {
730
- --player-icon-size: 18px;
731
- --player-progress-height: 8px; / Thicker for touch /
732
- --player-button-padding: 12px; / Larger touch targets */
733
- }
947
+ .video-wrapper {
948
+ --player-icon-size: 18px;
949
+ --player-progress-height: 8px; /* Thicker for touch */
950
+ --player-button-padding: 12px; /* Larger touch targets */
951
+ }
734
952
  }
735
953
 
736
954
  @media (max-width: 480px) {
737
- .video-wrapper {
738
- --player-controls-padding: 12px 8px 8px;
739
- --player-border-radius: 0; /* Full width on small screens */
740
- }
955
+ .video-wrapper {
956
+ --player-controls-padding: 12px 8px 8px;
957
+ --player-border-radius: 0; /* Full width on small screens */
958
+ }
741
959
  }
960
+
961
+
742
962
  ```
963
+
743
964
  ### Custom Subtitle Styling
744
965
 
745
966
  Customize the appearance of subtitles:
746
- ```
967
+
968
+ ```css
747
969
  .video-player::cue {
748
970
  background: rgba(0, 0, 0, 0.9);
749
971
  color: #ffffff;
@@ -759,11 +981,15 @@ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8);
759
981
  background: var(--player-primary-color);
760
982
  color: black;
761
983
  }
984
+
985
+
762
986
  ```
987
+
763
988
  ### Animation Customization
764
989
 
765
990
  Control the player's animations:
766
- ```
991
+
992
+ ```css
767
993
  .video-wrapper {
768
994
  /* Faster animations */
769
995
  --player-transition-fast: 0.1s ease;
@@ -780,11 +1006,15 @@ Control the player's animations:
780
1006
  transition: none !important;
781
1007
  animation: none !important;
782
1008
  }
1009
+
1010
+
783
1011
  ```
1012
+
784
1013
  ### Quality Selector Customization
785
1014
 
786
1015
  The dual-quality indicator can be customized:
787
- ```
1016
+
1017
+ ```css
788
1018
  .quality-btn {
789
1019
  min-height: 40px; /* More space for two lines */
790
1020
  }
@@ -798,11 +1028,15 @@ font-weight: 600;
798
1028
  font-size: 11px; /* Current playing quality */
799
1029
  opacity: 0.7;
800
1030
  }
1031
+
1032
+
801
1033
  ```
1034
+
802
1035
  ### Usage Examples
803
1036
 
804
1037
  #### Apply Theme via JavaScript
805
- ```
1038
+
1039
+ ```javascript
806
1040
  // Apply theme when initializing
807
1041
  const player = new MYETVvideoplayer('video', {
808
1042
  // ... other options
@@ -810,12 +1044,23 @@ const player = new MYETVvideoplayer('video', {
810
1044
 
811
1045
  // Add theme class
812
1046
  document.querySelector('.video-wrapper').classList.add('player-theme-blue');
1047
+
1048
+
813
1049
  ```
1050
+
814
1051
  #### Apply Theme via HTML
815
- ```<div class="video-wrapper player-theme-dark player-large-controls"> <video id="my-video"> <!-- video sources --> </video> </div> ```
816
1052
 
817
- #### Dynamic Theme Switching
1053
+ ```html
1054
+ <div class="video-wrapper player-theme-dark player-large-controls">
1055
+ <video id="my-video"> </video>
1056
+ </div>
1057
+
1058
+
818
1059
  ```
1060
+
1061
+ #### Dynamic Theme Switching
1062
+
1063
+ ```javascript
819
1064
  function switchTheme(themeName) {
820
1065
  const wrapper = document.querySelector('.video-wrapper');
821
1066
 
@@ -832,8 +1077,12 @@ function switchTheme(themeName) {
832
1077
  switchTheme('blue'); // Switch to blue theme
833
1078
  switchTheme('dark'); // Switch to dark theme
834
1079
  switchTheme('default'); // Switch to default theme
1080
+
1081
+
835
1082
  ```
1083
+
836
1084
  ## Browser Compatibility
1085
+
837
1086
  The CSS uses modern features with fallbacks:
838
1087
 
839
1088
  CSS Custom Properties: Supported in all modern browsers
@@ -866,7 +1115,7 @@ If no language is specified in the initialization options, the player **automati
866
1115
  The player currently supports the following languages:
867
1116
 
868
1117
  | Code | Language | Native Name |
869
- |------|----------|-------------|
1118
+ | --- | --- | --- |
870
1119
  | `it` | Italian | Italiano |
871
1120
  | `en` | English | English |
872
1121
  | `es` | Spanish | Español |
@@ -881,22 +1130,30 @@ The player currently supports the following languages:
881
1130
  ### Setting Language at Initialization
882
1131
 
883
1132
  To specify a language during player initialization, use the `language` option:
884
- ```
1133
+
1134
+ ```javascript
885
1135
  const player = new VideoPlayer('myVideo', {
886
1136
  language: 'en', // Set to English
887
1137
  // other options...
888
1138
  });
1139
+
1140
+
889
1141
  ```
1142
+
890
1143
  ### Changing Language Dynamically
891
1144
 
892
1145
  You can change the player language at any time using the `setLanguage()` method:
893
- ```
1146
+
1147
+ ```javascript
894
1148
  // Change language to Spanish
895
1149
  player.setLanguage('es');
896
1150
 
897
1151
  // Change language to French
898
1152
  player.setLanguage('fr');
1153
+
1154
+
899
1155
  ```
1156
+
900
1157
  The method returns `true` if the language was successfully changed, `false` if the specified language is not available.
901
1158
 
902
1159
  ### Getting Language Information
@@ -904,48 +1161,62 @@ The method returns `true` if the language was successfully changed, `false` if t
904
1161
  The player provides several methods to retrieve language information:
905
1162
 
906
1163
  #### Get current language:
907
- ```
1164
+
1165
+ ```javascript
908
1166
  const currentLang = player.getCurrentLanguage();
909
1167
  console.log(currentLang); // e.g., 'en'
1168
+
1169
+
910
1170
  ```
1171
+
911
1172
  #### Get list of supported languages:
912
- ```
1173
+
1174
+ ```javascript
913
1175
  const languages = player.getSupportedLanguages();
914
1176
  console.log(languages); // ['it', 'en', 'es', 'fr', 'de', 'pt', 'zh', 'ja', 'ru', 'ar']
1177
+
1178
+
915
1179
  ```
1180
+
916
1181
  ### Translated Elements
917
1182
 
918
1183
  The i18n system automatically translates the following interface elements:
919
1184
 
920
- - Control buttons (play/pause, mute, fullscreen, etc.)
921
- - Settings menus
922
- - Video quality options
923
- - Subtitle controls
924
- - Playback speed controls
925
- - Playlist controls
926
- - Tooltips and help messages
927
- - Brand logo
1185
+ * Control buttons (play/pause, mute, fullscreen, etc.)
1186
+ * Settings menus
1187
+ * Video quality options
1188
+ * Subtitle controls
1189
+ * Playback speed controls
1190
+ * Playlist controls
1191
+ * Tooltips and help messages
1192
+ * Brand logo
928
1193
 
929
1194
  ## Plugins feature
1195
+
930
1196
  The player supports custom plugins to extend its functionality. Every plugins must have its own documentation to clearly known how to use it. Plugins are modular so you can add or remove any plugins whenever you want. This is just an example based on two plugins.
931
1197
 
932
- [Plugins and Feature Help: https://github.com/OskarCosimo/myetv-video-player-opensource/tree/main/plugins](https://github.com/OskarCosimo/myetv-video-player-opensource/tree/main/plugins)
1198
+ Some of the supported plugins: autosub (with ai), cloudflare, facebook, soundcloud, twitch, vimeo, youtube, gamepad-remote-controller, google-adsense-ads, google-analytics, google-ima-ads, vast-vpaid-ads, iframe-ads, radio tuner
1199
+
1200
+ Plugins and Feature Help: [https://github.com/OskarCosimo/myetv-video-player-opensource/tree/main/plugins](https://github.com/OskarCosimo/myetv-video-player-opensource/tree/main/plugins)
933
1201
 
934
1202
  ## Chapters feature
1203
+
935
1204
  Supports flexible time formats (HH:MM:SS, MM:SS, or seconds) and images url (optional)
1205
+
936
1206
  ### JSON format
937
- ```
1207
+
1208
+ ```javascript
938
1209
  const player = new VideoPlayer('myVideo', {
939
1210
  chapters: [
940
1211
  {
941
1212
  time: 0,
942
1213
  title: "Introduction",
943
- image: "https://example.com/intro.jpg"
1214
+ image: "[https://example.com/intro.jpg](https://example.com/intro.jpg)"
944
1215
  },
945
1216
  {
946
1217
  time: 120,
947
1218
  title: "Main Content",
948
- image: "https://example.com/main.jpg",
1219
+ image: "[https://example.com/main.jpg](https://example.com/main.jpg)",
949
1220
  color: "#FF5722" // Custom color (optional)
950
1221
  },
951
1222
  {
@@ -955,18 +1226,27 @@ const player = new VideoPlayer('myVideo', {
955
1226
  }
956
1227
  ]
957
1228
  });
1229
+
1230
+
958
1231
  ```
1232
+
959
1233
  ### String format
960
- ```
1234
+
1235
+ ```javascript
961
1236
  const player = new VideoPlayer('myVideo', {
962
1237
  chapters: "0:00:00|Introduction|intro.jpg,0:02:00|Main Content|main.jpg,0:05:00|Conclusion"
963
1238
  });
1239
+
1240
+
964
1241
  ```
1242
+
965
1243
  ## Playlist feature
1244
+
966
1245
  ### Playlist Detection System
1246
+
967
1247
  The playlist detection will work through HTML attributes on your video elements:
968
- ```
969
- <!-- Example playlist setup -->
1248
+
1249
+ ```html
970
1250
  <video id="myVideo" class="video-player"
971
1251
  data-playlist-id="my-series"
972
1252
  data-playlist-index="0">
@@ -974,39 +1254,52 @@ The playlist detection will work through HTML attributes on your video elements:
974
1254
  <source src="video1-480p.mp4" type="video/mp4" data-quality="480p">
975
1255
  </video>
976
1256
 
977
- <!-- Next video in playlist -->
978
1257
  <video id="video2" class="video-player"
979
1258
  data-playlist-id="my-series"
980
1259
  data-playlist-index="1">
981
1260
  <source src="video2-720p.mp4" type="video/mp4" data-quality="720p">
982
1261
  <source src="video2-480p.mp4" type="video/mp4" data-quality="480p">
983
1262
  </video>
1263
+
1264
+
984
1265
  ```
985
- ## Adaptive streaming (HLS/DASH)
986
- (Dash)
987
- Ecco un esempio per il tuo README.md:​
988
1266
 
989
- text
990
- ## Adaptive Streaming (DASH/HLS)
1267
+ ## Adaptive streaming (HLS/DASH)
991
1268
 
992
1269
  MyeTV Player supports adaptive bitrate streaming using DASH (Dynamic Adaptive Streaming over HTTP) and HLS (HTTP Live Streaming) protocols. This enables automatic quality switching based on network conditions for optimal playback experience.
993
1270
 
994
1271
  ### Features
995
1272
 
996
- - **Automatic Quality Selection**: The player automatically adjusts video quality based on available bandwidth
997
- - **Manual Quality Control**: Users can manually select specific resolutions (240p, 360p, 480p, 720p, 1080p, 4K)
998
- - **Seamless Switching**: Quality changes occur smoothly without interrupting playback
999
- - **Real-time Monitoring**: Displays current playing quality in the control bar
1273
+ * **Automatic Quality Selection**: The player automatically adjusts video quality based on available bandwidth
1274
+ * **Manual Quality Control**: Users can manually select specific resolutions (240p, 360p, 480p, 720p, 1080p, 4K)
1275
+ * **Seamless Switching**: Quality changes occur smoothly without interrupting playback
1276
+ * **Real-time Monitoring**: Displays current playing quality in the control bar
1000
1277
 
1001
1278
  ### Basic Usage
1002
1279
 
1003
1280
  #### Method 1: Using HTML Video Tag
1281
+
1282
+ ```html
1283
+ <video id="my-player" controls>
1284
+ <source src="[https://example.com/video/manifest.mpd](https://example.com/video/manifest.mpd)" type="application/dash+xml">
1285
+ <source src="[https://example.com/video/fallback.mp4](https://example.com/video/fallback.mp4)" type="video/mp4">
1286
+ </video>
1287
+ <script>
1288
+ const player = new MYETVvideoplayer({
1289
+ container: '#my-player',
1290
+ autoplay: false,
1291
+ adaptiveStreaming: true,
1292
+ adaptiveQualityControl: true,
1293
+ debug: true
1294
+ });
1295
+ </script>
1296
+
1297
+
1004
1298
  ```
1005
- <video id="my-player" controls> <source src="https://example.com/video/manifest.mpd" type="application/dash+xml"> <!-- Fallback for browsers without DASH support --> <source src="https://example.com/video/fallback.mp4" type="video/mp4"> </video>
1006
- <script>const player = new MYETVvideoplayer({ container: '#my-player', autoplay: false, adaptiveStreaming: true, adaptiveQualityControl: true, debug: true });</script>
1007
- ```
1299
+
1008
1300
  #### Method 2: Using JavaScript Load
1009
- ```
1301
+
1302
+ ```javascript
1010
1303
  const player = new MYETVvideoplayer({
1011
1304
  container: '#player-container',
1012
1305
  autoplay: true,
@@ -1015,46 +1308,56 @@ debug: true
1015
1308
 
1016
1309
  // Load DASH stream
1017
1310
  player.load({
1018
- src: 'https://example.com/video/manifest.mpd',
1311
+ src: '[https://example.com/video/manifest.mpd](https://example.com/video/manifest.mpd)',
1019
1312
  type: 'application/dash+xml'
1020
1313
  });
1021
1314
 
1022
1315
  // Or load HLS stream
1023
1316
  player.load({
1024
- src: 'https://example.com/video/playlist.m3u8',
1317
+ src: '[https://example.com/video/playlist.m3u8](https://example.com/video/playlist.m3u8)',
1025
1318
  type: 'application/x-mpegURL'
1026
1319
  });
1320
+
1321
+
1027
1322
  ```
1323
+
1028
1324
  The player automatically loads the required libraries:
1029
1325
 
1030
- - **dash.js** (v5.x) for DASH streams
1031
- - **hls.js** (latest) for HLS streams
1326
+ * **dash.js** (v5.x) for DASH streams
1327
+ * **hls.js** (latest) for HLS streams
1032
1328
 
1033
1329
  No additional configuration needed - libraries are loaded on-demand when adaptive streaming is detected.
1330
+
1034
1331
  ### Adaptive Streaming APIs
1035
- ```
1332
+
1333
+ ```javascript
1036
1334
  // Info adaptive streaming
1037
1335
  player.getAdaptiveStreamingInfo();
1038
1336
 
1039
1337
  // Change quality of adaptive streaming
1040
1338
  player.setAdaptiveQuality(1); // Specify quality
1041
1339
  player.setAdaptiveQuality('auto'); // Auto-switching
1340
+
1341
+
1042
1342
  ```
1343
+
1043
1344
  ### Example Playlist+Adaptive Streaming
1044
- ```
1045
- <!-- Video 1: DASH -->
1345
+
1346
+ ```html
1046
1347
  <video data-playlist-id="series" data-playlist-index="0" src="ep1.mpd">
1047
1348
 
1048
- <!-- Video 2: HLS -->
1049
1349
  <video data-playlist-id="series" data-playlist-index="1" src="ep2.m3u8">
1050
1350
 
1051
- <!-- Video 3: Traditional -->
1052
1351
  <video data-playlist-id="series" data-playlist-index="2">
1053
1352
  <source src="ep3-1080p.mp4" data-quality="1080p">
1054
1353
  <source src="ep3-720p.mp4" data-quality="720p">
1055
1354
  </video>
1355
+
1356
+
1056
1357
  ```
1358
+
1057
1359
  ## Supported Browsers
1360
+
1058
1361
  Chrome 60+
1059
1362
  Firefox 55+
1060
1363
  Safari 11+
@@ -1062,9 +1365,11 @@ Edge 79+
1062
1365
  Mobile browsers with HTML5 support
1063
1366
 
1064
1367
  ## License
1368
+
1065
1369
  This project is released under the MIT License.
1066
1370
 
1067
1371
  ## Contributing
1372
+
1068
1373
  Fork the repository
1069
1374
 
1070
1375
  Create a feature branch (git checkout -b feature/feature-name)
@@ -1082,4 +1387,5 @@ Donate to the project here: [https://blog.myetv.tv/donate-to-developers/](https:
1082
1387
  Watch MYETV here: [https://www.myetv.tv](https://www.myetv.tv)
1083
1388
 
1084
1389
  ## Bug Reports
1390
+
1085
1391
  To report bugs or request features, open an issue in the repository.