@smartimpact-it/modern-video-embed 2.0.5 → 2.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.
Files changed (65) hide show
  1. package/README.md +322 -71
  2. package/dist/components/BaseVideoEmbed.d.ts +91 -0
  3. package/dist/components/BaseVideoEmbed.d.ts.map +1 -0
  4. package/dist/components/BaseVideoEmbed.js +275 -0
  5. package/dist/components/BaseVideoEmbed.js.map +1 -0
  6. package/dist/components/VideoEmbed.d.ts +68 -0
  7. package/dist/components/VideoEmbed.d.ts.map +1 -0
  8. package/dist/components/VideoEmbed.js +786 -0
  9. package/dist/components/VideoEmbed.js.map +1 -0
  10. package/dist/components/VimeoEmbed.d.ts +26 -36
  11. package/dist/components/VimeoEmbed.d.ts.map +1 -1
  12. package/dist/components/VimeoEmbed.js +231 -326
  13. package/dist/components/VimeoEmbed.js.map +1 -1
  14. package/dist/components/VimeoEmbed.min.js +1 -1
  15. package/dist/components/YouTubeEmbed.d.ts +108 -42
  16. package/dist/components/YouTubeEmbed.d.ts.map +1 -1
  17. package/dist/components/YouTubeEmbed.js +361 -375
  18. package/dist/components/YouTubeEmbed.js.map +1 -1
  19. package/dist/components/YouTubeEmbed.min.js +1 -1
  20. package/dist/css/components.css +285 -68
  21. package/dist/css/components.css.map +1 -1
  22. package/dist/css/components.min.css +1 -1
  23. package/dist/css/main.css +285 -68
  24. package/dist/css/main.css.map +1 -1
  25. package/dist/css/main.min.css +1 -1
  26. package/dist/index.d.ts +1 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +1 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/index.min.js +1 -1
  31. package/dist/types/index.d.ts +1 -0
  32. package/dist/types/index.d.ts.map +1 -1
  33. package/dist/video-only.d.ts +7 -0
  34. package/dist/video-only.d.ts.map +1 -0
  35. package/dist/video-only.js +8 -0
  36. package/dist/video-only.js.map +1 -0
  37. package/dist/vimeo-only.d.ts +2 -2
  38. package/dist/vimeo-only.d.ts.map +1 -1
  39. package/dist/vimeo-only.js +2 -2
  40. package/dist/vimeo-only.js.map +1 -1
  41. package/dist/vimeo-only.min.js +1 -1
  42. package/dist/youtube-only.d.ts +2 -2
  43. package/dist/youtube-only.d.ts.map +1 -1
  44. package/dist/youtube-only.js +2 -2
  45. package/dist/youtube-only.js.map +1 -1
  46. package/dist/youtube-only.min.js +1 -1
  47. package/package.json +6 -5
  48. package/src/components/BaseVideoEmbed.ts +335 -0
  49. package/src/components/VideoEmbed.ts +870 -0
  50. package/src/components/VideoEmbed.ts.backup +1051 -0
  51. package/src/components/VimeoEmbed.ts +258 -395
  52. package/src/components/YouTubeEmbed.ts +378 -432
  53. package/src/index.ts +1 -0
  54. package/src/styles/_embed-base.scss +275 -0
  55. package/src/styles/_shared-functions.scss +56 -0
  56. package/src/styles/components.scss +4 -3
  57. package/src/styles/main.scss +7 -5
  58. package/src/styles/video-embed.scss +55 -0
  59. package/src/styles/vimeo-embed.scss +8 -248
  60. package/src/styles/youtube-embed.scss +8 -254
  61. package/src/types/index.ts +1 -0
  62. package/src/types/video-embed.d.ts +90 -0
  63. package/src/video-only.ts +9 -0
  64. package/src/vimeo-only.ts +2 -2
  65. package/src/youtube-only.ts +2 -2
package/README.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # Video Embed Components
2
2
 
3
- Modern, performant YouTube and Vimeo embed web components with lazy loading, event-driven architecture, and comprehensive API control.
3
+ Modern, performant YouTube, Vimeo, and HTML5 video embed web components with lazy loading, event-driven architecture, and comprehensive API control.
4
+
5
+ ## 📋 Quick Reference
6
+
7
+ | Component | Best For | Bundle Size (Min) | External API |
8
+ | ----------------- | ------------------ | ----------------- | ------------------ |
9
+ | `<youtube-embed>` | YouTube videos | 15KB | YouTube iframe API |
10
+ | `<vimeo-embed>` | Vimeo videos | 14KB | Vimeo Player API |
11
+ | `<video-embed>` | Self-hosted videos | 12KB | Native HTML5 |
12
+
13
+ **Need help?** See [AI Instructions](.ai-instructions.md) for development guidance.
4
14
 
5
15
  ## ✨ Features
6
16
 
@@ -11,9 +21,43 @@ Modern, performant YouTube and Vimeo embed web components with lazy loading, eve
11
21
  - **📱 Responsive** - Mobile-first design with touch-friendly controls
12
22
  - **♿ Accessible** - Keyboard navigation and screen reader support
