@obipascal/player 1.0.1 → 1.0.3
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 +261 -40
- package/dist/src/react.d.ts +3 -2
- package/dist/wontum-player.cjs.js +12 -12
- package/dist/wontum-player.esm.js +133 -128
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@ A modern, feature-rich HLS video player SDK for educational platforms with Cloud
|
|
|
5
5
|
## ✨ Features
|
|
6
6
|
|
|
7
7
|
### Core Playback
|
|
8
|
+
|
|
8
9
|
- 🎬 **HLS Streaming**: Full HLS.js support with adaptive bitrate streaming
|
|
9
10
|
- 🔒 **CloudFront Integration**: Native support for CloudFront signed cookies and S3-hosted videos
|
|
10
11
|
- 🎯 **Skip Controls**: 10-second forward/backward skip with circular arrow buttons
|
|
@@ -13,11 +14,13 @@ A modern, feature-rich HLS video player SDK for educational platforms with Cloud
|
|
|
13
14
|
- 🎛️ **Playback Rate**: Adjustable speed (0.5x - 2x)
|
|
14
15
|
|
|
15
16
|
### Subtitle & Accessibility
|
|
17
|
+
|
|
16
18
|
- 📝 **Subtitle Support**: Full subtitle/caption support with programmatic API
|
|
17
19
|
- 🌐 **Multi-language**: Support for multiple subtitle tracks with language selection
|
|
18
20
|
- ♿ **Accessibility**: WCAG compliant with keyboard navigation
|
|
19
21
|
|
|
20
22
|
### UI & Controls
|
|
23
|
+
|
|
21
24
|
- 🎨 **Modern UI Design**: Beautiful controls with blur effects, gradients, and smooth animations
|
|
22
25
|
- 🖱️ **Smart Controls**: Auto-hide on inactivity, fade on hover
|
|
23
26
|
- 📍 **Sticky Controls**: Optional persistent controls (toggle in settings)
|
|
@@ -27,6 +30,7 @@ A modern, feature-rich HLS video player SDK for educational platforms with Cloud
|
|
|
27
30
|
- 🎨 **Custom Theming**: Full CSS variable theming with 8 customizable properties
|
|
28
31
|
|
|
29
32
|
### Developer Experience
|
|
33
|
+
|
|
30
34
|
- ⚛️ **React Support**: Component, Hook, and Context Provider patterns
|
|
31
35
|
- 🔧 **TypeScript**: Full TypeScript support with comprehensive type definitions
|
|
32
36
|
- 📊 **Analytics & QoE**: Built-in analytics tracking and Quality of Experience metrics
|
|
@@ -98,7 +102,7 @@ yarn add @obipascal/player hls.js
|
|
|
98
102
|
player.on("timeupdate", (event) => {
|
|
99
103
|
console.log("Current time:", event.data.currentTime)
|
|
100
104
|
})
|
|
101
|
-
|
|
105
|
+
|
|
102
106
|
// Programmatic subtitle control
|
|
103
107
|
player.enableSubtitles(0) // Enable first subtitle track
|
|
104
108
|
player.toggleSubtitles() // Toggle subtitles on/off
|
|
@@ -213,43 +217,165 @@ function ControlPanel() {
|
|
|
213
217
|
|
|
214
218
|
## 🔒 CloudFront & S3 Integration
|
|
215
219
|
|
|
216
|
-
|
|
220
|
+
This player supports **three video hosting scenarios**. Choose the one that fits your needs:
|
|
221
|
+
|
|
222
|
+
### Scenario 1: Public Videos (Easiest - No Authentication Required)
|
|
223
|
+
|
|
224
|
+
**When to use:** Your videos are publicly accessible and don't require user authentication.
|
|
217
225
|
|
|
218
|
-
|
|
226
|
+
**Setup:** Just provide the video URL!
|
|
219
227
|
|
|
220
228
|
```typescript
|
|
221
229
|
import { WontumPlayer } from "@obipascal/player"
|
|
222
230
|
|
|
223
|
-
// Your backend sets signed cookies for CloudFront
|
|
224
|
-
// Cookie names: CloudFront-Policy, CloudFront-Signature, CloudFront-Key-Pair-Id
|
|
225
|
-
|
|
226
231
|
const player = new WontumPlayer({
|
|
227
|
-
src: "https://
|
|
232
|
+
src: "https://d1234567890.cloudfront.net/video/playlist.m3u8",
|
|
228
233
|
container: "#player",
|
|
229
|
-
s3Config: {
|
|
230
|
-
cloudfront: {
|
|
231
|
-
domain: "media.yourdomain.com",
|
|
232
|
-
// Cookies are automatically sent by browser
|
|
233
|
-
},
|
|
234
|
-
},
|
|
235
234
|
})
|
|
236
235
|
```
|
|
237
236
|
|
|
238
|
-
|
|
237
|
+
✅ **That's it!** No backend needed. Works for public S3 buckets or CloudFront distributions.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
### Scenario 2: Private Videos with CloudFront Signed Cookies (Recommended)
|
|
242
|
+
|
|
243
|
+
**When to use:** You want to restrict video access to authorized users (e.g., paid courses, premium content).
|
|
244
|
+
|
|
245
|
+
**How it works:**
|
|
246
|
+
|
|
247
|
+
1. User logs into your app
|
|
248
|
+
2. Your backend verifies the user and sets CloudFront signed cookies
|
|
249
|
+
3. Player automatically sends these cookies with every video request
|
|
250
|
+
4. CloudFront checks the cookies and allows/denies access
|
|
251
|
+
|
|
252
|
+
**Frontend Setup:**
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
import { WontumPlayer } from "@obipascal/player"
|
|
256
|
+
|
|
257
|
+
// STEP 1: Call your backend to set signed cookies BEFORE creating the player
|
|
258
|
+
async function initializePlayer() {
|
|
259
|
+
// This endpoint sets CloudFront cookies in the browser
|
|
260
|
+
await fetch("/api/auth/video-access", {
|
|
261
|
+
credentials: "include", // Important: include cookies
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
// STEP 2: Create player - it will automatically use the cookies
|
|
265
|
+
const player = new WontumPlayer({
|
|
266
|
+
src: "https://media.yourdomain.com/videos/lesson-1/playlist.m3u8",
|
|
267
|
+
container: "#player",
|
|
268
|
+
s3Config: {
|
|
269
|
+
cloudFrontDomains: ["media.yourdomain.com"], // Your CloudFront domain
|
|
270
|
+
signUrl: async (url) => {
|
|
271
|
+
// This function is called when player needs to access a video
|
|
272
|
+
// Call your backend to refresh/set cookies if needed
|
|
273
|
+
const response = await fetch("/api/auth/sign-url", {
|
|
274
|
+
method: "POST",
|
|
275
|
+
headers: { "Content-Type": "application/json" },
|
|
276
|
+
credentials: "include",
|
|
277
|
+
body: JSON.stringify({ url }),
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
if (!response.ok) {
|
|
281
|
+
throw new Error("Failed to authenticate video access")
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Backend sets cookies, return the URL
|
|
285
|
+
return url
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
})
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
initializePlayer()
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Backend Setup (Node.js/Express):**
|
|
239
295
|
|
|
240
296
|
```typescript
|
|
241
|
-
|
|
242
|
-
import { CloudFrontClient } from "@aws-sdk/client-cloudfront"
|
|
297
|
+
import express from "express"
|
|
243
298
|
import { getSignedCookies } from "@aws-sdk/cloudfront-signer"
|
|
299
|
+
import fs from "fs"
|
|
300
|
+
|
|
301
|
+
const app = express()
|
|
302
|
+
|
|
303
|
+
// STEP 1: Create endpoint that sets CloudFront signed cookies
|
|
304
|
+
app.get("/api/auth/video-access", (req, res) => {
|
|
305
|
+
// Check if user is logged in (your authentication logic)
|
|
306
|
+
if (!req.user) {
|
|
307
|
+
return res.status(401).json({ error: "Not authenticated" })
|
|
308
|
+
}
|
|
244
309
|
|
|
245
|
-
|
|
310
|
+
// Define what resources user can access
|
|
311
|
+
const policy = {
|
|
312
|
+
Statement: [
|
|
313
|
+
{
|
|
314
|
+
Resource: "https://media.yourdomain.com/*", // All videos on this domain
|
|
315
|
+
Condition: {
|
|
316
|
+
DateLessThan: {
|
|
317
|
+
"AWS:EpochTime": Math.floor(Date.now() / 1000) + 3600, // Expires in 1 hour
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Generate CloudFront signed cookies
|
|
325
|
+
const cookies = getSignedCookies({
|
|
326
|
+
keyPairId: process.env.CLOUDFRONT_KEY_PAIR_ID!, // Your CloudFront key pair ID
|
|
327
|
+
privateKey: fs.readFileSync("./cloudfront-private-key.pem", "utf8"), // Your private key
|
|
328
|
+
policy: JSON.stringify(policy),
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
// Set the three required cookies
|
|
332
|
+
res.cookie("CloudFront-Policy", cookies["CloudFront-Policy"], {
|
|
333
|
+
domain: ".yourdomain.com", // Use your domain
|
|
334
|
+
path: "/",
|
|
335
|
+
secure: true, // HTTPS only
|
|
336
|
+
httpOnly: true, // Prevent JavaScript access
|
|
337
|
+
sameSite: "none",
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
res.cookie("CloudFront-Signature", cookies["CloudFront-Signature"], {
|
|
341
|
+
domain: ".yourdomain.com",
|
|
342
|
+
path: "/",
|
|
343
|
+
secure: true,
|
|
344
|
+
httpOnly: true,
|
|
345
|
+
sameSite: "none",
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
res.cookie("CloudFront-Key-Pair-Id", cookies["CloudFront-Key-Pair-Id"], {
|
|
349
|
+
domain: ".yourdomain.com",
|
|
350
|
+
path: "/",
|
|
351
|
+
secure: true,
|
|
352
|
+
httpOnly: true,
|
|
353
|
+
sameSite: "none",
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
res.json({ success: true })
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
// STEP 2: Optional endpoint for on-demand signing (called by signUrl function)
|
|
360
|
+
app.post("/api/auth/sign-url", (req, res) => {
|
|
361
|
+
const { url } = req.body
|
|
362
|
+
|
|
363
|
+
// Verify user is authorized
|
|
364
|
+
if (!req.user) {
|
|
365
|
+
return res.status(401).json({ error: "Not authenticated" })
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// You can add additional authorization logic here
|
|
369
|
+
// For example, check if user has access to this specific video
|
|
370
|
+
|
|
371
|
+
// Refresh cookies (same code as above)
|
|
246
372
|
const policy = {
|
|
247
373
|
Statement: [
|
|
248
374
|
{
|
|
249
375
|
Resource: "https://media.yourdomain.com/*",
|
|
250
376
|
Condition: {
|
|
251
377
|
DateLessThan: {
|
|
252
|
-
"AWS:EpochTime": Math.floor(Date.now() / 1000) + 3600,
|
|
378
|
+
"AWS:EpochTime": Math.floor(Date.now() / 1000) + 3600,
|
|
253
379
|
},
|
|
254
380
|
},
|
|
255
381
|
},
|
|
@@ -257,43 +383,142 @@ app.get("/api/video-auth", async (req, res) => {
|
|
|
257
383
|
}
|
|
258
384
|
|
|
259
385
|
const cookies = getSignedCookies({
|
|
260
|
-
keyPairId: process.env.CLOUDFRONT_KEY_PAIR_ID
|
|
261
|
-
privateKey:
|
|
386
|
+
keyPairId: process.env.CLOUDFRONT_KEY_PAIR_ID!,
|
|
387
|
+
privateKey: fs.readFileSync("./cloudfront-private-key.pem", "utf8"),
|
|
262
388
|
policy: JSON.stringify(policy),
|
|
263
389
|
})
|
|
264
390
|
|
|
265
|
-
// Set cookies
|
|
266
391
|
res.cookie("CloudFront-Policy", cookies["CloudFront-Policy"], {
|
|
267
392
|
domain: ".yourdomain.com",
|
|
393
|
+
path: "/",
|
|
268
394
|
secure: true,
|
|
269
395
|
httpOnly: true,
|
|
396
|
+
sameSite: "none",
|
|
270
397
|
})
|
|
398
|
+
|
|
271
399
|
res.cookie("CloudFront-Signature", cookies["CloudFront-Signature"], {
|
|
272
400
|
domain: ".yourdomain.com",
|
|
401
|
+
path: "/",
|
|
273
402
|
secure: true,
|
|
274
403
|
httpOnly: true,
|
|
404
|
+
sameSite: "none",
|
|
275
405
|
})
|
|
406
|
+
|
|
276
407
|
res.cookie("CloudFront-Key-Pair-Id", cookies["CloudFront-Key-Pair-Id"], {
|
|
277
408
|
domain: ".yourdomain.com",
|
|
409
|
+
path: "/",
|
|
278
410
|
secure: true,
|
|
279
411
|
httpOnly: true,
|
|
412
|
+
sameSite: "none",
|
|
280
413
|
})
|
|
281
414
|
|
|
282
415
|
res.json({ success: true })
|
|
283
416
|
})
|
|
284
417
|
```
|
|
285
418
|
|
|
286
|
-
|
|
419
|
+
**AWS CloudFront Setup:**
|
|
420
|
+
|
|
421
|
+
1. Create a CloudFront key pair in AWS Console → CloudFront → Key pairs
|
|
422
|
+
2. Download the private key file
|
|
423
|
+
3. Set up environment variables:
|
|
424
|
+
```bash
|
|
425
|
+
CLOUDFRONT_KEY_PAIR_ID=APKA...
|
|
426
|
+
```
|
|
427
|
+
4. Configure your CloudFront distribution to require signed cookies
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
### Scenario 3: Private S3 Videos with Presigned URLs
|
|
432
|
+
|
|
433
|
+
**When to use:** Videos are in private S3 buckets without CloudFront.
|
|
434
|
+
|
|
435
|
+
**How it works:**
|
|
436
|
+
|
|
437
|
+
1. Your backend generates temporary presigned URLs for S3 objects
|
|
438
|
+
2. Player uses these URLs to access videos
|
|
439
|
+
3. URLs expire after a set time (e.g., 1 hour)
|
|
287
440
|
|
|
288
|
-
|
|
441
|
+
**Frontend Setup:**
|
|
289
442
|
|
|
290
443
|
```typescript
|
|
444
|
+
import { WontumPlayer } from "@obipascal/player"
|
|
445
|
+
|
|
291
446
|
const player = new WontumPlayer({
|
|
292
|
-
src: "
|
|
447
|
+
src: "s3://my-bucket/videos/lesson-1/playlist.m3u8", // S3 URI
|
|
293
448
|
container: "#player",
|
|
449
|
+
s3Config: {
|
|
450
|
+
getPresignedUrl: async (s3Key) => {
|
|
451
|
+
// Call your backend to generate presigned URL
|
|
452
|
+
const response = await fetch("/api/s3/presigned-url", {
|
|
453
|
+
method: "POST",
|
|
454
|
+
headers: { "Content-Type": "application/json" },
|
|
455
|
+
body: JSON.stringify({ key: s3Key }),
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
if (!response.ok) {
|
|
459
|
+
throw new Error("Failed to get presigned URL")
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const data = await response.json()
|
|
463
|
+
return data.url // Return the presigned URL
|
|
464
|
+
},
|
|
465
|
+
},
|
|
294
466
|
})
|
|
295
467
|
```
|
|
296
468
|
|
|
469
|
+
**Backend Setup (Node.js):**
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3"
|
|
473
|
+
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"
|
|
474
|
+
|
|
475
|
+
const s3Client = new S3Client({
|
|
476
|
+
region: "us-east-1",
|
|
477
|
+
credentials: {
|
|
478
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
479
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
480
|
+
},
|
|
481
|
+
})
|
|
482
|
+
|
|
483
|
+
app.post("/api/s3/presigned-url", async (req, res) => {
|
|
484
|
+
const { key } = req.body
|
|
485
|
+
|
|
486
|
+
// Verify user is authorized to access this video
|
|
487
|
+
if (!req.user) {
|
|
488
|
+
return res.status(401).json({ error: "Not authenticated" })
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
try {
|
|
492
|
+
// Generate presigned URL
|
|
493
|
+
const command = new GetObjectCommand({
|
|
494
|
+
Bucket: "my-bucket",
|
|
495
|
+
Key: key, // e.g., "videos/lesson-1/playlist.m3u8"
|
|
496
|
+
})
|
|
497
|
+
|
|
498
|
+
const url = await getSignedUrl(s3Client, command, {
|
|
499
|
+
expiresIn: 3600, // URL valid for 1 hour
|
|
500
|
+
})
|
|
501
|
+
|
|
502
|
+
res.json({ url })
|
|
503
|
+
} catch (error) {
|
|
504
|
+
console.error("Error generating presigned URL:", error)
|
|
505
|
+
res.status(500).json({ error: "Failed to generate presigned URL" })
|
|
506
|
+
}
|
|
507
|
+
})
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
### Which Method Should I Use?
|
|
513
|
+
|
|
514
|
+
| Method | Best For | Complexity | Performance |
|
|
515
|
+
| ---------------------- | ---------------------------------------------- | ----------- | ------------ |
|
|
516
|
+
| **Public Videos** | Free content, marketing videos | ⭐ Easy | ⚡ Fast |
|
|
517
|
+
| **CloudFront Cookies** | ⭐ **Recommended** for paid courses, premium | ⭐⭐ Medium | ⚡⚡ Fastest |
|
|
518
|
+
| **S3 Presigned URLs** | Direct S3 access, simple private video hosting | ⭐⭐ Medium | ⚡ Good |
|
|
519
|
+
|
|
520
|
+
💡 **Tip:** Use CloudFront with signed cookies for production. It's more secure and performant for HLS videos (which have many file segments).
|
|
521
|
+
|
|
297
522
|
## 📝 Subtitle Support
|
|
298
523
|
|
|
299
524
|
### Adding Subtitles
|
|
@@ -568,15 +793,7 @@ function CustomPlayer() {
|
|
|
568
793
|
Wontum Player comes with 7 beautiful pre-made themes:
|
|
569
794
|
|
|
570
795
|
```typescript
|
|
571
|
-
import {
|
|
572
|
-
netflixTheme,
|
|
573
|
-
youtubeTheme,
|
|
574
|
-
modernTheme,
|
|
575
|
-
greenTheme,
|
|
576
|
-
cyberpunkTheme,
|
|
577
|
-
pastelTheme,
|
|
578
|
-
educationTheme,
|
|
579
|
-
} from "@obipascal/player"
|
|
796
|
+
import { netflixTheme, youtubeTheme, modernTheme, greenTheme, cyberpunkTheme, pastelTheme, educationTheme } from "@obipascal/player"
|
|
580
797
|
|
|
581
798
|
const player = new WontumPlayer({
|
|
582
799
|
src: "https://media.example.com/video/playlist.m3u8",
|
|
@@ -586,6 +803,7 @@ const player = new WontumPlayer({
|
|
|
586
803
|
```
|
|
587
804
|
|
|
588
805
|
**Available Themes:**
|
|
806
|
+
|
|
589
807
|
- `netflixTheme()` - Netflix-inspired red and black
|
|
590
808
|
- `youtubeTheme()` - YouTube-inspired red and white
|
|
591
809
|
- `modernTheme()` - Modern blue gradient
|
|
@@ -634,6 +852,7 @@ const player = new WontumPlayer({
|
|
|
634
852
|
```
|
|
635
853
|
|
|
636
854
|
**Available Brand Colors:**
|
|
855
|
+
|
|
637
856
|
- `blue`, `lightBlue`, `darkBlue`
|
|
638
857
|
- `red`, `lightRed`, `darkRed`
|
|
639
858
|
- `green`, `lightGreen`, `darkGreen`
|
|
@@ -788,6 +1007,7 @@ For detailed API documentation including all methods, events, types, and configu
|
|
|
788
1007
|
### Quick Reference
|
|
789
1008
|
|
|
790
1009
|
**Player Methods:**
|
|
1010
|
+
|
|
791
1011
|
- **Playback:** `play()`, `pause()`, `seek(time)`, `skipForward(seconds)`, `skipBackward(seconds)`
|
|
792
1012
|
- **Volume:** `setVolume(level)`, `mute()`, `unmute()`
|
|
793
1013
|
- **Subtitles:** `enableSubtitles(index)`, `disableSubtitles()`, `toggleSubtitles()`, `getSubtitleTracks()`, `areSubtitlesEnabled()`
|
|
@@ -798,6 +1018,7 @@ For detailed API documentation including all methods, events, types, and configu
|
|
|
798
1018
|
- **Lifecycle:** `destroy()`
|
|
799
1019
|
|
|
800
1020
|
**Events (25 total):**
|
|
1021
|
+
|
|
801
1022
|
- **Playback:** `play`, `pause`, `ended`, `timeupdate`, `durationchange`
|
|
802
1023
|
- **Loading:** `loadstart`, `loadedmetadata`, `loadeddata`, `canplay`, `canplaythrough`
|
|
803
1024
|
- **Buffering:** `waiting`, `playing`, `stalled`, `suspend`, `abort`
|
|
@@ -812,13 +1033,13 @@ For detailed API documentation including all methods, events, types, and configu
|
|
|
812
1033
|
|
|
813
1034
|
## 🌐 Browser Support
|
|
814
1035
|
|
|
815
|
-
| Browser
|
|
816
|
-
|
|
817
|
-
| Chrome
|
|
818
|
-
| Edge
|
|
819
|
-
| Firefox
|
|
820
|
-
| Safari
|
|
821
|
-
| iOS Safari
|
|
1036
|
+
| Browser | Minimum Version |
|
|
1037
|
+
| -------------- | ----------------- |
|
|
1038
|
+
| Chrome | Latest 2 versions |
|
|
1039
|
+
| Edge | Latest 2 versions |
|
|
1040
|
+
| Firefox | Latest 2 versions |
|
|
1041
|
+
| Safari | Latest 2 versions |
|
|
1042
|
+
| iOS Safari | iOS 12+ |
|
|
822
1043
|
| Android Chrome | Latest 2 versions |
|
|
823
1044
|
|
|
824
1045
|
**Note:** HLS playback requires HLS.js support. Native HLS playback is supported on Safari.
|
package/dist/src/react.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { default as React } from 'react';
|
|
2
1
|
import { WontumPlayer } from './player';
|
|
3
2
|
import { WontumPlayerConfig, PlayerState } from './types';
|
|
4
|
-
|
|
3
|
+
import * as React from "react";
|
|
5
4
|
export interface WontumPlayerReactProps extends Omit<WontumPlayerConfig, "container"> {
|
|
6
5
|
/** Callback when player is ready */
|
|
7
6
|
onReady?: (player: WontumPlayer) => void;
|
|
@@ -12,6 +11,8 @@ export interface WontumPlayerReactProps extends Omit<WontumPlayerConfig, "contai
|
|
|
12
11
|
onTimeUpdate?: (currentTime: number) => void;
|
|
13
12
|
onVolumeChange?: (volume: number, muted: boolean) => void;
|
|
14
13
|
onError?: (error: any) => void;
|
|
14
|
+
onLoadedMetadata?: () => void;
|
|
15
|
+
onQualityChange?: (level: number) => void;
|
|
15
16
|
/** Container style */
|
|
16
17
|
style?: React.CSSProperties;
|
|
17
18
|
/** Container className */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var lt=Object.defineProperty;var ct=(l,t,e)=>t in l?lt(l,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):l[t]=e;var o=(l,t,e)=>ct(l,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("hls.js"),v=require("react");function ut(l){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const e in l)if(e!=="default"){const s=Object.getOwnPropertyDescriptor(l,e);Object.defineProperty(t,e,s.get?s:{enumerable:!0,get:()=>l[e]})}}return t.default=l,Object.freeze(t)}const et=ut(v);class nt{constructor(t){o(this,"config");o(this,"sessionId");o(this,"events",[]);o(this,"sessionStartTime");o(this,"playbackStartTime",null);o(this,"totalPlayTime",0);o(this,"totalBufferTime",0);o(this,"bufferStartTime",null);o(this,"rebufferCount",0);o(this,"seekCount",0);var e;this.config=t,this.sessionId=(t==null?void 0:t.sessionId)||this.generateSessionId(),this.sessionStartTime=Date.now(),(e=this.config)!=null&&e.enabled&&this.trackEvent("session_start",this.getSessionData())}trackEvent(t,e={}){var r;if(!((r=this.config)!=null&&r.enabled))return;const s={eventType:t,timestamp:Date.now(),sessionId:this.sessionId,videoId:this.config.videoId,userId:this.config.userId,data:{...e,...this.getQoEMetrics()}};this.events.push(s),this.updateMetrics(t,e),this.config.endpoint&&this.sendEvent(s),process.env.NODE_ENV==="development"&&console.log("[Analytics]",t,s.data)}updateMetrics(t,e){switch(t){case"play":this.playbackStartTime=Date.now();break;case"pause":case"ended":this.playbackStartTime&&(this.totalPlayTime+=Date.now()-this.playbackStartTime,this.playbackStartTime=null);break;case"buffering_start":this.bufferStartTime=Date.now(),this.rebufferCount++;break;case"buffering_end":this.bufferStartTime&&(this.totalBufferTime+=Date.now()-this.bufferStartTime,this.bufferStartTime=null);break;case"seeked":this.seekCount++;break}}getQoEMetrics(){const t=Date.now()-this.sessionStartTime,e=this.totalPlayTime>0?this.totalBufferTime/this.totalPlayTime:0;return{sessionDuration:t,totalPlayTime:this.totalPlayTime,totalBufferTime:this.totalBufferTime,bufferingRatio:Math.round(e*1e3)/1e3,rebufferCount:this.rebufferCount,seekCount:this.seekCount}}getSessionData(){return{userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,screenResolution:`${screen.width}x${screen.height}`,viewport:`${window.innerWidth}x${window.innerHeight}`,connection:this.getConnectionInfo()}}getConnectionInfo(){const t=navigator,e=t.connection||t.mozConnection||t.webkitConnection;return e?{effectiveType:e.effectiveType,downlink:e.downlink,rtt:e.rtt,saveData:e.saveData}:null}async sendEvent(t){var e;if((e=this.config)!=null&&e.endpoint)try{await fetch(this.config.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}catch(s){console.error("Failed to send analytics event:",s)}}generateSessionId(){return`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}getEvents(){return[...this.events]}getMetrics(){return{sessionId:this.sessionId,...this.getQoEMetrics(),eventCount:this.events.length}}destroy(){var t;(t=this.config)!=null&&t.enabled&&this.trackEvent("session_end",this.getSessionData()),this.events=[]}}class st{constructor(t,e){o(this,"container");o(this,"player");o(this,"controlsContainer");o(this,"progressContainer");o(this,"progressBar");o(this,"playButton");o(this,"skipBackwardButton");o(this,"skipForwardButton");o(this,"volumeButton");o(this,"fullscreenButton");o(this,"qualityButton");o(this,"subtitleButton");o(this,"speedButton");o(this,"settingsButton");o(this,"volumeSlider");o(this,"progressInput");o(this,"hideControlsTimeout",null);o(this,"stickyControls",!1);this.container=t,this.player=e,this.injectStyles(),this.createProgressBar(),this.controlsContainer=this.createControls(),this.container.appendChild(this.controlsContainer),this.playButton=this.controlsContainer.querySelector(".wontum-play-btn"),this.skipBackwardButton=this.controlsContainer.querySelector(".wontum-skip-backward-btn"),this.skipForwardButton=this.controlsContainer.querySelector(".wontum-skip-forward-btn"),this.volumeButton=this.controlsContainer.querySelector(".wontum-volume-btn"),this.fullscreenButton=this.controlsContainer.querySelector(".wontum-fullscreen-btn"),this.qualityButton=this.controlsContainer.querySelector(".wontum-quality-btn"),this.subtitleButton=this.controlsContainer.querySelector(".wontum-subtitle-btn"),this.speedButton=this.controlsContainer.querySelector(".wontum-speed-btn"),this.settingsButton=this.controlsContainer.querySelector(".wontum-settings-btn"),this.volumeSlider=this.controlsContainer.querySelector(".wontum-volume-slider"),this.progressInput=this.container.querySelector(".wontum-progress-input"),this.progressBar=this.container.querySelector(".wontum-progress-filled"),this.stickyControls=this.player.config.stickyControls||!1,this.stickyControls&&this.controlsContainer.classList.add("sticky"),this.setupEventListeners(),this.setupPlayerEventListeners()}injectStyles(){const t="wontum-player-styles";if(document.getElementById(t))return;const e=this.player.config.theme||{},s=e.primaryColor||"#3b82f6",r=e.accentColor||"#2563eb",i=e.fontFamily||"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",c=e.controlsBackground||"linear-gradient(to top, rgba(0,0,0,0.8), transparent)",u=e.buttonHoverBg||"rgba(255, 255, 255, 0.1)",f=e.progressHeight||"6px",b=e.borderRadius||"4px",y=document.createElement("style");y.id=t,y.textContent=`
|
|
2
2
|
.wontum-player-container {
|
|
3
3
|
position: relative;
|
|
4
4
|
background: #000;
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
overflow: hidden;
|
|
7
7
|
--primary-color: ${s};
|
|
8
8
|
--accent-color: ${r};
|
|
9
|
-
--controls-bg: ${
|
|
9
|
+
--controls-bg: ${c};
|
|
10
10
|
--button-hover: ${u};
|
|
11
|
-
--progress-height: ${
|
|
11
|
+
--progress-height: ${f};
|
|
12
12
|
--border-radius: ${b};
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -463,7 +463,7 @@
|
|
|
463
463
|
transform: translateY(0) !important;
|
|
464
464
|
pointer-events: all !important;
|
|
465
465
|
}
|
|
466
|
-
`,document.head.appendChild(
|
|
466
|
+
`,document.head.appendChild(y),this.container.classList.add("wontum-player-container")}createProgressBar(){const t=document.createElement("div");t.className="wontum-progress-container",t.innerHTML=`
|
|
467
467
|
<div class="wontum-progress-track"></div>
|
|
468
468
|
<div class="wontum-progress-filled"></div>
|
|
469
469
|
<input type="range" class="wontum-progress-input" min="0" max="100" value="0" step="0.1">
|
|
@@ -535,18 +535,18 @@
|
|
|
535
535
|
<div class="wontum-loading" style="display: none;">
|
|
536
536
|
<div class="wontum-spinner"></div>
|
|
537
537
|
</div>
|
|
538
|
-
`,t}setupEventListeners(){this.playButton.addEventListener("click",()=>{this.player.getState().playing?this.player.pause():this.player.play()}),this.skipBackwardButton.addEventListener("click",()=>{this.player.skipBackward(10)}),this.skipForwardButton.addEventListener("click",()=>{this.player.skipForward(10)}),this.progressInput.addEventListener("input",e=>{const s=e.target,r=parseFloat(s.value),i=this.player.getState(),
|
|
538
|
+
`,t}setupEventListeners(){this.playButton.addEventListener("click",()=>{this.player.getState().playing?this.player.pause():this.player.play()}),this.skipBackwardButton.addEventListener("click",()=>{this.player.skipBackward(10)}),this.skipForwardButton.addEventListener("click",()=>{this.player.skipForward(10)}),this.progressInput.addEventListener("input",e=>{const s=e.target,r=parseFloat(s.value),i=this.player.getState(),c=r/100*i.duration;this.player.seek(c)}),this.volumeSlider.addEventListener("input",e=>{const s=e.target,r=parseFloat(s.value)/100;this.player.setVolume(r)}),this.volumeButton.addEventListener("click",()=>{this.player.getState().muted?this.player.unmute():this.player.mute()}),this.fullscreenButton.addEventListener("click",()=>{this.player.getState().fullscreen?this.player.exitFullscreen():this.player.enterFullscreen()}),this.qualityButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-quality-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-settings-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-subtitle-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-speed-menu"))==null||i.classList.remove("active")}),this.subtitleButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-subtitle-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-settings-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-quality-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-speed-menu"))==null||i.classList.remove("active"),this.updateSubtitleMenu()}),this.speedButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-speed-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-settings-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-quality-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-subtitle-menu"))==null||i.classList.remove("active"),this.updateSpeedMenu()}),this.settingsButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-settings-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-quality-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-subtitle-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-speed-menu"))==null||i.classList.remove("active"),this.updateSettingsMenu()}),this.player.getVideoElement().addEventListener("click",()=>{this.player.getState().playing?this.player.pause():this.player.play()}),this.container.addEventListener("mousemove",()=>{this.showControls(),this.resetHideControlsTimeout()}),this.container.addEventListener("mouseleave",()=>{this.hideControls()})}setupPlayerEventListeners(){this.player.on("play",()=>{this.playButton.innerHTML=this.getPauseIcon()}),this.player.on("pause",()=>{this.playButton.innerHTML=this.getPlayIcon()}),this.player.on("timeupdate",t=>{const{currentTime:e}=t.data,s=this.player.getState();if(s.duration>0){const i=e/s.duration*100;this.progressBar.style.width=`${i}%`,this.progressInput.value=i.toString()}const r=this.controlsContainer.querySelector(".wontum-current-time");r.textContent=this.formatTime(e)}),this.player.on("loadedmetadata",t=>{const{duration:e}=t.data,s=this.controlsContainer.querySelector(".wontum-duration");s.textContent=this.formatTime(e),t.data.qualities&&this.updateQualityMenu(t.data.qualities)}),this.player.on("volumechange",t=>{const{volume:e,muted:s}=t.data;this.volumeSlider.value=(e*100).toString(),this.volumeButton.innerHTML=s?this.getMutedIcon():this.getVolumeIcon()}),this.player.on("waiting",()=>{const t=this.controlsContainer.querySelector(".wontum-loading");t.style.display="block"}),this.player.on("canplay",()=>{const t=this.controlsContainer.querySelector(".wontum-loading");t.style.display="none"})}updateSubtitleMenu(){const t=this.controlsContainer.querySelector(".wontum-subtitle-menu"),e=this.player.getSubtitleTracks();if(e.length===0){t.innerHTML='<div class="wontum-subtitle-option">No subtitles available</div>';return}const s=e.findIndex(r=>r.mode==="showing");t.innerHTML=`
|
|
539
539
|
<div class="wontum-subtitle-option ${s===-1?"active":""}" data-track="-1">Off</div>
|
|
540
540
|
${e.map((r,i)=>`
|
|
541
541
|
<div class="wontum-subtitle-option ${i===s?"active":""}" data-track="${i}">
|
|
542
542
|
${r.label||r.language||`Track ${i+1}`}
|
|
543
543
|
</div>
|
|
544
544
|
`).join("")}
|
|
545
|
-
`,t.querySelectorAll(".wontum-subtitle-option").forEach(r=>{r.addEventListener("click",i=>{const
|
|
545
|
+
`,t.querySelectorAll(".wontum-subtitle-option").forEach(r=>{r.addEventListener("click",i=>{const c=i.target,u=parseInt(c.dataset.track||"-1");u===-1?this.player.disableSubtitles():this.player.enableSubtitles(u),t.querySelectorAll(".wontum-subtitle-option").forEach(f=>f.classList.remove("active")),c.classList.add("active"),t.classList.remove("active")})})}updateSpeedMenu(){const t=this.controlsContainer.querySelector(".wontum-speed-menu"),s=this.player.getState().playbackRate||1,r=[.25,.5,.75,1,1.25,1.5,1.75,2];t.innerHTML=r.map(i=>`
|
|
546
546
|
<div class="wontum-speed-option ${s===i?"active":""}" data-speed="${i}">
|
|
547
547
|
${i===1?"Normal":i+"x"}
|
|
548
548
|
</div>
|
|
549
|
-
`).join(""),t.querySelectorAll(".wontum-speed-option").forEach(i=>{i.addEventListener("click",
|
|
549
|
+
`).join(""),t.querySelectorAll(".wontum-speed-option").forEach(i=>{i.addEventListener("click",c=>{const u=c.target,f=parseFloat(u.dataset.speed||"1");this.player.setPlaybackRate(f),t.querySelectorAll(".wontum-speed-option").forEach(b=>b.classList.remove("active")),u.classList.add("active"),t.classList.remove("active")})})}updateSettingsMenu(){const t=this.controlsContainer.querySelector(".wontum-settings-menu");t.innerHTML=`
|
|
550
550
|
<div class="wontum-settings-option" data-setting="sticky-controls">
|
|
551
551
|
<span>Sticky Controls</span>
|
|
552
552
|
<div class="wontum-toggle-switch ${this.stickyControls?"active":""}"></div>
|
|
@@ -556,7 +556,7 @@
|
|
|
556
556
|
${t.map((s,r)=>`
|
|
557
557
|
<div class="wontum-quality-option" data-quality="${r}">${s.name}</div>
|
|
558
558
|
`).join("")}
|
|
559
|
-
`,e.querySelectorAll(".wontum-quality-option").forEach(s=>{s.addEventListener("click",r=>{const i=r.target,
|
|
559
|
+
`,e.querySelectorAll(".wontum-quality-option").forEach(s=>{s.addEventListener("click",r=>{const i=r.target,c=parseInt(i.dataset.quality||"-1");this.player.setQuality(c),e.querySelectorAll(".wontum-quality-option").forEach(u=>u.classList.remove("active")),i.classList.add("active"),e.classList.remove("active")})})}showControls(){this.controlsContainer.classList.remove("hidden"),this.progressContainer.classList.remove("hidden")}hideControls(){if(this.stickyControls)return;this.player.getState().playing&&(this.controlsContainer.classList.add("hidden"),this.progressContainer.classList.add("hidden"))}resetHideControlsTimeout(){this.stickyControls||(this.hideControlsTimeout&&clearTimeout(this.hideControlsTimeout),this.hideControlsTimeout=window.setTimeout(()=>{this.hideControls()},1e4))}formatTime(t){if(isNaN(t))return"0:00";const e=Math.floor(t/60),s=Math.floor(t%60);return`${e}:${s.toString().padStart(2,"0")}`}getPlayIcon(){return'<svg viewBox="0 0 24 24"><path fill="white" d="M8 5v14l11-7z"/></svg>'}getPauseIcon(){return'<svg viewBox="0 0 24 24"><path fill="white" d="M6 4h4v16H6V4zm8 0h4v16h-4V4z"/></svg>'}getVolumeIcon(){return'<svg viewBox="0 0 24 24"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>'}getMutedIcon(){return'<svg viewBox="0 0 24 24"><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/></svg>'}getFullscreenIcon(){return'<svg viewBox="0 0 24 24"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>'}getQualityIcon(){return'<svg viewBox="0 0 24 24"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z"/></svg>'}getSkipBackwardIcon(){return`<svg viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
560
560
|
<circle cx="30" cy="30" r="28" stroke="white" stroke-width="2"/>
|
|
561
561
|
<!-- Circular arrow backward -->
|
|
562
562
|
<path d="M30 12 A18 18 0 1 0 30 48" stroke="white" stroke-width="2.5" stroke-linecap="round" fill="none"/>
|
|
@@ -568,7 +568,7 @@
|
|
|
568
568
|
<path d="M30 12 A18 18 0 1 1 30 48" stroke="white" stroke-width="2.5" stroke-linecap="round" fill="none"/>
|
|
569
569
|
<path d="M35 12 L30 12 L30 17" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
|
570
570
|
<text x="30" y="35" font-family="Arial, sans-serif" font-size="14" font-weight="bold" fill="white" text-anchor="middle">10</text>
|
|
571
|
-
</svg>`}getSubtitleIcon(){return'<svg viewBox="0 0 24 24"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM4 12h4v2H4v-2zm10 6H4v-2h10v2zm6 0h-4v-2h4v2zm0-4H10v-2h10v2z"/></svg>'}getSpeedIcon(){return'<svg viewBox="0 0 24 24"><path d="M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44zm-9.79 6.84a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z"/></svg>'}getSettingsIcon(){return'<svg viewBox="0 0 24 24"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>'}destroy(){this.hideControlsTimeout&&clearTimeout(this.hideControlsTimeout),this.controlsContainer.remove()}}class nt{constructor(t){o(this,"config");o(this,"urlCache",new Map);o(this,"signedUrls",new Set);this.config=t}async processUrl(t){return this.isCloudFrontUrl(t)?this.signCloudFrontUrl(t):this.isS3Url(t)?this.getPresignedUrl(t):t}isCloudFrontUrl(t){var e;if(!((e=this.config)!=null&&e.cloudFrontDomains)||this.config.cloudFrontDomains.length===0)return!1;try{const s=new URL(t);return this.config.cloudFrontDomains.some(r=>s.hostname.includes(r))}catch{return!1}}isS3Url(t){return t.includes(".s3.")||t.includes("s3.amazonaws.com")||t.startsWith("s3://")}async signCloudFrontUrl(t){var e;if(this.signedUrls.has(t))return t;if((e=this.config)!=null&&e.signUrl)try{const s=await this.config.signUrl(t);return this.signedUrls.add(t),s}catch(s){throw console.error("Failed to sign CloudFront URL:",s),new Error("Failed to sign CloudFront URL")}return console.warn("No signUrl function provided. CloudFront cookies may not be set."),t}extractS3Key(t){if(t.startsWith("s3://"))return t.replace("s3://","").split("/").slice(1).join("/");const e=t.match(/s3[.-]([^.]+)\.amazonaws\.com\/(.+)/);if(e)return e[2];const s=t.match(/([^.]+)\.s3\.amazonaws\.com\/(.+)/);return s?s[2]:t}async getPresignedUrl(t){var r;const e=this.extractS3Key(t),s=this.urlCache.get(e);if(s&&s.expiresAt>Date.now())return s.url;if((r=this.config)!=null&&r.getPresignedUrl)try{const i=await this.config.getPresignedUrl(e);return this.urlCache.set(e,{url:i,expiresAt:Date.now()+50*60*1e3}),i}catch(i){throw console.error("Failed to generate presigned URL:",i),new Error("Failed to generate presigned URL for S3 object")}return console.warn("No getPresignedUrl function provided. Using direct S3 URL (requires public bucket)"),t}static constructS3Url(t,e,s="us-east-1"){return`https://${t}.s3.${s}.amazonaws.com/${e}`}static parseS3Uri(t){if(!t.startsWith("s3://"))return null;const e=t.replace("s3://","").split("/"),s=e[0],r=e.slice(1).join("/");return{bucket:s,key:r}}clearCache(){this.urlCache.clear(),this.signedUrls.clear()}}class V{constructor(t){o(this,"container");o(this,"videoElement");o(this,"hls",null);o(this,"config");o(this,"eventListeners",new Map);o(this,"analytics");o(this,"s3Handler");o(this,"uiController");o(this,"state",{playing:!1,paused:!0,ended:!1,buffering:!1,currentTime:0,duration:0,volume:1,muted:!1,playbackRate:1,quality:"auto",availableQualities:[],fullscreen:!1});if(this.config=t,this.container=typeof t.container=="string"?document.querySelector(t.container):t.container,!this.container)throw new Error("Container element not found");this.analytics=new tt(t.analytics),this.s3Handler=new nt(t.s3Config),this.videoElement=this.createVideoElement(),this.container.appendChild(this.videoElement),this.uiController=new et(this.container,this),this.setupVideoListeners(),this.loadSource(t.src),t.autoplay&&(this.videoElement.autoplay=!0),t.muted&&this.mute(),t.poster&&(this.videoElement.poster=t.poster),t.preload&&(this.videoElement.preload=t.preload),t.subtitles&&this.addSubtitleTracks(t.subtitles)}addSubtitleTracks(t){t.forEach(e=>{const s=document.createElement("track");s.kind="subtitles",s.label=e.label,s.src=e.src,s.srclang=e.srclang,e.default&&(s.default=!0),this.videoElement.appendChild(s)})}createVideoElement(){const t=document.createElement("video");return t.className="wontum-player-video",t.style.width="100%",t.style.height="100%",t.playsInline=!0,t}setupVideoListeners(){this.videoElement.addEventListener("play",()=>{this.state.playing=!0,this.state.paused=!1,this.emit("play"),this.analytics.trackEvent("play",this.getAnalyticsData())}),this.videoElement.addEventListener("pause",()=>{this.state.playing=!1,this.state.paused=!0,this.emit("pause"),this.analytics.trackEvent("pause",this.getAnalyticsData())}),this.videoElement.addEventListener("ended",()=>{this.state.ended=!0,this.state.playing=!1,this.emit("ended"),this.analytics.trackEvent("ended",this.getAnalyticsData())}),this.videoElement.addEventListener("timeupdate",()=>{this.state.currentTime=this.videoElement.currentTime,this.emit("timeupdate",{currentTime:this.state.currentTime})}),this.videoElement.addEventListener("loadedmetadata",()=>{this.state.duration=this.videoElement.duration,this.emit("loadedmetadata",{duration:this.state.duration}),this.analytics.trackEvent("loadedmetadata",this.getAnalyticsData())}),this.videoElement.addEventListener("volumechange",()=>{this.state.volume=this.videoElement.volume,this.state.muted=this.videoElement.muted,this.emit("volumechange",{volume:this.state.volume,muted:this.state.muted})}),this.videoElement.addEventListener("ratechange",()=>{this.state.playbackRate=this.videoElement.playbackRate,this.emit("ratechange",{playbackRate:this.state.playbackRate})}),this.videoElement.addEventListener("waiting",()=>{this.state.buffering=!0,this.emit("waiting"),this.analytics.trackEvent("buffering_start",this.getAnalyticsData())}),this.videoElement.addEventListener("canplay",()=>{this.state.buffering=!1,this.emit("canplay"),this.analytics.trackEvent("buffering_end",this.getAnalyticsData())}),this.videoElement.addEventListener("seeking",()=>{this.emit("seeking")}),this.videoElement.addEventListener("seeked",()=>{this.emit("seeked",{currentTime:this.state.currentTime}),this.analytics.trackEvent("seeked",this.getAnalyticsData())}),this.videoElement.addEventListener("error",t=>{const e=this.videoElement.error;this.emit("error",{error:e}),this.analytics.trackEvent("error",{...this.getAnalyticsData(),error:e==null?void 0:e.message})}),this.videoElement.addEventListener("loadstart",()=>{this.emit("loadstart")}),this.videoElement.addEventListener("loadeddata",()=>{this.emit("loadeddata")}),this.videoElement.addEventListener("canplaythrough",()=>{this.emit("canplaythrough")}),this.videoElement.addEventListener("playing",()=>{this.state.playing=!0,this.state.buffering=!1,this.emit("playing")}),this.videoElement.addEventListener("durationchange",()=>{this.state.duration=this.videoElement.duration,this.emit("durationchange",{duration:this.state.duration})}),this.videoElement.addEventListener("progress",()=>{this.emit("progress",{buffered:this.videoElement.buffered})}),this.videoElement.addEventListener("stalled",()=>{this.emit("stalled")}),this.videoElement.addEventListener("suspend",()=>{this.emit("suspend")}),this.videoElement.addEventListener("abort",()=>{this.emit("abort")}),this.videoElement.addEventListener("emptied",()=>{this.emit("emptied")}),this.videoElement.addEventListener("resize",()=>{this.emit("resize",{videoWidth:this.videoElement.videoWidth,videoHeight:this.videoElement.videoHeight})})}async loadSource(t){try{const e=await this.s3Handler.processUrl(t);if(k.isSupported())this.hls=new k(this.config.hlsConfig),this.hls.loadSource(e),this.hls.attachMedia(this.videoElement),this.hls.on(k.Events.MANIFEST_PARSED,(s,r)=>{const i=this.extractQualities(r.levels);this.state.availableQualities=i.map(l=>l.name),this.emit("loadedmetadata",{qualities:i})}),this.hls.on(k.Events.LEVEL_SWITCHED,(s,r)=>{var l;const i=(l=this.hls)==null?void 0:l.levels[r.level];i&&(this.state.quality=`${i.height}p`,this.emit("qualitychange",{quality:this.state.quality}))}),this.hls.on(k.Events.ERROR,(s,r)=>{r.fatal&&this.handleHlsError(r)});else if(this.videoElement.canPlayType("application/vnd.apple.mpegurl"))this.videoElement.src=e;else throw new Error("HLS is not supported in this browser")}catch(e){console.error("Failed to load video source:",e),this.emit("error",{error:e})}}extractQualities(t){return t.map(e=>({height:e.height,width:e.width,bitrate:e.bitrate,name:`${e.height}p`}))}handleHlsError(t){var e,s;switch(t.type){case k.ErrorTypes.NETWORK_ERROR:console.error("Network error occurred"),(e=this.hls)==null||e.startLoad();break;case k.ErrorTypes.MEDIA_ERROR:console.error("Media error occurred"),(s=this.hls)==null||s.recoverMediaError();break;default:console.error("Fatal error occurred:",t),this.destroy();break}}getAnalyticsData(){return{currentTime:this.state.currentTime,duration:this.state.duration,quality:this.state.quality,playbackRate:this.state.playbackRate,volume:this.state.volume,muted:this.state.muted}}play(){return this.videoElement.play()}pause(){this.videoElement.pause()}seek(t){this.videoElement.currentTime=t}skipForward(t=10){const e=Math.min(this.state.currentTime+t,this.state.duration);this.seek(e)}skipBackward(t=10){const e=Math.max(this.state.currentTime-t,0);this.seek(e)}setVolume(t){this.videoElement.volume=Math.max(0,Math.min(1,t))}mute(){this.videoElement.muted=!0}unmute(){this.videoElement.muted=!1}setPlaybackRate(t){this.videoElement.playbackRate=t}setQuality(t){this.hls&&(this.hls.currentLevel=t)}enterFullscreen(){this.container.requestFullscreen&&(this.container.requestFullscreen(),this.state.fullscreen=!0,this.emit("fullscreenchange",{fullscreen:!0}))}exitFullscreen(){document.exitFullscreen&&(document.exitFullscreen(),this.state.fullscreen=!1,this.emit("fullscreenchange",{fullscreen:!1}))}getState(){return{...this.state}}getVideoElement(){return this.videoElement}enableSubtitles(t){const e=this.videoElement.textTracks;for(let s=0;s<e.length;s++)e[s].mode=s===t?"showing":"hidden"}disableSubtitles(){const t=this.videoElement.textTracks;for(let e=0;e<t.length;e++)t[e].mode="hidden"}toggleSubtitles(){const t=this.videoElement.textTracks;return Array.from(t).some(s=>s.mode==="showing")?(this.disableSubtitles(),!1):t.length>0?(this.enableSubtitles(0),!0):!1}getSubtitleTracks(){return Array.from(this.videoElement.textTracks)}areSubtitlesEnabled(){const t=this.videoElement.textTracks;return Array.from(t).some(e=>e.mode==="showing")}on(t,e){this.eventListeners.has(t)||this.eventListeners.set(t,new Set),this.eventListeners.get(t).add(e)}off(t,e){var s;(s=this.eventListeners.get(t))==null||s.delete(e)}emit(t,e){var r;const s={type:t,data:e,timestamp:Date.now()};(r=this.eventListeners.get(t))==null||r.forEach(i=>{i(s)})}destroy(){this.hls&&(this.hls.destroy(),this.hls=null),this.uiController.destroy(),this.videoElement.remove(),this.eventListeners.clear(),this.analytics.destroy()}}var N={exports:{}},P={};/**
|
|
571
|
+
</svg>`}getSubtitleIcon(){return'<svg viewBox="0 0 24 24"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM4 12h4v2H4v-2zm10 6H4v-2h10v2zm6 0h-4v-2h4v2zm0-4H10v-2h10v2z"/></svg>'}getSpeedIcon(){return'<svg viewBox="0 0 24 24"><path d="M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44zm-9.79 6.84a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z"/></svg>'}getSettingsIcon(){return'<svg viewBox="0 0 24 24"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>'}destroy(){this.hideControlsTimeout&&clearTimeout(this.hideControlsTimeout),this.controlsContainer.remove()}}class rt{constructor(t){o(this,"config");o(this,"urlCache",new Map);o(this,"signedUrls",new Set);this.config=t}async processUrl(t){return this.isCloudFrontUrl(t)?this.signCloudFrontUrl(t):this.isS3Url(t)?this.getPresignedUrl(t):t}isCloudFrontUrl(t){var e;if(!((e=this.config)!=null&&e.cloudFrontDomains)||this.config.cloudFrontDomains.length===0)return!1;try{const s=new URL(t);return this.config.cloudFrontDomains.some(r=>s.hostname.includes(r))}catch{return!1}}isS3Url(t){return t.includes(".s3.")||t.includes("s3.amazonaws.com")||t.startsWith("s3://")}async signCloudFrontUrl(t){var e;if(this.signedUrls.has(t))return t;if((e=this.config)!=null&&e.signUrl)try{const s=await this.config.signUrl(t);return this.signedUrls.add(t),s}catch(s){throw console.error("Failed to sign CloudFront URL:",s),new Error("Failed to sign CloudFront URL")}return console.warn("No signUrl function provided. CloudFront cookies may not be set."),t}extractS3Key(t){if(t.startsWith("s3://"))return t.replace("s3://","").split("/").slice(1).join("/");const e=t.match(/s3[.-]([^.]+)\.amazonaws\.com\/(.+)/);if(e)return e[2];const s=t.match(/([^.]+)\.s3\.amazonaws\.com\/(.+)/);return s?s[2]:t}async getPresignedUrl(t){var r;const e=this.extractS3Key(t),s=this.urlCache.get(e);if(s&&s.expiresAt>Date.now())return s.url;if((r=this.config)!=null&&r.getPresignedUrl)try{const i=await this.config.getPresignedUrl(e);return this.urlCache.set(e,{url:i,expiresAt:Date.now()+50*60*1e3}),i}catch(i){throw console.error("Failed to generate presigned URL:",i),new Error("Failed to generate presigned URL for S3 object")}return console.warn("No getPresignedUrl function provided. Using direct S3 URL (requires public bucket)"),t}static constructS3Url(t,e,s="us-east-1"){return`https://${t}.s3.${s}.amazonaws.com/${e}`}static parseS3Uri(t){if(!t.startsWith("s3://"))return null;const e=t.replace("s3://","").split("/"),s=e[0],r=e.slice(1).join("/");return{bucket:s,key:r}}clearCache(){this.urlCache.clear(),this.signedUrls.clear()}}class Y{constructor(t){o(this,"container");o(this,"videoElement");o(this,"hls",null);o(this,"config");o(this,"eventListeners",new Map);o(this,"analytics");o(this,"s3Handler");o(this,"uiController");o(this,"state",{playing:!1,paused:!0,ended:!1,buffering:!1,currentTime:0,duration:0,volume:1,muted:!1,playbackRate:1,quality:"auto",availableQualities:[],fullscreen:!1});if(this.config=t,this.container=typeof t.container=="string"?document.querySelector(t.container):t.container,!this.container)throw new Error("Container element not found");this.analytics=new nt(t.analytics),this.s3Handler=new rt(t.s3Config),this.videoElement=this.createVideoElement(),this.container.appendChild(this.videoElement),this.uiController=new st(this.container,this),this.setupVideoListeners(),this.loadSource(t.src),t.autoplay&&(this.videoElement.autoplay=!0),t.muted&&this.mute(),t.poster&&(this.videoElement.poster=t.poster),t.preload&&(this.videoElement.preload=t.preload),t.subtitles&&this.addSubtitleTracks(t.subtitles)}addSubtitleTracks(t){t.forEach(e=>{const s=document.createElement("track");s.kind="subtitles",s.label=e.label,s.src=e.src,s.srclang=e.srclang,e.default&&(s.default=!0),this.videoElement.appendChild(s)})}createVideoElement(){const t=document.createElement("video");return t.className="wontum-player-video",t.style.width="100%",t.style.height="100%",t.playsInline=!0,t}setupVideoListeners(){this.videoElement.addEventListener("play",()=>{this.state.playing=!0,this.state.paused=!1,this.emit("play"),this.analytics.trackEvent("play",this.getAnalyticsData())}),this.videoElement.addEventListener("pause",()=>{this.state.playing=!1,this.state.paused=!0,this.emit("pause"),this.analytics.trackEvent("pause",this.getAnalyticsData())}),this.videoElement.addEventListener("ended",()=>{this.state.ended=!0,this.state.playing=!1,this.emit("ended"),this.analytics.trackEvent("ended",this.getAnalyticsData())}),this.videoElement.addEventListener("timeupdate",()=>{this.state.currentTime=this.videoElement.currentTime,this.emit("timeupdate",{currentTime:this.state.currentTime})}),this.videoElement.addEventListener("loadedmetadata",()=>{this.state.duration=this.videoElement.duration,this.emit("loadedmetadata",{duration:this.state.duration}),this.analytics.trackEvent("loadedmetadata",this.getAnalyticsData())}),this.videoElement.addEventListener("volumechange",()=>{this.state.volume=this.videoElement.volume,this.state.muted=this.videoElement.muted,this.emit("volumechange",{volume:this.state.volume,muted:this.state.muted})}),this.videoElement.addEventListener("ratechange",()=>{this.state.playbackRate=this.videoElement.playbackRate,this.emit("ratechange",{playbackRate:this.state.playbackRate})}),this.videoElement.addEventListener("waiting",()=>{this.state.buffering=!0,this.emit("waiting"),this.analytics.trackEvent("buffering_start",this.getAnalyticsData())}),this.videoElement.addEventListener("canplay",()=>{this.state.buffering=!1,this.emit("canplay"),this.analytics.trackEvent("buffering_end",this.getAnalyticsData())}),this.videoElement.addEventListener("seeking",()=>{this.emit("seeking")}),this.videoElement.addEventListener("seeked",()=>{this.emit("seeked",{currentTime:this.state.currentTime}),this.analytics.trackEvent("seeked",this.getAnalyticsData())}),this.videoElement.addEventListener("error",t=>{const e=this.videoElement.error;this.emit("error",{error:e}),this.analytics.trackEvent("error",{...this.getAnalyticsData(),error:e==null?void 0:e.message})}),this.videoElement.addEventListener("loadstart",()=>{this.emit("loadstart")}),this.videoElement.addEventListener("loadeddata",()=>{this.emit("loadeddata")}),this.videoElement.addEventListener("canplaythrough",()=>{this.emit("canplaythrough")}),this.videoElement.addEventListener("playing",()=>{this.state.playing=!0,this.state.buffering=!1,this.emit("playing")}),this.videoElement.addEventListener("durationchange",()=>{this.state.duration=this.videoElement.duration,this.emit("durationchange",{duration:this.state.duration})}),this.videoElement.addEventListener("progress",()=>{this.emit("progress",{buffered:this.videoElement.buffered})}),this.videoElement.addEventListener("stalled",()=>{this.emit("stalled")}),this.videoElement.addEventListener("suspend",()=>{this.emit("suspend")}),this.videoElement.addEventListener("abort",()=>{this.emit("abort")}),this.videoElement.addEventListener("emptied",()=>{this.emit("emptied")}),this.videoElement.addEventListener("resize",()=>{this.emit("resize",{videoWidth:this.videoElement.videoWidth,videoHeight:this.videoElement.videoHeight})})}async loadSource(t){try{const e=await this.s3Handler.processUrl(t);if(E.isSupported())this.hls=new E(this.config.hlsConfig),this.hls.loadSource(e),this.hls.attachMedia(this.videoElement),this.hls.on(E.Events.MANIFEST_PARSED,(s,r)=>{const i=this.extractQualities(r.levels);this.state.availableQualities=i.map(c=>c.name),this.emit("loadedmetadata",{qualities:i})}),this.hls.on(E.Events.LEVEL_SWITCHED,(s,r)=>{var c;const i=(c=this.hls)==null?void 0:c.levels[r.level];i&&(this.state.quality=`${i.height}p`,this.emit("qualitychange",{quality:this.state.quality}))}),this.hls.on(E.Events.ERROR,(s,r)=>{r.fatal&&this.handleHlsError(r)});else if(this.videoElement.canPlayType("application/vnd.apple.mpegurl"))this.videoElement.src=e;else throw new Error("HLS is not supported in this browser")}catch(e){console.error("Failed to load video source:",e),this.emit("error",{error:e})}}extractQualities(t){return t.map(e=>({height:e.height,width:e.width,bitrate:e.bitrate,name:`${e.height}p`}))}handleHlsError(t){var e,s;switch(t.type){case E.ErrorTypes.NETWORK_ERROR:console.error("Network error occurred"),(e=this.hls)==null||e.startLoad();break;case E.ErrorTypes.MEDIA_ERROR:console.error("Media error occurred"),(s=this.hls)==null||s.recoverMediaError();break;default:console.error("Fatal error occurred:",t),this.destroy();break}}getAnalyticsData(){return{currentTime:this.state.currentTime,duration:this.state.duration,quality:this.state.quality,playbackRate:this.state.playbackRate,volume:this.state.volume,muted:this.state.muted}}play(){return this.videoElement.play()}pause(){this.videoElement.pause()}seek(t){this.videoElement.currentTime=t}skipForward(t=10){const e=Math.min(this.state.currentTime+t,this.state.duration);this.seek(e)}skipBackward(t=10){const e=Math.max(this.state.currentTime-t,0);this.seek(e)}setVolume(t){this.videoElement.volume=Math.max(0,Math.min(1,t))}mute(){this.videoElement.muted=!0}unmute(){this.videoElement.muted=!1}setPlaybackRate(t){this.videoElement.playbackRate=t}setQuality(t){this.hls&&(this.hls.currentLevel=t)}enterFullscreen(){this.container.requestFullscreen&&(this.container.requestFullscreen(),this.state.fullscreen=!0,this.emit("fullscreenchange",{fullscreen:!0}))}exitFullscreen(){document.exitFullscreen&&(document.exitFullscreen(),this.state.fullscreen=!1,this.emit("fullscreenchange",{fullscreen:!1}))}getState(){return{...this.state}}getVideoElement(){return this.videoElement}enableSubtitles(t){const e=this.videoElement.textTracks;for(let s=0;s<e.length;s++)e[s].mode=s===t?"showing":"hidden"}disableSubtitles(){const t=this.videoElement.textTracks;for(let e=0;e<t.length;e++)t[e].mode="hidden"}toggleSubtitles(){const t=this.videoElement.textTracks;return Array.from(t).some(s=>s.mode==="showing")?(this.disableSubtitles(),!1):t.length>0?(this.enableSubtitles(0),!0):!1}getSubtitleTracks(){return Array.from(this.videoElement.textTracks)}areSubtitlesEnabled(){const t=this.videoElement.textTracks;return Array.from(t).some(e=>e.mode==="showing")}on(t,e){this.eventListeners.has(t)||this.eventListeners.set(t,new Set),this.eventListeners.get(t).add(e)}off(t,e){var s;(s=this.eventListeners.get(t))==null||s.delete(e)}emit(t,e){var r;const s={type:t,data:e,timestamp:Date.now()};(r=this.eventListeners.get(t))==null||r.forEach(i=>{i(s)})}destroy(){this.hls&&(this.hls.destroy(),this.hls=null),this.uiController.destroy(),this.videoElement.remove(),this.eventListeners.clear(),this.analytics.destroy()}}var W={exports:{}},q={};/**
|
|
572
572
|
* @license React
|
|
573
573
|
* react-jsx-runtime.production.js
|
|
574
574
|
*
|
|
@@ -576,7 +576,7 @@
|
|
|
576
576
|
*
|
|
577
577
|
* This source code is licensed under the MIT license found in the
|
|
578
578
|
* LICENSE file in the root directory of this source tree.
|
|
579
|
-
*/var
|
|
579
|
+
*/var K;function dt(){if(K)return q;K=1;var l=Symbol.for("react.transitional.element"),t=Symbol.for("react.fragment");function e(s,r,i){var c=null;if(i!==void 0&&(c=""+i),r.key!==void 0&&(c=""+r.key),"key"in r){i={};for(var u in r)u!=="key"&&(i[u]=r[u])}else i=r;return r=i.ref,{$$typeof:l,type:s,key:c,ref:r!==void 0?r:null,props:i}}return q.Fragment=t,q.jsx=e,q.jsxs=e,q}var P={};/**
|
|
580
580
|
* @license React
|
|
581
581
|
* react-jsx-runtime.development.js
|
|
582
582
|
*
|
|
@@ -584,9 +584,9 @@
|
|
|
584
584
|
*
|
|
585
585
|
* This source code is licensed under the MIT license found in the
|
|
586
586
|
* LICENSE file in the root directory of this source tree.
|
|
587
|
-
*/var
|
|
587
|
+
*/var tt;function ht(){return tt||(tt=1,process.env.NODE_ENV!=="production"&&function(){function l(n){if(n==null)return null;if(typeof n=="function")return n.$$typeof===z?null:n.displayName||n.name||null;if(typeof n=="string")return n;switch(n){case x:return"Fragment";case $:return"Profiler";case B:return"StrictMode";case H:return"Suspense";case N:return"SuspenseList";case R:return"Activity"}if(typeof n=="object")switch(typeof n.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),n.$$typeof){case I:return"Portal";case j:return n.displayName||"Context";case O:return(n._context.displayName||"Context")+".Consumer";case F:var a=n.render;return n=n.displayName,n||(n=a.displayName||a.name||"",n=n!==""?"ForwardRef("+n+")":"ForwardRef"),n;case L:return a=n.displayName||null,a!==null?a:l(n.type)||"Memo";case k:a=n._payload,n=n._init;try{return l(n(a))}catch{}}return null}function t(n){return""+n}function e(n){try{t(n);var a=!1}catch{a=!0}if(a){a=console;var d=a.error,h=typeof Symbol=="function"&&Symbol.toStringTag&&n[Symbol.toStringTag]||n.constructor.name||"Object";return d.call(a,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",h),t(n)}}function s(n){if(n===x)return"<>";if(typeof n=="object"&&n!==null&&n.$$typeof===k)return"<...>";try{var a=l(n);return a?"<"+a+">":"<...>"}catch{return"<...>"}}function r(){var n=_.A;return n===null?null:n.getOwner()}function i(){return Error("react-stack-top-frame")}function c(n){if(p.call(n,"key")){var a=Object.getOwnPropertyDescriptor(n,"key").get;if(a&&a.isReactWarning)return!1}return n.key!==void 0}function u(n,a){function d(){Q||(Q=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",a))}d.isReactWarning=!0,Object.defineProperty(n,"key",{get:d,configurable:!0})}function f(){var n=l(this.type);return J[n]||(J[n]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),n=this.props.ref,n!==void 0?n:null}function b(n,a,d,h,D,U){var m=d.ref;return n={$$typeof:T,type:n,key:a,props:d,_owner:h},(m!==void 0?m:null)!==null?Object.defineProperty(n,"ref",{enumerable:!1,get:f}):Object.defineProperty(n,"ref",{enumerable:!1,value:null}),n._store={},Object.defineProperty(n._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(n,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(n,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:D}),Object.defineProperty(n,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:U}),Object.freeze&&(Object.freeze(n.props),Object.freeze(n)),n}function y(n,a,d,h,D,U){var m=a.children;if(m!==void 0)if(h)if(g(m)){for(h=0;h<m.length;h++)A(m[h]);Object.freeze&&Object.freeze(m)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else A(m);if(p.call(a,"key")){m=l(n);var C=Object.keys(a).filter(function(at){return at!=="key"});h=0<C.length?"{key: someKey, "+C.join(": ..., ")+": ...}":"{key: someKey}",Z[m+h]||(C=0<C.length?"{"+C.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
|
|
588
588
|
let props = %s;
|
|
589
589
|
<%s {...props} />
|
|
590
590
|
React keys must be passed directly to JSX without using spread:
|
|
591
591
|
let props = %s;
|
|
592
|
-
<%s key={someKey} {...props} />`,h,m,
|
|
592
|
+
<%s key={someKey} {...props} />`,h,m,C,m),Z[m+h]=!0)}if(m=null,d!==void 0&&(e(d),m=""+d),c(a)&&(e(a.key),m=""+a.key),"key"in a){d={};for(var V in a)V!=="key"&&(d[V]=a[V])}else d=a;return m&&u(d,typeof n=="function"?n.displayName||n.name||"Unknown":n),b(n,m,d,r(),D,U)}function A(n){M(n)?n._store&&(n._store.validated=1):typeof n=="object"&&n!==null&&n.$$typeof===k&&(n._payload.status==="fulfilled"?M(n._payload.value)&&n._payload.value._store&&(n._payload.value._store.validated=1):n._store&&(n._store.validated=1))}function M(n){return typeof n=="object"&&n!==null&&n.$$typeof===T}var w=v,T=Symbol.for("react.transitional.element"),I=Symbol.for("react.portal"),x=Symbol.for("react.fragment"),B=Symbol.for("react.strict_mode"),$=Symbol.for("react.profiler"),O=Symbol.for("react.consumer"),j=Symbol.for("react.context"),F=Symbol.for("react.forward_ref"),H=Symbol.for("react.suspense"),N=Symbol.for("react.suspense_list"),L=Symbol.for("react.memo"),k=Symbol.for("react.lazy"),R=Symbol.for("react.activity"),z=Symbol.for("react.client.reference"),_=w.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,p=Object.prototype.hasOwnProperty,g=Array.isArray,S=console.createTask?console.createTask:function(){return null};w={react_stack_bottom_frame:function(n){return n()}};var Q,J={},X=w.react_stack_bottom_frame.bind(w,i)(),G=S(s(i)),Z={};P.Fragment=x,P.jsx=function(n,a,d){var h=1e4>_.recentlyCreatedOwnerStacks++;return y(n,a,d,!1,h?Error("react-stack-top-frame"):X,h?S(s(n)):G)},P.jsxs=function(n,a,d){var h=1e4>_.recentlyCreatedOwnerStacks++;return y(n,a,d,!0,h?Error("react-stack-top-frame"):X,h?S(s(n)):G)}}()),P}process.env.NODE_ENV==="production"?W.exports=dt():W.exports=ht();var it=W.exports;const mt=l=>{const{src:t,autoplay:e,muted:s,controls:r=!0,poster:i,preload:c,theme:u,s3Config:f,analytics:b,hlsConfig:y,subtitles:A,stickyControls:M,onReady:w,onPlay:T,onPause:I,onEnded:x,onTimeUpdate:B,onVolumeChange:$,onError:O,onLoadedMetadata:j,onQualityChange:F,style:H,className:N,width:L="100%",height:k="500px"}=l,R=v.useRef(null),z=v.useRef(null);return v.useEffect(()=>{if(!R.current)return;const _={src:t,container:R.current,autoplay:e,muted:s,controls:r,poster:i,preload:c,theme:u,s3Config:f,analytics:b,hlsConfig:y,subtitles:A,stickyControls:M},p=new Y(_);return z.current=p,T&&p.on("play",T),I&&p.on("pause",I),x&&p.on("ended",x),O&&p.on("error",g=>{var S;return O((S=g.data)==null?void 0:S.error)}),j&&p.on("loadedmetadata",j),F&&p.on("qualitychange",g=>F(g.data.level)),B&&p.on("timeupdate",g=>B(g.data.currentTime)),$&&p.on("volumechange",g=>$(g.data.volume,g.data.muted)),w&&w(p),()=>{p.destroy(),z.current=null}},[t]),it.jsx("div",{ref:R,className:N,style:{width:typeof L=="number"?`${L}px`:L,height:typeof k=="number"?`${k}px`:k,...H}})},pt=l=>{const[t,e]=v.useState(null),[s,r]=v.useState(null),i=v.useRef(null);return v.useEffect(()=>{if(!i.current)return;const c=new Y({...l,container:i.current});e(c);const u=()=>{r(c.getState())};return c.on("play",u),c.on("pause",u),c.on("timeupdate",u),c.on("volumechange",u),c.on("loadedmetadata",u),()=>{c.destroy()}},[l.src]),{containerRef:i,player:t,state:s}},ot=et.createContext({player:null,state:null}),vt=l=>{const{player:t,children:e}=l,[s,r]=v.useState(t.getState());return v.useEffect(()=>{const i=()=>{r(t.getState())};return t.on("play",i),t.on("pause",i),t.on("timeupdate",i),t.on("volumechange",i),t.on("loadedmetadata",i),()=>{}},[t]),it.jsx(ot.Provider,{value:{player:t,state:s},children:e})},gt=()=>{const l=et.useContext(ot);if(!l.player)throw new Error("useWontumPlayerContext must be used within WontumPlayerProvider");return l};exports.Analytics=nt;exports.S3Handler=rt;exports.UIController=st;exports.WontumPlayer=Y;exports.WontumPlayerProvider=vt;exports.WontumPlayerReact=mt;exports.useWontumPlayer=pt;exports.useWontumPlayerContext=gt;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
var at = Object.defineProperty;
|
|
2
2
|
var lt = (c, t, e) => t in c ? at(c, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[t] = e;
|
|
3
3
|
var o = (c, t, e) => lt(c, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
4
|
+
import k from "hls.js";
|
|
5
|
+
import * as nt from "react";
|
|
6
|
+
import ct, { useRef as V, useEffect as Q, useState as W } from "react";
|
|
7
|
+
class ut {
|
|
7
8
|
constructor(t) {
|
|
8
9
|
o(this, "config");
|
|
9
10
|
o(this, "sessionId");
|
|
@@ -117,7 +118,7 @@ class ct {
|
|
|
117
118
|
(t = this.config) != null && t.enabled && this.trackEvent("session_end", this.getSessionData()), this.events = [];
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
|
-
class
|
|
121
|
+
class dt {
|
|
121
122
|
constructor(t, e) {
|
|
122
123
|
o(this, "container");
|
|
123
124
|
o(this, "player");
|
|
@@ -144,8 +145,8 @@ class ut {
|
|
|
144
145
|
injectStyles() {
|
|
145
146
|
const t = "wontum-player-styles";
|
|
146
147
|
if (document.getElementById(t)) return;
|
|
147
|
-
const e = this.player.config.theme || {}, s = e.primaryColor || "#3b82f6", r = e.accentColor || "#2563eb", i = e.fontFamily || "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", l = e.controlsBackground || "linear-gradient(to top, rgba(0,0,0,0.8), transparent)", u = e.buttonHoverBg || "rgba(255, 255, 255, 0.1)",
|
|
148
|
-
|
|
148
|
+
const e = this.player.config.theme || {}, s = e.primaryColor || "#3b82f6", r = e.accentColor || "#2563eb", i = e.fontFamily || "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", l = e.controlsBackground || "linear-gradient(to top, rgba(0,0,0,0.8), transparent)", u = e.buttonHoverBg || "rgba(255, 255, 255, 0.1)", g = e.progressHeight || "6px", y = e.borderRadius || "4px", f = document.createElement("style");
|
|
149
|
+
f.id = t, f.textContent = `
|
|
149
150
|
.wontum-player-container {
|
|
150
151
|
position: relative;
|
|
151
152
|
background: #000;
|
|
@@ -155,7 +156,7 @@ class ut {
|
|
|
155
156
|
--accent-color: ${r};
|
|
156
157
|
--controls-bg: ${l};
|
|
157
158
|
--button-hover: ${u};
|
|
158
|
-
--progress-height: ${
|
|
159
|
+
--progress-height: ${g};
|
|
159
160
|
--border-radius: ${y};
|
|
160
161
|
}
|
|
161
162
|
|
|
@@ -610,7 +611,7 @@ class ut {
|
|
|
610
611
|
transform: translateY(0) !important;
|
|
611
612
|
pointer-events: all !important;
|
|
612
613
|
}
|
|
613
|
-
`, document.head.appendChild(
|
|
614
|
+
`, document.head.appendChild(f), this.container.classList.add("wontum-player-container");
|
|
614
615
|
}
|
|
615
616
|
createProgressBar() {
|
|
616
617
|
const t = document.createElement("div");
|
|
@@ -775,7 +776,7 @@ class ut {
|
|
|
775
776
|
`, t.querySelectorAll(".wontum-subtitle-option").forEach((r) => {
|
|
776
777
|
r.addEventListener("click", (i) => {
|
|
777
778
|
const l = i.target, u = parseInt(l.dataset.track || "-1");
|
|
778
|
-
u === -1 ? this.player.disableSubtitles() : this.player.enableSubtitles(u), t.querySelectorAll(".wontum-subtitle-option").forEach((
|
|
779
|
+
u === -1 ? this.player.disableSubtitles() : this.player.enableSubtitles(u), t.querySelectorAll(".wontum-subtitle-option").forEach((g) => g.classList.remove("active")), l.classList.add("active"), t.classList.remove("active");
|
|
779
780
|
});
|
|
780
781
|
});
|
|
781
782
|
}
|
|
@@ -789,8 +790,8 @@ class ut {
|
|
|
789
790
|
`
|
|
790
791
|
).join(""), t.querySelectorAll(".wontum-speed-option").forEach((i) => {
|
|
791
792
|
i.addEventListener("click", (l) => {
|
|
792
|
-
const u = l.target,
|
|
793
|
-
this.player.setPlaybackRate(
|
|
793
|
+
const u = l.target, g = parseFloat(u.dataset.speed || "1");
|
|
794
|
+
this.player.setPlaybackRate(g), t.querySelectorAll(".wontum-speed-option").forEach((y) => y.classList.remove("active")), u.classList.add("active"), t.classList.remove("active");
|
|
794
795
|
});
|
|
795
796
|
});
|
|
796
797
|
}
|
|
@@ -890,7 +891,7 @@ class ut {
|
|
|
890
891
|
this.hideControlsTimeout && clearTimeout(this.hideControlsTimeout), this.controlsContainer.remove();
|
|
891
892
|
}
|
|
892
893
|
}
|
|
893
|
-
class
|
|
894
|
+
class ht {
|
|
894
895
|
constructor(t) {
|
|
895
896
|
o(this, "config");
|
|
896
897
|
o(this, "urlCache", /* @__PURE__ */ new Map());
|
|
@@ -994,7 +995,7 @@ class dt {
|
|
|
994
995
|
this.urlCache.clear(), this.signedUrls.clear();
|
|
995
996
|
}
|
|
996
997
|
}
|
|
997
|
-
class
|
|
998
|
+
class st {
|
|
998
999
|
constructor(t) {
|
|
999
1000
|
o(this, "container");
|
|
1000
1001
|
o(this, "videoElement");
|
|
@@ -1020,7 +1021,7 @@ class nt {
|
|
|
1020
1021
|
});
|
|
1021
1022
|
if (this.config = t, this.container = typeof t.container == "string" ? document.querySelector(t.container) : t.container, !this.container)
|
|
1022
1023
|
throw new Error("Container element not found");
|
|
1023
|
-
this.analytics = new
|
|
1024
|
+
this.analytics = new ut(t.analytics), this.s3Handler = new ht(t.s3Config), this.videoElement = this.createVideoElement(), this.container.appendChild(this.videoElement), this.uiController = new dt(this.container, this), this.setupVideoListeners(), this.loadSource(t.src), t.autoplay && (this.videoElement.autoplay = !0), t.muted && this.mute(), t.poster && (this.videoElement.poster = t.poster), t.preload && (this.videoElement.preload = t.preload), t.subtitles && this.addSubtitleTracks(t.subtitles);
|
|
1024
1025
|
}
|
|
1025
1026
|
addSubtitleTracks(t) {
|
|
1026
1027
|
t.forEach((e) => {
|
|
@@ -1088,15 +1089,15 @@ class nt {
|
|
|
1088
1089
|
async loadSource(t) {
|
|
1089
1090
|
try {
|
|
1090
1091
|
const e = await this.s3Handler.processUrl(t);
|
|
1091
|
-
if (
|
|
1092
|
-
this.hls = new
|
|
1092
|
+
if (k.isSupported())
|
|
1093
|
+
this.hls = new k(this.config.hlsConfig), this.hls.loadSource(e), this.hls.attachMedia(this.videoElement), this.hls.on(k.Events.MANIFEST_PARSED, (s, r) => {
|
|
1093
1094
|
const i = this.extractQualities(r.levels);
|
|
1094
1095
|
this.state.availableQualities = i.map((l) => l.name), this.emit("loadedmetadata", { qualities: i });
|
|
1095
|
-
}), this.hls.on(
|
|
1096
|
+
}), this.hls.on(k.Events.LEVEL_SWITCHED, (s, r) => {
|
|
1096
1097
|
var l;
|
|
1097
1098
|
const i = (l = this.hls) == null ? void 0 : l.levels[r.level];
|
|
1098
1099
|
i && (this.state.quality = `${i.height}p`, this.emit("qualitychange", { quality: this.state.quality }));
|
|
1099
|
-
}), this.hls.on(
|
|
1100
|
+
}), this.hls.on(k.Events.ERROR, (s, r) => {
|
|
1100
1101
|
r.fatal && this.handleHlsError(r);
|
|
1101
1102
|
});
|
|
1102
1103
|
else if (this.videoElement.canPlayType("application/vnd.apple.mpegurl"))
|
|
@@ -1118,10 +1119,10 @@ class nt {
|
|
|
1118
1119
|
handleHlsError(t) {
|
|
1119
1120
|
var e, s;
|
|
1120
1121
|
switch (t.type) {
|
|
1121
|
-
case
|
|
1122
|
+
case k.ErrorTypes.NETWORK_ERROR:
|
|
1122
1123
|
console.error("Network error occurred"), (e = this.hls) == null || e.startLoad();
|
|
1123
1124
|
break;
|
|
1124
|
-
case
|
|
1125
|
+
case k.ErrorTypes.MEDIA_ERROR:
|
|
1125
1126
|
console.error("Media error occurred"), (s = this.hls) == null || s.recoverMediaError();
|
|
1126
1127
|
break;
|
|
1127
1128
|
default:
|
|
@@ -1242,7 +1243,7 @@ class nt {
|
|
|
1242
1243
|
this.hls && (this.hls.destroy(), this.hls = null), this.uiController.destroy(), this.videoElement.remove(), this.eventListeners.clear(), this.analytics.destroy();
|
|
1243
1244
|
}
|
|
1244
1245
|
}
|
|
1245
|
-
var
|
|
1246
|
+
var Y = { exports: {} }, _ = {};
|
|
1246
1247
|
/**
|
|
1247
1248
|
* @license React
|
|
1248
1249
|
* react-jsx-runtime.production.js
|
|
@@ -1253,8 +1254,8 @@ var W = { exports: {} }, q = {};
|
|
|
1253
1254
|
* LICENSE file in the root directory of this source tree.
|
|
1254
1255
|
*/
|
|
1255
1256
|
var tt;
|
|
1256
|
-
function
|
|
1257
|
-
if (tt) return
|
|
1257
|
+
function mt() {
|
|
1258
|
+
if (tt) return _;
|
|
1258
1259
|
tt = 1;
|
|
1259
1260
|
var c = Symbol.for("react.transitional.element"), t = Symbol.for("react.fragment");
|
|
1260
1261
|
function e(s, r, i) {
|
|
@@ -1272,9 +1273,9 @@ function ht() {
|
|
|
1272
1273
|
props: i
|
|
1273
1274
|
};
|
|
1274
1275
|
}
|
|
1275
|
-
return
|
|
1276
|
+
return _.Fragment = t, _.jsx = e, _.jsxs = e, _;
|
|
1276
1277
|
}
|
|
1277
|
-
var
|
|
1278
|
+
var q = {};
|
|
1278
1279
|
/**
|
|
1279
1280
|
* @license React
|
|
1280
1281
|
* react-jsx-runtime.development.js
|
|
@@ -1285,43 +1286,43 @@ var P = {};
|
|
|
1285
1286
|
* LICENSE file in the root directory of this source tree.
|
|
1286
1287
|
*/
|
|
1287
1288
|
var et;
|
|
1288
|
-
function
|
|
1289
|
+
function pt() {
|
|
1289
1290
|
return et || (et = 1, process.env.NODE_ENV !== "production" && function() {
|
|
1290
1291
|
function c(n) {
|
|
1291
1292
|
if (n == null) return null;
|
|
1292
1293
|
if (typeof n == "function")
|
|
1293
|
-
return n.$$typeof ===
|
|
1294
|
+
return n.$$typeof === O ? null : n.displayName || n.name || null;
|
|
1294
1295
|
if (typeof n == "string") return n;
|
|
1295
1296
|
switch (n) {
|
|
1296
|
-
case
|
|
1297
|
+
case E:
|
|
1297
1298
|
return "Fragment";
|
|
1298
|
-
case
|
|
1299
|
+
case B:
|
|
1299
1300
|
return "Profiler";
|
|
1300
|
-
case
|
|
1301
|
+
case I:
|
|
1301
1302
|
return "StrictMode";
|
|
1302
|
-
case
|
|
1303
|
+
case D:
|
|
1303
1304
|
return "Suspense";
|
|
1304
|
-
case
|
|
1305
|
+
case H:
|
|
1305
1306
|
return "SuspenseList";
|
|
1306
|
-
case
|
|
1307
|
+
case L:
|
|
1307
1308
|
return "Activity";
|
|
1308
1309
|
}
|
|
1309
1310
|
if (typeof n == "object")
|
|
1310
1311
|
switch (typeof n.tag == "number" && console.error(
|
|
1311
1312
|
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
|
|
1312
1313
|
), n.$$typeof) {
|
|
1313
|
-
case
|
|
1314
|
+
case M:
|
|
1314
1315
|
return "Portal";
|
|
1315
|
-
case
|
|
1316
|
+
case F:
|
|
1316
1317
|
return n.displayName || "Context";
|
|
1317
|
-
case
|
|
1318
|
+
case $:
|
|
1318
1319
|
return (n._context.displayName || "Context") + ".Consumer";
|
|
1319
|
-
case
|
|
1320
|
+
case z:
|
|
1320
1321
|
var a = n.render;
|
|
1321
1322
|
return n = n.displayName, n || (n = a.displayName || a.name || "", n = n !== "" ? "ForwardRef(" + n + ")" : "ForwardRef"), n;
|
|
1322
|
-
case
|
|
1323
|
+
case T:
|
|
1323
1324
|
return a = n.displayName || null, a !== null ? a : c(n.type) || "Memo";
|
|
1324
|
-
case
|
|
1325
|
+
case w:
|
|
1325
1326
|
a = n._payload, n = n._init;
|
|
1326
1327
|
try {
|
|
1327
1328
|
return c(n(a));
|
|
@@ -1351,8 +1352,8 @@ function mt() {
|
|
|
1351
1352
|
}
|
|
1352
1353
|
}
|
|
1353
1354
|
function s(n) {
|
|
1354
|
-
if (n ===
|
|
1355
|
-
if (typeof n == "object" && n !== null && n.$$typeof ===
|
|
1355
|
+
if (n === E) return "<>";
|
|
1356
|
+
if (typeof n == "object" && n !== null && n.$$typeof === w)
|
|
1356
1357
|
return "<...>";
|
|
1357
1358
|
try {
|
|
1358
1359
|
var a = c(n);
|
|
@@ -1362,14 +1363,14 @@ function mt() {
|
|
|
1362
1363
|
}
|
|
1363
1364
|
}
|
|
1364
1365
|
function r() {
|
|
1365
|
-
var n =
|
|
1366
|
+
var n = R.A;
|
|
1366
1367
|
return n === null ? null : n.getOwner();
|
|
1367
1368
|
}
|
|
1368
1369
|
function i() {
|
|
1369
1370
|
return Error("react-stack-top-frame");
|
|
1370
1371
|
}
|
|
1371
1372
|
function l(n) {
|
|
1372
|
-
if (
|
|
1373
|
+
if (p.call(n, "key")) {
|
|
1373
1374
|
var a = Object.getOwnPropertyDescriptor(n, "key").get;
|
|
1374
1375
|
if (a && a.isReactWarning) return !1;
|
|
1375
1376
|
}
|
|
@@ -1387,13 +1388,13 @@ function mt() {
|
|
|
1387
1388
|
configurable: !0
|
|
1388
1389
|
});
|
|
1389
1390
|
}
|
|
1390
|
-
function
|
|
1391
|
+
function g() {
|
|
1391
1392
|
var n = c(this.type);
|
|
1392
1393
|
return X[n] || (X[n] = !0, console.error(
|
|
1393
1394
|
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
|
|
1394
1395
|
)), n = this.props.ref, n !== void 0 ? n : null;
|
|
1395
1396
|
}
|
|
1396
|
-
function y(n, a, d, h,
|
|
1397
|
+
function y(n, a, d, h, j, N) {
|
|
1397
1398
|
var m = d.ref;
|
|
1398
1399
|
return n = {
|
|
1399
1400
|
$$typeof: C,
|
|
@@ -1403,7 +1404,7 @@ function mt() {
|
|
|
1403
1404
|
_owner: h
|
|
1404
1405
|
}, (m !== void 0 ? m : null) !== null ? Object.defineProperty(n, "ref", {
|
|
1405
1406
|
enumerable: !1,
|
|
1406
|
-
get:
|
|
1407
|
+
get: g
|
|
1407
1408
|
}) : Object.defineProperty(n, "ref", { enumerable: !1, value: null }), n._store = {}, Object.defineProperty(n._store, "validated", {
|
|
1408
1409
|
configurable: !1,
|
|
1409
1410
|
enumerable: !1,
|
|
@@ -1418,33 +1419,33 @@ function mt() {
|
|
|
1418
1419
|
configurable: !1,
|
|
1419
1420
|
enumerable: !1,
|
|
1420
1421
|
writable: !0,
|
|
1421
|
-
value:
|
|
1422
|
+
value: j
|
|
1422
1423
|
}), Object.defineProperty(n, "_debugTask", {
|
|
1423
1424
|
configurable: !1,
|
|
1424
1425
|
enumerable: !1,
|
|
1425
1426
|
writable: !0,
|
|
1426
|
-
value:
|
|
1427
|
+
value: N
|
|
1427
1428
|
}), Object.freeze && (Object.freeze(n.props), Object.freeze(n)), n;
|
|
1428
1429
|
}
|
|
1429
|
-
function
|
|
1430
|
+
function f(n, a, d, h, j, N) {
|
|
1430
1431
|
var m = a.children;
|
|
1431
1432
|
if (m !== void 0)
|
|
1432
1433
|
if (h)
|
|
1433
|
-
if (
|
|
1434
|
+
if (v(m)) {
|
|
1434
1435
|
for (h = 0; h < m.length; h++)
|
|
1435
|
-
|
|
1436
|
+
P(m[h]);
|
|
1436
1437
|
Object.freeze && Object.freeze(m);
|
|
1437
1438
|
} else
|
|
1438
1439
|
console.error(
|
|
1439
1440
|
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
|
|
1440
1441
|
);
|
|
1441
|
-
else
|
|
1442
|
-
if (
|
|
1442
|
+
else P(m);
|
|
1443
|
+
if (p.call(a, "key")) {
|
|
1443
1444
|
m = c(n);
|
|
1444
|
-
var
|
|
1445
|
+
var S = Object.keys(a).filter(function(ot) {
|
|
1445
1446
|
return ot !== "key";
|
|
1446
1447
|
});
|
|
1447
|
-
h = 0 <
|
|
1448
|
+
h = 0 < S.length ? "{key: someKey, " + S.join(": ..., ") + ": ...}" : "{key: someKey}", K[m + h] || (S = 0 < S.length ? "{" + S.join(": ..., ") + ": ...}" : "{}", console.error(
|
|
1448
1449
|
`A props object containing a "key" prop is being spread into JSX:
|
|
1449
1450
|
let props = %s;
|
|
1450
1451
|
<%s {...props} />
|
|
@@ -1453,14 +1454,14 @@ React keys must be passed directly to JSX without using spread:
|
|
|
1453
1454
|
<%s key={someKey} {...props} />`,
|
|
1454
1455
|
h,
|
|
1455
1456
|
m,
|
|
1456
|
-
|
|
1457
|
+
S,
|
|
1457
1458
|
m
|
|
1458
1459
|
), K[m + h] = !0);
|
|
1459
1460
|
}
|
|
1460
1461
|
if (m = null, d !== void 0 && (e(d), m = "" + d), l(a) && (e(a.key), m = "" + a.key), "key" in a) {
|
|
1461
1462
|
d = {};
|
|
1462
|
-
for (var
|
|
1463
|
-
|
|
1463
|
+
for (var U in a)
|
|
1464
|
+
U !== "key" && (d[U] = a[U]);
|
|
1464
1465
|
} else d = a;
|
|
1465
1466
|
return m && u(
|
|
1466
1467
|
d,
|
|
@@ -1470,17 +1471,17 @@ React keys must be passed directly to JSX without using spread:
|
|
|
1470
1471
|
m,
|
|
1471
1472
|
d,
|
|
1472
1473
|
r(),
|
|
1473
|
-
|
|
1474
|
-
|
|
1474
|
+
j,
|
|
1475
|
+
N
|
|
1475
1476
|
);
|
|
1476
1477
|
}
|
|
1477
|
-
function
|
|
1478
|
-
|
|
1478
|
+
function P(n) {
|
|
1479
|
+
A(n) ? n._store && (n._store.validated = 1) : typeof n == "object" && n !== null && n.$$typeof === w && (n._payload.status === "fulfilled" ? A(n._payload.value) && n._payload.value._store && (n._payload.value._store.validated = 1) : n._store && (n._store.validated = 1));
|
|
1479
1480
|
}
|
|
1480
|
-
function
|
|
1481
|
+
function A(n) {
|
|
1481
1482
|
return typeof n == "object" && n !== null && n.$$typeof === C;
|
|
1482
1483
|
}
|
|
1483
|
-
var b =
|
|
1484
|
+
var b = ct, C = Symbol.for("react.transitional.element"), M = Symbol.for("react.portal"), E = Symbol.for("react.fragment"), I = Symbol.for("react.strict_mode"), B = Symbol.for("react.profiler"), $ = Symbol.for("react.consumer"), F = Symbol.for("react.context"), z = Symbol.for("react.forward_ref"), D = Symbol.for("react.suspense"), H = Symbol.for("react.suspense_list"), T = Symbol.for("react.memo"), w = Symbol.for("react.lazy"), L = Symbol.for("react.activity"), O = Symbol.for("react.client.reference"), R = b.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, p = Object.prototype.hasOwnProperty, v = Array.isArray, x = console.createTask ? console.createTask : function() {
|
|
1484
1485
|
return null;
|
|
1485
1486
|
};
|
|
1486
1487
|
b = {
|
|
@@ -1491,33 +1492,33 @@ React keys must be passed directly to JSX without using spread:
|
|
|
1491
1492
|
var J, X = {}, G = b.react_stack_bottom_frame.bind(
|
|
1492
1493
|
b,
|
|
1493
1494
|
i
|
|
1494
|
-
)(), Z =
|
|
1495
|
-
|
|
1496
|
-
var h = 1e4 >
|
|
1497
|
-
return
|
|
1495
|
+
)(), Z = x(s(i)), K = {};
|
|
1496
|
+
q.Fragment = E, q.jsx = function(n, a, d) {
|
|
1497
|
+
var h = 1e4 > R.recentlyCreatedOwnerStacks++;
|
|
1498
|
+
return f(
|
|
1498
1499
|
n,
|
|
1499
1500
|
a,
|
|
1500
1501
|
d,
|
|
1501
1502
|
!1,
|
|
1502
1503
|
h ? Error("react-stack-top-frame") : G,
|
|
1503
|
-
h ?
|
|
1504
|
+
h ? x(s(n)) : Z
|
|
1504
1505
|
);
|
|
1505
|
-
},
|
|
1506
|
-
var h = 1e4 >
|
|
1507
|
-
return
|
|
1506
|
+
}, q.jsxs = function(n, a, d) {
|
|
1507
|
+
var h = 1e4 > R.recentlyCreatedOwnerStacks++;
|
|
1508
|
+
return f(
|
|
1508
1509
|
n,
|
|
1509
1510
|
a,
|
|
1510
1511
|
d,
|
|
1511
1512
|
!0,
|
|
1512
1513
|
h ? Error("react-stack-top-frame") : G,
|
|
1513
|
-
h ?
|
|
1514
|
+
h ? x(s(n)) : Z
|
|
1514
1515
|
);
|
|
1515
1516
|
};
|
|
1516
|
-
}()),
|
|
1517
|
+
}()), q;
|
|
1517
1518
|
}
|
|
1518
|
-
process.env.NODE_ENV === "production" ?
|
|
1519
|
-
var
|
|
1520
|
-
const
|
|
1519
|
+
process.env.NODE_ENV === "production" ? Y.exports = mt() : Y.exports = pt();
|
|
1520
|
+
var rt = Y.exports;
|
|
1521
|
+
const yt = (c) => {
|
|
1521
1522
|
const {
|
|
1522
1523
|
src: t,
|
|
1523
1524
|
autoplay: e,
|
|
@@ -1526,61 +1527,65 @@ const ft = (c) => {
|
|
|
1526
1527
|
poster: i,
|
|
1527
1528
|
preload: l,
|
|
1528
1529
|
theme: u,
|
|
1529
|
-
s3Config:
|
|
1530
|
+
s3Config: g,
|
|
1530
1531
|
analytics: y,
|
|
1531
|
-
hlsConfig:
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1532
|
+
hlsConfig: f,
|
|
1533
|
+
subtitles: P,
|
|
1534
|
+
stickyControls: A,
|
|
1535
|
+
onReady: b,
|
|
1536
|
+
onPlay: C,
|
|
1537
|
+
onPause: M,
|
|
1538
|
+
onEnded: E,
|
|
1539
|
+
onTimeUpdate: I,
|
|
1540
|
+
onVolumeChange: B,
|
|
1541
|
+
onError: $,
|
|
1542
|
+
onLoadedMetadata: F,
|
|
1543
|
+
onQualityChange: z,
|
|
1544
|
+
style: D,
|
|
1545
|
+
className: H,
|
|
1541
1546
|
width: T = "100%",
|
|
1542
|
-
height:
|
|
1543
|
-
} = c,
|
|
1544
|
-
return
|
|
1545
|
-
if (!
|
|
1546
|
-
const
|
|
1547
|
+
height: w = "500px"
|
|
1548
|
+
} = c, L = V(null), O = V(null);
|
|
1549
|
+
return Q(() => {
|
|
1550
|
+
if (!L.current) return;
|
|
1551
|
+
const R = {
|
|
1547
1552
|
src: t,
|
|
1548
|
-
container:
|
|
1553
|
+
container: L.current,
|
|
1549
1554
|
autoplay: e,
|
|
1550
1555
|
muted: s,
|
|
1551
1556
|
controls: r,
|
|
1552
1557
|
poster: i,
|
|
1553
1558
|
preload: l,
|
|
1554
1559
|
theme: u,
|
|
1555
|
-
s3Config:
|
|
1560
|
+
s3Config: g,
|
|
1556
1561
|
analytics: y,
|
|
1557
|
-
hlsConfig:
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1562
|
+
hlsConfig: f,
|
|
1563
|
+
subtitles: P,
|
|
1564
|
+
stickyControls: A
|
|
1565
|
+
}, p = new st(R);
|
|
1566
|
+
return O.current = p, C && p.on("play", C), M && p.on("pause", M), E && p.on("ended", E), $ && p.on("error", (v) => {
|
|
1567
|
+
var x;
|
|
1568
|
+
return $((x = v.data) == null ? void 0 : x.error);
|
|
1569
|
+
}), F && p.on("loadedmetadata", F), z && p.on("qualitychange", (v) => z(v.data.level)), I && p.on("timeupdate", (v) => I(v.data.currentTime)), B && p.on("volumechange", (v) => B(v.data.volume, v.data.muted)), b && b(p), () => {
|
|
1570
|
+
p.destroy(), O.current = null;
|
|
1564
1571
|
};
|
|
1565
|
-
}, [t]),
|
|
1566
|
-
_.current;
|
|
1567
|
-
}, [e, s, r]), /* @__PURE__ */ st.jsx(
|
|
1572
|
+
}, [t]), /* @__PURE__ */ rt.jsx(
|
|
1568
1573
|
"div",
|
|
1569
1574
|
{
|
|
1570
|
-
ref:
|
|
1571
|
-
className:
|
|
1575
|
+
ref: L,
|
|
1576
|
+
className: H,
|
|
1572
1577
|
style: {
|
|
1573
1578
|
width: typeof T == "number" ? `${T}px` : T,
|
|
1574
|
-
height: typeof
|
|
1575
|
-
...
|
|
1579
|
+
height: typeof w == "number" ? `${w}px` : w,
|
|
1580
|
+
...D
|
|
1576
1581
|
}
|
|
1577
1582
|
}
|
|
1578
1583
|
);
|
|
1579
|
-
},
|
|
1580
|
-
const [t, e] =
|
|
1581
|
-
return
|
|
1584
|
+
}, bt = (c) => {
|
|
1585
|
+
const [t, e] = W(null), [s, r] = W(null), i = V(null);
|
|
1586
|
+
return Q(() => {
|
|
1582
1587
|
if (!i.current) return;
|
|
1583
|
-
const l = new
|
|
1588
|
+
const l = new st({
|
|
1584
1589
|
...c,
|
|
1585
1590
|
container: i.current
|
|
1586
1591
|
});
|
|
@@ -1596,31 +1601,31 @@ const ft = (c) => {
|
|
|
1596
1601
|
player: t,
|
|
1597
1602
|
state: s
|
|
1598
1603
|
};
|
|
1599
|
-
},
|
|
1604
|
+
}, it = nt.createContext({
|
|
1600
1605
|
player: null,
|
|
1601
1606
|
state: null
|
|
1602
|
-
}),
|
|
1603
|
-
const { player: t, children: e } = c, [s, r] =
|
|
1604
|
-
return
|
|
1607
|
+
}), wt = (c) => {
|
|
1608
|
+
const { player: t, children: e } = c, [s, r] = W(t.getState());
|
|
1609
|
+
return Q(() => {
|
|
1605
1610
|
const i = () => {
|
|
1606
1611
|
r(t.getState());
|
|
1607
1612
|
};
|
|
1608
1613
|
return t.on("play", i), t.on("pause", i), t.on("timeupdate", i), t.on("volumechange", i), t.on("loadedmetadata", i), () => {
|
|
1609
1614
|
};
|
|
1610
|
-
}, [t]), /* @__PURE__ */
|
|
1611
|
-
},
|
|
1612
|
-
const c =
|
|
1615
|
+
}, [t]), /* @__PURE__ */ rt.jsx(it.Provider, { value: { player: t, state: s }, children: e });
|
|
1616
|
+
}, kt = () => {
|
|
1617
|
+
const c = nt.useContext(it);
|
|
1613
1618
|
if (!c.player)
|
|
1614
1619
|
throw new Error("useWontumPlayerContext must be used within WontumPlayerProvider");
|
|
1615
1620
|
return c;
|
|
1616
1621
|
};
|
|
1617
1622
|
export {
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1623
|
+
ut as Analytics,
|
|
1624
|
+
ht as S3Handler,
|
|
1625
|
+
dt as UIController,
|
|
1626
|
+
st as WontumPlayer,
|
|
1627
|
+
wt as WontumPlayerProvider,
|
|
1628
|
+
yt as WontumPlayerReact,
|
|
1629
|
+
bt as useWontumPlayer,
|
|
1630
|
+
kt as useWontumPlayerContext
|
|
1626
1631
|
};
|
package/package.json
CHANGED