streamit-player 1.0.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.
Files changed (118) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/LICENSE +203 -0
  3. package/README.md +552 -0
  4. package/dist/Player-BfmqCREY.cjs +11616 -0
  5. package/dist/Player-YpukGRGt.js +11617 -0
  6. package/dist/PlayerController-Bt7Po42U.cjs +14093 -0
  7. package/dist/PlayerController-CW0pxrIt.js +14072 -0
  8. package/dist/core/index.cjs +194 -0
  9. package/dist/core/index.js +194 -0
  10. package/dist/core/src/AdScheduler.d.ts +56 -0
  11. package/dist/core/src/AdScheduler.d.ts.map +1 -0
  12. package/dist/core/src/AdsController.d.ts +48 -0
  13. package/dist/core/src/AdsController.d.ts.map +1 -0
  14. package/dist/core/src/AdsManager.d.ts +181 -0
  15. package/dist/core/src/AdsManager.d.ts.map +1 -0
  16. package/dist/core/src/DrmManager.d.ts +162 -0
  17. package/dist/core/src/DrmManager.d.ts.map +1 -0
  18. package/dist/core/src/DrmValidator.d.ts +36 -0
  19. package/dist/core/src/DrmValidator.d.ts.map +1 -0
  20. package/dist/core/src/KeyboardManager.d.ts +73 -0
  21. package/dist/core/src/KeyboardManager.d.ts.map +1 -0
  22. package/dist/core/src/PictureInPictureManager.d.ts +47 -0
  23. package/dist/core/src/PictureInPictureManager.d.ts.map +1 -0
  24. package/dist/core/src/PlayerController.d.ts +231 -0
  25. package/dist/core/src/PlayerController.d.ts.map +1 -0
  26. package/dist/core/src/PlaylistManager.d.ts +63 -0
  27. package/dist/core/src/PlaylistManager.d.ts.map +1 -0
  28. package/dist/core/src/SourceManager.d.ts +142 -0
  29. package/dist/core/src/SourceManager.d.ts.map +1 -0
  30. package/dist/core/src/SubtitleManager.d.ts +77 -0
  31. package/dist/core/src/SubtitleManager.d.ts.map +1 -0
  32. package/dist/core/src/TimelineMath.d.ts +14 -0
  33. package/dist/core/src/TimelineMath.d.ts.map +1 -0
  34. package/dist/core/src/html-overlay/HtmlOverlayRenderer.d.ts +103 -0
  35. package/dist/core/src/html-overlay/HtmlOverlayRenderer.d.ts.map +1 -0
  36. package/dist/core/src/index.d.ts +21 -0
  37. package/dist/core/src/index.d.ts.map +1 -0
  38. package/dist/core/src/providers/ImaProvider.d.ts +135 -0
  39. package/dist/core/src/providers/ImaProvider.d.ts.map +1 -0
  40. package/dist/core/src/providers/ThumbnailProviders.d.ts +102 -0
  41. package/dist/core/src/providers/ThumbnailProviders.d.ts.map +1 -0
  42. package/dist/core/src/providers/VastProvider.d.ts +202 -0
  43. package/dist/core/src/providers/VastProvider.d.ts.map +1 -0
  44. package/dist/core/src/providers/VmapProvider.d.ts +98 -0
  45. package/dist/core/src/providers/VmapProvider.d.ts.map +1 -0
  46. package/dist/core/src/providers/fetchXmlWithPolicy.d.ts +9 -0
  47. package/dist/core/src/providers/fetchXmlWithPolicy.d.ts.map +1 -0
  48. package/dist/core/src/simid/SimidBridge.d.ts +44 -0
  49. package/dist/core/src/simid/SimidBridge.d.ts.map +1 -0
  50. package/dist/core/src/simid/SimidManager.d.ts +21 -0
  51. package/dist/core/src/simid/SimidManager.d.ts.map +1 -0
  52. package/dist/core/src/simid/SimidRuntime.d.ts +113 -0
  53. package/dist/core/src/simid/SimidRuntime.d.ts.map +1 -0
  54. package/dist/core/src/simid/SimidSession.d.ts +48 -0
  55. package/dist/core/src/simid/SimidSession.d.ts.map +1 -0
  56. package/dist/core/src/simid/types.d.ts +115 -0
  57. package/dist/core/src/simid/types.d.ts.map +1 -0
  58. package/dist/core/src/storage.d.ts +10 -0
  59. package/dist/core/src/storage.d.ts.map +1 -0
  60. package/dist/core/src/types.d.ts +1403 -0
  61. package/dist/core/src/types.d.ts.map +1 -0
  62. package/dist/core/src/utils.d.ts +34 -0
  63. package/dist/core/src/utils.d.ts.map +1 -0
  64. package/dist/core/src/vendorLoaders.d.ts +16 -0
  65. package/dist/core/src/vendorLoaders.d.ts.map +1 -0
  66. package/dist/index.cjs +55 -0
  67. package/dist/index.js +55 -0
  68. package/dist/src/index.d.ts +3 -0
  69. package/dist/src/index.d.ts.map +1 -0
  70. package/dist/streamit-player.esm.js +26226 -0
  71. package/dist/streamit-player.esm.min.js +18830 -0
  72. package/dist/streamit-player.iife.js +26229 -0
  73. package/dist/streamit-player.iife.min.js +4750 -0
  74. package/dist/web-components/index.cjs +15 -0
  75. package/dist/web-components/index.js +15 -0
  76. package/dist/web-components/src/ChaptersButton.d.ts +27 -0
  77. package/dist/web-components/src/ChaptersButton.d.ts.map +1 -0
  78. package/dist/web-components/src/ChaptersButton.styles.d.ts +2 -0
  79. package/dist/web-components/src/ChaptersButton.styles.d.ts.map +1 -0
  80. package/dist/web-components/src/PlayButton.d.ts +17 -0
  81. package/dist/web-components/src/PlayButton.d.ts.map +1 -0
  82. package/dist/web-components/src/PlayButton.styles.d.ts +2 -0
  83. package/dist/web-components/src/PlayButton.styles.d.ts.map +1 -0
  84. package/dist/web-components/src/Player.d.ts +271 -0
  85. package/dist/web-components/src/Player.d.ts.map +1 -0
  86. package/dist/web-components/src/Player.styles.d.ts +2 -0
  87. package/dist/web-components/src/Player.styles.d.ts.map +1 -0
  88. package/dist/web-components/src/SeekButton.d.ts +18 -0
  89. package/dist/web-components/src/SeekButton.d.ts.map +1 -0
  90. package/dist/web-components/src/SeekButton.styles.d.ts +2 -0
  91. package/dist/web-components/src/SeekButton.styles.d.ts.map +1 -0
  92. package/dist/web-components/src/Seekbar.d.ts +101 -0
  93. package/dist/web-components/src/Seekbar.d.ts.map +1 -0
  94. package/dist/web-components/src/Seekbar.styles.d.ts +2 -0
  95. package/dist/web-components/src/Seekbar.styles.d.ts.map +1 -0
  96. package/dist/web-components/src/Themes.d.ts +5 -0
  97. package/dist/web-components/src/Themes.d.ts.map +1 -0
  98. package/dist/web-components/src/VerticalControls.d.ts +49 -0
  99. package/dist/web-components/src/VerticalControls.d.ts.map +1 -0
  100. package/dist/web-components/src/VerticalControls.styles.d.ts +2 -0
  101. package/dist/web-components/src/VerticalControls.styles.d.ts.map +1 -0
  102. package/dist/web-components/src/VolumeControl.d.ts +21 -0
  103. package/dist/web-components/src/VolumeControl.d.ts.map +1 -0
  104. package/dist/web-components/src/VolumeControl.styles.d.ts +2 -0
  105. package/dist/web-components/src/VolumeControl.styles.d.ts.map +1 -0
  106. package/dist/web-components/src/icons/IconRegistry.d.ts +24 -0
  107. package/dist/web-components/src/icons/IconRegistry.d.ts.map +1 -0
  108. package/dist/web-components/src/index.d.ts +10 -0
  109. package/dist/web-components/src/index.d.ts.map +1 -0
  110. package/dist/web-components/src/player-internals/GestureController.d.ts +140 -0
  111. package/dist/web-components/src/player-internals/GestureController.d.ts.map +1 -0
  112. package/dist/web-components/src/player-internals/PrefetchController.d.ts +34 -0
  113. package/dist/web-components/src/player-internals/PrefetchController.d.ts.map +1 -0
  114. package/dist/web-components/src/player-internals/SettingsMenuController.d.ts +59 -0
  115. package/dist/web-components/src/player-internals/SettingsMenuController.d.ts.map +1 -0
  116. package/dist/web-components/src/player-internals/ThumbnailCache.d.ts +64 -0
  117. package/dist/web-components/src/player-internals/ThumbnailCache.d.ts.map +1 -0
  118. package/package.json +84 -0