13
23
  - **🎨 Customizable** - Custom overlay controls or native player controls
14
- - **🎬 Multi-Platform** - Both YouTube and Vimeo support
24
+ - **🎬 Multi-Platform** - YouTube, Vimeo, and self-hosted HTML5 video support
15
25
 
16
- ## 🚀 Quick Start
26
+ ## Project Structure
27
+
28
+ ```
29
+ si_video_embed/
30
+ ├── src/
31
+ │ ├── components/ # Web Components
32
+ │ │ ├── BaseVideoEmbed.ts # Abstract base class (shared functionality)
33
+ │ │ ├── YouTubeEmbed.ts # YouTube iframe component
34
+ │ │ ├── VimeoEmbed.ts # Vimeo iframe component
35
+ │ │ └── VideoEmbed.ts # Native HTML5 video component
36
+ │ ├── types/ # TypeScript type definitions
37
+ │ └── styles/ # SCSS stylesheets
38
+ │ ├── _shared-functions.scss # Reusable SVG encoding functions
39
+ │ ├── _embed-base.scss # Shared component mixins
40
+ │ ├── youtube-embed.scss # YouTube-specific styles
41
+ │ ├── vimeo-embed.scss # Vimeo-specific styles
42
+ │ └── video-embed.scss # Video-specific styles
43
+ ├── dist/ # Compiled output (auto-generated)
44
+ │ ├── index.js/.min.js # Full bundle (YouTube + Vimeo + Video)
45
+ │ ├── youtube-only.js # YouTube-only bundle (15KB min)
46
+ │ ├── vimeo-only.js # Vimeo-only bundle (14KB min)
47
+ │ ├── video-only.js # Native video-only bundle (12KB min)
48
+ │ └── css/ # Compiled styles
49
+ ├── examples/ # Live demos and usage examples
50
+ ├── test/ # Automated test suite (67+ tests)
51
+ └── scripts/ # Build validation and cache-busting scripts
52
+ ```
53
+
54
+ **Key Files:**
55
+
56
+ - `.ai-instructions.md` - Development guide for AI agents and contributors
57
+ - `package.json` - NPM scripts and dependencies
58
+ - `tsconfig.json` - TypeScript configuration (strict mode)
59
+
60
+ ## �🚀 Quick Start
17
61
 
18
62
  ### Installation
19
63
 
@@ -25,14 +69,16 @@ npm install @smartimpact-it/modern-video-embed
25
69
 
26
70
  #### Via CDN (for quick prototypes)
27
71
 
28
- ```html
29
- <script
30
- type="module"
31
- src="https://unpkg.com/@smartimpact-it/modern-video-embed@latest/dist/index.js"
32
- ></script>
33
- <link
34
- rel="stylesheet"
35
- href="https://unpkg.com/@smartimpact-it/modern-video-embed@latest/dist/css/components.css"
72
+ ```html |
73
+ | ----------------- | ------------------------- | ---------- | ----------- |
74
+ ----------------------- | | **Full** | `dist/index.js` | 58KB | **29KB** | All
75
+ three components | | **YouTube Only** | `dist/youtube-only.js` | 29KB | **15KB**
76
+ | Only YouTube embeds | | **Vimeo Only** | `dist/vimeo-only.js` | 29KB |
77
+ **14KB** | Only Vimeo embeds | | **Video Only** | `dist/video-only.js` | 24KB |
78
+ **12KB** | Only HTML5 video embeds | | **Styles (Core)** |
79
+ `dist/css/components.css` | 9KB | **7KB** | Component styles only | | **Styles
80
+ (Full)** | `dist/css/main.css` | 276KB | **224KB** | With Bootstrap (demos)
81
+ href="https://unpkg.com/@smartimpact-it/modern-video-embed@latest/dist/css/components.css"
36
82
  />
37
83
  ```
38
84
 
@@ -126,6 +172,20 @@ Choose the right bundle for your needs:
126
172
  <vimeo-embed url="https://vimeo.com/76979871" controls> </vimeo-embed>
127
173
  ```
128
174
 
175
+ # HTML5 Video (Self-hosted)
176
+
177
+ ```html
178
+ <!-- Use in HTML with self-hosted videos -->
179
+ <video-embed
180
+ url="https://example.com/videos/demo.mp4"
181
+ controls
182
+ poster="thumbnail.jpg"
183
+ >
184
+ </video-embed>
185
+ ```
186
+
187
+ ###
188
+
129
189
  ### Advanced Usage
130
190
 
131
191
  #### YouTube
@@ -144,17 +204,34 @@ Choose the right bundle for your needs:
144
204
 
145
205
  #### Vimeo
146
206
 
