@elementmints/shadow-plyr 1.1.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +180 -204
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +2 -3
- package/dist/index.umd.js.map +1 -1
- package/dist/{types/types.d.ts → types.d.ts} +26 -3
- package/package.json +26 -5
- /package/dist/{types/icons.d.ts → icons.d.ts} +0 -0
- /package/dist/{types/index.d.ts → index.d.ts} +0 -0
- /package/dist/{types/shadow-plyr.d.ts → shadow-plyr.d.ts} +0 -0
- /package/dist/{types/utils.d.ts → utils.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,59 +1,84 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Shadow Plyr
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
<h1 align="center">Shadow Plyr</h1>
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
A modern Web Component video player built with Shadow DOM.
|
|
7
|
+
</p>
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## ❤️ Support the Project
|
|
9
|
+
<p align="center">
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+

|
|
12
|
+

|
|
13
|
+

|
|
14
|
+

|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
</p>
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="https://elementmints.github.io/shadow-plyr/">Live Demo</a>
|
|
20
|
+
|
|
|
21
|
+
<a href="https://www.npmjs.com/package/@elementmints/shadow-plyr">NPM</a>
|
|
22
|
+
</p>
|
|
18
23
|
|
|
19
24
|
---
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
# 🎬 Demo
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
- 🔐 Secure SVG sanitization
|
|
32
|
-
- 🧵 Virtual playback mode (only one video plays)
|
|
33
|
-
- 📦 Framework agnostic (React / Vue / Angular / Vanilla)
|
|
28
|
+
```html
|
|
29
|
+
<shadow-plyr
|
|
30
|
+
desktop-video="https://example.com/video.mp4"
|
|
31
|
+
desktop-poster="https://example.com/poster.jpg"
|
|
32
|
+
show-controls="true"
|
|
33
|
+
show-center-play="true">
|
|
34
|
+
</shadow-plyr>
|
|
35
|
+
```
|
|
34
36
|
|
|
35
37
|
---
|
|
36
38
|
|
|
37
|
-
#
|
|
39
|
+
# ✨ Features
|
|
40
|
+
|
|
41
|
+
| Feature | Supported |
|
|
42
|
+
|------|------|
|
|
43
|
+
| Web Component architecture | ✅ |
|
|
44
|
+
| Shadow DOM encapsulation | ✅ |
|
|
45
|
+
| Adaptive HLS streaming | ✅ |
|
|
46
|
+
| Quality selector | ✅ |
|
|
47
|
+
| Subtitles / captions | ✅ |
|
|
48
|
+
| Mobile gestures | ✅ |
|
|
49
|
+
| Theater mode | ✅ |
|
|
50
|
+
| Mini player | ✅ |
|
|
51
|
+
| Picture-in-Picture | ✅ |
|
|
52
|
+
| Screenshot capture | ✅ |
|
|
53
|
+
| AirPlay support | ✅ |
|
|
54
|
+
| Custom SVG icons | ✅ |
|
|
55
|
+
| CSS theming | ✅ |
|
|
56
|
+
| `::part` styling | ✅ |
|
|
57
|
+
| Lazy loading | ✅ |
|
|
58
|
+
| Resume playback | ✅ |
|
|
38
59
|
|
|
39
|
-
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
# ⚡ Quick Start
|
|
63
|
+
|
|
64
|
+
## Install
|
|
40
65
|
|
|
41
66
|
```bash
|
|
42
|
-
npm install shadow-plyr
|
|
67
|
+
npm install @elementmints/shadow-plyr
|
|
43
68
|
```
|
|
44
69
|
|
|
45
|
-
|
|
70
|
+
Import the component:
|
|
46
71
|
|
|
47
72
|
```ts
|
|
48
|
-
import
|
|
73
|
+
import "@elementmints/shadow-plyr";
|
|
49
74
|
```
|
|
50
75
|
|
|
51
76
|
---
|
|
52
77
|
|
|
53
|
-
##
|
|
78
|
+
## Or use CDN
|
|
54
79
|
|
|
55
80
|
```html
|
|
56
|
-
<script type="module" src="https://unpkg.com/shadow-plyr/dist/shadow-plyr.js"></script>
|
|
81
|
+
<script type="module" src="https://unpkg.com/@elementmints/shadow-plyr@2.2.0/dist/shadow-plyr.js"></script>
|
|
57
82
|
```
|
|
58
83
|
|
|
59
84
|
---
|
|
@@ -64,8 +89,22 @@ import 'shadow-plyr';
|
|
|
64
89
|
<shadow-plyr
|
|
65
90
|
desktop-video="video.mp4"
|
|
66
91
|
desktop-poster="poster.jpg"
|
|
67
|
-
show-controls="true"
|
|
68
|
-
|
|
92
|
+
show-controls="true">
|
|
93
|
+
</shadow-plyr>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
# 🖼 Poster with `<picture>`
|
|
99
|
+
|
|
100
|
+
Art-directed responsive posters are supported.
|
|
101
|
+
|
|
102
|
+
```html
|
|
103
|
+
<shadow-plyr>
|
|
104
|
+
<picture>
|
|
105
|
+
<source media="(max-width:768px)" srcset="mobile-poster.jpg">
|
|
106
|
+
<img src="desktop-poster.jpg" alt="Poster">
|
|
107
|
+
</picture>
|
|
69
108
|
</shadow-plyr>
|
|
70
109
|
```
|
|
71
110
|
|
|
@@ -74,38 +113,57 @@ import 'shadow-plyr';
|
|
|
74
113
|
# 📱 Mobile Gestures
|
|
75
114
|
|
|
76
115
|
| Gesture | Action |
|
|
77
|
-
|
|
78
|
-
| Double tap left |
|
|
116
|
+
|------|------|
|
|
117
|
+
| Double tap left | −10 seconds |
|
|
79
118
|
| Double tap right | +10 seconds |
|
|
80
|
-
| Triple tap left |
|
|
119
|
+
| Triple tap left | −30 seconds |
|
|
81
120
|
| Triple tap right | +30 seconds |
|
|
82
|
-
|
|
|
83
|
-
|
|
|
121
|
+
| Tap video | Play / pause |
|
|
122
|
+
| Seekbar drag | Scrub |
|
|
84
123
|
|
|
85
124
|
---
|
|
86
125
|
|
|
87
|
-
#
|
|
126
|
+
# 🎬 Quality Switching
|
|
88
127
|
|
|
89
|
-
|
|
128
|
+
Provide multiple sources using `data-quality`.
|
|
90
129
|
|
|
91
130
|
```html
|
|
92
|
-
<shadow-plyr
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
131
|
+
<shadow-plyr show-quality="true">
|
|
132
|
+
|
|
133
|
+
<source src="video-1080.mp4"
|
|
134
|
+
type="video/mp4"
|
|
135
|
+
data-quality="1080">
|
|
136
|
+
|
|
137
|
+
<source src="video-720.mp4"
|
|
138
|
+
type="video/mp4"
|
|
139
|
+
data-quality="720">
|
|
140
|
+
|
|
141
|
+
<source src="video-480.mp4"
|
|
142
|
+
type="video/mp4"
|
|
143
|
+
data-quality="480">
|
|
144
|
+
|
|
145
|
+
</shadow-plyr>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
# 📺 Subtitles
|
|
151
|
+
|
|
152
|
+
```html
|
|
153
|
+
<shadow-plyr show-subtitles="true">
|
|
154
|
+
|
|
155
|
+
<track
|
|
156
|
+
src="subtitles-en.vtt"
|
|
157
|
+
kind="subtitles"
|
|
158
|
+
srclang="en"
|
|
159
|
+
label="English">
|
|
160
|
+
|
|
103
161
|
</shadow-plyr>
|
|
104
162
|
```
|
|
105
163
|
|
|
106
164
|
---
|
|
107
165
|
|
|
108
|
-
|
|
166
|
+
# 🎛 Controls
|
|
109
167
|
|
|
110
168
|
```html
|
|
111
169
|
<shadow-plyr
|
|
@@ -115,13 +173,16 @@ import 'shadow-plyr';
|
|
|
115
173
|
show-volume="true"
|
|
116
174
|
show-fullscreen="true"
|
|
117
175
|
show-speed="true"
|
|
118
|
-
|
|
176
|
+
show-quality="true"
|
|
177
|
+
show-subtitles="true"
|
|
178
|
+
show-mini-player="true"
|
|
179
|
+
show-theater-mode="true">
|
|
119
180
|
</shadow-plyr>
|
|
120
181
|
```
|
|
121
182
|
|
|
122
183
|
---
|
|
123
184
|
|
|
124
|
-
|
|
185
|
+
# 👆 Gestures
|
|
125
186
|
|
|
126
187
|
```html
|
|
127
188
|
<shadow-plyr
|
|
@@ -133,117 +194,84 @@ import 'shadow-plyr';
|
|
|
133
194
|
</shadow-plyr>
|
|
134
195
|
```
|
|
135
196
|
|
|
136
|
-
Disable triple tap:
|
|
137
|
-
|
|
138
|
-
```html
|
|
139
|
-
<shadow-plyr triple-tap-seek="false"></shadow-plyr>
|
|
140
|
-
```
|
|
141
|
-
|
|
142
197
|
---
|
|
143
198
|
|
|
144
|
-
|
|
199
|
+
# 🧠 Performance Features
|
|
145
200
|
|
|
146
201
|
```html
|
|
147
202
|
<shadow-plyr
|
|
148
|
-
|
|
149
|
-
|
|
203
|
+
lazy="true"
|
|
204
|
+
pause-on-out-of-view="true"
|
|
205
|
+
pause-on-tab-hide="true"
|
|
206
|
+
single-active="true">
|
|
150
207
|
</shadow-plyr>
|
|
151
208
|
```
|
|
152
209
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
## ⚡ Performance Mode
|
|
156
|
-
|
|
157
|
-
```html
|
|
158
|
-
<shadow-plyr performance-mode="true"></shadow-plyr>
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
Optimized for pages with many videos.
|
|
210
|
+
These options improve performance on **video-heavy pages**.
|
|
162
211
|
|
|
163
212
|
---
|
|
164
213
|
|
|
165
|
-
|
|
214
|
+
# 🎨 Theming
|
|
166
215
|
|
|
167
216
|
```html
|
|
168
217
|
<shadow-plyr
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
lazy-threshold="0.5"
|
|
173
|
-
pause-threshold="0.3">
|
|
218
|
+
theme="dark"
|
|
219
|
+
accent-color="#ff3b30"
|
|
220
|
+
controls-background="rgba(0,0,0,0.9)">
|
|
174
221
|
</shadow-plyr>
|
|
175
222
|
```
|
|
176
223
|
|
|
177
224
|
---
|
|
178
225
|
|
|
179
|
-
|
|
226
|
+
# 🎨 CSS Variables
|
|
180
227
|
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
```
|
|
228
|
+
```css
|
|
229
|
+
shadow-plyr {
|
|
184
230
|
|
|
185
|
-
|
|
231
|
+
--accent-color: #00ffcc;
|
|
186
232
|
|
|
187
|
-
|
|
233
|
+
--controls-bg: rgba(0,0,0,0.95);
|
|
188
234
|
|
|
189
|
-
#
|
|
235
|
+
--tooltip-bg: #333;
|
|
190
236
|
|
|
191
|
-
|
|
237
|
+
--tooltip-color: #fff;
|
|
192
238
|
|
|
193
|
-
|
|
194
|
-
<shadow-plyr
|
|
195
|
-
theme="dark"
|
|
196
|
-
accent-color="#ff3b30"
|
|
197
|
-
controls-background="rgba(0,0,0,0.9)"
|
|
198
|
-
center-play-background="rgba(0,0,0,0.8)"
|
|
199
|
-
center-play-size="100">
|
|
200
|
-
</shadow-plyr>
|
|
239
|
+
}
|
|
201
240
|
```
|
|
202
241
|
|
|
203
|
-
|
|
242
|
+
---
|
|
204
243
|
|
|
205
|
-
|
|
206
|
-
<shadow-plyr theme="light"></shadow-plyr>
|
|
207
|
-
```
|
|
244
|
+
# 🎨 Styling with `::part`
|
|
208
245
|
|
|
209
|
-
|
|
246
|
+
```css
|
|
247
|
+
shadow-plyr::part(play-pause) {
|
|
210
248
|
|
|
211
|
-
|
|
249
|
+
background: red;
|
|
212
250
|
|
|
213
|
-
|
|
251
|
+
border-radius: 50%;
|
|
214
252
|
|
|
215
|
-
```css
|
|
216
|
-
shadow-plyr {
|
|
217
|
-
--accent-color: #00ffcc;
|
|
218
|
-
--controls-bg: rgba(0,0,0,0.95);
|
|
219
|
-
--center-play-size: 90px;
|
|
220
253
|
}
|
|
221
254
|
```
|
|
222
255
|
|
|
223
256
|
---
|
|
224
257
|
|
|
225
|
-
# 🧩 Custom
|
|
258
|
+
# 🧩 Custom Icons
|
|
226
259
|
|
|
227
260
|
```html
|
|
228
261
|
<shadow-plyr
|
|
229
|
-
play-icon=
|
|
230
|
-
pause-icon=
|
|
231
|
-
volume-icon="<svg>...</svg>"
|
|
232
|
-
muted-icon="<svg>...</svg>"
|
|
233
|
-
fullscreen-icon="<svg>...</svg>"
|
|
234
|
-
exit-fullscreen-icon="<svg>...</svg>"
|
|
235
|
-
speed-icon="<svg>...</svg>">
|
|
262
|
+
play-icon='<svg viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>'
|
|
263
|
+
pause-icon='<svg viewBox="0 0 24 24"><path d="M6 19h4V5H6z"/></svg>'>
|
|
236
264
|
</shadow-plyr>
|
|
237
265
|
```
|
|
238
266
|
|
|
239
|
-
|
|
267
|
+
SVG icons are automatically **sanitized with DOMPurify**.
|
|
240
268
|
|
|
241
269
|
---
|
|
242
270
|
|
|
243
271
|
# 🧑💻 JavaScript API
|
|
244
272
|
|
|
245
273
|
```ts
|
|
246
|
-
const player = document.querySelector(
|
|
274
|
+
const player = document.querySelector("shadow-plyr");
|
|
247
275
|
|
|
248
276
|
player.play();
|
|
249
277
|
player.pause();
|
|
@@ -252,147 +280,95 @@ player.unmute();
|
|
|
252
280
|
player.seek(120);
|
|
253
281
|
```
|
|
254
282
|
|
|
283
|
+
### Properties
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
player.currentTime
|
|
287
|
+
player.duration
|
|
288
|
+
player.volume
|
|
289
|
+
player.muted
|
|
290
|
+
player.playing
|
|
291
|
+
```
|
|
292
|
+
|
|
255
293
|
---
|
|
256
294
|
|
|
257
295
|
# 📡 Events
|
|
258
296
|
|
|
259
297
|
```ts
|
|
260
|
-
player.addEventListener(
|
|
261
|
-
console.log(
|
|
298
|
+
player.addEventListener("video-playing", e => {
|
|
299
|
+
console.log(e.detail.currentTime);
|
|
262
300
|
});
|
|
263
301
|
```
|
|
264
302
|
|
|
265
|
-
### Available Events
|
|
266
|
-
|
|
267
303
|
| Event | Description |
|
|
268
|
-
|
|
304
|
+
|------|------|
|
|
269
305
|
| video-ready | Metadata loaded |
|
|
270
306
|
| video-playing | Playback started |
|
|
271
307
|
| video-paused | Playback paused |
|
|
272
308
|
| video-ended | Playback ended |
|
|
273
309
|
| video-seeking | Seeking started |
|
|
274
310
|
| video-seeked | Seeking finished |
|
|
275
|
-
| video-volume-change | Volume
|
|
276
|
-
| video-error |
|
|
277
|
-
| video-fullscreen-enter | Enter fullscreen |
|
|
278
|
-
| video-fullscreen-exit | Exit fullscreen |
|
|
279
|
-
|
|
280
|
-
---
|
|
281
|
-
|
|
282
|
-
# 🧪 Real World Presets
|
|
283
|
-
|
|
284
|
-
---
|
|
285
|
-
|
|
286
|
-
## 🎬 Netflix Style
|
|
287
|
-
|
|
288
|
-
```html
|
|
289
|
-
<shadow-plyr
|
|
290
|
-
show-controls="true"
|
|
291
|
-
show-center-play="true"
|
|
292
|
-
double-tap-seek="true"
|
|
293
|
-
triple-tap-seek="true"
|
|
294
|
-
enable-tap-ripple="true"
|
|
295
|
-
theme="dark"
|
|
296
|
-
accent-color="#e50914">
|
|
297
|
-
</shadow-plyr>
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
---
|
|
301
|
-
|
|
302
|
-
## 📱 Minimal Mobile Player
|
|
303
|
-
|
|
304
|
-
```html
|
|
305
|
-
<shadow-plyr
|
|
306
|
-
show-controls="false"
|
|
307
|
-
show-center-play="true"
|
|
308
|
-
double-tap-seek="true"
|
|
309
|
-
triple-tap-seek="false">
|
|
310
|
-
</shadow-plyr>
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## 🎨 Brand Custom Player
|
|
316
|
-
|
|
317
|
-
```html
|
|
318
|
-
<shadow-plyr
|
|
319
|
-
theme="light"
|
|
320
|
-
accent-color="#6c5ce7"
|
|
321
|
-
controls-background="rgba(255,255,255,0.95)"
|
|
322
|
-
center-play-background="rgba(255,255,255,0.8)">
|
|
323
|
-
</shadow-plyr>
|
|
324
|
-
```
|
|
311
|
+
| video-volume-change | Volume change |
|
|
312
|
+
| video-error | Playback error |
|
|
325
313
|
|
|
326
314
|
---
|
|
327
315
|
|
|
328
316
|
# 🌍 Browser Support
|
|
329
317
|
|
|
330
318
|
| Browser | Supported |
|
|
331
|
-
|
|
319
|
+
|------|------|
|
|
332
320
|
| Chrome | ✅ |
|
|
333
321
|
| Edge | ✅ |
|
|
334
322
|
| Safari | ✅ |
|
|
323
|
+
| Firefox | ✅ |
|
|
335
324
|
| iOS Safari | ✅ |
|
|
336
325
|
| Android Chrome | ✅ |
|
|
337
|
-
| Firefox | ✅ |
|
|
338
326
|
|
|
339
327
|
---
|
|
340
328
|
|
|
341
329
|
# 🏗 Built With
|
|
342
330
|
|
|
343
331
|
- Web Components
|
|
344
|
-
- Shadow DOM
|
|
345
332
|
- TypeScript
|
|
333
|
+
- Shadow DOM
|
|
346
334
|
- Constructable Stylesheets
|
|
347
335
|
- DOMPurify
|
|
336
|
+
- hls.js (optional)
|
|
348
337
|
|
|
349
338
|
---
|
|
350
339
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
This project follows a structured Git workflow:
|
|
354
|
-
|
|
355
|
-
### Branches
|
|
356
|
-
|
|
357
|
-
- `master` → Stable production releases
|
|
358
|
-
- `develop` → Integration branch (active development)
|
|
359
|
-
- `feature/*` → New features
|
|
360
|
-
- `fix/*` → Bug fixes
|
|
361
|
-
- `release/*` → Release preparation
|
|
362
|
-
- `hotfix/*` → Emergency production fixes
|
|
363
|
-
|
|
364
|
-
### Contribution Flow
|
|
340
|
+
# 🤝 Contributing
|
|
365
341
|
|
|
366
342
|
1. Fork the repository
|
|
367
|
-
2. Create a feature branch:
|
|
368
|
-
```bash
|
|
369
|
-
git checkout -b feature/your-feature-name
|
|
370
343
|
|
|
371
|
-
|
|
344
|
+
2. Create a feature branch
|
|
372
345
|
|
|
373
|
-
|
|
346
|
+
```bash
|
|
347
|
+
git checkout -b feature/my-feature
|
|
348
|
+
```
|
|
374
349
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
4. Open PR
|
|
350
|
+
3. Commit your changes
|
|
351
|
+
|
|
352
|
+
4. Open a Pull Request
|
|
379
353
|
|
|
380
354
|
---
|
|
381
355
|
|
|
382
356
|
# 📄 License
|
|
383
357
|
|
|
384
|
-
MIT
|
|
358
|
+
MIT © Element Mint
|
|
385
359
|
|
|
386
360
|
---
|
|
387
361
|
|
|
388
362
|
# ⭐ Why Shadow Plyr?
|
|
389
363
|
|
|
390
|
-
|
|
364
|
+
The native `<video>` element provides only basic controls.
|
|
365
|
+
|
|
366
|
+
Shadow Plyr delivers:
|
|
391
367
|
|
|
392
|
-
|
|
368
|
+
- Modern gesture controls
|
|
369
|
+
- Adaptive streaming
|
|
370
|
+
- Full UI customization
|
|
371
|
+
- Performance optimizations
|
|
372
|
+
- Clean Web Component architecture
|
|
393
373
|
|
|
394
|
-
-
|
|
395
|
-
- Modern mobile gestures
|
|
396
|
-
- Performance optimization
|
|
397
|
-
- Clean architecture
|
|
398
|
-
- Production-ready UX
|
|
374
|
+
All inside a **lightweight, zero-dependency video player**.
|