@oddin-gg/havik-player 2.26.1 → 2.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/havik-player.global.js +2 -2
- package/dist/havik-player.global.js.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -4
- package/dist/index.d.ts +23 -4
- package/dist/index.js +389 -338
- package/dist/index.js.map +1 -1
- package/docs/API.md +11 -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 ve(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 S(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 C(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 w(e, t) {
|
|
337
337
|
let n = e;
|
|
338
338
|
if (n.webkitDisplayingFullscreen) {
|
|
339
339
|
n.webkitExitFullscreen?.();
|
|
@@ -344,7 +344,7 @@ async function T(e, t) {
|
|
|
344
344
|
}
|
|
345
345
|
//#endregion
|
|
346
346
|
//#region src/core/catalog.ts
|
|
347
|
-
async function
|
|
347
|
+
async function ye(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 ve(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: be(await s.json()),
|
|
366
366
|
etag: s.headers.get("etag") ?? void 0,
|
|
367
367
|
notModified: !1
|
|
368
368
|
};
|
|
369
369
|
}
|
|
370
|
-
function
|
|
370
|
+
function be(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 ye(e) {
|
|
|
389
389
|
};
|
|
390
390
|
});
|
|
391
391
|
}
|
|
392
|
-
async function
|
|
392
|
+
async function xe(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 be(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: Se(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 Se(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 xe(e) {
|
|
|
435
435
|
}))
|
|
436
436
|
};
|
|
437
437
|
}
|
|
438
|
-
function
|
|
438
|
+
function Ce(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 we = /* @__PURE__ */ new Set([
|
|
444
444
|
"NOT_FOUND",
|
|
445
445
|
"GEO_DENIED",
|
|
446
446
|
"GONE",
|
|
447
447
|
"INVALID_URN"
|
|
448
448
|
]);
|
|
449
|
-
function
|
|
449
|
+
function Te(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 we(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
|
+
we.has(r.code) && (c = !0), e.onError?.(r);
|
|
483
483
|
}
|
|
484
484
|
} finally {
|
|
485
485
|
d();
|
|
@@ -491,16 +491,16 @@ function we(e) {
|
|
|
491
491
|
}
|
|
492
492
|
//#endregion
|
|
493
493
|
//#region src/core/events.ts
|
|
494
|
-
var
|
|
494
|
+
var Ee = 45e3, T = 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
|
+
}, De = 3e5;
|
|
502
|
+
function E(e) {
|
|
503
|
+
let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = Math.max(t, e.notFoundRetryMs ?? De), i = e.idleTimeoutMs ?? Ee, 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 D(e) {
|
|
|
567
567
|
});
|
|
568
568
|
if (clearTimeout(_), s) return;
|
|
569
569
|
if (!o.ok || !o.body) {
|
|
570
|
-
let t = new
|
|
570
|
+
let t = new T(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 D(e) {
|
|
|
585
585
|
s || (s = !0, o.abort());
|
|
586
586
|
} };
|
|
587
587
|
}
|
|
588
|
-
function
|
|
588
|
+
function D(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 O(e) {
|
|
|
595
595
|
}
|
|
596
596
|
//#endregion
|
|
597
597
|
//#region src/core/drm/deviceId.ts
|
|
598
|
-
var
|
|
599
|
-
function
|
|
598
|
+
var O = "havik.player.deviceId", k;
|
|
599
|
+
function A() {
|
|
600
600
|
if (k) return k;
|
|
601
601
|
try {
|
|
602
|
-
let e = globalThis.localStorage?.getItem(
|
|
602
|
+
let e = globalThis.localStorage?.getItem(O);
|
|
603
603
|
if (e) return k = e, e;
|
|
604
604
|
} catch {}
|
|
605
|
-
let e =
|
|
605
|
+
let e = ke();
|
|
606
606
|
k = e;
|
|
607
607
|
try {
|
|
608
|
-
globalThis.localStorage?.setItem(
|
|
608
|
+
globalThis.localStorage?.setItem(O, e);
|
|
609
609
|
} catch {}
|
|
610
610
|
return e;
|
|
611
611
|
}
|
|
612
|
-
function
|
|
612
|
+
function Oe() {
|
|
613
613
|
k = void 0;
|
|
614
614
|
try {
|
|
615
|
-
globalThis.localStorage?.removeItem(
|
|
615
|
+
globalThis.localStorage?.removeItem(O);
|
|
616
616
|
} catch {}
|
|
617
617
|
}
|
|
618
|
-
function
|
|
618
|
+
function ke() {
|
|
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 Ae() {
|
|
|
627
627
|
}
|
|
628
628
|
//#endregion
|
|
629
629
|
//#region src/core/drm/headers.ts
|
|
630
|
-
function
|
|
630
|
+
function Ae(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 ?? A(),
|
|
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 j = "havik.player.bandwidth", je = .8, Me = 2e7, Ne = 3e5;
|
|
642
|
+
function Pe() {
|
|
643
643
|
return globalThis.navigator?.connection;
|
|
644
644
|
}
|
|
645
|
-
function
|
|
646
|
-
let e =
|
|
645
|
+
function Fe() {
|
|
646
|
+
let e = Pe()?.type;
|
|
647
647
|
return typeof e == "string" && e !== "" && e !== "unknown" ? e : "any";
|
|
648
648
|
}
|
|
649
|
-
function
|
|
650
|
-
let e =
|
|
649
|
+
function Ie() {
|
|
650
|
+
let e = Pe()?.downlink;
|
|
651
651
|
return typeof e == "number" && Number.isFinite(e) && e > 0 ? e * 1e6 : void 0;
|
|
652
652
|
}
|
|
653
|
-
function
|
|
653
|
+
function Le() {
|
|
654
654
|
try {
|
|
655
|
-
let e = globalThis.localStorage?.getItem(
|
|
655
|
+
let e = globalThis.localStorage?.getItem(j);
|
|
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 ze() {
|
|
|
660
660
|
return {};
|
|
661
661
|
}
|
|
662
662
|
}
|
|
663
|
-
function
|
|
664
|
-
let t =
|
|
663
|
+
function Re(e = Date.now()) {
|
|
664
|
+
let t = Le()[Fe()];
|
|
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 = Ie(), i = r === void 0 ? t.bps : Math.min(t.bps, r);
|
|
669
|
+
return Math.round(Math.min(Me, Math.max(Ne, i * je)));
|
|
670
670
|
}
|
|
671
|
-
function
|
|
671
|
+
function ze(e, t = Date.now()) {
|
|
672
672
|
if (!Number.isFinite(e) || e <= 0) return;
|
|
673
|
-
let n =
|
|
674
|
-
n[
|
|
673
|
+
let n = Le();
|
|
674
|
+
n[Fe()] = {
|
|
675
675
|
bps: Math.round(e),
|
|
676
676
|
at: t
|
|
677
677
|
};
|
|
678
678
|
try {
|
|
679
|
-
globalThis.localStorage?.setItem(
|
|
679
|
+
globalThis.localStorage?.setItem(j, JSON.stringify(n));
|
|
680
680
|
} catch {}
|
|
681
681
|
}
|
|
682
|
-
function
|
|
682
|
+
function Be() {
|
|
683
683
|
try {
|
|
684
|
-
globalThis.localStorage?.removeItem(
|
|
684
|
+
globalThis.localStorage?.removeItem(j);
|
|
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 Ve = /* @__PURE__ */ new WeakMap();
|
|
690
|
+
function He(e, t) {
|
|
691
|
+
let n = Ve.get(e);
|
|
692
|
+
n || (n = /* @__PURE__ */ new Map(), Ve.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 We(e, t) {
|
|
|
697
697
|
});
|
|
698
698
|
return n.set(t.keySystem, i), i;
|
|
699
699
|
}
|
|
700
|
-
function
|
|
700
|
+
function M() {
|
|
701
701
|
return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
|
|
702
702
|
}
|
|
703
|
-
var
|
|
704
|
-
function
|
|
703
|
+
var Ue = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
|
|
704
|
+
function We(e) {
|
|
705
705
|
return e.startsWith("com.widevine");
|
|
706
706
|
}
|
|
707
|
-
function
|
|
708
|
-
if (!
|
|
707
|
+
function Ge(e, t) {
|
|
708
|
+
if (!We(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 = Ue.indexOf(e.robustness);
|
|
713
|
+
return n === -1 || Ue.indexOf(t) > n;
|
|
714
714
|
});
|
|
715
|
-
}, r =
|
|
715
|
+
}, r = Ue.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 M(e, t) {
|
|
|
722
722
|
return [...t, ...r];
|
|
723
723
|
}
|
|
724
724
|
function Ke(e) {
|
|
725
|
-
return (t, n) =>
|
|
725
|
+
return (t, n) => M() ? navigator.requestMediaKeySystemAccess(t, Ge(t, n)).then((t) => ({
|
|
726
726
|
keySystem: t.keySystem,
|
|
727
727
|
getConfiguration: () => t.getConfiguration(),
|
|
728
|
-
createMediaKeys: () =>
|
|
728
|
+
createMediaKeys: () => He(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 (!M()) 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", Ge("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 (M()) 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
|
+
}] : Ge("com.widevine.alpha", [{
|
|
822
822
|
initDataTypes: ["cenc"],
|
|
823
823
|
videoCapabilities: [{
|
|
824
824
|
contentType: et,
|
|
@@ -975,26 +975,36 @@ var ht = class {
|
|
|
975
975
|
this.video.removeEventListener("timeupdate", e), this.video.removeEventListener("seeking", e);
|
|
976
976
|
};
|
|
977
977
|
}
|
|
978
|
-
};
|
|
979
|
-
function
|
|
980
|
-
let n =
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
["
|
|
978
|
+
}, gt = .25;
|
|
979
|
+
function _t(e, t) {
|
|
980
|
+
let n = null, r = (r) => {
|
|
981
|
+
n = r === "buffering" ? e.currentTime : null, t(r);
|
|
982
|
+
}, i = [
|
|
983
|
+
["playing", () => r("playing")],
|
|
984
|
+
["waiting", () => r("buffering")],
|
|
985
|
+
["stalled", () => {
|
|
986
|
+
!e.paused && e.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && r("buffering");
|
|
987
|
+
}],
|
|
988
|
+
["seeked", () => {
|
|
989
|
+
n !== null && (n = e.currentTime);
|
|
990
|
+
}],
|
|
991
|
+
["timeupdate", () => {
|
|
992
|
+
n !== null && !e.paused && !e.seeking && e.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA && e.currentTime - n >= gt && r("playing");
|
|
993
|
+
}],
|
|
984
994
|
["pause", () => {
|
|
985
|
-
e.ended ||
|
|
995
|
+
e.ended || r("paused");
|
|
986
996
|
}],
|
|
987
|
-
["ended", () =>
|
|
997
|
+
["ended", () => r("ended")]
|
|
988
998
|
];
|
|
989
|
-
for (let [t,
|
|
999
|
+
for (let [t, n] of i) e.addEventListener(t, n);
|
|
990
1000
|
return () => {
|
|
991
|
-
for (let [t,
|
|
1001
|
+
for (let [t, n] of i) e.removeEventListener(t, n);
|
|
992
1002
|
};
|
|
993
1003
|
}
|
|
994
1004
|
//#endregion
|
|
995
1005
|
//#region src/core/engine/native.ts
|
|
996
|
-
var
|
|
997
|
-
function
|
|
1006
|
+
var vt = 2e3, yt = 3, z = 500, bt = 6e3, xt = .25, St = 250, Ct = .05, wt = 4, Tt = 12e3, Et = .25, Dt = 1e3;
|
|
1007
|
+
function Ot(e) {
|
|
998
1008
|
try {
|
|
999
1009
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
1000
1010
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -1010,7 +1020,7 @@ function V() {
|
|
|
1010
1020
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
1011
1021
|
return e || t;
|
|
1012
1022
|
}
|
|
1013
|
-
function
|
|
1023
|
+
function kt() {
|
|
1014
1024
|
if (typeof navigator > "u" || !V()) return !1;
|
|
1015
1025
|
let e = navigator.userAgent ?? "";
|
|
1016
1026
|
return /iPhone|iPad|iPod/.test(e) ? !0 : /Macintosh/.test(e) && typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1;
|
|
@@ -1066,7 +1076,7 @@ var H = class {
|
|
|
1066
1076
|
type: "error",
|
|
1067
1077
|
error: L() ? new n("INTERNAL", 0, "native HLS playback error") : new n("NETWORK", 0, "native HLS playback error while offline"),
|
|
1068
1078
|
fatal: !0
|
|
1069
|
-
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src =
|
|
1079
|
+
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = jt(t.manifestUrl, t.analytics?.sid), e.load();
|
|
1070
1080
|
}
|
|
1071
1081
|
startLoad() {
|
|
1072
1082
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -1094,7 +1104,7 @@ var H = class {
|
|
|
1094
1104
|
};
|
|
1095
1105
|
this.onEncrypted = (n) => {
|
|
1096
1106
|
let a = n;
|
|
1097
|
-
a.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
1107
|
+
a.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Ot(a.initData), (async () => {
|
|
1098
1108
|
try {
|
|
1099
1109
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
1100
1110
|
initDataTypes: [a.initDataType],
|
|
@@ -1197,7 +1207,7 @@ var H = class {
|
|
|
1197
1207
|
if (this.cdnHost ||= mt(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
|
|
1198
1208
|
n.isLive = !0;
|
|
1199
1209
|
let t = this.liveEdgeEstimate(), r = t == null ? NaN : t - e.currentTime;
|
|
1200
|
-
Number.isFinite(r) && (n.atLiveEdge = r <=
|
|
1210
|
+
Number.isFinite(r) && (n.atLiveEdge = r <= wt, !e.paused && r >= 0 && (n.latencySeconds = r));
|
|
1201
1211
|
} else Number.isFinite(e.duration) && e.duration > 0 && (n.isLive = !1);
|
|
1202
1212
|
return n;
|
|
1203
1213
|
}
|
|
@@ -1215,7 +1225,7 @@ var H = class {
|
|
|
1215
1225
|
return;
|
|
1216
1226
|
}
|
|
1217
1227
|
let t = this.hiddenSince;
|
|
1218
|
-
this.hiddenSince = null, t != null && e - t >=
|
|
1228
|
+
this.hiddenSince = null, t != null && e - t >= vt && this.armRefocus();
|
|
1219
1229
|
}, this.onPageShow = (e) => {
|
|
1220
1230
|
e.persisted && this.armRefocus();
|
|
1221
1231
|
}, document.addEventListener("visibilitychange", this.onVisibility), typeof window < "u" && window.addEventListener("pageshow", this.onPageShow));
|
|
@@ -1225,7 +1235,7 @@ var H = class {
|
|
|
1225
1235
|
let e = this.liveEnd(), t = U, n = t(), r = 0, i = () => {
|
|
1226
1236
|
if (this.refocusTimer = null, Number.isFinite(this.deps.video.duration)) return;
|
|
1227
1237
|
r += z;
|
|
1228
|
-
let a = this.liveEnd(), o = a != null && (e == null || a >= e +
|
|
1238
|
+
let a = this.liveEnd(), o = a != null && (e == null || a >= e + xt), s = Math.max(r, t() - n) >= bt;
|
|
1229
1239
|
if (o || s && a != null) {
|
|
1230
1240
|
this.snapToLive();
|
|
1231
1241
|
return;
|
|
@@ -1245,9 +1255,9 @@ var H = class {
|
|
|
1245
1255
|
}, e.addEventListener("seeking", this.onEdgeReset), e.addEventListener("emptied", this.onEdgeReset), this.edgeTimer = setInterval(() => {
|
|
1246
1256
|
if (e.duration !== Infinity) return;
|
|
1247
1257
|
this.checkEndStale();
|
|
1248
|
-
let t =
|
|
1249
|
-
t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >=
|
|
1250
|
-
},
|
|
1258
|
+
let t = At(e, e.currentTime);
|
|
1259
|
+
t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >= Ct) && (this.bufferedAdvancedAt = U()), this.lastBufferedEnd = t);
|
|
1260
|
+
}, St);
|
|
1251
1261
|
}
|
|
1252
1262
|
checkEndStale() {
|
|
1253
1263
|
if (this.endedEmitted) return;
|
|
@@ -1255,14 +1265,14 @@ var H = class {
|
|
|
1255
1265
|
this.lastTickAt = e;
|
|
1256
1266
|
let n = this.liveEnd();
|
|
1257
1267
|
if (n == null) return;
|
|
1258
|
-
let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >=
|
|
1268
|
+
let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >= Et;
|
|
1259
1269
|
this.lastSeekableEnd = n;
|
|
1260
1270
|
let i = this.deps.video, a = typeof document < "u" && document.visibilityState === "hidden";
|
|
1261
|
-
if (r || t >
|
|
1271
|
+
if (r || t > Dt || a || i.paused) {
|
|
1262
1272
|
this.edgeStampedAt = e;
|
|
1263
1273
|
return;
|
|
1264
1274
|
}
|
|
1265
|
-
e - (this.edgeStampedAt ?? e) >
|
|
1275
|
+
e - (this.edgeStampedAt ?? e) > Tt && (this.endedEmitted = !0, this.deps.emit({
|
|
1266
1276
|
type: "ended",
|
|
1267
1277
|
reason: "stalled"
|
|
1268
1278
|
}));
|
|
@@ -1276,7 +1286,7 @@ var H = class {
|
|
|
1276
1286
|
liveEdgeEstimate() {
|
|
1277
1287
|
let e = this.deps.video;
|
|
1278
1288
|
if (e.duration !== Infinity) return null;
|
|
1279
|
-
let t = this.liveEnd(), n =
|
|
1289
|
+
let t = this.liveEnd(), n = At(e, e.currentTime) ?? this.lastBufferedEnd;
|
|
1280
1290
|
if (n != null) {
|
|
1281
1291
|
let e = this.bufferedAdvancedAt, r = n + (e == null ? 0 : Math.max(0, (U() - e) / 1e3));
|
|
1282
1292
|
(t == null || r > t) && (t = r);
|
|
@@ -1292,7 +1302,7 @@ var H = class {
|
|
|
1292
1302
|
snapToLive() {
|
|
1293
1303
|
let e = this.deps.video, t = this.liveEnd();
|
|
1294
1304
|
if (t == null) return;
|
|
1295
|
-
let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t -
|
|
1305
|
+
let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t - yt, r);
|
|
1296
1306
|
try {
|
|
1297
1307
|
e.currentTime = i;
|
|
1298
1308
|
} catch {}
|
|
@@ -1313,7 +1323,7 @@ var H = class {
|
|
|
1313
1323
|
function U() {
|
|
1314
1324
|
return typeof performance < "u" ? performance.now() : Date.now();
|
|
1315
1325
|
}
|
|
1316
|
-
function
|
|
1326
|
+
function At(e, t) {
|
|
1317
1327
|
let n = e.buffered;
|
|
1318
1328
|
if (!n || !Number.isFinite(t)) return null;
|
|
1319
1329
|
for (let e = 0; e < n.length; e += 1) if (n.start(e) <= t + .1 && n.end(e) > t) {
|
|
@@ -1322,7 +1332,7 @@ function kt(e, t) {
|
|
|
1322
1332
|
}
|
|
1323
1333
|
return null;
|
|
1324
1334
|
}
|
|
1325
|
-
function
|
|
1335
|
+
function jt(e, t) {
|
|
1326
1336
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
1327
1337
|
}
|
|
1328
1338
|
//#endregion
|
|
@@ -1339,13 +1349,13 @@ function W(e, t = Date.now()) {
|
|
|
1339
1349
|
}
|
|
1340
1350
|
//#endregion
|
|
1341
1351
|
//#region src/core/drm/xhrBody.ts
|
|
1342
|
-
var
|
|
1343
|
-
function
|
|
1352
|
+
var Mt = 4096;
|
|
1353
|
+
function Nt(e) {
|
|
1344
1354
|
if (!e || typeof e != "object") return;
|
|
1345
1355
|
let { response: t } = e;
|
|
1346
1356
|
if (typeof t == "string") return t;
|
|
1347
1357
|
let n;
|
|
1348
|
-
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 >
|
|
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 > Mt)) try {
|
|
1349
1359
|
return new TextDecoder().decode(n);
|
|
1350
1360
|
} catch {
|
|
1351
1361
|
return;
|
|
@@ -1353,7 +1363,7 @@ function Mt(e) {
|
|
|
1353
1363
|
}
|
|
1354
1364
|
//#endregion
|
|
1355
1365
|
//#region src/core/engine/prefetch.ts
|
|
1356
|
-
var
|
|
1366
|
+
var Pt = 15e3, Ft = 5e3, It = 6, Lt = 4e3, Rt = 2;
|
|
1357
1367
|
function G(e) {
|
|
1358
1368
|
try {
|
|
1359
1369
|
let t = new URL(e);
|
|
@@ -1362,7 +1372,7 @@ function G(e) {
|
|
|
1362
1372
|
return e;
|
|
1363
1373
|
}
|
|
1364
1374
|
}
|
|
1365
|
-
var
|
|
1375
|
+
var zt = class {
|
|
1366
1376
|
cmcd;
|
|
1367
1377
|
entries = /* @__PURE__ */ new Map();
|
|
1368
1378
|
keyed = /* @__PURE__ */ new Set();
|
|
@@ -1394,17 +1404,17 @@ var Rt = class {
|
|
|
1394
1404
|
let r = G(e);
|
|
1395
1405
|
if (this.entries.has(r)) return;
|
|
1396
1406
|
let i = this.perTrack.get(t) ?? 0;
|
|
1397
|
-
i >=
|
|
1407
|
+
i >= It || (this.perTrack.set(t, i + 1), this.start(r, this.withCmcd(e, t, n), !1, Pt), this.stats.started += 1);
|
|
1398
1408
|
}
|
|
1399
1409
|
prefetchHint(e, t) {
|
|
1400
1410
|
let n = G(e);
|
|
1401
1411
|
if (this.entries.has(n)) return;
|
|
1402
1412
|
let r = this.hints.get(t) ?? [];
|
|
1403
|
-
for (; r.length >=
|
|
1413
|
+
for (; r.length >= Rt;) {
|
|
1404
1414
|
let e = r.shift();
|
|
1405
1415
|
e !== void 0 && this.drop(e) && (this.stats.hintDropped += 1);
|
|
1406
1416
|
}
|
|
1407
|
-
r.push(n), this.hints.set(t, r), this.start(n, this.withCmcd(e, t, "media"), !0,
|
|
1417
|
+
r.push(n), this.hints.set(t, r), this.start(n, this.withCmcd(e, t, "media"), !0, Lt), this.stats.hintStarted += 1;
|
|
1408
1418
|
}
|
|
1409
1419
|
dropHints(e) {
|
|
1410
1420
|
for (let t of this.hints.get(e) ?? []) this.drop(t) && (this.stats.hintDropped += 1);
|
|
@@ -1457,14 +1467,14 @@ var Rt = class {
|
|
|
1457
1467
|
}
|
|
1458
1468
|
}
|
|
1459
1469
|
};
|
|
1460
|
-
function
|
|
1470
|
+
function Bt(t, n) {
|
|
1461
1471
|
let r = typeof n == "function" ? n : e.DefaultConfig?.loader;
|
|
1462
1472
|
if (typeof r != "function") return;
|
|
1463
1473
|
class i extends r {
|
|
1464
1474
|
served = !1;
|
|
1465
1475
|
cancelled = !1;
|
|
1466
1476
|
entry;
|
|
1467
|
-
stats =
|
|
1477
|
+
stats = Vt();
|
|
1468
1478
|
load(e, n, r) {
|
|
1469
1479
|
let i = e.rangeEnd ? void 0 : t.take(e.url);
|
|
1470
1480
|
if (!i) {
|
|
@@ -1476,7 +1486,7 @@ function zt(t, n) {
|
|
|
1476
1486
|
i.hint ? t.stats.hintFailed += 1 : t.stats.failed += 1;
|
|
1477
1487
|
}, s = () => {
|
|
1478
1488
|
!this.cancelled && this.served && (i.abort.abort(), o(), this.served = !1, this.entry = void 0, super.load(e, n, r));
|
|
1479
|
-
}, c = n?.loadPolicy, l = c?.maxTimeToFirstByteMs ||
|
|
1489
|
+
}, c = n?.loadPolicy, l = c?.maxTimeToFirstByteMs || Ft, u = setTimeout(s, l);
|
|
1480
1490
|
i.headers.then(() => {
|
|
1481
1491
|
clearTimeout(u);
|
|
1482
1492
|
let e = c?.maxLoadTimeMs;
|
|
@@ -1509,7 +1519,7 @@ function zt(t, n) {
|
|
|
1509
1519
|
}
|
|
1510
1520
|
return i;
|
|
1511
1521
|
}
|
|
1512
|
-
function
|
|
1522
|
+
function Vt() {
|
|
1513
1523
|
return {
|
|
1514
1524
|
aborted: !1,
|
|
1515
1525
|
loaded: 0,
|
|
@@ -1533,10 +1543,10 @@ function Bt() {
|
|
|
1533
1543
|
}
|
|
1534
1544
|
};
|
|
1535
1545
|
}
|
|
1536
|
-
function
|
|
1546
|
+
function Ht(e) {
|
|
1537
1547
|
return e === "audio" ? "audio" : "main";
|
|
1538
1548
|
}
|
|
1539
|
-
function
|
|
1549
|
+
function Ut(e, t) {
|
|
1540
1550
|
let n = [];
|
|
1541
1551
|
t.initSegment?.url && !t.initSegment.data && n.push({
|
|
1542
1552
|
url: t.initSegment.url,
|
|
@@ -1553,7 +1563,7 @@ function Ht(e, t) {
|
|
|
1553
1563
|
});
|
|
1554
1564
|
return n;
|
|
1555
1565
|
}
|
|
1556
|
-
function
|
|
1566
|
+
function Wt(e) {
|
|
1557
1567
|
let t = e, n = t?.preloadHint;
|
|
1558
1568
|
if (!n || !t?.url || n.TYPE !== "PART" || n["BYTERANGE-START"] !== void 0 || n["BYTERANGE-LENGTH"] !== void 0) return null;
|
|
1559
1569
|
let r = n.URI;
|
|
@@ -1571,10 +1581,15 @@ function K(e, t) {
|
|
|
1571
1581
|
}
|
|
1572
1582
|
//#endregion
|
|
1573
1583
|
//#region src/core/engine/hls.ts
|
|
1574
|
-
function
|
|
1584
|
+
function Gt() {
|
|
1575
1585
|
return e.isSupported();
|
|
1576
1586
|
}
|
|
1577
|
-
var
|
|
1587
|
+
var Kt = 3, qt = 1e6, Jt = 20, Yt = 1e4, Xt = 3, Zt = 5, Qt = 3, $t = 1e4, en = 3e4, tn = 12e3, nn = 3e3, rn = .02, an = 6e3, on = .5, sn = 3, cn = .5, ln = 1.1, un = .25, dn = 5e3, fn = 4e3, pn = 2, mn = 5, hn = 2, gn = 2, _n = 4, vn = 4, yn = 2e3, bn = 3e4, xn = 1, Sn = 2, Cn = .5, wn = .6, Tn = 2, En = 1.5, Dn = 1e4, On = 18e4, kn = .5, An = 2;
|
|
1588
|
+
function jn(e) {
|
|
1589
|
+
let t = e.config ?? {};
|
|
1590
|
+
return t.capLevelToPlayerSize === !0 || t.capLevelOnFPSDrop === !0;
|
|
1591
|
+
}
|
|
1592
|
+
var q = 8, Mn = 12e4, Nn = 6e4;
|
|
1578
1593
|
function J(e, t, n) {
|
|
1579
1594
|
if (n <= 0 || t < 0 || t >= e.length) return t;
|
|
1580
1595
|
let r = (t, n) => e[t].width === e[n].width && e[t].height === e[n].height, i = (t) => {
|
|
@@ -1587,11 +1602,11 @@ function J(e, t, n) {
|
|
|
1587
1602
|
function Y() {
|
|
1588
1603
|
return typeof self < "u" && self.devicePixelRatio > 0 ? self.devicePixelRatio : 1;
|
|
1589
1604
|
}
|
|
1590
|
-
var
|
|
1591
|
-
function
|
|
1605
|
+
var Pn = .2, Fn = 30, In = 2, Ln = 2, Rn = 2, zn = 9, Bn = .5, Vn = 64, Hn = 1e4, Un = 8, Wn = .6, Gn = .4, Kn = .4, qn = 2, Jn = 6e4, X = .5, Yn = 3.5, Xn = 300;
|
|
1606
|
+
function Z(e) {
|
|
1592
1607
|
return (e?.part ?? e?.frag)?.stats;
|
|
1593
1608
|
}
|
|
1594
|
-
function
|
|
1609
|
+
function Zn() {
|
|
1595
1610
|
if (typeof navigator > "u") return 0;
|
|
1596
1611
|
try {
|
|
1597
1612
|
let e = navigator.connection?.rtt;
|
|
@@ -1600,20 +1615,20 @@ function qn() {
|
|
|
1600
1615
|
return 0;
|
|
1601
1616
|
}
|
|
1602
1617
|
}
|
|
1603
|
-
function
|
|
1618
|
+
function Qn(e) {
|
|
1604
1619
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
1605
1620
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
1606
1621
|
return;
|
|
1607
1622
|
}
|
|
1608
|
-
e.liveSyncDuration ??=
|
|
1609
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
1610
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
1623
|
+
e.liveSyncDuration ??= Rn;
|
|
1624
|
+
let t = Math.max(12, e.liveSyncDuration + zn);
|
|
1625
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), $n(e, e.liveSyncDuration);
|
|
1611
1626
|
}
|
|
1612
|
-
function
|
|
1627
|
+
function $n(e, t) {
|
|
1613
1628
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
1614
1629
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
1615
1630
|
}
|
|
1616
|
-
var
|
|
1631
|
+
var er = class {
|
|
1617
1632
|
name = "hls";
|
|
1618
1633
|
hls = null;
|
|
1619
1634
|
deps;
|
|
@@ -1702,6 +1717,11 @@ var Xn = class {
|
|
|
1702
1717
|
pushedCapLevel = -1;
|
|
1703
1718
|
pushedCapReason = null;
|
|
1704
1719
|
fpsCapBitrate = null;
|
|
1720
|
+
stallCapBitrate = null;
|
|
1721
|
+
stallCapSince = 0;
|
|
1722
|
+
stallCapTickAt = 0;
|
|
1723
|
+
stallDownCaps = 0;
|
|
1724
|
+
stallCapEnabled;
|
|
1705
1725
|
fpsCapFailedHeight = null;
|
|
1706
1726
|
fpsCapManaged = !0;
|
|
1707
1727
|
fpsLastFrames = -1;
|
|
@@ -1716,7 +1736,7 @@ var Xn = class {
|
|
|
1716
1736
|
frameCounter;
|
|
1717
1737
|
detachFrames = null;
|
|
1718
1738
|
constructor(e) {
|
|
1719
|
-
this.deps = e, this.holdBackEnabled = e.adaptiveHoldBack !== !1, this.frameCounter = new ht(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
1739
|
+
this.deps = e, this.holdBackEnabled = e.adaptiveHoldBack !== !1, this.stallCapEnabled = e.stallCap !== !1, this.frameCounter = new ht(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
1720
1740
|
}
|
|
1721
1741
|
async load() {
|
|
1722
1742
|
this.detachFrames ??= this.frameCounter.attach();
|
|
@@ -1761,7 +1781,7 @@ var Xn = class {
|
|
|
1761
1781
|
}
|
|
1762
1782
|
this.loadSuspended = !0;
|
|
1763
1783
|
}
|
|
1764
|
-
},
|
|
1784
|
+
}, dn));
|
|
1765
1785
|
}
|
|
1766
1786
|
resumeLoading() {
|
|
1767
1787
|
if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.resetChaseWindow(), this.resetFrameDropWindow(), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
|
|
@@ -1793,7 +1813,7 @@ var Xn = class {
|
|
|
1793
1813
|
let t = e.liveSyncPosition;
|
|
1794
1814
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1795
1815
|
let { video: n } = this.deps;
|
|
1796
|
-
n.currentTime <= t +
|
|
1816
|
+
n.currentTime <= t + Bn || (n.currentTime = t);
|
|
1797
1817
|
}
|
|
1798
1818
|
reanchorPartTimeline(e, t) {
|
|
1799
1819
|
let { frag: n, part: r } = t;
|
|
@@ -1805,7 +1825,7 @@ var Xn = class {
|
|
|
1805
1825
|
let o = n.sn, s = i.fragments.find((e) => e && e.sn === o) ?? (i.fragmentHint?.sn === o ? i.fragmentHint : void 0);
|
|
1806
1826
|
if (!s) return;
|
|
1807
1827
|
let c = a.startPTS - s.start;
|
|
1808
|
-
if (!(!Number.isFinite(c) || Math.abs(c) <
|
|
1828
|
+
if (!(!Number.isFinite(c) || Math.abs(c) < rn)) {
|
|
1809
1829
|
for (let e of i.fragments) e && e.setStart(e.start + c);
|
|
1810
1830
|
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})`);
|
|
1811
1831
|
}
|
|
@@ -1833,7 +1853,7 @@ var Xn = class {
|
|
|
1833
1853
|
videoEncryptionScheme: N.scheme,
|
|
1834
1854
|
audioEncryptionScheme: N.scheme
|
|
1835
1855
|
},
|
|
1836
|
-
...
|
|
1856
|
+
...M() ? { requestMediaKeySystemAccessFunc: Ke(t) } : {},
|
|
1837
1857
|
licenseXhrSetup: (e, t) => {
|
|
1838
1858
|
let o = performance.now(), s = () => {
|
|
1839
1859
|
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", () => {
|
|
@@ -1845,7 +1865,7 @@ var Xn = class {
|
|
|
1845
1865
|
return;
|
|
1846
1866
|
}
|
|
1847
1867
|
let l = this.hls, u, d = new Promise((e) => {
|
|
1848
|
-
u = setTimeout(() => e(void 0),
|
|
1868
|
+
u = setTimeout(() => e(void 0), $t);
|
|
1849
1869
|
});
|
|
1850
1870
|
return Promise.race([c().catch(() => void 0), d]).finally(() => clearTimeout(u)).then((e) => {
|
|
1851
1871
|
if (!this.hls || this.hls !== l) throw Error("havik-player: engine torn down during refresh");
|
|
@@ -1863,28 +1883,28 @@ var Xn = class {
|
|
|
1863
1883
|
this.prefetch?.destroy(), this.prefetch = null;
|
|
1864
1884
|
let p = !1, m = !1, h = u && this.deps.mediaDuringKey !== !1, g = this.deps.preloadHints !== !1;
|
|
1865
1885
|
if ((h || g) && !f.fLoader) {
|
|
1866
|
-
let e = new
|
|
1886
|
+
let e = new zt({
|
|
1867
1887
|
sessionId: n.analytics?.sid,
|
|
1868
1888
|
contentId: n.matchUrn
|
|
1869
|
-
}), t =
|
|
1889
|
+
}), t = Bt(e, f.loader);
|
|
1870
1890
|
t && (this.prefetch = e, p = h, m = g, f.fLoader = t);
|
|
1871
1891
|
}
|
|
1872
|
-
|
|
1892
|
+
Qn(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;
|
|
1873
1893
|
let _ = new e(f);
|
|
1874
1894
|
if (this.hls = _, this.armHoldBack(_, f), _.on(e.Events.FRAG_PARSED, (e, t) => this.reanchorPartTimeline(_, t)), _.on(e.Events.MANIFEST_PARSED, () => {
|
|
1875
1895
|
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" });
|
|
1876
1896
|
}), _.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1877
1897
|
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(() => {
|
|
1878
1898
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1879
|
-
},
|
|
1899
|
+
}, en)));
|
|
1880
1900
|
}), _.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1881
1901
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1882
1902
|
}), _.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
1883
1903
|
t?.frag?.type === "main" && (this.mainFragsSinceTick += 1, this.bwFragsLoaded += 1, this.maybeRememberBandwidth(!1));
|
|
1884
|
-
let n = t?.frag, r =
|
|
1904
|
+
let n = t?.frag, r = Z(t), i = r?.loaded;
|
|
1885
1905
|
typeof i == "number" && (this.bytesLoaded += i), !this.reportedFirstBytes && typeof i == "number" && i > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
|
|
1886
1906
|
let a = r?.loading;
|
|
1887
|
-
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 >
|
|
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 > Vn && this.requestTimesMs.shift()), this.sampleHoldBack(t), this.sampleHeadroom(t);
|
|
1888
1908
|
let o = n?.url;
|
|
1889
1909
|
if (o) {
|
|
1890
1910
|
let e = ft(o);
|
|
@@ -1904,8 +1924,8 @@ var Xn = class {
|
|
|
1904
1924
|
let i = e;
|
|
1905
1925
|
if (!i?.live || !i.partList?.length || typeof i.edge != "number") return;
|
|
1906
1926
|
let a = n.buffered, o = a.length ? a.end(a.length - 1) : 0;
|
|
1907
|
-
if (i.edge - o >
|
|
1908
|
-
let s =
|
|
1927
|
+
if (i.edge - o > Kt * (i.partTarget || .5)) return;
|
|
1928
|
+
let s = Wt(e);
|
|
1909
1929
|
s && t.prefetchHint(s, r);
|
|
1910
1930
|
};
|
|
1911
1931
|
_.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1917,15 +1937,15 @@ var Xn = class {
|
|
|
1917
1937
|
if (this.prefetch && p) {
|
|
1918
1938
|
let t = this.prefetch;
|
|
1919
1939
|
_.on(e.Events.KEY_LOADING, (e, n) => {
|
|
1920
|
-
let r = n?.frag, i =
|
|
1921
|
-
if (r && t.isActive(i)) for (let e of
|
|
1922
|
-
}), _.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(
|
|
1940
|
+
let r = n?.frag, i = Ht(r?.type);
|
|
1941
|
+
if (r && t.isActive(i)) for (let e of Ut(_, r)) t.prefetch(e.url, i, e.kind);
|
|
1942
|
+
}), _.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(Ht(n?.frag?.type)));
|
|
1923
1943
|
}
|
|
1924
1944
|
_.on(e.Events.KEY_LOADED, () => {
|
|
1925
1945
|
u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
|
|
1926
1946
|
}), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1927
|
-
this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.adaptHoldBack(), this.reviewSizeCapHeadroom(), this.checkFrameDrops();
|
|
1928
|
-
},
|
|
1947
|
+
this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.adaptHoldBack(), this.reviewSizeCapHeadroom(), this.releaseStallCap(), this.checkFrameDrops();
|
|
1948
|
+
}, nn), _.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1929
1949
|
this.renditionSwitches += 1;
|
|
1930
1950
|
let n = this.lastLevelIndex >= 0 ? _.levels[this.lastLevelIndex] : void 0, r = _.levels[t.level];
|
|
1931
1951
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, this.armFrameDropGrace(), l({
|
|
@@ -1986,8 +2006,8 @@ var Xn = class {
|
|
|
1986
2006
|
let e = this.hls, t = this.sizeCapCover();
|
|
1987
2007
|
if (!e || !t) return null;
|
|
1988
2008
|
let { cover: n, deviceRatio: r } = t, i = this.deps.sizeCapHeadroom, a = i == null || Number.isNaN(i);
|
|
1989
|
-
if (a && r >=
|
|
1990
|
-
if (a) return this.headroomUngated || this.headroomGranted ? J(e.levels, n,
|
|
2009
|
+
if (a && r >= Sn) return n;
|
|
2010
|
+
if (a) return this.headroomUngated || this.headroomGranted ? J(e.levels, n, xn) : n;
|
|
1991
2011
|
let o = i === Infinity ? e.levels.length : Math.max(0, Math.floor(i));
|
|
1992
2012
|
return J(e.levels, n, o);
|
|
1993
2013
|
}
|
|
@@ -2004,11 +2024,11 @@ var Xn = class {
|
|
|
2004
2024
|
return;
|
|
2005
2025
|
}
|
|
2006
2026
|
this.capTimer && clearTimeout(this.capTimer);
|
|
2007
|
-
let t = e > this.sizeCapLevel ?
|
|
2027
|
+
let t = e > this.sizeCapLevel ? yn : bn;
|
|
2008
2028
|
this.capTimer = setTimeout(() => {
|
|
2009
2029
|
this.capTimer = null;
|
|
2010
2030
|
let n = this.computeSizeCapTarget();
|
|
2011
|
-
n === e || t ===
|
|
2031
|
+
n === e || t === bn && n != null && n < e ? this.applySizeCap() : this.onMediaResize();
|
|
2012
2032
|
}, t);
|
|
2013
2033
|
}
|
|
2014
2034
|
measureLadder(e) {
|
|
@@ -2035,7 +2055,7 @@ var Xn = class {
|
|
|
2035
2055
|
}
|
|
2036
2056
|
defaultHeadroomApplies() {
|
|
2037
2057
|
let e = this.deps.sizeCapHeadroom;
|
|
2038
|
-
return e != null && !Number.isNaN(e) || this.headroomUngated ? !1 : Y() <
|
|
2058
|
+
return e != null && !Number.isNaN(e) || this.headroomUngated ? !1 : Y() < Sn;
|
|
2039
2059
|
}
|
|
2040
2060
|
applySizeCapUnlessPending() {
|
|
2041
2061
|
this.capTimer || this.applySizeCap();
|
|
@@ -2044,7 +2064,7 @@ var Xn = class {
|
|
|
2044
2064
|
if (!this.sizeCapManaged || !this.defaultHeadroomApplies() || e.frag?.type !== "main" || typeof e.frag.level != "number" || typeof document < "u" && document.hidden) return;
|
|
2045
2065
|
let t = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag.duration;
|
|
2046
2066
|
if (typeof t != "number" || !(t > 0)) return;
|
|
2047
|
-
let n =
|
|
2067
|
+
let n = Z(e)?.loading;
|
|
2048
2068
|
if (!n || !(n.start > 0) || !(n.end >= n.start)) return;
|
|
2049
2069
|
let r = this.hls?.levels?.[e.frag.level]?.bitrate;
|
|
2050
2070
|
if (!(typeof r == "number" && r > 0)) return;
|
|
@@ -2055,9 +2075,42 @@ var Xn = class {
|
|
|
2055
2075
|
bitrate: r
|
|
2056
2076
|
}), this.headroomSamples.length > 256 && this.headroomSamples.shift();
|
|
2057
2077
|
}
|
|
2058
|
-
onPlaybackStall() {
|
|
2059
|
-
let
|
|
2060
|
-
this.deps.video.seeking || !this.playingSince ||
|
|
2078
|
+
onPlaybackStall(e) {
|
|
2079
|
+
let t = Date.now();
|
|
2080
|
+
this.deps.video.seeking || !this.playingSince || t - this.playingSince < Dn || (this.lastStallAt = t, this.stepStallCapDown(t, e), this.headroomGranted && (this.headroomGranted = !1, this.applySizeCapUnlessPending()));
|
|
2081
|
+
}
|
|
2082
|
+
stallCapLevel(e) {
|
|
2083
|
+
if (this.stallCapBitrate == null) return -1;
|
|
2084
|
+
let t = -1;
|
|
2085
|
+
return e.levels.forEach((e, n) => {
|
|
2086
|
+
e.bitrate <= this.stallCapBitrate && (t = n);
|
|
2087
|
+
}), t < 0 ? 0 : t;
|
|
2088
|
+
}
|
|
2089
|
+
stepStallCapDown(e, t) {
|
|
2090
|
+
let n = this.hls;
|
|
2091
|
+
if (!n || !this.stallCapEnabled || jn(n) || !n.autoLevelEnabled || typeof t == "number" && t >= kn || this.isLiveEdgeWait(n, t ?? 0)) return;
|
|
2092
|
+
this.stallCapBitrate != null && (this.stallCapSince = e);
|
|
2093
|
+
let r = Math.max(n.levels[n.currentLevel]?.bitrate ?? 0, n.levels[n.loadLevel]?.bitrate ?? 0);
|
|
2094
|
+
if (!(r > 0)) return;
|
|
2095
|
+
let i = n.levels.map((e) => e.bitrate).filter((e) => e > 0 && e < r).sort((e, t) => t - e)[0];
|
|
2096
|
+
i != null && (this.stallCapBitrate != null && i >= this.stallCapBitrate || (this.stallCapBitrate = i, this.stallCapSince = e, this.stallDownCaps += 1, this.pushCap()));
|
|
2097
|
+
}
|
|
2098
|
+
isLiveEdgeWait(e, t) {
|
|
2099
|
+
let n = e.latestLevelDetails;
|
|
2100
|
+
if (!n?.live) return !1;
|
|
2101
|
+
let r = n.partTarget || n.targetduration;
|
|
2102
|
+
return !(r > 0) || !(n.edge > 0) ? !1 : n.edge - (this.deps.video.currentTime + t) < An * r;
|
|
2103
|
+
}
|
|
2104
|
+
releaseStallCap() {
|
|
2105
|
+
let e = this.hls, t = Date.now(), n = this.stallCapTickAt;
|
|
2106
|
+
if (this.stallCapTickAt = t, !e || this.stallCapBitrate == null) return;
|
|
2107
|
+
if (this.deps.video.paused || this.loadSuspended || this.offlineHold) {
|
|
2108
|
+
n && (this.stallCapSince += t - Math.max(n, this.stallCapSince));
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2111
|
+
if (t - this.stallCapSince < On) return;
|
|
2112
|
+
let r = this.stallCapBitrate, i = e.levels.map((e) => e.bitrate).filter((e) => e > r).sort((e, t) => e - t)[0];
|
|
2113
|
+
this.stallCapBitrate = i ?? null, this.stallCapSince = t, this.pushCap();
|
|
2061
2114
|
}
|
|
2062
2115
|
reviewSizeCapHeadroom() {
|
|
2063
2116
|
let e = Date.now(), { video: t } = this.deps;
|
|
@@ -2068,26 +2121,26 @@ var Xn = class {
|
|
|
2068
2121
|
this.headroomGranted = !1, this.headroomSamples = [];
|
|
2069
2122
|
return;
|
|
2070
2123
|
}
|
|
2071
|
-
this.headroomSamples = this.headroomSamples.filter((t) => t.t >= e -
|
|
2124
|
+
this.headroomSamples = this.headroomSamples.filter((t) => t.t >= e - Hn);
|
|
2072
2125
|
let r = this.headroomEarned(n, e);
|
|
2073
|
-
r !== this.headroomGranted && (r || (this.headroomRegrantAt = e +
|
|
2126
|
+
r !== this.headroomGranted && (r || (this.headroomRegrantAt = e + Nn), this.headroomGranted = r, this.applySizeCapUnlessPending());
|
|
2074
2127
|
}
|
|
2075
2128
|
headroomEarned(e, t) {
|
|
2076
|
-
if (t - this.lastStallAt <
|
|
2129
|
+
if (t - this.lastStallAt < Mn || !this.headroomGranted && t < this.headroomRegrantAt || !this.headroomGranted && this.headroomSamples.length < q) return !1;
|
|
2077
2130
|
let n = e.levels, r = this.sizeCapCoverLevel();
|
|
2078
2131
|
if (r == null) return this.headroomGranted;
|
|
2079
|
-
let i = J(n, r,
|
|
2132
|
+
let i = J(n, r, xn);
|
|
2080
2133
|
if (i === r) return this.headroomGranted;
|
|
2081
|
-
let a = n[i]?.bitrate, o = e.bandwidthEstimate, s = this.headroomGranted ?
|
|
2134
|
+
let a = n[i]?.bitrate, o = e.bandwidthEstimate, s = this.headroomGranted ? En : Tn;
|
|
2082
2135
|
if (!(a > 0) || !(o >= s * a)) return !1;
|
|
2083
2136
|
let c = (e) => K([...e].sort((e, t) => e - t), 90);
|
|
2084
2137
|
if (this.headroomGranted) {
|
|
2085
2138
|
let e = this.headroomSamples.filter((e) => e.bitrate >= a).map((e) => e.ratio);
|
|
2086
|
-
return e.length < q || c(e) <=
|
|
2139
|
+
return e.length < q || c(e) <= wn;
|
|
2087
2140
|
}
|
|
2088
2141
|
let l = [];
|
|
2089
2142
|
for (let e of this.headroomSamples) e.bitrate < a && l.push(e.ratio * (a / e.bitrate));
|
|
2090
|
-
return l.length >= q && c(l) <=
|
|
2143
|
+
return l.length >= q && c(l) <= Cn;
|
|
2091
2144
|
}
|
|
2092
2145
|
applySizeCap() {
|
|
2093
2146
|
if (!this.sizeCapManaged) return;
|
|
@@ -2101,7 +2154,8 @@ var Xn = class {
|
|
|
2101
2154
|
let t = [
|
|
2102
2155
|
["size", this.sizeCapLevel ?? -1],
|
|
2103
2156
|
["bitrate", this.bitrateCapLevel],
|
|
2104
|
-
["fps", this.fpsCapLevel(e)]
|
|
2157
|
+
["fps", this.fpsCapLevel(e)],
|
|
2158
|
+
["stall", this.stallCapLevel(e)]
|
|
2105
2159
|
], n = -1, r = null;
|
|
2106
2160
|
for (let [e, i] of t) i >= 0 && (n < 0 || i < n) && (n = i, r = e);
|
|
2107
2161
|
e.autoLevelCapping = n, this.pushedCapLevel = n, this.pushedCapReason = r;
|
|
@@ -2146,6 +2200,7 @@ var Xn = class {
|
|
|
2146
2200
|
liveRetargets: this.liveRetargets,
|
|
2147
2201
|
holdBackSteps: this.holdBackSteps,
|
|
2148
2202
|
fpsDownCaps: this.fpsDownCaps,
|
|
2203
|
+
stallDownCaps: this.stallDownCaps,
|
|
2149
2204
|
licenseTimeMs: this.licenseTimeMs,
|
|
2150
2205
|
upshifts: this.upshifts,
|
|
2151
2206
|
downshifts: this.downshifts,
|
|
@@ -2160,12 +2215,7 @@ var Xn = class {
|
|
|
2160
2215
|
let t = e.currentLevel >= 0 ? e.levels[e.currentLevel] : void 0;
|
|
2161
2216
|
t && (n.levelHeight = t.height);
|
|
2162
2217
|
let r = e.autoLevelCapping, i = r >= 0 ? e.levels[r] : void 0;
|
|
2163
|
-
|
|
2164
|
-
n.maxLevelHeight = i.height;
|
|
2165
|
-
let t = e.config ?? {};
|
|
2166
|
-
t.capLevelToPlayerSize !== !0 && t.capLevelOnFPSDrop !== !0 && r === this.pushedCapLevel && this.pushedCapReason && (n.capReason = this.pushedCapReason);
|
|
2167
|
-
}
|
|
2168
|
-
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));
|
|
2218
|
+
i && i.height > 0 && (n.maxLevelHeight = i.height, !jn(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));
|
|
2169
2219
|
}
|
|
2170
2220
|
return n;
|
|
2171
2221
|
}
|
|
@@ -2193,7 +2243,7 @@ var Xn = class {
|
|
|
2193
2243
|
return;
|
|
2194
2244
|
}
|
|
2195
2245
|
let e = Date.now() - this.lastAdvanceMs;
|
|
2196
|
-
!this.chaseSuspended && e >
|
|
2246
|
+
!this.chaseSuspended && e > an && this.suspendChasing(), e > tn && this.emitEnded("stalled");
|
|
2197
2247
|
}
|
|
2198
2248
|
resetStarvationWindow() {
|
|
2199
2249
|
this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
|
|
@@ -2208,7 +2258,7 @@ var Xn = class {
|
|
|
2208
2258
|
this.resetStarvationWindow();
|
|
2209
2259
|
return;
|
|
2210
2260
|
}
|
|
2211
|
-
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs <
|
|
2261
|
+
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < an, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > fn, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = R(t), c = o - s, l = c !== this.starvedFrames;
|
|
2212
2262
|
if (this.starvedFrames = c, !a || l) {
|
|
2213
2263
|
(t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
|
|
2214
2264
|
return;
|
|
@@ -2217,12 +2267,12 @@ var Xn = class {
|
|
|
2217
2267
|
this.resetStarvationWindow();
|
|
2218
2268
|
return;
|
|
2219
2269
|
}
|
|
2220
|
-
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 >
|
|
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 > _n && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= hn && (this.clearKick(), this.starvationRebuilds < gn)) {
|
|
2221
2271
|
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");
|
|
2222
2272
|
return;
|
|
2223
2273
|
}
|
|
2224
|
-
let u = i && this.starvedTicks >=
|
|
2225
|
-
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >=
|
|
2274
|
+
let u = i && this.starvedTicks >= pn, d = !i && this.deadTicks >= _n && this.recentMainFrags.reduce((e, t) => e + t, 0) >= vn;
|
|
2275
|
+
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= mn))) {
|
|
2226
2276
|
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");
|
|
2227
2277
|
try {
|
|
2228
2278
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -2237,7 +2287,7 @@ var Xn = class {
|
|
|
2237
2287
|
let t = e.latency, n = e.targetLatency;
|
|
2238
2288
|
if (typeof t != "number" || typeof n != "number" || !Number.isFinite(t)) return;
|
|
2239
2289
|
let r = t - n;
|
|
2240
|
-
!this.catchUpEngaged && r >
|
|
2290
|
+
!this.catchUpEngaged && r > on ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= on && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
|
|
2241
2291
|
let i = this.catchUpEngaged ? this.catchUpRate : 1;
|
|
2242
2292
|
e.config.maxLiveSyncPlaybackRate !== i && (e.config.maxLiveSyncPlaybackRate = i);
|
|
2243
2293
|
}
|
|
@@ -2250,7 +2300,7 @@ var Xn = class {
|
|
|
2250
2300
|
}), n < 0 ? 0 : n;
|
|
2251
2301
|
}
|
|
2252
2302
|
armFrameDropGrace() {
|
|
2253
|
-
this.fpsGraceTicks > 0 || (this.fpsGraceTicks =
|
|
2303
|
+
this.fpsGraceTicks > 0 || (this.fpsGraceTicks = Ln, this.fpsBadTicks = 0);
|
|
2254
2304
|
}
|
|
2255
2305
|
resetFrameDropWindow() {
|
|
2256
2306
|
this.fpsLastFrames = -1, this.fpsLastDropped = -1, this.fpsBadTicks = 0;
|
|
@@ -2262,7 +2312,7 @@ var Xn = class {
|
|
|
2262
2312
|
return;
|
|
2263
2313
|
}
|
|
2264
2314
|
let { totalFrames: n, dropped: r } = R(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
|
|
2265
|
-
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a <
|
|
2315
|
+
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < Fn || o < 0) {
|
|
2266
2316
|
this.fpsBadTicks = 0;
|
|
2267
2317
|
return;
|
|
2268
2318
|
}
|
|
@@ -2270,11 +2320,11 @@ var Xn = class {
|
|
|
2270
2320
|
--this.fpsGraceTicks, this.fpsBadTicks = 0;
|
|
2271
2321
|
return;
|
|
2272
2322
|
}
|
|
2273
|
-
if (o <=
|
|
2323
|
+
if (o <= Pn * a) {
|
|
2274
2324
|
this.fpsBadTicks = 0;
|
|
2275
2325
|
return;
|
|
2276
2326
|
}
|
|
2277
|
-
if (this.fpsBadTicks += 1, this.fpsBadTicks <
|
|
2327
|
+
if (this.fpsBadTicks += 1, this.fpsBadTicks < In) return;
|
|
2278
2328
|
this.fpsBadTicks = 0;
|
|
2279
2329
|
let s = e.levels, c = s[e.currentLevel];
|
|
2280
2330
|
if (!c) return;
|
|
@@ -2291,22 +2341,22 @@ var Xn = class {
|
|
|
2291
2341
|
return;
|
|
2292
2342
|
}
|
|
2293
2343
|
let n = e.latency, r = t.playbackRate, i = e.config.maxLiveSyncPlaybackRate;
|
|
2294
|
-
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(
|
|
2344
|
+
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(ln, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
|
|
2295
2345
|
this.resetChaseWindow();
|
|
2296
2346
|
return;
|
|
2297
2347
|
}
|
|
2298
|
-
if (this.chaseLatency < 0 || this.chaseLatency - n >=
|
|
2348
|
+
if (this.chaseLatency < 0 || this.chaseLatency - n >= cn) {
|
|
2299
2349
|
this.chaseLatency = n, this.chaseTicks = 0;
|
|
2300
2350
|
return;
|
|
2301
2351
|
}
|
|
2302
|
-
if (this.chaseTicks += 1, this.chaseTicks <
|
|
2352
|
+
if (this.chaseTicks += 1, this.chaseTicks < sn) return;
|
|
2303
2353
|
this.resetChaseWindow();
|
|
2304
2354
|
let a = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
|
|
2305
2355
|
if (!(a > 1)) return;
|
|
2306
2356
|
let o = e.targetLatency;
|
|
2307
2357
|
if (typeof o != "number" || !(o > 0)) return;
|
|
2308
2358
|
let s = Math.min(n, a - 1);
|
|
2309
|
-
s < o +
|
|
2359
|
+
s < o + un || (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({
|
|
2310
2360
|
type: "livetargetchange",
|
|
2311
2361
|
change: {
|
|
2312
2362
|
targetSeconds: s,
|
|
@@ -2323,13 +2373,13 @@ var Xn = class {
|
|
|
2323
2373
|
if (!this.holdBackEnabled || this.holdBackPriorChecked || !e || (this.holdBackPriorChecked = !0, this.holdBackApplied > 0 || this.holdBackStepCount > 0)) return;
|
|
2324
2374
|
let t = e.targetLatency;
|
|
2325
2375
|
if (this.holdBackBase < 0 && typeof t == "number" && t > 0 && (this.holdBackBase = t), this.holdBackBase < 0) return;
|
|
2326
|
-
let n =
|
|
2327
|
-
if (!(n >=
|
|
2376
|
+
let n = Zn();
|
|
2377
|
+
if (!(n >= Xn)) return;
|
|
2328
2378
|
let r = typeof t == "number" && t > 0 ? t : this.holdBackBase, i = Math.min(this.holdBackCeiling(e), this.holdBackBase + X);
|
|
2329
2379
|
i > r && (this.holdBackStepCount = 1, this.moveHoldBack(e, r, i, "connection-rtt", `connection rtt ${n} ms`));
|
|
2330
2380
|
}
|
|
2331
2381
|
holdBackCeiling(e) {
|
|
2332
|
-
let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t :
|
|
2382
|
+
let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t : Yn, r = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
|
|
2333
2383
|
return r > 1 ? Math.min(n, r - 1) : n;
|
|
2334
2384
|
}
|
|
2335
2385
|
sampleHoldBack(e) {
|
|
@@ -2338,7 +2388,7 @@ var Xn = class {
|
|
|
2338
2388
|
if (t !== "main" && t !== "audio") return;
|
|
2339
2389
|
let n = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag?.duration;
|
|
2340
2390
|
if (typeof n != "number" || !(n > 0)) return;
|
|
2341
|
-
let r =
|
|
2391
|
+
let r = Z(e)?.loading;
|
|
2342
2392
|
if (!r || !(r.start > 0) || !(r.end > 0)) return;
|
|
2343
2393
|
let i = r.first > r.start ? r.first : r.end, a = Math.max(0, i - r.start) / (n * 1e3);
|
|
2344
2394
|
this.holdBackSamples.push({
|
|
@@ -2353,20 +2403,20 @@ var Xn = class {
|
|
|
2353
2403
|
this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [];
|
|
2354
2404
|
return;
|
|
2355
2405
|
}
|
|
2356
|
-
let t = Date.now(), n = t -
|
|
2406
|
+
let t = Date.now(), n = t - Hn, r = this.holdBackSamples, i = 0;
|
|
2357
2407
|
for (; i < r.length && r[i].t < n;) i += 1;
|
|
2358
2408
|
i > 0 && r.splice(0, i);
|
|
2359
2409
|
let a = e.targetLatency;
|
|
2360
2410
|
if (typeof a != "number" || !(a > 0)) return;
|
|
2361
2411
|
this.holdBackBase < 0 && (this.holdBackBase = a);
|
|
2362
2412
|
let o = this.holdBackBase, s = this.holdBackCeiling(e);
|
|
2363
|
-
if (r.length <
|
|
2413
|
+
if (r.length < Un) {
|
|
2364
2414
|
this.holdBackSlowTicks = 0;
|
|
2365
2415
|
return;
|
|
2366
2416
|
}
|
|
2367
2417
|
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);
|
|
2368
|
-
if (l >=
|
|
2369
|
-
if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks <
|
|
2418
|
+
if (l >= Wn && u >= Gn) {
|
|
2419
|
+
if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks < qn) return;
|
|
2370
2420
|
this.holdBackSlowTicks = 0;
|
|
2371
2421
|
let t = Math.ceil((s - o) / X), n = Math.ceil((a - o) / X - 1e-9);
|
|
2372
2422
|
if (n > this.holdBackStepCount && (this.holdBackStepCount = n), this.holdBackStepCount >= t) return;
|
|
@@ -2376,7 +2426,7 @@ var Xn = class {
|
|
|
2376
2426
|
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)`);
|
|
2377
2427
|
return;
|
|
2378
2428
|
}
|
|
2379
|
-
if (this.holdBackSlowTicks = 0, l >=
|
|
2429
|
+
if (this.holdBackSlowTicks = 0, l >= Kn) {
|
|
2380
2430
|
this.holdBackFastSince = 0;
|
|
2381
2431
|
return;
|
|
2382
2432
|
}
|
|
@@ -2384,7 +2434,7 @@ var Xn = class {
|
|
|
2384
2434
|
this.holdBackFastSince = t;
|
|
2385
2435
|
return;
|
|
2386
2436
|
}
|
|
2387
|
-
if (t - this.holdBackFastSince <
|
|
2437
|
+
if (t - this.holdBackFastSince < Jn || (this.holdBackFastSince = t, this.holdBackStepCount === 0 || a !== this.holdBackApplied)) return;
|
|
2388
2438
|
--this.holdBackStepCount;
|
|
2389
2439
|
let f = Math.max(o, o + this.holdBackStepCount * X);
|
|
2390
2440
|
f >= a || this.moveHoldBack(e, a, f, "fast-fetches", `part fetches fast again (p95 first byte ${d} ms per 1 s of media)`);
|
|
@@ -2427,14 +2477,14 @@ var Xn = class {
|
|
|
2427
2477
|
} catch {}
|
|
2428
2478
|
}
|
|
2429
2479
|
startEstimate() {
|
|
2430
|
-
return this.deps.rememberBandwidth === !1 ?
|
|
2480
|
+
return this.deps.rememberBandwidth === !1 ? qt : Re() ?? qt;
|
|
2431
2481
|
}
|
|
2432
2482
|
maybeRememberBandwidth(e) {
|
|
2433
|
-
if (this.deps.rememberBandwidth === !1 || this.bwFragsLoaded <
|
|
2483
|
+
if (this.deps.rememberBandwidth === !1 || this.bwFragsLoaded < Jt) return;
|
|
2434
2484
|
let t = Date.now();
|
|
2435
|
-
if (!e && t - this.bwSavedAt <
|
|
2485
|
+
if (!e && t - this.bwSavedAt < Yt) return;
|
|
2436
2486
|
let n = this.hls?.bandwidthEstimate;
|
|
2437
|
-
typeof n != "number" || !Number.isFinite(n) || n <= 0 || (this.bwSavedAt = t,
|
|
2487
|
+
typeof n != "number" || !Number.isFinite(n) || n <= 0 || (this.bwSavedAt = t, ze(n));
|
|
2438
2488
|
}
|
|
2439
2489
|
destroy() {
|
|
2440
2490
|
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) {
|
|
@@ -2452,7 +2502,7 @@ var Xn = class {
|
|
|
2452
2502
|
scheduleLicenseRetry(t) {
|
|
2453
2503
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
2454
2504
|
let n = t.response?.code ?? 0;
|
|
2455
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
2505
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Qt) return !1;
|
|
2456
2506
|
this.licenseRecoveries += 1;
|
|
2457
2507
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
2458
2508
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -2470,7 +2520,7 @@ var Xn = class {
|
|
|
2470
2520
|
}
|
|
2471
2521
|
}
|
|
2472
2522
|
onError(t) {
|
|
2473
|
-
if (t.details === e.ErrorDetails.BUFFER_STALLED_ERROR && this.onPlaybackStall(), t.type === e.ErrorTypes.NETWORK_ERROR && String(t.details ?? "").startsWith("frag") && (this.requestErrors += 1), !t.fatal) return;
|
|
2523
|
+
if (t.details === e.ErrorDetails.BUFFER_STALLED_ERROR && this.onPlaybackStall(t.buffer), t.type === e.ErrorTypes.NETWORK_ERROR && String(t.details ?? "").startsWith("frag") && (this.requestErrors += 1), !t.fatal) return;
|
|
2474
2524
|
let n = this.hls;
|
|
2475
2525
|
if (n) {
|
|
2476
2526
|
if (this.clearRecoveryReset(), t.type === e.ErrorTypes.KEY_SYSTEM_ERROR) {
|
|
@@ -2488,7 +2538,7 @@ var Xn = class {
|
|
|
2488
2538
|
this.offlineHold = !0, this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null);
|
|
2489
2539
|
return;
|
|
2490
2540
|
}
|
|
2491
|
-
if (this.networkRecoveries <
|
|
2541
|
+
if (this.networkRecoveries < Zt) {
|
|
2492
2542
|
this.networkRecoveries += 1;
|
|
2493
2543
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
2494
2544
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -2505,7 +2555,7 @@ var Xn = class {
|
|
|
2505
2555
|
return;
|
|
2506
2556
|
}
|
|
2507
2557
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
2508
|
-
if (this.mediaRecoveries <
|
|
2558
|
+
if (this.mediaRecoveries < Xt) {
|
|
2509
2559
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
2510
2560
|
return;
|
|
2511
2561
|
}
|
|
@@ -2526,18 +2576,18 @@ var Xn = class {
|
|
|
2526
2576
|
}
|
|
2527
2577
|
}
|
|
2528
2578
|
toError(t, r = "PLAYBACK") {
|
|
2529
|
-
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(
|
|
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(Nt(t.networkDetails)) : void 0;
|
|
2530
2580
|
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);
|
|
2531
2581
|
}
|
|
2532
|
-
},
|
|
2582
|
+
}, tr = 15e3, nr = 6e5, rr = 3e5, ir = 100, Q = 1, ar = 1e3, or = 3e4, sr = 1e3, cr = {
|
|
2533
2583
|
inline: "PRESENTATION_INLINE",
|
|
2534
2584
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
2535
2585
|
pip: "PRESENTATION_PIP"
|
|
2536
|
-
},
|
|
2586
|
+
}, lr = {
|
|
2537
2587
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
2538
2588
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
2539
2589
|
none: "KEY_SYSTEM_NONE"
|
|
2540
|
-
},
|
|
2590
|
+
}, ur = /* @__PURE__ */ new Set([
|
|
2541
2591
|
"INVALID_URN",
|
|
2542
2592
|
"NOT_FOUND",
|
|
2543
2593
|
"GEO_DENIED",
|
|
@@ -2548,7 +2598,7 @@ var Xn = class {
|
|
|
2548
2598
|
"FORBIDDEN",
|
|
2549
2599
|
"RATE_LIMITED",
|
|
2550
2600
|
"TIMEOUT"
|
|
2551
|
-
]),
|
|
2601
|
+
]), dr = {
|
|
2552
2602
|
idle: "PLAYER_STATE_IDLE",
|
|
2553
2603
|
waiting: "PLAYER_STATE_WAITING",
|
|
2554
2604
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -2558,7 +2608,7 @@ var Xn = class {
|
|
|
2558
2608
|
ended: "PLAYER_STATE_ENDED",
|
|
2559
2609
|
error: "PLAYER_STATE_ERROR"
|
|
2560
2610
|
};
|
|
2561
|
-
function
|
|
2611
|
+
function fr(e) {
|
|
2562
2612
|
try {
|
|
2563
2613
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
2564
2614
|
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);
|
|
@@ -2566,8 +2616,8 @@ function cr(e) {
|
|
|
2566
2616
|
return;
|
|
2567
2617
|
}
|
|
2568
2618
|
}
|
|
2569
|
-
var
|
|
2570
|
-
function
|
|
2619
|
+
var pr = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), mr = /* @__PURE__ */ new Set(), hr = /* @__PURE__ */ new Set(), gr = /* @__PURE__ */ new Set(), _r = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
|
|
2620
|
+
function vr(e) {
|
|
2571
2621
|
if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
|
|
2572
2622
|
let t;
|
|
2573
2623
|
try {
|
|
@@ -2576,19 +2626,19 @@ function mr(e) {
|
|
|
2576
2626
|
} catch {
|
|
2577
2627
|
return;
|
|
2578
2628
|
}
|
|
2579
|
-
if (
|
|
2580
|
-
|
|
2581
|
-
for (let e of
|
|
2629
|
+
if (mr.has(t) && !hr.has(t)) {
|
|
2630
|
+
hr.add(t), _(_r(new URL(t).origin));
|
|
2631
|
+
for (let e of gr) e.noteCspBlocked();
|
|
2582
2632
|
}
|
|
2583
2633
|
}
|
|
2584
|
-
function
|
|
2634
|
+
function yr(e, t) {
|
|
2585
2635
|
return _(t, e), { disabledReason: t };
|
|
2586
2636
|
}
|
|
2587
|
-
function
|
|
2588
|
-
if (n) return t && !
|
|
2637
|
+
function br(e, t, n) {
|
|
2638
|
+
if (n) return t && !pr(t, n) && _(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
|
|
2589
2639
|
if (t) return { endpoint: t };
|
|
2590
|
-
if (t !== void 0) return
|
|
2591
|
-
let r =
|
|
2640
|
+
if (t !== void 0) return yr("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).");
|
|
2641
|
+
let r = fr(e);
|
|
2592
2642
|
if (r) return { endpoint: r };
|
|
2593
2643
|
let i;
|
|
2594
2644
|
try {
|
|
@@ -2596,9 +2646,9 @@ function gr(e, t, n) {
|
|
|
2596
2646
|
} catch {
|
|
2597
2647
|
i = e;
|
|
2598
2648
|
}
|
|
2599
|
-
return
|
|
2649
|
+
return yr(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).`);
|
|
2600
2650
|
}
|
|
2601
|
-
var
|
|
2651
|
+
var xr = class {
|
|
2602
2652
|
opts;
|
|
2603
2653
|
url;
|
|
2604
2654
|
cspKey;
|
|
@@ -2680,8 +2730,8 @@ var _r = class {
|
|
|
2680
2730
|
constructor(e) {
|
|
2681
2731
|
this.opts = {
|
|
2682
2732
|
...e,
|
|
2683
|
-
heartbeatMs: e.heartbeatMs ??
|
|
2684
|
-
idleMs: e.idleMs ??
|
|
2733
|
+
heartbeatMs: e.heartbeatMs ?? tr,
|
|
2734
|
+
idleMs: e.idleMs ?? nr
|
|
2685
2735
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
|
|
2686
2736
|
try {
|
|
2687
2737
|
let e = new URL(this.url);
|
|
@@ -2698,11 +2748,11 @@ var _r = class {
|
|
|
2698
2748
|
sdkVersion: this.opts.sdkVersion,
|
|
2699
2749
|
...this.opts.environment
|
|
2700
2750
|
};
|
|
2701
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
2751
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), ar), 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 && mr.add(this.cspKey), document.addEventListener("securitypolicyviolation", vr), gr.add(this), this.noteCspBlocked(), this.onVisibility());
|
|
2702
2752
|
}
|
|
2703
2753
|
checkSuspension(e) {
|
|
2704
2754
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
2705
|
-
let t = Math.max(this.opts.idleMs,
|
|
2755
|
+
let t = Math.max(this.opts.idleMs, rr);
|
|
2706
2756
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
2707
2757
|
}
|
|
2708
2758
|
syncIdle(e) {
|
|
@@ -2716,21 +2766,21 @@ var _r = class {
|
|
|
2716
2766
|
noteStateChange(e, t, n, r) {
|
|
2717
2767
|
if (this.endedFlag || e === t) return;
|
|
2718
2768
|
let i = this.now();
|
|
2719
|
-
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(
|
|
2769
|
+
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(Q, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(Q, 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") {
|
|
2720
2770
|
this.stallIsSeekInduced = this.seekInduced(i);
|
|
2721
2771
|
let e = !this.isHidden && !this.stallIsSeekInduced;
|
|
2722
|
-
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(
|
|
2772
|
+
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(Q, Math.round(this.playingTotalMs)));
|
|
2723
2773
|
} else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
|
|
2724
2774
|
this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
|
|
2725
2775
|
let a = {
|
|
2726
|
-
fromState:
|
|
2727
|
-
toState:
|
|
2728
|
-
presentation:
|
|
2776
|
+
fromState: dr[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2777
|
+
toState: dr[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2778
|
+
presentation: cr[this.presentation]
|
|
2729
2779
|
}, o = this.causeOf(e, t, i);
|
|
2730
2780
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
2731
2781
|
}
|
|
2732
2782
|
seekInduced(e) {
|
|
2733
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
2783
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < sr;
|
|
2734
2784
|
}
|
|
2735
2785
|
causeOf(e, t, n) {
|
|
2736
2786
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -2767,25 +2817,25 @@ var _r = class {
|
|
|
2767
2817
|
}
|
|
2768
2818
|
this.muteChanges += 1;
|
|
2769
2819
|
let r = this.now();
|
|
2770
|
-
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(
|
|
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(Q, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
|
|
2771
2821
|
}
|
|
2772
2822
|
notePresentation(e) {
|
|
2773
2823
|
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
2774
2824
|
}
|
|
2775
2825
|
notePlayIntent() {
|
|
2776
|
-
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs =
|
|
2826
|
+
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = Q), this.firstPlaylistMs > 0 && (this.firstPlaylistMs = Q), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = Q), this.drmSetupMs > 0 && (this.drmSetupMs = Q));
|
|
2777
2827
|
}
|
|
2778
2828
|
noteReady() {
|
|
2779
|
-
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(
|
|
2829
|
+
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(Q, this.now() - this.startupAnchorMs));
|
|
2780
2830
|
}
|
|
2781
2831
|
noteFirstPlaylist() {
|
|
2782
|
-
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(
|
|
2832
|
+
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(Q, this.now() - this.startupAnchorMs));
|
|
2783
2833
|
}
|
|
2784
2834
|
noteDrmReady() {
|
|
2785
|
-
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(
|
|
2835
|
+
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(Q, this.now() - this.startupAnchorMs));
|
|
2786
2836
|
}
|
|
2787
2837
|
noteFirstBytes() {
|
|
2788
|
-
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(
|
|
2838
|
+
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(Q, this.now() - this.startupAnchorMs));
|
|
2789
2839
|
}
|
|
2790
2840
|
noteSeek() {
|
|
2791
2841
|
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
@@ -2804,7 +2854,7 @@ var _r = class {
|
|
|
2804
2854
|
let r = n ?? "";
|
|
2805
2855
|
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";
|
|
2806
2856
|
if (e === "DRM_CLIENT" || e === "DRM_DEVICE_REVOKED") return "ERROR_STAGE_DRM";
|
|
2807
|
-
if (
|
|
2857
|
+
if (ur.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
2808
2858
|
let i = t ?? "";
|
|
2809
2859
|
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";
|
|
2810
2860
|
}
|
|
@@ -2836,7 +2886,7 @@ var _r = class {
|
|
|
2836
2886
|
let l = t.droppedFrames ?? 0;
|
|
2837
2887
|
l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
|
|
2838
2888
|
let u = t.renditionSwitches ?? 0;
|
|
2839
|
-
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 =
|
|
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 = dr[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
|
|
2840
2890
|
let d = this.mutedTotalMs;
|
|
2841
2891
|
this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
|
|
2842
2892
|
let f = t.upshifts ?? 0;
|
|
@@ -2858,13 +2908,13 @@ var _r = class {
|
|
|
2858
2908
|
maybeEmitMediaInfo(e) {
|
|
2859
2909
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
2860
2910
|
let t = {};
|
|
2861
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
2911
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = lr[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);
|
|
2862
2912
|
let n = JSON.stringify(t);
|
|
2863
2913
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
2864
2914
|
}
|
|
2865
2915
|
end(e, t) {
|
|
2866
2916
|
if (this.endedFlag) return;
|
|
2867
|
-
this.endedFlag = !0,
|
|
2917
|
+
this.endedFlag = !0, gr.delete(this);
|
|
2868
2918
|
let n = t ?? this.now();
|
|
2869
2919
|
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));
|
|
2870
2920
|
let r = this.safeSample();
|
|
@@ -2878,7 +2928,7 @@ var _r = class {
|
|
|
2878
2928
|
let c = r?.positionMs ?? 0;
|
|
2879
2929
|
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));
|
|
2880
2930
|
let l = e !== "END_REASON_ENDED";
|
|
2881
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
2931
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= or && (i.abandonAfterStallMs = Math.max(Q, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= or && (i.abandonAfterErrorMs = Math.max(Q, 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);
|
|
2882
2932
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
2883
2933
|
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");
|
|
2884
2934
|
}
|
|
@@ -2898,13 +2948,13 @@ var _r = class {
|
|
|
2898
2948
|
};
|
|
2899
2949
|
}
|
|
2900
2950
|
noteCspBlocked() {
|
|
2901
|
-
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(
|
|
2951
|
+
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(_r(new URL(this.url).origin)));
|
|
2902
2952
|
}
|
|
2903
2953
|
cspBlocked() {
|
|
2904
|
-
return !!this.cspKey &&
|
|
2954
|
+
return !!this.cspKey && hr.has(this.cspKey);
|
|
2905
2955
|
}
|
|
2906
2956
|
enqueue(e) {
|
|
2907
|
-
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
2957
|
+
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > ir;) {
|
|
2908
2958
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
2909
2959
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
2910
2960
|
}
|
|
@@ -2931,7 +2981,7 @@ var _r = class {
|
|
|
2931
2981
|
};
|
|
2932
2982
|
//#endregion
|
|
2933
2983
|
//#region src/core/environment.ts
|
|
2934
|
-
function
|
|
2984
|
+
function Sr() {
|
|
2935
2985
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
2936
2986
|
let e;
|
|
2937
2987
|
try {
|
|
@@ -2956,14 +3006,14 @@ function vr() {
|
|
|
2956
3006
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
2957
3007
|
};
|
|
2958
3008
|
}
|
|
2959
|
-
function
|
|
3009
|
+
function Cr() {
|
|
2960
3010
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
2961
3011
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
2962
3012
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
2963
3013
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
2964
3014
|
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";
|
|
2965
3015
|
}
|
|
2966
|
-
function
|
|
3016
|
+
function wr() {
|
|
2967
3017
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
2968
3018
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
2969
3019
|
let t = {
|
|
@@ -2982,17 +3032,17 @@ function br() {
|
|
|
2982
3032
|
}
|
|
2983
3033
|
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;
|
|
2984
3034
|
}
|
|
2985
|
-
function
|
|
2986
|
-
let t =
|
|
2987
|
-
deviceClass:
|
|
3035
|
+
function Tr(e) {
|
|
3036
|
+
let t = Sr(), n = {
|
|
3037
|
+
deviceClass: Cr(),
|
|
2988
3038
|
integration: t.integration,
|
|
2989
|
-
...
|
|
3039
|
+
...wr()
|
|
2990
3040
|
};
|
|
2991
3041
|
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);
|
|
2992
3042
|
let r = e.getBoundingClientRect?.();
|
|
2993
3043
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
2994
3044
|
}
|
|
2995
|
-
async function
|
|
3045
|
+
async function Er() {
|
|
2996
3046
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
2997
3047
|
if (!e?.getHighEntropyValues) return {};
|
|
2998
3048
|
try {
|
|
@@ -3004,7 +3054,7 @@ async function Sr() {
|
|
|
3004
3054
|
}
|
|
3005
3055
|
//#endregion
|
|
3006
3056
|
//#region src/core/version.ts
|
|
3007
|
-
var
|
|
3057
|
+
var Dr = "2.27.1", Or = {
|
|
3008
3058
|
accent: "#E1B600",
|
|
3009
3059
|
accentText: "#1B1C23",
|
|
3010
3060
|
background: "#0e0f13",
|
|
@@ -3015,7 +3065,7 @@ var Cr = "2.26.1", wr = {
|
|
|
3015
3065
|
border: "rgba(255, 255, 255, 0.1)",
|
|
3016
3066
|
radius: "8px",
|
|
3017
3067
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
3018
|
-
},
|
|
3068
|
+
}, kr = {
|
|
3019
3069
|
accent: "--havik-accent",
|
|
3020
3070
|
accentText: "--havik-accent-text",
|
|
3021
3071
|
background: "--havik-bg",
|
|
@@ -3027,26 +3077,26 @@ var Cr = "2.26.1", wr = {
|
|
|
3027
3077
|
radius: "--havik-radius",
|
|
3028
3078
|
fontFamily: "--havik-font"
|
|
3029
3079
|
};
|
|
3030
|
-
function
|
|
3080
|
+
function Ar(e, t) {
|
|
3031
3081
|
let n = {
|
|
3032
|
-
...
|
|
3082
|
+
...Or,
|
|
3033
3083
|
...t
|
|
3034
3084
|
};
|
|
3035
|
-
for (let t of Object.keys(
|
|
3085
|
+
for (let t of Object.keys(kr)) e.style.setProperty(kr[t], n[t]);
|
|
3036
3086
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
3037
3087
|
}
|
|
3038
3088
|
//#endregion
|
|
3039
3089
|
//#region src/ui/styles.ts
|
|
3040
|
-
var
|
|
3041
|
-
function
|
|
3042
|
-
let n = e.querySelector(`style#${
|
|
3043
|
-
if (n && (!t ||
|
|
3090
|
+
var jr = "havik-player-styles", Mr = "\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", Nr = /* @__PURE__ */ new WeakMap();
|
|
3091
|
+
function Pr(e = document, t) {
|
|
3092
|
+
let n = e.querySelector(`style#${jr}`);
|
|
3093
|
+
if (n && (!t || Nr.get(n) === t)) return;
|
|
3044
3094
|
let r = e.createElement("style");
|
|
3045
|
-
r.id =
|
|
3095
|
+
r.id = jr, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = Mr, Nr.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
|
|
3046
3096
|
}
|
|
3047
3097
|
//#endregion
|
|
3048
3098
|
//#region src/ui/icons.ts
|
|
3049
|
-
var
|
|
3099
|
+
var Fr = {
|
|
3050
3100
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
3051
3101
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
3052
3102
|
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\"/>",
|
|
@@ -3059,12 +3109,12 @@ var jr = {
|
|
|
3059
3109
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
3060
3110
|
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\"/>"
|
|
3061
3111
|
};
|
|
3062
|
-
function
|
|
3063
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
3112
|
+
function $(e) {
|
|
3113
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Fr[e]}</svg>`;
|
|
3064
3114
|
}
|
|
3065
3115
|
//#endregion
|
|
3066
3116
|
//#region src/ui/controls.ts
|
|
3067
|
-
var
|
|
3117
|
+
var Ir = 3e3, Lr = 250, Rr = /* @__PURE__ */ new Set([
|
|
3068
3118
|
"GONE",
|
|
3069
3119
|
"NOT_FOUND",
|
|
3070
3120
|
"GEO_DENIED",
|
|
@@ -3072,15 +3122,15 @@ var Mr = 3e3, Nr = 250, Pr = /* @__PURE__ */ new Set([
|
|
|
3072
3122
|
"UNAUTHORIZED",
|
|
3073
3123
|
"DRM_DEVICE_REVOKED"
|
|
3074
3124
|
]);
|
|
3075
|
-
function
|
|
3125
|
+
function zr(e) {
|
|
3076
3126
|
let t = "This match isn't available in your country";
|
|
3077
3127
|
return e ? `${t} (${e})` : t;
|
|
3078
3128
|
}
|
|
3079
|
-
var
|
|
3080
|
-
function
|
|
3081
|
-
return new
|
|
3129
|
+
var Br = "This device can't play protected video";
|
|
3130
|
+
function Vr(e) {
|
|
3131
|
+
return new Hr(e);
|
|
3082
3132
|
}
|
|
3083
|
-
var
|
|
3133
|
+
var Hr = class {
|
|
3084
3134
|
root;
|
|
3085
3135
|
video;
|
|
3086
3136
|
player;
|
|
@@ -3129,7 +3179,7 @@ var Rr = class {
|
|
|
3129
3179
|
scrubbing = !1;
|
|
3130
3180
|
offFns = [];
|
|
3131
3181
|
constructor(e) {
|
|
3132
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
3182
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Ir, 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", Pr(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");
|
|
3133
3183
|
let t = (e, t, n) => {
|
|
3134
3184
|
let r = this.doc.createElement(e);
|
|
3135
3185
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -3140,12 +3190,12 @@ var Rr = class {
|
|
|
3140
3190
|
"aria-label": r,
|
|
3141
3191
|
title: r
|
|
3142
3192
|
});
|
|
3143
|
-
return i.innerHTML =
|
|
3193
|
+
return i.innerHTML = $(n), i;
|
|
3144
3194
|
};
|
|
3145
3195
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
3146
3196
|
type: "button",
|
|
3147
3197
|
"aria-label": "Play"
|
|
3148
|
-
}), this.center.innerHTML =
|
|
3198
|
+
}), this.center.innerHTML = $("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", {
|
|
3149
3199
|
role: "slider",
|
|
3150
3200
|
"aria-label": "Seek",
|
|
3151
3201
|
"aria-valuemin": "0",
|
|
@@ -3163,7 +3213,7 @@ var Rr = class {
|
|
|
3163
3213
|
"aria-label": "Volume"
|
|
3164
3214
|
});
|
|
3165
3215
|
let a = t("div", "havik-vol");
|
|
3166
|
-
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML =
|
|
3216
|
+
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = $("liveDot");
|
|
3167
3217
|
let o = this.doc.createElement("span");
|
|
3168
3218
|
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";
|
|
3169
3219
|
let s = t("div", "havik-spacer");
|
|
@@ -3215,7 +3265,7 @@ var Rr = class {
|
|
|
3215
3265
|
let t = this.surfaceWasHidden;
|
|
3216
3266
|
this.tapTimer = setTimeout(() => {
|
|
3217
3267
|
this.tapTimer = void 0, this.toggleBar(t);
|
|
3218
|
-
},
|
|
3268
|
+
}, Lr);
|
|
3219
3269
|
}
|
|
3220
3270
|
toggleBar(e) {
|
|
3221
3271
|
e ? this.poke() : this.hideIfIdle();
|
|
@@ -3242,7 +3292,7 @@ var Rr = class {
|
|
|
3242
3292
|
this.renderStatus(t);
|
|
3243
3293
|
}
|
|
3244
3294
|
statusMessageFor(e) {
|
|
3245
|
-
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" ?
|
|
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" ? zr(this.lastError.country) : this.lastError?.code === "DRM_DEVICE_REVOKED" ? Br : this.lastError?.message ?? "Playback unavailable" : this.errorMessage : null;
|
|
3246
3296
|
}
|
|
3247
3297
|
renderStatus(e) {
|
|
3248
3298
|
let t = this.statusMessageFor(e);
|
|
@@ -3254,12 +3304,12 @@ var Rr = class {
|
|
|
3254
3304
|
}
|
|
3255
3305
|
if (e === "preplay") {
|
|
3256
3306
|
let e = this.doc.createElement("button");
|
|
3257
|
-
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML =
|
|
3307
|
+
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = $("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
|
|
3258
3308
|
} else {
|
|
3259
3309
|
let r = this.doc.createElement("div");
|
|
3260
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
3310
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Rr.has(this.lastError.code)) {
|
|
3261
3311
|
let e = this.doc.createElement("button");
|
|
3262
|
-
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${
|
|
3312
|
+
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${$("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
|
|
3263
3313
|
}
|
|
3264
3314
|
}
|
|
3265
3315
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -3298,7 +3348,7 @@ var Rr = class {
|
|
|
3298
3348
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
3299
3349
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
3300
3350
|
}
|
|
3301
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
3351
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Ur(this.video.currentTime)} / ${Ur(this.video.duration)}`);
|
|
3302
3352
|
}
|
|
3303
3353
|
syncLive() {
|
|
3304
3354
|
let e = this.player.getStats(), t = e.isLive !== !1, n = this.isGone(), r = this.player.state === "ended" || n, i = !t && !this.streamEnded() && !n;
|
|
@@ -3348,17 +3398,17 @@ var Rr = class {
|
|
|
3348
3398
|
renderQualityMenu() {
|
|
3349
3399
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
3350
3400
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
3351
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
3401
|
+
for (let n of e) this.menu.append(this.menuItem(Wr(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
3352
3402
|
}
|
|
3353
3403
|
renderAudioMenu() {
|
|
3354
3404
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
3355
3405
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
3356
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
3406
|
+
for (let t of e) this.menu.append(this.menuItem(Gr(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
3357
3407
|
}
|
|
3358
3408
|
renderCcMenu() {
|
|
3359
3409
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
3360
3410
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
3361
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
3411
|
+
for (let t of e) this.menu.append(this.menuItem(Kr(t), !1, () => this.player.setTextTrack(t.id)));
|
|
3362
3412
|
}
|
|
3363
3413
|
onTracksChanged() {
|
|
3364
3414
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -3378,14 +3428,14 @@ var Rr = class {
|
|
|
3378
3428
|
}
|
|
3379
3429
|
async toggleFullscreen() {
|
|
3380
3430
|
try {
|
|
3381
|
-
|
|
3431
|
+
ve(this.video, this.root) ? await w(this.video, this.root) : await C(this.video, this.root);
|
|
3382
3432
|
} catch {}
|
|
3383
3433
|
}
|
|
3384
3434
|
syncFullscreenSupport() {
|
|
3385
|
-
this.fsSupported =
|
|
3435
|
+
this.fsSupported = S(this.video, this.root), this.fsBtn.style.display = this.fsSupported ? "" : "none";
|
|
3386
3436
|
}
|
|
3387
3437
|
syncFullscreen() {
|
|
3388
|
-
let e =
|
|
3438
|
+
let e = ve(this.video, this.root);
|
|
3389
3439
|
this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
|
|
3390
3440
|
}
|
|
3391
3441
|
poke() {
|
|
@@ -3446,7 +3496,7 @@ var Rr = class {
|
|
|
3446
3496
|
}
|
|
3447
3497
|
}
|
|
3448
3498
|
setIcon(e, t) {
|
|
3449
|
-
e.innerHTML =
|
|
3499
|
+
e.innerHTML = $(t);
|
|
3450
3500
|
}
|
|
3451
3501
|
destroy() {
|
|
3452
3502
|
this.hideTimer && clearTimeout(this.hideTimer), this.tapTimer && clearTimeout(this.tapTimer);
|
|
@@ -3463,23 +3513,23 @@ var Rr = class {
|
|
|
3463
3513
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
3464
3514
|
}
|
|
3465
3515
|
};
|
|
3466
|
-
function
|
|
3516
|
+
function Ur(e) {
|
|
3467
3517
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
3468
3518
|
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");
|
|
3469
3519
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
3470
3520
|
}
|
|
3471
|
-
function
|
|
3521
|
+
function Wr(e) {
|
|
3472
3522
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
3473
3523
|
}
|
|
3474
|
-
function
|
|
3524
|
+
function Gr(e) {
|
|
3475
3525
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3476
3526
|
}
|
|
3477
|
-
function
|
|
3527
|
+
function Kr(e) {
|
|
3478
3528
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3479
3529
|
}
|
|
3480
3530
|
//#endregion
|
|
3481
3531
|
//#region src/managed/index.ts
|
|
3482
|
-
var
|
|
3532
|
+
var qr = 6e3, Jr = 45e3, Yr = 2e3, Xr = 3, Zr = 5e3, Qr = 2e3, $r = 48e4, ei = "keySystemLicenseRequestFailed", ti = /* @__PURE__ */ new Set([
|
|
3483
3533
|
"GONE",
|
|
3484
3534
|
"NOT_FOUND",
|
|
3485
3535
|
"INVALID_URN",
|
|
@@ -3487,27 +3537,27 @@ var Ur = 6e3, Wr = 45e3, Gr = 2e3, Kr = 3, qr = 5e3, Jr = 2e3, Yr = 48e4, Xr = "
|
|
|
3487
3537
|
"GEO_DENIED",
|
|
3488
3538
|
"DRM_DEVICE_REVOKED"
|
|
3489
3539
|
]);
|
|
3490
|
-
function
|
|
3491
|
-
return !
|
|
3540
|
+
function ni(e) {
|
|
3541
|
+
return !ti.has(e);
|
|
3492
3542
|
}
|
|
3493
|
-
function
|
|
3543
|
+
function ri(e) {
|
|
3494
3544
|
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)})`);
|
|
3495
3545
|
if (e.env !== void 0) return lt(e.env);
|
|
3496
3546
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
3497
3547
|
return e.baseUrl;
|
|
3498
3548
|
}
|
|
3499
|
-
async function
|
|
3549
|
+
async function ii(e) {
|
|
3500
3550
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
3501
|
-
let t =
|
|
3551
|
+
let t = ri(e);
|
|
3502
3552
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
3503
3553
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
3504
|
-
let r = new
|
|
3554
|
+
let r = new ai({
|
|
3505
3555
|
...e,
|
|
3506
3556
|
baseUrl: t
|
|
3507
3557
|
});
|
|
3508
3558
|
return await r.start(), r;
|
|
3509
3559
|
}
|
|
3510
|
-
var
|
|
3560
|
+
var ai = class {
|
|
3511
3561
|
opts;
|
|
3512
3562
|
abort = new AbortController();
|
|
3513
3563
|
listeners = {};
|
|
@@ -3586,7 +3636,7 @@ var ti = class {
|
|
|
3586
3636
|
};
|
|
3587
3637
|
}
|
|
3588
3638
|
beginArming(e, t, n = !1) {
|
|
3589
|
-
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ??
|
|
3639
|
+
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
|
|
3590
3640
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
3591
3641
|
}
|
|
3592
3642
|
beginArmingByPolling(e) {
|
|
@@ -3607,7 +3657,7 @@ var ti = class {
|
|
|
3607
3657
|
setTimeout(() => {
|
|
3608
3658
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
3609
3659
|
phase: i ? "unavailable" : "tooEarly",
|
|
3610
|
-
retryInMs:
|
|
3660
|
+
retryInMs: Jr,
|
|
3611
3661
|
attempt: 1,
|
|
3612
3662
|
elapsedMs: 0,
|
|
3613
3663
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -3646,13 +3696,13 @@ var ti = class {
|
|
|
3646
3696
|
!a && !p() && h();
|
|
3647
3697
|
}, e);
|
|
3648
3698
|
};
|
|
3649
|
-
_(
|
|
3699
|
+
_(qr), this.armingSub = E({
|
|
3650
3700
|
eventsBaseUrl: t,
|
|
3651
3701
|
matchUrn: this.opts.matchUrn,
|
|
3652
3702
|
credential: this.opts.credential,
|
|
3653
|
-
onAlive: () => _(
|
|
3703
|
+
onAlive: () => _(Jr),
|
|
3654
3704
|
onState: (e) => {
|
|
3655
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
3705
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Yr);
|
|
3656
3706
|
},
|
|
3657
3707
|
onError: () => h()
|
|
3658
3708
|
});
|
|
@@ -3675,7 +3725,7 @@ var ti = class {
|
|
|
3675
3725
|
let n = await c(this.opts.credential);
|
|
3676
3726
|
if (this.destroyed || t !== this.loadGen) return;
|
|
3677
3727
|
this.setState("loading");
|
|
3678
|
-
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a =
|
|
3728
|
+
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = _t(this.opts.video, (e) => {
|
|
3679
3729
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
3680
3730
|
});
|
|
3681
3731
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -3697,19 +3747,19 @@ var ti = class {
|
|
|
3697
3747
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
3698
3748
|
let i = e.analytics?.sid;
|
|
3699
3749
|
if (!i) return;
|
|
3700
|
-
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } =
|
|
3750
|
+
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = br(this.opts.baseUrl, a, e.analytics?.endpoint);
|
|
3701
3751
|
if (!o) {
|
|
3702
3752
|
s && setTimeout(() => {
|
|
3703
3753
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
|
|
3704
3754
|
}, 0);
|
|
3705
3755
|
return;
|
|
3706
3756
|
}
|
|
3707
|
-
let c = this.opts.video, l = new
|
|
3757
|
+
let c = this.opts.video, l = new xr({
|
|
3708
3758
|
endpoint: o,
|
|
3709
3759
|
sid: i,
|
|
3710
3760
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
3711
|
-
sdkVersion:
|
|
3712
|
-
environment:
|
|
3761
|
+
sdkVersion: Dr,
|
|
3762
|
+
environment: Tr(c),
|
|
3713
3763
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
3714
3764
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
3715
3765
|
onBlocked: (e) => setTimeout(() => {
|
|
@@ -3730,7 +3780,7 @@ var ti = class {
|
|
|
3730
3780
|
let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
|
|
3731
3781
|
c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
|
|
3732
3782
|
c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
|
|
3733
|
-
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()),
|
|
3783
|
+
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), Er().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
3734
3784
|
}
|
|
3735
3785
|
currentPresentation() {
|
|
3736
3786
|
let e = this.opts.video;
|
|
@@ -3745,7 +3795,7 @@ var ti = class {
|
|
|
3745
3795
|
video: this.opts.video,
|
|
3746
3796
|
descriptor: e,
|
|
3747
3797
|
credential: t,
|
|
3748
|
-
deviceId:
|
|
3798
|
+
deviceId: A(),
|
|
3749
3799
|
userId: this.opts.userId,
|
|
3750
3800
|
lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
|
|
3751
3801
|
snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
|
|
@@ -3753,6 +3803,7 @@ var ti = class {
|
|
|
3753
3803
|
sizeCapHeadroom: this.opts.sizeCapHeadroom,
|
|
3754
3804
|
adaptiveHoldBack: this.opts.adaptiveHoldBack,
|
|
3755
3805
|
adaptiveHoldBackCeiling: this.opts.adaptiveHoldBackCeiling,
|
|
3806
|
+
stallCap: this.opts.stallCap,
|
|
3756
3807
|
mediaDuringKey: this.opts.mediaDuringKey,
|
|
3757
3808
|
preloadHints: this.opts.preloadHints,
|
|
3758
3809
|
debug: this.opts.debug,
|
|
@@ -3762,9 +3813,9 @@ var ti = class {
|
|
|
3762
3813
|
freshLicenseUrl: () => this.refreshLicense()
|
|
3763
3814
|
}, o = this.opts.engine ?? "auto";
|
|
3764
3815
|
if (o === "native") return new H(a);
|
|
3765
|
-
if (o === "hls") return new
|
|
3766
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && B(this.opts.video) && V() || !e.drmEnabled &&
|
|
3767
|
-
if (
|
|
3816
|
+
if (o === "hls") return new er(a);
|
|
3817
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && B(this.opts.video) && V() || !e.drmEnabled && kt() && B(this.opts.video)) return new H(a);
|
|
3818
|
+
if (Gt()) return new er(a);
|
|
3768
3819
|
if (B(this.opts.video)) return new H(a);
|
|
3769
3820
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
3770
3821
|
}
|
|
@@ -3815,11 +3866,11 @@ var ti = class {
|
|
|
3815
3866
|
}
|
|
3816
3867
|
startLiveState(e) {
|
|
3817
3868
|
if (this.opts.liveStateEvents === !1) return;
|
|
3818
|
-
let t = this.opts.eventsBaseUrl ??
|
|
3869
|
+
let t = this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
|
|
3819
3870
|
if (!t) return;
|
|
3820
3871
|
this.closeLiveState();
|
|
3821
3872
|
let i = 0, a = !1;
|
|
3822
|
-
this.liveStateSub =
|
|
3873
|
+
this.liveStateSub = E({
|
|
3823
3874
|
eventsBaseUrl: t,
|
|
3824
3875
|
matchUrn: this.opts.matchUrn,
|
|
3825
3876
|
credential: this.opts.credential,
|
|
@@ -3831,11 +3882,11 @@ var ti = class {
|
|
|
3831
3882
|
},
|
|
3832
3883
|
onError: (o) => {
|
|
3833
3884
|
if (!(this.destroyed || e !== this.loadGen || a) && !this.endedHandled) {
|
|
3834
|
-
if (o instanceof
|
|
3885
|
+
if (o instanceof T && (o.terminal || o.status === 404)) {
|
|
3835
3886
|
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."));
|
|
3836
3887
|
return;
|
|
3837
3888
|
}
|
|
3838
|
-
i += 1, i >=
|
|
3889
|
+
i += 1, i >= Xr && (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.`)));
|
|
3839
3890
|
}
|
|
3840
3891
|
}
|
|
3841
3892
|
});
|
|
@@ -3852,7 +3903,7 @@ var ti = class {
|
|
|
3852
3903
|
}
|
|
3853
3904
|
if (this.emit("online"), this._state !== "error" || !this._lastError) return;
|
|
3854
3905
|
let t = this._lastError.code;
|
|
3855
|
-
|
|
3906
|
+
ni(t) && (t === "NETWORK" || this.failedWhileOffline) && this.retry().catch(() => void 0);
|
|
3856
3907
|
}));
|
|
3857
3908
|
}
|
|
3858
3909
|
watchReturn() {
|
|
@@ -3862,7 +3913,7 @@ var ti = class {
|
|
|
3862
3913
|
return;
|
|
3863
3914
|
}
|
|
3864
3915
|
let e = this.hiddenAtMs;
|
|
3865
|
-
this.hiddenAtMs = null, e != null && Date.now() - e >=
|
|
3916
|
+
this.hiddenAtMs = null, e != null && Date.now() - e >= Zr && this.resyncLiveState();
|
|
3866
3917
|
}, this.onReturnPageShow = (e) => {
|
|
3867
3918
|
e.persisted && this.resyncLiveState();
|
|
3868
3919
|
}, document.addEventListener("visibilitychange", this.onReturnVisible), typeof window < "u" && window.addEventListener("pageshow", this.onReturnPageShow));
|
|
@@ -3894,7 +3945,7 @@ var ti = class {
|
|
|
3894
3945
|
scheduleRejoin(e) {
|
|
3895
3946
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
3896
3947
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
3897
|
-
}, Math.random() *
|
|
3948
|
+
}, Math.random() * Yr));
|
|
3898
3949
|
}
|
|
3899
3950
|
cancelRejoin() {
|
|
3900
3951
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -3918,7 +3969,7 @@ var ti = class {
|
|
|
3918
3969
|
}
|
|
3919
3970
|
t.controls = !1;
|
|
3920
3971
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
3921
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
3972
|
+
r && r.insertBefore(n, t), n.appendChild(t), Ar(n, this.opts.theme), this.container = n, this.controlBar = Vr({
|
|
3922
3973
|
root: n,
|
|
3923
3974
|
video: t,
|
|
3924
3975
|
player: this,
|
|
@@ -3957,7 +4008,7 @@ var ti = class {
|
|
|
3957
4008
|
}
|
|
3958
4009
|
startStats() {
|
|
3959
4010
|
this.stopStats();
|
|
3960
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
4011
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Qr);
|
|
3961
4012
|
this.statsTimer = setInterval(() => {
|
|
3962
4013
|
if (!this.engine) return;
|
|
3963
4014
|
let e = this.engine.getStats();
|
|
@@ -3968,14 +4019,14 @@ var ti = class {
|
|
|
3968
4019
|
this.statsTimer && clearInterval(this.statsTimer), this.statsTimer = void 0;
|
|
3969
4020
|
}
|
|
3970
4021
|
isStaleLicenseDenial(e) {
|
|
3971
|
-
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !==
|
|
4022
|
+
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== ei || e.error.httpStatus !== 403 || e.error.code !== "FORBIDDEN" || e.error.serverCode === "license_refused" ? !1 : W(this._descriptor?.drm?.widevine?.licenseUrl);
|
|
3972
4023
|
}
|
|
3973
4024
|
scheduleLicenseRefresh() {
|
|
3974
4025
|
if (this.stopRefresh(), !this._descriptor?.drmEnabled) return;
|
|
3975
4026
|
typeof document < "u" && this.engine?.name === "hls" && (this.onRefocus = () => {
|
|
3976
4027
|
document.visibilityState !== "visible" || this.destroyed || W(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
|
|
3977
4028
|
}, document.addEventListener("visibilitychange", this.onRefocus));
|
|
3978
|
-
let e = this.opts.licenseRefreshMs ??
|
|
4029
|
+
let e = this.opts.licenseRefreshMs ?? $r;
|
|
3979
4030
|
e && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
3980
4031
|
}
|
|
3981
4032
|
stopRefresh() {
|
|
@@ -4071,13 +4122,13 @@ var ti = class {
|
|
|
4071
4122
|
e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
|
|
4072
4123
|
}
|
|
4073
4124
|
async enterFullscreen() {
|
|
4074
|
-
return !this.destroyed &&
|
|
4125
|
+
return !this.destroyed && C(this.opts.video, this.container ?? void 0);
|
|
4075
4126
|
}
|
|
4076
4127
|
async exitFullscreen() {
|
|
4077
|
-
await
|
|
4128
|
+
await w(this.opts.video, this.container ?? void 0);
|
|
4078
4129
|
}
|
|
4079
4130
|
fullscreenSupported() {
|
|
4080
|
-
return !this.destroyed &&
|
|
4131
|
+
return !this.destroyed && S(this.opts.video, this.container ?? void 0);
|
|
4081
4132
|
}
|
|
4082
4133
|
retry() {
|
|
4083
4134
|
return this.reload();
|
|
@@ -4140,12 +4191,12 @@ var ti = class {
|
|
|
4140
4191
|
};
|
|
4141
4192
|
//#endregion
|
|
4142
4193
|
//#region src/embed/protocol.ts
|
|
4143
|
-
function
|
|
4194
|
+
function oi(e) {
|
|
4144
4195
|
return !!e && typeof e == "object" && typeof e.type == "string" && e.type.startsWith("oddin:");
|
|
4145
4196
|
}
|
|
4146
4197
|
//#endregion
|
|
4147
4198
|
//#region src/embed/host.ts
|
|
4148
|
-
function
|
|
4199
|
+
function si(e) {
|
|
4149
4200
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
4150
4201
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
4151
4202
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -4154,7 +4205,7 @@ function ni(e) {
|
|
|
4154
4205
|
let r = document.createElement("iframe");
|
|
4155
4206
|
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);
|
|
4156
4207
|
let i = /* @__PURE__ */ new Set(), a = (t) => {
|
|
4157
|
-
if (t.source !== r.contentWindow || t.origin !== n ||
|
|
4208
|
+
if (t.source !== r.contentWindow || t.origin !== n || !oi(t.data)) return;
|
|
4158
4209
|
let a = t.data;
|
|
4159
4210
|
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));
|
|
4160
4211
|
};
|
|
@@ -4204,15 +4255,15 @@ function ni(e) {
|
|
|
4204
4255
|
}
|
|
4205
4256
|
//#endregion
|
|
4206
4257
|
//#region src/embed/page.ts
|
|
4207
|
-
var
|
|
4208
|
-
function
|
|
4258
|
+
var ci = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
4259
|
+
function li(e) {
|
|
4209
4260
|
if (typeof e == "boolean") return e;
|
|
4210
4261
|
if (typeof e == "object" && e) {
|
|
4211
4262
|
let t = e.endpoint;
|
|
4212
4263
|
return typeof t == "string" ? { endpoint: t } : {};
|
|
4213
4264
|
}
|
|
4214
4265
|
}
|
|
4215
|
-
function
|
|
4266
|
+
function ui() {
|
|
4216
4267
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
4217
4268
|
if (e) return {
|
|
4218
4269
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -4222,7 +4273,7 @@ function ai() {
|
|
|
4222
4273
|
autoplay: e.autoplay ?? !0,
|
|
4223
4274
|
muted: e.muted ?? !0,
|
|
4224
4275
|
waitForLive: e.waitForLive ?? !0,
|
|
4225
|
-
analytics:
|
|
4276
|
+
analytics: li(e.analytics)
|
|
4226
4277
|
};
|
|
4227
4278
|
let t = new URLSearchParams(location.search);
|
|
4228
4279
|
return {
|
|
@@ -4235,9 +4286,9 @@ function ai() {
|
|
|
4235
4286
|
waitForLive: !0
|
|
4236
4287
|
};
|
|
4237
4288
|
}
|
|
4238
|
-
async function
|
|
4239
|
-
let e =
|
|
4240
|
-
|
|
4289
|
+
async function di() {
|
|
4290
|
+
let e = ui();
|
|
4291
|
+
pi();
|
|
4241
4292
|
let t = document.createElement("video");
|
|
4242
4293
|
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);
|
|
4243
4294
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -4293,12 +4344,12 @@ async function oi() {
|
|
|
4293
4344
|
message: e.message,
|
|
4294
4345
|
...e.country === void 0 ? {} : { country: e.country }
|
|
4295
4346
|
})), e.on("autoplayblocked", () => {
|
|
4296
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
4347
|
+
i({ type: "oddin:autoplayblocked" }), fi(t, e);
|
|
4297
4348
|
});
|
|
4298
4349
|
}, s = async (r) => {
|
|
4299
4350
|
a?.destroy(), a = null;
|
|
4300
4351
|
try {
|
|
4301
|
-
let n = await
|
|
4352
|
+
let n = await ii({
|
|
4302
4353
|
video: t,
|
|
4303
4354
|
baseUrl: e.baseUrl,
|
|
4304
4355
|
matchUrn: r,
|
|
@@ -4361,30 +4412,30 @@ async function oi() {
|
|
|
4361
4412
|
a?.retry();
|
|
4362
4413
|
break;
|
|
4363
4414
|
case "oddin:load":
|
|
4364
|
-
typeof e.matchUrn == "string" &&
|
|
4415
|
+
typeof e.matchUrn == "string" && ci.test(e.matchUrn) && s(e.matchUrn);
|
|
4365
4416
|
break;
|
|
4366
4417
|
case "oddin:destroy": c();
|
|
4367
4418
|
}
|
|
4368
4419
|
}, u = (e) => {
|
|
4369
|
-
r && e.origin === r &&
|
|
4420
|
+
r && e.origin === r && oi(e.data) && l(e.data);
|
|
4370
4421
|
};
|
|
4371
4422
|
r && window.addEventListener("message", u), window.addEventListener("pagehide", c, { once: !0 }), await s(e.matchUrn), i({
|
|
4372
4423
|
type: "oddin:ready",
|
|
4373
4424
|
protocol: 1
|
|
4374
4425
|
});
|
|
4375
4426
|
}
|
|
4376
|
-
function
|
|
4427
|
+
function fi(e, t) {
|
|
4377
4428
|
if (document.getElementById("havik-tap")) return;
|
|
4378
4429
|
let n = document.createElement("button");
|
|
4379
4430
|
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", () => {
|
|
4380
4431
|
n.remove(), t.play();
|
|
4381
4432
|
}), document.body.appendChild(n);
|
|
4382
4433
|
}
|
|
4383
|
-
function
|
|
4434
|
+
function pi() {
|
|
4384
4435
|
let e = document.createElement("style");
|
|
4385
4436
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
4386
4437
|
}
|
|
4387
4438
|
//#endregion
|
|
4388
|
-
export {
|
|
4439
|
+
export { T as LiveStateHttpError, Or as ODDIN_THEME, n as PlaybackError, Ar as applyTheme, lt as baseUrlForEnv, di as bootEmbed, Oe as clearDeviceId, Be as clearRememberedBandwidth, ii as createPlayer, D as deriveEventsBaseUrl, at as detectDrmSupport, C as enterVideoFullscreen, w as exitVideoFullscreen, ye as fetchCatalog, xe as fetchTournament, Ce as flattenMatches, S as fullscreenSupported, A as getDeviceId, st as isLowLatencyManifest, oi as isOddinMessage, Ae as licenseRequestHeaders, si as mountEmbed, fe as pollToLive, y as resolveStream, E as subscribeLiveState, ve as videoFullscreenActive, Te as watchStatus };
|
|
4389
4440
|
|
|
4390
4441
|
//# sourceMappingURL=index.js.map
|