@oddin-gg/havik-player 2.1.0 → 2.1.1
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/dist/havik-player.global.js +2 -2
- package/dist/havik-player.global.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +213 -189
- package/dist/index.js.map +1 -1
- package/embed/index.html +1 -1
- package/examples/vanilla.html +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -244,32 +244,32 @@ function ce(e, t) {
|
|
|
244
244
|
function S(e) {
|
|
245
245
|
return e.ownerDocument ?? document;
|
|
246
246
|
}
|
|
247
|
-
function
|
|
247
|
+
function le(e) {
|
|
248
248
|
return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
|
|
249
249
|
}
|
|
250
|
-
function
|
|
251
|
-
let n =
|
|
250
|
+
function C(e, t) {
|
|
251
|
+
let n = le(S(e));
|
|
252
252
|
return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
|
|
253
253
|
}
|
|
254
|
-
async function
|
|
254
|
+
async function w(e, t) {
|
|
255
255
|
let n = t ?? e;
|
|
256
256
|
if (typeof n.requestFullscreen == "function") return await n.requestFullscreen(), !0;
|
|
257
257
|
if (typeof n.webkitRequestFullscreen == "function") return n.webkitRequestFullscreen(), !0;
|
|
258
258
|
let r = e;
|
|
259
259
|
return r.webkitSupportsFullscreen && typeof r.webkitEnterFullscreen == "function" ? (r.webkitEnterFullscreen(), !0) : !1;
|
|
260
260
|
}
|
|
261
|
-
async function
|
|
261
|
+
async function T(e, t) {
|
|
262
262
|
let n = e;
|
|
263
263
|
if (n.webkitDisplayingFullscreen) {
|
|
264
264
|
n.webkitExitFullscreen?.();
|
|
265
265
|
return;
|
|
266
266
|
}
|
|
267
|
-
let r = S(e), i =
|
|
267
|
+
let r = S(e), i = le(r);
|
|
268
268
|
i != null && (i === e || t != null && i === t) && (typeof r.exitFullscreen == "function" ? await r.exitFullscreen() : r.webkitExitFullscreen?.());
|
|
269
269
|
}
|
|
270
270
|
//#endregion
|
|
271
271
|
//#region src/core/catalog.ts
|
|
272
|
-
async function
|
|
272
|
+
async function ue(e) {
|
|
273
273
|
let t = new URLSearchParams();
|
|
274
274
|
e.status && t.set("status", Array.isArray(e.status) ? e.status.join(",") : e.status), e.sport && t.set("sport", e.sport);
|
|
275
275
|
let i = t.toString(), a = c(e.baseUrl, "/v1/catalog" + (i ? `?${i}` : "")), o = new Headers();
|
|
@@ -287,12 +287,12 @@ async function le(e) {
|
|
|
287
287
|
};
|
|
288
288
|
if (!s.ok) throw new n(r(s.status), s.status, `catalog request failed (HTTP ${s.status})`);
|
|
289
289
|
return {
|
|
290
|
-
tournaments:
|
|
290
|
+
tournaments: de(await s.json()),
|
|
291
291
|
etag: s.headers.get("etag") ?? void 0,
|
|
292
292
|
notModified: !1
|
|
293
293
|
};
|
|
294
294
|
}
|
|
295
|
-
function
|
|
295
|
+
function de(e) {
|
|
296
296
|
return (e.tournaments ?? []).map((e) => {
|
|
297
297
|
let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
|
|
298
298
|
return {
|
|
@@ -312,7 +312,7 @@ function ue(e) {
|
|
|
312
312
|
};
|
|
313
313
|
});
|
|
314
314
|
}
|
|
315
|
-
async function
|
|
315
|
+
async function fe(e) {
|
|
316
316
|
let t = c(e.baseUrl, `/v1/tournaments/${encodeURIComponent(e.urn)}`), i = new Headers();
|
|
317
317
|
e.etag && i.set("If-None-Match", e.etag);
|
|
318
318
|
let a = await u(t, {
|
|
@@ -332,13 +332,13 @@ async function de(e) {
|
|
|
332
332
|
};
|
|
333
333
|
if (!a.ok) throw new n(r(a.status), a.status, `tournament request failed (HTTP ${a.status})`);
|
|
334
334
|
return {
|
|
335
|
-
tournament:
|
|
335
|
+
tournament: pe(await a.json()),
|
|
336
336
|
etag: a.headers.get("etag") ?? void 0,
|
|
337
337
|
notModified: !1,
|
|
338
338
|
notFound: !1
|
|
339
339
|
};
|
|
340
340
|
}
|
|
341
|
-
function
|
|
341
|
+
function pe(e) {
|
|
342
342
|
let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
|
|
343
343
|
return {
|
|
344
344
|
urn: t,
|
|
@@ -356,12 +356,12 @@ function fe(e) {
|
|
|
356
356
|
}))
|
|
357
357
|
};
|
|
358
358
|
}
|
|
359
|
-
function
|
|
359
|
+
function me(e) {
|
|
360
360
|
return e.tournaments.flatMap((e) => e.matches);
|
|
361
361
|
}
|
|
362
362
|
//#endregion
|
|
363
363
|
//#region src/core/poll.ts
|
|
364
|
-
function
|
|
364
|
+
function he(e) {
|
|
365
365
|
let t = Math.max(2e3, e.intervalMs ?? 1e4), i = new AbortController(), a, o, s, l = !1, d = () => {
|
|
366
366
|
l || (a = setTimeout(f, t));
|
|
367
367
|
}, f = async () => {
|
|
@@ -397,7 +397,7 @@ function me(e) {
|
|
|
397
397
|
}
|
|
398
398
|
//#endregion
|
|
399
399
|
//#region src/core/events.ts
|
|
400
|
-
function
|
|
400
|
+
function E(e) {
|
|
401
401
|
let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = new AbortController(), i = !1, a = (e) => new Promise((t) => {
|
|
402
402
|
if (r.signal.aborted) return t();
|
|
403
403
|
let n = setTimeout(t, e);
|
|
@@ -464,7 +464,7 @@ function D(e) {
|
|
|
464
464
|
i || (i = !0, r.abort());
|
|
465
465
|
} };
|
|
466
466
|
}
|
|
467
|
-
function
|
|
467
|
+
function D(e) {
|
|
468
468
|
try {
|
|
469
469
|
let t = new URL(e);
|
|
470
470
|
return t.hostname = `events.${t.hostname}`, t.pathname = "", t.search = "", t.origin;
|
|
@@ -474,27 +474,27 @@ function O(e) {
|
|
|
474
474
|
}
|
|
475
475
|
//#endregion
|
|
476
476
|
//#region src/core/drm/deviceId.ts
|
|
477
|
-
var
|
|
478
|
-
function
|
|
479
|
-
if (
|
|
477
|
+
var O = "havik.player.deviceId", k;
|
|
478
|
+
function A() {
|
|
479
|
+
if (k) return k;
|
|
480
480
|
try {
|
|
481
|
-
let e = globalThis.localStorage?.getItem(
|
|
482
|
-
if (e) return
|
|
481
|
+
let e = globalThis.localStorage?.getItem(O);
|
|
482
|
+
if (e) return k = e, e;
|
|
483
483
|
} catch {}
|
|
484
|
-
let e =
|
|
485
|
-
|
|
484
|
+
let e = _e();
|
|
485
|
+
k = e;
|
|
486
486
|
try {
|
|
487
|
-
globalThis.localStorage?.setItem(
|
|
487
|
+
globalThis.localStorage?.setItem(O, e);
|
|
488
488
|
} catch {}
|
|
489
489
|
return e;
|
|
490
490
|
}
|
|
491
|
-
function
|
|
492
|
-
|
|
491
|
+
function ge() {
|
|
492
|
+
k = void 0;
|
|
493
493
|
try {
|
|
494
|
-
globalThis.localStorage?.removeItem(
|
|
494
|
+
globalThis.localStorage?.removeItem(O);
|
|
495
495
|
} catch {}
|
|
496
496
|
}
|
|
497
|
-
function
|
|
497
|
+
function _e() {
|
|
498
498
|
let e = globalThis.crypto;
|
|
499
499
|
if (e && typeof e.randomUUID == "function") return e.randomUUID();
|
|
500
500
|
let t = /* @__PURE__ */ new Uint8Array(16);
|
|
@@ -506,22 +506,22 @@ function ge() {
|
|
|
506
506
|
}
|
|
507
507
|
//#endregion
|
|
508
508
|
//#region src/core/drm/headers.ts
|
|
509
|
-
function
|
|
509
|
+
function ve(e, t, n = {}) {
|
|
510
510
|
let r = {
|
|
511
511
|
"x-api-key": t.apiKey,
|
|
512
512
|
"X-Match-Urn": e.matchUrn,
|
|
513
|
-
"X-Device-Id": n.deviceId ??
|
|
513
|
+
"X-Device-Id": n.deviceId ?? A(),
|
|
514
514
|
"Content-Type": "application/octet-stream"
|
|
515
515
|
};
|
|
516
516
|
return n.userId && (r["X-User-Id"] = n.userId), r;
|
|
517
517
|
}
|
|
518
518
|
//#endregion
|
|
519
519
|
//#region src/core/drm/support.ts
|
|
520
|
-
var
|
|
520
|
+
var ye = 5e3, j = "video/mp4; codecs=\"avc1.42E01E\"", M = "audio/mp4; codecs=\"mp4a.40.2\"", be = {
|
|
521
521
|
widevine: ["com.widevine.alpha"],
|
|
522
522
|
fairplay: ["com.apple.fps"]
|
|
523
523
|
};
|
|
524
|
-
function
|
|
524
|
+
function xe(e) {
|
|
525
525
|
return e === "fairplay" ? [{
|
|
526
526
|
initDataTypes: [
|
|
527
527
|
"sinf",
|
|
@@ -529,30 +529,30 @@ function be(e) {
|
|
|
529
529
|
"cenc"
|
|
530
530
|
],
|
|
531
531
|
videoCapabilities: [{
|
|
532
|
-
contentType:
|
|
532
|
+
contentType: j,
|
|
533
533
|
robustness: "",
|
|
534
534
|
encryptionScheme: "cbcs"
|
|
535
535
|
}],
|
|
536
536
|
audioCapabilities: [{
|
|
537
|
-
contentType:
|
|
537
|
+
contentType: M,
|
|
538
538
|
robustness: "",
|
|
539
539
|
encryptionScheme: "cbcs"
|
|
540
540
|
}]
|
|
541
541
|
}] : [{
|
|
542
542
|
initDataTypes: ["cenc"],
|
|
543
543
|
videoCapabilities: [{
|
|
544
|
-
contentType:
|
|
544
|
+
contentType: j,
|
|
545
545
|
robustness: "SW_SECURE_DECODE",
|
|
546
546
|
encryptionScheme: "cbcs"
|
|
547
547
|
}],
|
|
548
548
|
audioCapabilities: [{
|
|
549
|
-
contentType:
|
|
549
|
+
contentType: M,
|
|
550
550
|
robustness: "SW_SECURE_CRYPTO",
|
|
551
551
|
encryptionScheme: "cbcs"
|
|
552
552
|
}]
|
|
553
553
|
}];
|
|
554
554
|
}
|
|
555
|
-
function
|
|
555
|
+
function N(e, t) {
|
|
556
556
|
return new Promise((n, r) => {
|
|
557
557
|
let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
|
|
558
558
|
e.then((e) => {
|
|
@@ -562,8 +562,8 @@ function P(e, t) {
|
|
|
562
562
|
});
|
|
563
563
|
});
|
|
564
564
|
}
|
|
565
|
-
async function
|
|
566
|
-
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ??
|
|
565
|
+
async function Se(e = {}) {
|
|
566
|
+
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? ye, r = {};
|
|
567
567
|
if (typeof window < "u" && window.isSecureContext === !1) return {
|
|
568
568
|
verdict: "insecure-context",
|
|
569
569
|
detail: r
|
|
@@ -575,7 +575,7 @@ async function xe(e = {}) {
|
|
|
575
575
|
};
|
|
576
576
|
let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
|
|
577
577
|
for (let e of t) {
|
|
578
|
-
let t =
|
|
578
|
+
let t = be[e];
|
|
579
579
|
if (!t) {
|
|
580
580
|
r[e] = "unknown system";
|
|
581
581
|
continue;
|
|
@@ -586,7 +586,7 @@ async function xe(e = {}) {
|
|
|
586
586
|
break;
|
|
587
587
|
}
|
|
588
588
|
try {
|
|
589
|
-
return await
|
|
589
|
+
return await N((await N(i(n, xe(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
|
|
590
590
|
verdict: "supported",
|
|
591
591
|
system: e,
|
|
592
592
|
detail: r
|
|
@@ -610,21 +610,44 @@ async function xe(e = {}) {
|
|
|
610
610
|
}
|
|
611
611
|
//#endregion
|
|
612
612
|
//#region src/core/manifest.ts
|
|
613
|
-
var
|
|
614
|
-
function
|
|
615
|
-
return
|
|
613
|
+
var Ce = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
|
|
614
|
+
function we(e) {
|
|
615
|
+
return Ce.test(e);
|
|
616
|
+
}
|
|
617
|
+
//#endregion
|
|
618
|
+
//#region src/core/drm/cdm.ts
|
|
619
|
+
var Te = /* @__PURE__ */ new WeakMap();
|
|
620
|
+
function Ee(e, t) {
|
|
621
|
+
let n = Te.get(e);
|
|
622
|
+
n || (n = /* @__PURE__ */ new Map(), Te.set(e, n));
|
|
623
|
+
let r = n.get(t.keySystem);
|
|
624
|
+
if (r) return r;
|
|
625
|
+
let i = t.createMediaKeys().catch((e) => {
|
|
626
|
+
throw n.get(t.keySystem) === i && n.delete(t.keySystem), e;
|
|
627
|
+
});
|
|
628
|
+
return n.set(t.keySystem, i), i;
|
|
629
|
+
}
|
|
630
|
+
function P() {
|
|
631
|
+
return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
|
|
632
|
+
}
|
|
633
|
+
function De(e) {
|
|
634
|
+
return (t, n) => P() ? navigator.requestMediaKeySystemAccess(t, n).then((t) => ({
|
|
635
|
+
keySystem: t.keySystem,
|
|
636
|
+
getConfiguration: () => t.getConfiguration(),
|
|
637
|
+
createMediaKeys: () => Ee(e, t)
|
|
638
|
+
})) : Promise.reject(/* @__PURE__ */ Error("navigator.requestMediaKeySystemAccess is unavailable — EME needs a secure context (https, or localhost)"));
|
|
616
639
|
}
|
|
617
640
|
//#endregion
|
|
618
641
|
//#region src/core/stats.ts
|
|
619
|
-
var
|
|
620
|
-
function
|
|
642
|
+
var F = { droppedFrames: 0 };
|
|
643
|
+
function I(e) {
|
|
621
644
|
let t = e.getVideoPlaybackQuality?.();
|
|
622
645
|
return {
|
|
623
646
|
dropped: t?.droppedVideoFrames ?? 0,
|
|
624
647
|
decoded: t?.totalVideoFrames ?? 0
|
|
625
648
|
};
|
|
626
649
|
}
|
|
627
|
-
function
|
|
650
|
+
function Oe(e, t) {
|
|
628
651
|
let n = [
|
|
629
652
|
["playing", () => t("playing")],
|
|
630
653
|
["waiting", () => t("buffering")],
|
|
@@ -641,7 +664,7 @@ function Te(e, t) {
|
|
|
641
664
|
}
|
|
642
665
|
//#endregion
|
|
643
666
|
//#region src/core/engine/native.ts
|
|
644
|
-
function
|
|
667
|
+
function ke(e) {
|
|
645
668
|
try {
|
|
646
669
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
647
670
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -649,15 +672,15 @@ function Ee(e) {
|
|
|
649
672
|
return;
|
|
650
673
|
}
|
|
651
674
|
}
|
|
652
|
-
function
|
|
675
|
+
function L(e) {
|
|
653
676
|
return !!(e ?? (typeof document < "u" ? document.createElement("video") : void 0))?.canPlayType("application/vnd.apple.mpegurl");
|
|
654
677
|
}
|
|
655
|
-
function
|
|
678
|
+
function R() {
|
|
656
679
|
if (typeof window > "u") return !1;
|
|
657
680
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
658
681
|
return e || t;
|
|
659
682
|
}
|
|
660
|
-
var
|
|
683
|
+
var z = class {
|
|
661
684
|
name = "native";
|
|
662
685
|
deps;
|
|
663
686
|
onLoaded;
|
|
@@ -691,7 +714,7 @@ var R = class {
|
|
|
691
714
|
type: "error",
|
|
692
715
|
error: new n("INTERNAL", 0, "native HLS playback error"),
|
|
693
716
|
fatal: !0
|
|
694
|
-
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src =
|
|
717
|
+
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = Ae(t.manifestUrl, t.analytics?.sid), e.load();
|
|
695
718
|
}
|
|
696
719
|
startLoad() {
|
|
697
720
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -713,7 +736,7 @@ var R = class {
|
|
|
713
736
|
});
|
|
714
737
|
this.onEncrypted = (n) => {
|
|
715
738
|
let i = n;
|
|
716
|
-
!i.initData || this.fairplayArmed || (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
739
|
+
!i.initData || this.fairplayArmed || (this.fairplayArmed = !0, this.fairplayKeyIV = ke(i.initData), (async () => {
|
|
717
740
|
try {
|
|
718
741
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
719
742
|
initDataTypes: [i.initDataType],
|
|
@@ -808,7 +831,7 @@ var R = class {
|
|
|
808
831
|
e.seekable.length > 0 && (e.currentTime = e.seekable.end(e.seekable.length - 1));
|
|
809
832
|
}
|
|
810
833
|
getStats() {
|
|
811
|
-
let e = this.deps.video, t =
|
|
834
|
+
let e = this.deps.video, t = I(e), n = {
|
|
812
835
|
droppedFrames: t.dropped,
|
|
813
836
|
decodedFrames: t.decoded
|
|
814
837
|
};
|
|
@@ -831,36 +854,36 @@ var R = class {
|
|
|
831
854
|
} catch {}
|
|
832
855
|
}
|
|
833
856
|
};
|
|
834
|
-
function
|
|
857
|
+
function Ae(e, t) {
|
|
835
858
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
836
859
|
}
|
|
837
860
|
//#endregion
|
|
838
861
|
//#region src/core/engine/hls.ts
|
|
839
|
-
function
|
|
862
|
+
function je() {
|
|
840
863
|
return e.isSupported();
|
|
841
864
|
}
|
|
842
|
-
var
|
|
843
|
-
function
|
|
865
|
+
var Me = 3, Ne = 5, Pe = 3, Fe = 3e4, Ie = 12e3, Le = 3e3, B = 6e3, Re = 4e3, ze = 2, Be = 5, Ve = 2, He = 2, Ue = 2e3, We = 3e4, Ge = 2, Ke = 9, qe = .5, Je = 64;
|
|
866
|
+
function Ye(e) {
|
|
844
867
|
try {
|
|
845
868
|
return new URL(e).host;
|
|
846
869
|
} catch {
|
|
847
870
|
return "";
|
|
848
871
|
}
|
|
849
872
|
}
|
|
850
|
-
function
|
|
873
|
+
function Xe(e) {
|
|
851
874
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
852
875
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
853
876
|
return;
|
|
854
877
|
}
|
|
855
|
-
e.liveSyncDuration ??=
|
|
856
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
857
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
878
|
+
e.liveSyncDuration ??= Ge;
|
|
879
|
+
let t = Math.max(12, e.liveSyncDuration + Ke);
|
|
880
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Ze(e, e.liveSyncDuration);
|
|
858
881
|
}
|
|
859
|
-
function
|
|
882
|
+
function Ze(e, t) {
|
|
860
883
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
861
884
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
862
885
|
}
|
|
863
|
-
var
|
|
886
|
+
var V = class {
|
|
864
887
|
name = "hls";
|
|
865
888
|
hls = null;
|
|
866
889
|
deps;
|
|
@@ -914,7 +937,7 @@ var B = class {
|
|
|
914
937
|
this.deps = e, this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
915
938
|
}
|
|
916
939
|
async load() {
|
|
917
|
-
let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a =
|
|
940
|
+
let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = L(r) && R(), o = !!e.drm?.widevine?.licenseUrl && !a;
|
|
918
941
|
if (e.drmEnabled && !o) {
|
|
919
942
|
i({
|
|
920
943
|
type: "error",
|
|
@@ -954,7 +977,7 @@ var B = class {
|
|
|
954
977
|
let t = e.liveSyncPosition;
|
|
955
978
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
956
979
|
let { video: n } = this.deps;
|
|
957
|
-
n.currentTime <= t +
|
|
980
|
+
n.currentTime <= t + qe || (n.currentTime = t);
|
|
958
981
|
}
|
|
959
982
|
startHls() {
|
|
960
983
|
let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
|
|
@@ -978,6 +1001,7 @@ var B = class {
|
|
|
978
1001
|
videoEncryptionScheme: "cbcs",
|
|
979
1002
|
audioEncryptionScheme: "cbcs"
|
|
980
1003
|
},
|
|
1004
|
+
...P() ? { requestMediaKeySystemAccessFunc: De(t) } : {},
|
|
981
1005
|
licenseXhrSetup: (e, t) => {
|
|
982
1006
|
e.open("POST", this.licenseUrl ?? t, !0), e.setRequestHeader("x-api-key", r.apiKey), e.setRequestHeader("X-Match-Urn", n.matchUrn), e.setRequestHeader("X-Device-Id", i), a && e.setRequestHeader("X-User-Id", a), this.licenseRequested = !0;
|
|
983
1007
|
let o = performance.now();
|
|
@@ -993,7 +1017,7 @@ var B = class {
|
|
|
993
1017
|
} } : {},
|
|
994
1018
|
...c
|
|
995
1019
|
};
|
|
996
|
-
|
|
1020
|
+
Xe(d), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.loadStarted = d.autoStartLoad !== !1;
|
|
997
1021
|
let f = new e(d);
|
|
998
1022
|
this.hls = f, f.on(e.Events.MANIFEST_PARSED, () => {
|
|
999
1023
|
this.mediaRecoveries = 0, this.networkRecoveries = 0;
|
|
@@ -1002,17 +1026,17 @@ var B = class {
|
|
|
1002
1026
|
}), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1003
1027
|
t?.frag?.type === "main" && (this.kickPending = !1, this.kickTicks = 0, (this.mediaRecoveries > 0 || this.networkRecoveries > 0 || this.licenseRecoveries > 0 || this.starvationKicks > 0 || this.starvationRebuilds > 0) && !this.recoveryResetTimer && (this.recoveryResetTimer = setTimeout(() => {
|
|
1004
1028
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1005
|
-
},
|
|
1029
|
+
}, Fe)));
|
|
1006
1030
|
}), f.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1007
1031
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1008
1032
|
}), f.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
1009
1033
|
let n = t?.frag?.stats, r = n?.loaded;
|
|
1010
1034
|
typeof r == "number" && (this.bytesLoaded += r);
|
|
1011
1035
|
let i = n?.loading;
|
|
1012
|
-
i && i.end > 0 && i.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(i.end - i.start))), this.requestTimesMs.length >
|
|
1036
|
+
i && i.end > 0 && i.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(i.end - i.start))), this.requestTimesMs.length > Je && this.requestTimesMs.shift());
|
|
1013
1037
|
let a = t?.frag?.url;
|
|
1014
1038
|
if (a) {
|
|
1015
|
-
let e =
|
|
1039
|
+
let e = Ye(a);
|
|
1016
1040
|
e && (this.cdnHost = e);
|
|
1017
1041
|
}
|
|
1018
1042
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1025,7 +1049,7 @@ var B = class {
|
|
|
1025
1049
|
}));
|
|
1026
1050
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1027
1051
|
this.checkEndStale(), this.checkStarvation();
|
|
1028
|
-
},
|
|
1052
|
+
}, Le), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1029
1053
|
this.renditionSwitches += 1;
|
|
1030
1054
|
let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
|
|
1031
1055
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
|
|
@@ -1089,7 +1113,7 @@ var B = class {
|
|
|
1089
1113
|
return;
|
|
1090
1114
|
}
|
|
1091
1115
|
this.capTimer && clearTimeout(this.capTimer);
|
|
1092
|
-
let t = e > this.sizeCapLevel ?
|
|
1116
|
+
let t = e > this.sizeCapLevel ? Ue : We;
|
|
1093
1117
|
this.capTimer = setTimeout(() => {
|
|
1094
1118
|
this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
|
|
1095
1119
|
}, t);
|
|
@@ -1136,7 +1160,7 @@ var B = class {
|
|
|
1136
1160
|
e.widevine && (this.licenseUrl = e.widevine);
|
|
1137
1161
|
}
|
|
1138
1162
|
getStats() {
|
|
1139
|
-
let e = this.hls, t =
|
|
1163
|
+
let e = this.hls, t = I(this.deps.video), n = {
|
|
1140
1164
|
droppedFrames: t.dropped,
|
|
1141
1165
|
decodedFrames: t.decoded,
|
|
1142
1166
|
lowLatency: this.detectedLowLatency,
|
|
@@ -1178,7 +1202,7 @@ var B = class {
|
|
|
1178
1202
|
return;
|
|
1179
1203
|
}
|
|
1180
1204
|
let e = Date.now() - this.lastAdvanceMs;
|
|
1181
|
-
!this.chaseSuspended && e >
|
|
1205
|
+
!this.chaseSuspended && e > B && this.suspendChasing(), e > Ie && this.emitEnded("stalled");
|
|
1182
1206
|
}
|
|
1183
1207
|
checkStarvation() {
|
|
1184
1208
|
let e = this.hls, { video: t } = this.deps;
|
|
@@ -1187,17 +1211,17 @@ var B = class {
|
|
|
1187
1211
|
this.starvedTicks = 0;
|
|
1188
1212
|
return;
|
|
1189
1213
|
}
|
|
1190
|
-
let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs <
|
|
1214
|
+
let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs < B, r = this.lastFragLoadingMs !== 0 && Date.now() - this.lastFragLoadingMs > Re;
|
|
1191
1215
|
if (!(t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused && n && r)) {
|
|
1192
1216
|
this.starvedTicks = 0;
|
|
1193
1217
|
return;
|
|
1194
1218
|
}
|
|
1195
|
-
if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks <
|
|
1196
|
-
if (this.starvedTicks = 0, this.kickPending && this.kickTicks >=
|
|
1219
|
+
if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks < ze)) {
|
|
1220
|
+
if (this.starvedTicks = 0, this.kickPending && this.kickTicks >= Ve && (this.kickPending = !1, this.kickTicks = 0, this.starvationRebuilds < He)) {
|
|
1197
1221
|
this.starvationRebuilds += 1, console.warn("havik-player: restarting the load did not resume video (the wedge is in hls.js state that only a rebuild clears) — rebuilding the player"), this.rebuildInstance("starvation rebuild");
|
|
1198
1222
|
return;
|
|
1199
1223
|
}
|
|
1200
|
-
if (!(this.starvationKicks >=
|
|
1224
|
+
if (!(this.starvationKicks >= Be)) {
|
|
1201
1225
|
this.starvationKicks += 1, this.kickPending = !0, this.kickTicks = 0, console.warn("havik-player: video starved while the live playlist advances (wedged hls.js fragment pipeline) — restarting the load");
|
|
1202
1226
|
try {
|
|
1203
1227
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -1247,7 +1271,7 @@ var B = class {
|
|
|
1247
1271
|
scheduleLicenseRetry(t) {
|
|
1248
1272
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
1249
1273
|
let n = t.response?.code ?? 0;
|
|
1250
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
1274
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Pe) return !1;
|
|
1251
1275
|
this.licenseRecoveries += 1;
|
|
1252
1276
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
1253
1277
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -1279,7 +1303,7 @@ var B = class {
|
|
|
1279
1303
|
return;
|
|
1280
1304
|
}
|
|
1281
1305
|
if (t.type === e.ErrorTypes.NETWORK_ERROR) {
|
|
1282
|
-
if (this.networkRecoveries <
|
|
1306
|
+
if (this.networkRecoveries < Ne) {
|
|
1283
1307
|
this.networkRecoveries += 1;
|
|
1284
1308
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
1285
1309
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -1296,7 +1320,7 @@ var B = class {
|
|
|
1296
1320
|
return;
|
|
1297
1321
|
}
|
|
1298
1322
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
1299
|
-
if (this.mediaRecoveries <
|
|
1323
|
+
if (this.mediaRecoveries < Me) {
|
|
1300
1324
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
1301
1325
|
return;
|
|
1302
1326
|
}
|
|
@@ -1320,19 +1344,19 @@ var B = class {
|
|
|
1320
1344
|
let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
|
|
1321
1345
|
return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
|
|
1322
1346
|
}
|
|
1323
|
-
},
|
|
1347
|
+
}, Qe = 15e3, $e = 100, H = 1, et = 1e3, U = 3e4, tt = {
|
|
1324
1348
|
inline: "PRESENTATION_INLINE",
|
|
1325
1349
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
1326
1350
|
pip: "PRESENTATION_PIP"
|
|
1327
|
-
},
|
|
1351
|
+
}, nt = {
|
|
1328
1352
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
1329
1353
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
1330
1354
|
none: "KEY_SYSTEM_NONE"
|
|
1331
1355
|
};
|
|
1332
|
-
function
|
|
1356
|
+
function W(e, t) {
|
|
1333
1357
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
1334
1358
|
}
|
|
1335
|
-
var
|
|
1359
|
+
var rt = /* @__PURE__ */ new Set([
|
|
1336
1360
|
"INVALID_URN",
|
|
1337
1361
|
"NOT_FOUND",
|
|
1338
1362
|
"GONE",
|
|
@@ -1342,7 +1366,7 @@ var et = /* @__PURE__ */ new Set([
|
|
|
1342
1366
|
"FORBIDDEN",
|
|
1343
1367
|
"RATE_LIMITED",
|
|
1344
1368
|
"TIMEOUT"
|
|
1345
|
-
]),
|
|
1369
|
+
]), G = {
|
|
1346
1370
|
idle: "PLAYER_STATE_IDLE",
|
|
1347
1371
|
waiting: "PLAYER_STATE_WAITING",
|
|
1348
1372
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -1352,7 +1376,7 @@ var et = /* @__PURE__ */ new Set([
|
|
|
1352
1376
|
ended: "PLAYER_STATE_ENDED",
|
|
1353
1377
|
error: "PLAYER_STATE_ERROR"
|
|
1354
1378
|
};
|
|
1355
|
-
function
|
|
1379
|
+
function it(e) {
|
|
1356
1380
|
try {
|
|
1357
1381
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
1358
1382
|
return !n || r.length === 0 || n !== "feed" && !n.startsWith("feed-") ? void 0 : (t.hostname = [n.replace(/^feed/, "beacons"), ...r].join("."), t.pathname = "", t.search = "", t.origin);
|
|
@@ -1360,7 +1384,7 @@ function tt(e) {
|
|
|
1360
1384
|
return;
|
|
1361
1385
|
}
|
|
1362
1386
|
}
|
|
1363
|
-
var
|
|
1387
|
+
var at = class {
|
|
1364
1388
|
opts;
|
|
1365
1389
|
url;
|
|
1366
1390
|
now;
|
|
@@ -1426,7 +1450,7 @@ var nt = class {
|
|
|
1426
1450
|
constructor(e) {
|
|
1427
1451
|
this.opts = {
|
|
1428
1452
|
...e,
|
|
1429
|
-
heartbeatMs: e.heartbeatMs ??
|
|
1453
|
+
heartbeatMs: e.heartbeatMs ?? Qe
|
|
1430
1454
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`, this.now = e.now ?? (() => Date.now()), this.bornMs = this.now(), this.presentationSinceMs = this.bornMs;
|
|
1431
1455
|
}
|
|
1432
1456
|
start() {
|
|
@@ -1436,16 +1460,16 @@ var nt = class {
|
|
|
1436
1460
|
sdkVersion: this.opts.sdkVersion,
|
|
1437
1461
|
...this.opts.environment
|
|
1438
1462
|
};
|
|
1439
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
1463
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), et), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), this.onVisibility());
|
|
1440
1464
|
}
|
|
1441
1465
|
noteStateChange(e, t, n, r) {
|
|
1442
1466
|
if (this.endedFlag || e === t) return;
|
|
1443
1467
|
let i = this.now();
|
|
1444
|
-
t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(
|
|
1468
|
+
t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(H, i - this.bornMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(H, i - this.bornMs)), this.isMuted && this.mutedSinceMs === null && (this.mutedSinceMs = i)) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null, this.mutedSinceMs !== null && (this.mutedTotalMs += i - this.mutedSinceMs, this.mutedSinceMs = null)), this.isPlaying = t === "playing", this.syncActive(), t === "waiting" ? this.waitingSinceMs = i : this.waitingSinceMs !== null && (this.waitingTotalMs += i - this.waitingSinceMs, this.waitingSinceMs = null), t === "buffering" && e === "playing" ? (this.rebufferCount += 1, this.bufferingSinceMs = i, this.lastStallMs = i, this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(H, Math.round(this.playingTotalMs)))) : e === "buffering" && this.bufferingSinceMs !== null && (this.rebufferTotalMs += i - this.bufferingSinceMs, this.bufferingSinceMs = null), t === "paused" && (this.pauseCount += 1);
|
|
1445
1469
|
let a = {
|
|
1446
|
-
fromState:
|
|
1447
|
-
toState:
|
|
1448
|
-
presentation:
|
|
1470
|
+
fromState: G[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1471
|
+
toState: G[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1472
|
+
presentation: tt[this.presentation]
|
|
1449
1473
|
}, o = this.causeOf(e, t, i);
|
|
1450
1474
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
1451
1475
|
}
|
|
@@ -1480,16 +1504,16 @@ var nt = class {
|
|
|
1480
1504
|
}
|
|
1481
1505
|
this.muteChanges += 1;
|
|
1482
1506
|
let r = this.now();
|
|
1483
|
-
n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(
|
|
1507
|
+
n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(H, r - this.bornMs))), this.isMuted = n, this.syncActive();
|
|
1484
1508
|
}
|
|
1485
1509
|
notePresentation(e) {
|
|
1486
1510
|
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
1487
1511
|
}
|
|
1488
1512
|
noteReady() {
|
|
1489
|
-
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(
|
|
1513
|
+
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(H, this.now() - this.bornMs));
|
|
1490
1514
|
}
|
|
1491
1515
|
noteFirstBytes() {
|
|
1492
|
-
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(
|
|
1516
|
+
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(H, this.now() - this.bornMs));
|
|
1493
1517
|
}
|
|
1494
1518
|
noteSeek() {
|
|
1495
1519
|
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
@@ -1508,7 +1532,7 @@ var nt = class {
|
|
|
1508
1532
|
let r = n ?? "";
|
|
1509
1533
|
if (r !== "") return /^fragLoad/i.test(r) ? this.sawFirstBytes ? "ERROR_STAGE_SEGMENT" : "ERROR_STAGE_FIRST_SEGMENT" : /^(manifest|level|audioTrack|subtitleTrack)/i.test(r) ? "ERROR_STAGE_MANIFEST" : /key|licen[cs]e/i.test(r) ? "ERROR_STAGE_DRM" : /parsing|append|buffer|remux|decrypt|media/i.test(r) ? "ERROR_STAGE_DECODE" : "ERROR_STAGE_OTHER";
|
|
1510
1534
|
if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
|
|
1511
|
-
if (
|
|
1535
|
+
if (rt.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
1512
1536
|
let i = t ?? "";
|
|
1513
1537
|
return /frag|segment/i.test(i) ? this.sawFirstBytes ? "ERROR_STAGE_SEGMENT" : "ERROR_STAGE_FIRST_SEGMENT" : /manifest|level|playlist/i.test(i) ? "ERROR_STAGE_MANIFEST" : /key|licen[cs]e/i.test(i) ? "ERROR_STAGE_DRM" : /buffer|decode|media|append/i.test(i) ? "ERROR_STAGE_DECODE" : "ERROR_STAGE_OTHER";
|
|
1514
1538
|
}
|
|
@@ -1534,7 +1558,7 @@ var nt = class {
|
|
|
1534
1558
|
let s = e.droppedFrames ?? 0;
|
|
1535
1559
|
s > this.lastDropped && (i.droppedFramesDelta = s - this.lastDropped), this.lastDropped = s;
|
|
1536
1560
|
let c = e.renditionSwitches ?? 0;
|
|
1537
|
-
c > this.lastSwitches && (i.renditionSwitchesDelta = c - this.lastSwitches), this.lastSwitches = c, n > this.lastHbPlayingMs && (i.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (i.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, typeof e.latencySeconds == "number" && (i.latencyMs = Math.round(e.latencySeconds * 1e3)), typeof e.targetLatencySeconds == "number" && (i.targetLatencyMs = Math.round(e.targetLatencySeconds * 1e3)), typeof e.bandwidthKbps == "number" && (i.bandwidthEstKbps = e.bandwidthKbps), typeof e.levelHeight == "number" && (i.renditionHeight = e.levelHeight), typeof e.renditionBitrateKbps == "number" && (i.renditionBitrateKbps = e.renditionBitrateKbps), e.atLiveEdge === !0 && (i.atLiveEdge = !0), typeof e.bufferedMs == "number" && e.bufferedMs > 0 && (i.bufferedMs = Math.round(e.bufferedMs)), i.playerState =
|
|
1561
|
+
c > this.lastSwitches && (i.renditionSwitchesDelta = c - this.lastSwitches), this.lastSwitches = c, n > this.lastHbPlayingMs && (i.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (i.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, typeof e.latencySeconds == "number" && (i.latencyMs = Math.round(e.latencySeconds * 1e3)), typeof e.targetLatencySeconds == "number" && (i.targetLatencyMs = Math.round(e.targetLatencySeconds * 1e3)), typeof e.bandwidthKbps == "number" && (i.bandwidthEstKbps = e.bandwidthKbps), typeof e.levelHeight == "number" && (i.renditionHeight = e.levelHeight), typeof e.renditionBitrateKbps == "number" && (i.renditionBitrateKbps = e.renditionBitrateKbps), e.atLiveEdge === !0 && (i.atLiveEdge = !0), typeof e.bufferedMs == "number" && e.bufferedMs > 0 && (i.bufferedMs = Math.round(e.bufferedMs)), i.playerState = G[e.state] ?? "PLAYER_STATE_UNSPECIFIED";
|
|
1538
1562
|
let l = this.mutedTotalMs;
|
|
1539
1563
|
this.mutedSinceMs !== null && (l += t - this.mutedSinceMs), l > this.lastHbMutedMs && (i.mutedMsDelta = Math.round(l - this.lastHbMutedMs)), this.lastHbMutedMs = l;
|
|
1540
1564
|
let u = e.upshifts ?? 0;
|
|
@@ -1549,14 +1573,14 @@ var nt = class {
|
|
|
1549
1573
|
if (this.lastRequestCount = m, h > 0) {
|
|
1550
1574
|
i.requestCountDelta = h;
|
|
1551
1575
|
let t = e.requestTimesMs ?? [], n = t.slice(Math.max(0, t.length - h)).sort((e, t) => e - t);
|
|
1552
|
-
n.length > 0 && (i.requestTimeP50Ms =
|
|
1576
|
+
n.length > 0 && (i.requestTimeP50Ms = W(n, 50), i.requestTimeP95Ms = W(n, 95));
|
|
1553
1577
|
}
|
|
1554
1578
|
typeof e.latencySeconds == "number" && typeof e.targetLatencySeconds == "number" && (i.driftMs = Math.round((e.latencySeconds - e.targetLatencySeconds) * 1e3)), typeof e.playbackRate == "number" && e.playbackRate > 0 && (i.playbackRate = e.playbackRate), e.qualityPinned === !0 && (i.qualityPinned = !0), e.cdnHost && (i.cdnHost = e.cdnHost), this.maybeEmitMediaInfo(e), this.enqueue({ heartbeat: i }), this.flush(), a > 0 && this.noteFirstBytes();
|
|
1555
1579
|
}
|
|
1556
1580
|
maybeEmitMediaInfo(e) {
|
|
1557
1581
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
1558
1582
|
let t = {};
|
|
1559
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
1583
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = nt[e.keySystem]), e.drmSecurityLevel && (t.drmSecurityLevel = e.drmSecurityLevel), e.ladderHeights?.length && (t.ladderHeights = e.ladderHeights), e.ladderTopBitrateKbps && (t.ladderTopBitrateKbps = e.ladderTopBitrateKbps), e.lowLatency && (t.lowLatency = !0);
|
|
1560
1584
|
let n = JSON.stringify(t);
|
|
1561
1585
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
1562
1586
|
}
|
|
@@ -1576,7 +1600,7 @@ var nt = class {
|
|
|
1576
1600
|
let s = n?.positionMs ?? 0;
|
|
1577
1601
|
s > 0 && (r.exitPositionMs = Math.round(s)), this.activeTotalMs > 0 && (r.activeWatchTimeMs = Math.round(this.activeTotalMs)), this.mutedTotalMs > 0 && (r.mutedTimeMs = Math.round(this.mutedTotalMs));
|
|
1578
1602
|
let c = e !== "END_REASON_ENDED";
|
|
1579
|
-
c && this.lastStallMs > 0 && t - this.lastStallMs <=
|
|
1603
|
+
c && this.lastStallMs > 0 && t - this.lastStallMs <= U && (r.abandonAfterStallMs = Math.max(H, Math.round(t - this.lastStallMs))), c && this.lastErrorMs > 0 && t - this.lastErrorMs <= U && (r.abandonAfterErrorMs = Math.max(H, Math.round(t - this.lastErrorMs))), this.fullscreenTotalMs > 0 && (r.fullscreenTimeMs = Math.round(this.fullscreenTotalMs)), this.pipTotalMs > 0 && (r.pipTimeMs = Math.round(this.pipTotalMs)), this.volumeChanges > 0 && (r.volumeChanges = this.volumeChanges), this.muteChanges > 0 && (r.muteChanges = this.muteChanges);
|
|
1580
1604
|
let l = n?.decodedFrames ?? this.lastDecoded;
|
|
1581
1605
|
l > 0 && (r.decodedFramesTotal = l), this.startupTimeMs === 0 && (r.failedStage = this.lastErrorStage ?? (this.manifestLoadMs === 0 ? "ERROR_STAGE_MANIFEST" : this.firstFragLoadMs === 0 ? "ERROR_STAGE_FIRST_SEGMENT" : "ERROR_STAGE_OTHER")), this.pending.push(this.wrap({ sessionEnd: r })), this.flush(e === "END_REASON_PAGEHIDE");
|
|
1582
1606
|
}
|
|
@@ -1596,7 +1620,7 @@ var nt = class {
|
|
|
1596
1620
|
};
|
|
1597
1621
|
}
|
|
1598
1622
|
enqueue(e) {
|
|
1599
|
-
for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
1623
|
+
for (this.pending.push(this.wrap(e)); this.pending.length > $e;) {
|
|
1600
1624
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
1601
1625
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
1602
1626
|
}
|
|
@@ -1621,7 +1645,7 @@ var nt = class {
|
|
|
1621
1645
|
};
|
|
1622
1646
|
//#endregion
|
|
1623
1647
|
//#region src/core/environment.ts
|
|
1624
|
-
function
|
|
1648
|
+
function ot() {
|
|
1625
1649
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
1626
1650
|
let e;
|
|
1627
1651
|
try {
|
|
@@ -1646,14 +1670,14 @@ function rt() {
|
|
|
1646
1670
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
1647
1671
|
};
|
|
1648
1672
|
}
|
|
1649
|
-
function
|
|
1673
|
+
function st() {
|
|
1650
1674
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
1651
1675
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
1652
1676
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
1653
1677
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
1654
1678
|
return e?.mobile ?? (typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1 && n > 0 && n < 900) ? n >= 600 ? "DEVICE_CLASS_TABLET" : "DEVICE_CLASS_PHONE" : e || n >= 900 || /mac|win|linux|chrome os/i.test(t) ? "DEVICE_CLASS_DESKTOP" : "DEVICE_CLASS_OTHER";
|
|
1655
1679
|
}
|
|
1656
|
-
function
|
|
1680
|
+
function ct() {
|
|
1657
1681
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
1658
1682
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
1659
1683
|
let t = { connectionType: e.type ? {
|
|
@@ -1663,17 +1687,17 @@ function at() {
|
|
|
1663
1687
|
}[e.type] ?? "CONNECTION_TYPE_OTHER" : "CONNECTION_TYPE_UNKNOWN" };
|
|
1664
1688
|
return typeof e.downlink == "number" && e.downlink > 0 && (t.downlinkKbps = Math.round(e.downlink * 1e3)), e.saveData && (t.saveData = !0), t;
|
|
1665
1689
|
}
|
|
1666
|
-
function
|
|
1667
|
-
let t =
|
|
1668
|
-
deviceClass:
|
|
1690
|
+
function lt(e) {
|
|
1691
|
+
let t = ot(), n = {
|
|
1692
|
+
deviceClass: st(),
|
|
1669
1693
|
integration: t.integration,
|
|
1670
|
-
...
|
|
1694
|
+
...ct()
|
|
1671
1695
|
};
|
|
1672
1696
|
t.host && (n.host = t.host), typeof screen < "u" && screen.width > 0 && (n.screenWidth = screen.width, n.screenHeight = screen.height), typeof window < "u" && window.devicePixelRatio > 0 && (n.devicePixelRatio = Math.round(window.devicePixelRatio * 100) / 100);
|
|
1673
1697
|
let r = e.getBoundingClientRect?.();
|
|
1674
1698
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
1675
1699
|
}
|
|
1676
|
-
async function
|
|
1700
|
+
async function ut() {
|
|
1677
1701
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
1678
1702
|
if (!e?.getHighEntropyValues) return {};
|
|
1679
1703
|
try {
|
|
@@ -1685,7 +1709,7 @@ async function st() {
|
|
|
1685
1709
|
}
|
|
1686
1710
|
//#endregion
|
|
1687
1711
|
//#region src/core/version.ts
|
|
1688
|
-
var
|
|
1712
|
+
var dt = "2.1.1", K = {
|
|
1689
1713
|
accent: "#E1B600",
|
|
1690
1714
|
accentText: "#1B1C23",
|
|
1691
1715
|
background: "#0e0f13",
|
|
@@ -1696,7 +1720,7 @@ var ct = "2.1.0", G = {
|
|
|
1696
1720
|
border: "rgba(255, 255, 255, 0.1)",
|
|
1697
1721
|
radius: "8px",
|
|
1698
1722
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
1699
|
-
},
|
|
1723
|
+
}, q = {
|
|
1700
1724
|
accent: "--havik-accent",
|
|
1701
1725
|
accentText: "--havik-accent-text",
|
|
1702
1726
|
background: "--havik-bg",
|
|
@@ -1708,25 +1732,25 @@ var ct = "2.1.0", G = {
|
|
|
1708
1732
|
radius: "--havik-radius",
|
|
1709
1733
|
fontFamily: "--havik-font"
|
|
1710
1734
|
};
|
|
1711
|
-
function
|
|
1735
|
+
function J(e, t) {
|
|
1712
1736
|
let n = {
|
|
1713
|
-
...
|
|
1737
|
+
...K,
|
|
1714
1738
|
...t
|
|
1715
1739
|
};
|
|
1716
|
-
for (let t of Object.keys(
|
|
1740
|
+
for (let t of Object.keys(q)) e.style.setProperty(q[t], n[t]);
|
|
1717
1741
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
1718
1742
|
}
|
|
1719
1743
|
//#endregion
|
|
1720
1744
|
//#region src/ui/styles.ts
|
|
1721
|
-
var
|
|
1722
|
-
function
|
|
1723
|
-
if (e.getElementById(
|
|
1745
|
+
var Y = "havik-player-styles", ft = "\n.havik-player{position:relative;display:block;width:100%;background:var(--havik-bg,#0e0f13);\n color:var(--havik-text,#fff);font-family:var(--havik-font,system-ui,sans-serif);\n overflow:hidden;line-height:1.4;-webkit-tap-highlight-color:transparent}\n.havik-player video{display:block;width:100%;height:auto;aspect-ratio:16/9;\n object-fit:contain;background:#000;outline:none}\n.havik-player:focus{outline:none}\n.havik-player *{box-sizing:border-box}\n\n.havik-player:fullscreen,.havik-player:-webkit-full-screen{display:flex;align-items:center;\n justify-content:center;width:100vw;height:100vh;aspect-ratio:auto}\n.havik-player:fullscreen video,.havik-player:-webkit-full-screen video{width:100%;height:100%;\n aspect-ratio:auto;object-fit:contain}\n\n.havik-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer}\n.havik-gradient{position:absolute;left:0;right:0;bottom:0;height:120px;pointer-events:none;\n background:linear-gradient(to top,rgba(0,0,0,.78),transparent);\n opacity:1;transition:opacity .25s}\n.havik-player.havik-hide .havik-gradient,\n.havik-player.havik-hide .havik-bar{opacity:0;pointer-events:none}\n.havik-player.havik-hide{cursor:none}\n\n.havik-center{width:74px;height:74px;border-radius:50%;border:0;cursor:pointer;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);\n display:flex;align-items:center;justify-content:center;\n box-shadow:0 6px 24px rgba(0,0,0,.45);transition:transform .15s,opacity .15s}\n.havik-center:hover{transform:scale(1.06)}\n.havik-center svg{width:38px;height:38px;margin-left:2px}\n.havik-center.havik-gone{opacity:0;pointer-events:none;transform:scale(.8)}\n\n.havik-spinner{width:56px;height:56px;border-radius:50%;\n border:4px solid rgba(255,255,255,.2);border-top-color:var(--havik-accent,#E1B600);\n animation:havik-spin .8s linear infinite}\n@keyframes havik-spin{to{transform:rotate(360deg)}}\n\n/* Status card — branded full-bleed overlay for the stopped/pre-play states\n (ended / fatal error / pre-play / armed-waiting). */\n.havik-status{position:absolute;inset:0;display:flex;flex-direction:column;gap:16px;\n align-items:center;justify-content:center;background:rgba(14,15,19,.82);text-align:center;padding:24px}\n.havik-status__logo{width:128px;height:46px;background:var(--havik-logo) center/contain no-repeat;opacity:.95}\n.havik-status__msg{color:var(--havik-text,#fff);font-size:15px;font-weight:600;max-width:480px}\n.havik-status__btn{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;\n padding:10px 18px;border-radius:var(--havik-radius,8px);font-weight:700;font-size:14px;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);transition:transform .15s}\n.havik-status__btn:hover{transform:scale(1.04)}\n.havik-status__btn svg{width:18px;height:18px}\n/* Pre-play: lighter scrim so the poster shows through, and a round play CTA. */\n.havik-status--preplay{background:rgba(14,15,19,.4)}\n.havik-status--preplay .havik-status__btn--play{width:74px;height:74px;border-radius:50%;padding:0;\n justify-content:center;box-shadow:0 6px 24px rgba(0,0,0,.45)}\n.havik-status--preplay .havik-status__btn--play svg{width:38px;height:38px;margin-left:3px}\n\n.havik-watermark{position:absolute;top:12px;right:14px;height:22px;opacity:.85;pointer-events:none;\n content:'';background:var(--havik-logo) center/contain no-repeat;width:90px}\n/* A status card carries its own logo — the corner watermark would duplicate it. */\n.havik-player.havik-has-status .havik-watermark{display:none}\n\n.havik-bar{position:absolute;left:0;right:0;bottom:0;padding:0 12px 8px;\n opacity:1;transition:opacity .25s;z-index:2}\n.havik-seek{position:relative;height:16px;display:flex;align-items:center;cursor:pointer;margin-bottom:2px}\n.havik-seek__track{position:relative;width:100%;height:4px;border-radius:3px;background:rgba(255,255,255,.25)}\n.havik-seek__buffered{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:rgba(255,255,255,.4)}\n.havik-seek__played{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-seek__thumb{position:absolute;top:50%;width:13px;height:13px;border-radius:50%;\n background:var(--havik-accent,#E1B600);transform:translate(-50%,-50%) scale(0);transition:transform .1s}\n.havik-seek:hover .havik-seek__thumb{transform:translate(-50%,-50%) scale(1)}\n\n.havik-controls{display:flex;align-items:center;gap:6px;height:40px}\n.havik-spacer{flex:1}\n.havik-btn{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;border-radius:var(--havik-radius,8px);\n padding:0;transition:background .12s,color .12s}\n.havik-btn:hover{background:rgba(255,255,255,.12)}\n.havik-btn:focus-visible{outline:2px solid var(--havik-accent,#E1B600);outline-offset:1px}\n.havik-btn svg{width:22px;height:22px}\n\n/* The volume level is filled in accent up to the thumb, like the seek bar's\n played span — a native range input paints no \"elapsed\" side, which left the\n level readable only from the dot's position. --havik-vol (0..1) is set by\n syncVolume(); the track width and thumb size live here as variables because\n the WebKit fill has to compute the thumb centre from both. */\n.havik-vol{display:flex;align-items:center}\n.havik-vol__slider{--havik-vol-w:70px;--havik-vol-thumb:12px;--havik-vol:1;\n --havik-vol-pos:calc(var(--havik-vol-thumb) / 2 + var(--havik-vol) * (var(--havik-vol-w) - var(--havik-vol-thumb)));\n width:0;opacity:0;transition:width .18s,opacity .18s;height:4px;cursor:pointer;\n appearance:none;-webkit-appearance:none;background:transparent;border-radius:3px;margin:0 4px}\n.havik-vol:hover .havik-vol__slider,.havik-vol:focus-within .havik-vol__slider{width:var(--havik-vol-w);opacity:1}\n/* WebKit/Blink have no progress pseudo-element: paint the fill as a hard-stop\n gradient that ends at the thumb centre. */\n.havik-vol__slider::-webkit-slider-runnable-track{height:4px;border-radius:3px;\n background:linear-gradient(to right,var(--havik-accent,#E1B600) var(--havik-vol-pos),\n rgba(255,255,255,.3) var(--havik-vol-pos))}\n/* Firefox fills natively, and tracks the thumb exactly. */\n.havik-vol__slider::-moz-range-track{height:4px;border-radius:3px;background:rgba(255,255,255,.3)}\n.havik-vol__slider::-moz-range-progress{height:4px;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-vol__slider::-webkit-slider-thumb{-webkit-appearance:none;width:var(--havik-vol-thumb);\n height:var(--havik-vol-thumb);border-radius:50%;background:var(--havik-accent,#E1B600);\n margin-top:calc((4px - var(--havik-vol-thumb)) / 2)}\n.havik-vol__slider::-moz-range-thumb{width:var(--havik-vol-thumb);height:var(--havik-vol-thumb);\n border:0;border-radius:50%;background:var(--havik-accent,#E1B600)}\n\n.havik-time{font-size:12px;color:var(--havik-text-muted,#9aa0ad);\n font-variant-numeric:tabular-nums;padding:0 6px;white-space:nowrap}\n.havik-live{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;\n letter-spacing:.4px;padding:0 8px;color:var(--havik-text,#fff)}\n.havik-live svg{width:9px;height:9px;color:var(--havik-text-muted,#9aa0ad)}\n.havik-live.is-live svg{color:var(--havik-accent,#E1B600)}\n.havik-live__go{margin-left:2px;border:0;cursor:pointer;background:transparent;color:var(--havik-text-muted,#9aa0ad);\n font:inherit;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 6px;border-radius:6px}\n.havik-live.is-live .havik-live__go{display:none}\n.havik-live__go:hover{color:var(--havik-accent,#E1B600)}\n\n.havik-menu{position:absolute;bottom:54px;right:12px;min-width:170px;max-height:230px;overflow:auto;\n background:var(--havik-surface,#1B1C23);border:1px solid var(--havik-border,rgba(255,255,255,.1));\n border-radius:var(--havik-radius,8px);box-shadow:0 10px 30px rgba(0,0,0,.5);padding:6px;z-index:3}\n.havik-menu[hidden]{display:none}\n.havik-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;\n color:var(--havik-text-muted,#9aa0ad);padding:6px 8px 4px}\n.havik-menu__item{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;font:inherit;font-size:13px;\n text-align:left;padding:7px 8px;border-radius:6px}\n.havik-menu__item:hover{background:var(--havik-surface-muted,#2a2c36)}\n.havik-menu__item[aria-checked=\"true\"]{color:var(--havik-accent,#E1B600);font-weight:600}\n.havik-menu__item[aria-checked=\"true\"]::after{content:'✓'}\n";
|
|
1746
|
+
function pt(e = document) {
|
|
1747
|
+
if (e.getElementById(Y)) return;
|
|
1724
1748
|
let t = e.createElement("style");
|
|
1725
|
-
t.id =
|
|
1749
|
+
t.id = Y, t.textContent = ft, e.head.appendChild(t);
|
|
1726
1750
|
}
|
|
1727
1751
|
//#endregion
|
|
1728
1752
|
//#region src/ui/icons.ts
|
|
1729
|
-
var
|
|
1753
|
+
var mt = {
|
|
1730
1754
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
1731
1755
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
1732
1756
|
volumeHigh: "<path d=\"M3 10v4h4l5 5V5L7 10H3zm13.5 2a4.5 4.5 0 0 0-2.5-4v8a4.5 4.5 0 0 0 2.5-4zm-2.5-9v2.06A7 7 0 0 1 14 19v2a9 9 0 0 0 0-18z\"/>",
|
|
@@ -1739,21 +1763,21 @@ var dt = {
|
|
|
1739
1763
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
1740
1764
|
retry: "<path d=\"M17.65 6.35A8 8 0 1 0 19.73 13h-2.08A6 6 0 1 1 12 6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z\"/>"
|
|
1741
1765
|
};
|
|
1742
|
-
function
|
|
1743
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
1766
|
+
function X(e) {
|
|
1767
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${mt[e]}</svg>`;
|
|
1744
1768
|
}
|
|
1745
1769
|
//#endregion
|
|
1746
1770
|
//#region src/ui/controls.ts
|
|
1747
|
-
var
|
|
1771
|
+
var ht = 3e3, gt = /* @__PURE__ */ new Set([
|
|
1748
1772
|
"GONE",
|
|
1749
1773
|
"NOT_FOUND",
|
|
1750
1774
|
"INVALID_URN",
|
|
1751
1775
|
"UNAUTHORIZED"
|
|
1752
1776
|
]);
|
|
1753
|
-
function
|
|
1754
|
-
return new
|
|
1777
|
+
function _t(e) {
|
|
1778
|
+
return new vt(e);
|
|
1755
1779
|
}
|
|
1756
|
-
var
|
|
1780
|
+
var vt = class {
|
|
1757
1781
|
root;
|
|
1758
1782
|
video;
|
|
1759
1783
|
player;
|
|
@@ -1795,7 +1819,7 @@ var ht = class {
|
|
|
1795
1819
|
scrubbing = !1;
|
|
1796
1820
|
offFns = [];
|
|
1797
1821
|
constructor(e) {
|
|
1798
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
1822
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? ht, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, pt(this.doc), this.root.classList.add("havik-player"), this.root.hasAttribute("tabindex") || (this.root.tabIndex = 0), this.root.setAttribute("role", "region"), this.root.setAttribute("aria-label", "Video player");
|
|
1799
1823
|
let t = (e, t, n) => {
|
|
1800
1824
|
let r = this.doc.createElement(e);
|
|
1801
1825
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -1806,12 +1830,12 @@ var ht = class {
|
|
|
1806
1830
|
"aria-label": r,
|
|
1807
1831
|
title: r
|
|
1808
1832
|
});
|
|
1809
|
-
return i.innerHTML =
|
|
1833
|
+
return i.innerHTML = X(n), i;
|
|
1810
1834
|
};
|
|
1811
1835
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
1812
1836
|
type: "button",
|
|
1813
1837
|
"aria-label": "Play"
|
|
1814
|
-
}), this.center.innerHTML =
|
|
1838
|
+
}), this.center.innerHTML = X("play"), this.spinner = t("div", "havik-spinner"), this.spinner.style.display = "none", this.overlay.append(this.center, this.spinner), this.gradient = t("div", "havik-gradient"), this.bar = t("div", "havik-bar"), this.seek = t("div", "havik-seek", {
|
|
1815
1839
|
role: "slider",
|
|
1816
1840
|
"aria-label": "Seek",
|
|
1817
1841
|
"aria-valuemin": "0",
|
|
@@ -1829,7 +1853,7 @@ var ht = class {
|
|
|
1829
1853
|
"aria-label": "Volume"
|
|
1830
1854
|
});
|
|
1831
1855
|
let a = t("div", "havik-vol");
|
|
1832
|
-
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML =
|
|
1856
|
+
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = X("liveDot");
|
|
1833
1857
|
let o = this.doc.createElement("span");
|
|
1834
1858
|
o.textContent = "LIVE", this.liveGo = t("button", "havik-live__go", { type: "button" }), this.liveGo.textContent = "Go live", this.live.append(o, this.liveGo), this.time = t("div", "havik-time"), this.time.textContent = "0:00", this.time.style.display = "none";
|
|
1835
1859
|
let s = t("div", "havik-spacer");
|
|
@@ -1883,12 +1907,12 @@ var ht = class {
|
|
|
1883
1907
|
}
|
|
1884
1908
|
if (e === "preplay") {
|
|
1885
1909
|
let e = this.doc.createElement("button");
|
|
1886
|
-
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML =
|
|
1910
|
+
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = X("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
|
|
1887
1911
|
} else {
|
|
1888
1912
|
let r = this.doc.createElement("div");
|
|
1889
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
1913
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !gt.has(this.lastError.code)) {
|
|
1890
1914
|
let e = this.doc.createElement("button");
|
|
1891
|
-
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${
|
|
1915
|
+
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${X("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
|
|
1892
1916
|
}
|
|
1893
1917
|
}
|
|
1894
1918
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -1927,7 +1951,7 @@ var ht = class {
|
|
|
1927
1951
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
1928
1952
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
1929
1953
|
}
|
|
1930
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
1954
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Z(this.video.currentTime)} / ${Z(this.video.duration)}`);
|
|
1931
1955
|
}
|
|
1932
1956
|
syncLive() {
|
|
1933
1957
|
let e = this.player.getStats(), t = e.isLive !== !1;
|
|
@@ -1977,17 +2001,17 @@ var ht = class {
|
|
|
1977
2001
|
renderQualityMenu() {
|
|
1978
2002
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
1979
2003
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
1980
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
2004
|
+
for (let n of e) this.menu.append(this.menuItem(yt(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
1981
2005
|
}
|
|
1982
2006
|
renderAudioMenu() {
|
|
1983
2007
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
1984
2008
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
1985
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2009
|
+
for (let t of e) this.menu.append(this.menuItem(bt(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
1986
2010
|
}
|
|
1987
2011
|
renderCcMenu() {
|
|
1988
2012
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
1989
2013
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
1990
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2014
|
+
for (let t of e) this.menu.append(this.menuItem(xt(t), !1, () => this.player.setTextTrack(t.id)));
|
|
1991
2015
|
}
|
|
1992
2016
|
onTracksChanged() {
|
|
1993
2017
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -2007,11 +2031,11 @@ var ht = class {
|
|
|
2007
2031
|
}
|
|
2008
2032
|
async toggleFullscreen() {
|
|
2009
2033
|
try {
|
|
2010
|
-
|
|
2034
|
+
C(this.video, this.root) ? await T(this.video, this.root) : await w(this.video, this.root);
|
|
2011
2035
|
} catch {}
|
|
2012
2036
|
}
|
|
2013
2037
|
syncFullscreen() {
|
|
2014
|
-
let e =
|
|
2038
|
+
let e = C(this.video, this.root);
|
|
2015
2039
|
this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
|
|
2016
2040
|
}
|
|
2017
2041
|
poke() {
|
|
@@ -2070,7 +2094,7 @@ var ht = class {
|
|
|
2070
2094
|
}
|
|
2071
2095
|
}
|
|
2072
2096
|
setIcon(e, t) {
|
|
2073
|
-
e.innerHTML =
|
|
2097
|
+
e.innerHTML = X(t);
|
|
2074
2098
|
}
|
|
2075
2099
|
destroy() {
|
|
2076
2100
|
this.hideTimer && clearTimeout(this.hideTimer);
|
|
@@ -2087,32 +2111,32 @@ var ht = class {
|
|
|
2087
2111
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
2088
2112
|
}
|
|
2089
2113
|
};
|
|
2090
|
-
function
|
|
2114
|
+
function Z(e) {
|
|
2091
2115
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
2092
2116
|
let t = Math.floor(e % 60), n = Math.floor(e / 60 % 60), r = Math.floor(e / 3600), i = r > 0 ? String(n).padStart(2, "0") : String(n), a = String(t).padStart(2, "0");
|
|
2093
2117
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
2094
2118
|
}
|
|
2095
|
-
function
|
|
2119
|
+
function yt(e) {
|
|
2096
2120
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
2097
2121
|
}
|
|
2098
|
-
function
|
|
2122
|
+
function bt(e) {
|
|
2099
2123
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2100
2124
|
}
|
|
2101
|
-
function
|
|
2125
|
+
function xt(e) {
|
|
2102
2126
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2103
2127
|
}
|
|
2104
2128
|
//#endregion
|
|
2105
2129
|
//#region src/managed/index.ts
|
|
2106
|
-
var
|
|
2107
|
-
async function
|
|
2130
|
+
var St = 6e3, Q = 45e3, Ct = 2e3, wt = 3, Tt = 2e3, Et = 48e4;
|
|
2131
|
+
async function Dt(e) {
|
|
2108
2132
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
2109
2133
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: baseUrl is required");
|
|
2110
2134
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
2111
2135
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
2112
|
-
let t = new
|
|
2136
|
+
let t = new Ot(e);
|
|
2113
2137
|
return await t.start(), t;
|
|
2114
2138
|
}
|
|
2115
|
-
var
|
|
2139
|
+
var Ot = class {
|
|
2116
2140
|
opts;
|
|
2117
2141
|
abort = new AbortController();
|
|
2118
2142
|
listeners = {};
|
|
@@ -2178,7 +2202,7 @@ var wt = class {
|
|
|
2178
2202
|
};
|
|
2179
2203
|
}
|
|
2180
2204
|
beginArming(e, t, n = !1) {
|
|
2181
|
-
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ??
|
|
2205
|
+
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
|
|
2182
2206
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
2183
2207
|
}
|
|
2184
2208
|
beginArmingByPolling(e) {
|
|
@@ -2199,7 +2223,7 @@ var wt = class {
|
|
|
2199
2223
|
setTimeout(() => {
|
|
2200
2224
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
2201
2225
|
phase: i ? "unavailable" : "tooEarly",
|
|
2202
|
-
retryInMs:
|
|
2226
|
+
retryInMs: Q,
|
|
2203
2227
|
attempt: 1,
|
|
2204
2228
|
elapsedMs: 0,
|
|
2205
2229
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -2238,13 +2262,13 @@ var wt = class {
|
|
|
2238
2262
|
!a && !p() && h();
|
|
2239
2263
|
}, e);
|
|
2240
2264
|
};
|
|
2241
|
-
_(
|
|
2265
|
+
_(St), this.armingSub = E({
|
|
2242
2266
|
eventsBaseUrl: t,
|
|
2243
2267
|
matchUrn: this.opts.matchUrn,
|
|
2244
2268
|
credential: this.opts.credential,
|
|
2245
|
-
onAlive: () => _(
|
|
2269
|
+
onAlive: () => _(Q),
|
|
2246
2270
|
onState: (e) => {
|
|
2247
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
2271
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Ct);
|
|
2248
2272
|
},
|
|
2249
2273
|
onError: () => h()
|
|
2250
2274
|
});
|
|
@@ -2267,7 +2291,7 @@ var wt = class {
|
|
|
2267
2291
|
let n = await s(this.opts.credential);
|
|
2268
2292
|
if (this.destroyed || t !== this.loadGen) return;
|
|
2269
2293
|
this.setState("loading");
|
|
2270
|
-
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a =
|
|
2294
|
+
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = Oe(this.opts.video, (e) => {
|
|
2271
2295
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
2272
2296
|
});
|
|
2273
2297
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -2286,17 +2310,17 @@ var wt = class {
|
|
|
2286
2310
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
2287
2311
|
let r = e.analytics?.sid;
|
|
2288
2312
|
if (!r) return;
|
|
2289
|
-
let i = (typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0) ??
|
|
2313
|
+
let i = (typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0) ?? it(this.opts.baseUrl);
|
|
2290
2314
|
if (!i) return;
|
|
2291
|
-
let a = this.opts.video, o = new
|
|
2315
|
+
let a = this.opts.video, o = new at({
|
|
2292
2316
|
endpoint: i,
|
|
2293
2317
|
sid: r,
|
|
2294
2318
|
apiKey: n,
|
|
2295
2319
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
2296
|
-
sdkVersion:
|
|
2297
|
-
environment:
|
|
2320
|
+
sdkVersion: dt,
|
|
2321
|
+
environment: lt(a),
|
|
2298
2322
|
sample: () => {
|
|
2299
|
-
let e = this.engine?.getStats() ??
|
|
2323
|
+
let e = this.engine?.getStats() ?? F, t = a.buffered.length ? Math.max(0, a.buffered.end(a.buffered.length - 1) - a.currentTime) : 0;
|
|
2300
2324
|
return {
|
|
2301
2325
|
...e,
|
|
2302
2326
|
bufferedMs: Math.round(t * 1e3),
|
|
@@ -2310,7 +2334,7 @@ var wt = class {
|
|
|
2310
2334
|
let s = () => o.noteSeek(), c = () => o.noteVolume(a.muted, a.volume);
|
|
2311
2335
|
a.addEventListener("seeking", s), a.addEventListener("volumechange", c), this.detachMediaListeners = () => {
|
|
2312
2336
|
a.removeEventListener("seeking", s), a.removeEventListener("volumechange", c);
|
|
2313
|
-
}, o.start(), o.seedVolume(a.muted, a.volume), o.notePresentation(this.currentPresentation()),
|
|
2337
|
+
}, o.start(), o.seedVolume(a.muted, a.volume), o.notePresentation(this.currentPresentation()), ut().then((e) => o.noteEnvironment(e)), this.opts.autoplay === !1 && o.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
2314
2338
|
}
|
|
2315
2339
|
currentPresentation() {
|
|
2316
2340
|
let e = this.opts.video;
|
|
@@ -2325,7 +2349,7 @@ var wt = class {
|
|
|
2325
2349
|
video: this.opts.video,
|
|
2326
2350
|
descriptor: e,
|
|
2327
2351
|
credential: t,
|
|
2328
|
-
deviceId:
|
|
2352
|
+
deviceId: A(),
|
|
2329
2353
|
userId: this.opts.userId,
|
|
2330
2354
|
lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
|
|
2331
2355
|
snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
|
|
@@ -2334,11 +2358,11 @@ var wt = class {
|
|
|
2334
2358
|
hlsConfig: i,
|
|
2335
2359
|
emit: (e) => this.onEngineEvent(e)
|
|
2336
2360
|
}, o = this.opts.engine ?? "auto";
|
|
2337
|
-
if (o === "native") return new
|
|
2338
|
-
if (o === "hls") return new
|
|
2339
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl &&
|
|
2340
|
-
if (
|
|
2341
|
-
if (
|
|
2361
|
+
if (o === "native") return new z(a);
|
|
2362
|
+
if (o === "hls") return new V(a);
|
|
2363
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && L(this.opts.video) && R()) return new z(a);
|
|
2364
|
+
if (je()) return new V(a);
|
|
2365
|
+
if (L(this.opts.video)) return new z(a);
|
|
2342
2366
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
2343
2367
|
}
|
|
2344
2368
|
onEngineEvent(e) {
|
|
@@ -2366,11 +2390,11 @@ var wt = class {
|
|
|
2366
2390
|
}
|
|
2367
2391
|
startLiveState(e) {
|
|
2368
2392
|
if (this.opts.liveStateEvents === !1) return;
|
|
2369
|
-
let t = this.opts.eventsBaseUrl ??
|
|
2393
|
+
let t = this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
|
|
2370
2394
|
if (!t) return;
|
|
2371
2395
|
this.closeLiveState();
|
|
2372
2396
|
let r = 0, i = !1;
|
|
2373
|
-
this.liveStateSub =
|
|
2397
|
+
this.liveStateSub = E({
|
|
2374
2398
|
eventsBaseUrl: t,
|
|
2375
2399
|
matchUrn: this.opts.matchUrn,
|
|
2376
2400
|
credential: this.opts.credential,
|
|
@@ -2381,7 +2405,7 @@ var wt = class {
|
|
|
2381
2405
|
r = 0, i = !1;
|
|
2382
2406
|
},
|
|
2383
2407
|
onError: () => {
|
|
2384
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
2408
|
+
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= wt && (i = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${r} attempts — end-of-stream detection degraded to the HLS staleness watchdog. Check the events host, the api-key's allowed origins, and CSP connect-src.`))));
|
|
2385
2409
|
}
|
|
2386
2410
|
});
|
|
2387
2411
|
}
|
|
@@ -2403,7 +2427,7 @@ var wt = class {
|
|
|
2403
2427
|
scheduleRejoin(e) {
|
|
2404
2428
|
!this.rejoinEnabled() || this.rejoinTimer || (this.rejoinTimer = setTimeout(() => {
|
|
2405
2429
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
2406
|
-
}, Math.random() *
|
|
2430
|
+
}, Math.random() * Ct));
|
|
2407
2431
|
}
|
|
2408
2432
|
cancelRejoin() {
|
|
2409
2433
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -2427,7 +2451,7 @@ var wt = class {
|
|
|
2427
2451
|
}
|
|
2428
2452
|
t.controls = !1;
|
|
2429
2453
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
2430
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
2454
|
+
r && r.insertBefore(n, t), n.appendChild(t), J(n, this.opts.theme), this.container = n, this.controlBar = _t({
|
|
2431
2455
|
root: n,
|
|
2432
2456
|
video: t,
|
|
2433
2457
|
player: this,
|
|
@@ -2457,7 +2481,7 @@ var wt = class {
|
|
|
2457
2481
|
}
|
|
2458
2482
|
startStats() {
|
|
2459
2483
|
this.stopStats();
|
|
2460
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
2484
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Tt);
|
|
2461
2485
|
this.statsTimer = setInterval(() => {
|
|
2462
2486
|
if (!this.engine) return;
|
|
2463
2487
|
let e = this.engine.getStats();
|
|
@@ -2469,7 +2493,7 @@ var wt = class {
|
|
|
2469
2493
|
}
|
|
2470
2494
|
scheduleLicenseRefresh() {
|
|
2471
2495
|
this.stopRefresh();
|
|
2472
|
-
let e = this.opts.licenseRefreshMs ??
|
|
2496
|
+
let e = this.opts.licenseRefreshMs ?? Et;
|
|
2473
2497
|
!e || !this._descriptor?.drmEnabled || (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
2474
2498
|
}
|
|
2475
2499
|
stopRefresh() {
|
|
@@ -2511,7 +2535,7 @@ var wt = class {
|
|
|
2511
2535
|
this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
|
|
2512
2536
|
}
|
|
2513
2537
|
getStats() {
|
|
2514
|
-
return this.engine?.getStats() ??
|
|
2538
|
+
return this.engine?.getStats() ?? F;
|
|
2515
2539
|
}
|
|
2516
2540
|
getQualityLevels() {
|
|
2517
2541
|
return this.engine?.getQualityLevels() ?? [];
|
|
@@ -2550,10 +2574,10 @@ var wt = class {
|
|
|
2550
2574
|
e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
|
|
2551
2575
|
}
|
|
2552
2576
|
async enterFullscreen() {
|
|
2553
|
-
return !this.destroyed &&
|
|
2577
|
+
return !this.destroyed && w(this.opts.video, this.container ?? void 0);
|
|
2554
2578
|
}
|
|
2555
2579
|
async exitFullscreen() {
|
|
2556
|
-
await
|
|
2580
|
+
await T(this.opts.video, this.container ?? void 0);
|
|
2557
2581
|
}
|
|
2558
2582
|
retry() {
|
|
2559
2583
|
return this.reload();
|
|
@@ -2621,7 +2645,7 @@ function $(e) {
|
|
|
2621
2645
|
}
|
|
2622
2646
|
//#endregion
|
|
2623
2647
|
//#region src/embed/host.ts
|
|
2624
|
-
function
|
|
2648
|
+
function kt(e) {
|
|
2625
2649
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
2626
2650
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
2627
2651
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -2680,8 +2704,8 @@ function Tt(e) {
|
|
|
2680
2704
|
}
|
|
2681
2705
|
//#endregion
|
|
2682
2706
|
//#region src/embed/page.ts
|
|
2683
|
-
var
|
|
2684
|
-
function
|
|
2707
|
+
var At = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
2708
|
+
function jt() {
|
|
2685
2709
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
2686
2710
|
if (e) return {
|
|
2687
2711
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -2703,9 +2727,9 @@ function Dt() {
|
|
|
2703
2727
|
waitForLive: !0
|
|
2704
2728
|
};
|
|
2705
2729
|
}
|
|
2706
|
-
async function
|
|
2707
|
-
let e =
|
|
2708
|
-
|
|
2730
|
+
async function Mt() {
|
|
2731
|
+
let e = jt();
|
|
2732
|
+
Pt();
|
|
2709
2733
|
let t = document.createElement("video");
|
|
2710
2734
|
t.setAttribute("playsinline", ""), t.muted = e.muted ?? !0, t.style.cssText = "width:100%;height:100%;object-fit:contain;background:#000;aspect-ratio:auto", document.body.appendChild(t);
|
|
2711
2735
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -2760,12 +2784,12 @@ async function Ot() {
|
|
|
2760
2784
|
code: e.code,
|
|
2761
2785
|
message: e.message
|
|
2762
2786
|
})), e.on("autoplayblocked", () => {
|
|
2763
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
2787
|
+
i({ type: "oddin:autoplayblocked" }), Nt(t, e);
|
|
2764
2788
|
});
|
|
2765
2789
|
}, s = async (r) => {
|
|
2766
2790
|
a?.destroy(), a = null;
|
|
2767
2791
|
try {
|
|
2768
|
-
let n = await
|
|
2792
|
+
let n = await Dt({
|
|
2769
2793
|
video: t,
|
|
2770
2794
|
baseUrl: e.baseUrl,
|
|
2771
2795
|
matchUrn: r,
|
|
@@ -2826,7 +2850,7 @@ async function Ot() {
|
|
|
2826
2850
|
a?.retry();
|
|
2827
2851
|
break;
|
|
2828
2852
|
case "oddin:load":
|
|
2829
|
-
typeof e.matchUrn == "string" &&
|
|
2853
|
+
typeof e.matchUrn == "string" && At.test(e.matchUrn) && s(e.matchUrn);
|
|
2830
2854
|
break;
|
|
2831
2855
|
case "oddin:destroy": c();
|
|
2832
2856
|
}
|
|
@@ -2838,18 +2862,18 @@ async function Ot() {
|
|
|
2838
2862
|
protocol: 1
|
|
2839
2863
|
});
|
|
2840
2864
|
}
|
|
2841
|
-
function
|
|
2865
|
+
function Nt(e, t) {
|
|
2842
2866
|
if (document.getElementById("havik-tap")) return;
|
|
2843
2867
|
let n = document.createElement("button");
|
|
2844
2868
|
n.id = "havik-tap", n.textContent = "▶ Tap to play", n.style.cssText = "position:fixed;inset:0;width:100%;height:100%;border:0;background:rgba(0,0,0,.55);color:#fff;font:600 18px system-ui,sans-serif;cursor:pointer;z-index:9", n.addEventListener("click", () => {
|
|
2845
2869
|
n.remove(), t.play();
|
|
2846
2870
|
}), document.body.appendChild(n);
|
|
2847
2871
|
}
|
|
2848
|
-
function
|
|
2872
|
+
function Pt() {
|
|
2849
2873
|
let e = document.createElement("style");
|
|
2850
2874
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
2851
2875
|
}
|
|
2852
2876
|
//#endregion
|
|
2853
|
-
export {
|
|
2877
|
+
export { K as ODDIN_THEME, n as PlaybackError, J as applyTheme, Mt as bootEmbed, ge as clearDeviceId, Dt as createPlayer, D as deriveEventsBaseUrl, Se as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ue as fetchCatalog, fe as fetchTournament, me as flattenMatches, A as getDeviceId, we as isLowLatencyManifest, $ as isOddinMessage, ve as licenseRequestHeaders, kt as mountEmbed, v as pollToLive, b as resolveStream, E as subscribeLiveState, C as videoFullscreenActive, he as watchStatus };
|
|
2854
2878
|
|
|
2855
2879
|
//# sourceMappingURL=index.js.map
|