147
- ```html
207
+ ````html
148
208
  <!-- Lazy loading with custom poster -->
149
209
  <vimeo-embed
150
- video-id="123456789"
210
+ ## HTML5 Video
211
+
212
+ ```html
213
+ <!-- Self-hostedAll Components)
214
+
215
+ | Attribute | Type | YouTube | Vimeo | Video | Description |
216
+ | ------------- | ------- | ------- | ----- | ----- | -------------------------------------------- |
217
+ | `url` | String | ✅ | ✅ | ✅ | Full video URL |
218
+ | `video-id` | String | ✅ | ✅ | ❌ | Video ID (YouTube: 11 chars, Vimeo: numeric) |
219
+ | `autoplay` | Boolean | ✅ | ✅ | ✅ | Auto-play video when loaded |
220
+ | `controls` | Boolean | ✅ | ✅ | ✅ | Show native player controls |
221
+ | `lazy` | Boolean | ✅ | ✅ | ✅ | Enable lazy loading with poster |
222
+ | `muted` | Boolean | ✅ | ✅ | ✅ | Start video muted |
223
+ | `poster` | String | ✅ | ✅ | ✅ | Custom poster image URL |
224
+ | `background` | Boolean | ✅ | ✅ | ✅ | Enable background video mode |
225
+ | `player-vars` | JSON | ✅ | ✅ | ❌ | JSON object of extra player parameters |
226
+ | `loop` | Boolean | ❌ | ❌ | ✅ | Loop video (native video only) |
227
+ | `preload` | String | ❌ | ❌ | ✅ | Preload strategy: "none", "metadata", "auto"
151
228
  lazy
152
229
  autoplay
153
230
  muted
154
231
  poster="custom-poster.jpg"
155
232
  >
156
233
  </vimeo-embed>
157
- ```
234
+ ````
158
235
 
159
236
  ## 📖 API Reference
160
237
 
@@ -179,16 +256,25 @@ Choose the right bundle for your needs:
179
256
  ```javascript
180
257
  const embed = document.querySelector("youtube-embed");
181
258
 
182
- // Playback control
183
- embed.play(); // ▶️ Play video
184
- embed.pause(); // ⏸️ Pause video
185
- embed.stopVideo(); // ⏹️ Stop video
259
+ // Playback control (wraps YouTube IFrame API Player methods)
260
+ // Reference: https://developers.google.com/youtube/iframe_api_reference#Playback_controls
261
+ embed.play(); // ▶️ Play video (calls playVideo())
262
+ embed.pause(); // ⏸️ Pause video (calls pauseVideo())
263
+ embed.stopVideo(); // ⏹️ Stop video (calls stopVideo())
186
264
  embed.togglePlay(); // ⏯️ Toggle play/pause
187
265
 
188
266
  // Audio control
189
- embed.mute(); // 🔇 Mute audio
190
- embed.unmute(); // 🔊 Unmute audio
267
+ // Reference: https://developers.google.com/youtube/iframe_api_reference#Playback_volume
268
+ embed.mute(); // 🔇 Mute audio (calls mute())
269
+ embed.unmute(); // 🔊 Unmute audio (calls unMute())
191
270
  embed.toggleMute(); // 🔇 Toggle mute
271
+ const isMuted = embed.isMuted(); // Check if muted (calls isMuted())
272
+
273
+ // Playback time control
274
+ // Reference: https://developers.google.com/youtube/iframe_api_reference#Playback_status
275
+ const currentTime = embed.getCurrentTime(); // Get current time in seconds (calls getCurrentTime())
276
+ embed.seekTo(30); // Seek to 30 seconds (calls seekTo())
277
+ embed.currentTime = 45; // Seek to 45 seconds using property setter
192
278
 
193
279
  // Video management
194
280
  embed.loadVideo("dQw4w9WgXcQ"); // Load by video ID
@@ -198,10 +284,12 @@ embed.loadVideo("https://youtu.be/dQw4w9WgXcQ"); // Load by URL
198
284
  const state = embed.getPlayerState();
199
285
  // Returns: { playing: boolean, muted: boolean, videoId: string, ready: boolean, initialized: boolean }
200
286
 
201
- // Quality control
202
- const qualities = embed.getAvailableQualities(); // Get available quality levels
203
- const current = embed.getCurrentQuality(); // Get current quality
204
- embed.setQuality("hd1080"); // Set quality to 1080p
287
+ // Quality control (DEPRECATED as of October 2019 - YouTube controls quality automatically)
288
+ // Reference: https://developers.google.com/youtube/iframe_api_reference#Playback_quality
289
+ // WARNING: These methods are NO-OPS and have no effect on YouTube videos
290
+ const qualities = embed.getAvailableQualities(); // ⚠️ DEPRECATED - Returns empty array
291
+ const current = embed.getCurrentQuality(); // ⚠️ DEPRECATED - Returns "auto"
292
+ embed.setQuality("hd1080"); // ⚠️ DEPRECATED - Does nothing (no-op function)
205
293
 
206
294
  // Fullscreen control
207
295
  embed.enterFullscreen(); // Enter fullscreen mode
@@ -210,12 +298,15 @@ embed.toggleFullscreen(); // Toggle fullscreen
210
298
  const isFs = embed.isFullscreen(); // Check fullscreen state
211
299
 
212
300
  // Set extra player parameters
301
+ // Reference: https://developers.google.com/youtube/player_parameters
213
302
  embed.playerVars = { loop: 1, playlist: "dQw4w9WgXcQ" };
