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 +461 -155
- package/dist/myetv-player.js +391 -82
- package/dist/myetv-player.min.js +314 -53
- package/package.json +1 -1
- package/plugins/autosub/myetv-autosub-plugin.js +303 -155
- package/plugins/autosub/readme.md +63 -69
- 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/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 | `''` |
|
|
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
|
|
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);
|
|
172
|
-
player.getVolume();
|
|
173
|
-
player.toggleMute();
|
|
174
|
-
player.setMuted(true);
|
|
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);
|
|
180
|
-
player.getCurrentTime();
|
|
181
|
-
player.getDuration();
|
|
182
|
-
player.skipTime(10);
|
|
183
|
-
player.skipTime(-10);
|
|
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');
|
|
209
|
-
player.setQuality('1080p');
|
|
210
|
-
player.getSelectedQuality();
|
|
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();
|
|
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();
|
|
218
|
-
player.enableSubtitleTrack(0);
|
|
219
|
-
player.disableSubtitles();
|
|
220
|
-
player.getAvailableSubtitles();
|
|
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();
|
|
247
|
-
player.enterFullscreen();
|
|
248
|
-
player.exitFullscreen();
|
|
249
|
-
player.togglePictureInPicture();
|
|
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);
|
|
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
|
-
|
|
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;
|
|
732
|
-
--player-button-padding: 12px;
|
|
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
|
-
|
|
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
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1031
|
-
|
|
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
|
-
|
|
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.
|