playron 1.0.0 → 1.0.2

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 (2) hide show
  1. package/README.md +417 -217
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,287 +1,487 @@
1
1
  # Playron
2
2
 
3
- Modern, özelleştirilebilir OTT video player. React, Next.js ve vanilla JavaScript projelerde kullanılabilir.
3
+ > Professional OTT video player library for React, Next.js, and Vanilla JS.
4
+ > HLS · DASH · DRM · VAST/VMAP · Live Stream · Subtitles · TypeScript-first
4
5
 
5
- ## Özellikler
6
+ ---
6
7
 
7
- - 🎬 **Adaptive Streaming**: HLS ve DASH desteği
8
- - 🔒 **DRM**: Widevine, PlayReady, FairPlay desteği
9
- - 📱 **Responsive**: Mobil ve desktop uyumlu
10
- - 🎨 **Özelleştirilebilir**: Tüm UI bileşenleri özelleştirilebilir
11
- - 📊 **Analytics**: Entegre analytics desteği
12
- - 📺 **Ads**: VAST/VMAP reklam desteği
13
- - ⚡ **Performanslı**: React Compiler ile optimize edilmiş
14
- - 🎯 **TypeScript**: Full type safety
8
+ ## Overview
15
9
 
16
- ## Kurulum
10
+ Playron is a modular, tree-shakeable video player library designed for OTT platforms. It wraps **hls.js** and **dash.js** as streaming engines and adds a full React UI layer with adaptive controls, DRM passthrough, ad integration, live stream support, and more.
17
11
 
18
- ### Development için (npm link)
19
-
20
- Bu projeyi geliştirme aşamasında başka projelerde kullanmak için:
12
+ ```tsx
13
+ import { Player } from 'playron'
14
+ import 'playron/dist/playron.css'
21
15
 
22
- ```bash
23
- # Playron dizininde
24
- npm install
25
- npm run build
26
- npm link
16
+ <Player src="https://example.com/stream.m3u8" />
27
17
  ```
28
18
 
29
- Sonra kullanacağın projede:
30
-
31
- ```bash
32
- npm link playron
33
- ```
19
+ ---
34
20
 
35
- ### NPM'den (gelecekte)
21
+ ## Installation
36
22
 
37
23
  ```bash
38
24
  npm install playron
39
- # veya
25
+ # or
40
26
  yarn add playron
41
- # veya
42
27
  pnpm add playron
43
28
  ```
44
29
 
45
- ## Kullanım
30
+ ### Local Development (yalc)
31
+
32
+ ```bash
33
+ # In the playron repo
34
+ npm run build
35
+ npx yalc push
46
36
 
47
- ### React/Next.js Projelerinde
37
+ # In your project
38
+ npx yalc add playron
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Quick Start
44
+
45
+ ### React / Next.js
48
46
 
49
47
  ```tsx
50
- import { Player } from 'playron';
51
- import 'playron/style.css';
48
+ import { Player } from 'playron'
49
+ import 'playron/dist/playron.css'
52
50
 
53
- function MyApp() {
51
+ export default function VideoPage() {
54
52
  return (
55
- <div>
56
- <Player
57
- src="https://example.com/video.m3u8"
58
- poster="https://example.com/poster.jpg"
59
- autoPlay={false}
60
- controls={true}
61
- />
62
- </div>
63
- );
53
+ <Player
54
+ src="https://example.com/stream.m3u8"
55
+ poster="https://example.com/poster.jpg"
56
+ config={{
57
+ player: {
58
+ defaultVolume: 0.8,
59
+ skipSeconds: 10,
60
+ },
61
+ features: {
62
+ pip: true,
63
+ fullscreen: true,
64
+ theaterMode: true,
65
+ subtitles: true,
66
+ qualitySelector: true,
67
+ playbackSpeed: true,
68
+ keyboardShortcuts: true,
69
+ },
70
+ branding: {
71
+ primaryColor: '#e50914',
72
+ },
73
+ }}
74
+ />
75
+ )
64
76
  }
65
77
  ```
66
78
 
67
- ### Vanilla JavaScript (MVC) Projelerinde
79
+ ### Next.js App Router
68
80
 
