vidply 1.0.5 → 1.0.6

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
@@ -1,593 +1,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
- ![License](https://img.shields.io/badge/license-GPL--2.0--or--later-blue.svg)
8
- ![ES6](https://img.shields.io/badge/ES6-Module-yellow.svg)
9
- ![WCAG](https://img.shields.io/badge/WCAG-2.1%20AA-green.svg)
10
- ![Version](https://img.shields.io/badge/version-1.0.4-brightgreen.svg)
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
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
- ## API Reference
323
-
324
- ### Playback Control
325
-
326
- ```javascript
327
- player.play() // Start playback
328
- player.pause() // Pause playback
329
- player.stop() // Stop and reset
330
- player.toggle() // Toggle play/pause
331
- player.seek(30) // Seek to 30 seconds
332
- player.seekForward(10) // Skip forward 10 seconds
333
- player.seekBackward(10) // Skip backward 10 seconds
334
- ```
335
-
336
- ### Volume Control
337
-
338
- ```javascript
339
- player.setVolume(0.5) // Set volume (0-1)
340
- player.getVolume() // Get current volume
341
- player.mute() // Mute audio
342
- player.unmute() // Unmute audio
343
- player.toggleMute() // Toggle mute state
344
- ```
345
-
346
- ### Playback Speed
347
-
348
- ```javascript
349
- player.setPlaybackSpeed(1.5) // Set speed (0.25-2.0)
350
- player.getPlaybackSpeed() // Get current speed
351
- ```
352
-
353
- ### Fullscreen
354
-
355
- ```javascript
356
- player.enterFullscreen() // Enter fullscreen
357
- player.exitFullscreen() // Exit fullscreen
358
- player.toggleFullscreen() // Toggle fullscreen
359
- ```
360
-
361
- ### Captions
362
-
363
- ```javascript
364
- player.enableCaptions() // Enable captions
365
- player.disableCaptions() // Disable captions
366
- player.toggleCaptions() // Toggle captions
367
-
368
- // Switch between caption tracks
369
- player.captionManager.switchTrack(0) // Switch to first track
370
- player.captionManager.getAvailableTracks() // Get all tracks
371
- ```
372
-
373
- ### Transcript
374
-
375
- ```javascript
376
- player.transcriptManager.showTranscript() // Show transcript window
377
- player.transcriptManager.hideTranscript() // Hide transcript window
378
- player.transcriptManager.toggleTranscript() // Toggle transcript
379
- ```
380
-
381
- ### Audio Description
382
-
383
- ```javascript
384
- player.enableAudioDescription() // Switch to described version
385
- player.disableAudioDescription() // Switch back to original
386
- player.toggleAudioDescription() // Toggle audio description
387
- ```
388
-
389
- ### Sign Language
390
-
391
- ```javascript
392
- player.enableSignLanguage() // Show sign language overlay
393
- player.disableSignLanguage() // Hide sign language overlay
394
- player.toggleSignLanguage() // Toggle sign language
395
- ```
396
-
397
- ### Playlists
398
-
399
- ```javascript
400
- import { Player, PlaylistManager } from './dist/vidply.esm.js';
401
-
402
- // Create player
403
- const player = new Player('#my-player');
404
-
405
- // Create playlist manager
406
- const playlist = new PlaylistManager(player, {
407
- autoAdvance: true, // Auto-play next track
408
- loop: false, // Loop back to start
409
- showPanel: true // Show playlist UI
410
- });
411
-
412
- // Load tracks
413
- playlist.loadPlaylist([
414
- {
415
- src: 'track1.mp3',
416
- title: 'Track 1',
417
- artist: 'Artist Name',
418
- poster: 'thumb1.jpg'
419
- },
420
- {
421
- src: 'track2.mp3',
422
- title: 'Track 2',
423
- artist: 'Artist Name',
424
- tracks: [
425
- { src: 'captions.vtt', kind: 'captions', srclang: 'en' }
426
- ]
427
- }
428
- ]);
429
-
430
- // Control playlist
431
- playlist.next() // Go to next track
432
- playlist.previous() // Go to previous track
433
- playlist.goToTrack(2) // Jump to specific track
434
- playlist.hasNext() // Check if next track exists
435
- playlist.hasPrevious() // Check if previous track exists
436
-
437
- // Listen for track changes
438
- player.on('playlisttrackchange', (e) => {
439
- console.log('Now playing:', e.item.title);
440
- });
441
- ```
442
-
443
- ### Settings
444
-
445
- ```javascript
446
- player.showSettings() // Open settings dialog
447
- player.hideSettings() // Close settings dialog
448
- ```
449
-
450
- ### State Information
451
-
452
- ```javascript
453
- player.getCurrentTime() // Get current time
454
- player.getDuration() // Get duration
455
- player.isPlaying() // Check if playing
456
- player.isPaused() // Check if paused
457
- player.isEnded() // Check if ended
458
- player.isMuted() // Check if muted
459
- player.isFullscreen() // Check if fullscreen
460
- ```
461
-
462
- ### Event Listeners
463
-
464
- ```javascript
465
- player.on('ready', () => {})
466
- player.on('play', () => {})
467
- player.on('pause', () => {})
468
- player.on('ended', () => {})
469
- player.on('timeupdate', (time) => {})
470
- player.on('volumechange', (volume) => {})
471
- player.on('playbackspeedchange', (speed) => {})
472
- player.on('fullscreenchange', (isFullscreen) => {})
473
- player.on('captionsenabled', (track) => {})
474
- player.on('captionsdisabled', () => {})
475
- player.on('error', (error) => {})
476
- ```
477
-
478
- ### Cleanup
479
-
480
- ```javascript
481
- player.destroy() // Remove player and cleanup
482
- ```
483
-
484
- ## Customization
485
-
486
- ### Custom Styling
487
-
488
- ```css
489
- /* Override default colors */
490
- .vidply-player {
491
- --vidply-primary-color: #3b82f6;
492
- --vidply-background: rgba(0, 0, 0, 0.8);
493
- --vidply-text-color: #ffffff;
494
- }
495
-
496
- /* Custom progress bar */
497
- .vidply-progress-played {
498
- background: linear-gradient(90deg, #667eea, #764ba2);
499
- }
500
-
501
- /* Custom buttons */
502
- .vidply-button:hover {
503
- background: rgba(59, 130, 246, 0.2);
504
- }
505
- ```
506
-
507
- ### Add Custom Language
508
-
509
- ```javascript
510
- import { i18n } from './src/i18n/i18n.js';
511
-
512
- i18n.addTranslation('pt', {
513
- player: {
514
- play: 'Reproduzir',
515
- pause: 'Pausar',
516
- // ... more translations
517
- }
518
- });
519
-
520
- i18n.setLanguage('pt');
521
- ```
522
-
523
- ## 🔧 Build Process
524
-
525
- VidPly uses a modern build system with esbuild for JavaScript and clean-css for CSS.
526
-
527
- ### Available Scripts
528
-
529
- ```bash
530
- npm run build # Build everything (JS + CSS)
531
- npm run build:js # Build JavaScript only
532
- npm run build:css # Build CSS only
533
- npm run watch # Watch mode for development
534
- npm run clean # Clean dist directory
535
- npm run dev # Start dev server
536
- ```
537
-
538
- ### Output Files
539
-
540
- - `dist/vidply.esm.js` - ES Module (development)
541
- - `dist/vidply.esm.min.js` - ES Module (production)
542
- - `dist/vidply.js` - IIFE (development)
543
- - `dist/vidply.min.js` - IIFE (production)
544
- - `dist/vidply.css` - Styles (unminified)
545
- - `dist/vidply.min.css` - Styles (minified)
546
-
547
- See [BUILD.md](docs/BUILD.md) for detailed build documentation.
548
-
549
- ## Browser Support
550
-
551
- - Chrome 90+
552
- - Firefox 88+
553
- - Safari 14+
554
- - Edge 90+
555
- - iOS Safari 14+
556
- - Android Chrome 90+
557
-
558
- ## License
559
-
560
- GNU General Public License v2.0 or later
561
-
562
- Copyright (C) 2025 Matthias Peltzer
563
-
564
- This program is free software; you can redistribute it and/or modify
565
- it under the terms of the GNU General Public License as published by
566
- the Free Software Foundation; either version 2 of the License, or
567
- (at your option) any later version.
568
-
569
- See [LICENSE](LICENSE) for full license text.
570
-
571
- ## Contributing
572
-
573
- Contributions are welcome! Please feel free to submit a Pull Request.
574
-
575
- ## Documentation
576
-
577
- - [Getting Started Guide](docs/GETTING_STARTED.md) - Basic setup and usage
578
- - [Usage Guide](docs/USAGE.md) - Detailed usage examples
579
- - [Playlist Guide](docs/PLAYLIST.md) - Audio/video playlists
580
- - [Transcript Guide](docs/TRANSCRIPT.md) - Interactive transcripts
581
- - [Keyboard Shortcuts](docs/KEYBOARD.md) - Complete keyboard reference
582
- - [Build Guide](docs/BUILD.md) - Build system and development
583
- - [Changelog](docs/CHANGELOG.md) - Version history and updates
584
-
585
- ## Credits
586
-
587
- Inspired by:
588
- - [AblePlayer](https://github.com/ableplayer/ableplayer) - Accessibility features
589
- - [MediaElement.js](https://github.com/mediaelement/mediaelement) - Streaming support
590
-
591
- ---
592
-
593
- Made with Vanilla JavaScript by Matthias Peltzer
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
+ ![License](https://img.shields.io/badge/license-GPL--2.0--or--later-blue.svg)
8
+ ![ES6](https://img.shields.io/badge/ES6-Module-yellow.svg)
9
+ ![WCAG](https://img.shields.io/badge/WCAG-2.1%20AA-green.svg)
10
+ ![Version](https://img.shields.io/badge/version-1.0.5-brightgreen.svg)
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
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
+ ## API Reference
323
+
324
+ ### Playback Control
325
+
326
+ ```javascript
327
+ player.play() // Start playback
328
+ player.pause() // Pause playback
329
+ player.stop() // Stop and reset
330
+ player.toggle() // Toggle play/pause
331
+ player.seek(30) // Seek to 30 seconds
332
+ player.seekForward(10) // Skip forward 10 seconds
333
+ player.seekBackward(10) // Skip backward 10 seconds
334
+ ```
335
+
336
+ ### Volume Control
337
+
338
+ ```javascript
339
+ player.setVolume(0.5) // Set volume (0-1)
340
+ player.getVolume() // Get current volume
341
+ player.mute() // Mute audio
342
+ player.unmute() // Unmute audio
343
+ player.toggleMute() // Toggle mute state
344
+ ```
345
+
346
+ ### Playback Speed
347
+
348
+ ```javascript
349
+ player.setPlaybackSpeed(1.5) // Set speed (0.25-2.0)
350
+ player.getPlaybackSpeed() // Get current speed
351
+ ```
352
+
353
+ ### Fullscreen
354
+
355
+ ```javascript
356
+ player.enterFullscreen() // Enter fullscreen
357
+ player.exitFullscreen() // Exit fullscreen
358
+ player.toggleFullscreen() // Toggle fullscreen
359
+ ```
360
+
361
+ ### Captions
362
+
363
+ ```javascript
364
+ player.enableCaptions() // Enable captions
365
+ player.disableCaptions() // Disable captions
366
+ player.toggleCaptions() // Toggle captions
367
+
368
+ // Switch between caption tracks
369
+ player.captionManager.switchTrack(0) // Switch to first track
370
+ player.captionManager.getAvailableTracks() // Get all tracks
371
+ ```
372
+
373
+ ### Transcript
374
+
375
+ ```javascript
376
+ player.transcriptManager.showTranscript() // Show transcript window
377
+ player.transcriptManager.hideTranscript() // Hide transcript window
378
+ player.transcriptManager.toggleTranscript() // Toggle transcript
379
+ ```
380
+
381
+ ### Audio Description
382
+
383
+ ```javascript
384
+ player.enableAudioDescription() // Switch to described version
385
+ player.disableAudioDescription() // Switch back to original
386
+ player.toggleAudioDescription() // Toggle audio description
387
+ ```
388
+
389
+ ### Sign Language
390
+
391
+ ```javascript
392
+ player.enableSignLanguage() // Show sign language overlay
393
+ player.disableSignLanguage() // Hide sign language overlay
394
+ player.toggleSignLanguage() // Toggle sign language
395
+ ```
396
+
397
+ ### Playlists
398
+
399
+ ```javascript
400
+ import { Player, PlaylistManager } from './dist/vidply.esm.js';
401
+
402
+ // Create player
403
+ const player = new Player('#my-player');
404
+
405
+ // Create playlist manager
406
+ const playlist = new PlaylistManager(player, {
407
+ autoAdvance: true, // Auto-play next track
408
+ loop: false, // Loop back to start
409
+ showPanel: true // Show playlist UI
410
+ });
411
+
412
+ // Load tracks
413
+ playlist.loadPlaylist([
414
+ {
415
+ src: 'track1.mp3',
416
+ title: 'Track 1',
417
+ artist: 'Artist Name',
418
+ poster: 'thumb1.jpg'
419
+ },
420
+ {
421
+ src: 'track2.mp3',
422
+ title: 'Track 2',
423
+ artist: 'Artist Name',
424
+ tracks: [
425
+ { src: 'captions.vtt', kind: 'captions', srclang: 'en' }
426
+ ]
427
+ }
428
+ ]);
429
+
430
+ // Control playlist
431
+ playlist.next() // Go to next track
432
+ playlist.previous() // Go to previous track
433
+ playlist.goToTrack(2) // Jump to specific track
434
+ playlist.hasNext() // Check if next track exists
435
+ playlist.hasPrevious() // Check if previous track exists
436
+
437
+ // Listen for track changes
438
+ player.on('playlisttrackchange', (e) => {
439
+ console.log('Now playing:', e.item.title);
440
+ });
441
+ ```
442
+
443
+ ### Settings
444
+
445
+ ```javascript
446
+ player.showSettings() // Open settings dialog
447
+ player.hideSettings() // Close settings dialog
448
+ ```
449
+
450
+ ### State Information
451
+
452
+ ```javascript
453
+ player.getCurrentTime() // Get current time
454
+ player.getDuration() // Get duration
455
+ player.isPlaying() // Check if playing
456
+ player.isPaused() // Check if paused
457
+ player.isEnded() // Check if ended
458
+ player.isMuted() // Check if muted
459
+ player.isFullscreen() // Check if fullscreen
460
+ ```
461
+
462
+ ### Event Listeners
463
+
464
+ ```javascript
465
+ player.on('ready', () => {})
466
+ player.on('play', () => {})
467
+ player.on('pause', () => {})
468
+ player.on('ended', () => {})
469
+ player.on('timeupdate', (time) => {})
470
+ player.on('volumechange', (volume) => {})
471
+ player.on('playbackspeedchange', (speed) => {})
472
+ player.on('fullscreenchange', (isFullscreen) => {})
473
+ player.on('captionsenabled', (track) => {})
474
+ player.on('captionsdisabled', () => {})
475
+ player.on('error', (error) => {})
476
+ ```
477
+
478
+ ### Cleanup
479
+
480
+ ```javascript
481
+ player.destroy() // Remove player and cleanup
482
+ ```
483
+
484
+ ## Customization
485
+
486
+ ### Custom Styling
487
+
488
+ ```css
489
+ /* Override default colors */
490
+ .vidply-player {
491
+ --vidply-primary-color: #3b82f6;
492
+ --vidply-background: rgba(0, 0, 0, 0.8);
493
+ --vidply-text-color: #ffffff;
494
+ }
495
+
496
+ /* Custom progress bar */
497
+ .vidply-progress-played {
498
+ background: linear-gradient(90deg, #667eea, #764ba2);
499
+ }
500
+
501
+ /* Custom buttons */
502
+ .vidply-button:hover {
503
+ background: rgba(59, 130, 246, 0.2);
504
+ }
505
+ ```
506
+
507
+ ### Add Custom Language
508
+
509
+ ```javascript
510
+ import { i18n } from './src/i18n/i18n.js';
511
+
512
+ i18n.addTranslation('pt', {
513
+ player: {
514
+ play: 'Reproduzir',
515
+ pause: 'Pausar',
516
+ // ... more translations
517
+ }
518
+ });
519
+
520
+ i18n.setLanguage('pt');
521
+ ```
522
+
523
+ ## 🔧 Build Process
524
+
525
+ VidPly uses a modern build system with esbuild for JavaScript and clean-css for CSS.
526
+
527
+ ### Available Scripts
528
+
529
+ ```bash
530
+ npm run build # Build everything (JS + CSS)
531
+ npm run build:js # Build JavaScript only
532
+ npm run build:css # Build CSS only
533
+ npm run watch # Watch mode for development
534
+ npm run clean # Clean dist directory
535
+ npm run dev # Start dev server
536
+ ```
537
+
538
+ ### Output Files
539
+
540
+ - `dist/vidply.esm.js` - ES Module (development)
541
+ - `dist/vidply.esm.min.js` - ES Module (production)
542
+ - `dist/vidply.js` - IIFE (development)
543
+ - `dist/vidply.min.js` - IIFE (production)
544
+ - `dist/vidply.css` - Styles (unminified)
545
+ - `dist/vidply.min.css` - Styles (minified)
546
+
547
+ See [BUILD.md](docs/BUILD.md) for detailed build documentation.
548
+
549
+ ## Browser Support
550
+
551
+ - Chrome 90+
552
+ - Firefox 88+
553
+ - Safari 14+
554
+ - Edge 90+
555
+ - iOS Safari 14+
556
+ - Android Chrome 90+
557
+
558
+ ## License
559
+
560
+ GNU General Public License v2.0 or later
561
+
562
+ Copyright (C) 2025 Matthias Peltzer
563
+
564
+ This program is free software; you can redistribute it and/or modify
565
+ it under the terms of the GNU General Public License as published by
566
+ the Free Software Foundation; either version 2 of the License, or
567
+ (at your option) any later version.
568
+
569
+ See [LICENSE](LICENSE) for full license text.
570
+
571
+ ## Contributing
572
+
573
+ Contributions are welcome! Please feel free to submit a Pull Request.
574
+
575
+ ## Documentation
576
+
577
+ - [Getting Started Guide](docs/GETTING_STARTED.md) - Basic setup and usage
578
+ - [Usage Guide](docs/USAGE.md) - Detailed usage examples
579
+ - [Playlist Guide](docs/PLAYLIST.md) - Audio/video playlists
580
+ - [Transcript Guide](docs/TRANSCRIPT.md) - Interactive transcripts
581
+ - [Keyboard Shortcuts](docs/KEYBOARD.md) - Complete keyboard reference
582
+ - [Build Guide](docs/BUILD.md) - Build system and development
583
+ - [Changelog](docs/CHANGELOG.md) - Version history and updates
584
+
585
+ ## Credits
586
+
587
+ Inspired by:
588
+ - [AblePlayer](https://github.com/ableplayer/ableplayer) - Accessibility features
589
+ - [MediaElement.js](https://github.com/mediaelement/mediaelement) - Streaming support
590
+
591
+ ---
592
+
593
+ Made with Vanilla JavaScript by Matthias Peltzer