vidply 1.0.5 → 1.0.7
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/LICENSE +22 -22
- package/README.md +608 -593
- package/dist/vidply.css +2422 -1807
- package/dist/vidply.esm.js +1480 -93
- package/dist/vidply.esm.js.map +3 -3
- package/dist/vidply.esm.min.js +3 -3
- package/dist/vidply.esm.min.meta.json +48 -25
- package/dist/vidply.js +1480 -93
- package/dist/vidply.js.map +3 -3
- package/dist/vidply.min.css +1 -1
- package/dist/vidply.min.js +3 -3
- package/dist/vidply.min.meta.json +48 -25
- package/package.json +2 -2
- package/src/controls/CaptionManager.js +278 -248
- package/src/controls/ControlBar.js +2033 -2026
- package/src/controls/KeyboardManager.js +233 -233
- package/src/controls/SettingsDialog.js +417 -417
- package/src/controls/TranscriptManager.js +1803 -728
- package/src/core/Player.js +1616 -1134
- package/src/i18n/i18n.js +66 -66
- package/src/i18n/translations.js +616 -561
- package/src/icons/Icons.js +187 -183
- package/src/index.js +95 -95
- package/src/renderers/HLSRenderer.js +302 -302
- package/src/renderers/HTML5Renderer.js +298 -298
- package/src/renderers/VimeoRenderer.js +257 -257
- package/src/renderers/YouTubeRenderer.js +274 -274
- package/src/styles/vidply.css +2422 -1807
- package/src/utils/DOMUtils.js +154 -154
- package/src/utils/EventEmitter.js +53 -53
- package/src/utils/StorageManager.js +156 -0
- package/src/utils/TimeUtils.js +87 -87
package/README.md
CHANGED
|
@@ -1,593 +1,608 @@
|
|
|
1
|
-
# <img src="favicon.svg" width="32" alt="VidPly" /> VidPly
|
|
2
|
-
|
|
3
|
-
**Universal, Accessible Video & Audio Player**
|
|
4
|
-
|
|
5
|
-
A modern, feature-rich media player built with vanilla ES6 JavaScript. Combines the best accessibility features from AblePlayer with the streaming capabilities of MediaElement.js. Fully internationalized with support for 5 languages and complete WCAG 2.1 AA compliance.
|
|
6
|
-
|
|
7
|
-

|
|
8
|
-

|
|
9
|
-