package/README.md ADDED
@@ -0,0 +1,552 @@
1
+ # Streamit Player (`streamit-player`)
2
+
3
+ A high-performance, enterprise-grade video player SDK and Web Component for modern web applications. Featuring adaptive streaming (HLS & MPEG-DASH), multi-DRM protection (Widevine, PlayReady, FairPlay, ClearKey), comprehensive advertising monetization (VAST 2.0-4.2, VMAP, Google IMA, SIMID 1.0, HTML Overlays), Smart Seek filmstrip preview, live DVR, TikTok/Reels-style vertical feeds, and customizable glassmorphism theming.
4
+
5
+ ---
6
+
7
+ ## 📦 Installation
8
+
9
+ ```bash
10
+ npm install streamit-player
11
+ ```
12
+
13
+ npm (v7+) and pnpm also install the `hls.js` and `dashjs` peer dependencies automatically. With Yarn, add them yourself:
14
+
15
+ ```bash
16
+ yarn add streamit-player hls.js dashjs
17
+ ```
18
+
19
+ Both libraries are loaded on demand, only when an HLS or DASH source is played.
20
+
21
+ ### CDN Installation (No Build Step)
22
+
23
+ #### Modern ESM (`<script type="module">`)
24
+ ```html
25
+ <script type="module" src="https://cdn.jsdelivr.net/npm/streamit-player@1/dist/streamit-player.esm.min.js"></script>
26
+ ```
27
+
28
+ #### Classic Script (`IIFE` global `window.StreamitPlayer`)
29
+ ```html
30
+ <script src="https://cdn.jsdelivr.net/npm/streamit-player@1/dist/streamit-player.iife.min.js"></script>
31
+ ```
32
+
33
+ The CDN bundles download `hls.js` and `dash.js` from jsDelivr the first time an HLS or DASH source plays. To self-host them instead (for example under a strict Content-Security-Policy), load their script builds **before** the player. A page-level `window.Hls` / `window.dashjs` is always used when present:
34
+
35
+ ```html
36
+ <script src="https://cdn.jsdelivr.net/npm/hls.js@1/dist/hls.min.js"></script>
37
+ <script src="https://cdn.jsdelivr.net/npm/dashjs@5/dist/modern/umd/dash.all.min.js"></script>
38
+ <script src="https://cdn.jsdelivr.net/npm/streamit-player@1/dist/streamit-player.iife.min.js"></script>
39
+ ```
40
+
41
+ ---
42
+
43
+ ## ⚡ Quick Start
44
+
45
+ The fastest way to get a player on the page, with no JavaScript required. The source type is detected from the URL (`.m3u8` → HLS, `.mpd` → DASH, otherwise progressive video):
46
+
47
+ ```html
48
+ <script src="https://cdn.jsdelivr.net/npm/streamit-player@1/dist/streamit-player.iife.min.js"></script>
49
+
50
+ <streamit-player
51
+ src="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"
52
+ poster="https://example.com/poster.jpg"
53
+ style="display: block; width: 100%; aspect-ratio: 16 / 9;"
54
+ ></streamit-player>
55
+ ```
56
+
57
+ Supported attributes include `src`, `poster`, `autoplay`, `muted`, `loop`, `playsinline`, `preload`, `crossorigin` and `captions`.
58
+
59
+ ---
60
+
61
+ ## 🚀 Package Architecture & Subpath Entry Points
62
+
63
+ The `streamit-player` package is distributed as a single npm package with clean, optimized subpath exports:
64
+
65
+ | Entry Point | Description | Lit / UI Included |
66
+ |---|---|---|
67
+ | `streamit-player` | **Default / All-in-One**: Registers `<streamit-player>` and `<player-player>` custom elements; exports `PlayerPlayer`, sub-components, and the full core API and types. | ✅ Yes |
68
+ | `streamit-player/core` | **Headless Playback Engine**: `PlayerController`, DRM manager, VAST/VMAP/IMA/SIMID ad engines, thumbnail providers, and all types. | ❌ **Zero Lit / UI** |
69
+ | `streamit-player/web-components` | **Lit Web Component Layer**: `<streamit-player>`, theme presets (`THEME_PRESETS`, `compileTheme`), icon registry (`renderIcon`), and sub-components. | ✅ Yes |
70
+
71
+ ---
72
+
73
+ ## ⚙️ Configuration, Sources & Events
74
+
75
+ Configuration is a flat object assigned to the element's `config` **property** (not an attribute). Sources are loaded with `loadSource()` (or `loadPlaylist()` for several items):
76
+
77
+ ```js
78
+ const player = document.querySelector('streamit-player');
79
+
80
+ player.config = {
81
+ autoplay: false,
82
+ muted: false,
83
+ volume: 0.8,
84
+ poster: 'https://example.com/poster.jpg',
85
+ theme: { preset: 'glass-dark' },
86
+ drm: { widevine: { licenseUrl: 'https://license.example.com/widevine' } },
87
+ ads: { enabled: true, provider: 'VAST', tagUrl: 'https://example.com/vast.xml' },
88
+ };
89
+
90
+ player.loadSource({
91
+ type: 'hls', // 'hls' | 'dash' | 'mp4' | 'webm' | ...; detected from the URL when omitted
92
+ src: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8',
93
+ subtitles: [{ src: '/subs/en.vtt', label: 'English', srclang: 'en', default: true }],
94
+ });
95
+ ```
96
+
97
+ Every player event is dispatched on the element as a bubbling `player-<name>` DOM event, with the payload in `event.detail`. You can also subscribe with `player.on()`:
98
+
99
+ ```js
100
+ player.addEventListener('player-play', () => console.log('Playback started'));
101
+ player.addEventListener('player-timeupdate', (e) => console.log('Time:', e.detail.currentTime));
102
+
103
+ player.on('ended', () => console.log('Finished'));
104
+ ```
105
+
106
+ For advanced control, `player.controllerInstance` returns the underlying headless `PlayerController`.
107
+
108
+ ---
109
+
110
+ ## 🛠️ Multi-Framework Integration Recipes
111
+
112
+ ### 1. Plain HTML5 & Vanilla JavaScript
113
+
114
+ #### Modern ESM (no build step)
115
+ ```html
116
+ <!DOCTYPE html>
117
+ <html lang="en">
118
+ <head>
119
+ <meta charset="UTF-8">
120
+ <title>Streamit Player - Plain HTML</title>
121
+ <style>
122
+ .player-wrapper {
123
+ max-width: 960px;
124
+ margin: 40px auto;
125
+ aspect-ratio: 16 / 9;
126
+ }
127
+ streamit-player {
128
+ width: 100%;
129
+ height: 100%;
130
+ display: block;
131
+ }
132
+ </style>
133
+ </head>
134
+ <body>
135
+ <div class="player-wrapper">
136
+ <streamit-player id="my-player"></streamit-player>
137
+ </div>
138
+
139
+ <script type="module">
140
+ import 'https://cdn.jsdelivr.net/npm/streamit-player@1/dist/streamit-player.esm.min.js';
141
+
142
+ const player = document.getElementById('my-player');
143
+ player.config = {
144
+ poster: 'https://images.unsplash.com/photo-1536240478700-b869070f9279?w=1200',
145
+ autoplay: false,
146
+ muted: false,
147
+ theme: { preset: 'glass-dark' }
148
+ };
149
+ player.loadSource({
150
+ type: 'hls',
151
+ src: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8'
152
+ });
153
+
154
+ player.addEventListener('player-play', () => console.log('Playback started'));
155
+ player.addEventListener('player-timeupdate', (e) => console.log('Current time:', e.detail.currentTime));
156
+ </script>
157
+ </body>
158
+ </html>
159
+ ```
160
+
161
+ With a bundler (Vite, webpack, Rollup, …) use the package name instead: `import 'streamit-player';`.
162
+
163
+ #### Classic Script (IIFE)
164
+ ```html
165
+ <script src="https://cdn.jsdelivr.net/npm/streamit-player@1/dist/streamit-player.iife.min.js"></script>
166
+ <streamit-player id="classic-player" style="width: 100%; aspect-ratio: 16/9; display: block;"></streamit-player>
167
+ <script>
168
+ var player = document.getElementById('classic-player');
169
+ player.loadSource({
170
+ type: 'mp4',
171
+ src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'
172
+ });
173
+ </script>
174
+ ```
175
+
176
+ ---
177
+
178
+ ### 2. React (18 & 19)
179
+
180
+ Assign objects such as `config` through a `ref` (React 18 would otherwise stringify them into attributes), and listen for `player-*` events with `addEventListener`:
181
+
182
+ ```tsx
183
+ import { useEffect, useRef } from 'react';
184
+ import 'streamit-player';
185
+ import type { PlayerPlayer, PlayerConfiguration, PlayerSource } from 'streamit-player';
186
+
187
+ export interface StreamitVideoPlayerProps {
188
+ src: string;
189
+ type?: PlayerSource['type'];
190
+ config?: PlayerConfiguration;
191
+ onPlay?: () => void;
192
+ className?: string;
193
+ }
194
+
195
+ export function StreamitVideoPlayer({ src, type, config, onPlay, className }: StreamitVideoPlayerProps) {
196
+ const playerRef = useRef<PlayerPlayer>(null);
197
+
198
+ useEffect(() => {
199
+ if (playerRef.current && config) playerRef.current.config = config;
200
+ }, [config]);
201
+
202
+ useEffect(() => {
203
+ playerRef.current?.loadSource({ src, type });
204
+ }, [src, type]);
205
+
206
+ useEffect(() => {
207
+ const el = playerRef.current;
208
+ if (!el || !onPlay) return;
209
+ el.addEventListener('player-play', onPlay);
210
+ return () => el.removeEventListener('player-play', onPlay);
211
+ }, [onPlay]);
212
+
213
+ return (
214
+ <streamit-player
215
+ ref={playerRef}
216
+ className={className}
217
+ style={{ display: 'block', width: '100%', aspectRatio: '16 / 9' }}
218
+ />
219
+ );
220
+ }
221
+ ```
222
+
223
+ In React 19 you can also pass `config={config}` directly, because React 19 sets it as a property.
224
+
225
+ #### TypeScript: declaring the JSX element
226
+
227
+ TypeScript doesn't know about custom elements in JSX until you declare them. Add this file anywhere in your project (e.g. `src/streamit-player.d.ts`):
228
+
229
+ ```ts
230
+ import type { DetailedHTMLProps, HTMLAttributes } from 'react';
231
+ import type { PlayerPlayer } from 'streamit-player';
232
+
233
+ declare module 'react' {
234
+ namespace JSX {
235
+ interface IntrinsicElements {
236
+ 'streamit-player': DetailedHTMLProps<HTMLAttributes<PlayerPlayer>, PlayerPlayer> & {
237
+ src?: string;
238
+ poster?: string;
239
+ };
240
+ }
241
+ }
242
+ }
243
+ ```
244
+
245
+ ---
246
+
247
+ ### 3. Next.js (App Router & Pages Router)
248
+
249
+ The player registers custom elements when imported, so load it in the browser only, inside the `useEffect` of a client component:
250
+
251
+ #### Component (`components/StreamitPlayerClient.tsx`)
252
+ ```tsx
253
+ 'use client';
254
+
255
+ import { useEffect, useRef } from 'react';
256
+ import type { PlayerPlayer, PlayerConfiguration } from 'streamit-player';
257
+
258
+ export default function StreamitPlayerClient({ src, config }: { src: string; config?: PlayerConfiguration }) {
259
+ const playerRef = useRef<PlayerPlayer>(null);
260
+
261
+ useEffect(() => {
262
+ let cancelled = false;
263
+ import('streamit-player').then(() => {
264
+ const el = playerRef.current;
265
+ if (cancelled || !el) return;
266
+ if (config) el.config = config;
267
+ el.loadSource({ src });
268
+ });
269
+ return () => {
270
+ cancelled = true;
271
+ };
272
+ }, [src, config]);
273
+
274
+ return (
275
+ <streamit-player
276
+ ref={playerRef}
277
+ style={{ display: 'block', width: '100%', aspectRatio: '16 / 9', borderRadius: '12px', overflow: 'hidden' }}
278
+ />
279
+ );
280
+ }
281
+ ```
282
+
283
+ #### App Router Page (`app/watch/page.tsx`)
284
+ ```tsx
285
+ import StreamitPlayerClient from '@/components/StreamitPlayerClient';
286
+
287
+ export default function WatchPage() {
288
+ return (
289
+ <main style={{ maxWidth: '1100px', margin: '40px auto', padding: '0 20px' }}>
290
+ <h1>Now Watching</h1>
291
+ <StreamitPlayerClient
292
+ src="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"
293
+ config={{ autoplay: true, muted: true, theme: { preset: 'glass-dark' } }}
294
+ />
295
+ </main>
296
+ );
297
+ }
298
+ ```
299
+
300
+ The same component works unchanged in the Pages Router. Add the JSX declaration from the React section for TypeScript.
301
+
302
+ ---
303
+
304
+ ### 4. Laravel (Blade with Vite)
305
+
306
+ 1. **Install and import in your Vite entry point (`resources/js/app.js`):**
307
+ ```javascript
308
+ import './bootstrap';
309
+ import 'streamit-player';
310
+ ```
311
+
312
+ 2. **Render the custom element in your Blade view (`resources/views/watch.blade.php`):**
313
+ ```html
314
+ @extends('layouts.app')
315
+
316
+ @section('content')
317
+ <div class="max-w-5xl mx-auto py-8">
318
+ <h1 class="text-2xl font-bold mb-4">{{ $video->title }}</h1>
319
+
320
+ <div class="rounded-xl overflow-hidden shadow-2xl aspect-video bg-black">
321
+ <streamit-player
322
+ src="{{ $video->stream_url }}"
323
+ poster="{{ $video->poster_url }}"
324
+ style="display:block;width:100%;height:100%"
325
+ ></streamit-player>
326
+ </div>
327
+ </div>
328
+ @endsection
329
+ ```
330
+
331
+ To pass a full `config` object from a script, wait until the element is registered:
332
+
333
+ ```javascript
334
+ customElements.whenDefined('streamit-player').then(() => {
335
+ document.querySelector('streamit-player').config = { volume: 0.8, theme: { preset: 'glass-dark' } };
336
+ });
337
+ ```
338
+
339
+ ---
340
+
341
+ ### 5. Vue 3 (incl. Laravel Inertia)
342
+
343
+ Tell Vue that `streamit-*` tags are custom elements (`vite.config.js`):
344
+
345
+ ```javascript
346
+ import vue from '@vitejs/plugin-vue';
347
+
348
+ export default {
349
+ plugins: [
350
+ vue({
351
+ template: {
352
+ compilerOptions: { isCustomElement: (tag) => tag.startsWith('streamit-') },
353
+ },
354
+ }),
355
+ ],
356
+ };
357
+ ```
358
+
359
+ Then use the element in a component (`resources/js/Pages/Watch.vue`):
360
+
361
+ ```html
362
+ <template>
363
+ <div class="player-container aspect-video w-full rounded-2xl overflow-hidden">
364
+ <streamit-player
365
+ ref="playerRef"
366
+ :config.prop="config"
367
+ style="display:block;width:100%;height:100%"
368
+ @player-play="onPlay"
369
+ @player-timeupdate="onTimeUpdate"
370
+ />
371
+ </div>
372
+ </template>
373
+
374
+ <script setup>
375
+ import { ref, onMounted, watch } from 'vue';
376
+ import 'streamit-player';
377
+
378
+ const props = defineProps({
379
+ video: Object
380
+ });
381
+
382
+ const playerRef = ref(null);
383
+ const config = { autoplay: false, muted: false, theme: { preset: 'glass-dark' } };
384
+
385
+ const loadVideo = () => {
386
+ playerRef.value?.loadSource({ src: props.video.url, type: props.video.type });
387
+ };
388
+
389
+ onMounted(loadVideo);
390
+ watch(() => props.video, loadVideo, { deep: true });
391
+
392
+ const onPlay = () => console.log('Playback started');
393
+ const onTimeUpdate = (e) => console.log('Time:', e.detail.currentTime);
394
+ </script>
395
+ ```
396
+
397
+ ---
398
+
399
+ ### 6. WordPress (Classic PHP & Gutenberg)
400
+
401
+ #### WordPress Classic Theme / Shortcode (`functions.php`)
402
+ ```php
403
+ <?php
404
+ // Enqueue the Streamit Player IIFE bundle from the CDN
405
+ function streamit_player_register_assets() {
406
+ wp_register_script(
407
+ 'streamit-player',
408
+ 'https://cdn.jsdelivr.net/npm/streamit-player@1/dist/streamit-player.iife.min.js',
409
+ array(),
410
+ null,
411
+ true
412
+ );
413
+ }
414
+ add_action('wp_enqueue_scripts', 'streamit_player_register_assets');
415
+
416
+ // Register the [streamit_player src="..." poster="..." autoplay="true"] shortcode
417
+ function streamit_player_shortcode($atts) {
418
+ wp_enqueue_script('streamit-player');
419
+
420
+ $atts = shortcode_atts(array(
421
+ 'src' => '',
422
+ 'poster' => '',
423
+ 'autoplay' => 'false',
424
+ ), $atts, 'streamit_player');
425
+
426
+ // Browsers only allow autoplay when muted
427
+ $autoplay = $atts['autoplay'] === 'true' ? ' autoplay muted' : '';
428
+
429
+ return sprintf(
430
+ '<div style="width:100%%;max-width:960px;margin:20px auto;aspect-ratio:16/9;">'
431
+ . '<streamit-player src="%s" poster="%s"%s style="display:block;width:100%%;height:100%%;"></streamit-player>'
432
+ . '</div>',
433
+ esc_url($atts['src']),
434
+ esc_url($atts['poster']),
435
+ $autoplay
436
+ );
437
+ }
438
+ add_shortcode('streamit_player', 'streamit_player_shortcode');
439
+ ```
440
+
441
+ #### WordPress Gutenberg Custom HTML Block
442
+ Paste directly into a Gutenberg **Custom HTML** block:
443
+ ```html
444
+ <script src="https://cdn.jsdelivr.net/npm/streamit-player@1/dist/streamit-player.iife.min.js"></script>
445
+
446
+ <div style="width: 100%; aspect-ratio: 16/9; max-width: 900px; margin: 0 auto; border-radius: 12px; overflow: hidden;">
447
+ <streamit-player
448
+ src="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"
449
+ style="width: 100%; height: 100%; display: block;"
450
+ ></streamit-player>
451
+ </div>
452
+ ```
453
+
454
+ ---
455
+
456
+ ### 7. Headless & Core-Only TypeScript (Zero Lit / Custom UI)
457
+
458
+ Build your own bespoke UI around the headless engine without including any Lit or Web Component DOM overhead:
459
+
460
+ ```typescript
461
+ import { PlayerController } from 'streamit-player/core';
462
+ import type { PlayerConfiguration, PlayerState } from 'streamit-player/core';
463
+
464
+ // Reference your existing HTML5 <video> element
465
+ const videoElement = document.getElementById('my-video') as HTMLVideoElement;
466
+
467
+ const config: PlayerConfiguration = {
468
+ autoplay: false,
469
+ drm: {
470
+ widevine: {
471
+ licenseUrl: 'https://license.widevine.com/cenc/getlicense'
472
+ }
473
+ },
474
+ ads: {
475
+ enabled: true,
476
+ provider: 'VAST',
477
+ tagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?iu=...'
478
+ }
479
+ };
480
+
481
+ // Initialize headless engine
482
+ const controller = new PlayerController(videoElement, config);
483
+
484
+ // Subscribe to state changes (returns an unsubscribe function)
485
+ const unsubscribe = controller.onStateChange((state: PlayerState) => {
486
+ console.log('Status:', state.status, '| playing:', state.isPlaying);
487
+ console.log('Position:', state.currentTime, '/', state.duration);
488
+ console.log('Quality levels:', state.qualities);
489
+ console.log('Audio tracks:', state.audioTracks);
490
+ });
491
+
492
+ // Load a source and control playback
493
+ controller.loadSource({
494
+ type: 'hls',
495
+ src: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8'
496
+ });
497
+ controller.play();
498
+ controller.seek(45.5);
499
+ controller.setVolume(0.75);
500
+
501
+ // Teardown when done
502
+ // unsubscribe();
503
+ // controller.destroy();
504
+ ```
505
+
506
+ ---
507
+
508
+ ## 🎨 Theming & CSS Custom Properties
509
+
510
+ Streamit Player ships four theme presets (`glass-dark`, `glass-light`, `dark`, `light`). Pick one and override individual values through `config.theme`:
511
+
512
+ ```js
513
+ player.config = {
514
+ theme: {
515
+ preset: 'glass-dark',
516
+ primaryColor: '#3b82f6',
517
+ accentColor: '#60a5fa',
518
+ borderRadius: '12px',
519
+ fontFamily: "'Inter', system-ui, sans-serif",
520
+ // Any CSS custom property can be set directly:
521
+ customVariables: { '--player-seekbar-played': '#3b82f6' }
522
+ }
523
+ };
524
+ ```
525
+
526
+ Without a `theme` object you can style the player from your own CSS with its `--player-*` custom properties (more than 60 are available):
527
+
528
+ ```css
529
+ streamit-player {
530
+ --player-primary-color: #3b82f6;
531
+ --player-accent-color: #60a5fa;
532
+ --player-seekbar-played: #3b82f6;
533
+ --player-seekbar-buffer: rgba(255, 255, 255, 0.4);
534
+ --player-glass-blur: 16px;
535
+ --player-border-radius: 12px;
536
+ --player-font-family: 'Inter', system-ui, sans-serif;
537
+ }
538
+ ```
539
+
540
+ Values from `config.theme` are written inline on the element, so they take precedence over stylesheet rules.
541
+
542
+ ---
543
+
544
+ ## 🏷️ Tag Name Aliases
545
+
546
+ `<player-player>` and all `player-*` sub-component tag names (`<player-play-button>`, `<player-seekbar>`, `<player-volume-control>`, etc.) are registered as aliases of their `streamit-*` equivalents.
547
+
548
+ ---
549
+
550
+ ## 📄 License
551
+
552
+ [Apache-2.0](./LICENSE)