@goboss/web-video-player-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @goboss/web-video-player-sdk might be problematic. Click here for more details.

package/dist/index.js ADDED
@@ -0,0 +1,1803 @@
1
+ import { createElement as e, useEffect as t, useRef as n, useState as r } from "react";
2
+ import { createRoot as i } from "react-dom/client";
3
+ import a from "hls.js";
4
+ import { Airplay as o, Cast as s, Check as c, ChevronRight as l, Languages as u, ListVideo as d, Maximize as f, Minimize as p, Pause as ee, PictureInPicture as te, Play as ne, RotateCcw as re, RotateCw as ie, Settings as ae, Subtitles as oe, Volume as se, Volume1 as ce, Volume2 as le, VolumeX as ue, X as de } from "lucide-react";
5
+ import * as m from "dashjs";
6
+ import { getApps as h, initializeApp as fe } from "firebase/app";
7
+ import { getAnalytics as g, isSupported as _, logEvent as pe } from "firebase/analytics";
8
+ import { jsx as v, jsxs as y } from "react/jsx-runtime";
9
+ //#region ../analytics/src/analytics.ts
10
+ var me = class {
11
+ callback;
12
+ heartbeatInterval;
13
+ isBuffering = !1;
14
+ sessionId;
15
+ videoId;
16
+ deviceType;
17
+ networkType;
18
+ isFirstPlay = !0;
19
+ watchStartTime = null;
20
+ totalWatchTime = 0;
21
+ bufferingCount = 0;
22
+ totalBufferingTime = 0;
23
+ bufferingStartTime = null;
24
+ milestonesHit = /* @__PURE__ */ new Set();
25
+ lastHeartbeatPosition = null;
26
+ lastHeartbeatAt = null;
27
+ constructor(e, t) {
28
+ this.callback = e, this.sessionId = this.generateSessionId(), this.videoId = t ? this.extractVideoId(t) : "", this.deviceType = this.getDeviceType(), this.networkType = this.getNetworkType();
29
+ }
30
+ registerCallback(e) {
31
+ this.callback = e;
32
+ }
33
+ track(e, t, n = {}) {
34
+ e === "play" && this.isFirstPlay && (this.isFirstPlay = !1, this.dispatchRaw({
35
+ eventType: "session_start",
36
+ timestamp: Date.now(),
37
+ currentTime: t.currentTime,
38
+ duration: t.duration || 0,
39
+ sessionId: this.sessionId,
40
+ videoId: this.videoId,
41
+ deviceType: this.deviceType,
42
+ networkType: this.networkType,
43
+ watchPercentage: 0,
44
+ totalWatchTime: 0,
45
+ bufferingCount: 0,
46
+ totalBufferingTime: 0
47
+ })), e === "play" && (this.watchStartTime = Date.now()), (e === "pause" || e === "ended") && this.watchStartTime !== null && (this.totalWatchTime += (Date.now() - this.watchStartTime) / 1e3, this.watchStartTime = null);
48
+ let r = t.duration ? Math.min(100, Math.round(t.currentTime / t.duration * 100)) : 0, i = {
49
+ eventType: e,
50
+ timestamp: Date.now(),
51
+ currentTime: t.currentTime,
52
+ duration: t.duration || 0,
53
+ volume: t.volume,
54
+ speed: t.playbackRate,
55
+ sessionId: this.sessionId,
56
+ videoId: this.videoId,
57
+ deviceType: this.deviceType,
58
+ networkType: this.networkType,
59
+ watchPercentage: r,
60
+ totalWatchTime: Math.round(this.totalWatchTime),
61
+ bufferingCount: this.bufferingCount,
62
+ totalBufferingTime: Math.round(this.totalBufferingTime),
63
+ ...n
64
+ };
65
+ this.dispatchRaw(i);
66
+ }
67
+ startHeartbeat(e, t) {
68
+ this.stopHeartbeat(), this.heartbeatInterval = window.setInterval(() => {
69
+ !e.paused && !this.isBuffering && (this.checkMilestones(e, t), this.checkStall(e, t), this.track("heartbeat", e, t())), this.lastHeartbeatPosition = e.currentTime, this.lastHeartbeatAt = Date.now();
70
+ }, 5e3);
71
+ }
72
+ stopHeartbeat() {
73
+ this.heartbeatInterval &&= (window.clearInterval(this.heartbeatInterval), void 0);
74
+ }
75
+ setBuffering(e, t, n) {
76
+ this.isBuffering !== e && (this.isBuffering = e, e ? (this.bufferingCount++, this.bufferingStartTime = Date.now()) : this.bufferingStartTime !== null && (this.totalBufferingTime += (Date.now() - this.bufferingStartTime) / 1e3, this.bufferingStartTime = null), this.track(e ? "buffering_start" : "buffering_end", t, n()));
77
+ }
78
+ checkMilestones(e, t) {
79
+ let { currentTime: n, duration: r } = e;
80
+ if (!r) return;
81
+ let i = n / r;
82
+ for (let [n, r] of [
83
+ [.25, "first_quartile"],
84
+ [.5, "midpoint"],
85
+ [.75, "third_quartile"]
86
+ ]) i >= n && !this.milestonesHit.has(r) && (this.milestonesHit.add(r), this.track(r, e, {
87
+ ...t(),
88
+ watchPercentage: n * 100
89
+ }));
90
+ }
91
+ checkStall(e, t) {
92
+ this.lastHeartbeatPosition !== null && this.lastHeartbeatAt !== null && e.currentTime - this.lastHeartbeatPosition < .1 && Date.now() - this.lastHeartbeatAt >= 4500 && this.track("stall", e, t());
93
+ }
94
+ dispatchRaw(e) {
95
+ if (this.callback) try {
96
+ this.callback(e);
97
+ } catch (e) {
98
+ console.error("[PlayerSDK Analytics] Callback failed:", e);
99
+ }
100
+ }
101
+ generateSessionId() {
102
+ return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `sess-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
103
+ }
104
+ extractVideoId(e) {
105
+ try {
106
+ let t = new URL(e), n = t.pathname.split("/").filter(Boolean);
107
+ return n.length > 0 && n[n.length - 1].includes(".") && n.pop(), n[n.length - 1] || t.hostname;
108
+ } catch {
109
+ let t = e.split("/").filter(Boolean);
110
+ return t.length >= 2 && t[t.length - 1].includes(".") ? t[t.length - 2] : t[t.length - 1] || "unknown";
111
+ }
112
+ }
113
+ getDeviceType() {
114
+ let e = navigator.userAgent;
115
+ return /mobile/i.test(e) ? "mobile" : /tablet|ipad/i.test(e) ? "tablet" : "desktop";
116
+ }
117
+ getNetworkType() {
118
+ let e = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
119
+ return e && (e.effectiveType || e.type) || "unknown";
120
+ }
121
+ }, b = {
122
+ session_start: "player_session_start",
123
+ error: "player_error"
124
+ }, he = new Set(["heartbeat"]), ge = class {
125
+ analytics = null;
126
+ constructor(e) {
127
+ this.init(e);
128
+ }
129
+ async init(e) {
130
+ try {
131
+ if (!await _()) {
132
+ console.warn("[FirebaseAnalytics] Not supported in this environment.");
133
+ return;
134
+ }
135
+ let t = h(), n = t.length === 0 ? fe(e) : t[0];
136
+ this.analytics = g(n);
137
+ } catch (e) {
138
+ console.error("[FirebaseAnalytics] Initialization failed:", e);
139
+ }
140
+ }
141
+ createCallback() {
142
+ return (e) => this.handleEvent(e);
143
+ }
144
+ handleEvent(e) {
145
+ if (!this.analytics || he.has(e.eventType)) return;
146
+ let t = b[e.eventType] ?? e.eventType, n = this.buildParams(e);
147
+ try {
148
+ pe(this.analytics, t, n);
149
+ } catch (e) {
150
+ console.error("[FirebaseAnalytics] logEvent failed:", e);
151
+ }
152
+ }
153
+ buildParams(e) {
154
+ let t = {
155
+ session_id: (e.sessionId ?? "").slice(0, 100),
156
+ video_id: (e.videoId ?? "").slice(0, 100),
157
+ device_type: e.deviceType ?? "unknown",
158
+ network_type: e.networkType ?? "unknown",
159
+ current_time: Math.round(e.currentTime),
160
+ duration: Math.round(e.duration),
161
+ watch_percentage: e.watchPercentage ?? 0,
162
+ total_watch_time: e.totalWatchTime ?? 0,
163
+ buffering_count: e.bufferingCount ?? 0,
164
+ total_buffering_time: e.totalBufferingTime ?? 0
165
+ };
166
+ return e.rendition && (t.rendition = e.rendition.slice(0, 100)), e.bitrate && (t.bitrate = e.bitrate), e.fromRendition && (t.from_rendition = e.fromRendition.slice(0, 100)), e.volume !== void 0 && (t.volume = Math.round(e.volume * 100)), e.speed !== void 0 && (t.speed = e.speed), e.errorMessage && (t.error_message = e.errorMessage.slice(0, 100)), e.errorCode && (t.error_code = e.errorCode), e.seekFrom !== void 0 && (t.seek_from = Math.round(e.seekFrom)), e.pipState && (t.pip_state = e.pipState), t;
167
+ }
168
+ destroy() {
169
+ return Promise.resolve();
170
+ }
171
+ }, _e = class {
172
+ keyMoments = [];
173
+ currentMomentIndex = -1;
174
+ onMomentChangeCallback;
175
+ constructor(e = []) {
176
+ this.setKeyMoments(e);
177
+ }
178
+ setKeyMoments(e) {
179
+ this.keyMoments = [...e].sort((e, t) => e.startTime - t.startTime), this.currentMomentIndex = -1;
180
+ }
181
+ getKeyMoments() {
182
+ return this.keyMoments;
183
+ }
184
+ getCurrentMoment(e) {
185
+ let t = this.keyMoments.findIndex((t) => e >= t.startTime && e < t.endTime);
186
+ return t === -1 ? {
187
+ keyMoment: null,
188
+ index: -1
189
+ } : {
190
+ keyMoment: this.keyMoments[t],
191
+ index: t
192
+ };
193
+ }
194
+ updateTime(e) {
195
+ let { keyMoment: t, index: n } = this.getCurrentMoment(e);
196
+ n !== this.currentMomentIndex && (this.currentMomentIndex = n, this.onMomentChangeCallback && this.onMomentChangeCallback(t, n));
197
+ }
198
+ onMomentChange(e) {
199
+ this.onMomentChangeCallback = e;
200
+ }
201
+ setChapters(e) {
202
+ this.setKeyMoments(e);
203
+ }
204
+ getChapters() {
205
+ return this.getKeyMoments();
206
+ }
207
+ getCurrentChapter(e) {
208
+ let t = this.getCurrentMoment(e);
209
+ return {
210
+ chapter: t.keyMoment,
211
+ index: t.index
212
+ };
213
+ }
214
+ onChapterChange(e) {
215
+ this.onMomentChange(e);
216
+ }
217
+ }, x = class {
218
+ tracks = [];
219
+ activeTrackId = "off";
220
+ currentCues = [];
221
+ activeText = "";
222
+ onSubtitleChangeCallback;
223
+ onTrackSwitchCallback;
224
+ constructor(e = []) {
225
+ this.tracks = e;
226
+ let t = e.find((e) => e.isDefault);
227
+ t && this.setActiveTrack(t.id);
228
+ }
229
+ getTracks() {
230
+ return this.tracks;
231
+ }
232
+ getActiveTrackId() {
233
+ return this.activeTrackId;
234
+ }
235
+ setHlsTracks(e) {
236
+ let t = this.tracks.filter((e) => !e.isHls && !e.isNative);
237
+ this.tracks = [...t, ...e];
238
+ }
239
+ addTrack(e) {
240
+ this.tracks.find((t) => t.id === e.id) || this.tracks.push(e);
241
+ }
242
+ onTrackSwitch(e) {
243
+ this.onTrackSwitchCallback = e;
244
+ }
245
+ setCustomSubtitleText(e) {
246
+ e !== this.activeText && (this.activeText = e, this.onSubtitleChangeCallback && this.onSubtitleChangeCallback(e));
247
+ }
248
+ async setActiveTrack(e) {
249
+ if (this.activeTrackId = e, e === "off") {
250
+ this.currentCues = [], this.updateActiveText(0), this.onTrackSwitchCallback && this.onTrackSwitchCallback(null);
251
+ return;
252
+ }
253
+ let t = this.tracks.find((t) => t.id === e);
254
+ if (!t) {
255
+ this.currentCues = [], this.updateActiveText(0), this.onTrackSwitchCallback && this.onTrackSwitchCallback(null);
256
+ return;
257
+ }
258
+ if (t.isHls || t.isNative) {
259
+ this.currentCues = [], this.updateActiveText(0), this.onTrackSwitchCallback && this.onTrackSwitchCallback(t);
260
+ return;
261
+ }
262
+ if (this.onTrackSwitchCallback && this.onTrackSwitchCallback(null), t.cues) {
263
+ this.currentCues = t.cues;
264
+ return;
265
+ }
266
+ if (t.src) try {
267
+ let n = await fetch(t.src);
268
+ if (!n.ok) throw Error(`HTTP error ${n.status}`);
269
+ let r = await n.text(), i = this.parseVttOrSrt(r);
270
+ t.cues = i, this.activeTrackId === e && (this.currentCues = i);
271
+ } catch (e) {
272
+ console.error(`[PlayerSDK Subtitles] Failed to fetch track ${t.label}:`, e), this.currentCues = [];
273
+ }
274
+ }
275
+ updateTime(e) {
276
+ if (this.activeTrackId === "off" || this.currentCues.length === 0) {
277
+ let e = this.tracks.find((e) => e.id === this.activeTrackId);
278
+ (!e || !e.isHls && !e.isNative) && this.activeText !== "" && (this.activeText = "", this.onSubtitleChangeCallback && this.onSubtitleChangeCallback(""));
279
+ return;
280
+ }
281
+ this.updateActiveText(e);
282
+ }
283
+ updateActiveText(e) {
284
+ let t = this.currentCues.filter((t) => e >= t.startTime && e <= t.endTime).map((e) => e.text).join("<br />");
285
+ t !== this.activeText && (this.activeText = t, this.onSubtitleChangeCallback && this.onSubtitleChangeCallback(t));
286
+ }
287
+ onSubtitleChange(e) {
288
+ this.onSubtitleChangeCallback = e;
289
+ }
290
+ parseVttOrSrt(e) {
291
+ let t = e.replace(/^/, "");
292
+ if (t.trimStart().startsWith("#EXTM3U")) return [];
293
+ let n = [], r = t.split(/\r?\n/), i = 0, a = 0, o = [], s = !1, c = !1, l = /(\d+):(\d{2}):(\d{2})[.,](\d{3})\s*-->\s*(\d+):(\d{2}):(\d{2})[.,](\d{3})/, u = /^(\d{2}):(\d{2})[.,](\d{3})\s*-->\s*(\d{2}):(\d{2})[.,](\d{3})/, d = (e, t, n, r) => parseInt(e, 10) * 3600 + parseInt(t, 10) * 60 + parseInt(n, 10) + parseInt(r, 10) / 1e3, f = (e) => e.replace(/<\d{2}[:.]\d{2}[:.]\d{2}\.\d{3}>/g, "").replace(/<[^>]+>/g, ""), p = () => {
294
+ s && o.length > 0 && n.push({
295
+ startTime: i,
296
+ endTime: a,
297
+ text: o.map(f).join("\n")
298
+ }), o = [], s = !1;
299
+ };
300
+ for (let e of r) {
301
+ let t = e.trim();
302
+ if (!t) {
303
+ s && p(), c = !1;
304
+ continue;
305
+ }
306
+ let n = t.toUpperCase();
307
+ if (n === "WEBVTT" || n.startsWith("NOTE") || n.startsWith("X-TIMESTAMP-MAP") || n.startsWith("STYLE") || n.startsWith("REGION")) {
308
+ c = !0;
309
+ continue;
310
+ }
311
+ if (c) continue;
312
+ let r = t.match(l);
313
+ if (r) {
314
+ p(), i = d(r[1], r[2], r[3], r[4]), a = d(r[5], r[6], r[7], r[8]), s = !0;
315
+ continue;
316
+ }
317
+ let f = t.match(u);
318
+ if (f) {
319
+ p(), i = parseInt(f[1], 10) * 60 + parseInt(f[2], 10) + parseInt(f[3], 10) / 1e3, a = parseInt(f[4], 10) * 60 + parseInt(f[5], 10) + parseInt(f[6], 10) / 1e3, s = !0;
320
+ continue;
321
+ }
322
+ s && o.push(t);
323
+ }
324
+ return p(), n;
325
+ }
326
+ }, ve = class {
327
+ config;
328
+ watermarkElement;
329
+ floatInterval;
330
+ constructor(e) {
331
+ this.config = e;
332
+ }
333
+ validateDomain(e) {
334
+ return !this.config || !this.config.allowedDomains || this.config.allowedDomains.length === 0 ? !0 : this.config.allowedDomains.includes(e) || this.config.allowedDomains.some((t) => e.endsWith(t));
335
+ }
336
+ getAuthToken() {
337
+ return this.config?.authToken;
338
+ }
339
+ setupWatermark(e) {
340
+ if (this.removeWatermark(), !this.config || !this.config.watermarkText) return;
341
+ let t = this.config.watermarkText, n = document.createElement("div");
342
+ n.className = "sdk-watermark-overlay", n.innerText = t, n.style.position = "absolute", n.style.pointerEvents = "none", n.style.userSelect = "none", n.style.color = "rgba(255, 255, 255, 0.4)", n.style.fontSize = "12px", n.style.fontFamily = "monospace", n.style.fontWeight = "bold", n.style.zIndex = "9", n.style.padding = "4px 8px", n.style.borderRadius = "4px", n.style.background = "rgba(0, 0, 0, 0.4)", n.style.backdropFilter = "blur(2px)", n.style.top = "20px", n.style.right = "20px", e.appendChild(n), this.watermarkElement = n;
343
+ }
344
+ removeWatermark() {
345
+ this.floatInterval &&= (window.clearInterval(this.floatInterval), void 0), this.watermarkElement && this.watermarkElement.parentElement && this.watermarkElement.parentElement.removeChild(this.watermarkElement), this.watermarkElement = void 0;
346
+ }
347
+ isDRMProtected() {
348
+ return !!(this.config?.widevineLicenseUrl || this.config?.playreadyLicenseUrl || this.config?.fairplayLicenseUrl);
349
+ }
350
+ getDRMDetails() {
351
+ return {
352
+ widevine: this.config?.widevineLicenseUrl || null,
353
+ playready: this.config?.playreadyLicenseUrl || null,
354
+ fairplay: this.config?.fairplayLicenseUrl || null,
355
+ authTokenPresent: !!this.config?.authToken,
356
+ allowedDomains: this.config?.allowedDomains || []
357
+ };
358
+ }
359
+ }, ye = class {
360
+ isCasting = !1;
361
+ castDeviceName = "";
362
+ onCastStateChangeCallback;
363
+ castContext = null;
364
+ remotePlayer = null;
365
+ remotePlayerController = null;
366
+ constructor() {
367
+ this.initCastApi();
368
+ }
369
+ initCastApi() {
370
+ let e = () => {
371
+ this.castContext = window.cast.framework.CastContext.getInstance(), this.castContext.setOptions({
372
+ receiverApplicationId: window.chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID,
373
+ autoJoinPolicy: window.chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED
374
+ }), this.remotePlayer = new window.cast.framework.RemotePlayer(), this.remotePlayerController = new window.cast.framework.RemotePlayerController(this.remotePlayer), this.remotePlayerController.addEventListener(window.cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED, () => {
375
+ this.isCasting = this.remotePlayer.isConnected;
376
+ let e = this.castContext.getCurrentSession();
377
+ this.castDeviceName = e ? e.getCastDevice().friendlyName : "", this.onCastStateChangeCallback && this.onCastStateChangeCallback(this.isCasting, this.castDeviceName);
378
+ });
379
+ };
380
+ window.cast && window.cast.framework ? e() : window.__onGCastApiAvailable = (t) => {
381
+ t && e();
382
+ };
383
+ }
384
+ getCastingState() {
385
+ return {
386
+ isCasting: this.isCasting,
387
+ deviceName: this.castDeviceName
388
+ };
389
+ }
390
+ async requestSession(e, t) {
391
+ if (!this.castContext) {
392
+ console.error("[PlayerSDK Cast] Google Cast Framework not loaded.");
393
+ return;
394
+ }
395
+ try {
396
+ await this.castContext.requestSession();
397
+ let n = this.castContext.getCurrentSession();
398
+ if (n && e) {
399
+ let r = new window.chrome.cast.media.MediaInfo(e, "video/mp4"), i = new window.chrome.cast.media.LoadRequest(r);
400
+ i.currentTime = t, i.autoplay = !0, await n.loadMedia(i);
401
+ }
402
+ } catch (e) {
403
+ console.warn("[PlayerSDK Cast] Session request failed or cancelled by user.", e);
404
+ }
405
+ }
406
+ stopCasting() {
407
+ if (this.castContext) try {
408
+ this.castContext.endCurrentSession(!0);
409
+ } catch (e) {
410
+ console.warn("[PlayerSDK Cast] Failed to disconnect session", e);
411
+ }
412
+ }
413
+ onCastStateChange(e) {
414
+ this.onCastStateChangeCallback = e;
415
+ }
416
+ requestAirPlaySession(e) {
417
+ let t = e;
418
+ typeof t.webkitShowPlaybackTargetPicker == "function" ? t.webkitShowPlaybackTargetPicker() : console.warn("[PlayerSDK AirPlay] AirPlay request is not supported on this device.");
419
+ }
420
+ stopAirPlay(e) {
421
+ let t = e;
422
+ typeof t.webkitShowPlaybackTargetPicker == "function" ? t.webkitShowPlaybackTargetPicker() : console.warn("[PlayerSDK AirPlay] AirPlay stop is not supported on this device.");
423
+ }
424
+ isAirPlayAvailable() {
425
+ return !!window.WebKitPlaybackTargetAvailabilityEvent || navigator.userAgent.includes("Safari") && !navigator.userAgent.includes("Chrome");
426
+ }
427
+ }, be = class {
428
+ config;
429
+ constructor(e) {
430
+ this.config = e;
431
+ }
432
+ getThumbnail(e) {
433
+ if (!this.config) return null;
434
+ let { spriteUrl: t, tileWidth: n, tileHeight: r, columns: i, interval: a, totalCount: o } = this.config, s = Math.floor(e / a);
435
+ s < 0 && (s = 0), s >= o && (s = o - 1);
436
+ let c = s % i, l = Math.floor(s / i);
437
+ return {
438
+ url: t,
439
+ x: c * n,
440
+ y: l * r,
441
+ width: n,
442
+ height: r
443
+ };
444
+ }
445
+ hasThumbnails() {
446
+ return !!this.config;
447
+ }
448
+ }, xe = class {
449
+ options;
450
+ videoElement;
451
+ hlsInstance = null;
452
+ dashInstance = null;
453
+ activeQuality = {
454
+ id: -1,
455
+ height: 0,
456
+ width: 0,
457
+ bitrate: 0,
458
+ label: "Auto"
459
+ };
460
+ qualityLevels = [];
461
+ analytics;
462
+ keyMoments;
463
+ chapters;
464
+ subtitles;
465
+ drm;
466
+ casting;
467
+ thumbnails;
468
+ hlsSubtitleCues = /* @__PURE__ */ new Map();
469
+ hlsActiveSubtitleKey = null;
470
+ audioTrackList = [];
471
+ eventListeners = {};
472
+ constructor(e) {
473
+ this.options = {
474
+ autoplay: !1,
475
+ muted: !1,
476
+ themeColor: "#6366f1",
477
+ ...e
478
+ }, this.analytics = new me(this.options.analyticsCallback, this.options.src), this.keyMoments = new _e(this.options.keyMoments || this.options.chapters || []), this.chapters = this.keyMoments, this.subtitles = new x(this.options.subtitles), this.drm = new ve(this.options.drm), this.casting = new ye(), this.thumbnails = new be(this.options.thumbnails), this.initializePlayer();
479
+ }
480
+ initializePlayer() {
481
+ let e = window.location.hostname;
482
+ if (!this.drm.validateDomain(e)) {
483
+ let t = `Domain Blocked: Access to streaming content is restricted on ${e}.`;
484
+ throw console.error(t), this.options.container.innerHTML = `
485
+ <div style="background:#0f172a; color:#f43f5e; padding:20px; text-align:center; font-family:sans-serif; border-radius:12px; border:1px solid #e11d48; margin: 10px;">
486
+ <h4 style="margin:0 0 10px 0;">Content Protection Alert</h4>
487
+ <p style="font-size:13px; margin:0; opacity:0.8;">${t}</p>
488
+ </div>
489
+ `, Error(t);
490
+ }
491
+ this.videoElement = document.createElement("video"), this.videoElement.className = "sdk-html5-video", this.videoElement.style.width = "100%", this.videoElement.style.height = "100%", this.videoElement.style.display = "block", this.videoElement.style.backgroundColor = "#000000", this.videoElement.playsInline = !0, this.videoElement.controls = !1, this.videoElement.muted = !!this.options.muted, this.options.container.appendChild(this.videoElement), this.drm.setupWatermark(this.options.container), this.bindMediaEvents(), this.loadSource(this.options.src), this.setupBackgroundControls();
492
+ }
493
+ bindMediaEvents() {
494
+ let e = this.videoElement;
495
+ e.addEventListener("play", () => {
496
+ this.analytics.track("play", e, this.getAnalyticsPayload()), this.analytics.startHeartbeat(e, () => this.getAnalyticsPayload()), this.emit("play", null);
497
+ }), e.addEventListener("pause", () => {
498
+ this.analytics.track("pause", e, this.getAnalyticsPayload()), this.analytics.stopHeartbeat(), this.emit("pause", null);
499
+ }), e.addEventListener("timeupdate", () => {
500
+ let t = e.currentTime;
501
+ if (this.chapters.updateTime(t), this.subtitles.updateTime(t), this.hlsActiveSubtitleKey !== null) {
502
+ let e = (this.hlsSubtitleCues.get(this.hlsActiveSubtitleKey) ?? []).filter((e) => t >= e.startTime && t < e.endTime);
503
+ this.subtitles.setCustomSubtitleText(e.map((e) => e.text).join("<br />"));
504
+ }
505
+ this.emit("timeupdate", t);
506
+ }), e.addEventListener("seeking", () => {
507
+ this.analytics.track("seek", e, this.getAnalyticsPayload()), this.emit("seeking", e.currentTime);
508
+ }), e.addEventListener("waiting", () => {
509
+ this.analytics.setBuffering(!0, e, () => this.getAnalyticsPayload()), this.emit("buffering", !0);
510
+ }), e.addEventListener("playing", () => {
511
+ this.analytics.setBuffering(!1, e, () => this.getAnalyticsPayload()), this.emit("buffering", !1);
512
+ }), e.addEventListener("volumechange", () => {
513
+ this.analytics.track("volume_change", e, this.getAnalyticsPayload()), this.emit("volumechange", {
514
+ volume: e.volume,
515
+ muted: e.muted
516
+ });
517
+ }), e.addEventListener("ratechange", () => {
518
+ this.analytics.track("speed_change", e, this.getAnalyticsPayload()), this.emit("ratechange", e.playbackRate);
519
+ }), e.addEventListener("ended", () => {
520
+ this.analytics.track("ended", e, this.getAnalyticsPayload()), this.analytics.track("complete", e, {
521
+ ...this.getAnalyticsPayload(),
522
+ watchPercentage: 100
523
+ }), this.analytics.stopHeartbeat(), this.emit("ended", null);
524
+ }), e.addEventListener("enterpictureinpicture", () => {
525
+ this.analytics.track("pip_toggle", e, {
526
+ ...this.getAnalyticsPayload(),
527
+ errorMessage: "entered"
528
+ }), this.emit("pipchange", !0);
529
+ }), e.addEventListener("leavepictureinpicture", () => {
530
+ this.analytics.track("pip_toggle", e, {
531
+ ...this.getAnalyticsPayload(),
532
+ errorMessage: "exited"
533
+ }), this.emit("pipchange", !1);
534
+ }), e.addEventListener("error", () => {
535
+ let t = e.error;
536
+ this.analytics.track("error", e, {
537
+ ...this.getAnalyticsPayload(),
538
+ errorMessage: t ? `${t.code}: ${t.message}` : "Unknown HTML5 video playback error"
539
+ }), this.emit("error", t);
540
+ });
541
+ let t = e.textTracks;
542
+ if (t) {
543
+ let n = (e, t) => {
544
+ if (e.kind !== "subtitles" && e.kind !== "captions" || this.subtitles.getTracks().some((e) => e.isNative && e.nativeTrackIndex === t)) return;
545
+ let n = e.kind === "captions";
546
+ this.subtitles.addTrack({
547
+ id: `native-${t}`,
548
+ label: e.label || e.language || (n ? `CC ${t + 1}` : `Track ${t + 1}`),
549
+ lang: e.language || "und",
550
+ isDefault: !this.hlsInstance && (e.default || e.mode === "showing"),
551
+ isNative: !0,
552
+ nativeTrackIndex: t
553
+ });
554
+ };
555
+ e.addEventListener("loadedmetadata", () => {
556
+ this.analytics.track("video_loaded", e, this.getAnalyticsPayload());
557
+ let r = 0, i = this.hlsInstance ? ["captions"] : ["subtitles", "captions"];
558
+ for (let e = 0; e < t.length; e++) {
559
+ if (!i.includes(t[e].kind)) continue;
560
+ let a = this.subtitles.getTracks().length;
561
+ n(t[e], e), this.subtitles.getTracks().length > a && r++;
562
+ }
563
+ r > 0 && this.emit("subtitlesloaded", this.subtitles.getTracks());
564
+ }), t.addEventListener("addtrack", (e) => {
565
+ let r = e.track;
566
+ if (r) for (let e = 0; e < t.length; e++) {
567
+ if (t[e] !== r) continue;
568
+ let i = this.subtitles.getTracks().length;
569
+ n(r, e), this.subtitles.getTracks().length > i && this.emit("subtitlesloaded", this.subtitles.getTracks());
570
+ break;
571
+ }
572
+ });
573
+ }
574
+ this.subtitles.onTrackSwitch((e) => {
575
+ if (e === null) {
576
+ if (this.hlsInstance) this.hlsInstance.subtitleTrack = -1;
577
+ else if (t) {
578
+ for (let e = 0; e < t.length; e++) t[e].mode = "disabled", t[e].oncuechange = null;
579
+ this.subtitles.setCustomSubtitleText("");
580
+ }
581
+ } else if (e.isHls) this.hlsInstance && e.hlsTrackId !== void 0 && (this.hlsInstance.subtitleTrack = e.hlsTrackId);
582
+ else if (e.isNative && t && e.nativeTrackIndex !== void 0 && t[e.nativeTrackIndex]) for (let n = 0; n < t.length; n++) if (t[n].oncuechange = null, n === e.nativeTrackIndex) {
583
+ t[n].mode = "hidden";
584
+ let e = t[n];
585
+ e.oncuechange = () => {
586
+ let t = e.activeCues;
587
+ if (t && t.length > 0) {
588
+ let e = Array.from(t).map((e) => e.text).join("<br />");
589
+ this.subtitles.setCustomSubtitleText(e);
590
+ } else this.subtitles.setCustomSubtitleText("");
591
+ };
592
+ } else t[n].mode = "disabled";
593
+ });
594
+ }
595
+ rewriteToProxy(e) {
596
+ if (e.includes("d3queh3es1i8u.cloudfront.net")) try {
597
+ let t = new URL(e);
598
+ return `/video-proxy${t.pathname}${t.search}`;
599
+ } catch {
600
+ return e.replace("https://d3queh3es1i8u.cloudfront.net", "/video-proxy");
601
+ }
602
+ return e;
603
+ }
604
+ loadSource(e) {
605
+ this.extractKeyMomentsFromManifest(e), this.extractSubtitlesFromManifest(e);
606
+ let t = this.rewriteToProxy(e), n = t.endsWith(".m3u8") || t.includes(".m3u8"), r = t.endsWith(".mpd") || t.includes(".mpd");
607
+ if (n) if (a.isSupported()) {
608
+ let n = new a({
609
+ enableWorker: !0,
610
+ lowLatencyMode: !0,
611
+ backBufferLength: 90,
612
+ maxMaxBufferLength: 30,
613
+ renderTextTracksNatively: !1,
614
+ xhrSetup: (t, n) => {
615
+ let r = this.drm.getAuthToken();
616
+ if (!r) try {
617
+ let t = new URL(e), n = t.searchParams.get("token") || t.searchParams.get("key") || t.searchParams.get("auth") || t.searchParams.get("authToken");
618
+ n && (r = n);
619
+ } catch {}
620
+ try {
621
+ let e = this.rewriteToProxy(n), i = new URL(e, window.location.origin);
622
+ r && i.searchParams.set("token", r), t.open("GET", i.toString(), !0);
623
+ } catch (e) {
624
+ console.error("[PlayerSDK Core] Error in xhrSetup URL parsing:", e);
625
+ }
626
+ }
627
+ });
628
+ this.hlsInstance = n, n.loadSource(t), n.attachMedia(this.videoElement), n.on(a.Events.SUBTITLE_TRACK_SWITCH, (e, t) => {
629
+ if (this.hlsActiveSubtitleKey = null, this.subtitles.setCustomSubtitleText(""), t.id !== -1) {
630
+ let e = n.subtitleTracks[t.id];
631
+ this.hlsActiveSubtitleKey = e?.default ? "default" : `subtitles${t.id}`;
632
+ }
633
+ }), n.on(a.Events.CUES_PARSED, (e, t) => {
634
+ let n = this.hlsSubtitleCues.get(t.track) ?? [], r = t.cues.filter((e) => !n.some((t) => t.startTime === e.startTime && t.endTime === e.endTime));
635
+ r.length > 0 && this.hlsSubtitleCues.set(t.track, [...n, ...r]);
636
+ }), n.on(a.Events.MANIFEST_PARSED, () => {
637
+ this.qualityLevels = n.levels.map((e, t) => ({
638
+ id: t,
639
+ height: e.height,
640
+ width: e.width,
641
+ bitrate: e.bitrate,
642
+ label: e.height ? `${e.height}p` : `Option ${t + 1}`
643
+ }));
644
+ let e = {
645
+ id: -1,
646
+ height: 0,
647
+ width: 0,
648
+ bitrate: 0,
649
+ label: "Auto"
650
+ };
651
+ this.qualityLevels.unshift(e), this.activeQuality = e, this.emit("qualitylevels", this.qualityLevels), this.options.autoplay && this.play();
652
+ }), n.on(a.Events.AUDIO_TRACKS_UPDATED, () => {
653
+ n.audioTracks.length > 1 && (this.audioTrackList = n.audioTracks.map((e, t) => ({
654
+ id: t,
655
+ label: e.name || e.lang || `Audio ${t + 1}`,
656
+ lang: e.lang || ""
657
+ })), this.emit("audiotracksloaded", this.audioTrackList));
658
+ }), n.on(a.Events.AUDIO_TRACK_SWITCHED, (e, t) => {
659
+ this.analytics.track("audio_track_change", this.videoElement, this.getAnalyticsPayload()), this.emit("audiotrackchange", t.id);
660
+ }), n.on(a.Events.LEVEL_SWITCHED, (e, t) => {
661
+ let n = this.qualityLevels.find((e) => e.id === t.level);
662
+ n && (this.analytics.track("quality_change", this.videoElement, {
663
+ ...this.getAnalyticsPayload(),
664
+ rendition: n.label,
665
+ bitrate: n.bitrate
666
+ }), this.emit("qualitychange", n));
667
+ }), n.on(a.Events.ERROR, (e, t) => {
668
+ t.fatal && (t.type === a.ErrorTypes.NETWORK_ERROR ? (this.analytics.track("network_error", this.videoElement, {
669
+ ...this.getAnalyticsPayload(),
670
+ errorMessage: t.details,
671
+ errorCode: 0
672
+ }), n.startLoad()) : t.type === a.ErrorTypes.MEDIA_ERROR ? n.recoverMediaError() : this.destroy());
673
+ });
674
+ } else this.videoElement.canPlayType("application/vnd.apple.mpegurl") && (this.videoElement.src = e, this.qualityLevels = [{
675
+ id: 0,
676
+ height: 720,
677
+ width: 1280,
678
+ bitrate: 2e6,
679
+ label: "720p (Native)"
680
+ }], this.activeQuality = this.qualityLevels[0], this.options.autoplay && this.videoElement.play().catch(console.error));
681
+ else if (r) {
682
+ let t = m.MediaPlayer().create();
683
+ this.dashInstance = t, t.initialize(this.videoElement, e, !!this.options.autoplay), t.updateSettings({ streaming: {
684
+ abr: { autoSwitchBitrate: {
685
+ video: !0,
686
+ audio: !0
687
+ } },
688
+ buffer: { bufferTimeAtTopQuality: 30 }
689
+ } }), this.qualityLevels = [{
690
+ id: 0,
691
+ height: 0,
692
+ width: 0,
693
+ bitrate: 0,
694
+ label: "Auto (DASH)"
695
+ }], this.activeQuality = this.qualityLevels[0], this.emit("qualitylevels", this.qualityLevels);
696
+ } else this.videoElement.src = e, this.qualityLevels = [{
697
+ id: 0,
698
+ height: 1080,
699
+ width: 1920,
700
+ bitrate: 45e5,
701
+ label: "1080p (Source)"
702
+ }], this.activeQuality = this.qualityLevels[0], this.options.autoplay && this.videoElement.play().catch(console.error);
703
+ }
704
+ setupBackgroundControls() {
705
+ if ("mediaSession" in navigator) {
706
+ navigator.mediaSession.metadata = new MediaMetadata({
707
+ title: "Video Player",
708
+ album: "Video Player",
709
+ artwork: [{
710
+ src: "https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=512&q=80",
711
+ sizes: "512x512",
712
+ type: "image/jpeg"
713
+ }]
714
+ });
715
+ try {
716
+ navigator.mediaSession.setActionHandler("play", () => this.play()), navigator.mediaSession.setActionHandler("pause", () => this.pause()), navigator.mediaSession.setActionHandler("seekbackward", (e) => {
717
+ let t = e.seekOffset || 10;
718
+ this.seek(this.videoElement.currentTime - t);
719
+ }), navigator.mediaSession.setActionHandler("seekforward", (e) => {
720
+ let t = e.seekOffset || 10;
721
+ this.seek(this.videoElement.currentTime + t);
722
+ });
723
+ } catch {
724
+ console.warn("[PlayerSDK Session] Action handler binding is unsupported by browser.");
725
+ }
726
+ }
727
+ }
728
+ play() {
729
+ this.videoElement.play().catch((e) => {
730
+ console.warn("[PlayerSDK Play] Autoplay blocked, wait for user interaction:", e);
731
+ });
732
+ }
733
+ pause() {
734
+ this.videoElement.pause();
735
+ }
736
+ seek(e) {
737
+ let t = Math.max(0, Math.min(e, this.getDuration()));
738
+ this.videoElement.currentTime = t;
739
+ }
740
+ setVolume(e) {
741
+ let t = Math.max(0, Math.min(e, 1));
742
+ this.videoElement.volume = t, this.videoElement.muted = t === 0;
743
+ }
744
+ setMute(e) {
745
+ this.videoElement.muted = e;
746
+ }
747
+ setPlaybackRate(e) {
748
+ this.videoElement.playbackRate = e;
749
+ }
750
+ setQuality(e) {
751
+ let t = this.qualityLevels.find((t) => t.id === e);
752
+ t && (this.activeQuality = t, this.hlsInstance ? this.hlsInstance.currentLevel = e : console.warn("[PlayerSDK Core] Manual rendition switching is not supported by standard native players."));
753
+ }
754
+ async togglePictureInPicture() {
755
+ if (!document.pictureInPictureEnabled) return console.warn("[PlayerSDK Core] Picture-in-Picture is disabled or unsupported."), !1;
756
+ try {
757
+ return document.pictureInPictureElement ? (await document.exitPictureInPicture(), !1) : (await this.videoElement.requestPictureInPicture(), !0);
758
+ } catch (e) {
759
+ return console.error("[PlayerSDK Core] PiP toggle failed:", e), !1;
760
+ }
761
+ }
762
+ toggleFullscreen() {
763
+ let e = this.options.container;
764
+ document.fullscreenElement ? document.exitFullscreen() : e.requestFullscreen().catch((e) => {
765
+ console.error("[PlayerSDK Fullscreen] Failed entering fullscreen:", e);
766
+ });
767
+ }
768
+ getVideoElement() {
769
+ return this.videoElement;
770
+ }
771
+ getCurrentTime() {
772
+ return this.videoElement.currentTime;
773
+ }
774
+ getDuration() {
775
+ return this.videoElement.duration || 0;
776
+ }
777
+ getVolume() {
778
+ return this.videoElement.volume;
779
+ }
780
+ isMuted() {
781
+ return this.videoElement.muted;
782
+ }
783
+ getPlaybackRate() {
784
+ return this.videoElement.playbackRate;
785
+ }
786
+ getActiveQuality() {
787
+ return this.activeQuality;
788
+ }
789
+ getQualityLevels() {
790
+ return this.qualityLevels;
791
+ }
792
+ getBufferLength() {
793
+ let e = this.videoElement.buffered, t = this.videoElement.currentTime;
794
+ for (let n = 0; n < e.length; n++) if (t >= e.start(n) && t <= e.end(n)) return e.end(n) - t;
795
+ return 0;
796
+ }
797
+ getBufferedRanges() {
798
+ let e = this.videoElement.buffered, t = [];
799
+ for (let n = 0; n < e.length; n++) t.push({
800
+ start: e.start(n),
801
+ end: e.end(n)
802
+ });
803
+ return t;
804
+ }
805
+ getAnalyticsPayload() {
806
+ return {
807
+ rendition: this.activeQuality.label,
808
+ bitrate: this.activeQuality.bitrate,
809
+ volume: this.videoElement.volume,
810
+ speed: this.videoElement.playbackRate
811
+ };
812
+ }
813
+ on(e, t) {
814
+ this.eventListeners[e] || (this.eventListeners[e] = []), this.eventListeners[e].push(t);
815
+ }
816
+ off(e, t) {
817
+ this.eventListeners[e] && (this.eventListeners[e] = this.eventListeners[e].filter((e) => e !== t));
818
+ }
819
+ emit(e, ...t) {
820
+ this.eventListeners[e] && this.eventListeners[e].forEach((e) => e(...t));
821
+ }
822
+ async extractSubtitlesFromManifest(e) {
823
+ try {
824
+ let t = this.rewriteToProxy(e), n = await fetch(t);
825
+ if (!n.ok) return;
826
+ let r = (await n.text()).split("\n"), i = this.drm.getAuthToken() || void 0;
827
+ if (!i) try {
828
+ let t = new URL(e);
829
+ i = t.searchParams.get("token") || t.searchParams.get("key") || t.searchParams.get("auth") || t.searchParams.get("authToken") || void 0;
830
+ } catch {}
831
+ let a = e.substring(0, e.lastIndexOf("/") + 1), o = [];
832
+ for (let e of r) {
833
+ if (!e.startsWith("#EXT-X-MEDIA:TYPE=SUBTITLES")) continue;
834
+ let t = e.match(/NAME="([^"]+)"/), n = e.match(/LANGUAGE="([^"]+)"/), r = e.match(/URI="([^"]+)"/), s = /DEFAULT=YES/i.test(e);
835
+ if (!r) continue;
836
+ let c = r[1], l = o.length, u = t ? t[1] : n ? n[1] : `Track ${l + 1}`, d = n ? n[1] : "und";
837
+ if (/\.m3u8?(\?|$)/i.test(c)) {
838
+ o.push({
839
+ id: `subtitle-${l}`,
840
+ label: u,
841
+ lang: d,
842
+ isDefault: s,
843
+ isHls: !0,
844
+ hlsTrackId: l
845
+ });
846
+ continue;
847
+ }
848
+ let f = c.startsWith("http") ? c : a + c, p = this.rewriteToProxy(f);
849
+ if (i) try {
850
+ let e = new URL(p, window.location.origin);
851
+ e.searchParams.set("token", i), p = e.toString();
852
+ } catch {}
853
+ o.push({
854
+ id: `subtitle-${l}`,
855
+ label: u,
856
+ lang: d,
857
+ isDefault: s,
858
+ src: p
859
+ });
860
+ }
861
+ o.length > 0 && (this.subtitles.setHlsTracks(o), this.emit("subtitlesloaded", this.subtitles.getTracks()));
862
+ } catch (e) {
863
+ console.error("[PlayerSDK] Error extracting subtitles from manifest:", e);
864
+ }
865
+ }
866
+ async extractKeyMomentsFromManifest(e) {
867
+ try {
868
+ let t = this.rewriteToProxy(e), n = await fetch(t);
869
+ if (!n.ok) return;
870
+ let r = (await n.text()).split("\n"), i = [];
871
+ for (let e of r) if (e.startsWith("#EXT-X-DATERANGE:")) {
872
+ let t = e.match(/ID="([^"]+)"/), n = e.match(/START-DATE="([^"]+)"/), r = e.match(/X-TITLE="([^"]+)"/);
873
+ t && n && r && (i.some((e) => e.id === t[1]) || i.push({
874
+ id: t[1],
875
+ startDate: n[1],
876
+ title: r[1]
877
+ }));
878
+ }
879
+ if (i.length > 0) {
880
+ i.sort((e, t) => e.startDate.localeCompare(t.startDate));
881
+ let e = new Date(i[0].startDate).getTime(), t = i.map((t) => {
882
+ let n = (new Date(t.startDate).getTime() - e) / 1e3;
883
+ return {
884
+ title: t.title,
885
+ startTime: n,
886
+ endTime: 0
887
+ };
888
+ });
889
+ for (let e = 0; e < t.length; e++) e < t.length - 1 ? t[e].endTime = t[e + 1].startTime : t[e].endTime = 99999;
890
+ this.keyMoments.setKeyMoments(t), this.emit("keymomentsloaded", t), this.emit("chaptersloaded", t);
891
+ }
892
+ } catch (e) {
893
+ console.error("Error parsing manifest key moments:", e);
894
+ }
895
+ }
896
+ getAudioTracks() {
897
+ return this.audioTrackList;
898
+ }
899
+ setAudioTrack(e) {
900
+ this.hlsInstance && (this.hlsInstance.audioTrack = e);
901
+ }
902
+ destroy() {
903
+ this.hlsSubtitleCues.clear(), this.hlsActiveSubtitleKey = null, this.analytics.stopHeartbeat(), this.drm.removeWatermark(), this.hlsInstance &&= (this.hlsInstance.destroy(), null), this.dashInstance &&= (this.dashInstance.reset(), null), this.videoElement && (this.videoElement.pause(), this.videoElement.removeAttribute("src"), this.videoElement.load(), this.videoElement.parentElement && this.videoElement.parentElement.removeChild(this.videoElement)), this.eventListeners = {};
904
+ }
905
+ }, S = (e) => {
906
+ if (e.includes("d3queh3es1i8u.cloudfront.net")) try {
907
+ let t = new URL(e);
908
+ return `/video-proxy${t.pathname}${t.search}`;
909
+ } catch {
910
+ return e.replace("https://d3queh3es1i8u.cloudfront.net", "/video-proxy");
911
+ }
912
+ return e;
913
+ }, Se = (e) => {
914
+ let t = e.replace("#", "");
915
+ return t.length === 6 ? `${parseInt(t.substring(0, 2), 16)}, ${parseInt(t.substring(2, 4), 16)}, ${parseInt(t.substring(4, 6), 16)}` : t.length === 3 ? `${parseInt(t[0] + t[0], 16)}, ${parseInt(t[1] + t[1], 16)}, ${parseInt(t[2] + t[2], 16)}` : "99, 102, 241";
916
+ }, C = {
917
+ en: "English",
918
+ eng: "English",
919
+ fr: "French",
920
+ fre: "French",
921
+ fra: "French",
922
+ es: "Spanish",
923
+ spa: "Spanish",
924
+ de: "German",
925
+ ger: "German",
926
+ deu: "German",
927
+ it: "Italian",
928
+ ita: "Italian",
929
+ pt: "Portuguese",
930
+ por: "Portuguese",
931
+ ja: "Japanese",
932
+ zh: "Chinese",
933
+ ko: "Korean",
934
+ ru: "Russian",
935
+ ar: "Arabic",
936
+ hi: "Hindi"
937
+ }, w = (e) => {
938
+ if (!e) return null;
939
+ let t = e.trim().toLowerCase(), n = t.match(/^(en|eng|fr|fre|fra|es|spa|de|ger|deu|it|ita|pt|por|ja|zh|ko|ru|ar|hi)/);
940
+ if (n && C[n[0]]) return C[n[0]];
941
+ for (let [e, n] of Object.entries(C)) if (t.includes(e)) return n;
942
+ return /english|anglais|ingles/i.test(t) ? "English" : /french|français/i.test(t) ? "French" : /spanish|español/i.test(t) ? "Spanish" : /german|deutsch/i.test(t) ? "German" : /italian|italiano/i.test(t) ? "Italian" : /portuguese|português/i.test(t) ? "Portuguese" : /japanese|nihongo/i.test(t) ? "Japanese" : /chinese|中文/i.test(t) ? "Chinese" : /korean|한국어/i.test(t) ? "Korean" : /russian|русский/i.test(t) ? "Russian" : /arabic|العربية/i.test(t) ? "Arabic" : /hindi|हिन्दी/i.test(t) ? "Hindi" : null;
943
+ }, Ce = (e) => {
944
+ if (e.lang) {
945
+ let t = w(e.lang);
946
+ if (t) return t;
947
+ }
948
+ if (e.label) {
949
+ let t = e.label.trim(), n = t.split(/[#\d\.\s\-_/|:]+/).filter(Boolean);
950
+ for (let e = n.length - 1; e >= 0; --e) {
951
+ let t = w(n[e]);
952
+ if (t) return t;
953
+ }
954
+ let r = t.replace(/^[#\d\.\s]+/, "").trim();
955
+ return w(r) || r;
956
+ }
957
+ return "Unknown";
958
+ }, T = (e) => {
959
+ let t = /* @__PURE__ */ new Set();
960
+ return e.filter((e) => {
961
+ let n = `${Ce(e).toLowerCase()}|${(e.lang || "").trim().toLowerCase()}`;
962
+ return t.has(n) ? !1 : (t.add(n), !0);
963
+ });
964
+ }, E = ({ src: e, chapters: i = [], keyMoments: m, subtitles: h = [], watermark: fe = "GoBOSS", themeColor: g = "#6366f1", drmConfig: _, firebaseConfig: pe, onAnalyticsEvent: me, onKeyMomentsLoaded: b, enableControls: he = !0, enableChromecast: _e = !0, enableKeyMoments: x = !0, enableSubtitles: ve = !0, enableQuality: ye = !0, enablePlaybackSpeed: be = !0, enablePiP: C = !0, enableFullscreen: w = !0, subtitleStyle: E = {} }) => {
965
+ let D = n(null), we = n(null), O = n(null), Te = n(null), k = n(null), Ee = n(null), A = n(null), De = n(!1), j = n(!1), M = n(null), N = n(null), Oe = n(null), [P, ke] = r(null), [F, Ae] = r(!1), [I, je] = r(0), [L, Me] = r(0), [R, Ne] = r(1), [z, B] = r(!1), [Pe, Fe] = r(!1), [Ie, Le] = r(!1), [Re, ze] = r(!1), [Be, Ve] = r(!1), [He, Ue] = r([]), [We, Ge] = r({
966
+ id: -1,
967
+ height: 0,
968
+ width: 0,
969
+ bitrate: 0,
970
+ label: "Auto"
971
+ }), [Ke, qe] = r(""), [V, H] = r("off"), [Je, Ye] = r(T(h)), [Xe, Ze] = r([]), [Qe, $e] = r(0);
972
+ t(() => {
973
+ if (P) {
974
+ let e = P.subtitles.getTracks();
975
+ Ye(T([...h, ...e.filter((e) => !h.some((t) => t.id === e.id))]));
976
+ } else Ye(T(h));
977
+ }, [h, P]);
978
+ let [et, tt] = r({
979
+ chapter: null,
980
+ index: -1
981
+ }), [U, nt] = r(m || i || []), [W, G] = r("none"), [rt, it] = r(1), [K, at] = r(!1), [ot, st] = r({}), ct = JSON.stringify(U.map((e) => ({
982
+ title: e.title,
983
+ startTime: e.startTime
984
+ })));
985
+ t(() => {
986
+ nt(m || i || []);
987
+ }, [m, i]), t(() => {
988
+ if (!e || !U || U.length === 0) return;
989
+ st({});
990
+ let t = document.createElement("video");
991
+ t.muted = !0, t.preload = "metadata", t.crossOrigin = "anonymous", t.style.cssText = "position:fixed;top:0;left:0;width:10px;height:10px;opacity:0.01;pointer-events:none;z-index:-9999;", document.body.appendChild(t);
992
+ let n = null, r = e.includes(".m3u8"), i = document.createElement("canvas");
993
+ i.width = 160, i.height = 90;
994
+ let o = i.getContext("2d"), s = 0, c = !1, l = () => {
995
+ if (s >= U.length) {
996
+ f();
997
+ return;
998
+ }
999
+ let e = U[s].startTime;
1000
+ t.currentTime = e === 0 ? .01 : e;
1001
+ }, u = () => {
1002
+ if (o && t.readyState >= 2) {
1003
+ o.drawImage(t, 0, 0, i.width, i.height);
1004
+ let e = i.toDataURL("image/jpeg", .8);
1005
+ st((t) => ({
1006
+ ...t,
1007
+ [s]: e
1008
+ })), s++, l();
1009
+ } else setTimeout(u, 100);
1010
+ }, d = () => {
1011
+ c || (c = !0, l());
1012
+ };
1013
+ t.addEventListener("seeked", u), t.addEventListener("canplay", d), r && a.isSupported() ? (n = new a({
1014
+ enableWorker: !1,
1015
+ maxBufferLength: 5,
1016
+ xhrSetup: (t, n) => {
1017
+ let r = _?.authToken;
1018
+ if (!r) try {
1019
+ let t = new URL(e), n = t.searchParams.get("token") || t.searchParams.get("key") || t.searchParams.get("auth") || t.searchParams.get("authToken");
1020
+ n && (r = n);
1021
+ } catch {}
1022
+ try {
1023
+ let e = S(n), i = new URL(e, window.location.origin);
1024
+ r && i.searchParams.set("token", r), t.open("GET", i.toString(), !0);
1025
+ } catch (e) {
1026
+ console.error("[WebVideoPlayer tempHls] xhrSetup error:", e);
1027
+ }
1028
+ }
1029
+ }), n.loadSource(S(e)), n.attachMedia(t)) : t.src = e, t.readyState >= 2 && d();
1030
+ let f = () => {
1031
+ t.removeEventListener("seeked", u), t.removeEventListener("canplay", d), n && n.destroy(), document.body.contains(t) && document.body.removeChild(t);
1032
+ };
1033
+ return f;
1034
+ }, [e, ct]);
1035
+ let [q, lt] = r(null), [ut, dt] = r(!1), [ft, pt] = r(!1), [mt, ht] = r(null), [gt, _t] = r(null), [vt, yt] = r(0), [bt, xt] = r(null), [St, Ct] = r(null), [J, wt] = r(null);
1036
+ t(() => {
1037
+ if (Oe.current && !Oe.current.querySelector("google-cast-launcher")) {
1038
+ let e = document.createElement("google-cast-launcher");
1039
+ e.style.cursor = "pointer", e.style.width = "100%", e.style.height = "100%", e.style.display = "block", Oe.current.appendChild(e);
1040
+ }
1041
+ }, []), t(() => {
1042
+ if (!P) {
1043
+ dt(!1), pt(!1), ht(null);
1044
+ return;
1045
+ }
1046
+ let e = (e) => dt(e), t = () => {
1047
+ let e = P.getVideoElement(), t = !!e?.webkitCurrentPlaybackTargetIsWireless;
1048
+ pt(t), ht(t ? e.webkitCurrentPlaybackTargetName || "AirPlay device" : null);
1049
+ };
1050
+ e(P.casting.isAirPlayAvailable()), t();
1051
+ let n = P.getVideoElement(), r = (t) => {
1052
+ e(t.availability === "available");
1053
+ }, i = () => {
1054
+ t();
1055
+ };
1056
+ return "webkitShowPlaybackTargetPicker" in n && (n.addEventListener("webkitplaybacktargetavailabilitychanged", r), n.addEventListener("webkitcurrentplaybacktargetiswirelesschanged", i)), () => {
1057
+ "webkitShowPlaybackTargetPicker" in n && (n.removeEventListener("webkitplaybacktargetavailabilitychanged", r), n.removeEventListener("webkitcurrentplaybacktargetiswirelesschanged", i));
1058
+ };
1059
+ }, [P]);
1060
+ let [Tt, Et] = r(!0), Y = n(null), Dt = n(!1), Ot = n("none"), kt = n(h);
1061
+ t(() => {
1062
+ if (!D.current) return;
1063
+ let t = document.createElement("video");
1064
+ t.muted = !0, t.preload = "metadata", t.crossOrigin = "anonymous", t.style.cssText = "display:none;position:absolute;pointer-events:none;", document.body.appendChild(t), k.current = t;
1065
+ let n = e.includes(".m3u8");
1066
+ if (n && a.isSupported()) {
1067
+ let n = new a({
1068
+ enableWorker: !1,
1069
+ maxBufferLength: 5,
1070
+ xhrSetup: (t, n) => {
1071
+ let r = _?.authToken;
1072
+ if (!r) try {
1073
+ let t = new URL(e), n = t.searchParams.get("token") || t.searchParams.get("key") || t.searchParams.get("auth") || t.searchParams.get("authToken");
1074
+ n && (r = n);
1075
+ } catch {}
1076
+ try {
1077
+ let e = S(n), i = new URL(e, window.location.origin);
1078
+ r && i.searchParams.set("token", r), t.open("GET", i.toString(), !0);
1079
+ } catch (e) {
1080
+ console.error("[WebVideoPlayer hiddenHls] xhrSetup error:", e);
1081
+ }
1082
+ }
1083
+ });
1084
+ n.loadSource(S(e)), n.attachMedia(t), Ee.current = n;
1085
+ } else n && t.canPlayType("application/vnd.apple.mpegurl"), t.src = e;
1086
+ t.addEventListener("seeked", () => {
1087
+ let e = Te.current;
1088
+ if (!e) return;
1089
+ let n = e.getContext("2d");
1090
+ n && t.readyState >= 2 && (n.drawImage(t, 0, 0, e.width, e.height), xt(e.toDataURL("image/jpeg", .82)));
1091
+ });
1092
+ let r;
1093
+ if (pe) {
1094
+ let e = new ge(pe);
1095
+ we.current = e, r = e.createCallback();
1096
+ }
1097
+ let i = new xe({
1098
+ container: D.current,
1099
+ src: e,
1100
+ autoplay: !1,
1101
+ muted: !1,
1102
+ keyMoments: U,
1103
+ subtitles: h,
1104
+ drm: {
1105
+ watermarkText: fe,
1106
+ allowedDomains: ["localhost", "127.0.0.1"],
1107
+ ..._
1108
+ },
1109
+ analyticsCallback: (e) => {
1110
+ r?.(e), me && me(e);
1111
+ },
1112
+ themeColor: g
1113
+ });
1114
+ i.on("keymomentsloaded", (e) => {
1115
+ nt(e), b && b(e);
1116
+ }), i.on("chaptersloaded", (e) => {
1117
+ nt(e), b && b(e);
1118
+ }), i.on("play", () => {
1119
+ Ae(!0), Ve(!1);
1120
+ }), i.on("pause", () => Ae(!1)), i.on("ended", () => {
1121
+ Ae(!1), Ve(!0);
1122
+ }), i.on("timeupdate", (e) => {
1123
+ if (j.current && M.current !== null) if (Math.abs(e - M.current) < 5) j.current = !1, M.current = null, N.current &&= (window.clearTimeout(N.current), null);
1124
+ else return;
1125
+ je(e), Me(i.getDuration());
1126
+ let t = i.keyMoments.getCurrentMoment(e);
1127
+ tt({
1128
+ chapter: t.keyMoment,
1129
+ index: t.index
1130
+ });
1131
+ }), i.on("qualitylevels", (e) => {
1132
+ Ue(e);
1133
+ }), i.on("qualitychange", (e) => {
1134
+ Ge(e);
1135
+ }), i.on("buffering", (e) => {
1136
+ Fe(e);
1137
+ }), i.on("volumechange", (e) => {
1138
+ Ne(e.volume), B(e.muted);
1139
+ }), i.on("pipchange", (e) => {
1140
+ ze(e);
1141
+ }), i.subtitles.onSubtitleChange((e) => {
1142
+ qe(e);
1143
+ }), i.on("subtitlesloaded", (e) => {
1144
+ Ye(T([...e]));
1145
+ let t = e.find((e) => e.isDefault);
1146
+ t && (i.subtitles.setActiveTrack(t.id), H(t.id));
1147
+ }), i.on("audiotracksloaded", (e) => {
1148
+ Ze(e), $e(e[0]?.id ?? 0);
1149
+ }), i.on("audiotrackchange", (e) => {
1150
+ $e(e);
1151
+ }), i.casting.onCastStateChange((e, t) => {
1152
+ lt(e ? t : null);
1153
+ }), Ne(i.getVolume()), B(i.isMuted()), ke(i);
1154
+ let o = () => {
1155
+ let e = !!document.fullscreenElement;
1156
+ Le(e);
1157
+ let t = i.getVideoElement();
1158
+ i.analytics.track(e ? "fullscreen_enter" : "fullscreen_exit", t);
1159
+ };
1160
+ document.addEventListener("fullscreenchange", o);
1161
+ let s = (e) => {
1162
+ let t = document.activeElement;
1163
+ if (!(t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.getAttribute("contenteditable") === "true"))) {
1164
+ switch (e.key.toLowerCase()) {
1165
+ case " ":
1166
+ case "k":
1167
+ e.preventDefault(), i.getVideoElement().paused ? i.play() : i.pause();
1168
+ break;
1169
+ case "arrowleft":
1170
+ case "j":
1171
+ e.preventDefault(), i.seek(i.getCurrentTime() - 10);
1172
+ break;
1173
+ case "arrowright":
1174
+ case "l":
1175
+ e.preventDefault(), i.seek(i.getCurrentTime() + 10);
1176
+ break;
1177
+ case "arrowup":
1178
+ e.preventDefault(), i.setVolume(i.getVolume() + .1);
1179
+ break;
1180
+ case "arrowdown":
1181
+ e.preventDefault(), i.setVolume(i.getVolume() - .1);
1182
+ break;
1183
+ case "m":
1184
+ e.preventDefault(), i.setMute(!i.isMuted());
1185
+ break;
1186
+ case "f":
1187
+ e.preventDefault(), i.toggleFullscreen();
1188
+ break;
1189
+ case "p":
1190
+ e.preventDefault(), i.togglePictureInPicture();
1191
+ break;
1192
+ case "c":
1193
+ if (e.preventDefault(), i.subtitles.getActiveTrackId() !== "off") i.subtitles.setActiveTrack("off"), H("off");
1194
+ else {
1195
+ let e = kt.current;
1196
+ e && e.length > 0 && (i.subtitles.setActiveTrack(e[0].id), H(e[0].id));
1197
+ }
1198
+ break;
1199
+ default: return;
1200
+ }
1201
+ X();
1202
+ }
1203
+ };
1204
+ return document.addEventListener("keydown", s), X(), () => {
1205
+ i.destroy(), we.current?.destroy(), we.current = null, document.removeEventListener("fullscreenchange", o), document.removeEventListener("keydown", s), Y.current && window.clearTimeout(Y.current), Ee.current &&= (Ee.current.destroy(), null), k.current &&= (document.body.removeChild(k.current), null);
1206
+ };
1207
+ }, [e, fe]), t(() => {
1208
+ if (P) {
1209
+ P.keyMoments.setKeyMoments(U);
1210
+ let e = D.current?.querySelector("video");
1211
+ if (e) {
1212
+ let t = P.keyMoments.getCurrentMoment(e.currentTime);
1213
+ tt({
1214
+ chapter: t.keyMoment,
1215
+ index: t.index
1216
+ });
1217
+ }
1218
+ }
1219
+ }, [ct, P]), t(() => {
1220
+ let e = (e) => {
1221
+ W !== "none" && (e.target.closest(".sdk-menu-container") || G("none"));
1222
+ };
1223
+ return document.addEventListener("click", e), () => {
1224
+ document.removeEventListener("click", e);
1225
+ };
1226
+ }, [W]), Dt.current = F, Ot.current = W, kt.current = Je;
1227
+ let X = () => {
1228
+ Et(!0), Y.current && window.clearTimeout(Y.current), Y.current = window.setTimeout(() => {
1229
+ Dt.current && Ot.current === "none" && Et(!1);
1230
+ }, 1e4);
1231
+ }, At = () => {
1232
+ X();
1233
+ }, jt = () => {
1234
+ P && (Be ? (Z(0), P.play(), Ve(!1)) : F ? P.pause() : P.play(), X());
1235
+ }, Mt = (e) => {
1236
+ if (!O.current || !P || L === 0) return 0;
1237
+ let t = O.current.getBoundingClientRect();
1238
+ return Math.max(0, Math.min(1, (e.clientX - t.left) / t.width)) * L;
1239
+ }, Nt = (e) => {
1240
+ if (!P) return;
1241
+ De.current = !0, wt(Mt(e));
1242
+ let t = (e) => {
1243
+ if (!De.current || !O.current) return;
1244
+ let t = O.current.getBoundingClientRect(), n = Math.max(0, Math.min(1, (e.clientX - t.left) / t.width)) * L;
1245
+ wt(n), _t(e.clientX - t.left), yt(n), k.current && (k.current.currentTime = n), X();
1246
+ }, n = (e) => {
1247
+ if (De.current = !1, O.current) {
1248
+ let t = O.current.getBoundingClientRect();
1249
+ Z(Math.max(0, Math.min(1, (e.clientX - t.left) / t.width)) * L);
1250
+ }
1251
+ wt(null), document.removeEventListener("mousemove", t), document.removeEventListener("mouseup", n);
1252
+ };
1253
+ document.addEventListener("mousemove", t), document.addEventListener("mouseup", n);
1254
+ }, Z = (e) => {
1255
+ if (!P) return;
1256
+ let t = Math.max(0, L > 0 ? Math.min(e, L) : e);
1257
+ j.current = !0, M.current = t, je(t), P.seek(t), N.current && window.clearTimeout(N.current), N.current = window.setTimeout(() => {
1258
+ j.current = !1, M.current = null, N.current = null;
1259
+ }, 3e3);
1260
+ }, Pt = (e) => {
1261
+ if (!P) return;
1262
+ let t = parseFloat(e.target.value);
1263
+ P.setVolume(t), Ne(t), B(t === 0);
1264
+ }, Ft = () => {
1265
+ if (!P) return;
1266
+ let e = !z;
1267
+ P.setMute(e), B(e);
1268
+ }, It = (e) => {
1269
+ P && (P.setPlaybackRate(e), it(e), G("none"));
1270
+ }, Lt = (e) => {
1271
+ if (!P) return;
1272
+ P.setQuality(e);
1273
+ let t = He.find((t) => t.id === e);
1274
+ t && Ge(t), G("none");
1275
+ }, Rt = (e) => {
1276
+ P && (P.subtitles.setActiveTrack(e), H(e), G("none"));
1277
+ }, zt = (e) => {
1278
+ Z(e), G("none");
1279
+ }, Bt = () => {
1280
+ P && P.togglePictureInPicture();
1281
+ }, Vt = () => {
1282
+ P && P.toggleFullscreen();
1283
+ }, Ht = () => {
1284
+ P && (q ? P.casting.stopCasting() : P.casting.requestSession(e, I));
1285
+ }, Ut = () => {
1286
+ if (!P) return;
1287
+ let e = P.getVideoElement();
1288
+ if (ft) {
1289
+ P.casting.stopAirPlay(e);
1290
+ return;
1291
+ }
1292
+ typeof e.webkitShowPlaybackTargetPicker == "function" || P.casting.isAirPlayAvailable() ? P.casting.requestAirPlaySession(e) : console.warn("[PlayerSDK AirPlay] AirPlay is not available on this device.");
1293
+ }, Wt = (e) => {
1294
+ if (!O.current || L === 0 || !P) return;
1295
+ let t = O.current.getBoundingClientRect(), n = Math.max(0, Math.min(1, (e.clientX - t.left) / t.width)) * L;
1296
+ _t(e.clientX - t.left), yt(n), A.current && window.clearTimeout(A.current), A.current = window.setTimeout(() => {
1297
+ k.current && (k.current.currentTime = n);
1298
+ }, 100), Ct(P.keyMoments.getCurrentMoment(n).keyMoment);
1299
+ }, Gt = () => {
1300
+ _t(null), xt(null), Ct(null), A.current && window.clearTimeout(A.current);
1301
+ }, Q = (e) => {
1302
+ if (isNaN(e) || e < 0) return "00:00";
1303
+ let t = Math.floor(e), n = Math.floor(t / 3600), r = Math.floor(t % 3600 / 60), i = t % 60, a = (e) => String(e).padStart(2, "0");
1304
+ return n > 0 ? `${a(n)}:${a(r)}:${a(i)}` : `${a(r)}:${a(i)}`;
1305
+ }, Kt = () => v(z || R === 0 ? ue : R < .3 ? se : R < .7 ? ce : le, { size: 18 }), $ = (e) => {
1306
+ G(W === e ? "none" : e);
1307
+ };
1308
+ return /* @__PURE__ */ y("div", {
1309
+ ref: D,
1310
+ className: `sdk-player-container ${Tt ? "controls-active" : ""}`,
1311
+ onMouseMove: At,
1312
+ onMouseLeave: () => {},
1313
+ style: {
1314
+ border: "1px solid rgba(255, 255, 255, 0.08)",
1315
+ "--sdk-theme-color": g,
1316
+ "--sdk-theme-color-rgb": Se(g)
1317
+ },
1318
+ children: [
1319
+ /* @__PURE__ */ v("canvas", {
1320
+ ref: Te,
1321
+ width: 160,
1322
+ height: 90,
1323
+ style: {
1324
+ display: "none",
1325
+ position: "absolute",
1326
+ pointerEvents: "none"
1327
+ }
1328
+ }),
1329
+ /* @__PURE__ */ v("div", {
1330
+ className: `sdk-spinner-overlay ${Pe ? "active" : ""}`,
1331
+ children: /* @__PURE__ */ v("div", { className: "sdk-spinner" })
1332
+ }),
1333
+ Ke && V !== "off" && /* @__PURE__ */ v("div", {
1334
+ className: "sdk-subtitles-overlay",
1335
+ children: /* @__PURE__ */ v("span", {
1336
+ className: "sdk-subtitles-text",
1337
+ style: {
1338
+ fontSize: E.size === "small" ? "14px" : E.size === "large" ? "24px" : "18px",
1339
+ color: E.color ?? "#ffffff",
1340
+ background: E.background === "none" ? "transparent" : E.background === "solid" ? "rgba(0, 0, 0, 0.92)" : "rgba(15, 23, 42, 0.78)",
1341
+ border: E.background === "none" ? "none" : "1px solid rgba(255,255,255,0.08)",
1342
+ backdropFilter: E.background === "none" ? "none" : "blur(8px)"
1343
+ },
1344
+ dangerouslySetInnerHTML: { __html: Ke }
1345
+ })
1346
+ }),
1347
+ (q || ft) && /* @__PURE__ */ y("div", {
1348
+ className: "sdk-cast-screen",
1349
+ children: [
1350
+ /* @__PURE__ */ v(s, {
1351
+ size: 64,
1352
+ className: "sdk-cast-icon-glow"
1353
+ }),
1354
+ /* @__PURE__ */ v("div", {
1355
+ className: "sdk-cast-title",
1356
+ children: q ? `Casting to ${q}` : `AirPlay to ${mt || "device"}`
1357
+ }),
1358
+ /* @__PURE__ */ v("div", {
1359
+ className: "sdk-cast-desc",
1360
+ children: q ? "This media asset is currently streaming on your external screen." : `This media asset is currently streaming via AirPlay${mt ? ` to ${mt}` : ""}.`
1361
+ }),
1362
+ /* @__PURE__ */ v("button", {
1363
+ className: "sdk-cast-disconnect-btn",
1364
+ onClick: () => {
1365
+ q ? P?.casting.stopCasting() : ft && P?.casting.stopAirPlay(P.getVideoElement());
1366
+ },
1367
+ children: "Disconnect Streaming"
1368
+ })
1369
+ ]
1370
+ }),
1371
+ !q && !F && /* @__PURE__ */ v("div", {
1372
+ className: "sdk-center-action-overlay",
1373
+ onClick: jt,
1374
+ children: /* @__PURE__ */ v("div", {
1375
+ className: "sdk-center-action-btn",
1376
+ children: Be ? /* @__PURE__ */ v(re, {
1377
+ size: 32,
1378
+ className: "sdk-center-icon"
1379
+ }) : /* @__PURE__ */ v(ne, {
1380
+ size: 32,
1381
+ className: "sdk-center-icon",
1382
+ style: { marginLeft: "4px" },
1383
+ fill: "currentColor"
1384
+ })
1385
+ })
1386
+ }),
1387
+ !q && /* @__PURE__ */ v("div", {
1388
+ className: "sdk-controls-overlay",
1389
+ onClick: (e) => {
1390
+ e.target === e.currentTarget && jt();
1391
+ },
1392
+ children: he && /* @__PURE__ */ y("div", {
1393
+ className: "sdk-control-bar",
1394
+ children: [/* @__PURE__ */ y("div", {
1395
+ ref: O,
1396
+ className: "sdk-seekbar-container",
1397
+ onMouseDown: Nt,
1398
+ onMouseMove: Wt,
1399
+ onMouseLeave: Gt,
1400
+ children: [
1401
+ /* @__PURE__ */ v("div", {
1402
+ className: "sdk-seekbar-buffered",
1403
+ style: { width: `${L ? (P && P.getBufferedRanges()[0]?.end || 0) / L * 100 : 0}%` }
1404
+ }),
1405
+ /* @__PURE__ */ v("div", {
1406
+ className: "sdk-seekbar-progress",
1407
+ style: {
1408
+ width: `${L ? (J === null ? I : J) / L * 100 : 0}%`,
1409
+ background: g
1410
+ },
1411
+ children: /* @__PURE__ */ v("div", { className: "sdk-seekbar-handle" })
1412
+ }),
1413
+ x && U.map((e, t) => L === 0 ? null : /* @__PURE__ */ v("div", {
1414
+ className: "sdk-seekbar-chapter-marker",
1415
+ style: { left: `${e.startTime / L * 100}%` }
1416
+ }, t)),
1417
+ gt !== null && bt && /* @__PURE__ */ y("div", {
1418
+ className: "sdk-thumbnail-tooltip",
1419
+ style: { left: `${gt}px` },
1420
+ children: [/* @__PURE__ */ v("div", {
1421
+ className: "sdk-thumbnail-preview",
1422
+ children: /* @__PURE__ */ v("img", {
1423
+ src: bt,
1424
+ alt: "preview",
1425
+ style: {
1426
+ width: "100%",
1427
+ height: "100%",
1428
+ objectFit: "cover",
1429
+ borderRadius: "6px 6px 0 0",
1430
+ display: "block"
1431
+ }
1432
+ })
1433
+ }), /* @__PURE__ */ y("div", {
1434
+ className: "sdk-thumbnail-text",
1435
+ children: [Q(vt), St && /* @__PURE__ */ v("div", {
1436
+ className: "sdk-thumbnail-chapter",
1437
+ children: St.title
1438
+ })]
1439
+ })]
1440
+ })
1441
+ ]
1442
+ }), /* @__PURE__ */ y("div", {
1443
+ className: "sdk-control-row",
1444
+ children: [/* @__PURE__ */ y("div", {
1445
+ className: "sdk-control-group",
1446
+ children: [
1447
+ /* @__PURE__ */ v("button", {
1448
+ className: "sdk-control-btn",
1449
+ onClick: jt,
1450
+ title: F ? "Pause" : "Play",
1451
+ children: v(F ? ee : ne, {
1452
+ size: 18,
1453
+ fill: "currentColor"
1454
+ })
1455
+ }),
1456
+ /* @__PURE__ */ v("button", {
1457
+ className: "sdk-control-btn",
1458
+ onClick: () => {
1459
+ Z(0), F || P?.play();
1460
+ },
1461
+ title: "Replay from beginning",
1462
+ children: /* @__PURE__ */ v(re, { size: 18 })
1463
+ }),
1464
+ /* @__PURE__ */ v("button", {
1465
+ className: "sdk-control-btn",
1466
+ onClick: () => Z(I - 10),
1467
+ title: "Rewind 10s",
1468
+ children: /* @__PURE__ */ y("div", {
1469
+ style: {
1470
+ position: "relative",
1471
+ display: "flex",
1472
+ alignItems: "center",
1473
+ justifyContent: "center",
1474
+ width: "18px",
1475
+ height: "18px"
1476
+ },
1477
+ children: [/* @__PURE__ */ v(re, { size: 18 }), /* @__PURE__ */ v("span", {
1478
+ style: {
1479
+ position: "absolute",
1480
+ fontSize: "6px",
1481
+ fontWeight: "bold",
1482
+ top: "52%",
1483
+ left: "50%",
1484
+ transform: "translate(-50%, -50%)",
1485
+ pointerEvents: "none",
1486
+ fontFamily: "sans-serif",
1487
+ lineHeight: 1
1488
+ },
1489
+ children: "10"
1490
+ })]
1491
+ })
1492
+ }),
1493
+ /* @__PURE__ */ v("button", {
1494
+ className: "sdk-control-btn",
1495
+ onClick: () => Z(I + 10),
1496
+ title: "Forward 10s",
1497
+ children: /* @__PURE__ */ y("div", {
1498
+ style: {
1499
+ position: "relative",
1500
+ display: "flex",
1501
+ alignItems: "center",
1502
+ justifyContent: "center",
1503
+ width: "18px",
1504
+ height: "18px"
1505
+ },
1506
+ children: [/* @__PURE__ */ v(ie, { size: 18 }), /* @__PURE__ */ v("span", {
1507
+ style: {
1508
+ position: "absolute",
1509
+ fontSize: "6px",
1510
+ fontWeight: "bold",
1511
+ top: "52%",
1512
+ left: "50%",
1513
+ transform: "translate(-50%, -50%)",
1514
+ pointerEvents: "none",
1515
+ fontFamily: "sans-serif",
1516
+ lineHeight: 1
1517
+ },
1518
+ children: "10"
1519
+ })]
1520
+ })
1521
+ }),
1522
+ /* @__PURE__ */ y("div", {
1523
+ className: "sdk-volume-group",
1524
+ children: [/* @__PURE__ */ v("button", {
1525
+ className: "sdk-control-btn",
1526
+ onClick: Ft,
1527
+ children: Kt()
1528
+ }), /* @__PURE__ */ v("div", {
1529
+ className: "sdk-volume-slider-container",
1530
+ children: /* @__PURE__ */ v("input", {
1531
+ type: "range",
1532
+ min: "0",
1533
+ max: "1",
1534
+ step: "0.05",
1535
+ value: z ? 0 : R,
1536
+ onChange: Pt,
1537
+ className: "sdk-volume-slider",
1538
+ style: { "--volume-pct": `${(z ? 0 : R) * 100}%` }
1539
+ })
1540
+ })]
1541
+ }),
1542
+ /* @__PURE__ */ y("div", {
1543
+ className: "sdk-time-display",
1544
+ children: [
1545
+ Q(J === null ? I : J),
1546
+ " / ",
1547
+ Q(L)
1548
+ ]
1549
+ }),
1550
+ x && et.chapter && /* @__PURE__ */ y("div", {
1551
+ className: `sdk-chapter-badge ${K ? "active" : ""}`,
1552
+ title: "Toggle Key Moments side panel",
1553
+ onClick: () => at(!K),
1554
+ style: {
1555
+ cursor: "pointer",
1556
+ display: "flex",
1557
+ alignItems: "center"
1558
+ },
1559
+ children: [
1560
+ /* @__PURE__ */ v(d, {
1561
+ size: 10,
1562
+ style: { marginRight: "5px" }
1563
+ }),
1564
+ /* @__PURE__ */ v("span", {
1565
+ style: { marginRight: "3px" },
1566
+ children: et.chapter.title
1567
+ }),
1568
+ /* @__PURE__ */ v(l, {
1569
+ size: 10,
1570
+ style: {
1571
+ opacity: .8,
1572
+ transform: K ? "rotate(90deg)" : "none",
1573
+ transition: "transform 0.2s ease"
1574
+ }
1575
+ })
1576
+ ]
1577
+ })
1578
+ ]
1579
+ }), /* @__PURE__ */ y("div", {
1580
+ className: "sdk-control-group",
1581
+ children: [
1582
+ _e && /* @__PURE__ */ v("button", {
1583
+ className: "sdk-control-btn",
1584
+ onClick: Ht,
1585
+ title: "Cast Stream",
1586
+ style: { color: q ? "#3b82f6" : "" },
1587
+ children: /* @__PURE__ */ v(s, { size: 18 })
1588
+ }),
1589
+ ut && /* @__PURE__ */ v("button", {
1590
+ className: "sdk-control-btn",
1591
+ onClick: Ut,
1592
+ title: "AirPlay",
1593
+ style: { color: g },
1594
+ children: /* @__PURE__ */ v(o, { size: 18 })
1595
+ }),
1596
+ Xe.length > 1 && /* @__PURE__ */ y("div", {
1597
+ className: "sdk-menu-container",
1598
+ children: [/* @__PURE__ */ v("button", {
1599
+ className: "sdk-control-btn",
1600
+ onClick: () => $("audio"),
1601
+ title: "Audio track",
1602
+ style: { color: W === "audio" ? g : "" },
1603
+ children: /* @__PURE__ */ v(u, { size: 18 })
1604
+ }), W === "audio" && /* @__PURE__ */ y("div", {
1605
+ className: "sdk-dropup-menu",
1606
+ children: [/* @__PURE__ */ v("div", {
1607
+ className: "sdk-dropup-header",
1608
+ children: "Audio Tracks"
1609
+ }), Xe.map((e) => /* @__PURE__ */ y("div", {
1610
+ className: `sdk-dropup-item ${Qe === e.id ? "active" : ""}`,
1611
+ onClick: () => {
1612
+ P?.setAudioTrack(e.id), $e(e.id), G("none");
1613
+ },
1614
+ children: [/* @__PURE__ */ v("span", { children: Ce(e) }), Qe === e.id && /* @__PURE__ */ v(c, { size: 12 })]
1615
+ }, e.id))]
1616
+ })]
1617
+ }),
1618
+ ve && /* @__PURE__ */ y("div", {
1619
+ className: "sdk-menu-container",
1620
+ children: [/* @__PURE__ */ v("button", {
1621
+ className: "sdk-control-btn",
1622
+ onClick: () => $("subtitles"),
1623
+ title: "Subtitles track selector",
1624
+ style: { color: V === "off" ? "" : g },
1625
+ children: /* @__PURE__ */ v(oe, { size: 18 })
1626
+ }), W === "subtitles" && /* @__PURE__ */ y("div", {
1627
+ className: "sdk-dropup-menu",
1628
+ children: [
1629
+ /* @__PURE__ */ v("div", {
1630
+ className: "sdk-dropup-header",
1631
+ children: "Subtitles"
1632
+ }),
1633
+ /* @__PURE__ */ y("div", {
1634
+ className: `sdk-dropup-item ${V === "off" ? "active" : ""}`,
1635
+ onClick: () => Rt("off"),
1636
+ children: [/* @__PURE__ */ v("span", { children: "Off" }), V === "off" && /* @__PURE__ */ v(c, { size: 12 })]
1637
+ }),
1638
+ Je.map((e) => /* @__PURE__ */ y("div", {
1639
+ className: `sdk-dropup-item ${V === e.id ? "active" : ""}`,
1640
+ onClick: () => Rt(e.id),
1641
+ children: [/* @__PURE__ */ v("span", { children: Ce(e) }), V === e.id && /* @__PURE__ */ v(c, { size: 12 })]
1642
+ }, e.id))
1643
+ ]
1644
+ })]
1645
+ }),
1646
+ ye && /* @__PURE__ */ y("div", {
1647
+ className: "sdk-menu-container",
1648
+ children: [/* @__PURE__ */ v("button", {
1649
+ className: "sdk-control-btn",
1650
+ onClick: () => $("quality"),
1651
+ title: "Stream Quality settings",
1652
+ style: { color: We.id === -1 ? "" : g },
1653
+ children: /* @__PURE__ */ v(ae, { size: 18 })
1654
+ }), W === "quality" && /* @__PURE__ */ y("div", {
1655
+ className: "sdk-dropup-menu large",
1656
+ children: [/* @__PURE__ */ v("div", {
1657
+ className: "sdk-dropup-header",
1658
+ children: "Quality Options"
1659
+ }), He.map((e) => /* @__PURE__ */ y("div", {
1660
+ className: `sdk-dropup-item ${We.id === e.id ? "active" : ""}`,
1661
+ onClick: () => Lt(e.id),
1662
+ children: [/* @__PURE__ */ v("span", { children: e.label }), We.id === e.id && /* @__PURE__ */ v(c, { size: 12 })]
1663
+ }, e.id))]
1664
+ })]
1665
+ }),
1666
+ be && /* @__PURE__ */ y("div", {
1667
+ className: "sdk-menu-container",
1668
+ children: [/* @__PURE__ */ v("button", {
1669
+ className: "sdk-control-btn",
1670
+ onClick: () => $("speed"),
1671
+ title: "Playback Speed",
1672
+ children: /* @__PURE__ */ y("span", {
1673
+ style: {
1674
+ fontSize: "11px",
1675
+ fontWeight: "bold"
1676
+ },
1677
+ children: [rt, "x"]
1678
+ })
1679
+ }), W === "speed" && /* @__PURE__ */ y("div", {
1680
+ className: "sdk-dropup-menu",
1681
+ children: [/* @__PURE__ */ v("div", {
1682
+ className: "sdk-dropup-header",
1683
+ children: "Speed"
1684
+ }), [
1685
+ .5,
1686
+ .75,
1687
+ 1,
1688
+ 1.25,
1689
+ 1.5,
1690
+ 2
1691
+ ].map((e) => /* @__PURE__ */ y("div", {
1692
+ className: `sdk-dropup-item ${rt === e ? "active" : ""}`,
1693
+ onClick: () => It(e),
1694
+ children: [/* @__PURE__ */ v("span", { children: e === 1 ? "Normal" : `${e}x` }), rt === e && /* @__PURE__ */ v(c, { size: 12 })]
1695
+ }, e))]
1696
+ })]
1697
+ }),
1698
+ C && /* @__PURE__ */ v("button", {
1699
+ className: "sdk-control-btn",
1700
+ onClick: Bt,
1701
+ title: "Picture-in-Picture",
1702
+ style: { color: Re ? g : "" },
1703
+ children: /* @__PURE__ */ v(te, { size: 18 })
1704
+ }),
1705
+ w && /* @__PURE__ */ v("button", {
1706
+ className: "sdk-control-btn",
1707
+ onClick: Vt,
1708
+ title: "Fullscreen",
1709
+ children: v(Ie ? p : f, { size: 18 })
1710
+ })
1711
+ ]
1712
+ })]
1713
+ })]
1714
+ })
1715
+ }),
1716
+ x && K && U.length > 0 && /* @__PURE__ */ y("div", {
1717
+ className: "sdk-sidebar-panel",
1718
+ children: [
1719
+ /* @__PURE__ */ y("div", {
1720
+ className: "sdk-sidebar-header",
1721
+ children: [/* @__PURE__ */ v("div", {
1722
+ className: "sdk-sidebar-title",
1723
+ children: "In this video"
1724
+ }), /* @__PURE__ */ v("button", {
1725
+ className: "sdk-sidebar-close-btn",
1726
+ onClick: () => at(!1),
1727
+ title: "Close panel",
1728
+ children: /* @__PURE__ */ v(de, { size: 16 })
1729
+ })]
1730
+ }),
1731
+ /* @__PURE__ */ v("div", {
1732
+ className: "sdk-sidebar-tabs",
1733
+ children: /* @__PURE__ */ v("button", {
1734
+ className: "sdk-sidebar-tab active",
1735
+ children: "Key Moments"
1736
+ })
1737
+ }),
1738
+ /* @__PURE__ */ v("div", {
1739
+ className: "sdk-sidebar-content",
1740
+ children: U.map((e, t) => {
1741
+ let n = et.index === t;
1742
+ return /* @__PURE__ */ y("div", {
1743
+ className: `sdk-sidebar-chapter-row ${n ? "active" : ""}`,
1744
+ onClick: () => zt(e.startTime),
1745
+ children: [/* @__PURE__ */ y("div", {
1746
+ className: "sdk-sidebar-chapter-thumbnail",
1747
+ style: { overflow: "hidden" },
1748
+ children: [ot[t] || e.thumbnail ? /* @__PURE__ */ v("img", {
1749
+ src: ot[t] || e.thumbnail,
1750
+ alt: e.title,
1751
+ style: {
1752
+ width: "100%",
1753
+ height: "100%",
1754
+ objectFit: "cover",
1755
+ display: "block"
1756
+ }
1757
+ }) : /* @__PURE__ */ v(d, {
1758
+ size: 14,
1759
+ className: "sdk-sidebar-chapter-icon",
1760
+ style: { color: n ? g : "rgba(255,255,255,0.4)" }
1761
+ }), /* @__PURE__ */ v("span", {
1762
+ className: "sdk-sidebar-chapter-time",
1763
+ children: Q(e.startTime)
1764
+ })]
1765
+ }), /* @__PURE__ */ y("div", {
1766
+ className: "sdk-sidebar-chapter-info",
1767
+ children: [/* @__PURE__ */ v("div", {
1768
+ className: "sdk-sidebar-chapter-title",
1769
+ style: { color: n ? g : "#ffffff" },
1770
+ children: e.title
1771
+ }), /* @__PURE__ */ y("div", {
1772
+ className: "sdk-sidebar-chapter-duration",
1773
+ children: ["Start at ", Q(e.startTime)]
1774
+ })]
1775
+ })]
1776
+ }, t);
1777
+ })
1778
+ })
1779
+ ]
1780
+ })
1781
+ ]
1782
+ });
1783
+ };
1784
+ //#endregion
1785
+ //#region src/create-player.ts
1786
+ function D(t, n) {
1787
+ let r = i(t), a = n;
1788
+ return r.render(e(E, a)), {
1789
+ update(t) {
1790
+ a = {
1791
+ ...a,
1792
+ ...t
1793
+ }, r.render(e(E, a));
1794
+ },
1795
+ destroy() {
1796
+ r.unmount();
1797
+ }
1798
+ };
1799
+ }
1800
+ //#endregion
1801
+ export { ge as FirebaseAnalyticsProvider, xe as VideoPlayerSDK, E as WebVideoPlayer, D as createPlayer };
1802
+
1803
+ //# sourceMappingURL=index.js.map