|
|
10
|
-
** - Full-featured video player showcase
|
|
16
|
-
- **[Audio Playlist](https://matthiaspeltzer.github.io/vidply/demo/playlist-audio.html)** - Audio player with playlist support
|
|
17
|
-
- **[Video Playlist](https://matthiaspeltzer.github.io/vidply/demo/playlist-video.html)** - Video playlist with thumbnails
|
|
18
|
-
- **[HLS Streaming](https://matthiaspeltzer.github.io/vidply/demo/hls-test.html)** - Adaptive bitrate streaming demo
|
|
19
|
-
- **[Sign Language](https://matthiaspeltzer.github.io/vidply/demo/sign-language-demo.html)** - Sign language overlay demo
|
|
20
|
-
|
|
21
|
-
## Why VidPly?
|
|
22
|
-
|
|
23
|
-
- **Zero Dependencies** - Pure vanilla JavaScript, no frameworks required
|
|
24
|
-
- **Accessibility First** - WCAG 2.1 AA compliant with full keyboard and screen reader support
|
|
25
|
-
- **Multilingual** - Built-in translations for 5 languages with easy extensibility
|
|
26
|
-
- **Fully Customizable** - CSS variables and comprehensive API
|
|
27
|
-
- **Modern Build** - ES6 modules with tree-shaking support
|
|
28
|
-
- **Production Ready** - Thoroughly tested with real-world media content
|
|
29
|
-
|
|
30
|
-
## Features
|
|
31
|
-
|
|
32
|
-
### Core Media Support
|
|
33
|
-
- **Audio & Video Playback** - Native HTML5 support for both media types
|
|
34
|
-
- **Multiple Formats** - MP3, OGG, WAV (audio) / MP4, WebM (video)
|
|
35
|
-
- **YouTube Integration** - Embed YouTube videos with unified controls
|
|
36
|
-
- **Vimeo Integration** - Seamless Vimeo player integration
|
|
37
|
-
- **HLS Streaming** - Adaptive bitrate streaming with quality selection
|
|
38
|
-
- **Playlists** - Full playlist support with auto-advance and navigation
|
|
39
|
-
- Audio playlists with track info
|
|
40
|
-
- Video playlists with thumbnails
|
|
41
|
-
- Previous/Next controls
|
|
42
|
-
- Visual playlist panel
|
|
43
|
-
|
|
44
|
-
### Accessibility Features
|
|
45
|
-
- **Full Keyboard Navigation** - WCAG 2.1 compliant
|
|
46
|
-
- **Screen Reader Support** - Complete ARIA labels
|
|
47
|
-
- **Interactive Transcripts** - Click-to-seek transcript window
|
|
48
|
-
- **Sign Language Overlay** - Picture-in-picture sign language video
|
|
49
|
-
- **Audio Description** - Alternate audio track with descriptions
|
|
50
|
-
- **Customizable Shortcuts** - User-definable hotkeys
|
|
51
|
-
- **High Contrast Mode** - Windows HCM support
|
|
52
|
-
- **Focus Indicators** - Clear visual focus states
|
|
53
|
-
- **Live Announcements** - Screen reader updates
|
|
54
|
-
|
|
55
|
-
### Captions & Subtitles
|
|
56
|
-
- **WebVTT Support** - Standard caption format
|
|
57
|
-
- **Multiple Languages** - Multi-track support
|
|
58
|
-
- **Caption Selector** - Easy track switching with CC button
|
|
59
|
-
- **Caption Styling** - Dedicated styling menu (font, size, color, opacity)
|
|
60
|
-
- **Chapter Navigation** - Jump to video chapters
|
|
61
|
-
- **Interactive Transcripts** - Full-text searchable transcript panel
|
|
62
|
-
|
|
63
|
-
### Playback Features
|
|
64
|
-
- **Adjustable Speed** - 0.25x to 2x playback
|
|
65
|
-
- **Seek Controls** - Forward/backward navigation
|
|
66
|
-
- **Volume Control** - 0-100% with mute
|
|
67
|
-
- **Loop Playback** - Single or playlist loop
|
|
68
|
-
- **Fullscreen Mode** - Native fullscreen API
|
|
69
|
-
- **Picture-in-Picture** - PiP support
|
|
70
|
-
|
|
71
|
-
### Internationalization
|
|
72
|
-
Built-in support for 5 languages:
|
|
73
|
-
- 🇬🇧 English
|
|
74
|
-
- 🇪🇸 Spanish (Español)
|
|
75
|
-
- 🇫🇷 French (Français)
|
|
76
|
-
- 🇩🇪 German (Deutsch)
|
|
77
|
-
- 🇯🇵 Japanese (日本語)
|
|
78
|
-
|
|
79
|
-
All UI elements are fully translated, including:
|
|
80
|
-
- Control buttons and menus
|
|
81
|
-
- Time display and duration formatting
|
|
82
|
-
- Keyboard shortcuts
|
|
83
|
-
- Error messages and notifications
|
|
84
|
-
- ARIA labels for screen readers
|
|
85
|
-
|
|
86
|
-
Easy to add more languages via the i18n system
|
|
87
|
-
|
|
88
|
-
## Installation
|
|
89
|
-
|
|
90
|
-
### Build from Source
|
|
91
|
-
|
|
92
|
-
First, build the player:
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
# Install dependencies
|
|
96
|
-
npm install
|
|
97
|
-
|
|
98
|
-
# Build production files
|
|
99
|
-
npm run build
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
This creates minified files in the `dist/` folder.
|
|
103
|
-
|
|
104
|
-
### Option 1: Using Built Files (Recommended for Production)
|
|
105
|
-
|
|
106
|
-
```html
|
|
107
|
-
<!DOCTYPE html>
|
|
108
|
-
<html>
|
|
109
|
-
<head>
|
|
110
|
-
<link rel="stylesheet" href="dist/vidply.min.css">
|
|
111
|
-
</head>
|
|
112
|
-
<body>
|
|
113
|
-
<video data-vidply src="video.mp4" width="800" height="450">
|
|
114
|
-
<track kind="subtitles" src="captions.vtt" srclang="en" label="English">
|
|
115
|
-
</video>
|
|
116
|
-
|
|
117
|
-
<script type="module">
|
|
118
|
-
import Player from './dist/vidply.esm.min.js';
|
|
119
|
-
// Auto-initialized via data-vidply attribute
|
|
120
|
-
</script>
|
|
121
|
-
</body>
|
|
122
|
-
</html>
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Option 2: Traditional Script Tag (IIFE)
|
|
126
|
-
|
|
127
|
-
```html
|
|
128
|
-
<link rel="stylesheet" href="dist/vidply.min.css">
|
|
129
|
-
<script src="dist/vidply.min.js"></script>
|
|
130
|
-
|
|
131
|
-
<video id="my-video" src="video.mp4"></video>
|
|
132
|
-
|
|
133
|
-
<script>
|
|
134
|
-
const player = new VidPly.Player('#my-video', {
|
|
135
|
-
controls: true,
|
|
136
|
-
autoplay: false,
|
|
137
|
-
volume: 0.8,
|
|
138
|
-
language: 'en'
|
|
139
|
-
});
|
|
140
|
-
</script>
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Option 3: Development (Source Files)
|
|
144
|
-
|
|
145
|
-
```javascript
|
|
146
|
-
import Player from './src/index.js';
|
|
147
|
-
|
|
148
|
-
const player = new Player('#my-video', {
|
|
149
|
-
controls: true,
|
|
150
|
-
autoplay: false,
|
|
151
|
-
volume: 0.8,
|
|
152
|
-
language: 'en'
|
|
153
|
-
});
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
## Quick Start
|
|
157
|
-
|
|
158
|
-
### 1. Build the Player
|
|
159
|
-
|
|
160
|
-
```bash
|
|
161
|
-
npm install
|
|
162
|
-
npm run build
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### 2. Add to Your Page
|
|
166
|
-
|
|
167
|
-
```html
|
|
168
|
-
<link rel="stylesheet" href="dist/vidply.min.css">
|
|
169
|
-
<script type="module">
|
|
170
|
-
import Player from './dist/vidply.esm.min.js';
|
|
171
|
-
</script>
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### 3. Create a Video Player
|
|
175
|
-
|
|
176
|
-
```html
|
|
177
|
-
<video data-vidply width="800" height="450">
|
|
178
|
-
<source src="video.mp4" type="video/mp4">
|
|
179
|
-
<track kind="subtitles" src="captions-en.vtt" srclang="en" label="English">
|
|
180
|
-
<track kind="subtitles" src="captions-es.vtt" srclang="es" label="Español">
|
|
181
|
-
</video>
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
That's it! The player auto-initializes.
|
|
185
|
-
|
|
186
|
-
### YouTube Player
|
|
187
|
-
|
|
188
|
-
```html
|
|
189
|
-
<video data-vidply src="https://www.youtube.com/watch?v=VIDEO_ID"></video>
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### Vimeo Player
|
|
193
|
-
|
|
194
|
-
```html
|
|
195
|
-
<video data-vidply src="https://vimeo.com/VIDEO_ID"></video>
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### Audio Player
|
|
199
|
-
|
|
200
|
-
```html
|
|
201
|
-
<audio data-vidply>
|
|
202
|
-
<source src="audio.mp3" type="audio/mpeg">
|
|
203
|
-
</audio>
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### HLS Streaming
|
|
207
|
-
|
|
208
|
-
```html
|
|
209
|
-
<video data-vidply src="https://example.com/stream.m3u8"></video>
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
## Configuration Options
|
|
213
|
-
|
|
214
|
-
```javascript
|
|
215
|
-
const player = new Player('#video', {
|
|
216
|
-
// Display
|
|
217
|
-
width: 800,
|
|
218
|
-
height: 450,
|
|
219
|
-
poster: 'poster.jpg',
|
|
220
|
-
responsive: true,
|
|
221
|
-
|
|
222
|
-
// Playback
|
|
223
|
-
autoplay: false,
|
|
224
|
-
loop: false,
|
|
225
|
-
muted: false,
|
|
226
|
-
volume: 0.8,
|
|
227
|
-
playbackSpeed: 1.0,
|
|
228
|
-
startTime: 0,
|
|
229
|
-
|
|
230
|
-
// Controls
|
|
231
|
-
controls: true,
|
|
232
|
-
hideControlsDelay: 3000,
|
|
233
|
-
playPauseButton: true,
|
|
234
|
-
progressBar: true,
|
|
235
|
-
volumeControl: true,
|
|
236
|
-
chaptersButton: true,
|
|
237
|
-
qualityButton: true,
|
|
238
|
-
captionStyleButton: true,
|
|
239
|
-
speedButton: true,
|
|
240
|
-
captionsButton: true,
|
|
241
|
-
transcriptButton: true,
|
|
242
|
-
audioDescriptionButton: true,
|
|
243
|
-
signLanguageButton: true,
|
|
244
|
-
fullscreenButton: true,
|
|
245
|
-
pipButton: true,
|
|
246
|
-
|
|
247
|
-
// Captions
|
|
248
|
-
captions: true,
|
|
249
|
-
captionsDefault: false,
|
|
250
|
-
captionsFontSize: '100%',
|
|
251
|
-
captionsFontFamily: 'sans-serif',
|
|
252
|
-
captionsColor: '#FFFFFF',
|
|
253
|
-
captionsBackgroundColor: '#000000',
|
|
254
|
-
captionsOpacity: 0.8,
|
|
255
|
-
|
|
256
|
-
// Audio Description
|
|
257
|
-
audioDescription: true,
|
|
258
|
-
audioDescriptionSrc: null, // URL to audio-described version
|
|
259
|
-
audioDescriptionButton: true,
|
|
260
|
-
|
|
261
|
-
// Sign Language
|
|
262
|
-
signLanguage: true,
|
|
263
|
-
signLanguageSrc: null, // URL to sign language video
|
|
264
|
-
signLanguageButton: true,
|
|
265
|
-
signLanguagePosition: 'bottom-right', // 'bottom-right', 'bottom-left', 'top-right', 'top-left'
|
|
266
|
-
|
|
267
|
-
// Transcripts
|
|
268
|
-
transcript: false,
|
|
269
|
-
transcriptButton: true,
|
|
270
|
-
transcriptPosition: 'external',
|
|
271
|
-
transcriptContainer: null,
|
|
272
|
-
|
|
273
|
-
// Keyboard
|
|
274
|
-
keyboard: true,
|
|
275
|
-
keyboardShortcuts: {
|
|
276
|
-
'play-pause': [' ', 'p', 'k'],
|
|
277
|
-
'seek-forward': ['ArrowRight', 'l'],
|
|
278
|
-
'seek-backward': ['ArrowLeft', 'j'],
|
|
279
|
-
'volume-up': ['ArrowUp'],
|
|
280
|
-
'volume-down': ['ArrowDown'],
|
|
281
|
-
'mute': ['m'],
|
|
282
|
-
'fullscreen': ['f'],
|
|
283
|
-
'captions': ['c']
|
|
284
|
-
},
|
|
285
|
-
|
|
286
|
-
// Accessibility
|
|
287
|
-
screenReaderAnnouncements: true,
|
|
288
|
-
focusHighlight: true,
|
|
289
|
-
|
|
290
|
-
// Internationalization
|
|
291
|
-
language: 'en',
|
|
292
|
-
|
|
293
|
-
// Callbacks
|
|
294
|
-
onReady: () => console.log('Ready!'),
|
|
295
|
-
onPlay: () => console.log('Playing!'),
|
|
296
|
-
onPause: () => console.log('Paused!'),
|
|
297
|
-
onEnded: () => console.log('Ended!'),
|
|
298
|
-
|
|
299
|
-
// Advanced
|
|
300
|
-
debug: false,
|
|
301
|
-
pauseOthersOnPlay: true
|
|
302
|
-
});
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
## Keyboard Shortcuts
|
|
306
|
-
|
|
307
|
-
| Key | Action |
|
|
308
|
-
|-----|--------|
|
|
309
|
-
| <kbd>Space</kbd> / <kbd>P</kbd> / <kbd>K</kbd> | Play/Pause |
|
|
310
|
-
| <kbd>F</kbd> | Toggle Fullscreen |
|
|
311
|
-
| <kbd>M</kbd> | Mute/Unmute |
|
|
312
|
-
| <kbd>↑</kbd> / <kbd>↓</kbd> | Volume Up/Down |
|
|
313
|
-
| <kbd>←</kbd> / <kbd>→</kbd> | Seek -10s / +10s |
|
|
314
|
-
| <kbd>C</kbd> | Toggle Captions (or open menu if multiple) |
|
|
315
|
-
| <kbd>A</kbd> | Open Caption Style Menu |
|
|
316
|
-
| <kbd><</kbd> / <kbd>></kbd> | Decrease/Increase Speed |
|
|
317
|
-
| <kbd>S</kbd> | Open Speed Menu |
|
|
318
|
-
| <kbd>Q</kbd> | Open Quality Menu |
|
|
319
|
-
| <kbd>J</kbd> | Open Chapters Menu |
|
|
320
|
-
| <kbd>T</kbd> | Toggle Transcript |
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
player.
|
|
330
|
-
player.
|
|
331
|
-
player.
|
|
332
|
-
player.
|
|
333
|
-
player.
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
player.
|
|
342
|
-
player.
|
|
343
|
-
player.
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
player.
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
player.
|
|
367
|
-
|
|
368
|
-
//
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
player.transcriptManager.
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
player.
|
|
385
|
-
player.
|
|
386
|
-
player.
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
player.
|
|
393
|
-
player.
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
player.
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
player.
|
|
469
|
-
player.
|
|
470
|
-
player.
|
|
471
|
-
player.
|
|
472
|
-
player.
|
|
473
|
-
player.
|
|
474
|
-
player.
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
player.
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
.
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
```
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
-
|
|
556
|
-
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
1
|
+
# <img src="favicon.svg" width="32" alt="VidPly" /> VidPly
|
|
2
|
+
|
|
3
|
+
**Universal, Accessible Video & Audio Player**
|
|
4
|
+
|
|
5
|
+
A modern, feature-rich media player built with vanilla ES6 JavaScript. Combines the best accessibility features from AblePlayer with the streaming capabilities of MediaElement.js. Fully internationalized with support for 5 languages and complete WCAG 2.1 AA compliance.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
## Live Demos
|
|
13
|
+
|
|
14
|
+
Try VidPly in action:
|
|
15
|
+
- **[Main Demo](https://matthiaspeltzer.github.io/vidply/demo/demo.html)** - Full-featured video player showcase
|
|
16
|
+
- **[Audio Playlist](https://matthiaspeltzer.github.io/vidply/demo/playlist-audio.html)** - Audio player with playlist support
|
|
17
|
+
- **[Video Playlist](https://matthiaspeltzer.github.io/vidply/demo/playlist-video.html)** - Video playlist with thumbnails
|
|
18
|
+
- **[HLS Streaming](https://matthiaspeltzer.github.io/vidply/demo/hls-test.html)** - Adaptive bitrate streaming demo
|
|
19
|
+
- **[Sign Language](https://matthiaspeltzer.github.io/vidply/demo/sign-language-demo.html)** - Sign language overlay demo
|
|
20
|
+
|
|
21
|
+
## Why VidPly?
|
|
22
|
+
|
|
23
|
+
- **Zero Dependencies** - Pure vanilla JavaScript, no frameworks required
|
|
24
|
+
- **Accessibility First** - WCAG 2.1 AA compliant with full keyboard and screen reader support
|
|
25
|
+
- **Multilingual** - Built-in translations for 5 languages with easy extensibility
|
|
26
|
+
- **Fully Customizable** - CSS variables and comprehensive API
|
|
27
|
+
- **Modern Build** - ES6 modules with tree-shaking support
|
|
28
|
+
- **Production Ready** - Thoroughly tested with real-world media content
|
|
29
|
+
|
|
30
|
+
## Features
|
|
31
|
+
|
|
32
|
+
### Core Media Support
|
|
33
|
+
- **Audio & Video Playback** - Native HTML5 support for both media types
|
|
34
|
+
- **Multiple Formats** - MP3, OGG, WAV (audio) / MP4, WebM (video)
|
|
35
|
+
- **YouTube Integration** - Embed YouTube videos with unified controls
|
|
36
|
+
- **Vimeo Integration** - Seamless Vimeo player integration
|
|
37
|
+
- **HLS Streaming** - Adaptive bitrate streaming with quality selection
|
|
38
|
+
- **Playlists** - Full playlist support with auto-advance and navigation
|
|
39
|
+
- Audio playlists with track info
|
|
40
|
+
- Video playlists with thumbnails
|
|
41
|
+
- Previous/Next controls
|
|
42
|
+
- Visual playlist panel
|
|
43
|
+
|
|
44
|
+
### Accessibility Features
|
|
45
|
+
- **Full Keyboard Navigation** - WCAG 2.1 compliant
|
|
46
|
+
- **Screen Reader Support** - Complete ARIA labels
|
|
47
|
+
- **Interactive Transcripts** - Click-to-seek transcript window with move and resize controls
|
|
48
|
+
- **Sign Language Overlay** - Picture-in-picture sign language video
|
|
49
|
+
- **Audio Description** - Alternate audio track with descriptions
|
|
50
|
+
- **Customizable Shortcuts** - User-definable hotkeys
|
|
51
|
+
- **High Contrast Mode** - Windows HCM support
|
|
52
|
+
- **Focus Indicators** - Clear visual focus states
|
|
53
|
+
- **Live Announcements** - Screen reader updates
|
|
54
|
+
|
|
55
|
+
### Captions & Subtitles
|
|
56
|
+
- **WebVTT Support** - Standard caption format
|
|
57
|
+
- **Multiple Languages** - Multi-track support
|
|
58
|
+
- **Caption Selector** - Easy track switching with CC button
|
|
59
|
+
- **Caption Styling** - Dedicated styling menu (font, size, color, opacity)
|
|
60
|
+
- **Chapter Navigation** - Jump to video chapters
|
|
61
|
+
- **Interactive Transcripts** - Full-text searchable transcript panel
|
|
62
|
+
|
|
63
|
+
### Playback Features
|
|
64
|
+
- **Adjustable Speed** - 0.25x to 2x playback
|
|
65
|
+
- **Seek Controls** - Forward/backward navigation
|
|
66
|
+
- **Volume Control** - 0-100% with mute
|
|
67
|
+
- **Loop Playback** - Single or playlist loop
|
|
68
|
+
- **Fullscreen Mode** - Native fullscreen API
|
|
69
|
+
- **Picture-in-Picture** - PiP support
|
|
70
|
+
|
|
71
|
+
### Internationalization
|
|
72
|
+
Built-in support for 5 languages:
|
|
73
|
+
- 🇬🇧 English
|
|
74
|
+
- 🇪🇸 Spanish (Español)
|
|
75
|
+
- 🇫🇷 French (Français)
|
|
76
|
+
- 🇩🇪 German (Deutsch)
|
|
77
|
+
- 🇯🇵 Japanese (日本語)
|
|
78
|
+
|
|
79
|
+
All UI elements are fully translated, including:
|
|
80
|
+
- Control buttons and menus
|
|
81
|
+
- Time display and duration formatting
|
|
82
|
+
- Keyboard shortcuts
|
|
83
|
+
- Error messages and notifications
|
|
84
|
+
- ARIA labels for screen readers
|
|
85
|
+
|
|
86
|
+
Easy to add more languages via the i18n system
|
|
87
|
+
|
|
88
|
+
## Installation
|
|
89
|
+
|
|
90
|
+
### Build from Source
|
|
91
|
+
|
|
92
|
+
First, build the player:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Install dependencies
|
|
96
|
+
npm install
|
|
97
|
+
|
|
98
|
+
# Build production files
|
|
99
|
+
npm run build
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
This creates minified files in the `dist/` folder.
|
|
103
|
+
|
|
104
|
+
### Option 1: Using Built Files (Recommended for Production)
|
|
105
|
+
|
|
106
|
+
```html
|
|
107
|
+
<!DOCTYPE html>
|
|
108
|
+
<html>
|
|
109
|
+
<head>
|
|
110
|
+
<link rel="stylesheet" href="dist/vidply.min.css">
|
|
111
|
+
</head>
|
|
112
|
+
<body>
|
|
113
|
+
<video data-vidply src="video.mp4" width="800" height="450">
|
|
114
|
+
<track kind="subtitles" src="captions.vtt" srclang="en" label="English">
|
|
115
|
+
</video>
|
|
116
|
+
|
|
117
|
+
<script type="module">
|
|
118
|
+
import Player from './dist/vidply.esm.min.js';
|
|
119
|
+
// Auto-initialized via data-vidply attribute
|
|
120
|
+
</script>
|
|
121
|
+
</body>
|
|
122
|
+
</html>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Option 2: Traditional Script Tag (IIFE)
|
|
126
|
+
|
|
127
|
+
```html
|
|
128
|
+
<link rel="stylesheet" href="dist/vidply.min.css">
|
|
129
|
+
<script src="dist/vidply.min.js"></script>
|
|
130
|
+
|
|
131
|
+
<video id="my-video" src="video.mp4"></video>
|
|
132
|
+
|
|
133
|
+
<script>
|
|
134
|
+
const player = new VidPly.Player('#my-video', {
|
|
135
|
+
controls: true,
|
|
136
|
+
autoplay: false,
|
|
137
|
+
volume: 0.8,
|
|
138
|
+
language: 'en'
|
|
139
|
+
});
|
|
140
|
+
</script>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Option 3: Development (Source Files)
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
import Player from './src/index.js';
|
|
147
|
+
|
|
148
|
+
const player = new Player('#my-video', {
|
|
149
|
+
controls: true,
|
|
150
|
+
autoplay: false,
|
|
151
|
+
volume: 0.8,
|
|
152
|
+
language: 'en'
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Quick Start
|
|
157
|
+
|
|
158
|
+
### 1. Build the Player
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npm install
|
|
162
|
+
npm run build
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 2. Add to Your Page
|
|
166
|
+
|
|
167
|
+
```html
|
|
168
|
+
<link rel="stylesheet" href="dist/vidply.min.css">
|
|
169
|
+
<script type="module">
|
|
170
|
+
import Player from './dist/vidply.esm.min.js';
|
|
171
|
+
</script>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 3. Create a Video Player
|
|
175
|
+
|
|
176
|
+
```html
|
|
177
|
+
<video data-vidply width="800" height="450">
|
|
178
|
+
<source src="video.mp4" type="video/mp4">
|
|
179
|
+
<track kind="subtitles" src="captions-en.vtt" srclang="en" label="English">
|
|
180
|
+
<track kind="subtitles" src="captions-es.vtt" srclang="es" label="Español">
|
|
181
|
+
</video>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
That's it! The player auto-initializes.
|
|
185
|
+
|
|
186
|
+
### YouTube Player
|
|
187
|
+
|
|
188
|
+
```html
|
|
189
|
+
<video data-vidply src="https://www.youtube.com/watch?v=VIDEO_ID"></video>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Vimeo Player
|
|
193
|
+
|
|
194
|
+
```html
|
|
195
|
+
<video data-vidply src="https://vimeo.com/VIDEO_ID"></video>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Audio Player
|
|
199
|
+
|
|
200
|
+
```html
|
|
201
|
+
<audio data-vidply>
|
|
202
|
+
<source src="audio.mp3" type="audio/mpeg">
|
|
203
|
+
</audio>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### HLS Streaming
|
|
207
|
+
|
|
208
|
+
```html
|
|
209
|
+
<video data-vidply src="https://example.com/stream.m3u8"></video>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Configuration Options
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
const player = new Player('#video', {
|
|
216
|
+
// Display
|
|
217
|
+
width: 800,
|
|
218
|
+
height: 450,
|
|
219
|
+
poster: 'poster.jpg',
|
|
220
|
+
responsive: true,
|
|
221
|
+
|
|
222
|
+
// Playback
|
|
223
|
+
autoplay: false,
|
|
224
|
+
loop: false,
|
|
225
|
+
muted: false,
|
|
226
|
+
volume: 0.8,
|
|
227
|
+
playbackSpeed: 1.0,
|
|
228
|
+
startTime: 0,
|
|
229
|
+
|
|
230
|
+
// Controls
|
|
231
|
+
controls: true,
|
|
232
|
+
hideControlsDelay: 3000,
|
|
233
|
+
playPauseButton: true,
|
|
234
|
+
progressBar: true,
|
|
235
|
+
volumeControl: true,
|
|
236
|
+
chaptersButton: true,
|
|
237
|
+
qualityButton: true,
|
|
238
|
+
captionStyleButton: true,
|
|
239
|
+
speedButton: true,
|
|
240
|
+
captionsButton: true,
|
|
241
|
+
transcriptButton: true,
|
|
242
|
+
audioDescriptionButton: true,
|
|
243
|
+
signLanguageButton: true,
|
|
244
|
+
fullscreenButton: true,
|
|
245
|
+
pipButton: true,
|
|
246
|
+
|
|
247
|
+
// Captions
|
|
248
|
+
captions: true,
|
|
249
|
+
captionsDefault: false,
|
|
250
|
+
captionsFontSize: '100%',
|
|
251
|
+
captionsFontFamily: 'sans-serif',
|
|
252
|
+
captionsColor: '#FFFFFF',
|
|
253
|
+
captionsBackgroundColor: '#000000',
|
|
254
|
+
captionsOpacity: 0.8,
|
|
255
|
+
|
|
256
|
+
// Audio Description
|
|
257
|
+
audioDescription: true,
|
|
258
|
+
audioDescriptionSrc: null, // URL to audio-described version
|
|
259
|
+
audioDescriptionButton: true,
|
|
260
|
+
|
|
261
|
+
// Sign Language
|
|
262
|
+
signLanguage: true,
|
|
263
|
+
signLanguageSrc: null, // URL to sign language video
|
|
264
|
+
signLanguageButton: true,
|
|
265
|
+
signLanguagePosition: 'bottom-right', // 'bottom-right', 'bottom-left', 'top-right', 'top-left'
|
|
266
|
+
|
|
267
|
+
// Transcripts
|
|
268
|
+
transcript: false,
|
|
269
|
+
transcriptButton: true,
|
|
270
|
+
transcriptPosition: 'external',
|
|
271
|
+
transcriptContainer: null,
|
|
272
|
+
|
|
273
|
+
// Keyboard
|
|
274
|
+
keyboard: true,
|
|
275
|
+
keyboardShortcuts: {
|
|
276
|
+
'play-pause': [' ', 'p', 'k'],
|
|
277
|
+
'seek-forward': ['ArrowRight', 'l'],
|
|
278
|
+
'seek-backward': ['ArrowLeft', 'j'],
|
|
279
|
+
'volume-up': ['ArrowUp'],
|
|
280
|
+
'volume-down': ['ArrowDown'],
|
|
281
|
+
'mute': ['m'],
|
|
282
|
+
'fullscreen': ['f'],
|
|
283
|
+
'captions': ['c']
|
|
284
|
+
},
|
|
285
|
+
|
|
286
|
+
// Accessibility
|
|
287
|
+
screenReaderAnnouncements: true,
|
|
288
|
+
focusHighlight: true,
|
|
289
|
+
|
|
290
|
+
// Internationalization
|
|
291
|
+
language: 'en',
|
|
292
|
+
|
|
293
|
+
// Callbacks
|
|
294
|
+
onReady: () => console.log('Ready!'),
|
|
295
|
+
onPlay: () => console.log('Playing!'),
|
|
296
|
+
onPause: () => console.log('Paused!'),
|
|
297
|
+
onEnded: () => console.log('Ended!'),
|
|
298
|
+
|
|
299
|
+
// Advanced
|
|
300
|
+
debug: false,
|
|
301
|
+
pauseOthersOnPlay: true
|
|
302
|
+
});
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Keyboard Shortcuts
|
|
306
|
+
|
|
307
|
+
| Key | Action |
|
|
308
|
+
|-----|--------|
|
|
309
|
+
| <kbd>Space</kbd> / <kbd>P</kbd> / <kbd>K</kbd> | Play/Pause |
|
|
310
|
+
| <kbd>F</kbd> | Toggle Fullscreen |
|
|
311
|
+
| <kbd>M</kbd> | Mute/Unmute |
|
|
312
|
+
| <kbd>↑</kbd> / <kbd>↓</kbd> | Volume Up/Down |
|
|
313
|
+
| <kbd>←</kbd> / <kbd>→</kbd> | Seek -10s / +10s |
|
|
314
|
+
| <kbd>C</kbd> | Toggle Captions (or open menu if multiple) |
|
|
315
|
+
| <kbd>A</kbd> | Open Caption Style Menu |
|
|
316
|
+
| <kbd><</kbd> / <kbd>></kbd> | Decrease/Increase Speed |
|
|
317
|
+
| <kbd>S</kbd> | Open Speed Menu |
|
|
318
|
+
| <kbd>Q</kbd> | Open Quality Menu |
|
|
319
|
+
| <kbd>J</kbd> | Open Chapters Menu |
|
|
320
|
+
| <kbd>T</kbd> | Toggle Transcript |
|
|
321
|
+
| <kbd>D</kbd> | Toggle Keyboard Drag Mode (when transcript focused) |
|
|
322
|
+
| <kbd>R</kbd> | Toggle Resize Mode (when transcript focused) |
|
|
323
|
+
|
|
324
|
+
## API Reference
|
|
325
|
+
|
|
326
|
+
### Playback Control
|
|
327
|
+
|
|
328
|
+
```javascript
|
|
329
|
+
player.play() // Start playback
|
|
330
|
+
player.pause() // Pause playback
|
|
331
|
+
player.stop() // Stop and reset
|
|
332
|
+
player.toggle() // Toggle play/pause
|
|
333
|
+
player.seek(30) // Seek to 30 seconds
|
|
334
|
+
player.seekForward(10) // Skip forward 10 seconds
|
|
335
|
+
player.seekBackward(10) // Skip backward 10 seconds
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Volume Control
|
|
339
|
+
|
|
340
|
+
```javascript
|
|
341
|
+
player.setVolume(0.5) // Set volume (0-1)
|
|
342
|
+
player.getVolume() // Get current volume
|
|
343
|
+
player.mute() // Mute audio
|
|
344
|
+
player.unmute() // Unmute audio
|
|
345
|
+
player.toggleMute() // Toggle mute state
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Playback Speed
|
|
349
|
+
|
|
350
|
+
```javascript
|
|
351
|
+
player.setPlaybackSpeed(1.5) // Set speed (0.25-2.0)
|
|
352
|
+
player.getPlaybackSpeed() // Get current speed
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Fullscreen
|
|
356
|
+
|
|
357
|
+
```javascript
|
|
358
|
+
player.enterFullscreen() // Enter fullscreen
|
|
359
|
+
player.exitFullscreen() // Exit fullscreen
|
|
360
|
+
player.toggleFullscreen() // Toggle fullscreen
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Captions
|
|
364
|
+
|
|
365
|
+
```javascript
|
|
366
|
+
player.enableCaptions() // Enable captions
|
|
367
|
+
player.disableCaptions() // Disable captions
|
|
368
|
+
player.toggleCaptions() // Toggle captions
|
|
369
|
+
|
|
370
|
+
// Switch between caption tracks
|
|
371
|
+
player.captionManager.switchTrack(0) // Switch to first track
|
|
372
|
+
player.captionManager.getAvailableTracks() // Get all tracks
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Transcript
|
|
376
|
+
|
|
377
|
+
```javascript
|
|
378
|
+
player.transcriptManager.showTranscript() // Show transcript window
|
|
379
|
+
player.transcriptManager.hideTranscript() // Hide transcript window
|
|
380
|
+
player.transcriptManager.toggleTranscript() // Toggle transcript
|
|
381
|
+
|
|
382
|
+
// Settings & Move/Resize Controls
|
|
383
|
+
player.transcriptManager.showSettingsMenu() // Show settings dropdown
|
|
384
|
+
player.transcriptManager.hideSettingsMenu() // Hide settings dropdown
|
|
385
|
+
player.transcriptManager.enableMoveMode() // Show move mode feedback
|
|
386
|
+
player.transcriptManager.toggleResizeMode() // Toggle resize handles
|
|
387
|
+
player.transcriptManager.enableResizeHandles() // Enable window resizing
|
|
388
|
+
player.transcriptManager.disableResizeHandles() // Disable window resizing
|
|
389
|
+
|
|
390
|
+
// NEW: Full Keyboard Support
|
|
391
|
+
player.transcriptManager.enableKeyboardDragMode() // Enable arrow key dragging
|
|
392
|
+
player.transcriptManager.disableKeyboardDragMode() // Disable arrow key dragging
|
|
393
|
+
player.transcriptManager.toggleKeyboardDragMode() // Toggle keyboard drag mode
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Audio Description
|
|
397
|
+
|
|
398
|
+
```javascript
|
|
399
|
+
player.enableAudioDescription() // Switch to described version
|
|
400
|
+
player.disableAudioDescription() // Switch back to original
|
|
401
|
+
player.toggleAudioDescription() // Toggle audio description
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Sign Language
|
|
405
|
+
|
|
406
|
+
```javascript
|
|
407
|
+
player.enableSignLanguage() // Show sign language overlay
|
|
408
|
+
player.disableSignLanguage() // Hide sign language overlay
|
|
409
|
+
player.toggleSignLanguage() // Toggle sign language
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Playlists
|
|
413
|
+
|
|
414
|
+
```javascript
|
|
415
|
+
import { Player, PlaylistManager } from './dist/vidply.esm.js';
|
|
416
|
+
|
|
417
|
+
// Create player
|
|
418
|
+
const player = new Player('#my-player');
|
|
419
|
+
|
|
420
|
+
// Create playlist manager
|
|
421
|
+
const playlist = new PlaylistManager(player, {
|
|
422
|
+
autoAdvance: true, // Auto-play next track
|
|
423
|
+
loop: false, // Loop back to start
|
|
424
|
+
showPanel: true // Show playlist UI
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
// Load tracks
|
|
428
|
+
playlist.loadPlaylist([
|
|
429
|
+
{
|
|
430
|
+
src: 'track1.mp3',
|
|
431
|
+
title: 'Track 1',
|
|
432
|
+
artist: 'Artist Name',
|
|
433
|
+
poster: 'thumb1.jpg'
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
src: 'track2.mp3',
|
|
437
|
+
title: 'Track 2',
|
|
438
|
+
artist: 'Artist Name',
|
|
439
|
+
tracks: [
|
|
440
|
+
{ src: 'captions.vtt', kind: 'captions', srclang: 'en' }
|
|
441
|
+
]
|
|
442
|
+
}
|
|
443
|
+
]);
|
|
444
|
+
|
|
445
|
+
// Control playlist
|
|
446
|
+
playlist.next() // Go to next track
|
|
447
|
+
playlist.previous() // Go to previous track
|
|
448
|
+
playlist.goToTrack(2) // Jump to specific track
|
|
449
|
+
playlist.hasNext() // Check if next track exists
|
|
450
|
+
playlist.hasPrevious() // Check if previous track exists
|
|
451
|
+
|
|
452
|
+
// Listen for track changes
|
|
453
|
+
player.on('playlisttrackchange', (e) => {
|
|
454
|
+
console.log('Now playing:', e.item.title);
|
|
455
|
+
});
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Settings
|
|
459
|
+
|
|
460
|
+
```javascript
|
|
461
|
+
player.showSettings() // Open settings dialog
|
|
462
|
+
player.hideSettings() // Close settings dialog
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### State Information
|
|
466
|
+
|
|
467
|
+
```javascript
|
|
468
|
+
player.getCurrentTime() // Get current time
|
|
469
|
+
player.getDuration() // Get duration
|
|
470
|
+
player.isPlaying() // Check if playing
|
|
471
|
+
player.isPaused() // Check if paused
|
|
472
|
+
player.isEnded() // Check if ended
|
|
473
|
+
player.isMuted() // Check if muted
|
|
474
|
+
player.isFullscreen() // Check if fullscreen
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Event Listeners
|
|
478
|
+
|
|
479
|
+
```javascript
|
|
480
|
+
player.on('ready', () => {})
|
|
481
|
+
player.on('play', () => {})
|
|
482
|
+
player.on('pause', () => {})
|
|
483
|
+
player.on('ended', () => {})
|
|
484
|
+
player.on('timeupdate', (time) => {})
|
|
485
|
+
player.on('volumechange', (volume) => {})
|
|
486
|
+
player.on('playbackspeedchange', (speed) => {})
|
|
487
|
+
player.on('fullscreenchange', (isFullscreen) => {})
|
|
488
|
+
player.on('captionsenabled', (track) => {})
|
|
489
|
+
player.on('captionsdisabled', () => {})
|
|
490
|
+
player.on('error', (error) => {})
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Cleanup
|
|
494
|
+
|
|
495
|
+
```javascript
|
|
496
|
+
player.destroy() // Remove player and cleanup
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
## Customization
|
|
500
|
+
|
|
501
|
+
### Custom Styling
|
|
502
|
+
|
|
503
|
+
```css
|
|
504
|
+
/* Override default colors */
|
|
505
|
+
.vidply-player {
|
|
506
|
+
--vidply-primary-color: #3b82f6;
|
|
507
|
+
--vidply-background: rgba(0, 0, 0, 0.8);
|
|
508
|
+
--vidply-text-color: #ffffff;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/* Custom progress bar */
|
|
512
|
+
.vidply-progress-played {
|
|
513
|
+
background: linear-gradient(90deg, #667eea, #764ba2);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/* Custom buttons */
|
|
517
|
+
.vidply-button:hover {
|
|
518
|
+
background: rgba(59, 130, 246, 0.2);
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### Add Custom Language
|
|
523
|
+
|
|
524
|
+
```javascript
|
|
525
|
+
import { i18n } from './src/i18n/i18n.js';
|
|
526
|
+
|
|
527
|
+
i18n.addTranslation('pt', {
|
|
528
|
+
player: {
|
|
529
|
+
play: 'Reproduzir',
|
|
530
|
+
pause: 'Pausar',
|
|
531
|
+
// ... more translations
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
i18n.setLanguage('pt');
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
## 🔧 Build Process
|
|
539
|
+
|
|
540
|
+
VidPly uses a modern build system with esbuild for JavaScript and clean-css for CSS.
|
|
541
|
+
|
|
542
|
+
### Available Scripts
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
npm run build # Build everything (JS + CSS)
|
|
546
|
+
npm run build:js # Build JavaScript only
|
|
547
|
+
npm run build:css # Build CSS only
|
|
548
|
+
npm run watch # Watch mode for development
|
|
549
|
+
npm run clean # Clean dist directory
|
|
550
|
+
npm run dev # Start dev server
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### Output Files
|
|
554
|
+
|
|
555
|
+
- `dist/vidply.esm.js` - ES Module (development)
|
|
556
|
+
- `dist/vidply.esm.min.js` - ES Module (production)
|
|
557
|
+
- `dist/vidply.js` - IIFE (development)
|
|
558
|
+
- `dist/vidply.min.js` - IIFE (production)
|
|
559
|
+
- `dist/vidply.css` - Styles (unminified)
|
|
560
|
+
- `dist/vidply.min.css` - Styles (minified)
|
|
561
|
+
|
|
562
|
+
See [BUILD.md](docs/BUILD.md) for detailed build documentation.
|
|
563
|
+
|
|
564
|
+
## Browser Support
|
|
565
|
+
|
|
566
|
+
- Chrome 90+
|
|
567
|
+
- Firefox 88+
|
|
568
|
+
- Safari 14+
|
|
569
|
+
- Edge 90+
|
|
570
|
+
- iOS Safari 14+
|
|
571
|
+
- Android Chrome 90+
|
|
572
|
+
|
|
573
|
+
## License
|
|
574
|
+
|
|
575
|
+
GNU General Public License v2.0 or later
|
|
576
|
+
|
|
577
|
+
Copyright (C) 2025 Matthias Peltzer
|
|
578
|
+
|
|
579
|
+
This program is free software; you can redistribute it and/or modify
|
|
580
|
+
it under the terms of the GNU General Public License as published by
|
|
581
|
+
the Free Software Foundation; either version 2 of the License, or
|
|
582
|
+
(at your option) any later version.
|
|
583
|
+
|
|
584
|
+
See [LICENSE](LICENSE) for full license text.
|
|
585
|
+
|
|
586
|
+
## Contributing
|
|
587
|
+
|
|
588
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
589
|
+
|
|
590
|
+
## Documentation
|
|
591
|
+
|
|
592
|
+
- [Getting Started Guide](docs/GETTING_STARTED.md) - Basic setup and usage
|
|
593
|
+
- [Usage Guide](docs/USAGE.md) - Detailed usage examples
|
|
594
|
+
- [Playlist Guide](docs/PLAYLIST.md) - Audio/video playlists
|
|
595
|
+
- [Transcript Guide](docs/TRANSCRIPT.md) - Interactive transcripts
|
|
596
|
+
- [Keyboard Shortcuts](docs/KEYBOARD.md) - Complete keyboard reference
|
|
597
|
+
- [Build Guide](docs/BUILD.md) - Build system and development
|
|
598
|
+
- [Changelog](docs/CHANGELOG.md) - Version history and updates
|
|
599
|
+
|
|
600
|
+
## Credits
|
|
601
|
+
|
|
602
|
+
Inspired by:
|
|
603
|
+
- [AblePlayer](https://github.com/ableplayer/ableplayer) - Accessibility features
|
|
604
|
+
- [MediaElement.js](https://github.com/mediaelement/mediaelement) - Streaming support
|
|
605
|
+
|
|
606
|
+
---
|
|
607
|
+
|
|
608
|
+
Made with Vanilla JavaScript by Matthias Peltzer
|