69
- ```html
70
- <!DOCTYPE html>
71
- <html>
72
- <head>
73
- <link rel="stylesheet" href="node_modules/playron/dist/playron.css">
74
- </head>
75
- <body>
76
- <div id="player-container"></div>
77
-
78
- <script type="module">
79
- import { Playron } from './node_modules/playron/dist/playron.es.js';
80
-
81
- const player = new Playron({
82
- containerId: 'player-container',
83
- src: 'https://example.com/video.m3u8',
84
- poster: 'https://example.com/poster.jpg',
85
- autoPlay: false,
86
- width: '100%',
87
- height: 'auto'
88
- });
89
-
90
- // Event listeners
91
- player.on('play', () => console.log('Video playing'));
92
- player.on('pause', () => console.log('Video paused'));
93
-
94
- // Player kontrolü
95
- player.play();
96
- player.pause();
97
- player.setVolume(0.5);
98
- player.seekTo(30);
99
- </script>
100
- </body>
101
- </html>
81
+ ```tsx
82
+ 'use client'
83
+ import { Player } from 'playron'
84
+ import 'playron/dist/playron.css'
102
85
  ```
103
86
 
104
- ### UMD (Script tag ile)
87
+ ### Next.js Pages Router
105
88
 
106
- ```html
107
- <!DOCTYPE html>
108
- <html>
109
- <head>
110
- <link rel="stylesheet" href="node_modules/playron/dist/playron.css">
111
- <script src="node_modules/playron/dist/playron.umd.js"></script>
112
- </head>
113
- <body>
114
- <div id="player-container"></div>
115
-
116
- <script>
117
- const player = new Playron.Playron({
118
- containerId: 'player-container',
119
- src: 'https://example.com/video.m3u8'
120
- });
121
- </script>
122
- </body>
123
- </html>
89
+ ```tsx
90
+ import dynamic from 'next/dynamic'
91
+ const Player = dynamic(() => import('playron').then(m => m.Player), { ssr: false })
124
92
  ```
125
93
 
126
- ## API
94
+ ### Vanilla JavaScript
127
95
 