214
303
  ```
215
304
 
216
305
  **Passing Extra Parameters:**
217
306
 
218
- You can pass additional parameters to the YouTube or Vimeo player using the `player-vars` attribute or `playerVars` property:
307
+ You can pass additional parameters to the YouTube or Vimeo player using the `player-vars` attribute or `playerVars` property.
308
+
309
+ For YouTube, see the [YouTube Player Parameters Reference](https://developers.google.com/youtube/player_parameters) for all available options.
219
310
 
220
311
  ```html
221
312
  <!-- YouTube: Loop a video -->
@@ -289,7 +380,7 @@ const isFs = embed.isFullscreen(); // Check fullscreen state
289
380
 
290
381
  You can pass additional parameters to the Vimeo player using the `player-vars` attribute or `playerVars` property:
291
382
 
292
- ```html
383
+ ````html
293
384
  <!-- Vimeo: Loop a video -->
294
385
  <vimeo-embed video-id="76979871" player-vars='{"loop": true}'></vimeo-embed>
295
386
 
@@ -304,7 +395,57 @@ You can pass additional parameters to the Vimeo player using the `player-vars` a
304
395
  video-id="76979871"
305
396
  player-vars='{"dnt": true, "title": false, "byline": false, "portrait": false}'
306
397
  ></vimeo-embed>
307
- ```
398
+ ```# Video Embed (HTML5) All three components support the same event interface:
399
+ ```javascript // Listen to player events (works for youtube-embed, vimeo-embed,
400
+ and video-embed) embed.addEventListener("ready", () => console.log("Player
401
+ ready")); embed.addEventListener("play", () => console.log("Playing"));
402
+ embed.addEventListener("pause", () => console.log("Paused"));
403
+ embed.addEventListener("ended", () => console.log("Video ended"));
404
+ embed.addEventListener("error", (e) => console.error("Error:", e.detail));
405
+ embed.addEventListener("qualitychange", (e) => { console.log( "Quality
406
+ changed:", e.detail.oldQuality, "→", e.detail.newQuality, );
407
+ console.log("Available qualities:", e.detail.availableQualities); });
408
+ ````
409
+
410
+ **Supported Events:**
411
+
412
+ - `ready` - Player initialized and ready to use (wraps YouTube's [`onReady`](https://developers.google.com/youtube/iframe_api_reference#onReady))
413
+ - `play` - Video playback started (wraps YouTube's [`onStateChange`](https://developers.google.com/youtube/iframe_api_reference#onStateChange) with state `YT.PlayerState.PLAYING`)
414
+ - `pause` - Video playback paused (wraps `onStateChange` with state `YT.PlayerState.PAUSED`)
415
+ - `stop` - Video playback stopped
416
+ - `ended` - Video playback finished (wraps `onStateChange` with state `YT.PlayerState.ENDED`)
417
+ - `error` - An error occurred (wraps YouTube's [`onError`](https://developers.google.com/youtube/iframe_api_reference#onError), check `event.detail` for details)
418
+ - `timeupdate` - Current time position updated
419
+ - `qualitychange` - Video quality level changed (wraps YouTube's [`onPlaybackQualityChange`](https://developers.google.com/youtube/iframe_api_reference#onPlaybackQualityChange))
420
+ - `loadstart` - Video loading started (native video)
421
+ - `connected` - Component connected to DOM
422
+ - `disconnected` - Component disconnected from DOMst state = embed.getPlayerState();
423
+ // Returns: { playing: boolean, muted: boolean, videoId: string, ready: boolean, initialized: boolean }
424
+
425
+ const currentTime = embed.getCurrentTime();
426
+ const isMuted = embed.isMuted();
427
+
428
+ // Native video attributes
429
+ embed.loop = true; // Enable looping
430
+ embed.preload = "metadata"; // Set preload strategy
431
+
432
+ ````
433
+
434
+ **Native HTML5 Video Attributes:**
435
+
436
+ ```html
437
+ <!-- HTML5-specific attributes -->
438
+ <video-embed
439
+ url="video.mp4"
440
+ loop
441
+ preload="metadata"
442
+ controls
443
+ poster="thumb.jpg"
444
+ >
445
+ </video-embed>
446
+ ````
447
+
448
+ ###
308
449
 
309
450
  ```javascript
310
451
  // Set via JavaScript
@@ -347,7 +488,13 @@ embed.addEventListener("qualitychange", (e) => {
347
488
 
348
489
  Both components support programmatic quality control and emit events when quality changes.
349
490
 
350
- #### YouTube Quality Levels
491
+ **⚠️ IMPORTANT: YouTube Quality APIs Deprecated (October 2019)**
492
+
493
+ YouTube deprecated manual quality control methods as of October 24, 2019. The quality methods for YouTube (`getAvailableQualities()`, `getCurrentQuality()`, `setQuality()`) are **no-op functions** that have no effect. YouTube now automatically adjusts quality based on network conditions. See the [YouTube Help Center](https://support.google.com/youtube/answer/91449) for details.
494
+
495
+ **Use Vimeo or HTML5 Video if you need manual quality control.**
496
+
497
+ #### YouTube Quality Levels (Reference Only - APIs Deprecated)
351
498
 
352
499
  | Quality Level | Resolution | Description |
353
500
  | ------------- | ---------- | ------------------- |
@@ -379,18 +526,20 @@ Both components support programmatic quality control and emit events when qualit
379
526
 
380
527
  ```html
381
528
  <!-- Set initial quality via attribute -->
529
+ <!-- WARNING: YouTube quality attribute is ignored (APIs deprecated Oct 2019) -->
382
530
  <youtube-embed video-id="dQw4w9WgXcQ" quality="hd1080"></youtube-embed>
531
+ <!-- Vimeo quality control works normally -->
383
532
  <vimeo-embed video-id="76979871" quality="720p"></vimeo-embed>
384
533
  ```
385
534
 
386
535
  ```javascript
387
- // YouTube quality control
536
+ // YouTube quality control (DEPRECATED - These are no-op functions)
388
537
  const ytEmbed = document.querySelector("youtube-embed");
389
- const qualities = ytEmbed.getAvailableQualities(); // ["auto", "hd1080", "hd720", "large", "medium"]
390
- const current = ytEmbed.getCurrentQuality(); // "hd720"
391
- ytEmbed.setQuality("hd1080"); // Switch to 1080p
538
+ const qualities = ytEmbed.getAvailableQualities(); // ⚠️ Returns empty array - DEPRECATED
539
+ const current = ytEmbed.getCurrentQuality(); // ⚠️ Returns "auto" - DEPRECATED
540
+ ytEmbed.setQuality("hd1080"); // ⚠️ Does nothing - DEPRECATED (no-op)
392
541
 
393
- // Vimeo quality control (async)
542
+ // Vimeo quality control (Works normally - async)
394
543
  const vimeoEmbed = document.querySelector("vimeo-embed");
395
544
  const qualities = await vimeoEmbed.getAvailableQualities(); // ["auto", "1080p", "720p", "540p"]
396
545
  const current = await vimeoEmbed.getCurrentQuality(); // "720p"
@@ -407,6 +556,32 @@ embed.addEventListener("qualitychange", (event) => {
407
556
  });
408
557
  ```
409
558
 
559
+ **⚠️ CRITICAL: YouTube Quality Control APIs Are DEPRECATED (October 2019)**
560
+
561
+ As of **October 24, 2019**, YouTube deprecated all manual quality control functions. According to the [official documentation update](https://developers.google.com/youtube/iframe_api_reference#Revision_History):
562
+
563
+ **These methods are NO LONGER FUNCTIONAL:**
564
+
565
+ - [`getPlaybackQuality()`](https://developers.google.com/youtube/iframe_api_reference#getPlaybackQuality) - No longer returns accurate quality information
566
+ - [`setPlaybackQuality()`](https://developers.google.com/youtube/iframe_api_reference#setPlaybackQuality) - **No-op function** (does nothing)
567
+ - [`getAvailableQualityLevels()`](https://developers.google.com/youtube/iframe_api_reference#getAvailableQualityLevels) - No longer returns quality options
568
+
569
+ **Why these were deprecated:**
570
+ YouTube now automatically adjusts video quality based on viewing conditions (network bandwidth, device capabilities, viewport size) to provide the best viewing experience. Manual quality selection interferes with YouTube's adaptive streaming algorithms.
571
+
572
+ **What still works:**
573
+
574
+ - [`onPlaybackQualityChange`](https://developers.google.com/youtube/iframe_api_reference#onPlaybackQualityChange) event - Still fires when YouTube automatically changes quality
575
+ - The `qualitychange` event in this library still works and reports YouTube's automatic quality changes
576
+
577
+ **For developers:**
578
+ The quality methods (`getAvailableQualities()`, `getCurrentQuality()`, `setQuality()`) are kept in this library for API compatibility but **have no effect** on YouTube videos. They are maintained only to prevent breaking existing code. Use the Vimeo or native HTML5 video components if manual quality control is required.
579
+
580
+ **Official YouTube Help Article:**
581
+ [Why does YouTube adjust video quality?](https://support.google.com/youtube/answer/91449)
582
+
583
+ Vimeo's quality control is more reliable and respects quality changes consistently.
584
+
410
585
  ### Error Handling
411
586
 
412
587
  Components include comprehensive error handling with automatic retry and user-friendly feedback:
@@ -430,12 +605,20 @@ embed.addEventListener("error", (e) => {
430
605
 
431
606
  #### Common Error Scenarios
432
607
 
433
- | Error Type | Cause | Solution |
434
- | -------------------- | -------------------------- | ------------------------------------ |
435
- | API Load Timeout | Ad blocker or slow network | Disable ad blocker, check connection |
436
- | Script Load Failed | Network issue or CORS | Verify internet connection |
437
- | Video Not Found | Invalid video ID | Check video ID/URL |
438
- | Embedding Restricted | Video owner restrictions | Use different video |
608
+ | Error Type | Cause | Solution |
609
+ | ------------------ | -------------------------- | ------------------------------------ |
610
+ | API Load Timeout | Ad blocker or slow network | Disable ad blocker, check connection |
611
+ | Script Load Failed | Network issue or CORS | Verify internet connection |
612
+ | Video Not Found | Invalid video ID | Check video ID/URL |
613
+
614
+ | EmHTML5 Video Demos:\*\*
615
+
616
+ - `video-basic-demo.html` - Self-hosted video usage
617
+ - `video-lazy-loading-demo.html` - Native video lazy loading
618
+ - `video-background-demo.html` - Background video patterns
619
+ - **`platform-comparison-demo.html`** - Side-by-side platform comparison
620
+ - **`quality-control-demo.html`** - Quality selection and switching
621
+ - **`fullscreen-accessibility-demo.html`** - Fullscreen and accessibility featureso |
439
622
 
440
623
  ### Accessibility
441
624
 
@@ -551,9 +734,26 @@ This component includes a comprehensive automated test suite to ensure reliabili
551
734
 
552
735
  - Initialization speed benchmarks (< 200ms target)
553
736
  - Memory leak detection
554
- - Resource optimization verification
555
- - Scalability testing (20+ instances)
556
- - Bundle size impact assessment
737
+ - Resource build:cache-bust`| Update cache-busting params | Updates query strings in files |
738
+ |`npm run test:build` | Build + ready message | One-command test preparation |
739
+ |`npm run test:validate` | Build + comprehensive check | Full environment validation |
740
+ |`npm run watch` | Watch mode (TypeScript + SCSS) | Auto-rebuild during development |
741
+ |`npm run examples` | Build + examples ready | Prepare examples for viewing |
742
+
743
+ #### Build Scripts
744
+
745
+ The project includes helper scripts in the `scripts/` directory:
746
+
747
+ - **`verify-build.js`** - Validates that all required build outputs exist and are valid
748
+ - Checks for compiled JS files (index.js, youtube-only.js, vimeo-only.js, video-only.js)
749
+ - Verifies CSS compilation (main.css, components.css)
750
+ - Ensures test files are accessible
751
+ - Automatically run as part of `npm run build`
752
+
753
+ - **`update-cache-busters.js`** - Updates cache-busting query parameters in built files
754
+ - Appends version-based timestamps to asset references
755
+ - Ensures browsers load fresh assets after updates
756
+ - Automatically run as part of `npm run build`
557
757
 
558
758
  ### Test Framework Features
559
759
 
@@ -714,8 +914,43 @@ For detailed testing documentation, see `test/README.md`.
714
914
 
715
915
  - Modern browsers with Web Components support
716
916
  - ES6+ JavaScript features
717
- - YouTube iframe API integration
718
- - Vimeo Player API integration
917
+ - YouTube IFrame API integration ([API Reference](https://developers.google.com/youtube/iframe_api_reference))
918
+ - Vimeo Player API integration ([API Reference](https://developer.vimeo.com/player/sdk/reference))
919
+
920
+ ### YouTube IFrame API Integration
921
+
922
+ The `<youtube-embed>` component wraps the [YouTube IFrame Player API](https://developers.google.com/youtube/iframe_api_reference) to provide a consistent, web-component-based interface.
923
+
924
+ **API Loading:**
925
+
926
+ - Dynamically loads `https://www.youtube.com/iframe_api`
927
+ - Implements retry mechanism (up to 3 attempts) for reliability
928
+ - Handles API initialization via `onYouTubeIframeAPIReady` callback
929
+ - 10-second timeout protection against blocked scripts
930
+
931
+ **Player Methods Used:**
932
+
933
+ - [`playVideo()`](https://developers.google.com/youtube/iframe_api_reference#playVideo) - Start video playback ✅
934
+ - [`pauseVideo()`](https://developers.google.com/youtube/iframe_api_reference#pauseVideo) - Pause video playback ✅
935
+ - [`stopVideo()`](https://developers.google.com/youtube/iframe_api_reference#stopVideo) - Stop video and reset ✅
936
+ - [`seekTo(seconds, allowSeekAhead)`](https://developers.google.com/youtube/iframe_api_reference#seekTo) - Seek to specific time ✅
937
+ - [`mute()`](https://developers.google.com/youtube/iframe_api_reference#mute) - Mute the player ✅
938
+ - [`unMute()`](https://developers.google.com/youtube/iframe_api_reference#unMute) - Unmute the player ✅
939
+ - [`isMuted()`](https://developers.google.com/youtube/iframe_api_reference#isMuted) - Check mute state ✅
940
+ - [`getCurrentTime()`](https://developers.google.com/youtube/iframe_api_reference#getCurrentTime) - Get current playback time ✅
941
+ - ~~[`getPlaybackQuality()`](https://developers.google.com/youtube/iframe_api_reference#getPlaybackQuality)~~ - ⚠️ **DEPRECATED Oct 2019** - No longer functional
942
+ - ~~[`setPlaybackQuality(suggestedQuality)`](https://developers.google.com/youtube/iframe_api_reference#setPlaybackQuality)~~ - ⚠️ **DEPRECATED Oct 2019** - No-op function
943
+ - ~~[`getAvailableQualityLevels()`](https://developers.google.com/youtube/iframe_api_reference#getAvailableQualityLevels)~~ - ⚠️ **DEPRECATED Oct 2019** - No longer returns data
944
+
945
+ **Event Handlers:**
946
+
947
+ - [`onReady`](https://developers.google.com/youtube/iframe_api_reference#onReady) - Player is ready
948
+ - [`onStateChange`](https://developers.google.com/youtube/iframe_api_reference#onStateChange) - Player state changed (playing, paused, ended, etc.)
949
+ - [`onPlaybackQualityChange`](https://developers.google.com/youtube/iframe_api_reference#onPlaybackQualityChange) - Quality level changed
950
+ - [`onError`](https://developers.google.com/youtube/iframe_api_reference#onError) - Error occurred
951
+
952
+ **Player Parameters:**
953
+ Supports all [YouTube Player Parameters](https://developers.google.com/youtube/player_parameters) via the `player-vars` attribute, including `autoplay`, `loop`, `controls`, `modestbranding`, `rel`, `showinfo`, and more.
719
954
 
720
955
  ## 📝 Migration Guide
721
956
 
@@ -1075,31 +1310,35 @@ npm run build:prod
1075
1310
  This creates optimized `.min.js` and `.min.css` files with:
1076
1311
 
1077
1312
  - **Terser** minification for JavaScript (removes whitespace, shortens variable names)
1078
- - **CSSO** optimization for CSS (removes redundant rules, merges selectors)
1079
- - **~50% smaller** file sizes compared to development builds
1313
+ - **CSSO** opt (all three components)
1314
+ import "@smartimpact-it/modern-video-embed";
1080
1315
 
1081
- ### Build Output Structure
1316
+ // YouTube only
1317
+ import "@smartimpact-it/modern-video-embed/dist/youtube-only.js";
1082
1318
 
1083
- ```
1084
- dist/
1085
- ├── index.js # Full bundle (58KB)
1086
- ├── index.min.js # Full bundle minified (29KB) ⭐ Production
1087
- ├── youtube-only.js # YouTube bundle (29KB)
1088
- ├── youtube-only.min.js # YouTube minified (15KB) ⭐ Production
1089
- ├── vimeo-only.js # Vimeo bundle (29KB)
1090
- ├── vimeo-only.min.js # Vimeo minified (14KB) ⭐ Production
1319
+ // Vimeo only
1320
+ import "@smartimpact-it/modern-video-embed/dist/vimeo-only.js";
1321
+
1322
+ // Native video only
1323
+ import "@smartimpact-it/modern-video-embed/dist/vidKB)
1324
+ ├── index.min.js # Full bundle minified (29KB) ⭐ Production
1325
+ ├── youtube-only.js # YouTube bundle (29KB)
1326
+ ├── youtube-only.min.js # YouTube minified (15KB) ⭐ Production
1327
+ ├── vimeo-only.js # Vimeo bundle (29KB)
1328
+ ├── vimeo-only.min.js # Vimeo minified (14KB) ⭐ Production
1091
1329
  ├── components/
1092
- ├── YouTubeEmbed.js # YouTube component (58KB)
1093
- ├── YouTubeEmbed.min.js # YouTube minified (29KB)
1094
- ├── VimeoEmbed.js # Vimeo component (49KB)
1095
- └── VimeoEmbed.min.js # Vimeo minified (27KB)
1330
+ ├── YouTubeEmbed.js # YouTube component (58KB)
1331
+ ├── YouTubeEmbed.min.js # YouTube minified (29KB)
1332
+ ├── VimeoEmbed.js # Vimeo component (49KB)
1333
+ └── VimeoEmbed.min.js # Vimeo minified (27KB)
1096
1334
  ├── css/
1097
- ├── components.css # Core styles (9KB)
1098
- ├── components.min.css # Core minified (7KB) ⭐ Production
1099
- ├── main.css # With Bootstrap (276KB)
1100
- └── main.min.css # Bootstrap minified (224KB)
1101
- └── types/ # TypeScript declarations
1102
- ```
1335
+ ├── components.css # Core styles (9KB)
1336
+ ├── components.min.css # Core minified (7KB) ⭐ Production
1337
+ ├── main.css # With Bootstrap (276KB)
1338
+ └── main.min.css # Bootstrap minified (224KB)
1339
+ └── types/ # TypeScript declarations
1340
+
1341
+ ````
1103
1342
 
1104
1343
  ### Performance Optimization
1105
1344
 
@@ -1107,11 +1346,23 @@ dist/
1107
1346
 
1108
1347
  | Configuration | Size (Dev) | Size (Prod) | With gzip\* |
1109
1348
  | -------------------- | ---------- | ----------- | ----------- |
1110
- | YouTube + Core CSS | 38KB | **22KB** | ~7KB |
1111
- | Vimeo + Core CSS | 38KB | **21KB** | ~7KB |
1112
- | Both + Core CSS | 67KB | **36KB** | ~12KB |
1113
- | Both + Bootstrap CSS | 343KB | **253KB** | ~45KB |
1114
-
1349
+ We welcome contributions! Here's how to get started:
1350
+
1351
+ 1. **Read the docs**: Check [`.ai-instructions.md`](.ai-instructions.md) for development guidelines
1352
+ 2. **Fork the repository**: Create your own fork on GitHub
1353
+ 3. **Create a feature branch**: `git checkout -b feature/your-feature-name`
1354
+ 4. **Make your changes**: Follow TypeScript strict mode and existing patterns
1355
+ 5. **Build and test**: Run `npm run build` and test with `test/index.html`
1356
+ 6. **Update documentation**: Update README and type definitions if needed
1357
+ 7. **Submit a pull request**: Include a clear description of changes
1358
+
1359
+ **Development Checklist:**
1360
+ - ✅ Code follows existing patterns and conventions
1361
+ - ✅ TypeScript compiles without errors (strict mode)
1362
+ - ✅ All tests pass in `test/index.html`
1363
+ - ✅ Type definitions updated if API changed
1364
+ - ✅ README updated for user-facing changes
1365
+ - ✅ Examples added/updated if needed
1115
1366
  \*Estimated with gzip compression enabled on server
1116
1367
 
1117
1368
  **Optimization Tips:**
@@ -1128,7 +1379,7 @@ dist/
1128
1379
  <!-- YouTube only: 22KB total (7KB gzipped) -->
1129
1380
  <script type="module" src="dist/youtube-only.min.js"></script>
1130
1381
  <link rel="stylesheet" href="dist/css/components.min.css" />
1131
- ```
1382
+ ````
1132
1383
 
1133
1384
  ### Bundle Sizes
1134
1385
 
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Base class for all video embed components (VideoEmbed, YouTubeEmbed, VimeoEmbed).
3
+ * Contains shared functionality to reduce code duplication and ensure consistency.
4
+ */
5
+ export declare abstract class BaseVideoEmbed extends HTMLElement {
6
+ protected static instanceCount: number;
7
+ protected static DEBUG: boolean;
8
+ protected playerReady: boolean;
9
+ protected initialized: boolean;
10
+ protected updatingAttribute: boolean;
11
+ protected playPauseButton: HTMLDivElement | null;
12
+ protected setCustomControlState: ((playing: boolean) => void) | null;
13
+ protected ariaLiveRegion: HTMLElement | null;
14
+ protected intersectionObserver: IntersectionObserver | null;
15
+ protected hasLoadedVideo: boolean;
16
+ protected posterClickHandler: EventListener | null;
17
+ protected keyboardHandler: ((e: KeyboardEvent) => void) | null;
18
+ protected _playing: boolean;
19
+ protected _autoplay: boolean;
20
+ protected _muted: boolean;
21
+ protected _controls: boolean;
22
+ protected _lazy: boolean;
23
+ protected _background: boolean;
24
+ protected _poster: string;
25
+ /**
26
+ * Abstract methods that subclasses must implement
27
+ */
28
+ protected abstract initializePlayer(...args: any[]): Promise<void> | void;
29
+ protected abstract reinitializePlayer(): void;
30
+ protected abstract destroyPlayer(): void;
31
+ protected abstract getComponentName(): string;
32
+ /**
33
+ * Logging utilities
34
+ */
35
+ protected log(...args: any[]): void;
36
+ protected warn(...args: any[]): void;
37
+ protected error(...args: any[]): void;
38
+ /**
39
+ * Event dispatching
40
+ */
41
+ protected dispatchCustomEvent(eventName: string, detail?: any): void;
42
+ /**
43
+ * Attribute reflection helpers
44
+ */
45
+ protected reflectBooleanAttribute(name: string, value: boolean): void;
46
+ protected reflectAttribute(name: string, value: string): void;
47
+ /**
48
+ * Error message display (common across all components)
49
+ */
50
+ protected showErrorMessage(message: string, errorClass: string): void;
51
+ /**
52
+ * Retry handler - subclasses can override
53
+ */
54
+ protected handleRetry(): void;
55
+ /**
56
+ * Background mode management (common across all components)
57
+ */
58
+ protected updateBackgroundMode(): void;
59
+ /**
60
+ * Automatically set aspect ratio CSS custom properties
61
+ * This allows background videos to maintain correct proportions
62
+ */
63
+ protected setAspectRatio(width: number, height: number): void;
64
+ /**
65
+ * Custom controls creation (similar pattern across components)
66
+ */
67
+ protected addCustomControls(containerClass: string): void;
68
+ /**
69
+ * Play/Pause handlers - subclasses override with platform-specific logic
70
+ */
71
+ protected abstract handlePlay(): void;
72
+ protected abstract handlePause(): void;
73
+ /**
74
+ * Lazy loading setup (common pattern)
75
+ */
76
+ protected setupLazyLoading(callback: () => void): void;
77
+ /**
78
+ * ARIA announcements for accessibility
79
+ */
80
+ protected announceToScreenReader(message: string): void;
81
+ /**
82
+ * Lifecycle management
83
+ */
84
+ connectedCallback(): void;
85
+ disconnectedCallback(): void;
86
+ /**
87
+ * Static debug toggle
88
+ */
89
+ static toggleDebug(forceState?: boolean): void;
90
+ }
91
+ //# sourceMappingURL=BaseVideoEmbed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseVideoEmbed.d.ts","sourceRoot":"","sources":["../../src/components/BaseVideoEmbed.ts"],"names":[],"mappings":"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"}