@oddin-gg/havik-player 2.27.1 → 2.27.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/havik-player.global.js +2 -2
- package/dist/havik-player.global.js.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +338 -331
- 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
|
@@ -315,25 +315,25 @@ function x(e) {
|
|
|
315
315
|
function _e(e) {
|
|
316
316
|
return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
|
|
317
317
|
}
|
|
318
|
-
function
|
|
318
|
+
function S(e, t) {
|
|
319
319
|
let n = _e(x(e));
|
|
320
320
|
return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
|
|
321
321
|
}
|
|
322
|
-
function
|
|
322
|
+
function C(e, t) {
|
|
323
323
|
let n = t ?? e, r = x(e);
|
|
324
324
|
if (typeof n.requestFullscreen == "function") return r.fullscreenEnabled !== !1;
|
|
325
325
|
if (typeof n.webkitRequestFullscreen == "function") return r.webkitFullscreenEnabled !== !1;
|
|
326
326
|
let i = e;
|
|
327
327
|
return i.webkitSupportsFullscreen === !0 && typeof i.webkitEnterFullscreen == "function" || e.readyState < 1;
|
|
328
328
|
}
|
|
329
|
-
async function
|
|
329
|
+
async function w(e, t) {
|
|
330
330
|
let n = t ?? e;
|
|
331
331
|
if (typeof n.requestFullscreen == "function") return await n.requestFullscreen(), !0;
|
|
332
332
|
if (typeof n.webkitRequestFullscreen == "function") return n.webkitRequestFullscreen(), !0;
|
|
333
333
|
let r = e;
|
|
334
334
|
return r.webkitSupportsFullscreen && typeof r.webkitEnterFullscreen == "function" ? (r.webkitEnterFullscreen(), !0) : !1;
|
|
335
335
|
}
|
|
336
|
-
async function
|
|
336
|
+
async function T(e, t) {
|
|
337
337
|
let n = e;
|
|
338
338
|
if (n.webkitDisplayingFullscreen) {
|
|
339
339
|
n.webkitExitFullscreen?.();
|
|
@@ -344,7 +344,7 @@ async function w(e, t) {
|
|
|
344
344
|
}
|
|
345
345
|
//#endregion
|
|
346
346
|
//#region src/core/catalog.ts
|
|
347
|
-
async function
|
|
347
|
+
async function ve(e) {
|
|
348
348
|
let t = new URLSearchParams();
|
|
349
349
|
e.status && t.set("status", Array.isArray(e.status) ? e.status.join(",") : e.status), e.sport && t.set("sport", e.sport);
|
|
350
350
|
let i = t.toString(), a = f(e.baseUrl, "/v1/catalog" + (i ? `?${i}` : "")), o = new Headers();
|
|
@@ -362,12 +362,12 @@ async function ye(e) {
|
|
|
362
362
|
};
|
|
363
363
|
if (!s.ok) throw new n(r(s.status), s.status, `catalog request failed (HTTP ${s.status})`);
|
|
364
364
|
return {
|
|
365
|
-
tournaments:
|
|
365
|
+
tournaments: ye(await s.json()),
|
|
366
366
|
etag: s.headers.get("etag") ?? void 0,
|
|
367
367
|
notModified: !1
|
|
368
368
|
};
|
|
369
369
|
}
|
|
370
|
-
function
|
|
370
|
+
function ye(e) {
|
|
371
371
|
return (e.tournaments ?? []).map((e) => {
|
|
372
372
|
let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
|
|
373
373
|
return {
|
|
@@ -389,7 +389,7 @@ function be(e) {
|
|
|
389
389
|
};
|
|
390
390
|
});
|
|
391
391
|
}
|
|
392
|
-
async function
|
|
392
|
+
async function be(e) {
|
|
393
393
|
let t = f(e.baseUrl, `/v1/tournaments/${encodeURIComponent(e.urn)}`), i = new Headers();
|
|
394
394
|
e.etag && i.set("If-None-Match", e.etag);
|
|
395
395
|
let a = await m(t, {
|
|
@@ -409,13 +409,13 @@ async function xe(e) {
|
|
|
409
409
|
};
|
|
410
410
|
if (!a.ok) throw new n(r(a.status), a.status, `tournament request failed (HTTP ${a.status})`);
|
|
411
411
|
return {
|
|
412
|
-
tournament:
|
|
412
|
+
tournament: xe(await a.json()),
|
|
413
413
|
etag: a.headers.get("etag") ?? void 0,
|
|
414
414
|
notModified: !1,
|
|
415
415
|
notFound: !1
|
|
416
416
|
};
|
|
417
417
|
}
|
|
418
|
-
function
|
|
418
|
+
function xe(e) {
|
|
419
419
|
let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
|
|
420
420
|
return {
|
|
421
421
|
urn: t,
|
|
@@ -435,18 +435,18 @@ function Se(e) {
|
|
|
435
435
|
}))
|
|
436
436
|
};
|
|
437
437
|
}
|
|
438
|
-
function
|
|
438
|
+
function Se(e) {
|
|
439
439
|
return e.tournaments.flatMap((e) => e.matches);
|
|
440
440
|
}
|
|
441
441
|
//#endregion
|
|
442
442
|
//#region src/core/poll.ts
|
|
443
|
-
var
|
|
443
|
+
var Ce = /* @__PURE__ */ new Set([
|
|
444
444
|
"NOT_FOUND",
|
|
445
445
|
"GEO_DENIED",
|
|
446
446
|
"GONE",
|
|
447
447
|
"INVALID_URN"
|
|
448
448
|
]);
|
|
449
|
-
function
|
|
449
|
+
function we(e) {
|
|
450
450
|
let t = Math.max(2e3, e.intervalMs ?? 1e4), i = new AbortController(), a, o, s, c = !1, d = () => {
|
|
451
451
|
c || (a = setTimeout(p, t));
|
|
452
452
|
}, p = async () => {
|
|
@@ -479,7 +479,7 @@ function Te(e) {
|
|
|
479
479
|
} catch (t) {
|
|
480
480
|
if (!i.signal.aborted) {
|
|
481
481
|
let r = t instanceof n ? t : new n("NETWORK", 0, String(t));
|
|
482
|
-
|
|
482
|
+
Ce.has(r.code) && (c = !0), e.onError?.(r);
|
|
483
483
|
}
|
|
484
484
|
} finally {
|
|
485
485
|
d();
|
|
@@ -491,16 +491,16 @@ function Te(e) {
|
|
|
491
491
|
}
|
|
492
492
|
//#endregion
|
|
493
493
|
//#region src/core/events.ts
|
|
494
|
-
var
|
|
494
|
+
var Te = 45e3, E = class extends Error {
|
|
495
495
|
status;
|
|
496
496
|
terminal;
|
|
497
497
|
constructor(e) {
|
|
498
498
|
let t = e === 410;
|
|
499
499
|
super(t ? `live-state subscribe failed: HTTP ${e} — match is gone, not retrying` : e === 404 ? `live-state subscribe failed: HTTP ${e} — match not in the catalog, retrying slowly` : `live-state subscribe failed: HTTP ${e}`), this.name = "LiveStateHttpError", this.status = e, this.terminal = t;
|
|
500
500
|
}
|
|
501
|
-
},
|
|
502
|
-
function
|
|
503
|
-
let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = Math.max(t, e.notFoundRetryMs ??
|
|
501
|
+
}, Ee = 3e5;
|
|
502
|
+
function D(e) {
|
|
503
|
+
let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = Math.max(t, e.notFoundRetryMs ?? Ee), i = e.idleTimeoutMs ?? Te, a = Number.isFinite(i) && i > 0 ? i : 0, o = new AbortController(), s = !1, l = (e) => new Promise((t) => {
|
|
504
504
|
if (o.signal.aborted) return t();
|
|
505
505
|
let n = setTimeout(t, e);
|
|
506
506
|
o.signal.addEventListener("abort", () => {
|
|
@@ -567,7 +567,7 @@ function E(e) {
|
|
|
567
567
|
});
|
|
568
568
|
if (clearTimeout(_), s) return;
|
|
569
569
|
if (!o.ok || !o.body) {
|
|
570
|
-
let t = new
|
|
570
|
+
let t = new E(o.status);
|
|
571
571
|
h = t.terminal, g = o.status === 404, e.onError?.(t);
|
|
572
572
|
} else await p(o.body, () => {
|
|
573
573
|
i = t;
|
|
@@ -585,7 +585,7 @@ function E(e) {
|
|
|
585
585
|
s || (s = !0, o.abort());
|
|
586
586
|
} };
|
|
587
587
|
}
|
|
588
|
-
function
|
|
588
|
+
function O(e) {
|
|
589
589
|
try {
|
|
590
590
|
let t = new URL(e);
|
|
591
591
|
return t.hostname = `events.${t.hostname}`, t.pathname = "", t.search = "", t.origin;
|
|
@@ -595,27 +595,27 @@ function D(e) {
|
|
|
595
595
|
}
|
|
596
596
|
//#endregion
|
|
597
597
|
//#region src/core/drm/deviceId.ts
|
|
598
|
-
var
|
|
599
|
-
function
|
|
598
|
+
var De = "havik.player.deviceId", k;
|
|
599
|
+
function Oe() {
|
|
600
600
|
if (k) return k;
|
|
601
601
|
try {
|
|
602
|
-
let e = globalThis.localStorage?.getItem(
|
|
602
|
+
let e = globalThis.localStorage?.getItem(De);
|
|
603
603
|
if (e) return k = e, e;
|
|
604
604
|
} catch {}
|
|
605
|
-
let e =
|
|
605
|
+
let e = Ae();
|
|
606
606
|
k = e;
|
|
607
607
|
try {
|
|
608
|
-
globalThis.localStorage?.setItem(
|
|
608
|
+
globalThis.localStorage?.setItem(De, e);
|
|
609
609
|
} catch {}
|
|
610
610
|
return e;
|
|
611
611
|
}
|
|
612
|
-
function
|
|
612
|
+
function ke() {
|
|
613
613
|
k = void 0;
|
|
614
614
|
try {
|
|
615
|
-
globalThis.localStorage?.removeItem(
|
|
615
|
+
globalThis.localStorage?.removeItem(De);
|
|
616
616
|
} catch {}
|
|
617
617
|
}
|
|
618
|
-
function
|
|
618
|
+
function Ae() {
|
|
619
619
|
let e = globalThis.crypto;
|
|
620
620
|
if (e && typeof e.randomUUID == "function") return e.randomUUID();
|
|
621
621
|
let t = /* @__PURE__ */ new Uint8Array(16);
|
|
@@ -627,32 +627,32 @@ function ke() {
|
|
|
627
627
|
}
|
|
628
628
|
//#endregion
|
|
629
629
|
//#region src/core/drm/headers.ts
|
|
630
|
-
function
|
|
630
|
+
function je(e, t, n = {}) {
|
|
631
631
|
let r = {
|
|
632
632
|
"x-api-key": t.apiKey,
|
|
633
633
|
"X-Match-Urn": e.matchUrn,
|
|
634
|
-
"X-Device-Id": n.deviceId ??
|
|
634
|
+
"X-Device-Id": n.deviceId ?? Oe(),
|
|
635
635
|
"Content-Type": "application/octet-stream"
|
|
636
636
|
};
|
|
637
637
|
return n.userId && (r["X-User-Id"] = n.userId), r;
|
|
638
638
|
}
|
|
639
639
|
//#endregion
|
|
640
640
|
//#region src/core/bandwidthMemory.ts
|
|
641
|
-
var
|
|
642
|
-
function
|
|
641
|
+
var Me = "havik.player.bandwidth", Ne = .8, Pe = 2e7, Fe = 3e5;
|
|
642
|
+
function Ie() {
|
|
643
643
|
return globalThis.navigator?.connection;
|
|
644
644
|
}
|
|
645
|
-
function
|
|
646
|
-
let e =
|
|
645
|
+
function Le() {
|
|
646
|
+
let e = Ie()?.type;
|
|
647
647
|
return typeof e == "string" && e !== "" && e !== "unknown" ? e : "any";
|
|
648
648
|
}
|
|
649
|
-
function
|
|
650
|
-
let e =
|
|
649
|
+
function Re() {
|
|
650
|
+
let e = Ie()?.downlink;
|
|
651
651
|
return typeof e == "number" && Number.isFinite(e) && e > 0 ? e * 1e6 : void 0;
|
|
652
652
|
}
|
|
653
|
-
function
|
|
653
|
+
function ze() {
|
|
654
654
|
try {
|
|
655
|
-
let e = globalThis.localStorage?.getItem(
|
|
655
|
+
let e = globalThis.localStorage?.getItem(Me);
|
|
656
656
|
if (!e) return {};
|
|
657
657
|
let t = JSON.parse(e);
|
|
658
658
|
return t && typeof t == "object" && !Array.isArray(t) ? t : {};
|
|
@@ -660,36 +660,36 @@ function Le() {
|
|
|
660
660
|
return {};
|
|
661
661
|
}
|
|
662
662
|
}
|
|
663
|
-
function
|
|
664
|
-
let t =
|
|
663
|
+
function Be(e = Date.now()) {
|
|
664
|
+
let t = ze()[Le()];
|
|
665
665
|
if (!t || typeof t.bps != "number" || typeof t.at != "number" || !Number.isFinite(t.bps) || t.bps <= 0) return;
|
|
666
666
|
let n = e - t.at;
|
|
667
667
|
if (n < 0 || n > 2592e5) return;
|
|
668
|
-
let r =
|
|
669
|
-
return Math.round(Math.min(
|
|
668
|
+
let r = Re(), i = r === void 0 ? t.bps : Math.min(t.bps, r);
|
|
669
|
+
return Math.round(Math.min(Pe, Math.max(Fe, i * Ne)));
|
|
670
670
|
}
|
|
671
|
-
function
|
|
671
|
+
function Ve(e, t = Date.now()) {
|
|
672
672
|
if (!Number.isFinite(e) || e <= 0) return;
|
|
673
|
-
let n =
|
|
674
|
-
n[
|
|
673
|
+
let n = ze();
|
|
674
|
+
n[Le()] = {
|
|
675
675
|
bps: Math.round(e),
|
|
676
676
|
at: t
|
|
677
677
|
};
|
|
678
678
|
try {
|
|
679
|
-
globalThis.localStorage?.setItem(
|
|
679
|
+
globalThis.localStorage?.setItem(Me, JSON.stringify(n));
|
|
680
680
|
} catch {}
|
|
681
681
|
}
|
|
682
|
-
function
|
|
682
|
+
function He() {
|
|
683
683
|
try {
|
|
684
|
-
globalThis.localStorage?.removeItem(
|
|
684
|
+
globalThis.localStorage?.removeItem(Me);
|
|
685
685
|
} catch {}
|
|
686
686
|
}
|
|
687
687
|
//#endregion
|
|
688
688
|
//#region src/core/drm/cdm.ts
|
|
689
|
-
var
|
|
690
|
-
function
|
|
691
|
-
let n =
|
|
692
|
-
n || (n = /* @__PURE__ */ new Map(),
|
|
689
|
+
var Ue = /* @__PURE__ */ new WeakMap();
|
|
690
|
+
function We(e, t) {
|
|
691
|
+
let n = Ue.get(e);
|
|
692
|
+
n || (n = /* @__PURE__ */ new Map(), Ue.set(e, n));
|
|
693
693
|
let r = n.get(t.keySystem);
|
|
694
694
|
if (r) return r;
|
|
695
695
|
let i = t.createMediaKeys().catch((e) => {
|
|
@@ -697,22 +697,22 @@ function He(e, t) {
|
|
|
697
697
|
});
|
|
698
698
|
return n.set(t.keySystem, i), i;
|
|
699
699
|
}
|
|
700
|
-
function
|
|
700
|
+
function A() {
|
|
701
701
|
return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
|
|
702
702
|
}
|
|
703
|
-
var
|
|
704
|
-
function
|
|
703
|
+
var j = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
|
|
704
|
+
function Ge(e) {
|
|
705
705
|
return e.startsWith("com.widevine");
|
|
706
706
|
}
|
|
707
|
-
function
|
|
708
|
-
if (!
|
|
707
|
+
function M(e, t) {
|
|
708
|
+
if (!Ge(e)) return t;
|
|
709
709
|
let n = (e, t) => {
|
|
710
710
|
let n = e.videoCapabilities;
|
|
711
711
|
return !n?.length || !n.some((e) => e.robustness) ? !1 : n.every((e) => {
|
|
712
|
-
let n =
|
|
713
|
-
return n === -1 ||
|
|
712
|
+
let n = j.indexOf(e.robustness);
|
|
713
|
+
return n === -1 || j.indexOf(t) > n;
|
|
714
714
|
});
|
|
715
|
-
}, r =
|
|
715
|
+
}, r = j.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
|
|
716
716
|
...t,
|
|
717
717
|
videoCapabilities: t.videoCapabilities?.map((t) => ({
|
|
718
718
|
...t,
|
|
@@ -722,10 +722,10 @@ function Ge(e, t) {
|
|
|
722
722
|
return [...t, ...r];
|
|
723
723
|
}
|
|
724
724
|
function Ke(e) {
|
|
725
|
-
return (t, n) =>
|
|
725
|
+
return (t, n) => A() ? navigator.requestMediaKeySystemAccess(t, M(t, n)).then((t) => ({
|
|
726
726
|
keySystem: t.keySystem,
|
|
727
727
|
getConfiguration: () => t.getConfiguration(),
|
|
728
|
-
createMediaKeys: () =>
|
|
728
|
+
createMediaKeys: () => We(e, t)
|
|
729
729
|
})) : Promise.reject(/* @__PURE__ */ Error("navigator.requestMediaKeySystemAccess is unavailable — EME needs a secure context (https, or localhost)"));
|
|
730
730
|
}
|
|
731
731
|
var N = {
|
|
@@ -734,7 +734,7 @@ var N = {
|
|
|
734
734
|
scheme: "cbcs"
|
|
735
735
|
};
|
|
736
736
|
function qe(e) {
|
|
737
|
-
if (!
|
|
737
|
+
if (!A()) return;
|
|
738
738
|
let t = (e, t) => ({
|
|
739
739
|
contentType: e,
|
|
740
740
|
robustness: t,
|
|
@@ -781,7 +781,7 @@ function Xe(e) {
|
|
|
781
781
|
}]
|
|
782
782
|
}, i = (async () => {
|
|
783
783
|
try {
|
|
784
|
-
return await navigator.requestMediaKeySystemAccess("com.widevine.alpha",
|
|
784
|
+
return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", M("com.widevine.alpha", [r])), !0;
|
|
785
785
|
} catch {
|
|
786
786
|
return !1;
|
|
787
787
|
}
|
|
@@ -789,7 +789,7 @@ function Xe(e) {
|
|
|
789
789
|
return Ye.set(t, i), i;
|
|
790
790
|
}
|
|
791
791
|
function Ze() {
|
|
792
|
-
if (
|
|
792
|
+
if (A()) for (let e of Object.values(Je)) Xe(e);
|
|
793
793
|
}
|
|
794
794
|
function Qe(e) {
|
|
795
795
|
let t = P(e);
|
|
@@ -818,7 +818,7 @@ function rt(e) {
|
|
|
818
818
|
robustness: "",
|
|
819
819
|
encryptionScheme: "cbcs"
|
|
820
820
|
}]
|
|
821
|
-
}] :
|
|
821
|
+
}] : M("com.widevine.alpha", [{
|
|
822
822
|
initDataTypes: ["cenc"],
|
|
823
823
|
videoCapabilities: [{
|
|
824
824
|
contentType: et,
|
|
@@ -975,36 +975,43 @@ var ht = class {
|
|
|
975
975
|
this.video.removeEventListener("timeupdate", e), this.video.removeEventListener("seeking", e);
|
|
976
976
|
};
|
|
977
977
|
}
|
|
978
|
-
}, gt = .25;
|
|
979
|
-
function
|
|
978
|
+
}, gt = .25, _t = 1e3;
|
|
979
|
+
function vt(e, t) {
|
|
980
980
|
let n = null, r = (r) => {
|
|
981
981
|
n = r === "buffering" ? e.currentTime : null, t(r);
|
|
982
|
-
}, i =
|
|
983
|
-
|
|
982
|
+
}, i = () => typeof performance < "u" ? performance.now() : Date.now(), a = i(), o = e.currentTime, s = () => {
|
|
983
|
+
let t = e.currentTime;
|
|
984
|
+
t > o && !e.seeking && !e.paused && (a = i()), o = t;
|
|
985
|
+
}, c = [
|
|
986
|
+
["playing", () => {
|
|
987
|
+
a = i(), o = e.currentTime, r("playing");
|
|
988
|
+
}],
|
|
984
989
|
["waiting", () => r("buffering")],
|
|
985
990
|
["stalled", () => {
|
|
986
|
-
|
|
991
|
+
if (e.paused) return;
|
|
992
|
+
let t = e.readyState < HTMLMediaElement.HAVE_FUTURE_DATA, n = i() - a >= _t;
|
|
993
|
+
(t || n) && r("buffering");
|
|
987
994
|
}],
|
|
988
995
|
["seeked", () => {
|
|
989
|
-
n !== null && (n = e.currentTime);
|
|
996
|
+
o = e.currentTime, n !== null && (n = e.currentTime);
|
|
990
997
|
}],
|
|
991
998
|
["timeupdate", () => {
|
|
992
|
-
n !== null && !e.paused && !e.seeking && e.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA && e.currentTime - n >= gt && r("playing");
|
|
999
|
+
s(), n !== null && !e.paused && !e.seeking && e.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA && e.currentTime - n >= gt && r("playing");
|
|
993
1000
|
}],
|
|
994
1001
|
["pause", () => {
|
|
995
1002
|
e.ended || r("paused");
|
|
996
1003
|
}],
|
|
997
1004
|
["ended", () => r("ended")]
|
|
998
1005
|
];
|
|
999
|
-
for (let [t, n] of
|
|
1006
|
+
for (let [t, n] of c) e.addEventListener(t, n);
|
|
1000
1007
|
return () => {
|
|
1001
|
-
for (let [t, n] of
|
|
1008
|
+
for (let [t, n] of c) e.removeEventListener(t, n);
|
|
1002
1009
|
};
|
|
1003
1010
|
}
|
|
1004
1011
|
//#endregion
|
|
1005
1012
|
//#region src/core/engine/native.ts
|
|
1006
|
-
var
|
|
1007
|
-
function
|
|
1013
|
+
var yt = 2e3, bt = 3, z = 500, xt = 6e3, St = .25, Ct = 250, wt = .05, Tt = 4, Et = 12e3, Dt = .25, Ot = 1e3;
|
|
1014
|
+
function kt(e) {
|
|
1008
1015
|
try {
|
|
1009
1016
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
1010
1017
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -1020,7 +1027,7 @@ function V() {
|
|
|
1020
1027
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
1021
1028
|
return e || t;
|
|
1022
1029
|
}
|
|
1023
|
-
function
|
|
1030
|
+
function At() {
|
|
1024
1031
|
if (typeof navigator > "u" || !V()) return !1;
|
|
1025
1032
|
let e = navigator.userAgent ?? "";
|
|
1026
1033
|
return /iPhone|iPad|iPod/.test(e) ? !0 : /Macintosh/.test(e) && typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1;
|
|
@@ -1076,7 +1083,7 @@ var H = class {
|
|
|
1076
1083
|
type: "error",
|
|
1077
1084
|
error: L() ? new n("INTERNAL", 0, "native HLS playback error") : new n("NETWORK", 0, "native HLS playback error while offline"),
|
|
1078
1085
|
fatal: !0
|
|
1079
|
-
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src =
|
|
1086
|
+
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = Mt(t.manifestUrl, t.analytics?.sid), e.load();
|
|
1080
1087
|
}
|
|
1081
1088
|
startLoad() {
|
|
1082
1089
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -1104,7 +1111,7 @@ var H = class {
|
|
|
1104
1111
|
};
|
|
1105
1112
|
this.onEncrypted = (n) => {
|
|
1106
1113
|
let a = n;
|
|
1107
|
-
a.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
1114
|
+
a.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = kt(a.initData), (async () => {
|
|
1108
1115
|
try {
|
|
1109
1116
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
1110
1117
|
initDataTypes: [a.initDataType],
|
|
@@ -1207,7 +1214,7 @@ var H = class {
|
|
|
1207
1214
|
if (this.cdnHost ||= mt(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
|
|
1208
1215
|
n.isLive = !0;
|
|
1209
1216
|
let t = this.liveEdgeEstimate(), r = t == null ? NaN : t - e.currentTime;
|
|
1210
|
-
Number.isFinite(r) && (n.atLiveEdge = r <=
|
|
1217
|
+
Number.isFinite(r) && (n.atLiveEdge = r <= Tt, !e.paused && r >= 0 && (n.latencySeconds = r));
|
|
1211
1218
|
} else Number.isFinite(e.duration) && e.duration > 0 && (n.isLive = !1);
|
|
1212
1219
|
return n;
|
|
1213
1220
|
}
|
|
@@ -1225,7 +1232,7 @@ var H = class {
|
|
|
1225
1232
|
return;
|
|
1226
1233
|
}
|
|
1227
1234
|
let t = this.hiddenSince;
|
|
1228
|
-
this.hiddenSince = null, t != null && e - t >=
|
|
1235
|
+
this.hiddenSince = null, t != null && e - t >= yt && this.armRefocus();
|
|
1229
1236
|
}, this.onPageShow = (e) => {
|
|
1230
1237
|
e.persisted && this.armRefocus();
|
|
1231
1238
|
}, document.addEventListener("visibilitychange", this.onVisibility), typeof window < "u" && window.addEventListener("pageshow", this.onPageShow));
|
|
@@ -1235,7 +1242,7 @@ var H = class {
|
|
|
1235
1242
|
let e = this.liveEnd(), t = U, n = t(), r = 0, i = () => {
|
|
1236
1243
|
if (this.refocusTimer = null, Number.isFinite(this.deps.video.duration)) return;
|
|
1237
1244
|
r += z;
|
|
1238
|
-
let a = this.liveEnd(), o = a != null && (e == null || a >= e +
|
|
1245
|
+
let a = this.liveEnd(), o = a != null && (e == null || a >= e + St), s = Math.max(r, t() - n) >= xt;
|
|
1239
1246
|
if (o || s && a != null) {
|
|
1240
1247
|
this.snapToLive();
|
|
1241
1248
|
return;
|
|
@@ -1255,9 +1262,9 @@ var H = class {
|
|
|
1255
1262
|
}, e.addEventListener("seeking", this.onEdgeReset), e.addEventListener("emptied", this.onEdgeReset), this.edgeTimer = setInterval(() => {
|
|
1256
1263
|
if (e.duration !== Infinity) return;
|
|
1257
1264
|
this.checkEndStale();
|
|
1258
|
-
let t =
|
|
1259
|
-
t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >=
|
|
1260
|
-
},
|
|
1265
|
+
let t = jt(e, e.currentTime);
|
|
1266
|
+
t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >= wt) && (this.bufferedAdvancedAt = U()), this.lastBufferedEnd = t);
|
|
1267
|
+
}, Ct);
|
|
1261
1268
|
}
|
|
1262
1269
|
checkEndStale() {
|
|
1263
1270
|
if (this.endedEmitted) return;
|
|
@@ -1265,14 +1272,14 @@ var H = class {
|
|
|
1265
1272
|
this.lastTickAt = e;
|
|
1266
1273
|
let n = this.liveEnd();
|
|
1267
1274
|
if (n == null) return;
|
|
1268
|
-
let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >=
|
|
1275
|
+
let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >= Dt;
|
|
1269
1276
|
this.lastSeekableEnd = n;
|
|
1270
1277
|
let i = this.deps.video, a = typeof document < "u" && document.visibilityState === "hidden";
|
|
1271
|
-
if (r || t >
|
|
1278
|
+
if (r || t > Ot || a || i.paused) {
|
|
1272
1279
|
this.edgeStampedAt = e;
|
|
1273
1280
|
return;
|
|
1274
1281
|
}
|
|
1275
|
-
e - (this.edgeStampedAt ?? e) >
|
|
1282
|
+
e - (this.edgeStampedAt ?? e) > Et && (this.endedEmitted = !0, this.deps.emit({
|
|
1276
1283
|
type: "ended",
|
|
1277
1284
|
reason: "stalled"
|
|
1278
1285
|
}));
|
|
@@ -1286,7 +1293,7 @@ var H = class {
|
|
|
1286
1293
|
liveEdgeEstimate() {
|
|
1287
1294
|
let e = this.deps.video;
|
|
1288
1295
|
if (e.duration !== Infinity) return null;
|
|
1289
|
-
let t = this.liveEnd(), n =
|
|
1296
|
+
let t = this.liveEnd(), n = jt(e, e.currentTime) ?? this.lastBufferedEnd;
|
|
1290
1297
|
if (n != null) {
|
|
1291
1298
|
let e = this.bufferedAdvancedAt, r = n + (e == null ? 0 : Math.max(0, (U() - e) / 1e3));
|
|
1292
1299
|
(t == null || r > t) && (t = r);
|
|
@@ -1302,7 +1309,7 @@ var H = class {
|
|
|
1302
1309
|
snapToLive() {
|
|
1303
1310
|
let e = this.deps.video, t = this.liveEnd();
|
|
1304
1311
|
if (t == null) return;
|
|
1305
|
-
let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t -
|
|
1312
|
+
let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t - bt, r);
|
|
1306
1313
|
try {
|
|
1307
1314
|
e.currentTime = i;
|
|
1308
1315
|
} catch {}
|
|
@@ -1323,7 +1330,7 @@ var H = class {
|
|
|
1323
1330
|
function U() {
|
|
1324
1331
|
return typeof performance < "u" ? performance.now() : Date.now();
|
|
1325
1332
|
}
|
|
1326
|
-
function
|
|
1333
|
+
function jt(e, t) {
|
|
1327
1334
|
let n = e.buffered;
|
|
1328
1335
|
if (!n || !Number.isFinite(t)) return null;
|
|
1329
1336
|
for (let e = 0; e < n.length; e += 1) if (n.start(e) <= t + .1 && n.end(e) > t) {
|
|
@@ -1332,7 +1339,7 @@ function At(e, t) {
|
|
|
1332
1339
|
}
|
|
1333
1340
|
return null;
|
|
1334
1341
|
}
|
|
1335
|
-
function
|
|
1342
|
+
function Mt(e, t) {
|
|
1336
1343
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
1337
1344
|
}
|
|
1338
1345
|
//#endregion
|
|
@@ -1349,13 +1356,13 @@ function W(e, t = Date.now()) {
|
|
|
1349
1356
|
}
|
|
1350
1357
|
//#endregion
|
|
1351
1358
|
//#region src/core/drm/xhrBody.ts
|
|
1352
|
-
var
|
|
1353
|
-
function
|
|
1359
|
+
var Nt = 4096;
|
|
1360
|
+
function Pt(e) {
|
|
1354
1361
|
if (!e || typeof e != "object") return;
|
|
1355
1362
|
let { response: t } = e;
|
|
1356
1363
|
if (typeof t == "string") return t;
|
|
1357
1364
|
let n;
|
|
1358
|
-
if (Object.prototype.toString.call(t) === "[object ArrayBuffer]" ? n = new Uint8Array(t) : ArrayBuffer.isView(t) && (n = new Uint8Array(t.buffer, t.byteOffset, t.byteLength)), !(!n || n.byteLength === 0 || n.byteLength >
|
|
1365
|
+
if (Object.prototype.toString.call(t) === "[object ArrayBuffer]" ? n = new Uint8Array(t) : ArrayBuffer.isView(t) && (n = new Uint8Array(t.buffer, t.byteOffset, t.byteLength)), !(!n || n.byteLength === 0 || n.byteLength > Nt)) try {
|
|
1359
1366
|
return new TextDecoder().decode(n);
|
|
1360
1367
|
} catch {
|
|
1361
1368
|
return;
|
|
@@ -1363,7 +1370,7 @@ function Nt(e) {
|
|
|
1363
1370
|
}
|
|
1364
1371
|
//#endregion
|
|
1365
1372
|
//#region src/core/engine/prefetch.ts
|
|
1366
|
-
var
|
|
1373
|
+
var Ft = 15e3, It = 5e3, Lt = 6, Rt = 4e3, zt = 2;
|
|
1367
1374
|
function G(e) {
|
|
1368
1375
|
try {
|
|
1369
1376
|
let t = new URL(e);
|
|
@@ -1372,7 +1379,7 @@ function G(e) {
|
|
|
1372
1379
|
return e;
|
|
1373
1380
|
}
|
|
1374
1381
|
}
|
|
1375
|
-
var
|
|
1382
|
+
var Bt = class {
|
|
1376
1383
|
cmcd;
|
|
1377
1384
|
entries = /* @__PURE__ */ new Map();
|
|
1378
1385
|
keyed = /* @__PURE__ */ new Set();
|
|
@@ -1404,17 +1411,17 @@ var zt = class {
|
|
|
1404
1411
|
let r = G(e);
|
|
1405
1412
|
if (this.entries.has(r)) return;
|
|
1406
1413
|
let i = this.perTrack.get(t) ?? 0;
|
|
1407
|
-
i >=
|
|
1414
|
+
i >= Lt || (this.perTrack.set(t, i + 1), this.start(r, this.withCmcd(e, t, n), !1, Ft), this.stats.started += 1);
|
|
1408
1415
|
}
|
|
1409
1416
|
prefetchHint(e, t) {
|
|
1410
1417
|
let n = G(e);
|
|
1411
1418
|
if (this.entries.has(n)) return;
|
|
1412
1419
|
let r = this.hints.get(t) ?? [];
|
|
1413
|
-
for (; r.length >=
|
|
1420
|
+
for (; r.length >= zt;) {
|
|
1414
1421
|
let e = r.shift();
|
|
1415
1422
|
e !== void 0 && this.drop(e) && (this.stats.hintDropped += 1);
|
|
1416
1423
|
}
|
|
1417
|
-
r.push(n), this.hints.set(t, r), this.start(n, this.withCmcd(e, t, "media"), !0,
|
|
1424
|
+
r.push(n), this.hints.set(t, r), this.start(n, this.withCmcd(e, t, "media"), !0, Rt), this.stats.hintStarted += 1;
|
|
1418
1425
|
}
|
|
1419
1426
|
dropHints(e) {
|
|
1420
1427
|
for (let t of this.hints.get(e) ?? []) this.drop(t) && (this.stats.hintDropped += 1);
|
|
@@ -1467,14 +1474,14 @@ var zt = class {
|
|
|
1467
1474
|
}
|
|
1468
1475
|
}
|
|
1469
1476
|
};
|
|
1470
|
-
function
|
|
1477
|
+
function Vt(t, n) {
|
|
1471
1478
|
let r = typeof n == "function" ? n : e.DefaultConfig?.loader;
|
|
1472
1479
|
if (typeof r != "function") return;
|
|
1473
1480
|
class i extends r {
|
|
1474
1481
|
served = !1;
|
|
1475
1482
|
cancelled = !1;
|
|
1476
1483
|
entry;
|
|
1477
|
-
stats =
|
|
1484
|
+
stats = Ht();
|
|
1478
1485
|
load(e, n, r) {
|
|
1479
1486
|
let i = e.rangeEnd ? void 0 : t.take(e.url);
|
|
1480
1487
|
if (!i) {
|
|
@@ -1486,7 +1493,7 @@ function Bt(t, n) {
|
|
|
1486
1493
|
i.hint ? t.stats.hintFailed += 1 : t.stats.failed += 1;
|
|
1487
1494
|
}, s = () => {
|
|
1488
1495
|
!this.cancelled && this.served && (i.abort.abort(), o(), this.served = !1, this.entry = void 0, super.load(e, n, r));
|
|
1489
|
-
}, c = n?.loadPolicy, l = c?.maxTimeToFirstByteMs ||
|
|
1496
|
+
}, c = n?.loadPolicy, l = c?.maxTimeToFirstByteMs || It, u = setTimeout(s, l);
|
|
1490
1497
|
i.headers.then(() => {
|
|
1491
1498
|
clearTimeout(u);
|
|
1492
1499
|
let e = c?.maxLoadTimeMs;
|
|
@@ -1519,7 +1526,7 @@ function Bt(t, n) {
|
|
|
1519
1526
|
}
|
|
1520
1527
|
return i;
|
|
1521
1528
|
}
|
|
1522
|
-
function
|
|
1529
|
+
function Ht() {
|
|
1523
1530
|
return {
|
|
1524
1531
|
aborted: !1,
|
|
1525
1532
|
loaded: 0,
|
|
@@ -1543,10 +1550,10 @@ function Vt() {
|
|
|
1543
1550
|
}
|
|
1544
1551
|
};
|
|
1545
1552
|
}
|
|
1546
|
-
function
|
|
1553
|
+
function Ut(e) {
|
|
1547
1554
|
return e === "audio" ? "audio" : "main";
|
|
1548
1555
|
}
|
|
1549
|
-
function
|
|
1556
|
+
function Wt(e, t) {
|
|
1550
1557
|
let n = [];
|
|
1551
1558
|
t.initSegment?.url && !t.initSegment.data && n.push({
|
|
1552
1559
|
url: t.initSegment.url,
|
|
@@ -1563,7 +1570,7 @@ function Ut(e, t) {
|
|
|
1563
1570
|
});
|
|
1564
1571
|
return n;
|
|
1565
1572
|
}
|
|
1566
|
-
function
|
|
1573
|
+
function Gt(e) {
|
|
1567
1574
|
let t = e, n = t?.preloadHint;
|
|
1568
1575
|
if (!n || !t?.url || n.TYPE !== "PART" || n["BYTERANGE-START"] !== void 0 || n["BYTERANGE-LENGTH"] !== void 0) return null;
|
|
1569
1576
|
let r = n.URI;
|
|
@@ -1581,15 +1588,15 @@ function K(e, t) {
|
|
|
1581
1588
|
}
|
|
1582
1589
|
//#endregion
|
|
1583
1590
|
//#region src/core/engine/hls.ts
|
|
1584
|
-
function
|
|
1591
|
+
function Kt() {
|
|
1585
1592
|
return e.isSupported();
|
|
1586
1593
|
}
|
|
1587
|
-
var
|
|
1588
|
-
function
|
|
1594
|
+
var qt = 3, Jt = 1e6, Yt = 20, Xt = 1e4, Zt = 3, Qt = 5, $t = 3, en = 1e4, tn = 3e4, nn = 12e3, rn = 3e3, an = .02, on = 6e3, sn = .5, cn = 3, ln = .5, un = 1.1, dn = .25, fn = 5e3, pn = 4e3, mn = 2, hn = 5, gn = 2, _n = 2, vn = 4, yn = 4, bn = 2e3, xn = 3e4, Sn = 1, Cn = 2, wn = .5, Tn = .6, En = 2, Dn = 1.5, On = 1e4, kn = 18e4, An = .5, jn = 2;
|
|
1595
|
+
function Mn(e) {
|
|
1589
1596
|
let t = e.config ?? {};
|
|
1590
1597
|
return t.capLevelToPlayerSize === !0 || t.capLevelOnFPSDrop === !0;
|
|
1591
1598
|
}
|
|
1592
|
-
var q = 8,
|
|
1599
|
+
var q = 8, Nn = 12e4, Pn = 6e4;
|
|
1593
1600
|
function J(e, t, n) {
|
|
1594
1601
|
if (n <= 0 || t < 0 || t >= e.length) return t;
|
|
1595
1602
|
let r = (t, n) => e[t].width === e[n].width && e[t].height === e[n].height, i = (t) => {
|
|
@@ -1602,11 +1609,11 @@ function J(e, t, n) {
|
|
|
1602
1609
|
function Y() {
|
|
1603
1610
|
return typeof self < "u" && self.devicePixelRatio > 0 ? self.devicePixelRatio : 1;
|
|
1604
1611
|
}
|
|
1605
|
-
var
|
|
1606
|
-
function
|
|
1612
|
+
var Fn = .2, In = 30, Ln = 2, Rn = 2, zn = 2, Bn = 9, Vn = .5, Hn = 64, Un = 1e4, Wn = 8, Gn = .6, Kn = .4, qn = .4, Jn = 2, Yn = 6e4, X = .5, Xn = 3.5, Zn = 300;
|
|
1613
|
+
function Qn(e) {
|
|
1607
1614
|
return (e?.part ?? e?.frag)?.stats;
|
|
1608
1615
|
}
|
|
1609
|
-
function
|
|
1616
|
+
function $n() {
|
|
1610
1617
|
if (typeof navigator > "u") return 0;
|
|
1611
1618
|
try {
|
|
1612
1619
|
let e = navigator.connection?.rtt;
|
|
@@ -1615,20 +1622,20 @@ function Zn() {
|
|
|
1615
1622
|
return 0;
|
|
1616
1623
|
}
|
|
1617
1624
|
}
|
|
1618
|
-
function
|
|
1625
|
+
function er(e) {
|
|
1619
1626
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
1620
1627
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
1621
1628
|
return;
|
|
1622
1629
|
}
|
|
1623
|
-
e.liveSyncDuration ??=
|
|
1624
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
1625
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
1630
|
+
e.liveSyncDuration ??= zn;
|
|
1631
|
+
let t = Math.max(12, e.liveSyncDuration + Bn);
|
|
1632
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), tr(e, e.liveSyncDuration);
|
|
1626
1633
|
}
|
|
1627
|
-
function
|
|
1634
|
+
function tr(e, t) {
|
|
1628
1635
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
1629
1636
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
1630
1637
|
}
|
|
1631
|
-
var
|
|
1638
|
+
var nr = class {
|
|
1632
1639
|
name = "hls";
|
|
1633
1640
|
hls = null;
|
|
1634
1641
|
deps;
|
|
@@ -1781,7 +1788,7 @@ var er = class {
|
|
|
1781
1788
|
}
|
|
1782
1789
|
this.loadSuspended = !0;
|
|
1783
1790
|
}
|
|
1784
|
-
},
|
|
1791
|
+
}, fn));
|
|
1785
1792
|
}
|
|
1786
1793
|
resumeLoading() {
|
|
1787
1794
|
if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.resetChaseWindow(), this.resetFrameDropWindow(), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
|
|
@@ -1813,7 +1820,7 @@ var er = class {
|
|
|
1813
1820
|
let t = e.liveSyncPosition;
|
|
1814
1821
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1815
1822
|
let { video: n } = this.deps;
|
|
1816
|
-
n.currentTime <= t +
|
|
1823
|
+
n.currentTime <= t + Vn || (n.currentTime = t);
|
|
1817
1824
|
}
|
|
1818
1825
|
reanchorPartTimeline(e, t) {
|
|
1819
1826
|
let { frag: n, part: r } = t;
|
|
@@ -1825,7 +1832,7 @@ var er = class {
|
|
|
1825
1832
|
let o = n.sn, s = i.fragments.find((e) => e && e.sn === o) ?? (i.fragmentHint?.sn === o ? i.fragmentHint : void 0);
|
|
1826
1833
|
if (!s) return;
|
|
1827
1834
|
let c = a.startPTS - s.start;
|
|
1828
|
-
if (!(!Number.isFinite(c) || Math.abs(c) <
|
|
1835
|
+
if (!(!Number.isFinite(c) || Math.abs(c) < an)) {
|
|
1829
1836
|
for (let e of i.fragments) e && e.setStart(e.start + c);
|
|
1830
1837
|
i.fragmentHint?.setStart(i.fragmentHint.start + c), this.deps.debug === !0 && console.info(`havik-player: LL-HLS timeline re-anchored by ${c >= 0 ? "+" : ""}${c.toFixed(3)}s at sn ${n.sn} (level ${n.level})`);
|
|
1831
1838
|
}
|
|
@@ -1853,7 +1860,7 @@ var er = class {
|
|
|
1853
1860
|
videoEncryptionScheme: N.scheme,
|
|
1854
1861
|
audioEncryptionScheme: N.scheme
|
|
1855
1862
|
},
|
|
1856
|
-
...
|
|
1863
|
+
...A() ? { requestMediaKeySystemAccessFunc: Ke(t) } : {},
|
|
1857
1864
|
licenseXhrSetup: (e, t) => {
|
|
1858
1865
|
let o = performance.now(), s = () => {
|
|
1859
1866
|
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, e.addEventListener("loadend", () => {
|
|
@@ -1865,7 +1872,7 @@ var er = class {
|
|
|
1865
1872
|
return;
|
|
1866
1873
|
}
|
|
1867
1874
|
let l = this.hls, u, d = new Promise((e) => {
|
|
1868
|
-
u = setTimeout(() => e(void 0),
|
|
1875
|
+
u = setTimeout(() => e(void 0), en);
|
|
1869
1876
|
});
|
|
1870
1877
|
return Promise.race([c().catch(() => void 0), d]).finally(() => clearTimeout(u)).then((e) => {
|
|
1871
1878
|
if (!this.hls || this.hls !== l) throw Error("havik-player: engine torn down during refresh");
|
|
@@ -1883,28 +1890,28 @@ var er = class {
|
|
|
1883
1890
|
this.prefetch?.destroy(), this.prefetch = null;
|
|
1884
1891
|
let p = !1, m = !1, h = u && this.deps.mediaDuringKey !== !1, g = this.deps.preloadHints !== !1;
|
|
1885
1892
|
if ((h || g) && !f.fLoader) {
|
|
1886
|
-
let e = new
|
|
1893
|
+
let e = new Bt({
|
|
1887
1894
|
sessionId: n.analytics?.sid,
|
|
1888
1895
|
contentId: n.matchUrn
|
|
1889
|
-
}), t =
|
|
1896
|
+
}), t = Vt(e, f.loader);
|
|
1890
1897
|
t && (this.prefetch = e, p = h, m = g, f.fLoader = t);
|
|
1891
1898
|
}
|
|
1892
|
-
|
|
1899
|
+
er(f), this.catchUpRate = typeof f.maxLiveSyncPlaybackRate == "number" ? f.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (f.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = f.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = f.autoStartLoad !== !1;
|
|
1893
1900
|
let _ = new e(f);
|
|
1894
1901
|
if (this.hls = _, this.armHoldBack(_, f), _.on(e.Events.FRAG_PARSED, (e, t) => this.reanchorPartTimeline(_, t)), _.on(e.Events.MANIFEST_PARSED, () => {
|
|
1895
1902
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, u && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && this.dropLevelsWidevineCannotPlay(_), this.measureLadder(_), this.applySizeCap(), this.loadSuspended = !1, t.paused && this.schedulePauseSuspend(), l({ type: "ready" });
|
|
1896
1903
|
}), _.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1897
1904
|
t?.frag?.type === "main" && (this.kickKind !== "dead" && this.clearKick(), (this.mediaRecoveries > 0 || this.networkRecoveries > 0 || this.licenseRecoveries > 0 || this.starvationKicks > 0 || this.starvationRebuilds > 0) && !this.recoveryResetTimer && (this.recoveryResetTimer = setTimeout(() => {
|
|
1898
1905
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1899
|
-
},
|
|
1906
|
+
}, tn)));
|
|
1900
1907
|
}), _.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1901
1908
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1902
1909
|
}), _.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
1903
1910
|
t?.frag?.type === "main" && (this.mainFragsSinceTick += 1, this.bwFragsLoaded += 1, this.maybeRememberBandwidth(!1));
|
|
1904
|
-
let n = t?.frag, r =
|
|
1911
|
+
let n = t?.frag, r = Qn(t), i = r?.loaded;
|
|
1905
1912
|
typeof i == "number" && (this.bytesLoaded += i), !this.reportedFirstBytes && typeof i == "number" && i > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
|
|
1906
1913
|
let a = r?.loading;
|
|
1907
|
-
a && a.end > 0 && a.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(a.end - a.start))), this.requestTimesMs.length >
|
|
1914
|
+
a && a.end > 0 && a.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(a.end - a.start))), this.requestTimesMs.length > Hn && this.requestTimesMs.shift()), this.sampleHoldBack(t), this.sampleHeadroom(t);
|
|
1908
1915
|
let o = n?.url;
|
|
1909
1916
|
if (o) {
|
|
1910
1917
|
let e = ft(o);
|
|
@@ -1924,8 +1931,8 @@ var er = class {
|
|
|
1924
1931
|
let i = e;
|
|
1925
1932
|
if (!i?.live || !i.partList?.length || typeof i.edge != "number") return;
|
|
1926
1933
|
let a = n.buffered, o = a.length ? a.end(a.length - 1) : 0;
|
|
1927
|
-
if (i.edge - o >
|
|
1928
|
-
let s =
|
|
1934
|
+
if (i.edge - o > qt * (i.partTarget || .5)) return;
|
|
1935
|
+
let s = Gt(e);
|
|
1929
1936
|
s && t.prefetchHint(s, r);
|
|
1930
1937
|
};
|
|
1931
1938
|
_.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1937,15 +1944,15 @@ var er = class {
|
|
|
1937
1944
|
if (this.prefetch && p) {
|
|
1938
1945
|
let t = this.prefetch;
|
|
1939
1946
|
_.on(e.Events.KEY_LOADING, (e, n) => {
|
|
1940
|
-
let r = n?.frag, i =
|
|
1941
|
-
if (r && t.isActive(i)) for (let e of
|
|
1942
|
-
}), _.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(
|
|
1947
|
+
let r = n?.frag, i = Ut(r?.type);
|
|
1948
|
+
if (r && t.isActive(i)) for (let e of Wt(_, r)) t.prefetch(e.url, i, e.kind);
|
|
1949
|
+
}), _.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(Ut(n?.frag?.type)));
|
|
1943
1950
|
}
|
|
1944
1951
|
_.on(e.Events.KEY_LOADED, () => {
|
|
1945
1952
|
u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
|
|
1946
1953
|
}), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1947
1954
|
this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.adaptHoldBack(), this.reviewSizeCapHeadroom(), this.releaseStallCap(), this.checkFrameDrops();
|
|
1948
|
-
},
|
|
1955
|
+
}, rn), _.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1949
1956
|
this.renditionSwitches += 1;
|
|
1950
1957
|
let n = this.lastLevelIndex >= 0 ? _.levels[this.lastLevelIndex] : void 0, r = _.levels[t.level];
|
|
1951
1958
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, this.armFrameDropGrace(), l({
|
|
@@ -2006,8 +2013,8 @@ var er = class {
|
|
|
2006
2013
|
let e = this.hls, t = this.sizeCapCover();
|
|
2007
2014
|
if (!e || !t) return null;
|
|
2008
2015
|
let { cover: n, deviceRatio: r } = t, i = this.deps.sizeCapHeadroom, a = i == null || Number.isNaN(i);
|
|
2009
|
-
if (a && r >=
|
|
2010
|
-
if (a) return this.headroomUngated || this.headroomGranted ? J(e.levels, n,
|
|
2016
|
+
if (a && r >= Cn) return n;
|
|
2017
|
+
if (a) return this.headroomUngated || this.headroomGranted ? J(e.levels, n, Sn) : n;
|
|
2011
2018
|
let o = i === Infinity ? e.levels.length : Math.max(0, Math.floor(i));
|
|
2012
2019
|
return J(e.levels, n, o);
|
|
2013
2020
|
}
|
|
@@ -2024,11 +2031,11 @@ var er = class {
|
|
|
2024
2031
|
return;
|
|
2025
2032
|
}
|
|
2026
2033
|
this.capTimer && clearTimeout(this.capTimer);
|
|
2027
|
-
let t = e > this.sizeCapLevel ?
|
|
2034
|
+
let t = e > this.sizeCapLevel ? bn : xn;
|
|
2028
2035
|
this.capTimer = setTimeout(() => {
|
|
2029
2036
|
this.capTimer = null;
|
|
2030
2037
|
let n = this.computeSizeCapTarget();
|
|
2031
|
-
n === e || t ===
|
|
2038
|
+
n === e || t === xn && n != null && n < e ? this.applySizeCap() : this.onMediaResize();
|
|
2032
2039
|
}, t);
|
|
2033
2040
|
}
|
|
2034
2041
|
measureLadder(e) {
|
|
@@ -2055,7 +2062,7 @@ var er = class {
|
|
|
2055
2062
|
}
|
|
2056
2063
|
defaultHeadroomApplies() {
|
|
2057
2064
|
let e = this.deps.sizeCapHeadroom;
|
|
2058
|
-
return e != null && !Number.isNaN(e) || this.headroomUngated ? !1 : Y() <
|
|
2065
|
+
return e != null && !Number.isNaN(e) || this.headroomUngated ? !1 : Y() < Cn;
|
|
2059
2066
|
}
|
|
2060
2067
|
applySizeCapUnlessPending() {
|
|
2061
2068
|
this.capTimer || this.applySizeCap();
|
|
@@ -2064,7 +2071,7 @@ var er = class {
|
|
|
2064
2071
|
if (!this.sizeCapManaged || !this.defaultHeadroomApplies() || e.frag?.type !== "main" || typeof e.frag.level != "number" || typeof document < "u" && document.hidden) return;
|
|
2065
2072
|
let t = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag.duration;
|
|
2066
2073
|
if (typeof t != "number" || !(t > 0)) return;
|
|
2067
|
-
let n =
|
|
2074
|
+
let n = Qn(e)?.loading;
|
|
2068
2075
|
if (!n || !(n.start > 0) || !(n.end >= n.start)) return;
|
|
2069
2076
|
let r = this.hls?.levels?.[e.frag.level]?.bitrate;
|
|
2070
2077
|
if (!(typeof r == "number" && r > 0)) return;
|
|
@@ -2077,7 +2084,7 @@ var er = class {
|
|
|
2077
2084
|
}
|
|
2078
2085
|
onPlaybackStall(e) {
|
|
2079
2086
|
let t = Date.now();
|
|
2080
|
-
this.deps.video.seeking || !this.playingSince || t - this.playingSince <
|
|
2087
|
+
this.deps.video.seeking || !this.playingSince || t - this.playingSince < On || (this.lastStallAt = t, this.stepStallCapDown(t, e), this.headroomGranted && (this.headroomGranted = !1, this.applySizeCapUnlessPending()));
|
|
2081
2088
|
}
|
|
2082
2089
|
stallCapLevel(e) {
|
|
2083
2090
|
if (this.stallCapBitrate == null) return -1;
|
|
@@ -2088,7 +2095,7 @@ var er = class {
|
|
|
2088
2095
|
}
|
|
2089
2096
|
stepStallCapDown(e, t) {
|
|
2090
2097
|
let n = this.hls;
|
|
2091
|
-
if (!n || !this.stallCapEnabled ||
|
|
2098
|
+
if (!n || !this.stallCapEnabled || Mn(n) || !n.autoLevelEnabled || typeof t == "number" && t >= An || this.isLiveEdgeWait(n, t ?? 0)) return;
|
|
2092
2099
|
this.stallCapBitrate != null && (this.stallCapSince = e);
|
|
2093
2100
|
let r = Math.max(n.levels[n.currentLevel]?.bitrate ?? 0, n.levels[n.loadLevel]?.bitrate ?? 0);
|
|
2094
2101
|
if (!(r > 0)) return;
|
|
@@ -2099,7 +2106,7 @@ var er = class {
|
|
|
2099
2106
|
let n = e.latestLevelDetails;
|
|
2100
2107
|
if (!n?.live) return !1;
|
|
2101
2108
|
let r = n.partTarget || n.targetduration;
|
|
2102
|
-
return !(r > 0) || !(n.edge > 0) ? !1 : n.edge - (this.deps.video.currentTime + t) <
|
|
2109
|
+
return !(r > 0) || !(n.edge > 0) ? !1 : n.edge - (this.deps.video.currentTime + t) < jn * r;
|
|
2103
2110
|
}
|
|
2104
2111
|
releaseStallCap() {
|
|
2105
2112
|
let e = this.hls, t = Date.now(), n = this.stallCapTickAt;
|
|
@@ -2108,7 +2115,7 @@ var er = class {
|
|
|
2108
2115
|
n && (this.stallCapSince += t - Math.max(n, this.stallCapSince));
|
|
2109
2116
|
return;
|
|
2110
2117
|
}
|
|
2111
|
-
if (t - this.stallCapSince <
|
|
2118
|
+
if (t - this.stallCapSince < kn) return;
|
|
2112
2119
|
let r = this.stallCapBitrate, i = e.levels.map((e) => e.bitrate).filter((e) => e > r).sort((e, t) => e - t)[0];
|
|
2113
2120
|
this.stallCapBitrate = i ?? null, this.stallCapSince = t, this.pushCap();
|
|
2114
2121
|
}
|
|
@@ -2121,26 +2128,26 @@ var er = class {
|
|
|
2121
2128
|
this.headroomGranted = !1, this.headroomSamples = [];
|
|
2122
2129
|
return;
|
|
2123
2130
|
}
|
|
2124
|
-
this.headroomSamples = this.headroomSamples.filter((t) => t.t >= e -
|
|
2131
|
+
this.headroomSamples = this.headroomSamples.filter((t) => t.t >= e - Un);
|
|
2125
2132
|
let r = this.headroomEarned(n, e);
|
|
2126
|
-
r !== this.headroomGranted && (r || (this.headroomRegrantAt = e +
|
|
2133
|
+
r !== this.headroomGranted && (r || (this.headroomRegrantAt = e + Pn), this.headroomGranted = r, this.applySizeCapUnlessPending());
|
|
2127
2134
|
}
|
|
2128
2135
|
headroomEarned(e, t) {
|
|
2129
|
-
if (t - this.lastStallAt <
|
|
2136
|
+
if (t - this.lastStallAt < Nn || !this.headroomGranted && t < this.headroomRegrantAt || !this.headroomGranted && this.headroomSamples.length < q) return !1;
|
|
2130
2137
|
let n = e.levels, r = this.sizeCapCoverLevel();
|
|
2131
2138
|
if (r == null) return this.headroomGranted;
|
|
2132
|
-
let i = J(n, r,
|
|
2139
|
+
let i = J(n, r, Sn);
|
|
2133
2140
|
if (i === r) return this.headroomGranted;
|
|
2134
|
-
let a = n[i]?.bitrate, o = e.bandwidthEstimate, s = this.headroomGranted ?
|
|
2141
|
+
let a = n[i]?.bitrate, o = e.bandwidthEstimate, s = this.headroomGranted ? Dn : En;
|
|
2135
2142
|
if (!(a > 0) || !(o >= s * a)) return !1;
|
|
2136
2143
|
let c = (e) => K([...e].sort((e, t) => e - t), 90);
|
|
2137
2144
|
if (this.headroomGranted) {
|
|
2138
2145
|
let e = this.headroomSamples.filter((e) => e.bitrate >= a).map((e) => e.ratio);
|
|
2139
|
-
return e.length < q || c(e) <=
|
|
2146
|
+
return e.length < q || c(e) <= Tn;
|
|
2140
2147
|
}
|
|
2141
2148
|
let l = [];
|
|
2142
2149
|
for (let e of this.headroomSamples) e.bitrate < a && l.push(e.ratio * (a / e.bitrate));
|
|
2143
|
-
return l.length >= q && c(l) <=
|
|
2150
|
+
return l.length >= q && c(l) <= wn;
|
|
2144
2151
|
}
|
|
2145
2152
|
applySizeCap() {
|
|
2146
2153
|
if (!this.sizeCapManaged) return;
|
|
@@ -2215,7 +2222,7 @@ var er = class {
|
|
|
2215
2222
|
let t = e.currentLevel >= 0 ? e.levels[e.currentLevel] : void 0;
|
|
2216
2223
|
t && (n.levelHeight = t.height);
|
|
2217
2224
|
let r = e.autoLevelCapping, i = r >= 0 ? e.levels[r] : void 0;
|
|
2218
|
-
i && i.height > 0 && (n.maxLevelHeight = i.height, !
|
|
2225
|
+
i && i.height > 0 && (n.maxLevelHeight = i.height, !Mn(e) && r === this.pushedCapLevel && this.pushedCapReason && (n.capReason = this.pushedCapReason)), t?.videoCodec && (n.videoCodec = t.videoCodec), t?.audioCodec && (n.audioCodec = t.audioCodec), t && typeof t.bitrate == "number" && (n.renditionBitrateKbps = Math.round(t.bitrate / 1e3)), typeof t?.details?.live == "boolean" && (n.isLive = t.details.live, typeof e.liveSyncPosition == "number" && (n.atLiveEdge = this.deps.video.currentTime >= e.liveSyncPosition - 1.5));
|
|
2219
2226
|
}
|
|
2220
2227
|
return n;
|
|
2221
2228
|
}
|
|
@@ -2243,7 +2250,7 @@ var er = class {
|
|
|
2243
2250
|
return;
|
|
2244
2251
|
}
|
|
2245
2252
|
let e = Date.now() - this.lastAdvanceMs;
|
|
2246
|
-
!this.chaseSuspended && e >
|
|
2253
|
+
!this.chaseSuspended && e > on && this.suspendChasing(), e > nn && this.emitEnded("stalled");
|
|
2247
2254
|
}
|
|
2248
2255
|
resetStarvationWindow() {
|
|
2249
2256
|
this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
|
|
@@ -2258,7 +2265,7 @@ var er = class {
|
|
|
2258
2265
|
this.resetStarvationWindow();
|
|
2259
2266
|
return;
|
|
2260
2267
|
}
|
|
2261
|
-
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs <
|
|
2268
|
+
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < on, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > pn, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = R(t), c = o - s, l = c !== this.starvedFrames;
|
|
2262
2269
|
if (this.starvedFrames = c, !a || l) {
|
|
2263
2270
|
(t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
|
|
2264
2271
|
return;
|
|
@@ -2267,12 +2274,12 @@ var er = class {
|
|
|
2267
2274
|
this.resetStarvationWindow();
|
|
2268
2275
|
return;
|
|
2269
2276
|
}
|
|
2270
|
-
if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length >
|
|
2277
|
+
if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length > vn && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= gn && (this.clearKick(), this.starvationRebuilds < _n)) {
|
|
2271
2278
|
this.starvationRebuilds += 1, this.resetStarvationWindow(), this.clearRecoveryReset(), 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");
|
|
2272
2279
|
return;
|
|
2273
2280
|
}
|
|
2274
|
-
let u = i && this.starvedTicks >=
|
|
2275
|
-
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >=
|
|
2281
|
+
let u = i && this.starvedTicks >= mn, d = !i && this.deadTicks >= vn && this.recentMainFrags.reduce((e, t) => e + t, 0) >= yn;
|
|
2282
|
+
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= hn))) {
|
|
2276
2283
|
this.starvationKicks += 1, this.kickPending = !0, this.kickTicks = 0, this.kickKind = d ? "dead" : "quiet", this.clearRecoveryReset(), console.warn(d ? "havik-player: video starved while hls.js keeps loading media it never plays (dead pipeline at the live edge) — restarting the load" : "havik-player: video starved while the live playlist advances (wedged hls.js fragment pipeline) — restarting the load");
|
|
2277
2284
|
try {
|
|
2278
2285
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -2287,7 +2294,7 @@ var er = class {
|
|
|
2287
2294
|
let t = e.latency, n = e.targetLatency;
|
|
2288
2295
|
if (typeof t != "number" || typeof n != "number" || !Number.isFinite(t)) return;
|
|
2289
2296
|
let r = t - n;
|
|
2290
|
-
!this.catchUpEngaged && r >
|
|
2297
|
+
!this.catchUpEngaged && r > sn ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= sn && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
|
|
2291
2298
|
let i = this.catchUpEngaged ? this.catchUpRate : 1;
|
|
2292
2299
|
e.config.maxLiveSyncPlaybackRate !== i && (e.config.maxLiveSyncPlaybackRate = i);
|
|
2293
2300
|
}
|
|
@@ -2300,7 +2307,7 @@ var er = class {
|
|
|
2300
2307
|
}), n < 0 ? 0 : n;
|
|
2301
2308
|
}
|
|
2302
2309
|
armFrameDropGrace() {
|
|
2303
|
-
this.fpsGraceTicks > 0 || (this.fpsGraceTicks =
|
|
2310
|
+
this.fpsGraceTicks > 0 || (this.fpsGraceTicks = Rn, this.fpsBadTicks = 0);
|
|
2304
2311
|
}
|
|
2305
2312
|
resetFrameDropWindow() {
|
|
2306
2313
|
this.fpsLastFrames = -1, this.fpsLastDropped = -1, this.fpsBadTicks = 0;
|
|
@@ -2312,7 +2319,7 @@ var er = class {
|
|
|
2312
2319
|
return;
|
|
2313
2320
|
}
|
|
2314
2321
|
let { totalFrames: n, dropped: r } = R(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
|
|
2315
|
-
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a <
|
|
2322
|
+
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < In || o < 0) {
|
|
2316
2323
|
this.fpsBadTicks = 0;
|
|
2317
2324
|
return;
|
|
2318
2325
|
}
|
|
@@ -2320,11 +2327,11 @@ var er = class {
|
|
|
2320
2327
|
--this.fpsGraceTicks, this.fpsBadTicks = 0;
|
|
2321
2328
|
return;
|
|
2322
2329
|
}
|
|
2323
|
-
if (o <=
|
|
2330
|
+
if (o <= Fn * a) {
|
|
2324
2331
|
this.fpsBadTicks = 0;
|
|
2325
2332
|
return;
|
|
2326
2333
|
}
|
|
2327
|
-
if (this.fpsBadTicks += 1, this.fpsBadTicks <
|
|
2334
|
+
if (this.fpsBadTicks += 1, this.fpsBadTicks < Ln) return;
|
|
2328
2335
|
this.fpsBadTicks = 0;
|
|
2329
2336
|
let s = e.levels, c = s[e.currentLevel];
|
|
2330
2337
|
if (!c) return;
|
|
@@ -2341,22 +2348,22 @@ var er = class {
|
|
|
2341
2348
|
return;
|
|
2342
2349
|
}
|
|
2343
2350
|
let n = e.latency, r = t.playbackRate, i = e.config.maxLiveSyncPlaybackRate;
|
|
2344
|
-
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(
|
|
2351
|
+
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(un, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
|
|
2345
2352
|
this.resetChaseWindow();
|
|
2346
2353
|
return;
|
|
2347
2354
|
}
|
|
2348
|
-
if (this.chaseLatency < 0 || this.chaseLatency - n >=
|
|
2355
|
+
if (this.chaseLatency < 0 || this.chaseLatency - n >= ln) {
|
|
2349
2356
|
this.chaseLatency = n, this.chaseTicks = 0;
|
|
2350
2357
|
return;
|
|
2351
2358
|
}
|
|
2352
|
-
if (this.chaseTicks += 1, this.chaseTicks <
|
|
2359
|
+
if (this.chaseTicks += 1, this.chaseTicks < cn) return;
|
|
2353
2360
|
this.resetChaseWindow();
|
|
2354
2361
|
let a = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
|
|
2355
2362
|
if (!(a > 1)) return;
|
|
2356
2363
|
let o = e.targetLatency;
|
|
2357
2364
|
if (typeof o != "number" || !(o > 0)) return;
|
|
2358
2365
|
let s = Math.min(n, a - 1);
|
|
2359
|
-
s < o +
|
|
2366
|
+
s < o + dn || (console.warn(`havik-player: catch-up at ${r}x not gaining on the live edge (latency ${n.toFixed(1)}s); holding at ${s.toFixed(1)}s`), this.liveRetargets += 1, e.targetLatency = s, this.deps.emit({
|
|
2360
2367
|
type: "livetargetchange",
|
|
2361
2368
|
change: {
|
|
2362
2369
|
targetSeconds: s,
|
|
@@ -2373,13 +2380,13 @@ var er = class {
|
|
|
2373
2380
|
if (!this.holdBackEnabled || this.holdBackPriorChecked || !e || (this.holdBackPriorChecked = !0, this.holdBackApplied > 0 || this.holdBackStepCount > 0)) return;
|
|
2374
2381
|
let t = e.targetLatency;
|
|
2375
2382
|
if (this.holdBackBase < 0 && typeof t == "number" && t > 0 && (this.holdBackBase = t), this.holdBackBase < 0) return;
|
|
2376
|
-
let n =
|
|
2377
|
-
if (!(n >=
|
|
2383
|
+
let n = $n();
|
|
2384
|
+
if (!(n >= Zn)) return;
|
|
2378
2385
|
let r = typeof t == "number" && t > 0 ? t : this.holdBackBase, i = Math.min(this.holdBackCeiling(e), this.holdBackBase + X);
|
|
2379
2386
|
i > r && (this.holdBackStepCount = 1, this.moveHoldBack(e, r, i, "connection-rtt", `connection rtt ${n} ms`));
|
|
2380
2387
|
}
|
|
2381
2388
|
holdBackCeiling(e) {
|
|
2382
|
-
let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t :
|
|
2389
|
+
let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t : Xn, r = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
|
|
2383
2390
|
return r > 1 ? Math.min(n, r - 1) : n;
|
|
2384
2391
|
}
|
|
2385
2392
|
sampleHoldBack(e) {
|
|
@@ -2388,7 +2395,7 @@ var er = class {
|
|
|
2388
2395
|
if (t !== "main" && t !== "audio") return;
|
|
2389
2396
|
let n = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag?.duration;
|
|
2390
2397
|
if (typeof n != "number" || !(n > 0)) return;
|
|
2391
|
-
let r =
|
|
2398
|
+
let r = Qn(e)?.loading;
|
|
2392
2399
|
if (!r || !(r.start > 0) || !(r.end > 0)) return;
|
|
2393
2400
|
let i = r.first > r.start ? r.first : r.end, a = Math.max(0, i - r.start) / (n * 1e3);
|
|
2394
2401
|
this.holdBackSamples.push({
|
|
@@ -2403,20 +2410,20 @@ var er = class {
|
|
|
2403
2410
|
this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [];
|
|
2404
2411
|
return;
|
|
2405
2412
|
}
|
|
2406
|
-
let t = Date.now(), n = t -
|
|
2413
|
+
let t = Date.now(), n = t - Un, r = this.holdBackSamples, i = 0;
|
|
2407
2414
|
for (; i < r.length && r[i].t < n;) i += 1;
|
|
2408
2415
|
i > 0 && r.splice(0, i);
|
|
2409
2416
|
let a = e.targetLatency;
|
|
2410
2417
|
if (typeof a != "number" || !(a > 0)) return;
|
|
2411
2418
|
this.holdBackBase < 0 && (this.holdBackBase = a);
|
|
2412
2419
|
let o = this.holdBackBase, s = this.holdBackCeiling(e);
|
|
2413
|
-
if (r.length <
|
|
2420
|
+
if (r.length < Wn) {
|
|
2414
2421
|
this.holdBackSlowTicks = 0;
|
|
2415
2422
|
return;
|
|
2416
2423
|
}
|
|
2417
2424
|
let c = r.map((e) => e.ratio).sort((e, t) => e - t), l = K(c, 95), u = K(c, 50), d = Math.round(l * 1e3);
|
|
2418
|
-
if (l >=
|
|
2419
|
-
if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks <
|
|
2425
|
+
if (l >= Gn && u >= Kn) {
|
|
2426
|
+
if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks < Jn) return;
|
|
2420
2427
|
this.holdBackSlowTicks = 0;
|
|
2421
2428
|
let t = Math.ceil((s - o) / X), n = Math.ceil((a - o) / X - 1e-9);
|
|
2422
2429
|
if (n > this.holdBackStepCount && (this.holdBackStepCount = n), this.holdBackStepCount >= t) return;
|
|
@@ -2426,7 +2433,7 @@ var er = class {
|
|
|
2426
2433
|
this.moveHoldBack(e, a, r, "slow-fetches", `part fetches slow (first byte p50 ${Math.round(u * 1e3)} / p95 ${d} ms per 1 s of media)`);
|
|
2427
2434
|
return;
|
|
2428
2435
|
}
|
|
2429
|
-
if (this.holdBackSlowTicks = 0, l >=
|
|
2436
|
+
if (this.holdBackSlowTicks = 0, l >= qn) {
|
|
2430
2437
|
this.holdBackFastSince = 0;
|
|
2431
2438
|
return;
|
|
2432
2439
|
}
|
|
@@ -2434,7 +2441,7 @@ var er = class {
|
|
|
2434
2441
|
this.holdBackFastSince = t;
|
|
2435
2442
|
return;
|
|
2436
2443
|
}
|
|
2437
|
-
if (t - this.holdBackFastSince <
|
|
2444
|
+
if (t - this.holdBackFastSince < Yn || (this.holdBackFastSince = t, this.holdBackStepCount === 0 || a !== this.holdBackApplied)) return;
|
|
2438
2445
|
--this.holdBackStepCount;
|
|
2439
2446
|
let f = Math.max(o, o + this.holdBackStepCount * X);
|
|
2440
2447
|
f >= a || this.moveHoldBack(e, a, f, "fast-fetches", `part fetches fast again (p95 first byte ${d} ms per 1 s of media)`);
|
|
@@ -2477,14 +2484,14 @@ var er = class {
|
|
|
2477
2484
|
} catch {}
|
|
2478
2485
|
}
|
|
2479
2486
|
startEstimate() {
|
|
2480
|
-
return this.deps.rememberBandwidth === !1 ?
|
|
2487
|
+
return this.deps.rememberBandwidth === !1 ? Jt : Be() ?? Jt;
|
|
2481
2488
|
}
|
|
2482
2489
|
maybeRememberBandwidth(e) {
|
|
2483
|
-
if (this.deps.rememberBandwidth === !1 || this.bwFragsLoaded <
|
|
2490
|
+
if (this.deps.rememberBandwidth === !1 || this.bwFragsLoaded < Yt) return;
|
|
2484
2491
|
let t = Date.now();
|
|
2485
|
-
if (!e && t - this.bwSavedAt <
|
|
2492
|
+
if (!e && t - this.bwSavedAt < Xt) return;
|
|
2486
2493
|
let n = this.hls?.bandwidthEstimate;
|
|
2487
|
-
typeof n != "number" || !Number.isFinite(n) || n <= 0 || (this.bwSavedAt = t,
|
|
2494
|
+
typeof n != "number" || !Number.isFinite(n) || n <= 0 || (this.bwSavedAt = t, Ve(n));
|
|
2488
2495
|
}
|
|
2489
2496
|
destroy() {
|
|
2490
2497
|
if (this.maybeRememberBandwidth(!0), this.detachFrames?.(), this.detachFrames = null, this.prefetch?.destroy(), this.prefetch = null, this.clearRecoveryReset(), this.capTimer &&= (clearTimeout(this.capTimer), null), this.capObserver &&= (this.capObserver.disconnect(), null), this.unwatchDprChanges(), this.endWatchdog &&= (clearInterval(this.endWatchdog), null), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onOffline && typeof window < "u" && (window.removeEventListener("offline", this.onOffline), this.onOffline = null), this.onOnline && typeof window < "u" && (window.removeEventListener("online", this.onOnline), this.onOnline = null), this.onSeeking &&= (this.deps.video.removeEventListener("seeking", this.onSeeking), null), this.onTimeUpdate &&= (this.deps.video.removeEventListener("timeupdate", this.onTimeUpdate), null), this.onPause &&= (this.deps.video.removeEventListener("pause", this.onPause), null), this.onPlay &&= (this.deps.video.removeEventListener("play", this.onPlay), null), this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null), this.licenseRetryTimer &&= (clearTimeout(this.licenseRetryTimer), null), this.hls) {
|
|
@@ -2502,7 +2509,7 @@ var er = class {
|
|
|
2502
2509
|
scheduleLicenseRetry(t) {
|
|
2503
2510
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
2504
2511
|
let n = t.response?.code ?? 0;
|
|
2505
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
2512
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= $t) return !1;
|
|
2506
2513
|
this.licenseRecoveries += 1;
|
|
2507
2514
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
2508
2515
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -2538,7 +2545,7 @@ var er = class {
|
|
|
2538
2545
|
this.offlineHold = !0, this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null);
|
|
2539
2546
|
return;
|
|
2540
2547
|
}
|
|
2541
|
-
if (this.networkRecoveries <
|
|
2548
|
+
if (this.networkRecoveries < Qt) {
|
|
2542
2549
|
this.networkRecoveries += 1;
|
|
2543
2550
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
2544
2551
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -2555,7 +2562,7 @@ var er = class {
|
|
|
2555
2562
|
return;
|
|
2556
2563
|
}
|
|
2557
2564
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
2558
|
-
if (this.mediaRecoveries <
|
|
2565
|
+
if (this.mediaRecoveries < Zt) {
|
|
2559
2566
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
2560
2567
|
return;
|
|
2561
2568
|
}
|
|
@@ -2576,18 +2583,18 @@ var er = class {
|
|
|
2576
2583
|
}
|
|
2577
2584
|
}
|
|
2578
2585
|
toError(t, r = "PLAYBACK") {
|
|
2579
|
-
let o = t.response?.code ?? 0, s = t.details ?? t.type, c = t.reason ?? t.error?.message ?? "", l = r === "DRM" && o === 403 && t.details === e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED ? i(
|
|
2586
|
+
let o = t.response?.code ?? 0, s = t.details ?? t.type, c = t.reason ?? t.error?.message ?? "", l = r === "DRM" && o === 403 && t.details === e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED ? i(Pt(t.networkDetails)) : void 0;
|
|
2580
2587
|
return new n(r === "DRM" ? a(o, l) : r === "NETWORK" && o === 0 ? "NETWORK" : o === 401 ? "UNAUTHORIZED" : o === 403 ? "FORBIDDEN" : "INTERNAL", o, `${r} error: ${s}${c ? ` (${c})` : ""}`, l ? { serverCode: l } : void 0);
|
|
2581
2588
|
}
|
|
2582
|
-
},
|
|
2589
|
+
}, rr = 15e3, ir = 6e5, ar = 3e5, or = 100, Z = 1, sr = 1e3, cr = 3e4, lr = 1e3, ur = {
|
|
2583
2590
|
inline: "PRESENTATION_INLINE",
|
|
2584
2591
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
2585
2592
|
pip: "PRESENTATION_PIP"
|
|
2586
|
-
},
|
|
2593
|
+
}, dr = {
|
|
2587
2594
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
2588
2595
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
2589
2596
|
none: "KEY_SYSTEM_NONE"
|
|
2590
|
-
},
|
|
2597
|
+
}, fr = /* @__PURE__ */ new Set([
|
|
2591
2598
|
"INVALID_URN",
|
|
2592
2599
|
"NOT_FOUND",
|
|
2593
2600
|
"GEO_DENIED",
|
|
@@ -2598,7 +2605,7 @@ var er = class {
|
|
|
2598
2605
|
"FORBIDDEN",
|
|
2599
2606
|
"RATE_LIMITED",
|
|
2600
2607
|
"TIMEOUT"
|
|
2601
|
-
]),
|
|
2608
|
+
]), pr = {
|
|
2602
2609
|
idle: "PLAYER_STATE_IDLE",
|
|
2603
2610
|
waiting: "PLAYER_STATE_WAITING",
|
|
2604
2611
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -2608,7 +2615,7 @@ var er = class {
|
|
|
2608
2615
|
ended: "PLAYER_STATE_ENDED",
|
|
2609
2616
|
error: "PLAYER_STATE_ERROR"
|
|
2610
2617
|
};
|
|
2611
|
-
function
|
|
2618
|
+
function mr(e) {
|
|
2612
2619
|
try {
|
|
2613
2620
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
2614
2621
|
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);
|
|
@@ -2616,8 +2623,8 @@ function fr(e) {
|
|
|
2616
2623
|
return;
|
|
2617
2624
|
}
|
|
2618
2625
|
}
|
|
2619
|
-
var
|
|
2620
|
-
function
|
|
2626
|
+
var hr = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), gr = /* @__PURE__ */ new Set(), _r = /* @__PURE__ */ new Set(), vr = /* @__PURE__ */ new Set(), yr = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
|
|
2627
|
+
function br(e) {
|
|
2621
2628
|
if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
|
|
2622
2629
|
let t;
|
|
2623
2630
|
try {
|
|
@@ -2626,19 +2633,19 @@ function vr(e) {
|
|
|
2626
2633
|
} catch {
|
|
2627
2634
|
return;
|
|
2628
2635
|
}
|
|
2629
|
-
if (
|
|
2630
|
-
|
|
2631
|
-
for (let e of
|
|
2636
|
+
if (gr.has(t) && !_r.has(t)) {
|
|
2637
|
+
_r.add(t), _(yr(new URL(t).origin));
|
|
2638
|
+
for (let e of vr) e.noteCspBlocked();
|
|
2632
2639
|
}
|
|
2633
2640
|
}
|
|
2634
|
-
function
|
|
2641
|
+
function xr(e, t) {
|
|
2635
2642
|
return _(t, e), { disabledReason: t };
|
|
2636
2643
|
}
|
|
2637
|
-
function
|
|
2638
|
-
if (n) return t && !
|
|
2644
|
+
function Sr(e, t, n) {
|
|
2645
|
+
if (n) return t && !hr(t, n) && _(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
|
|
2639
2646
|
if (t) return { endpoint: t };
|
|
2640
|
-
if (t !== void 0) return
|
|
2641
|
-
let r =
|
|
2647
|
+
if (t !== void 0) return xr("empty-endpoint", "analytics is disabled: no QoE beacons will be sent. analytics.endpoint was supplied but empty. Pass a real beacons origin, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, or omit the option to derive it from baseUrl (or analytics: false to opt out).");
|
|
2648
|
+
let r = mr(e);
|
|
2642
2649
|
if (r) return { endpoint: r };
|
|
2643
2650
|
let i;
|
|
2644
2651
|
try {
|
|
@@ -2646,9 +2653,9 @@ function br(e, t, n) {
|
|
|
2646
2653
|
} catch {
|
|
2647
2654
|
i = e;
|
|
2648
2655
|
}
|
|
2649
|
-
return
|
|
2656
|
+
return xr(i, `analytics is disabled: no QoE beacons will be sent. The beacons endpoint cannot be derived from the baseUrl host "${i}" — the convention is feed[-dev].<domain> → beacons[-dev].<domain>. Pass an explicit endpoint, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, to createPlayer (or analytics: false to opt out deliberately).`);
|
|
2650
2657
|
}
|
|
2651
|
-
var
|
|
2658
|
+
var Cr = class {
|
|
2652
2659
|
opts;
|
|
2653
2660
|
url;
|
|
2654
2661
|
cspKey;
|
|
@@ -2730,8 +2737,8 @@ var xr = class {
|
|
|
2730
2737
|
constructor(e) {
|
|
2731
2738
|
this.opts = {
|
|
2732
2739
|
...e,
|
|
2733
|
-
heartbeatMs: e.heartbeatMs ??
|
|
2734
|
-
idleMs: e.idleMs ??
|
|
2740
|
+
heartbeatMs: e.heartbeatMs ?? rr,
|
|
2741
|
+
idleMs: e.idleMs ?? ir
|
|
2735
2742
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
|
|
2736
2743
|
try {
|
|
2737
2744
|
let e = new URL(this.url);
|
|
@@ -2748,11 +2755,11 @@ var xr = class {
|
|
|
2748
2755
|
sdkVersion: this.opts.sdkVersion,
|
|
2749
2756
|
...this.opts.environment
|
|
2750
2757
|
};
|
|
2751
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
2758
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), sr), this.lastTickMs = this.now(), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), document.addEventListener("freeze", this.onFreeze), document.addEventListener("resume", this.onResume), this.cspKey && gr.add(this.cspKey), document.addEventListener("securitypolicyviolation", br), vr.add(this), this.noteCspBlocked(), this.onVisibility());
|
|
2752
2759
|
}
|
|
2753
2760
|
checkSuspension(e) {
|
|
2754
2761
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
2755
|
-
let t = Math.max(this.opts.idleMs,
|
|
2762
|
+
let t = Math.max(this.opts.idleMs, ar);
|
|
2756
2763
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
2757
2764
|
}
|
|
2758
2765
|
syncIdle(e) {
|
|
@@ -2766,21 +2773,21 @@ var xr = class {
|
|
|
2766
2773
|
noteStateChange(e, t, n, r) {
|
|
2767
2774
|
if (this.endedFlag || e === t) return;
|
|
2768
2775
|
let i = this.now();
|
|
2769
|
-
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(
|
|
2776
|
+
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(Z, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(Z, i - this.startupAnchorMs)), 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") {
|
|
2770
2777
|
this.stallIsSeekInduced = this.seekInduced(i);
|
|
2771
2778
|
let e = !this.isHidden && !this.stallIsSeekInduced;
|
|
2772
|
-
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(
|
|
2779
|
+
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(Z, Math.round(this.playingTotalMs)));
|
|
2773
2780
|
} else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
|
|
2774
2781
|
this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
|
|
2775
2782
|
let a = {
|
|
2776
|
-
fromState:
|
|
2777
|
-
toState:
|
|
2778
|
-
presentation:
|
|
2783
|
+
fromState: pr[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2784
|
+
toState: pr[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2785
|
+
presentation: ur[this.presentation]
|
|
2779
2786
|
}, o = this.causeOf(e, t, i);
|
|
2780
2787
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
2781
2788
|
}
|
|
2782
2789
|
seekInduced(e) {
|
|
2783
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
2790
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < lr;
|
|
2784
2791
|
}
|
|
2785
2792
|
causeOf(e, t, n) {
|
|
2786
2793
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -2817,25 +2824,25 @@ var xr = class {
|
|
|
2817
2824
|
}
|
|
2818
2825
|
this.muteChanges += 1;
|
|
2819
2826
|
let r = this.now();
|
|
2820
|
-
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(
|
|
2827
|
+
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(Z, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
|
|
2821
2828
|
}
|
|
2822
2829
|
notePresentation(e) {
|
|
2823
2830
|
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
2824
2831
|
}
|
|
2825
2832
|
notePlayIntent() {
|
|
2826
|
-
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs =
|
|
2833
|
+
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = Z), this.firstPlaylistMs > 0 && (this.firstPlaylistMs = Z), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = Z), this.drmSetupMs > 0 && (this.drmSetupMs = Z));
|
|
2827
2834
|
}
|
|
2828
2835
|
noteReady() {
|
|
2829
|
-
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(
|
|
2836
|
+
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(Z, this.now() - this.startupAnchorMs));
|
|
2830
2837
|
}
|
|
2831
2838
|
noteFirstPlaylist() {
|
|
2832
|
-
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(
|
|
2839
|
+
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(Z, this.now() - this.startupAnchorMs));
|
|
2833
2840
|
}
|
|
2834
2841
|
noteDrmReady() {
|
|
2835
|
-
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(
|
|
2842
|
+
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(Z, this.now() - this.startupAnchorMs));
|
|
2836
2843
|
}
|
|
2837
2844
|
noteFirstBytes() {
|
|
2838
|
-
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(
|
|
2845
|
+
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(Z, this.now() - this.startupAnchorMs));
|
|
2839
2846
|
}
|
|
2840
2847
|
noteSeek() {
|
|
2841
2848
|
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
@@ -2854,7 +2861,7 @@ var xr = class {
|
|
|
2854
2861
|
let r = n ?? "";
|
|
2855
2862
|
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";
|
|
2856
2863
|
if (e === "DRM_CLIENT" || e === "DRM_DEVICE_REVOKED") return "ERROR_STAGE_DRM";
|
|
2857
|
-
if (
|
|
2864
|
+
if (fr.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
2858
2865
|
let i = t ?? "";
|
|
2859
2866
|
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";
|
|
2860
2867
|
}
|
|
@@ -2886,7 +2893,7 @@ var xr = class {
|
|
|
2886
2893
|
let l = t.droppedFrames ?? 0;
|
|
2887
2894
|
l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
|
|
2888
2895
|
let u = t.renditionSwitches ?? 0;
|
|
2889
|
-
u > this.lastSwitches && (o.renditionSwitchesDelta = u - this.lastSwitches), this.lastSwitches = u, n > this.lastHbPlayingMs && (o.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (o.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, i > this.lastHbRebufferMs && (o.rebufferMsDelta = Math.round(i - this.lastHbRebufferMs)), this.lastHbRebufferMs = i, this.rebufferCount > this.lastHbRebufferCount && (o.rebufferCountDelta = this.rebufferCount - this.lastHbRebufferCount), this.lastHbRebufferCount = this.rebufferCount, a > this.lastHbActiveMs && (o.activeMsDelta = Math.round(a - this.lastHbActiveMs)), this.lastHbActiveMs = a, typeof t.latencySeconds == "number" && (o.latencyMs = Math.round(t.latencySeconds * 1e3)), typeof t.targetLatencySeconds == "number" && (o.targetLatencyMs = Math.round(t.targetLatencySeconds * 1e3)), typeof t.bandwidthKbps == "number" && (o.bandwidthEstKbps = t.bandwidthKbps), typeof t.levelHeight == "number" && (o.renditionHeight = t.levelHeight), typeof t.renditionBitrateKbps == "number" && (o.renditionBitrateKbps = t.renditionBitrateKbps), t.atLiveEdge === !0 && (o.atLiveEdge = !0), typeof t.bufferedMs == "number" && t.bufferedMs > 0 && (o.bufferedMs = Math.round(t.bufferedMs)), o.playerState =
|
|
2896
|
+
u > this.lastSwitches && (o.renditionSwitchesDelta = u - this.lastSwitches), this.lastSwitches = u, n > this.lastHbPlayingMs && (o.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (o.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, i > this.lastHbRebufferMs && (o.rebufferMsDelta = Math.round(i - this.lastHbRebufferMs)), this.lastHbRebufferMs = i, this.rebufferCount > this.lastHbRebufferCount && (o.rebufferCountDelta = this.rebufferCount - this.lastHbRebufferCount), this.lastHbRebufferCount = this.rebufferCount, a > this.lastHbActiveMs && (o.activeMsDelta = Math.round(a - this.lastHbActiveMs)), this.lastHbActiveMs = a, typeof t.latencySeconds == "number" && (o.latencyMs = Math.round(t.latencySeconds * 1e3)), typeof t.targetLatencySeconds == "number" && (o.targetLatencyMs = Math.round(t.targetLatencySeconds * 1e3)), typeof t.bandwidthKbps == "number" && (o.bandwidthEstKbps = t.bandwidthKbps), typeof t.levelHeight == "number" && (o.renditionHeight = t.levelHeight), typeof t.renditionBitrateKbps == "number" && (o.renditionBitrateKbps = t.renditionBitrateKbps), t.atLiveEdge === !0 && (o.atLiveEdge = !0), typeof t.bufferedMs == "number" && t.bufferedMs > 0 && (o.bufferedMs = Math.round(t.bufferedMs)), o.playerState = pr[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
|
|
2890
2897
|
let d = this.mutedTotalMs;
|
|
2891
2898
|
this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
|
|
2892
2899
|
let f = t.upshifts ?? 0;
|
|
@@ -2908,13 +2915,13 @@ var xr = class {
|
|
|
2908
2915
|
maybeEmitMediaInfo(e) {
|
|
2909
2916
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
2910
2917
|
let t = {};
|
|
2911
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
2918
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = dr[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);
|
|
2912
2919
|
let n = JSON.stringify(t);
|
|
2913
2920
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
2914
2921
|
}
|
|
2915
2922
|
end(e, t) {
|
|
2916
2923
|
if (this.endedFlag) return;
|
|
2917
|
-
this.endedFlag = !0,
|
|
2924
|
+
this.endedFlag = !0, vr.delete(this);
|
|
2918
2925
|
let n = t ?? this.now();
|
|
2919
2926
|
this.playingSinceMs !== null && (this.playingTotalMs += n - this.playingSinceMs, this.playingSinceMs = null), this.hiddenSinceMs !== null && (this.hiddenTotalMs += n - this.hiddenSinceMs, this.hiddenSinceMs = null), this.bufferingSinceMs !== null && (this.rebufferTotalMs += n - this.bufferingSinceMs, this.bufferingSinceMs = null), this.mutedSinceMs !== null && (this.mutedTotalMs += n - this.mutedSinceMs, this.mutedSinceMs = null), this.waitingSinceMs !== null && (this.waitingTotalMs += n - this.waitingSinceMs, this.waitingSinceMs = null), this.isPlaying = !1, this.syncActive(n), this.closePresentation(n), this.firstFlushTimer &&= (clearTimeout(this.firstFlushTimer), null), this.timer &&= (clearInterval(this.timer), null), this.idleTimer &&= (clearTimeout(this.idleTimer), null), typeof window < "u" && window.removeEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), document.removeEventListener("freeze", this.onFreeze), document.removeEventListener("resume", this.onResume));
|
|
2920
2927
|
let r = this.safeSample();
|
|
@@ -2928,7 +2935,7 @@ var xr = class {
|
|
|
2928
2935
|
let c = r?.positionMs ?? 0;
|
|
2929
2936
|
c > 0 && (i.exitPositionMs = Math.round(c)), this.activeTotalMs > 0 && (i.activeWatchTimeMs = Math.round(this.activeTotalMs)), this.mutedTotalMs > 0 && (i.mutedTimeMs = Math.round(this.mutedTotalMs));
|
|
2930
2937
|
let l = e !== "END_REASON_ENDED";
|
|
2931
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
2938
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= cr && (i.abandonAfterStallMs = Math.max(Z, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= cr && (i.abandonAfterErrorMs = Math.max(Z, Math.round(n - this.lastErrorMs))), this.fullscreenTotalMs > 0 && (i.fullscreenTimeMs = Math.round(this.fullscreenTotalMs)), this.pipTotalMs > 0 && (i.pipTimeMs = Math.round(this.pipTotalMs)), this.volumeChanges > 0 && (i.volumeChanges = this.volumeChanges), this.muteChanges > 0 && (i.muteChanges = this.muteChanges);
|
|
2932
2939
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
2933
2940
|
u > 0 && (i.decodedFramesTotal = u), e === "END_REASON_STOPPED" && this.startupTimeMs === 0 && this.lastErrorStage === null && (e = "END_REASON_ABORTED", i.reason = e), this.startupTimeMs === 0 && e !== "END_REASON_ABORTED" && (i.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: i })), this.flush(e === "END_REASON_PAGEHIDE");
|
|
2934
2941
|
}
|
|
@@ -2948,13 +2955,13 @@ var xr = class {
|
|
|
2948
2955
|
};
|
|
2949
2956
|
}
|
|
2950
2957
|
noteCspBlocked() {
|
|
2951
|
-
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(
|
|
2958
|
+
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(yr(new URL(this.url).origin)));
|
|
2952
2959
|
}
|
|
2953
2960
|
cspBlocked() {
|
|
2954
|
-
return !!this.cspKey &&
|
|
2961
|
+
return !!this.cspKey && _r.has(this.cspKey);
|
|
2955
2962
|
}
|
|
2956
2963
|
enqueue(e) {
|
|
2957
|
-
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
2964
|
+
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > or;) {
|
|
2958
2965
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
2959
2966
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
2960
2967
|
}
|
|
@@ -2981,7 +2988,7 @@ var xr = class {
|
|
|
2981
2988
|
};
|
|
2982
2989
|
//#endregion
|
|
2983
2990
|
//#region src/core/environment.ts
|
|
2984
|
-
function
|
|
2991
|
+
function wr() {
|
|
2985
2992
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
2986
2993
|
let e;
|
|
2987
2994
|
try {
|
|
@@ -3006,14 +3013,14 @@ function Sr() {
|
|
|
3006
3013
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
3007
3014
|
};
|
|
3008
3015
|
}
|
|
3009
|
-
function
|
|
3016
|
+
function Tr() {
|
|
3010
3017
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
3011
3018
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
3012
3019
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
3013
3020
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
3014
3021
|
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";
|
|
3015
3022
|
}
|
|
3016
|
-
function
|
|
3023
|
+
function Er() {
|
|
3017
3024
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
3018
3025
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
3019
3026
|
let t = {
|
|
@@ -3032,17 +3039,17 @@ function wr() {
|
|
|
3032
3039
|
}
|
|
3033
3040
|
return typeof e.downlink == "number" && e.downlink > 0 && (i.downlinkKbps = Math.round(e.downlink * 1e3)), typeof e.rtt == "number" && e.rtt > 0 && (i.rttMs = Math.round(e.rtt)), e.saveData && (i.saveData = !0), i;
|
|
3034
3041
|
}
|
|
3035
|
-
function
|
|
3036
|
-
let t =
|
|
3037
|
-
deviceClass:
|
|
3042
|
+
function Dr(e) {
|
|
3043
|
+
let t = wr(), n = {
|
|
3044
|
+
deviceClass: Tr(),
|
|
3038
3045
|
integration: t.integration,
|
|
3039
|
-
...
|
|
3046
|
+
...Er()
|
|
3040
3047
|
};
|
|
3041
3048
|
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);
|
|
3042
3049
|
let r = e.getBoundingClientRect?.();
|
|
3043
3050
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
3044
3051
|
}
|
|
3045
|
-
async function
|
|
3052
|
+
async function Or() {
|
|
3046
3053
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
3047
3054
|
if (!e?.getHighEntropyValues) return {};
|
|
3048
3055
|
try {
|
|
@@ -3054,7 +3061,7 @@ async function Er() {
|
|
|
3054
3061
|
}
|
|
3055
3062
|
//#endregion
|
|
3056
3063
|
//#region src/core/version.ts
|
|
3057
|
-
var
|
|
3064
|
+
var kr = "2.27.2", Ar = {
|
|
3058
3065
|
accent: "#E1B600",
|
|
3059
3066
|
accentText: "#1B1C23",
|
|
3060
3067
|
background: "#0e0f13",
|
|
@@ -3065,7 +3072,7 @@ var Dr = "2.27.1", Or = {
|
|
|
3065
3072
|
border: "rgba(255, 255, 255, 0.1)",
|
|
3066
3073
|
radius: "8px",
|
|
3067
3074
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
3068
|
-
},
|
|
3075
|
+
}, jr = {
|
|
3069
3076
|
accent: "--havik-accent",
|
|
3070
3077
|
accentText: "--havik-accent-text",
|
|
3071
3078
|
background: "--havik-bg",
|
|
@@ -3077,26 +3084,26 @@ var Dr = "2.27.1", Or = {
|
|
|
3077
3084
|
radius: "--havik-radius",
|
|
3078
3085
|
fontFamily: "--havik-font"
|
|
3079
3086
|
};
|
|
3080
|
-
function
|
|
3087
|
+
function Mr(e, t) {
|
|
3081
3088
|
let n = {
|
|
3082
|
-
...
|
|
3089
|
+
...Ar,
|
|
3083
3090
|
...t
|
|
3084
3091
|
};
|
|
3085
|
-
for (let t of Object.keys(
|
|
3092
|
+
for (let t of Object.keys(jr)) e.style.setProperty(jr[t], n[t]);
|
|
3086
3093
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
3087
3094
|
}
|
|
3088
3095
|
//#endregion
|
|
3089
3096
|
//#region src/ui/styles.ts
|
|
3090
|
-
var
|
|
3091
|
-
function
|
|
3092
|
-
let n = e.querySelector(`style#${
|
|
3093
|
-
if (n && (!t ||
|
|
3097
|
+
var Nr = "havik-player-styles", Pr = "\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 touch-action:manipulation}\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/* Absolutely centred, NOT a flex sibling of .havik-center: the hidden center\n button (.havik-gone) still occupies its 74px in the row, which pushed an\n in-flow spinner 37px right of centre. */\n.havik-spinner{position:absolute;inset:0;margin:auto;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", Fr = /* @__PURE__ */ new WeakMap();
|
|
3098
|
+
function Ir(e = document, t) {
|
|
3099
|
+
let n = e.querySelector(`style#${Nr}`);
|
|
3100
|
+
if (n && (!t || Fr.get(n) === t)) return;
|
|
3094
3101
|
let r = e.createElement("style");
|
|
3095
|
-
r.id =
|
|
3102
|
+
r.id = Nr, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = Pr, Fr.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
|
|
3096
3103
|
}
|
|
3097
3104
|
//#endregion
|
|
3098
3105
|
//#region src/ui/icons.ts
|
|
3099
|
-
var
|
|
3106
|
+
var Lr = {
|
|
3100
3107
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
3101
3108
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
3102
3109
|
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\"/>",
|
|
@@ -3109,12 +3116,12 @@ var Fr = {
|
|
|
3109
3116
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
3110
3117
|
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\"/>"
|
|
3111
3118
|
};
|
|
3112
|
-
function
|
|
3113
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
3119
|
+
function Q(e) {
|
|
3120
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Lr[e]}</svg>`;
|
|
3114
3121
|
}
|
|
3115
3122
|
//#endregion
|
|
3116
3123
|
//#region src/ui/controls.ts
|
|
3117
|
-
var
|
|
3124
|
+
var Rr = 3e3, zr = 250, Br = /* @__PURE__ */ new Set([
|
|
3118
3125
|
"GONE",
|
|
3119
3126
|
"NOT_FOUND",
|
|
3120
3127
|
"GEO_DENIED",
|
|
@@ -3122,15 +3129,15 @@ var Ir = 3e3, Lr = 250, Rr = /* @__PURE__ */ new Set([
|
|
|
3122
3129
|
"UNAUTHORIZED",
|
|
3123
3130
|
"DRM_DEVICE_REVOKED"
|
|
3124
3131
|
]);
|
|
3125
|
-
function
|
|
3132
|
+
function Vr(e) {
|
|
3126
3133
|
let t = "This match isn't available in your country";
|
|
3127
3134
|
return e ? `${t} (${e})` : t;
|
|
3128
3135
|
}
|
|
3129
|
-
var
|
|
3130
|
-
function
|
|
3131
|
-
return new
|
|
3136
|
+
var Hr = "This device can't play protected video";
|
|
3137
|
+
function Ur(e) {
|
|
3138
|
+
return new Wr(e);
|
|
3132
3139
|
}
|
|
3133
|
-
var
|
|
3140
|
+
var Wr = class {
|
|
3134
3141
|
root;
|
|
3135
3142
|
video;
|
|
3136
3143
|
player;
|
|
@@ -3179,7 +3186,7 @@ var Hr = class {
|
|
|
3179
3186
|
scrubbing = !1;
|
|
3180
3187
|
offFns = [];
|
|
3181
3188
|
constructor(e) {
|
|
3182
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
3189
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Rr, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.streamEnded = e.streamEnded ?? (() => !1), this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, this.offlineMessage = e.offlineMessage ?? "No internet connection — waiting to reconnect", Ir(this.doc, e.cspNonce), 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");
|
|
3183
3190
|
let t = (e, t, n) => {
|
|
3184
3191
|
let r = this.doc.createElement(e);
|
|
3185
3192
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -3190,12 +3197,12 @@ var Hr = class {
|
|
|
3190
3197
|
"aria-label": r,
|
|
3191
3198
|
title: r
|
|
3192
3199
|
});
|
|
3193
|
-
return i.innerHTML =
|
|
3200
|
+
return i.innerHTML = Q(n), i;
|
|
3194
3201
|
};
|
|
3195
3202
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
3196
3203
|
type: "button",
|
|
3197
3204
|
"aria-label": "Play"
|
|
3198
|
-
}), this.center.innerHTML =
|
|
3205
|
+
}), this.center.innerHTML = Q("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", {
|
|
3199
3206
|
role: "slider",
|
|
3200
3207
|
"aria-label": "Seek",
|
|
3201
3208
|
"aria-valuemin": "0",
|
|
@@ -3213,7 +3220,7 @@ var Hr = class {
|
|
|
3213
3220
|
"aria-label": "Volume"
|
|
3214
3221
|
});
|
|
3215
3222
|
let a = t("div", "havik-vol");
|
|
3216
|
-
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML =
|
|
3223
|
+
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Q("liveDot");
|
|
3217
3224
|
let o = this.doc.createElement("span");
|
|
3218
3225
|
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";
|
|
3219
3226
|
let s = t("div", "havik-spacer");
|
|
@@ -3265,7 +3272,7 @@ var Hr = class {
|
|
|
3265
3272
|
let t = this.surfaceWasHidden;
|
|
3266
3273
|
this.tapTimer = setTimeout(() => {
|
|
3267
3274
|
this.tapTimer = void 0, this.toggleBar(t);
|
|
3268
|
-
},
|
|
3275
|
+
}, zr);
|
|
3269
3276
|
}
|
|
3270
3277
|
toggleBar(e) {
|
|
3271
3278
|
e ? this.poke() : this.hideIfIdle();
|
|
@@ -3292,7 +3299,7 @@ var Hr = class {
|
|
|
3292
3299
|
this.renderStatus(t);
|
|
3293
3300
|
}
|
|
3294
3301
|
statusMessageFor(e) {
|
|
3295
|
-
return e === "ended" ? this.isGone() ? this.endedMessage : this.player.endedReason === "interrupted" ? this.interruptedMessage : this.endedMessage : e === "offline" ? this.offlineMessage : e === "waiting" ? this.hasPlayed ? "Reconnecting — please stand by" : "Starting soon…" : e === "error" ? this.errorMessage === void 0 ? this.lastError?.code === "GEO_DENIED" ?
|
|
3302
|
+
return e === "ended" ? this.isGone() ? this.endedMessage : this.player.endedReason === "interrupted" ? this.interruptedMessage : this.endedMessage : e === "offline" ? this.offlineMessage : e === "waiting" ? this.hasPlayed ? "Reconnecting — please stand by" : "Starting soon…" : e === "error" ? this.errorMessage === void 0 ? this.lastError?.code === "GEO_DENIED" ? Vr(this.lastError.country) : this.lastError?.code === "DRM_DEVICE_REVOKED" ? Hr : this.lastError?.message ?? "Playback unavailable" : this.errorMessage : null;
|
|
3296
3303
|
}
|
|
3297
3304
|
renderStatus(e) {
|
|
3298
3305
|
let t = this.statusMessageFor(e);
|
|
@@ -3304,12 +3311,12 @@ var Hr = class {
|
|
|
3304
3311
|
}
|
|
3305
3312
|
if (e === "preplay") {
|
|
3306
3313
|
let e = this.doc.createElement("button");
|
|
3307
|
-
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML =
|
|
3314
|
+
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = Q("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
|
|
3308
3315
|
} else {
|
|
3309
3316
|
let r = this.doc.createElement("div");
|
|
3310
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
3317
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Br.has(this.lastError.code)) {
|
|
3311
3318
|
let e = this.doc.createElement("button");
|
|
3312
|
-
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${
|
|
3319
|
+
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${Q("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
|
|
3313
3320
|
}
|
|
3314
3321
|
}
|
|
3315
3322
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -3348,7 +3355,7 @@ var Hr = class {
|
|
|
3348
3355
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
3349
3356
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
3350
3357
|
}
|
|
3351
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
3358
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Gr(this.video.currentTime)} / ${Gr(this.video.duration)}`);
|
|
3352
3359
|
}
|
|
3353
3360
|
syncLive() {
|
|
3354
3361
|
let e = this.player.getStats(), t = e.isLive !== !1, n = this.isGone(), r = this.player.state === "ended" || n, i = !t && !this.streamEnded() && !n;
|
|
@@ -3398,17 +3405,17 @@ var Hr = class {
|
|
|
3398
3405
|
renderQualityMenu() {
|
|
3399
3406
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
3400
3407
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
3401
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
3408
|
+
for (let n of e) this.menu.append(this.menuItem(Kr(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
3402
3409
|
}
|
|
3403
3410
|
renderAudioMenu() {
|
|
3404
3411
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
3405
3412
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
3406
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
3413
|
+
for (let t of e) this.menu.append(this.menuItem(qr(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
3407
3414
|
}
|
|
3408
3415
|
renderCcMenu() {
|
|
3409
3416
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
3410
3417
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
3411
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
3418
|
+
for (let t of e) this.menu.append(this.menuItem(Jr(t), !1, () => this.player.setTextTrack(t.id)));
|
|
3412
3419
|
}
|
|
3413
3420
|
onTracksChanged() {
|
|
3414
3421
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -3428,14 +3435,14 @@ var Hr = class {
|
|
|
3428
3435
|
}
|
|
3429
3436
|
async toggleFullscreen() {
|
|
3430
3437
|
try {
|
|
3431
|
-
|
|
3438
|
+
S(this.video, this.root) ? await T(this.video, this.root) : await w(this.video, this.root);
|
|
3432
3439
|
} catch {}
|
|
3433
3440
|
}
|
|
3434
3441
|
syncFullscreenSupport() {
|
|
3435
|
-
this.fsSupported =
|
|
3442
|
+
this.fsSupported = C(this.video, this.root), this.fsBtn.style.display = this.fsSupported ? "" : "none";
|
|
3436
3443
|
}
|
|
3437
3444
|
syncFullscreen() {
|
|
3438
|
-
let e =
|
|
3445
|
+
let e = S(this.video, this.root);
|
|
3439
3446
|
this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
|
|
3440
3447
|
}
|
|
3441
3448
|
poke() {
|
|
@@ -3496,7 +3503,7 @@ var Hr = class {
|
|
|
3496
3503
|
}
|
|
3497
3504
|
}
|
|
3498
3505
|
setIcon(e, t) {
|
|
3499
|
-
e.innerHTML =
|
|
3506
|
+
e.innerHTML = Q(t);
|
|
3500
3507
|
}
|
|
3501
3508
|
destroy() {
|
|
3502
3509
|
this.hideTimer && clearTimeout(this.hideTimer), this.tapTimer && clearTimeout(this.tapTimer);
|
|
@@ -3513,23 +3520,23 @@ var Hr = class {
|
|
|
3513
3520
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
3514
3521
|
}
|
|
3515
3522
|
};
|
|
3516
|
-
function
|
|
3523
|
+
function Gr(e) {
|
|
3517
3524
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
3518
3525
|
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");
|
|
3519
3526
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
3520
3527
|
}
|
|
3521
|
-
function
|
|
3528
|
+
function Kr(e) {
|
|
3522
3529
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
3523
3530
|
}
|
|
3524
|
-
function
|
|
3531
|
+
function qr(e) {
|
|
3525
3532
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3526
3533
|
}
|
|
3527
|
-
function
|
|
3534
|
+
function Jr(e) {
|
|
3528
3535
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3529
3536
|
}
|
|
3530
3537
|
//#endregion
|
|
3531
3538
|
//#region src/managed/index.ts
|
|
3532
|
-
var
|
|
3539
|
+
var Yr = 6e3, Xr = 45e3, Zr = 2e3, Qr = 3, $r = 5e3, ei = 2e3, ti = 48e4, ni = "keySystemLicenseRequestFailed", ri = /* @__PURE__ */ new Set([
|
|
3533
3540
|
"GONE",
|
|
3534
3541
|
"NOT_FOUND",
|
|
3535
3542
|
"INVALID_URN",
|
|
@@ -3537,27 +3544,27 @@ var qr = 6e3, Jr = 45e3, Yr = 2e3, Xr = 3, Zr = 5e3, Qr = 2e3, $r = 48e4, ei = "
|
|
|
3537
3544
|
"GEO_DENIED",
|
|
3538
3545
|
"DRM_DEVICE_REVOKED"
|
|
3539
3546
|
]);
|
|
3540
|
-
function
|
|
3541
|
-
return !
|
|
3547
|
+
function ii(e) {
|
|
3548
|
+
return !ri.has(e);
|
|
3542
3549
|
}
|
|
3543
|
-
function
|
|
3550
|
+
function ai(e) {
|
|
3544
3551
|
if (e.env !== void 0 && e.baseUrl !== void 0) throw new n("INTERNAL", 0, `createPlayer: pass env OR baseUrl, not both (got env=${JSON.stringify(e.env)} and baseUrl=${JSON.stringify(e.baseUrl)})`);
|
|
3545
3552
|
if (e.env !== void 0) return lt(e.env);
|
|
3546
3553
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
3547
3554
|
return e.baseUrl;
|
|
3548
3555
|
}
|
|
3549
|
-
async function
|
|
3556
|
+
async function oi(e) {
|
|
3550
3557
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
3551
|
-
let t =
|
|
3558
|
+
let t = ai(e);
|
|
3552
3559
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
3553
3560
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
3554
|
-
let r = new
|
|
3561
|
+
let r = new si({
|
|
3555
3562
|
...e,
|
|
3556
3563
|
baseUrl: t
|
|
3557
3564
|
});
|
|
3558
3565
|
return await r.start(), r;
|
|
3559
3566
|
}
|
|
3560
|
-
var
|
|
3567
|
+
var si = class {
|
|
3561
3568
|
opts;
|
|
3562
3569
|
abort = new AbortController();
|
|
3563
3570
|
listeners = {};
|
|
@@ -3636,7 +3643,7 @@ var ai = class {
|
|
|
3636
3643
|
};
|
|
3637
3644
|
}
|
|
3638
3645
|
beginArming(e, t, n = !1) {
|
|
3639
|
-
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ??
|
|
3646
|
+
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? O(this.opts.baseUrl);
|
|
3640
3647
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
3641
3648
|
}
|
|
3642
3649
|
beginArmingByPolling(e) {
|
|
@@ -3657,7 +3664,7 @@ var ai = class {
|
|
|
3657
3664
|
setTimeout(() => {
|
|
3658
3665
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
3659
3666
|
phase: i ? "unavailable" : "tooEarly",
|
|
3660
|
-
retryInMs:
|
|
3667
|
+
retryInMs: Xr,
|
|
3661
3668
|
attempt: 1,
|
|
3662
3669
|
elapsedMs: 0,
|
|
3663
3670
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -3696,13 +3703,13 @@ var ai = class {
|
|
|
3696
3703
|
!a && !p() && h();
|
|
3697
3704
|
}, e);
|
|
3698
3705
|
};
|
|
3699
|
-
_(
|
|
3706
|
+
_(Yr), this.armingSub = D({
|
|
3700
3707
|
eventsBaseUrl: t,
|
|
3701
3708
|
matchUrn: this.opts.matchUrn,
|
|
3702
3709
|
credential: this.opts.credential,
|
|
3703
|
-
onAlive: () => _(
|
|
3710
|
+
onAlive: () => _(Xr),
|
|
3704
3711
|
onState: (e) => {
|
|
3705
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
3712
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Zr);
|
|
3706
3713
|
},
|
|
3707
3714
|
onError: () => h()
|
|
3708
3715
|
});
|
|
@@ -3725,7 +3732,7 @@ var ai = class {
|
|
|
3725
3732
|
let n = await c(this.opts.credential);
|
|
3726
3733
|
if (this.destroyed || t !== this.loadGen) return;
|
|
3727
3734
|
this.setState("loading");
|
|
3728
|
-
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a =
|
|
3735
|
+
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = vt(this.opts.video, (e) => {
|
|
3729
3736
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
3730
3737
|
});
|
|
3731
3738
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -3747,19 +3754,19 @@ var ai = class {
|
|
|
3747
3754
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
3748
3755
|
let i = e.analytics?.sid;
|
|
3749
3756
|
if (!i) return;
|
|
3750
|
-
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } =
|
|
3757
|
+
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = Sr(this.opts.baseUrl, a, e.analytics?.endpoint);
|
|
3751
3758
|
if (!o) {
|
|
3752
3759
|
s && setTimeout(() => {
|
|
3753
3760
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
|
|
3754
3761
|
}, 0);
|
|
3755
3762
|
return;
|
|
3756
3763
|
}
|
|
3757
|
-
let c = this.opts.video, l = new
|
|
3764
|
+
let c = this.opts.video, l = new Cr({
|
|
3758
3765
|
endpoint: o,
|
|
3759
3766
|
sid: i,
|
|
3760
3767
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
3761
|
-
sdkVersion:
|
|
3762
|
-
environment:
|
|
3768
|
+
sdkVersion: kr,
|
|
3769
|
+
environment: Dr(c),
|
|
3763
3770
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
3764
3771
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
3765
3772
|
onBlocked: (e) => setTimeout(() => {
|
|
@@ -3780,7 +3787,7 @@ var ai = class {
|
|
|
3780
3787
|
let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
|
|
3781
3788
|
c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
|
|
3782
3789
|
c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
|
|
3783
|
-
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()),
|
|
3790
|
+
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), Or().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
3784
3791
|
}
|
|
3785
3792
|
currentPresentation() {
|
|
3786
3793
|
let e = this.opts.video;
|
|
@@ -3795,7 +3802,7 @@ var ai = class {
|
|
|
3795
3802
|
video: this.opts.video,
|
|
3796
3803
|
descriptor: e,
|
|
3797
3804
|
credential: t,
|
|
3798
|
-
deviceId:
|
|
3805
|
+
deviceId: Oe(),
|
|
3799
3806
|
userId: this.opts.userId,
|
|
3800
3807
|
lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
|
|
3801
3808
|
snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
|
|
@@ -3813,9 +3820,9 @@ var ai = class {
|
|
|
3813
3820
|
freshLicenseUrl: () => this.refreshLicense()
|
|
3814
3821
|
}, o = this.opts.engine ?? "auto";
|
|
3815
3822
|
if (o === "native") return new H(a);
|
|
3816
|
-
if (o === "hls") return new
|
|
3817
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && B(this.opts.video) && V() || !e.drmEnabled &&
|
|
3818
|
-
if (
|
|
3823
|
+
if (o === "hls") return new nr(a);
|
|
3824
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && B(this.opts.video) && V() || !e.drmEnabled && At() && B(this.opts.video)) return new H(a);
|
|
3825
|
+
if (Kt()) return new nr(a);
|
|
3819
3826
|
if (B(this.opts.video)) return new H(a);
|
|
3820
3827
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
3821
3828
|
}
|
|
@@ -3866,11 +3873,11 @@ var ai = class {
|
|
|
3866
3873
|
}
|
|
3867
3874
|
startLiveState(e) {
|
|
3868
3875
|
if (this.opts.liveStateEvents === !1) return;
|
|
3869
|
-
let t = this.opts.eventsBaseUrl ??
|
|
3876
|
+
let t = this.opts.eventsBaseUrl ?? O(this.opts.baseUrl);
|
|
3870
3877
|
if (!t) return;
|
|
3871
3878
|
this.closeLiveState();
|
|
3872
3879
|
let i = 0, a = !1;
|
|
3873
|
-
this.liveStateSub =
|
|
3880
|
+
this.liveStateSub = D({
|
|
3874
3881
|
eventsBaseUrl: t,
|
|
3875
3882
|
matchUrn: this.opts.matchUrn,
|
|
3876
3883
|
credential: this.opts.credential,
|
|
@@ -3882,11 +3889,11 @@ var ai = class {
|
|
|
3882
3889
|
},
|
|
3883
3890
|
onError: (o) => {
|
|
3884
3891
|
if (!(this.destroyed || e !== this.loadGen || a) && !this.endedHandled) {
|
|
3885
|
-
if (o instanceof
|
|
3892
|
+
if (o instanceof E && (o.terminal || o.status === 404)) {
|
|
3886
3893
|
a = !0, this.emit("warning", new n(r(o.status), o.status, `live-state events answered HTTP ${o.status} for ${this.opts.matchUrn}: the match is ` + (o.terminal ? "gone, so the subscription stopped" : "not in the catalog (ended and dropped, or not listed yet), so it retries every 5 min") + " — end-of-stream detection falls back to the HLS staleness watchdog."));
|
|
3887
3894
|
return;
|
|
3888
3895
|
}
|
|
3889
|
-
i += 1, i >=
|
|
3896
|
+
i += 1, i >= Qr && (a = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${i} 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.`)));
|
|
3890
3897
|
}
|
|
3891
3898
|
}
|
|
3892
3899
|
});
|
|
@@ -3903,7 +3910,7 @@ var ai = class {
|
|
|
3903
3910
|
}
|
|
3904
3911
|
if (this.emit("online"), this._state !== "error" || !this._lastError) return;
|
|
3905
3912
|
let t = this._lastError.code;
|
|
3906
|
-
|
|
3913
|
+
ii(t) && (t === "NETWORK" || this.failedWhileOffline) && this.retry().catch(() => void 0);
|
|
3907
3914
|
}));
|
|
3908
3915
|
}
|
|
3909
3916
|
watchReturn() {
|
|
@@ -3913,7 +3920,7 @@ var ai = class {
|
|
|
3913
3920
|
return;
|
|
3914
3921
|
}
|
|
3915
3922
|
let e = this.hiddenAtMs;
|
|
3916
|
-
this.hiddenAtMs = null, e != null && Date.now() - e >=
|
|
3923
|
+
this.hiddenAtMs = null, e != null && Date.now() - e >= $r && this.resyncLiveState();
|
|
3917
3924
|
}, this.onReturnPageShow = (e) => {
|
|
3918
3925
|
e.persisted && this.resyncLiveState();
|
|
3919
3926
|
}, document.addEventListener("visibilitychange", this.onReturnVisible), typeof window < "u" && window.addEventListener("pageshow", this.onReturnPageShow));
|
|
@@ -3945,7 +3952,7 @@ var ai = class {
|
|
|
3945
3952
|
scheduleRejoin(e) {
|
|
3946
3953
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
3947
3954
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
3948
|
-
}, Math.random() *
|
|
3955
|
+
}, Math.random() * Zr));
|
|
3949
3956
|
}
|
|
3950
3957
|
cancelRejoin() {
|
|
3951
3958
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -3969,7 +3976,7 @@ var ai = class {
|
|
|
3969
3976
|
}
|
|
3970
3977
|
t.controls = !1;
|
|
3971
3978
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
3972
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
3979
|
+
r && r.insertBefore(n, t), n.appendChild(t), Mr(n, this.opts.theme), this.container = n, this.controlBar = Ur({
|
|
3973
3980
|
root: n,
|
|
3974
3981
|
video: t,
|
|
3975
3982
|
player: this,
|
|
@@ -4008,7 +4015,7 @@ var ai = class {
|
|
|
4008
4015
|
}
|
|
4009
4016
|
startStats() {
|
|
4010
4017
|
this.stopStats();
|
|
4011
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
4018
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? ei);
|
|
4012
4019
|
this.statsTimer = setInterval(() => {
|
|
4013
4020
|
if (!this.engine) return;
|
|
4014
4021
|
let e = this.engine.getStats();
|
|
@@ -4019,14 +4026,14 @@ var ai = class {
|
|
|
4019
4026
|
this.statsTimer && clearInterval(this.statsTimer), this.statsTimer = void 0;
|
|
4020
4027
|
}
|
|
4021
4028
|
isStaleLicenseDenial(e) {
|
|
4022
|
-
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !==
|
|
4029
|
+
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== ni || e.error.httpStatus !== 403 || e.error.code !== "FORBIDDEN" || e.error.serverCode === "license_refused" ? !1 : W(this._descriptor?.drm?.widevine?.licenseUrl);
|
|
4023
4030
|
}
|
|
4024
4031
|
scheduleLicenseRefresh() {
|
|
4025
4032
|
if (this.stopRefresh(), !this._descriptor?.drmEnabled) return;
|
|
4026
4033
|
typeof document < "u" && this.engine?.name === "hls" && (this.onRefocus = () => {
|
|
4027
4034
|
document.visibilityState !== "visible" || this.destroyed || W(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
|
|
4028
4035
|
}, document.addEventListener("visibilitychange", this.onRefocus));
|
|
4029
|
-
let e = this.opts.licenseRefreshMs ??
|
|
4036
|
+
let e = this.opts.licenseRefreshMs ?? ti;
|
|
4030
4037
|
e && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
4031
4038
|
}
|
|
4032
4039
|
stopRefresh() {
|
|
@@ -4122,13 +4129,13 @@ var ai = class {
|
|
|
4122
4129
|
e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
|
|
4123
4130
|
}
|
|
4124
4131
|
async enterFullscreen() {
|
|
4125
|
-
return !this.destroyed &&
|
|
4132
|
+
return !this.destroyed && w(this.opts.video, this.container ?? void 0);
|
|
4126
4133
|
}
|
|
4127
4134
|
async exitFullscreen() {
|
|
4128
|
-
await
|
|
4135
|
+
await T(this.opts.video, this.container ?? void 0);
|
|
4129
4136
|
}
|
|
4130
4137
|
fullscreenSupported() {
|
|
4131
|
-
return !this.destroyed &&
|
|
4138
|
+
return !this.destroyed && C(this.opts.video, this.container ?? void 0);
|
|
4132
4139
|
}
|
|
4133
4140
|
retry() {
|
|
4134
4141
|
return this.reload();
|
|
@@ -4191,12 +4198,12 @@ var ai = class {
|
|
|
4191
4198
|
};
|
|
4192
4199
|
//#endregion
|
|
4193
4200
|
//#region src/embed/protocol.ts
|
|
4194
|
-
function
|
|
4201
|
+
function $(e) {
|
|
4195
4202
|
return !!e && typeof e == "object" && typeof e.type == "string" && e.type.startsWith("oddin:");
|
|
4196
4203
|
}
|
|
4197
4204
|
//#endregion
|
|
4198
4205
|
//#region src/embed/host.ts
|
|
4199
|
-
function
|
|
4206
|
+
function ci(e) {
|
|
4200
4207
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
4201
4208
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
4202
4209
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -4205,7 +4212,7 @@ function si(e) {
|
|
|
4205
4212
|
let r = document.createElement("iframe");
|
|
4206
4213
|
r.src = t.toString(), r.allow = "autoplay; encrypted-media; fullscreen", r.setAttribute("allowfullscreen", ""), r.referrerPolicy = "no-referrer", r.setAttribute("sandbox", e.sandbox ?? "allow-scripts allow-same-origin allow-presentation"), r.style.cssText = "border:0;width:100%;height:100%;display:block", e.container.appendChild(r);
|
|
4207
4214
|
let i = /* @__PURE__ */ new Set(), a = (t) => {
|
|
4208
|
-
if (t.source !== r.contentWindow || t.origin !== n ||
|
|
4215
|
+
if (t.source !== r.contentWindow || t.origin !== n || !$(t.data)) return;
|
|
4209
4216
|
let a = t.data;
|
|
4210
4217
|
a.type === "oddin:ready" && a.protocol !== 1 && console.warn(`havik-player: embed protocol v${a.protocol} != host v1. Pin the embed page version to the SDK version to avoid skew.`), e.onEvent?.(a), i.forEach((e) => e(a));
|
|
4211
4218
|
};
|
|
@@ -4255,15 +4262,15 @@ function si(e) {
|
|
|
4255
4262
|
}
|
|
4256
4263
|
//#endregion
|
|
4257
4264
|
//#region src/embed/page.ts
|
|
4258
|
-
var
|
|
4259
|
-
function
|
|
4265
|
+
var li = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
4266
|
+
function ui(e) {
|
|
4260
4267
|
if (typeof e == "boolean") return e;
|
|
4261
4268
|
if (typeof e == "object" && e) {
|
|
4262
4269
|
let t = e.endpoint;
|
|
4263
4270
|
return typeof t == "string" ? { endpoint: t } : {};
|
|
4264
4271
|
}
|
|
4265
4272
|
}
|
|
4266
|
-
function
|
|
4273
|
+
function di() {
|
|
4267
4274
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
4268
4275
|
if (e) return {
|
|
4269
4276
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -4273,7 +4280,7 @@ function ui() {
|
|
|
4273
4280
|
autoplay: e.autoplay ?? !0,
|
|
4274
4281
|
muted: e.muted ?? !0,
|
|
4275
4282
|
waitForLive: e.waitForLive ?? !0,
|
|
4276
|
-
analytics:
|
|
4283
|
+
analytics: ui(e.analytics)
|
|
4277
4284
|
};
|
|
4278
4285
|
let t = new URLSearchParams(location.search);
|
|
4279
4286
|
return {
|
|
@@ -4286,9 +4293,9 @@ function ui() {
|
|
|
4286
4293
|
waitForLive: !0
|
|
4287
4294
|
};
|
|
4288
4295
|
}
|
|
4289
|
-
async function
|
|
4290
|
-
let e =
|
|
4291
|
-
|
|
4296
|
+
async function fi() {
|
|
4297
|
+
let e = di();
|
|
4298
|
+
mi();
|
|
4292
4299
|
let t = document.createElement("video");
|
|
4293
4300
|
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);
|
|
4294
4301
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -4344,12 +4351,12 @@ async function di() {
|
|
|
4344
4351
|
message: e.message,
|
|
4345
4352
|
...e.country === void 0 ? {} : { country: e.country }
|
|
4346
4353
|
})), e.on("autoplayblocked", () => {
|
|
4347
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
4354
|
+
i({ type: "oddin:autoplayblocked" }), pi(t, e);
|
|
4348
4355
|
});
|
|
4349
4356
|
}, s = async (r) => {
|
|
4350
4357
|
a?.destroy(), a = null;
|
|
4351
4358
|
try {
|
|
4352
|
-
let n = await
|
|
4359
|
+
let n = await oi({
|
|
4353
4360
|
video: t,
|
|
4354
4361
|
baseUrl: e.baseUrl,
|
|
4355
4362
|
matchUrn: r,
|
|
@@ -4412,30 +4419,30 @@ async function di() {
|
|
|
4412
4419
|
a?.retry();
|
|
4413
4420
|
break;
|
|
4414
4421
|
case "oddin:load":
|
|
4415
|
-
typeof e.matchUrn == "string" &&
|
|
4422
|
+
typeof e.matchUrn == "string" && li.test(e.matchUrn) && s(e.matchUrn);
|
|
4416
4423
|
break;
|
|
4417
4424
|
case "oddin:destroy": c();
|
|
4418
4425
|
}
|
|
4419
4426
|
}, u = (e) => {
|
|
4420
|
-
r && e.origin === r &&
|
|
4427
|
+
r && e.origin === r && $(e.data) && l(e.data);
|
|
4421
4428
|
};
|
|
4422
4429
|
r && window.addEventListener("message", u), window.addEventListener("pagehide", c, { once: !0 }), await s(e.matchUrn), i({
|
|
4423
4430
|
type: "oddin:ready",
|
|
4424
4431
|
protocol: 1
|
|
4425
4432
|
});
|
|
4426
4433
|
}
|
|
4427
|
-
function
|
|
4434
|
+
function pi(e, t) {
|
|
4428
4435
|
if (document.getElementById("havik-tap")) return;
|
|
4429
4436
|
let n = document.createElement("button");
|
|
4430
4437
|
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", () => {
|
|
4431
4438
|
n.remove(), t.play();
|
|
4432
4439
|
}), document.body.appendChild(n);
|
|
4433
4440
|
}
|
|
4434
|
-
function
|
|
4441
|
+
function mi() {
|
|
4435
4442
|
let e = document.createElement("style");
|
|
4436
4443
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
4437
4444
|
}
|
|
4438
4445
|
//#endregion
|
|
4439
|
-
export {
|
|
4446
|
+
export { E as LiveStateHttpError, Ar as ODDIN_THEME, n as PlaybackError, Mr as applyTheme, lt as baseUrlForEnv, fi as bootEmbed, ke as clearDeviceId, He as clearRememberedBandwidth, oi as createPlayer, O as deriveEventsBaseUrl, at as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ve as fetchCatalog, be as fetchTournament, Se as flattenMatches, C as fullscreenSupported, Oe as getDeviceId, st as isLowLatencyManifest, $ as isOddinMessage, je as licenseRequestHeaders, ci as mountEmbed, fe as pollToLive, y as resolveStream, D as subscribeLiveState, S as videoFullscreenActive, we as watchStatus };
|
|
4440
4447
|
|
|
4441
4448
|
//# sourceMappingURL=index.js.map
|