128
- ### Player Props (React)
96
+ ```html
97
+ <link rel="stylesheet" href="playron/dist/playron.css" />
129
98
 
130
- ```typescript
131
- interface PlayerProps {
132
- src: string; // Video source URL
133
- poster?: string; // Poster image URL
134
- autoPlay?: boolean; // Auto-play video
135
- muted?: boolean; // Start muted
136
- controls?: boolean; // Show controls
137
- loop?: boolean; // Loop video
138
- width?: string | number; // Player width
139
- height?: string | number; // Player height
140
- className?: string; // Custom CSS class
141
- style?: React.CSSProperties; // Inline styles
142
-
143
- // DRM Config
144
- drm?: {
145
- widevine?: { licenseUrl: string };
146
- playready?: { licenseUrl: string };
147
- fairplay?: { licenseUrl: string; certificateUrl: string };
148
- };
149
-
150
- // Events
151
- onPlay?: () => void;
152
- onPause?: () => void;
153
- onEnded?: () => void;
154
- onError?: (error: Error) => void;
155
- onTimeUpdate?: (time: number) => void;
156
- }
157
- ```
99
+ <div id="player"></div>
158
100
 
159
- ### Playron Class (Vanilla JS)
101
+ <script type="module">
102
+ import { PlayerCore } from 'playron/dist/playron.es.js'
160
103
 
161
- ```typescript
162
- class Playron {
163
- constructor(config: PlayerConfig);
164
-
165
- // Playback
166
- play(): Promise<void>;
167
- pause(): void;
168
- toggleMute(): void;
169
- setVolume(volume: number): void;
170
- seekTo(time: number): void;
171
- setPlaybackRate(rate: number): void;
172
-
173
- // Source
174
- setSource(src: string): Promise<void>;
175
- setPoster(poster: string): void;
176
-
177
- // Events
178
- on<T>(eventType: string, callback: (event: T) => void): void;
179
- off<T>(eventType: string, callback: (event: T) => void): void;
180
-
181
- // State
182
- getState(): PlayerState;
183
-
184
- // Cleanup
185
- destroy(): void;
186
- }
104
+ const player = new PlayerCore(document.querySelector('#player video'))
105
+ await player.setSource('https://example.com/stream.m3u8')
106
+
107
+ player.eventEmitter.on('play', () => console.log('playing'))
108
+ player.eventEmitter.on('ended', () => console.log('ended'))
109
+ </script>
187
110
  ```
188
111
 
189
- ### Events
112
+ ---
113
+
114
+ ## Features
115
+
116
+ ### Streaming
117
+
118
+ | Feature | Status |
119
+ |---------|--------|
120
+ | HLS (HTTP Live Streaming) | ✅ via **hls.js** |
121
+ | DASH (Dynamic Adaptive Streaming) | ✅ via **dash.js** |
122
+ | Progressive MP4 | ✅ native |
123
+ | Low Latency HLS (LL-HLS) | ✅ |
124
+ | Low Latency DASH (LL-DASH) | ✅ |
125
+ | VOD | ✅ |
126
+ | Live Stream | ✅ |
127
+ | DVR Window | ✅ |
128
+ | Adaptive Bitrate (ABR) | ✅ engine-native |
129
+
130
+ ### DRM
131
+
132
+ | Key System | HLS | DASH | Platform |
133
+ |-----------|-----|------|----------|
134
+ | **Widevine** | ✅ | ✅ | Chrome, Firefox, Edge, Android |
135
+ | **PlayReady** | ❌ | ✅ | Edge, Windows |
136
+ | **FairPlay** | ❌ | ❌ | *Not yet implemented* |
137
+ | **AES-128** | ✅ native | — | All browsers |
138
+
139
+ > **Note:** FairPlay (Safari/iOS) is planned for a future release. When Widevine content is loaded in Safari, Playron automatically shows a DRM error overlay with browser recommendations.
140
+
141
+ ### UI Controls
142
+
143
+ | Control | Description |
144
+ |---------|-------------|
145
+ | Play / Pause | Center overlay + control bar |
146
+ | Seek Bar | Scrubbing, buffered range visualization, thumbnail preview on hover |
147
+ | Volume | Slider + mute toggle, localStorage persistence |
148
+ | Playback Speed | 0.25× – 2× |
149
+ | Quality Selector | Manual ABR override |
150
+ | Audio Track | Multi-language audio |
151
+ | Subtitles | WebVTT + CEA-608/708 closed captions |
152
+ | Fullscreen | Native API |
153
+ | Picture-in-Picture | Native API |
154
+ | Theater Mode | Layout toggle |
155
+ | AirPlay | Safari WebKit API |
156
+ | Skip Forward / Backward | Configurable seconds |
157
+ | Skip Intro / Outro | Time-range based |
158
+ | Chapters | Navigation + auto-detection |
159
+ | Jump to Live | Appears when behind live edge |
160
+ | Live Latency Display | "Xs behind live" indicator |
161
+ | Timeline Markers | Sports events, chapters, ads |
162
+ | Settings Panel | YouTube-style unified panel (Quality · Speed · Audio · Subtitles) |
163
+ | Keyboard Shortcuts | Space, M, F, arrows, I, O, and more |
164
+ | Error Overlay | DRM-aware messages, network errors, retry |
165
+ | End Card | Next episode countdown |
166
+ | Context Menu | Loop, copy URL, copy speed |
167
+
168
+ ### Ad System
169
+
170
+ | Format | Support |
171
+ |--------|---------|
172
+ | VAST 2.0 / 3.0 / 4.x | ✅ |
173
+ | VMAP 1.0 | ✅ |
174
+ | Pre-roll | ✅ |
175
+ | Mid-roll | ✅ |
176
+ | Post-roll | ✅ |
177
+ | Skip button | ✅ configurable delay |
178
+ | VPAID 2.0 | ✅ iframe sandbox |
179
+ | Companion banner | ✅ |
180
+ | Ad pod | ✅ |
181
+ | Impression / tracking events | ✅ |
182
+
183
+ ### Accessibility
184
+
185
+ - WCAG 2.1 AA compliant
186
+ - ARIA roles on all interactive elements
187
+ - Full keyboard navigation
188
+ - Screen reader live region for status announcements
189
+
190
+ ---
191
+
192
+ ## Configuration
190
193
 
191
- ```typescript
192
- // Available events
193
- 'play' | 'pause' | 'ended' | 'error' |
194
- 'timeupdate' | 'volumechange' | 'mute' | 'unmute' |
195
- 'seeked' | 'seeking' | 'loadstart' | 'loadeddata' |
196
- 'canplay' | 'waiting' | 'stalled'
197
- ```
194
+ ```tsx
195
+ <Player
196
+ src="..."
197
+ config={{
198
+ player: {
199
+ defaultVolume: 1, // 0–1
200
+ defaultPlaybackRate: 1,
201
+ skipSeconds: 10,
202
+ autoResume: true,
203
+ loop: false,
204
+ preload: 'auto', // 'none' | 'metadata' | 'auto'
205
+ },
198
206
 
199
- ## Advanced Usage
207
+ ui: {
208
+ autoHideDelay: 3000, // ms
209
+ showTitle: true,
210
+ showTimeTooltip: true,
211
+ showVolumeSlider: true,
212
+ controlBarPosition: 'bottom',
213
+ },
200
214
 
201
- ### Custom Controls (React)
215
+ features: {
216
+ pip: true,
217
+ fullscreen: true,
218
+ theaterMode: true,
219
+ chapters: true,
220
+ skipIntro: true,
221
+ subtitles: true,
222
+ qualitySelector: true,
223
+ audioTrackSelector: true,
224
+ playbackSpeed: true,
225
+ keyboardShortcuts: true,
226
+ },
202
227
 
203
- ```tsx
204
- import { PlayerCore, EventBus } from 'playron';
205
- import { ControlBar, PlayButton, MuteButton } from 'playron';
228
+ branding: {
229
+ primaryColor: '#e50914', // hex
230
+ accentColor: '#ffffff',
231
+ logo: 'https://example.com/logo.svg',
232
+ logoLink: 'https://example.com',
233
+ },
206
234
 
207
- function CustomPlayer() {
208
- return (
209
- <div className="custom-player">
210
- <video id="my-video" />
211
- <ControlBar>
212
- <PlayButton />
213
- <MuteButton />
214
- {/* Kendi custom kontrollerini ekle */}
215
- </ControlBar>
216
- </div>
217
- );
218
- }
219
- ```
235
+ metadata: {
236
+ title: 'My Video',
237
+ thumbnail: 'https://example.com/thumb.jpg',
238
+ rating: 'TV-MA',
239
+ },
220
240
 
221
- ### DRM Kullanımı
241
+ thumbnails: {
242
+ vttUrl: 'https://example.com/thumbnails.vtt', // storyboard preview
243
+ },
222
244
 
223
- ```tsx
224
- <Player
225
- src="https://example.com/encrypted-video.mpd"
226
- drm={{
227
- widevine: {
228
- licenseUrl: 'https://example.com/widevine-license'
245
+ drm: {
246
+ enabled: true,
247
+ widevine: {
248
+ licenseUrl: 'https://license.example.com/widevine',
249
+ headers: { 'Authorization': 'Bearer TOKEN' },
250
+ withCredentials: false,
251
+ },
252
+ playready: {
253
+ licenseUrl: 'https://license.example.com/playready',
254
+ },
255
+ // fairplay: not yet implemented
256
+ preferredSystem: 'widevine',
257
+ },
258
+
259
+ ads: {
260
+ enabled: true,
261
+ vmapUrl: 'https://ads.example.com/vmap.xml', // takes priority over vastUrl
262
+ vastUrl: 'https://ads.example.com/vast.xml',
263
+ skipAfter: 5, // seconds before skip button appears
264
+ timeout: 10000, // fetch timeout ms
265
+ maxWrapperDepth: 5, // VAST wrapper chain limit
266
+ },
267
+
268
+ live: {
269
+ atLiveEdgeTolerance: 3, // seconds
270
+ showJumpToLiveButton: true,
271
+ showLatency: true,
272
+ dvr: { enabled: true, maxDvrWindow: 1800 },
273
+ },
274
+
275
+ advanced: {
276
+ bufferAhead: 30,
277
+ bufferBehind: 10,
278
+ maxBufferLength: 60,
279
+ debug: false,
229
280
  },
230
- playready: {
231
- licenseUrl: 'https://example.com/playready-license'
232
- }
233
281
  }}
234
282
  />
235
283
  ```
236
284
 
237
- ### VAST/VMAP Ads
285
+ ---
286
+
287
+ ## DRM Usage
288
+
289
+ ### Widevine (Chrome / Firefox / Edge)
238
290
 
239
291
  ```tsx
240
292
  <Player
241
- src="https://example.com/video.m3u8"
242
- ads={{
243
- vastUrl: 'https://example.com/vast.xml',
244
- // or
245
- vmapUrl: 'https://example.com/vmap.xml'
293
+ src="https://example.com/encrypted.mpd"
294
+ config={{
295
+ drm: {
296
+ enabled: true,
297
+ widevine: {
298
+ licenseUrl: 'https://license.example.com/widevine',
299
+ headers: { 'Authorization': 'Bearer YOUR_TOKEN' },
300
+ },
301
+ },
246
302
  }}
247
303
  />
248
304
  ```
249
305
 
250
- ## Development
306
+ ### Safari / iOS
251
307
 
252
- ```bash
253
- # Install dependencies
254
- npm install
308
+ FairPlay is not yet implemented. When a user on Safari attempts to play Widevine-protected content, Playron shows a DRM error overlay recommending Chrome or Firefox. This behaviour is automatic — no extra configuration needed.
255
309
 
256
- # Development mode
257
- npm run dev
310
+ ---
258
311
 
259
- # Build library
260
- npm run build
312
+ ## Event System
313
+
314
+ ```tsx
315
+ import { PlayerCore } from 'playron'
316
+
317
+ const player = new PlayerCore(videoElement)
318
+
319
+ player.eventEmitter.on('play', ({ timestamp }) => { })
320
+ player.eventEmitter.on('pause', ({ timestamp }) => { })
321
+ player.eventEmitter.on('ended', ({ timestamp }) => { })
322
+ player.eventEmitter.on('timeupdate', ({ currentTime, duration }) => { })
323
+ player.eventEmitter.on('volumechange',({ volume, isMuted }) => { })
324
+ player.eventEmitter.on('qualitychange',({ from, to }) => { })
325
+ player.eventEmitter.on('error', ({ code, message, details }) => { })
326
+ player.eventEmitter.on('ready', ({ player }) => { })
327
+ player.eventEmitter.on('destroy', ({ timestamp }) => { })
328
+
329
+ // One-time listener
330
+ player.eventEmitter.once('ready', ({ player }) => player.play())
331
+
332
+ // Remove listener
333
+ player.eventEmitter.off('play', handler)
334
+ ```
335
+
336
+ ### React Hooks
337
+
338
+ ```tsx
339
+ import { usePlayerState, usePlayerMethods, usePlayer } from 'playron'
340
+
341
+ function MyControls() {
342
+ const { isPlaying, volume, currentTime, duration, isLive, isBuffering } = usePlayerState()
343
+ const { play, pause, seekTo, setVolume, seekToLiveEdge } = usePlayerMethods()
344
+ const player = usePlayer() // raw PlayerCore instance
345
+ }
346
+ ```
347
+
348
+ ---
349
+
350
+ ## PlayerCore API
351
+
352
+ ```typescript
353
+ class PlayerCore {
354
+ // Playback
355
+ play(): Promise<void>
356
+ pause(): void
357
+ seekTo(time: number): void
358
+ setPlaybackRate(rate: number): void
359
+
360
+ // Volume
361
+ setVolume(volume: number): void // 0–1
362
+ toggleMute(): void
363
+
364
+ // Display
365
+ toggleFullscreen(): Promise<void>
366
+ togglePip(): Promise<void>
367
+ toggleTheaterMode(): void
368
+
369
+ // Stream
370
+ setSource(src: string): Promise<void>
371
+ getStreamType(): 'hls' | 'dash' | 'mp4' | 'unknown'
372
+ isLive(): boolean
373
+
374
+ // Live
375
+ seekToLiveEdge(): void
376
+ isAtLiveEdge(): boolean
377
+ getCurrentLatency(): number
378
+ getDVRRange(): { start: number; end: number } | null
379
+
380
+ // Quality / Audio / Subtitles
381
+ setQuality(id: string): void
382
+ getAvailableQualities(): QualityLevel[]
383
+ setAudioTrack(id: string): void
384
+ getAvailableAudioTracks(): AudioTrack[]
385
+
386
+ // Skip
387
+ skipForward(seconds?: number): void
388
+ skipBackward(seconds?: number): void
389
+
390
+ // DRM
391
+ setupDrm(config: DrmConfig): void
392
+
393
+ // Buffer
394
+ getBufferedRanges(): Array<{ start: number; end: number }>
261
395
 
262
- # Lint
263
- npm run lint
396
+ // Cleanup
397
+ destroy(): void
398
+ }
264
399
  ```
265
400
 
266
- ## Build Output
401
+ ---
402
+
403
+ ## Bundle Size
404
+
405
+ | File | Raw | Gzip |
406
+ |------|-----|------|
407
+ | `playron.es.js` | 2.1 MB | **559 KB** |
408
+ | `playron.cjs.js` | 1.6 MB | **490 KB** |
409
+ | `playron.css` | 5.9 KB | **2 KB** |
410
+
411
+ > Bundle includes hls.js + dash.js streaming engines, DRM passthrough layer, VAST/VMAP ad engine, WebVTT + CEA-608 subtitle decoders, and full React UI. In production, ESM tree-shaking eliminates unused modules.
412
+
413
+ ---
267
414
 
268
- Build sonrası `dist/` klasöründe:
269
- - `playron.es.js` - ES Module (modern projeler için)
270
- - `playron.umd.js` - UMD format (browser'da direkt kullanım)
271
- - `playron.css` - Styles
272
- - `index.d.ts` - TypeScript definitions
415
+ ## Framework Support
416
+
417
+ | Framework | Support | Notes |
418
+ |-----------|---------|-------|
419
+ | React 18 / 19 | ✅ Full | Hooks + Context API |
420
+ | Next.js App Router | ✅ Full | Add `'use client'` |
421
+ | Next.js Pages Router | ✅ Full | Use `dynamic(..., { ssr: false })` |
422
+ | Vite + React | ✅ Full | Reference dev environment |
423
+ | Remix | ✅ Full | Use `ClientOnly` wrapper |
424
+ | Astro | 🟡 Partial | `client:only="react"` |
425
+ | Vanilla JS | 🟡 Partial | Use `PlayerCore` directly |
426
+ | Vue / Nuxt | 🟡 Partial | Mount `PlayerCore` in `onMounted` |
427
+
428
+ ---
273
429
 
274
430
  ## Browser Support
275
431
 
276
- - Chrome/Edge 90+
277
- - Firefox 88+
278
- - Safari 14+
279
- - Mobile browsers (iOS Safari 14+, Chrome Android 90+)
432
+ | Browser | HLS | DASH | Widevine | PlayReady | FairPlay |
433
+ |---------|-----|------|----------|-----------|---------|
434
+ | Chrome 90+ | ✅ | ✅ | ✅ | — | — |
435
+ | Firefox 88+ | | | ✅ | — | — |
436
+ | Edge 90+ | ✅ | ✅ | ✅ | ✅ | — |
437
+ | Safari 14+ | ✅ | ✅ | ❌ | — | ⏳ planned |
438
+ | iOS Safari 14+ | ✅ | ✅ | ❌ | — | ⏳ planned |
439
+ | Chrome Android | ✅ | ✅ | ✅ | — | — |
280
440
 
281
- ## License
441
+ ---
282
442
 
283
- MIT
443
+ ## Development
284
444
 
285
- ## Author
445
+ ```bash
446
+ npm install
447
+
448
+ npm run dev # HTTPS dev server (port 5173)
449
+ npm run build # TypeScript check + library build
450
+ npm run build:watch # Watch mode
451
+ npm run push # Build + yalc push to linked projects
452
+ npm run lint # ESLint
453
+ ```
454
+
455
+ > **HTTPS is required.** See `SSL-SETUP.md` for local certificate setup.
456
+
457
+ ---
458
+
459
+ ## Roadmap
460
+
461
+ - [x] HLS engine (hls.js wrapper)
462
+ - [x] DASH engine (dash.js wrapper)
463
+ - [x] Widevine DRM — HLS + DASH
464
+ - [x] PlayReady DRM — DASH
465
+ - [x] AES-128 HLS decryption
466
+ - [x] VAST / VMAP ad system
467
+ - [x] WebVTT subtitles
468
+ - [x] CEA-608 / 708 closed captions
469
+ - [x] Live stream + DVR
470
+ - [x] LL-HLS / LL-DASH
471
+ - [x] Thumbnail storyboard preview
472
+ - [x] AirPlay
473
+ - [x] Analytics plugin
474
+ - [x] Stall detection + auto-recovery
475
+ - [x] DRM-aware error overlay
476
+ - [ ] **FairPlay** — Safari / iOS *(in progress)*
477
+ - [ ] Chromecast
478
+ - [ ] SSAI (Google DAI / AWS Elemental)
479
+ - [ ] TTML / IMSC subtitles
480
+ - [ ] Offline playback (Service Worker)
481
+ - [ ] 360° video (WebGL)
482
+
483
+ ---
484
+
485
+ ## License
286
486
 
287
- Suat Erkilic
487
+ MIT © Suat Erkilic
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playron",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Modern OTT video player for React, Next.js, and vanilla JS",
5
5
  "type": "module",
6
6
  "main": "./dist/playron.cjs.js",