@oddin-gg/havik-player 2.25.1 → 2.26.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 +9 -4
- package/dist/index.d.ts +9 -4
- package/dist/index.js +520 -439
- package/dist/index.js.map +1 -1
- package/docs/API.md +41 -41
- package/embed/index.html +1 -1
- package/examples/vanilla.html +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -315,25 +315,25 @@ function x(e) {
|
|
|
315
315
|
function _e(e) {
|
|
316
316
|
return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
|
|
317
317
|
}
|
|
318
|
-
function
|
|
318
|
+
function S(e, t) {
|
|
319
319
|
let n = _e(x(e));
|
|
320
320
|
return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
|
|
321
321
|
}
|
|
322
|
-
function
|
|
322
|
+
function C(e, t) {
|
|
323
323
|
let n = t ?? e, r = x(e);
|
|
324
324
|
if (typeof n.requestFullscreen == "function") return r.fullscreenEnabled !== !1;
|
|
325
325
|
if (typeof n.webkitRequestFullscreen == "function") return r.webkitFullscreenEnabled !== !1;
|
|
326
326
|
let i = e;
|
|
327
327
|
return i.webkitSupportsFullscreen === !0 && typeof i.webkitEnterFullscreen == "function" || e.readyState < 1;
|
|
328
328
|
}
|
|
329
|
-
async function
|
|
329
|
+
async function w(e, t) {
|
|
330
330
|
let n = t ?? e;
|
|
331
331
|
if (typeof n.requestFullscreen == "function") return await n.requestFullscreen(), !0;
|
|
332
332
|
if (typeof n.webkitRequestFullscreen == "function") return n.webkitRequestFullscreen(), !0;
|
|
333
333
|
let r = e;
|
|
334
334
|
return r.webkitSupportsFullscreen && typeof r.webkitEnterFullscreen == "function" ? (r.webkitEnterFullscreen(), !0) : !1;
|
|
335
335
|
}
|
|
336
|
-
async function
|
|
336
|
+
async function T(e, t) {
|
|
337
337
|
let n = e;
|
|
338
338
|
if (n.webkitDisplayingFullscreen) {
|
|
339
339
|
n.webkitExitFullscreen?.();
|
|
@@ -344,7 +344,7 @@ async function C(e, t) {
|
|
|
344
344
|
}
|
|
345
345
|
//#endregion
|
|
346
346
|
//#region src/core/catalog.ts
|
|
347
|
-
async function
|
|
347
|
+
async function ve(e) {
|
|
348
348
|
let t = new URLSearchParams();
|
|
349
349
|
e.status && t.set("status", Array.isArray(e.status) ? e.status.join(",") : e.status), e.sport && t.set("sport", e.sport);
|
|
350
350
|
let i = t.toString(), a = f(e.baseUrl, "/v1/catalog" + (i ? `?${i}` : "")), o = new Headers();
|
|
@@ -362,12 +362,12 @@ async function be(e) {
|
|
|
362
362
|
};
|
|
363
363
|
if (!s.ok) throw new n(r(s.status), s.status, `catalog request failed (HTTP ${s.status})`);
|
|
364
364
|
return {
|
|
365
|
-
tournaments:
|
|
365
|
+
tournaments: ye(await s.json()),
|
|
366
366
|
etag: s.headers.get("etag") ?? void 0,
|
|
367
367
|
notModified: !1
|
|
368
368
|
};
|
|
369
369
|
}
|
|
370
|
-
function
|
|
370
|
+
function ye(e) {
|
|
371
371
|
return (e.tournaments ?? []).map((e) => {
|
|
372
372
|
let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
|
|
373
373
|
return {
|
|
@@ -389,7 +389,7 @@ function xe(e) {
|
|
|
389
389
|
};
|
|
390
390
|
});
|
|
391
391
|
}
|
|
392
|
-
async function
|
|
392
|
+
async function be(e) {
|
|
393
393
|
let t = f(e.baseUrl, `/v1/tournaments/${encodeURIComponent(e.urn)}`), i = new Headers();
|
|
394
394
|
e.etag && i.set("If-None-Match", e.etag);
|
|
395
395
|
let a = await m(t, {
|
|
@@ -409,13 +409,13 @@ async function Se(e) {
|
|
|
409
409
|
};
|
|
410
410
|
if (!a.ok) throw new n(r(a.status), a.status, `tournament request failed (HTTP ${a.status})`);
|
|
411
411
|
return {
|
|
412
|
-
tournament:
|
|
412
|
+
tournament: xe(await a.json()),
|
|
413
413
|
etag: a.headers.get("etag") ?? void 0,
|
|
414
414
|
notModified: !1,
|
|
415
415
|
notFound: !1
|
|
416
416
|
};
|
|
417
417
|
}
|
|
418
|
-
function
|
|
418
|
+
function xe(e) {
|
|
419
419
|
let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
|
|
420
420
|
return {
|
|
421
421
|
urn: t,
|
|
@@ -435,18 +435,18 @@ function Ce(e) {
|
|
|
435
435
|
}))
|
|
436
436
|
};
|
|
437
437
|
}
|
|
438
|
-
function
|
|
438
|
+
function Se(e) {
|
|
439
439
|
return e.tournaments.flatMap((e) => e.matches);
|
|
440
440
|
}
|
|
441
441
|
//#endregion
|
|
442
442
|
//#region src/core/poll.ts
|
|
443
|
-
var
|
|
443
|
+
var Ce = /* @__PURE__ */ new Set([
|
|
444
444
|
"NOT_FOUND",
|
|
445
445
|
"GEO_DENIED",
|
|
446
446
|
"GONE",
|
|
447
447
|
"INVALID_URN"
|
|
448
448
|
]);
|
|
449
|
-
function
|
|
449
|
+
function we(e) {
|
|
450
450
|
let t = Math.max(2e3, e.intervalMs ?? 1e4), i = new AbortController(), a, o, s, c = !1, d = () => {
|
|
451
451
|
c || (a = setTimeout(p, t));
|
|
452
452
|
}, p = async () => {
|
|
@@ -479,7 +479,7 @@ function Ee(e) {
|
|
|
479
479
|
} catch (t) {
|
|
480
480
|
if (!i.signal.aborted) {
|
|
481
481
|
let r = t instanceof n ? t : new n("NETWORK", 0, String(t));
|
|
482
|
-
|
|
482
|
+
Ce.has(r.code) && (c = !0), e.onError?.(r);
|
|
483
483
|
}
|
|
484
484
|
} finally {
|
|
485
485
|
d();
|
|
@@ -491,16 +491,16 @@ function Ee(e) {
|
|
|
491
491
|
}
|
|
492
492
|
//#endregion
|
|
493
493
|
//#region src/core/events.ts
|
|
494
|
-
var
|
|
494
|
+
var Te = 45e3, E = class extends Error {
|
|
495
495
|
status;
|
|
496
496
|
terminal;
|
|
497
497
|
constructor(e) {
|
|
498
498
|
let t = e === 410;
|
|
499
499
|
super(t ? `live-state subscribe failed: HTTP ${e} — match is gone, not retrying` : e === 404 ? `live-state subscribe failed: HTTP ${e} — match not in the catalog, retrying slowly` : `live-state subscribe failed: HTTP ${e}`), this.name = "LiveStateHttpError", this.status = e, this.terminal = t;
|
|
500
500
|
}
|
|
501
|
-
},
|
|
502
|
-
function
|
|
503
|
-
let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = Math.max(t, e.notFoundRetryMs ??
|
|
501
|
+
}, Ee = 3e5;
|
|
502
|
+
function D(e) {
|
|
503
|
+
let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = Math.max(t, e.notFoundRetryMs ?? Ee), i = e.idleTimeoutMs ?? Te, a = Number.isFinite(i) && i > 0 ? i : 0, o = new AbortController(), s = !1, l = (e) => new Promise((t) => {
|
|
504
504
|
if (o.signal.aborted) return t();
|
|
505
505
|
let n = setTimeout(t, e);
|
|
506
506
|
o.signal.addEventListener("abort", () => {
|
|
@@ -567,7 +567,7 @@ function T(e) {
|
|
|
567
567
|
});
|
|
568
568
|
if (clearTimeout(_), s) return;
|
|
569
569
|
if (!o.ok || !o.body) {
|
|
570
|
-
let t = new
|
|
570
|
+
let t = new E(o.status);
|
|
571
571
|
h = t.terminal, g = o.status === 404, e.onError?.(t);
|
|
572
572
|
} else await p(o.body, () => {
|
|
573
573
|
i = t;
|
|
@@ -585,7 +585,7 @@ function T(e) {
|
|
|
585
585
|
s || (s = !0, o.abort());
|
|
586
586
|
} };
|
|
587
587
|
}
|
|
588
|
-
function
|
|
588
|
+
function O(e) {
|
|
589
589
|
try {
|
|
590
590
|
let t = new URL(e);
|
|
591
591
|
return t.hostname = `events.${t.hostname}`, t.pathname = "", t.search = "", t.origin;
|
|
@@ -595,24 +595,24 @@ function E(e) {
|
|
|
595
595
|
}
|
|
596
596
|
//#endregion
|
|
597
597
|
//#region src/core/drm/deviceId.ts
|
|
598
|
-
var
|
|
599
|
-
function
|
|
600
|
-
if (
|
|
598
|
+
var De = "havik.player.deviceId", k;
|
|
599
|
+
function Oe() {
|
|
600
|
+
if (k) return k;
|
|
601
601
|
try {
|
|
602
|
-
let e = globalThis.localStorage?.getItem(
|
|
603
|
-
if (e) return
|
|
602
|
+
let e = globalThis.localStorage?.getItem(De);
|
|
603
|
+
if (e) return k = e, e;
|
|
604
604
|
} catch {}
|
|
605
605
|
let e = Ae();
|
|
606
|
-
|
|
606
|
+
k = e;
|
|
607
607
|
try {
|
|
608
|
-
globalThis.localStorage?.setItem(
|
|
608
|
+
globalThis.localStorage?.setItem(De, e);
|
|
609
609
|
} catch {}
|
|
610
610
|
return e;
|
|
611
611
|
}
|
|
612
612
|
function ke() {
|
|
613
|
-
|
|
613
|
+
k = void 0;
|
|
614
614
|
try {
|
|
615
|
-
globalThis.localStorage?.removeItem(
|
|
615
|
+
globalThis.localStorage?.removeItem(De);
|
|
616
616
|
} catch {}
|
|
617
617
|
}
|
|
618
618
|
function Ae() {
|
|
@@ -631,28 +631,28 @@ function je(e, t, n = {}) {
|
|
|
631
631
|
let r = {
|
|
632
632
|
"x-api-key": t.apiKey,
|
|
633
633
|
"X-Match-Urn": e.matchUrn,
|
|
634
|
-
"X-Device-Id": n.deviceId ??
|
|
634
|
+
"X-Device-Id": n.deviceId ?? Oe(),
|
|
635
635
|
"Content-Type": "application/octet-stream"
|
|
636
636
|
};
|
|
637
637
|
return n.userId && (r["X-User-Id"] = n.userId), r;
|
|
638
638
|
}
|
|
639
639
|
//#endregion
|
|
640
640
|
//#region src/core/bandwidthMemory.ts
|
|
641
|
-
var
|
|
642
|
-
function
|
|
641
|
+
var Me = "havik.player.bandwidth", Ne = .8, Pe = 2e7, Fe = 3e5;
|
|
642
|
+
function Ie() {
|
|
643
643
|
return globalThis.navigator?.connection;
|
|
644
644
|
}
|
|
645
|
-
function
|
|
646
|
-
let e =
|
|
645
|
+
function Le() {
|
|
646
|
+
let e = Ie()?.type;
|
|
647
647
|
return typeof e == "string" && e !== "" && e !== "unknown" ? e : "any";
|
|
648
648
|
}
|
|
649
|
-
function
|
|
650
|
-
let e =
|
|
649
|
+
function Re() {
|
|
650
|
+
let e = Ie()?.downlink;
|
|
651
651
|
return typeof e == "number" && Number.isFinite(e) && e > 0 ? e * 1e6 : void 0;
|
|
652
652
|
}
|
|
653
|
-
function
|
|
653
|
+
function ze() {
|
|
654
654
|
try {
|
|
655
|
-
let e = globalThis.localStorage?.getItem(
|
|
655
|
+
let e = globalThis.localStorage?.getItem(Me);
|
|
656
656
|
if (!e) return {};
|
|
657
657
|
let t = JSON.parse(e);
|
|
658
658
|
return t && typeof t == "object" && !Array.isArray(t) ? t : {};
|
|
@@ -660,36 +660,36 @@ function Re() {
|
|
|
660
660
|
return {};
|
|
661
661
|
}
|
|
662
662
|
}
|
|
663
|
-
function
|
|
664
|
-
let t =
|
|
663
|
+
function Be(e = Date.now()) {
|
|
664
|
+
let t = ze()[Le()];
|
|
665
665
|
if (!t || typeof t.bps != "number" || typeof t.at != "number" || !Number.isFinite(t.bps) || t.bps <= 0) return;
|
|
666
666
|
let n = e - t.at;
|
|
667
667
|
if (n < 0 || n > 2592e5) return;
|
|
668
|
-
let r =
|
|
669
|
-
return Math.round(Math.min(
|
|
668
|
+
let r = Re(), i = r === void 0 ? t.bps : Math.min(t.bps, r);
|
|
669
|
+
return Math.round(Math.min(Pe, Math.max(Fe, i * Ne)));
|
|
670
670
|
}
|
|
671
|
-
function
|
|
671
|
+
function Ve(e, t = Date.now()) {
|
|
672
672
|
if (!Number.isFinite(e) || e <= 0) return;
|
|
673
|
-
let n =
|
|
674
|
-
n[
|
|
673
|
+
let n = ze();
|
|
674
|
+
n[Le()] = {
|
|
675
675
|
bps: Math.round(e),
|
|
676
676
|
at: t
|
|
677
677
|
};
|
|
678
678
|
try {
|
|
679
|
-
globalThis.localStorage?.setItem(
|
|
679
|
+
globalThis.localStorage?.setItem(Me, JSON.stringify(n));
|
|
680
680
|
} catch {}
|
|
681
681
|
}
|
|
682
|
-
function
|
|
682
|
+
function He() {
|
|
683
683
|
try {
|
|
684
|
-
globalThis.localStorage?.removeItem(
|
|
684
|
+
globalThis.localStorage?.removeItem(Me);
|
|
685
685
|
} catch {}
|
|
686
686
|
}
|
|
687
687
|
//#endregion
|
|
688
688
|
//#region src/core/drm/cdm.ts
|
|
689
|
-
var
|
|
690
|
-
function
|
|
691
|
-
let n =
|
|
692
|
-
n || (n = /* @__PURE__ */ new Map(),
|
|
689
|
+
var Ue = /* @__PURE__ */ new WeakMap();
|
|
690
|
+
function We(e, t) {
|
|
691
|
+
let n = Ue.get(e);
|
|
692
|
+
n || (n = /* @__PURE__ */ new Map(), Ue.set(e, n));
|
|
693
693
|
let r = n.get(t.keySystem);
|
|
694
694
|
if (r) return r;
|
|
695
695
|
let i = t.createMediaKeys().catch((e) => {
|
|
@@ -697,22 +697,22 @@ function Ue(e, t) {
|
|
|
697
697
|
});
|
|
698
698
|
return n.set(t.keySystem, i), i;
|
|
699
699
|
}
|
|
700
|
-
function
|
|
700
|
+
function A() {
|
|
701
701
|
return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
|
|
702
702
|
}
|
|
703
|
-
var
|
|
704
|
-
function
|
|
703
|
+
var j = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
|
|
704
|
+
function Ge(e) {
|
|
705
705
|
return e.startsWith("com.widevine");
|
|
706
706
|
}
|
|
707
|
-
function
|
|
708
|
-
if (!
|
|
707
|
+
function M(e, t) {
|
|
708
|
+
if (!Ge(e)) return t;
|
|
709
709
|
let n = (e, t) => {
|
|
710
710
|
let n = e.videoCapabilities;
|
|
711
711
|
return !n?.length || !n.some((e) => e.robustness) ? !1 : n.every((e) => {
|
|
712
|
-
let n =
|
|
713
|
-
return n === -1 ||
|
|
712
|
+
let n = j.indexOf(e.robustness);
|
|
713
|
+
return n === -1 || j.indexOf(t) > n;
|
|
714
714
|
});
|
|
715
|
-
}, r =
|
|
715
|
+
}, r = j.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
|
|
716
716
|
...t,
|
|
717
717
|
videoCapabilities: t.videoCapabilities?.map((t) => ({
|
|
718
718
|
...t,
|
|
@@ -721,53 +721,53 @@ function N(e, t) {
|
|
|
721
721
|
})));
|
|
722
722
|
return [...t, ...r];
|
|
723
723
|
}
|
|
724
|
-
function
|
|
725
|
-
return (t, n) =>
|
|
724
|
+
function Ke(e) {
|
|
725
|
+
return (t, n) => A() ? navigator.requestMediaKeySystemAccess(t, M(t, n)).then((t) => ({
|
|
726
726
|
keySystem: t.keySystem,
|
|
727
727
|
getConfiguration: () => t.getConfiguration(),
|
|
728
|
-
createMediaKeys: () =>
|
|
728
|
+
createMediaKeys: () => We(e, t)
|
|
729
729
|
})) : Promise.reject(/* @__PURE__ */ Error("navigator.requestMediaKeySystemAccess is unavailable — EME needs a secure context (https, or localhost)"));
|
|
730
730
|
}
|
|
731
|
-
var
|
|
731
|
+
var N = {
|
|
732
732
|
video: "SW_SECURE_DECODE",
|
|
733
733
|
audio: "SW_SECURE_CRYPTO",
|
|
734
734
|
scheme: "cbcs"
|
|
735
735
|
};
|
|
736
|
-
function
|
|
737
|
-
if (!
|
|
736
|
+
function qe(e) {
|
|
737
|
+
if (!A()) return;
|
|
738
738
|
let t = (e, t) => ({
|
|
739
739
|
contentType: e,
|
|
740
740
|
robustness: t,
|
|
741
|
-
encryptionScheme:
|
|
741
|
+
encryptionScheme: N.scheme
|
|
742
742
|
});
|
|
743
|
-
|
|
743
|
+
Ke(e)("com.widevine.alpha", [{
|
|
744
744
|
initDataTypes: ["cenc"],
|
|
745
745
|
distinctiveIdentifier: "optional",
|
|
746
746
|
persistentState: "optional",
|
|
747
747
|
sessionTypes: ["temporary"],
|
|
748
|
-
audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"",
|
|
749
|
-
videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"",
|
|
748
|
+
audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"", N.audio)],
|
|
749
|
+
videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"", N.video)]
|
|
750
750
|
}]).then((e) => e.createMediaKeys()).catch(() => {});
|
|
751
751
|
}
|
|
752
|
-
function
|
|
753
|
-
let t =
|
|
752
|
+
function P(e) {
|
|
753
|
+
let t = F(e);
|
|
754
754
|
if (/^avc[13]/.test(t)) return "avc";
|
|
755
755
|
if (/^(hvc1|hev1)/.test(t)) return "hevc";
|
|
756
756
|
if (/^(dvh1|dvhe)/.test(t)) return "dv";
|
|
757
757
|
if (t.startsWith("av01")) return "av1";
|
|
758
758
|
if (/^vp0?9/.test(t)) return "vp9";
|
|
759
759
|
}
|
|
760
|
-
function
|
|
760
|
+
function F(e) {
|
|
761
761
|
return (e ?? "").trim().toLowerCase();
|
|
762
762
|
}
|
|
763
|
-
var
|
|
763
|
+
var Je = {
|
|
764
764
|
hevc: "hvc1.1.6.L93.90",
|
|
765
765
|
dv: "dvh1.05.06",
|
|
766
766
|
av1: "av01.0.05M.08",
|
|
767
767
|
vp9: "vp09.00.10.08"
|
|
768
|
-
},
|
|
769
|
-
function
|
|
770
|
-
let t =
|
|
768
|
+
}, Ye = /* @__PURE__ */ new Map(), I = /* @__PURE__ */ new Map();
|
|
769
|
+
function Xe(e) {
|
|
770
|
+
let t = F(e), n = Ye.get(t);
|
|
771
771
|
if (n) return n;
|
|
772
772
|
let r = {
|
|
773
773
|
initDataTypes: ["cenc"],
|
|
@@ -776,32 +776,32 @@ function Ye(e) {
|
|
|
776
776
|
sessionTypes: ["temporary"],
|
|
777
777
|
videoCapabilities: [{
|
|
778
778
|
contentType: `video/mp4; codecs="${e.trim()}"`,
|
|
779
|
-
robustness:
|
|
780
|
-
encryptionScheme:
|
|
779
|
+
robustness: N.video,
|
|
780
|
+
encryptionScheme: N.scheme
|
|
781
781
|
}]
|
|
782
782
|
}, i = (async () => {
|
|
783
783
|
try {
|
|
784
|
-
return await navigator.requestMediaKeySystemAccess("com.widevine.alpha",
|
|
784
|
+
return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", M("com.widevine.alpha", [r])), !0;
|
|
785
785
|
} catch {
|
|
786
786
|
return !1;
|
|
787
787
|
}
|
|
788
|
-
})().then((e) => (
|
|
789
|
-
return
|
|
788
|
+
})().then((e) => (I.set(t, e), e));
|
|
789
|
+
return Ye.set(t, i), i;
|
|
790
790
|
}
|
|
791
|
-
function
|
|
792
|
-
if (
|
|
791
|
+
function Ze() {
|
|
792
|
+
if (A()) for (let e of Object.values(Je)) Xe(e);
|
|
793
793
|
}
|
|
794
|
-
function
|
|
795
|
-
let t =
|
|
796
|
-
if (t) return t === "avc" ? !0 :
|
|
794
|
+
function Qe(e) {
|
|
795
|
+
let t = P(e);
|
|
796
|
+
if (t) return t === "avc" ? !0 : I.get(F(e)) ?? I.get(F(Je[t]));
|
|
797
797
|
}
|
|
798
798
|
//#endregion
|
|
799
799
|
//#region src/core/drm/support.ts
|
|
800
|
-
var
|
|
800
|
+
var $e = 5e3, et = "video/mp4; codecs=\"avc1.42E01E\"", tt = "audio/mp4; codecs=\"mp4a.40.2\"", nt = {
|
|
801
801
|
widevine: ["com.widevine.alpha"],
|
|
802
802
|
fairplay: ["com.apple.fps"]
|
|
803
803
|
};
|
|
804
|
-
function
|
|
804
|
+
function rt(e) {
|
|
805
805
|
return e === "fairplay" ? [{
|
|
806
806
|
initDataTypes: [
|
|
807
807
|
"sinf",
|
|
@@ -809,30 +809,30 @@ function nt(e) {
|
|
|
809
809
|
"cenc"
|
|
810
810
|
],
|
|
811
811
|
videoCapabilities: [{
|
|
812
|
-
contentType:
|
|
812
|
+
contentType: et,
|
|
813
813
|
robustness: "",
|
|
814
814
|
encryptionScheme: "cbcs"
|
|
815
815
|
}],
|
|
816
816
|
audioCapabilities: [{
|
|
817
|
-
contentType:
|
|
817
|
+
contentType: tt,
|
|
818
818
|
robustness: "",
|
|
819
819
|
encryptionScheme: "cbcs"
|
|
820
820
|
}]
|
|
821
|
-
}] :
|
|
821
|
+
}] : M("com.widevine.alpha", [{
|
|
822
822
|
initDataTypes: ["cenc"],
|
|
823
823
|
videoCapabilities: [{
|
|
824
|
-
contentType:
|
|
825
|
-
robustness:
|
|
826
|
-
encryptionScheme:
|
|
824
|
+
contentType: et,
|
|
825
|
+
robustness: N.video,
|
|
826
|
+
encryptionScheme: N.scheme
|
|
827
827
|
}],
|
|
828
828
|
audioCapabilities: [{
|
|
829
|
-
contentType:
|
|
830
|
-
robustness:
|
|
831
|
-
encryptionScheme:
|
|
829
|
+
contentType: tt,
|
|
830
|
+
robustness: N.audio,
|
|
831
|
+
encryptionScheme: N.scheme
|
|
832
832
|
}]
|
|
833
833
|
}]);
|
|
834
834
|
}
|
|
835
|
-
function
|
|
835
|
+
function it(e, t) {
|
|
836
836
|
return new Promise((n, r) => {
|
|
837
837
|
let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
|
|
838
838
|
e.then((e) => {
|
|
@@ -842,8 +842,8 @@ function rt(e, t) {
|
|
|
842
842
|
});
|
|
843
843
|
});
|
|
844
844
|
}
|
|
845
|
-
async function
|
|
846
|
-
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ??
|
|
845
|
+
async function at(e = {}) {
|
|
846
|
+
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? $e, r = {};
|
|
847
847
|
if (typeof window < "u" && window.isSecureContext === !1) return {
|
|
848
848
|
verdict: "insecure-context",
|
|
849
849
|
detail: r
|
|
@@ -855,7 +855,7 @@ async function it(e = {}) {
|
|
|
855
855
|
};
|
|
856
856
|
let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
|
|
857
857
|
for (let e of t) {
|
|
858
|
-
let t =
|
|
858
|
+
let t = nt[e];
|
|
859
859
|
if (!t) {
|
|
860
860
|
r[e] = "unknown system";
|
|
861
861
|
continue;
|
|
@@ -866,7 +866,7 @@ async function it(e = {}) {
|
|
|
866
866
|
break;
|
|
867
867
|
}
|
|
868
868
|
try {
|
|
869
|
-
return await
|
|
869
|
+
return await it((await it(i(n, rt(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
|
|
870
870
|
verdict: "supported",
|
|
871
871
|
system: e,
|
|
872
872
|
detail: r
|
|
@@ -890,32 +890,32 @@ async function it(e = {}) {
|
|
|
890
890
|
}
|
|
891
891
|
//#endregion
|
|
892
892
|
//#region src/core/manifest.ts
|
|
893
|
-
var
|
|
894
|
-
function
|
|
895
|
-
return
|
|
893
|
+
var ot = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
|
|
894
|
+
function st(e) {
|
|
895
|
+
return ot.test(e);
|
|
896
896
|
}
|
|
897
897
|
//#endregion
|
|
898
898
|
//#region src/core/env.ts
|
|
899
|
-
var
|
|
899
|
+
var ct = {
|
|
900
900
|
integration: "https://feed-dev.oddin-video.gg",
|
|
901
901
|
production: "https://feed.oddin-video.gg"
|
|
902
902
|
};
|
|
903
|
-
function
|
|
904
|
-
let t = Object.prototype.hasOwnProperty.call(
|
|
903
|
+
function lt(e) {
|
|
904
|
+
let t = Object.prototype.hasOwnProperty.call(ct, e) ? ct[e] : void 0;
|
|
905
905
|
if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
|
|
906
906
|
return t;
|
|
907
907
|
}
|
|
908
908
|
//#endregion
|
|
909
909
|
//#region src/core/connectivity.ts
|
|
910
|
-
function
|
|
910
|
+
function L() {
|
|
911
911
|
return typeof navigator > "u" || navigator.onLine !== !1;
|
|
912
912
|
}
|
|
913
|
-
function
|
|
913
|
+
function ut() {
|
|
914
914
|
let e = /* @__PURE__ */ new Set(), t = (t) => {
|
|
915
915
|
for (let n of Array.from(e)) n(t);
|
|
916
916
|
}, n = () => t(!0), r = () => t(!1), i = typeof window < "u" && typeof window.addEventListener == "function";
|
|
917
917
|
return i && (window.addEventListener("online", n), window.addEventListener("offline", r)), {
|
|
918
|
-
isOnline:
|
|
918
|
+
isOnline: L,
|
|
919
919
|
onChange(t) {
|
|
920
920
|
return e.add(t), () => {
|
|
921
921
|
e.delete(t);
|
|
@@ -928,32 +928,32 @@ function lt() {
|
|
|
928
928
|
}
|
|
929
929
|
//#endregion
|
|
930
930
|
//#region src/core/stats.ts
|
|
931
|
-
var
|
|
932
|
-
function
|
|
931
|
+
var dt = { droppedFrames: 0 };
|
|
932
|
+
function ft(e) {
|
|
933
933
|
try {
|
|
934
934
|
return new URL(e).host;
|
|
935
935
|
} catch {
|
|
936
936
|
return "";
|
|
937
937
|
}
|
|
938
938
|
}
|
|
939
|
-
var
|
|
940
|
-
function
|
|
939
|
+
var pt = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
|
|
940
|
+
function mt(e) {
|
|
941
941
|
if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
|
|
942
942
|
let t = "", n = -1, r = performance.getEntriesByType("resource");
|
|
943
|
-
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" ||
|
|
944
|
-
let e =
|
|
943
|
+
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || pt.test(i.name)) && i.startTime >= n) {
|
|
944
|
+
let e = ft(i.name);
|
|
945
945
|
e && (t = e, n = i.startTime);
|
|
946
946
|
}
|
|
947
947
|
return t;
|
|
948
948
|
}
|
|
949
|
-
function
|
|
949
|
+
function R(e) {
|
|
950
950
|
let t = e.getVideoPlaybackQuality?.();
|
|
951
951
|
return {
|
|
952
952
|
dropped: t?.droppedVideoFrames ?? 0,
|
|
953
953
|
totalFrames: t?.totalVideoFrames ?? 0
|
|
954
954
|
};
|
|
955
955
|
}
|
|
956
|
-
var
|
|
956
|
+
var ht = class {
|
|
957
957
|
video;
|
|
958
958
|
baseFrames = 0;
|
|
959
959
|
baseDropped = 0;
|
|
@@ -963,7 +963,7 @@ var mt = class {
|
|
|
963
963
|
this.video = e;
|
|
964
964
|
}
|
|
965
965
|
read() {
|
|
966
|
-
let e =
|
|
966
|
+
let e = R(this.video);
|
|
967
967
|
return e.totalFrames < this.lastFrames && (this.baseFrames += this.lastFrames), e.dropped < this.lastDropped && (this.baseDropped += this.lastDropped), this.lastFrames = e.totalFrames, this.lastDropped = e.dropped, {
|
|
968
968
|
dropped: this.baseDropped + e.dropped,
|
|
969
969
|
totalFrames: this.baseFrames + e.totalFrames
|
|
@@ -976,7 +976,7 @@ var mt = class {
|
|
|
976
976
|
};
|
|
977
977
|
}
|
|
978
978
|
};
|
|
979
|
-
function
|
|
979
|
+
function gt(e, t) {
|
|
980
980
|
let n = [
|
|
981
981
|
["playing", () => t("playing")],
|
|
982
982
|
["waiting", () => t("buffering")],
|
|
@@ -993,8 +993,8 @@ function ht(e, t) {
|
|
|
993
993
|
}
|
|
994
994
|
//#endregion
|
|
995
995
|
//#region src/core/engine/native.ts
|
|
996
|
-
var
|
|
997
|
-
function
|
|
996
|
+
var _t = 2e3, vt = 3, z = 500, yt = 6e3, bt = .25, xt = 250, St = .05, Ct = 4, wt = 12e3, Tt = .25, Et = 1e3;
|
|
997
|
+
function Dt(e) {
|
|
998
998
|
try {
|
|
999
999
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
1000
1000
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -1002,20 +1002,20 @@ function Et(e) {
|
|
|
1002
1002
|
return;
|
|
1003
1003
|
}
|
|
1004
1004
|
}
|
|
1005
|
-
function
|
|
1005
|
+
function B(e) {
|
|
1006
1006
|
return !!(e ?? (typeof document < "u" ? document.createElement("video") : void 0))?.canPlayType("application/vnd.apple.mpegurl");
|
|
1007
1007
|
}
|
|
1008
|
-
function
|
|
1008
|
+
function V() {
|
|
1009
1009
|
if (typeof window > "u") return !1;
|
|
1010
1010
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
1011
1011
|
return e || t;
|
|
1012
1012
|
}
|
|
1013
|
-
function
|
|
1014
|
-
if (typeof navigator > "u" || !
|
|
1013
|
+
function Ot() {
|
|
1014
|
+
if (typeof navigator > "u" || !V()) return !1;
|
|
1015
1015
|
let e = navigator.userAgent ?? "";
|
|
1016
1016
|
return /iPhone|iPad|iPod/.test(e) ? !0 : /Macintosh/.test(e) && typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1;
|
|
1017
1017
|
}
|
|
1018
|
-
var
|
|
1018
|
+
var H = class {
|
|
1019
1019
|
name = "native";
|
|
1020
1020
|
deps;
|
|
1021
1021
|
onLoaded;
|
|
@@ -1045,7 +1045,7 @@ var U = class {
|
|
|
1045
1045
|
frameCounter;
|
|
1046
1046
|
detachFrames = null;
|
|
1047
1047
|
constructor(e) {
|
|
1048
|
-
this.deps = e, this.frameCounter = new
|
|
1048
|
+
this.deps = e, this.frameCounter = new ht(e.video), this.loadStarted = e.deferLoad !== !0, this.builtAt = typeof performance < "u" ? performance.now() : 0;
|
|
1049
1049
|
}
|
|
1050
1050
|
async load() {
|
|
1051
1051
|
this.detachFrames ??= this.frameCounter.attach();
|
|
@@ -1064,9 +1064,9 @@ var U = class {
|
|
|
1064
1064
|
let i = !this.loadStarted;
|
|
1065
1065
|
this.onLoaded = i ? void 0 : () => r({ type: "ready" }), this.onError = () => r({
|
|
1066
1066
|
type: "error",
|
|
1067
|
-
error:
|
|
1067
|
+
error: L() ? new n("INTERNAL", 0, "native HLS playback error") : new n("NETWORK", 0, "native HLS playback error while offline"),
|
|
1068
1068
|
fatal: !0
|
|
1069
|
-
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src =
|
|
1069
|
+
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = At(t.manifestUrl, t.analytics?.sid), e.load();
|
|
1070
1070
|
}
|
|
1071
1071
|
startLoad() {
|
|
1072
1072
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -1094,7 +1094,7 @@ var U = class {
|
|
|
1094
1094
|
};
|
|
1095
1095
|
this.onEncrypted = (n) => {
|
|
1096
1096
|
let a = n;
|
|
1097
|
-
a.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
1097
|
+
a.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Dt(a.initData), (async () => {
|
|
1098
1098
|
try {
|
|
1099
1099
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
1100
1100
|
initDataTypes: [a.initDataType],
|
|
@@ -1194,10 +1194,10 @@ var U = class {
|
|
|
1194
1194
|
droppedFrames: t.dropped,
|
|
1195
1195
|
decodedFrames: t.totalFrames
|
|
1196
1196
|
};
|
|
1197
|
-
if (this.cdnHost ||=
|
|
1197
|
+
if (this.cdnHost ||= mt(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
|
|
1198
1198
|
n.isLive = !0;
|
|
1199
1199
|
let t = this.liveEdgeEstimate(), r = t == null ? NaN : t - e.currentTime;
|
|
1200
|
-
Number.isFinite(r) && (n.atLiveEdge = r <=
|
|
1200
|
+
Number.isFinite(r) && (n.atLiveEdge = r <= Ct, !e.paused && r >= 0 && (n.latencySeconds = r));
|
|
1201
1201
|
} else Number.isFinite(e.duration) && e.duration > 0 && (n.isLive = !1);
|
|
1202
1202
|
return n;
|
|
1203
1203
|
}
|
|
@@ -1209,30 +1209,30 @@ var U = class {
|
|
|
1209
1209
|
}
|
|
1210
1210
|
watchRefocus() {
|
|
1211
1211
|
this.deps.snapToLiveOnRefocus === !1 || typeof document > "u" || this.onVisibility || (this.onVisibility = () => {
|
|
1212
|
-
let e =
|
|
1212
|
+
let e = U();
|
|
1213
1213
|
if (document.visibilityState === "hidden") {
|
|
1214
1214
|
this.hiddenSince = e, this.cancelRefocus();
|
|
1215
1215
|
return;
|
|
1216
1216
|
}
|
|
1217
1217
|
let t = this.hiddenSince;
|
|
1218
|
-
this.hiddenSince = null, t != null && e - t >=
|
|
1218
|
+
this.hiddenSince = null, t != null && e - t >= _t && this.armRefocus();
|
|
1219
1219
|
}, this.onPageShow = (e) => {
|
|
1220
1220
|
e.persisted && this.armRefocus();
|
|
1221
1221
|
}, document.addEventListener("visibilitychange", this.onVisibility), typeof window < "u" && window.addEventListener("pageshow", this.onPageShow));
|
|
1222
1222
|
}
|
|
1223
1223
|
armRefocus() {
|
|
1224
1224
|
if (this.cancelRefocus(), Number.isFinite(this.deps.video.duration)) return;
|
|
1225
|
-
let e = this.liveEnd(), t =
|
|
1225
|
+
let e = this.liveEnd(), t = U, n = t(), r = 0, i = () => {
|
|
1226
1226
|
if (this.refocusTimer = null, Number.isFinite(this.deps.video.duration)) return;
|
|
1227
|
-
r +=
|
|
1228
|
-
let a = this.liveEnd(), o = a != null && (e == null || a >= e +
|
|
1227
|
+
r += z;
|
|
1228
|
+
let a = this.liveEnd(), o = a != null && (e == null || a >= e + bt), s = Math.max(r, t() - n) >= yt;
|
|
1229
1229
|
if (o || s && a != null) {
|
|
1230
1230
|
this.snapToLive();
|
|
1231
1231
|
return;
|
|
1232
1232
|
}
|
|
1233
|
-
this.refocusTimer = setTimeout(i,
|
|
1233
|
+
this.refocusTimer = setTimeout(i, z);
|
|
1234
1234
|
};
|
|
1235
|
-
this.refocusTimer = setTimeout(i,
|
|
1235
|
+
this.refocusTimer = setTimeout(i, z);
|
|
1236
1236
|
}
|
|
1237
1237
|
cancelRefocus() {
|
|
1238
1238
|
this.refocusTimer != null && clearTimeout(this.refocusTimer), this.refocusTimer = null;
|
|
@@ -1245,24 +1245,24 @@ var U = class {
|
|
|
1245
1245
|
}, e.addEventListener("seeking", this.onEdgeReset), e.addEventListener("emptied", this.onEdgeReset), this.edgeTimer = setInterval(() => {
|
|
1246
1246
|
if (e.duration !== Infinity) return;
|
|
1247
1247
|
this.checkEndStale();
|
|
1248
|
-
let t =
|
|
1249
|
-
t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >=
|
|
1250
|
-
},
|
|
1248
|
+
let t = kt(e, e.currentTime);
|
|
1249
|
+
t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >= St) && (this.bufferedAdvancedAt = U()), this.lastBufferedEnd = t);
|
|
1250
|
+
}, xt);
|
|
1251
1251
|
}
|
|
1252
1252
|
checkEndStale() {
|
|
1253
1253
|
if (this.endedEmitted) return;
|
|
1254
|
-
let e =
|
|
1254
|
+
let e = U(), t = this.lastTickAt == null ? 0 : e - this.lastTickAt;
|
|
1255
1255
|
this.lastTickAt = e;
|
|
1256
1256
|
let n = this.liveEnd();
|
|
1257
1257
|
if (n == null) return;
|
|
1258
|
-
let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >=
|
|
1258
|
+
let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >= Tt;
|
|
1259
1259
|
this.lastSeekableEnd = n;
|
|
1260
1260
|
let i = this.deps.video, a = typeof document < "u" && document.visibilityState === "hidden";
|
|
1261
|
-
if (r || t >
|
|
1261
|
+
if (r || t > Et || a || i.paused) {
|
|
1262
1262
|
this.edgeStampedAt = e;
|
|
1263
1263
|
return;
|
|
1264
1264
|
}
|
|
1265
|
-
e - (this.edgeStampedAt ?? e) >
|
|
1265
|
+
e - (this.edgeStampedAt ?? e) > wt && (this.endedEmitted = !0, this.deps.emit({
|
|
1266
1266
|
type: "ended",
|
|
1267
1267
|
reason: "stalled"
|
|
1268
1268
|
}));
|
|
@@ -1276,9 +1276,9 @@ var U = class {
|
|
|
1276
1276
|
liveEdgeEstimate() {
|
|
1277
1277
|
let e = this.deps.video;
|
|
1278
1278
|
if (e.duration !== Infinity) return null;
|
|
1279
|
-
let t = this.liveEnd(), n =
|
|
1279
|
+
let t = this.liveEnd(), n = kt(e, e.currentTime) ?? this.lastBufferedEnd;
|
|
1280
1280
|
if (n != null) {
|
|
1281
|
-
let e = this.bufferedAdvancedAt, r = n + (e == null ? 0 : Math.max(0, (
|
|
1281
|
+
let e = this.bufferedAdvancedAt, r = n + (e == null ? 0 : Math.max(0, (U() - e) / 1e3));
|
|
1282
1282
|
(t == null || r > t) && (t = r);
|
|
1283
1283
|
}
|
|
1284
1284
|
return t != null && Number.isFinite(t) ? t : null;
|
|
@@ -1292,7 +1292,7 @@ var U = class {
|
|
|
1292
1292
|
snapToLive() {
|
|
1293
1293
|
let e = this.deps.video, t = this.liveEnd();
|
|
1294
1294
|
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 -
|
|
1295
|
+
let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t - vt, r);
|
|
1296
1296
|
try {
|
|
1297
1297
|
e.currentTime = i;
|
|
1298
1298
|
} catch {}
|
|
@@ -1310,10 +1310,10 @@ var U = class {
|
|
|
1310
1310
|
} catch {}
|
|
1311
1311
|
}
|
|
1312
1312
|
};
|
|
1313
|
-
function
|
|
1313
|
+
function U() {
|
|
1314
1314
|
return typeof performance < "u" ? performance.now() : Date.now();
|
|
1315
1315
|
}
|
|
1316
|
-
function
|
|
1316
|
+
function kt(e, t) {
|
|
1317
1317
|
let n = e.buffered;
|
|
1318
1318
|
if (!n || !Number.isFinite(t)) return null;
|
|
1319
1319
|
for (let e = 0; e < n.length; e += 1) if (n.start(e) <= t + .1 && n.end(e) > t) {
|
|
@@ -1322,12 +1322,12 @@ function Ot(e, t) {
|
|
|
1322
1322
|
}
|
|
1323
1323
|
return null;
|
|
1324
1324
|
}
|
|
1325
|
-
function
|
|
1325
|
+
function At(e, t) {
|
|
1326
1326
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
1327
1327
|
}
|
|
1328
1328
|
//#endregion
|
|
1329
1329
|
//#region src/core/drm/signedUrl.ts
|
|
1330
|
-
function
|
|
1330
|
+
function W(e, t = Date.now()) {
|
|
1331
1331
|
if (!e) return !1;
|
|
1332
1332
|
let n;
|
|
1333
1333
|
try {
|
|
@@ -1339,13 +1339,13 @@ function G(e, t = Date.now()) {
|
|
|
1339
1339
|
}
|
|
1340
1340
|
//#endregion
|
|
1341
1341
|
//#region src/core/drm/xhrBody.ts
|
|
1342
|
-
var
|
|
1343
|
-
function
|
|
1342
|
+
var jt = 4096;
|
|
1343
|
+
function Mt(e) {
|
|
1344
1344
|
if (!e || typeof e != "object") return;
|
|
1345
1345
|
let { response: t } = e;
|
|
1346
1346
|
if (typeof t == "string") return t;
|
|
1347
1347
|
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 >
|
|
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 > jt)) try {
|
|
1349
1349
|
return new TextDecoder().decode(n);
|
|
1350
1350
|
} catch {
|
|
1351
1351
|
return;
|
|
@@ -1353,8 +1353,8 @@ function jt(e) {
|
|
|
1353
1353
|
}
|
|
1354
1354
|
//#endregion
|
|
1355
1355
|
//#region src/core/engine/prefetch.ts
|
|
1356
|
-
var
|
|
1357
|
-
function
|
|
1356
|
+
var Nt = 15e3, Pt = 5e3, Ft = 6, It = 4e3, Lt = 2;
|
|
1357
|
+
function G(e) {
|
|
1358
1358
|
try {
|
|
1359
1359
|
let t = new URL(e);
|
|
1360
1360
|
return t.searchParams.delete("CMCD"), t.toString();
|
|
@@ -1362,7 +1362,7 @@ function K(e) {
|
|
|
1362
1362
|
return e;
|
|
1363
1363
|
}
|
|
1364
1364
|
}
|
|
1365
|
-
var
|
|
1365
|
+
var Rt = class {
|
|
1366
1366
|
cmcd;
|
|
1367
1367
|
entries = /* @__PURE__ */ new Map();
|
|
1368
1368
|
keyed = /* @__PURE__ */ new Set();
|
|
@@ -1391,20 +1391,20 @@ var Lt = class {
|
|
|
1391
1391
|
}
|
|
1392
1392
|
prefetch(e, t, n) {
|
|
1393
1393
|
if (!this.isActive(t)) return;
|
|
1394
|
-
let r =
|
|
1394
|
+
let r = G(e);
|
|
1395
1395
|
if (this.entries.has(r)) return;
|
|
1396
1396
|
let i = this.perTrack.get(t) ?? 0;
|
|
1397
|
-
i >=
|
|
1397
|
+
i >= Ft || (this.perTrack.set(t, i + 1), this.start(r, this.withCmcd(e, t, n), !1, Nt), this.stats.started += 1);
|
|
1398
1398
|
}
|
|
1399
1399
|
prefetchHint(e, t) {
|
|
1400
|
-
let n =
|
|
1400
|
+
let n = G(e);
|
|
1401
1401
|
if (this.entries.has(n)) return;
|
|
1402
1402
|
let r = this.hints.get(t) ?? [];
|
|
1403
|
-
for (; r.length >=
|
|
1403
|
+
for (; r.length >= Lt;) {
|
|
1404
1404
|
let e = r.shift();
|
|
1405
1405
|
e !== void 0 && this.drop(e) && (this.stats.hintDropped += 1);
|
|
1406
1406
|
}
|
|
1407
|
-
r.push(n), this.hints.set(t, r), this.start(n, this.withCmcd(e, t, "media"), !0,
|
|
1407
|
+
r.push(n), this.hints.set(t, r), this.start(n, this.withCmcd(e, t, "media"), !0, It), this.stats.hintStarted += 1;
|
|
1408
1408
|
}
|
|
1409
1409
|
dropHints(e) {
|
|
1410
1410
|
for (let t of this.hints.get(e) ?? []) this.drop(t) && (this.stats.hintDropped += 1);
|
|
@@ -1437,7 +1437,7 @@ var Lt = class {
|
|
|
1437
1437
|
}, r);
|
|
1438
1438
|
}
|
|
1439
1439
|
take(e) {
|
|
1440
|
-
let t =
|
|
1440
|
+
let t = G(e), n = this.entries.get(t);
|
|
1441
1441
|
return n && this.entries.delete(t), n;
|
|
1442
1442
|
}
|
|
1443
1443
|
destroy() {
|
|
@@ -1457,14 +1457,14 @@ var Lt = class {
|
|
|
1457
1457
|
}
|
|
1458
1458
|
}
|
|
1459
1459
|
};
|
|
1460
|
-
function
|
|
1461
|
-
let
|
|
1462
|
-
if (typeof
|
|
1463
|
-
class
|
|
1460
|
+
function zt(t, n) {
|
|
1461
|
+
let r = typeof n == "function" ? n : e.DefaultConfig?.loader;
|
|
1462
|
+
if (typeof r != "function") return;
|
|
1463
|
+
class i extends r {
|
|
1464
1464
|
served = !1;
|
|
1465
1465
|
cancelled = !1;
|
|
1466
1466
|
entry;
|
|
1467
|
-
stats =
|
|
1467
|
+
stats = Bt();
|
|
1468
1468
|
load(e, n, r) {
|
|
1469
1469
|
let i = e.rangeEnd ? void 0 : t.take(e.url);
|
|
1470
1470
|
if (!i) {
|
|
@@ -1476,7 +1476,7 @@ function Rt(t) {
|
|
|
1476
1476
|
i.hint ? t.stats.hintFailed += 1 : t.stats.failed += 1;
|
|
1477
1477
|
}, s = () => {
|
|
1478
1478
|
!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 ||
|
|
1479
|
+
}, c = n?.loadPolicy, l = c?.maxTimeToFirstByteMs || Pt, u = setTimeout(s, l);
|
|
1480
1480
|
i.headers.then(() => {
|
|
1481
1481
|
clearTimeout(u);
|
|
1482
1482
|
let e = c?.maxLoadTimeMs;
|
|
@@ -1507,9 +1507,9 @@ function Rt(t) {
|
|
|
1507
1507
|
super.abort();
|
|
1508
1508
|
}
|
|
1509
1509
|
}
|
|
1510
|
-
return
|
|
1510
|
+
return i;
|
|
1511
1511
|
}
|
|
1512
|
-
function
|
|
1512
|
+
function Bt() {
|
|
1513
1513
|
return {
|
|
1514
1514
|
aborted: !1,
|
|
1515
1515
|
loaded: 0,
|
|
@@ -1533,10 +1533,10 @@ function zt() {
|
|
|
1533
1533
|
}
|
|
1534
1534
|
};
|
|
1535
1535
|
}
|
|
1536
|
-
function
|
|
1536
|
+
function Vt(e) {
|
|
1537
1537
|
return e === "audio" ? "audio" : "main";
|
|
1538
1538
|
}
|
|
1539
|
-
function
|
|
1539
|
+
function Ht(e, t) {
|
|
1540
1540
|
let n = [];
|
|
1541
1541
|
t.initSegment?.url && !t.initSegment.data && n.push({
|
|
1542
1542
|
url: t.initSegment.url,
|
|
@@ -1553,7 +1553,7 @@ function Vt(e, t) {
|
|
|
1553
1553
|
});
|
|
1554
1554
|
return n;
|
|
1555
1555
|
}
|
|
1556
|
-
function
|
|
1556
|
+
function Ut(e) {
|
|
1557
1557
|
let t = e, n = t?.preloadHint;
|
|
1558
1558
|
if (!n || !t?.url || n.TYPE !== "PART" || n["BYTERANGE-START"] !== void 0 || n["BYTERANGE-LENGTH"] !== void 0) return null;
|
|
1559
1559
|
let r = n.URI;
|
|
@@ -1566,16 +1566,16 @@ function Ht(e) {
|
|
|
1566
1566
|
}
|
|
1567
1567
|
//#endregion
|
|
1568
1568
|
//#region src/core/percentile.ts
|
|
1569
|
-
function
|
|
1569
|
+
function K(e, t) {
|
|
1570
1570
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
1571
1571
|
}
|
|
1572
1572
|
//#endregion
|
|
1573
1573
|
//#region src/core/engine/hls.ts
|
|
1574
|
-
function
|
|
1574
|
+
function Wt() {
|
|
1575
1575
|
return e.isSupported();
|
|
1576
1576
|
}
|
|
1577
|
-
var
|
|
1578
|
-
function
|
|
1577
|
+
var Gt = 3, Kt = 1e6, qt = 20, Jt = 1e4, Yt = 3, Xt = 5, Zt = 3, Qt = 1e4, $t = 3e4, en = 12e3, tn = 3e3, nn = .02, rn = 6e3, an = .5, on = 3, sn = .5, cn = 1.1, ln = .25, un = 5e3, dn = 4e3, fn = 2, pn = 5, mn = 2, hn = 2, gn = 4, _n = 4, vn = 2e3, yn = 3e4, bn = 1, xn = 2, Sn = .5, Cn = .6, wn = 2, Tn = 1.5, En = 1e4, q = 8, Dn = 12e4, On = 6e4;
|
|
1578
|
+
function J(e, t, n) {
|
|
1579
1579
|
if (n <= 0 || t < 0 || t >= e.length) return t;
|
|
1580
1580
|
let r = (t, n) => e[t].width === e[n].width && e[t].height === e[n].height, i = (t) => {
|
|
1581
1581
|
for (; t + 1 < e.length && r(t + 1, t);) t++;
|
|
@@ -1584,11 +1584,14 @@ function xn(e, t, n) {
|
|
|
1584
1584
|
for (let t = 0; t < n && a + 1 < e.length; t++) a = i(a + 1);
|
|
1585
1585
|
return a;
|
|
1586
1586
|
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1587
|
+
function Y() {
|
|
1588
|
+
return typeof self < "u" && self.devicePixelRatio > 0 ? self.devicePixelRatio : 1;
|
|
1589
|
+
}
|
|
1590
|
+
var kn = .2, An = 30, jn = 2, Mn = 2, Nn = 2, Pn = 9, Fn = .5, In = 64, Ln = 1e4, Rn = 8, zn = .6, Bn = .4, Vn = .4, Hn = 2, Un = 6e4, X = .5, Wn = 3.5, Gn = 300;
|
|
1591
|
+
function Kn(e) {
|
|
1589
1592
|
return (e?.part ?? e?.frag)?.stats;
|
|
1590
1593
|
}
|
|
1591
|
-
function
|
|
1594
|
+
function qn() {
|
|
1592
1595
|
if (typeof navigator > "u") return 0;
|
|
1593
1596
|
try {
|
|
1594
1597
|
let e = navigator.connection?.rtt;
|
|
@@ -1597,20 +1600,20 @@ function Bn() {
|
|
|
1597
1600
|
return 0;
|
|
1598
1601
|
}
|
|
1599
1602
|
}
|
|
1600
|
-
function
|
|
1603
|
+
function Jn(e) {
|
|
1601
1604
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
1602
1605
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
1603
1606
|
return;
|
|
1604
1607
|
}
|
|
1605
|
-
e.liveSyncDuration ??=
|
|
1606
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
1607
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
1608
|
+
e.liveSyncDuration ??= Nn;
|
|
1609
|
+
let t = Math.max(12, e.liveSyncDuration + Pn);
|
|
1610
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Yn(e, e.liveSyncDuration);
|
|
1608
1611
|
}
|
|
1609
|
-
function
|
|
1612
|
+
function Yn(e, t) {
|
|
1610
1613
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
1611
1614
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
1612
1615
|
}
|
|
1613
|
-
var
|
|
1616
|
+
var Xn = class {
|
|
1614
1617
|
name = "hls";
|
|
1615
1618
|
hls = null;
|
|
1616
1619
|
deps;
|
|
@@ -1679,6 +1682,12 @@ var Un = class {
|
|
|
1679
1682
|
liveRetargets = 0;
|
|
1680
1683
|
holdBackEnabled;
|
|
1681
1684
|
holdBackSamples = [];
|
|
1685
|
+
headroomSamples = [];
|
|
1686
|
+
headroomGranted = !1;
|
|
1687
|
+
lastStallAt = 0;
|
|
1688
|
+
headroomRegrantAt = 0;
|
|
1689
|
+
headroomUngated = !1;
|
|
1690
|
+
playingSince = 0;
|
|
1682
1691
|
holdBackBase = -1;
|
|
1683
1692
|
holdBackStepCount = 0;
|
|
1684
1693
|
holdBackApplied = 0;
|
|
@@ -1707,11 +1716,11 @@ var Un = class {
|
|
|
1707
1716
|
frameCounter;
|
|
1708
1717
|
detachFrames = null;
|
|
1709
1718
|
constructor(e) {
|
|
1710
|
-
this.deps = e, this.holdBackEnabled = e.adaptiveHoldBack !== !1, this.frameCounter = new
|
|
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;
|
|
1711
1720
|
}
|
|
1712
1721
|
async load() {
|
|
1713
1722
|
this.detachFrames ??= this.frameCounter.attach();
|
|
1714
|
-
let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a =
|
|
1723
|
+
let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = B(r) && V(), o = !!e.drm?.widevine?.licenseUrl && !a;
|
|
1715
1724
|
if (e.drmEnabled && !o) {
|
|
1716
1725
|
i({
|
|
1717
1726
|
type: "error",
|
|
@@ -1720,7 +1729,7 @@ var Un = class {
|
|
|
1720
1729
|
});
|
|
1721
1730
|
return;
|
|
1722
1731
|
}
|
|
1723
|
-
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (
|
|
1732
|
+
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (qe(r), Ze()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
|
|
1724
1733
|
let e = this.hls;
|
|
1725
1734
|
if (document.visibilityState !== "visible" || !e) return;
|
|
1726
1735
|
let t = e.liveSyncPosition;
|
|
@@ -1736,7 +1745,7 @@ var Un = class {
|
|
|
1736
1745
|
this.hls.startLoad(-1);
|
|
1737
1746
|
} catch {}
|
|
1738
1747
|
}
|
|
1739
|
-
}, window.addEventListener("offline", this.onOffline), window.addEventListener("online", this.onOnline),
|
|
1748
|
+
}, window.addEventListener("offline", this.onOffline), window.addEventListener("online", this.onOnline), L() || this.onOffline()), this.onSeeking = () => {
|
|
1740
1749
|
this.clampOverSeek(), this.loadSuspended && (this.resumeLoading(), this.schedulePauseSuspend());
|
|
1741
1750
|
}, r.addEventListener("seeking", this.onSeeking), this.onTimeUpdate = () => this.updateCatchUpBand(), r.addEventListener("timeupdate", this.onTimeUpdate), this.onPause = () => this.schedulePauseSuspend(), this.onPlay = () => this.resumeLoading(), r.addEventListener("pause", this.onPause), r.addEventListener("play", this.onPlay), this.sizeCapManaged && typeof ResizeObserver < "u" && (this.capObserver = new ResizeObserver(() => this.onMediaResize()), this.capObserver.observe(r), this.watchDprChanges());
|
|
1742
1751
|
}
|
|
@@ -1752,7 +1761,7 @@ var Un = class {
|
|
|
1752
1761
|
}
|
|
1753
1762
|
this.loadSuspended = !0;
|
|
1754
1763
|
}
|
|
1755
|
-
},
|
|
1764
|
+
}, un));
|
|
1756
1765
|
}
|
|
1757
1766
|
resumeLoading() {
|
|
1758
1767
|
if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.resetChaseWindow(), this.resetFrameDropWindow(), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
|
|
@@ -1768,7 +1777,7 @@ var Un = class {
|
|
|
1768
1777
|
watchDprChanges() {
|
|
1769
1778
|
if (typeof matchMedia != "function") return;
|
|
1770
1779
|
this.unwatchDprChanges();
|
|
1771
|
-
let e =
|
|
1780
|
+
let e = Y(), t = matchMedia(`(resolution: ${e}dppx)`);
|
|
1772
1781
|
if (typeof t.addEventListener != "function") return;
|
|
1773
1782
|
let n = () => {
|
|
1774
1783
|
this.onMediaResize(), this.watchDprChanges();
|
|
@@ -1784,7 +1793,7 @@ var Un = class {
|
|
|
1784
1793
|
let t = e.liveSyncPosition;
|
|
1785
1794
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1786
1795
|
let { video: n } = this.deps;
|
|
1787
|
-
n.currentTime <= t +
|
|
1796
|
+
n.currentTime <= t + Fn || (n.currentTime = t);
|
|
1788
1797
|
}
|
|
1789
1798
|
reanchorPartTimeline(e, t) {
|
|
1790
1799
|
let { frag: n, part: r } = t;
|
|
@@ -1796,7 +1805,7 @@ var Un = class {
|
|
|
1796
1805
|
let o = n.sn, s = i.fragments.find((e) => e && e.sn === o) ?? (i.fragmentHint?.sn === o ? i.fragmentHint : void 0);
|
|
1797
1806
|
if (!s) return;
|
|
1798
1807
|
let c = a.startPTS - s.start;
|
|
1799
|
-
if (!(!Number.isFinite(c) || Math.abs(c) <
|
|
1808
|
+
if (!(!Number.isFinite(c) || Math.abs(c) < nn)) {
|
|
1800
1809
|
for (let e of i.fragments) e && e.setStart(e.start + c);
|
|
1801
1810
|
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})`);
|
|
1802
1811
|
}
|
|
@@ -1804,7 +1813,7 @@ var Un = class {
|
|
|
1804
1813
|
startHls() {
|
|
1805
1814
|
let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
|
|
1806
1815
|
this.clearKick(), this.resetStarvationWindow(), this.resetChaseWindow(), this.resetFrameDropWindow(), this.lastFragLoadingMs = 0, this.lastEndSN = -1, this.lastAdvanceMs = 0;
|
|
1807
|
-
let u = n.drmEnabled && !!(n.drm?.widevine?.licenseUrl || n.drm?.fairplay?.licenseUrl), d =
|
|
1816
|
+
let u = n.drmEnabled && !!(n.drm?.widevine?.licenseUrl || n.drm?.fairplay?.licenseUrl), d = B(this.deps.video) && V(), f = {
|
|
1808
1817
|
debug: s === !0,
|
|
1809
1818
|
enableWorker: !o,
|
|
1810
1819
|
lowLatencyMode: o,
|
|
@@ -1819,24 +1828,24 @@ var Un = class {
|
|
|
1819
1828
|
emeEnabled: !0,
|
|
1820
1829
|
drmSystems: { ...this.licenseUrl ? { "com.widevine.alpha": { licenseUrl: this.licenseUrl } } : {} },
|
|
1821
1830
|
drmSystemOptions: {
|
|
1822
|
-
videoRobustness:
|
|
1823
|
-
audioRobustness:
|
|
1824
|
-
videoEncryptionScheme:
|
|
1825
|
-
audioEncryptionScheme:
|
|
1831
|
+
videoRobustness: N.video,
|
|
1832
|
+
audioRobustness: N.audio,
|
|
1833
|
+
videoEncryptionScheme: N.scheme,
|
|
1834
|
+
audioEncryptionScheme: N.scheme
|
|
1826
1835
|
},
|
|
1827
|
-
...
|
|
1836
|
+
...A() ? { requestMediaKeySystemAccessFunc: Ke(t) } : {},
|
|
1828
1837
|
licenseXhrSetup: (e, t) => {
|
|
1829
1838
|
let o = performance.now(), s = () => {
|
|
1830
1839
|
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", () => {
|
|
1831
1840
|
this.licenseTimeMs === 0 && (this.licenseTimeMs = Math.max(1, Math.round(performance.now() - o)));
|
|
1832
1841
|
});
|
|
1833
1842
|
}, { freshLicenseUrl: c } = this.deps;
|
|
1834
|
-
if (!c || !
|
|
1843
|
+
if (!c || !W(this.licenseUrl)) {
|
|
1835
1844
|
s();
|
|
1836
1845
|
return;
|
|
1837
1846
|
}
|
|
1838
1847
|
let l = this.hls, u, d = new Promise((e) => {
|
|
1839
|
-
u = setTimeout(() => e(void 0),
|
|
1848
|
+
u = setTimeout(() => e(void 0), Qt);
|
|
1840
1849
|
});
|
|
1841
1850
|
return Promise.race([c().catch(() => void 0), d]).finally(() => clearTimeout(u)).then((e) => {
|
|
1842
1851
|
if (!this.hls || this.hls !== l) throw Error("havik-player: engine torn down during refresh");
|
|
@@ -1852,51 +1861,51 @@ var Un = class {
|
|
|
1852
1861
|
...c
|
|
1853
1862
|
};
|
|
1854
1863
|
this.prefetch?.destroy(), this.prefetch = null;
|
|
1855
|
-
let p = !1, m = !1, h = u && this.deps.mediaDuringKey !== !1, g = this.deps.preloadHints
|
|
1864
|
+
let p = !1, m = !1, h = u && this.deps.mediaDuringKey !== !1, g = this.deps.preloadHints !== !1;
|
|
1856
1865
|
if ((h || g) && !f.fLoader) {
|
|
1857
|
-
let e = new
|
|
1866
|
+
let e = new Rt({
|
|
1858
1867
|
sessionId: n.analytics?.sid,
|
|
1859
1868
|
contentId: n.matchUrn
|
|
1860
|
-
}), t =
|
|
1869
|
+
}), t = zt(e, f.loader);
|
|
1861
1870
|
t && (this.prefetch = e, p = h, m = g, f.fLoader = t);
|
|
1862
1871
|
}
|
|
1863
|
-
|
|
1872
|
+
Jn(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;
|
|
1864
1873
|
let _ = new e(f);
|
|
1865
1874
|
if (this.hls = _, this.armHoldBack(_, f), _.on(e.Events.FRAG_PARSED, (e, t) => this.reanchorPartTimeline(_, t)), _.on(e.Events.MANIFEST_PARSED, () => {
|
|
1866
1875
|
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" });
|
|
1867
1876
|
}), _.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1868
1877
|
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(() => {
|
|
1869
1878
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1870
|
-
},
|
|
1879
|
+
}, $t)));
|
|
1871
1880
|
}), _.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1872
1881
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1873
1882
|
}), _.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
1874
1883
|
t?.frag?.type === "main" && (this.mainFragsSinceTick += 1, this.bwFragsLoaded += 1, this.maybeRememberBandwidth(!1));
|
|
1875
|
-
let n = t?.frag, r =
|
|
1884
|
+
let n = t?.frag, r = Kn(t), i = r?.loaded;
|
|
1876
1885
|
typeof i == "number" && (this.bytesLoaded += i), !this.reportedFirstBytes && typeof i == "number" && i > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
|
|
1877
1886
|
let a = r?.loading;
|
|
1878
|
-
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 >
|
|
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 > In && this.requestTimesMs.shift()), this.sampleHoldBack(t), this.sampleHeadroom(t);
|
|
1879
1888
|
let o = n?.url;
|
|
1880
1889
|
if (o) {
|
|
1881
|
-
let e =
|
|
1890
|
+
let e = ft(o);
|
|
1882
1891
|
e && (this.cdnHost = e);
|
|
1883
1892
|
}
|
|
1884
1893
|
}), _.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
1885
1894
|
let n = t?.stats?.loaded;
|
|
1886
1895
|
if (typeof n == "number" && (this.playlistBytesLoaded += n), this.reportedFirstPlaylist || (this.reportedFirstPlaylist = !0, l({ type: "firstPlaylist" })), this.detectedLowLatency) return;
|
|
1887
1896
|
let r = t.details;
|
|
1888
|
-
|
|
1897
|
+
r?.partList?.length || (r?.partTarget ?? 0) > 0 ? (this.detectedLowLatency = !0, l({
|
|
1889
1898
|
type: "lowLatencyDetected",
|
|
1890
1899
|
value: !0
|
|
1891
|
-
}));
|
|
1900
|
+
}), this.headroomUngated && (this.headroomUngated = !1, this.applySizeCapUnlessPending())) : r && !this.headroomUngated && (this.headroomUngated = !0, this.applySizeCapUnlessPending());
|
|
1892
1901
|
}), _.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.prefetch && m) {
|
|
1893
1902
|
let t = this.prefetch, n = this.deps.video, r = (e, r) => {
|
|
1894
1903
|
if (n.paused) return;
|
|
1895
1904
|
let i = e;
|
|
1896
1905
|
if (!i?.live || !i.partList?.length || typeof i.edge != "number") return;
|
|
1897
1906
|
let a = n.buffered, o = a.length ? a.end(a.length - 1) : 0;
|
|
1898
|
-
if (i.edge - o >
|
|
1899
|
-
let s =
|
|
1907
|
+
if (i.edge - o > Gt * (i.partTarget || .5)) return;
|
|
1908
|
+
let s = Ut(e);
|
|
1900
1909
|
s && t.prefetchHint(s, r);
|
|
1901
1910
|
};
|
|
1902
1911
|
_.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1908,15 +1917,15 @@ var Un = class {
|
|
|
1908
1917
|
if (this.prefetch && p) {
|
|
1909
1918
|
let t = this.prefetch;
|
|
1910
1919
|
_.on(e.Events.KEY_LOADING, (e, n) => {
|
|
1911
|
-
let r = n?.frag, i =
|
|
1912
|
-
if (r && t.isActive(i)) for (let e of
|
|
1913
|
-
}), _.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(
|
|
1920
|
+
let r = n?.frag, i = Vt(r?.type);
|
|
1921
|
+
if (r && t.isActive(i)) for (let e of Ht(_, r)) t.prefetch(e.url, i, e.kind);
|
|
1922
|
+
}), _.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(Vt(n?.frag?.type)));
|
|
1914
1923
|
}
|
|
1915
1924
|
_.on(e.Events.KEY_LOADED, () => {
|
|
1916
1925
|
u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
|
|
1917
1926
|
}), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1918
|
-
this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.adaptHoldBack(), this.checkFrameDrops();
|
|
1919
|
-
},
|
|
1927
|
+
this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.adaptHoldBack(), this.reviewSizeCapHeadroom(), this.checkFrameDrops();
|
|
1928
|
+
}, tn), _.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1920
1929
|
this.renditionSwitches += 1;
|
|
1921
1930
|
let n = this.lastLevelIndex >= 0 ? _.levels[this.lastLevelIndex] : void 0, r = _.levels[t.level];
|
|
1922
1931
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, this.armFrameDropGrace(), l({
|
|
@@ -1959,17 +1968,28 @@ var Un = class {
|
|
|
1959
1968
|
this.pushCap();
|
|
1960
1969
|
}
|
|
1961
1970
|
}
|
|
1962
|
-
|
|
1971
|
+
sizeCapCover() {
|
|
1963
1972
|
let e = this.hls;
|
|
1964
1973
|
if (!e || e.levels.length === 0) return null;
|
|
1965
1974
|
let { video: n } = this.deps, r = n.getBoundingClientRect(), i = r.width, a = r.height;
|
|
1966
1975
|
if (!i && !a && (i = n.width || 0, a = n.height || 0), !(i > 0) || !(a > 0)) return null;
|
|
1967
|
-
let o = e.config ?? {}, s =
|
|
1968
|
-
c = Math.min(c, o.maxDevicePixelRatio ?? Infinity)
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1976
|
+
let o = e.config ?? {}, s = Y(), c = o.ignoreDevicePixelRatio ? 1 : s;
|
|
1977
|
+
return c = Math.min(c, o.maxDevicePixelRatio ?? Infinity), {
|
|
1978
|
+
cover: t.getMaxLevelByMediaSize(e.levels, i * c, a * c),
|
|
1979
|
+
deviceRatio: s
|
|
1980
|
+
};
|
|
1981
|
+
}
|
|
1982
|
+
sizeCapCoverLevel() {
|
|
1983
|
+
return this.sizeCapCover()?.cover ?? null;
|
|
1984
|
+
}
|
|
1985
|
+
computeSizeCapTarget() {
|
|
1986
|
+
let e = this.hls, t = this.sizeCapCover();
|
|
1987
|
+
if (!e || !t) return null;
|
|
1988
|
+
let { cover: n, deviceRatio: r } = t, i = this.deps.sizeCapHeadroom, a = i == null || Number.isNaN(i);
|
|
1989
|
+
if (a && r >= xn) return n;
|
|
1990
|
+
if (a) return this.headroomUngated || this.headroomGranted ? J(e.levels, n, bn) : n;
|
|
1991
|
+
let o = i === Infinity ? e.levels.length : Math.max(0, Math.floor(i));
|
|
1992
|
+
return J(e.levels, n, o);
|
|
1973
1993
|
}
|
|
1974
1994
|
onMediaResize() {
|
|
1975
1995
|
if (!this.sizeCapManaged) return;
|
|
@@ -1984,9 +2004,11 @@ var Un = class {
|
|
|
1984
2004
|
return;
|
|
1985
2005
|
}
|
|
1986
2006
|
this.capTimer && clearTimeout(this.capTimer);
|
|
1987
|
-
let t = e > this.sizeCapLevel ?
|
|
2007
|
+
let t = e > this.sizeCapLevel ? vn : yn;
|
|
1988
2008
|
this.capTimer = setTimeout(() => {
|
|
1989
|
-
this.capTimer = null
|
|
2009
|
+
this.capTimer = null;
|
|
2010
|
+
let n = this.computeSizeCapTarget();
|
|
2011
|
+
n === e || t === yn && n != null && n < e ? this.applySizeCap() : this.onMediaResize();
|
|
1990
2012
|
}, t);
|
|
1991
2013
|
}
|
|
1992
2014
|
measureLadder(e) {
|
|
@@ -1994,9 +2016,9 @@ var Un = class {
|
|
|
1994
2016
|
this.ladderHeights = t.length ? [...new Set(t)].sort((e, t) => e - t) : void 0, this.ladderTopBitrateKbps = e.levels.length ? Math.round(Math.max(...e.levels.map((e) => e.bitrate)) / 1e3) : 0;
|
|
1995
2017
|
}
|
|
1996
2018
|
dropLevelsWidevineCannotPlay(e) {
|
|
1997
|
-
this.removeLevelsWhere(e, (e) =>
|
|
1998
|
-
let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e &&
|
|
1999
|
-
for (let n of t)
|
|
2019
|
+
this.removeLevelsWhere(e, (e) => Qe(e) !== !0);
|
|
2020
|
+
let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && P(e) !== "avc" && !!P(e)));
|
|
2021
|
+
for (let n of t) Xe(n).then((t) => {
|
|
2000
2022
|
t || this.hls !== e || this.removeLevelsWhere(e, (e) => e === n) && (this.measureLadder(e), this.applySizeCap());
|
|
2001
2023
|
});
|
|
2002
2024
|
}
|
|
@@ -2004,13 +2026,69 @@ var Un = class {
|
|
|
2004
2026
|
let n = e.levels ?? [], r = [], i = /* @__PURE__ */ new Set();
|
|
2005
2027
|
if (n.forEach((e, n) => {
|
|
2006
2028
|
let a = e.videoCodec;
|
|
2007
|
-
a &&
|
|
2029
|
+
a && P(a) && t(a) && (r.push(n), i.add(a));
|
|
2008
2030
|
}), !r.length) return !1;
|
|
2009
2031
|
let a = [...i].join(", ");
|
|
2010
|
-
if (!n.some((e, t) => r.includes(t) ? !1 : !
|
|
2032
|
+
if (!n.some((e, t) => r.includes(t) ? !1 : !P(e.videoCodec) || Qe(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
|
|
2011
2033
|
for (let t = r.length - 1; t >= 0; --t) e.removeLevel(r[t]);
|
|
2012
2034
|
return console.info(`havik-player: skipped ${r.length} rendition(s) Widevine cannot play on this browser (${a})`), !0;
|
|
2013
2035
|
}
|
|
2036
|
+
defaultHeadroomApplies() {
|
|
2037
|
+
let e = this.deps.sizeCapHeadroom;
|
|
2038
|
+
return e != null && !Number.isNaN(e) || this.headroomUngated ? !1 : Y() < xn;
|
|
2039
|
+
}
|
|
2040
|
+
applySizeCapUnlessPending() {
|
|
2041
|
+
this.capTimer || this.applySizeCap();
|
|
2042
|
+
}
|
|
2043
|
+
sampleHeadroom(e) {
|
|
2044
|
+
if (!this.sizeCapManaged || !this.defaultHeadroomApplies() || e.frag?.type !== "main" || typeof e.frag.level != "number" || typeof document < "u" && document.hidden) return;
|
|
2045
|
+
let t = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag.duration;
|
|
2046
|
+
if (typeof t != "number" || !(t > 0)) return;
|
|
2047
|
+
let n = Kn(e)?.loading;
|
|
2048
|
+
if (!n || !(n.start > 0) || !(n.end >= n.start)) return;
|
|
2049
|
+
let r = this.hls?.levels?.[e.frag.level]?.bitrate;
|
|
2050
|
+
if (!(typeof r == "number" && r > 0)) return;
|
|
2051
|
+
let i = (n.end - n.start) / (t * 1e3);
|
|
2052
|
+
this.headroomSamples.push({
|
|
2053
|
+
t: Date.now(),
|
|
2054
|
+
ratio: i,
|
|
2055
|
+
bitrate: r
|
|
2056
|
+
}), this.headroomSamples.length > 256 && this.headroomSamples.shift();
|
|
2057
|
+
}
|
|
2058
|
+
onPlaybackStall() {
|
|
2059
|
+
let e = Date.now();
|
|
2060
|
+
this.deps.video.seeking || !this.playingSince || e - this.playingSince < En || (this.lastStallAt = e, this.headroomGranted && (this.headroomGranted = !1, this.applySizeCapUnlessPending()));
|
|
2061
|
+
}
|
|
2062
|
+
reviewSizeCapHeadroom() {
|
|
2063
|
+
let e = Date.now(), { video: t } = this.deps;
|
|
2064
|
+
!t.paused && !t.seeking && t.readyState >= 3 ? this.playingSince ||= e : this.playingSince = 0;
|
|
2065
|
+
let n = this.hls;
|
|
2066
|
+
if (!n || !this.sizeCapManaged) return;
|
|
2067
|
+
if (!this.defaultHeadroomApplies()) {
|
|
2068
|
+
this.headroomGranted = !1, this.headroomSamples = [];
|
|
2069
|
+
return;
|
|
2070
|
+
}
|
|
2071
|
+
this.headroomSamples = this.headroomSamples.filter((t) => t.t >= e - Ln);
|
|
2072
|
+
let r = this.headroomEarned(n, e);
|
|
2073
|
+
r !== this.headroomGranted && (r || (this.headroomRegrantAt = e + On), this.headroomGranted = r, this.applySizeCapUnlessPending());
|
|
2074
|
+
}
|
|
2075
|
+
headroomEarned(e, t) {
|
|
2076
|
+
if (t - this.lastStallAt < Dn || !this.headroomGranted && t < this.headroomRegrantAt || !this.headroomGranted && this.headroomSamples.length < q) return !1;
|
|
2077
|
+
let n = e.levels, r = this.sizeCapCoverLevel();
|
|
2078
|
+
if (r == null) return this.headroomGranted;
|
|
2079
|
+
let i = J(n, r, bn);
|
|
2080
|
+
if (i === r) return this.headroomGranted;
|
|
2081
|
+
let a = n[i]?.bitrate, o = e.bandwidthEstimate, s = this.headroomGranted ? Tn : wn;
|
|
2082
|
+
if (!(a > 0) || !(o >= s * a)) return !1;
|
|
2083
|
+
let c = (e) => K([...e].sort((e, t) => e - t), 90);
|
|
2084
|
+
if (this.headroomGranted) {
|
|
2085
|
+
let e = this.headroomSamples.filter((e) => e.bitrate >= a).map((e) => e.ratio);
|
|
2086
|
+
return e.length < q || c(e) <= Cn;
|
|
2087
|
+
}
|
|
2088
|
+
let l = [];
|
|
2089
|
+
for (let e of this.headroomSamples) e.bitrate < a && l.push(e.ratio * (a / e.bitrate));
|
|
2090
|
+
return l.length >= q && c(l) <= Sn;
|
|
2091
|
+
}
|
|
2014
2092
|
applySizeCap() {
|
|
2015
2093
|
if (!this.sizeCapManaged) return;
|
|
2016
2094
|
this.capTimer &&= (clearTimeout(this.capTimer), null);
|
|
@@ -2110,12 +2188,12 @@ var Un = class {
|
|
|
2110
2188
|
this.lastAdvanceMs = Date.now();
|
|
2111
2189
|
return;
|
|
2112
2190
|
}
|
|
2113
|
-
if (this.loadSuspended || this.offlineHold || !
|
|
2191
|
+
if (this.loadSuspended || this.offlineHold || !L()) {
|
|
2114
2192
|
this.lastAdvanceMs = Date.now();
|
|
2115
2193
|
return;
|
|
2116
2194
|
}
|
|
2117
2195
|
let e = Date.now() - this.lastAdvanceMs;
|
|
2118
|
-
!this.chaseSuspended && e >
|
|
2196
|
+
!this.chaseSuspended && e > rn && this.suspendChasing(), e > en && this.emitEnded("stalled");
|
|
2119
2197
|
}
|
|
2120
2198
|
resetStarvationWindow() {
|
|
2121
2199
|
this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
|
|
@@ -2126,11 +2204,11 @@ var Un = class {
|
|
|
2126
2204
|
checkStarvation() {
|
|
2127
2205
|
let e = this.hls, { video: t } = this.deps;
|
|
2128
2206
|
if (!e || this.endedEmitted || !this.sawLive || this.chaseSuspended) return;
|
|
2129
|
-
if (typeof document < "u" && document.hidden || this.loadSuspended || this.offlineHold || !
|
|
2207
|
+
if (typeof document < "u" && document.hidden || this.loadSuspended || this.offlineHold || !L()) {
|
|
2130
2208
|
this.resetStarvationWindow();
|
|
2131
2209
|
return;
|
|
2132
2210
|
}
|
|
2133
|
-
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs <
|
|
2211
|
+
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < rn, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > dn, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = R(t), c = o - s, l = c !== this.starvedFrames;
|
|
2134
2212
|
if (this.starvedFrames = c, !a || l) {
|
|
2135
2213
|
(t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
|
|
2136
2214
|
return;
|
|
@@ -2139,12 +2217,12 @@ var Un = class {
|
|
|
2139
2217
|
this.resetStarvationWindow();
|
|
2140
2218
|
return;
|
|
2141
2219
|
}
|
|
2142
|
-
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 >
|
|
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 > gn && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= mn && (this.clearKick(), this.starvationRebuilds < hn)) {
|
|
2143
2221
|
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");
|
|
2144
2222
|
return;
|
|
2145
2223
|
}
|
|
2146
|
-
let u = i && this.starvedTicks >=
|
|
2147
|
-
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >=
|
|
2224
|
+
let u = i && this.starvedTicks >= fn, d = !i && this.deadTicks >= gn && this.recentMainFrags.reduce((e, t) => e + t, 0) >= _n;
|
|
2225
|
+
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= pn))) {
|
|
2148
2226
|
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");
|
|
2149
2227
|
try {
|
|
2150
2228
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -2159,7 +2237,7 @@ var Un = class {
|
|
|
2159
2237
|
let t = e.latency, n = e.targetLatency;
|
|
2160
2238
|
if (typeof t != "number" || typeof n != "number" || !Number.isFinite(t)) return;
|
|
2161
2239
|
let r = t - n;
|
|
2162
|
-
!this.catchUpEngaged && r >
|
|
2240
|
+
!this.catchUpEngaged && r > an ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= an && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
|
|
2163
2241
|
let i = this.catchUpEngaged ? this.catchUpRate : 1;
|
|
2164
2242
|
e.config.maxLiveSyncPlaybackRate !== i && (e.config.maxLiveSyncPlaybackRate = i);
|
|
2165
2243
|
}
|
|
@@ -2172,7 +2250,7 @@ var Un = class {
|
|
|
2172
2250
|
}), n < 0 ? 0 : n;
|
|
2173
2251
|
}
|
|
2174
2252
|
armFrameDropGrace() {
|
|
2175
|
-
this.fpsGraceTicks > 0 || (this.fpsGraceTicks =
|
|
2253
|
+
this.fpsGraceTicks > 0 || (this.fpsGraceTicks = Mn, this.fpsBadTicks = 0);
|
|
2176
2254
|
}
|
|
2177
2255
|
resetFrameDropWindow() {
|
|
2178
2256
|
this.fpsLastFrames = -1, this.fpsLastDropped = -1, this.fpsBadTicks = 0;
|
|
@@ -2183,8 +2261,8 @@ var Un = class {
|
|
|
2183
2261
|
this.resetFrameDropWindow();
|
|
2184
2262
|
return;
|
|
2185
2263
|
}
|
|
2186
|
-
let { totalFrames: n, dropped: r } =
|
|
2187
|
-
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a <
|
|
2264
|
+
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 < An || o < 0) {
|
|
2188
2266
|
this.fpsBadTicks = 0;
|
|
2189
2267
|
return;
|
|
2190
2268
|
}
|
|
@@ -2192,11 +2270,11 @@ var Un = class {
|
|
|
2192
2270
|
--this.fpsGraceTicks, this.fpsBadTicks = 0;
|
|
2193
2271
|
return;
|
|
2194
2272
|
}
|
|
2195
|
-
if (o <=
|
|
2273
|
+
if (o <= kn * a) {
|
|
2196
2274
|
this.fpsBadTicks = 0;
|
|
2197
2275
|
return;
|
|
2198
2276
|
}
|
|
2199
|
-
if (this.fpsBadTicks += 1, this.fpsBadTicks <
|
|
2277
|
+
if (this.fpsBadTicks += 1, this.fpsBadTicks < jn) return;
|
|
2200
2278
|
this.fpsBadTicks = 0;
|
|
2201
2279
|
let s = e.levels, c = s[e.currentLevel];
|
|
2202
2280
|
if (!c) return;
|
|
@@ -2213,22 +2291,22 @@ var Un = class {
|
|
|
2213
2291
|
return;
|
|
2214
2292
|
}
|
|
2215
2293
|
let n = e.latency, r = t.playbackRate, i = e.config.maxLiveSyncPlaybackRate;
|
|
2216
|
-
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(
|
|
2294
|
+
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(cn, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
|
|
2217
2295
|
this.resetChaseWindow();
|
|
2218
2296
|
return;
|
|
2219
2297
|
}
|
|
2220
|
-
if (this.chaseLatency < 0 || this.chaseLatency - n >=
|
|
2298
|
+
if (this.chaseLatency < 0 || this.chaseLatency - n >= sn) {
|
|
2221
2299
|
this.chaseLatency = n, this.chaseTicks = 0;
|
|
2222
2300
|
return;
|
|
2223
2301
|
}
|
|
2224
|
-
if (this.chaseTicks += 1, this.chaseTicks <
|
|
2302
|
+
if (this.chaseTicks += 1, this.chaseTicks < on) return;
|
|
2225
2303
|
this.resetChaseWindow();
|
|
2226
2304
|
let a = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
|
|
2227
2305
|
if (!(a > 1)) return;
|
|
2228
2306
|
let o = e.targetLatency;
|
|
2229
2307
|
if (typeof o != "number" || !(o > 0)) return;
|
|
2230
2308
|
let s = Math.min(n, a - 1);
|
|
2231
|
-
s < o +
|
|
2309
|
+
s < o + ln || (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({
|
|
2232
2310
|
type: "livetargetchange",
|
|
2233
2311
|
change: {
|
|
2234
2312
|
targetSeconds: s,
|
|
@@ -2238,20 +2316,20 @@ var Un = class {
|
|
|
2238
2316
|
}));
|
|
2239
2317
|
}
|
|
2240
2318
|
armHoldBack(e, t) {
|
|
2241
|
-
this.holdBackEnabled && (this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [], this.holdBackBase < 0 && typeof t.liveSyncDuration == "number" && (this.holdBackBase = t.liveSyncDuration), this.holdBackApplied > 0 && (e.targetLatency = this.holdBackApplied));
|
|
2319
|
+
this.headroomSamples = [], this.headroomGranted = !1, this.holdBackEnabled && (this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [], this.holdBackBase < 0 && typeof t.liveSyncDuration == "number" && (this.holdBackBase = t.liveSyncDuration), this.holdBackApplied > 0 && (e.targetLatency = this.holdBackApplied));
|
|
2242
2320
|
}
|
|
2243
2321
|
applyHoldBackPrior() {
|
|
2244
2322
|
let e = this.hls;
|
|
2245
2323
|
if (!this.holdBackEnabled || this.holdBackPriorChecked || !e || (this.holdBackPriorChecked = !0, this.holdBackApplied > 0 || this.holdBackStepCount > 0)) return;
|
|
2246
2324
|
let t = e.targetLatency;
|
|
2247
2325
|
if (this.holdBackBase < 0 && typeof t == "number" && t > 0 && (this.holdBackBase = t), this.holdBackBase < 0) return;
|
|
2248
|
-
let n =
|
|
2249
|
-
if (!(n >=
|
|
2250
|
-
let r = typeof t == "number" && t > 0 ? t : this.holdBackBase, i = Math.min(this.holdBackCeiling(e), this.holdBackBase +
|
|
2326
|
+
let n = qn();
|
|
2327
|
+
if (!(n >= Gn)) return;
|
|
2328
|
+
let r = typeof t == "number" && t > 0 ? t : this.holdBackBase, i = Math.min(this.holdBackCeiling(e), this.holdBackBase + X);
|
|
2251
2329
|
i > r && (this.holdBackStepCount = 1, this.moveHoldBack(e, r, i, "connection-rtt", `connection rtt ${n} ms`));
|
|
2252
2330
|
}
|
|
2253
2331
|
holdBackCeiling(e) {
|
|
2254
|
-
let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t :
|
|
2332
|
+
let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t : Wn, r = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
|
|
2255
2333
|
return r > 1 ? Math.min(n, r - 1) : n;
|
|
2256
2334
|
}
|
|
2257
2335
|
sampleHoldBack(e) {
|
|
@@ -2260,7 +2338,7 @@ var Un = class {
|
|
|
2260
2338
|
if (t !== "main" && t !== "audio") return;
|
|
2261
2339
|
let n = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag?.duration;
|
|
2262
2340
|
if (typeof n != "number" || !(n > 0)) return;
|
|
2263
|
-
let r =
|
|
2341
|
+
let r = Kn(e)?.loading;
|
|
2264
2342
|
if (!r || !(r.start > 0) || !(r.end > 0)) return;
|
|
2265
2343
|
let i = r.first > r.start ? r.first : r.end, a = Math.max(0, i - r.start) / (n * 1e3);
|
|
2266
2344
|
this.holdBackSamples.push({
|
|
@@ -2275,30 +2353,30 @@ var Un = class {
|
|
|
2275
2353
|
this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [];
|
|
2276
2354
|
return;
|
|
2277
2355
|
}
|
|
2278
|
-
let t = Date.now(), n = t -
|
|
2356
|
+
let t = Date.now(), n = t - Ln, r = this.holdBackSamples, i = 0;
|
|
2279
2357
|
for (; i < r.length && r[i].t < n;) i += 1;
|
|
2280
2358
|
i > 0 && r.splice(0, i);
|
|
2281
2359
|
let a = e.targetLatency;
|
|
2282
2360
|
if (typeof a != "number" || !(a > 0)) return;
|
|
2283
2361
|
this.holdBackBase < 0 && (this.holdBackBase = a);
|
|
2284
2362
|
let o = this.holdBackBase, s = this.holdBackCeiling(e);
|
|
2285
|
-
if (r.length <
|
|
2363
|
+
if (r.length < Rn) {
|
|
2286
2364
|
this.holdBackSlowTicks = 0;
|
|
2287
2365
|
return;
|
|
2288
2366
|
}
|
|
2289
|
-
let c = r.map((e) => e.ratio).sort((e, t) => e - t), l =
|
|
2290
|
-
if (l >=
|
|
2291
|
-
if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks <
|
|
2367
|
+
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 >= zn && u >= Bn) {
|
|
2369
|
+
if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks < Hn) return;
|
|
2292
2370
|
this.holdBackSlowTicks = 0;
|
|
2293
|
-
let t = Math.ceil((s - o) /
|
|
2371
|
+
let t = Math.ceil((s - o) / X), n = Math.ceil((a - o) / X - 1e-9);
|
|
2294
2372
|
if (n > this.holdBackStepCount && (this.holdBackStepCount = n), this.holdBackStepCount >= t) return;
|
|
2295
2373
|
this.holdBackStepCount += 1;
|
|
2296
|
-
let r = Math.min(s, o + this.holdBackStepCount *
|
|
2374
|
+
let r = Math.min(s, o + this.holdBackStepCount * X);
|
|
2297
2375
|
if (r <= a) return;
|
|
2298
2376
|
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)`);
|
|
2299
2377
|
return;
|
|
2300
2378
|
}
|
|
2301
|
-
if (this.holdBackSlowTicks = 0, l >=
|
|
2379
|
+
if (this.holdBackSlowTicks = 0, l >= Vn) {
|
|
2302
2380
|
this.holdBackFastSince = 0;
|
|
2303
2381
|
return;
|
|
2304
2382
|
}
|
|
@@ -2306,9 +2384,9 @@ var Un = class {
|
|
|
2306
2384
|
this.holdBackFastSince = t;
|
|
2307
2385
|
return;
|
|
2308
2386
|
}
|
|
2309
|
-
if (t - this.holdBackFastSince <
|
|
2387
|
+
if (t - this.holdBackFastSince < Un || (this.holdBackFastSince = t, this.holdBackStepCount === 0 || a !== this.holdBackApplied)) return;
|
|
2310
2388
|
--this.holdBackStepCount;
|
|
2311
|
-
let f = Math.max(o, o + this.holdBackStepCount *
|
|
2389
|
+
let f = Math.max(o, o + this.holdBackStepCount * X);
|
|
2312
2390
|
f >= a || this.moveHoldBack(e, a, f, "fast-fetches", `part fetches fast again (p95 first byte ${d} ms per 1 s of media)`);
|
|
2313
2391
|
}
|
|
2314
2392
|
moveHoldBack(e, t, n, r, i) {
|
|
@@ -2349,14 +2427,14 @@ var Un = class {
|
|
|
2349
2427
|
} catch {}
|
|
2350
2428
|
}
|
|
2351
2429
|
startEstimate() {
|
|
2352
|
-
return this.deps.rememberBandwidth === !1 ?
|
|
2430
|
+
return this.deps.rememberBandwidth === !1 ? Kt : Be() ?? Kt;
|
|
2353
2431
|
}
|
|
2354
2432
|
maybeRememberBandwidth(e) {
|
|
2355
|
-
if (this.deps.rememberBandwidth === !1 || this.bwFragsLoaded <
|
|
2433
|
+
if (this.deps.rememberBandwidth === !1 || this.bwFragsLoaded < qt) return;
|
|
2356
2434
|
let t = Date.now();
|
|
2357
|
-
if (!e && t - this.bwSavedAt <
|
|
2435
|
+
if (!e && t - this.bwSavedAt < Jt) return;
|
|
2358
2436
|
let n = this.hls?.bandwidthEstimate;
|
|
2359
|
-
typeof n != "number" || !Number.isFinite(n) || n <= 0 || (this.bwSavedAt = t,
|
|
2437
|
+
typeof n != "number" || !Number.isFinite(n) || n <= 0 || (this.bwSavedAt = t, Ve(n));
|
|
2360
2438
|
}
|
|
2361
2439
|
destroy() {
|
|
2362
2440
|
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) {
|
|
@@ -2374,7 +2452,7 @@ var Un = class {
|
|
|
2374
2452
|
scheduleLicenseRetry(t) {
|
|
2375
2453
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
2376
2454
|
let n = t.response?.code ?? 0;
|
|
2377
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
2455
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Zt) return !1;
|
|
2378
2456
|
this.licenseRecoveries += 1;
|
|
2379
2457
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
2380
2458
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -2392,7 +2470,7 @@ var Un = class {
|
|
|
2392
2470
|
}
|
|
2393
2471
|
}
|
|
2394
2472
|
onError(t) {
|
|
2395
|
-
if (t.type === e.ErrorTypes.NETWORK_ERROR && String(t.details ?? "").startsWith("frag") && (this.requestErrors += 1), !t.fatal) return;
|
|
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;
|
|
2396
2474
|
let n = this.hls;
|
|
2397
2475
|
if (n) {
|
|
2398
2476
|
if (this.clearRecoveryReset(), t.type === e.ErrorTypes.KEY_SYSTEM_ERROR) {
|
|
@@ -2406,11 +2484,11 @@ var Un = class {
|
|
|
2406
2484
|
return;
|
|
2407
2485
|
}
|
|
2408
2486
|
if (t.type === e.ErrorTypes.NETWORK_ERROR) {
|
|
2409
|
-
if (!
|
|
2487
|
+
if (!L() && (t.response?.code ?? 0) === 0) {
|
|
2410
2488
|
this.offlineHold = !0, this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null);
|
|
2411
2489
|
return;
|
|
2412
2490
|
}
|
|
2413
|
-
if (this.networkRecoveries <
|
|
2491
|
+
if (this.networkRecoveries < Xt) {
|
|
2414
2492
|
this.networkRecoveries += 1;
|
|
2415
2493
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
2416
2494
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -2427,7 +2505,7 @@ var Un = class {
|
|
|
2427
2505
|
return;
|
|
2428
2506
|
}
|
|
2429
2507
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
2430
|
-
if (this.mediaRecoveries <
|
|
2508
|
+
if (this.mediaRecoveries < Yt) {
|
|
2431
2509
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
2432
2510
|
return;
|
|
2433
2511
|
}
|
|
@@ -2448,18 +2526,18 @@ var Un = class {
|
|
|
2448
2526
|
}
|
|
2449
2527
|
}
|
|
2450
2528
|
toError(t, r = "PLAYBACK") {
|
|
2451
|
-
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(
|
|
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(Mt(t.networkDetails)) : void 0;
|
|
2452
2530
|
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);
|
|
2453
2531
|
}
|
|
2454
|
-
},
|
|
2532
|
+
}, Zn = 15e3, Qn = 6e5, $n = 3e5, er = 100, Z = 1, tr = 1e3, nr = 3e4, rr = 1e3, ir = {
|
|
2455
2533
|
inline: "PRESENTATION_INLINE",
|
|
2456
2534
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
2457
2535
|
pip: "PRESENTATION_PIP"
|
|
2458
|
-
},
|
|
2536
|
+
}, ar = {
|
|
2459
2537
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
2460
2538
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
2461
2539
|
none: "KEY_SYSTEM_NONE"
|
|
2462
|
-
},
|
|
2540
|
+
}, or = /* @__PURE__ */ new Set([
|
|
2463
2541
|
"INVALID_URN",
|
|
2464
2542
|
"NOT_FOUND",
|
|
2465
2543
|
"GEO_DENIED",
|
|
@@ -2470,7 +2548,7 @@ var Un = class {
|
|
|
2470
2548
|
"FORBIDDEN",
|
|
2471
2549
|
"RATE_LIMITED",
|
|
2472
2550
|
"TIMEOUT"
|
|
2473
|
-
]),
|
|
2551
|
+
]), sr = {
|
|
2474
2552
|
idle: "PLAYER_STATE_IDLE",
|
|
2475
2553
|
waiting: "PLAYER_STATE_WAITING",
|
|
2476
2554
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -2480,7 +2558,7 @@ var Un = class {
|
|
|
2480
2558
|
ended: "PLAYER_STATE_ENDED",
|
|
2481
2559
|
error: "PLAYER_STATE_ERROR"
|
|
2482
2560
|
};
|
|
2483
|
-
function
|
|
2561
|
+
function cr(e) {
|
|
2484
2562
|
try {
|
|
2485
2563
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
2486
2564
|
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);
|
|
@@ -2488,8 +2566,8 @@ function er(e) {
|
|
|
2488
2566
|
return;
|
|
2489
2567
|
}
|
|
2490
2568
|
}
|
|
2491
|
-
var
|
|
2492
|
-
function
|
|
2569
|
+
var lr = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), ur = /* @__PURE__ */ new Set(), dr = /* @__PURE__ */ new Set(), fr = /* @__PURE__ */ new Set(), pr = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
|
|
2570
|
+
function mr(e) {
|
|
2493
2571
|
if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
|
|
2494
2572
|
let t;
|
|
2495
2573
|
try {
|
|
@@ -2498,19 +2576,19 @@ function ir(e) {
|
|
|
2498
2576
|
} catch {
|
|
2499
2577
|
return;
|
|
2500
2578
|
}
|
|
2501
|
-
if (
|
|
2502
|
-
|
|
2503
|
-
for (let e of
|
|
2579
|
+
if (ur.has(t) && !dr.has(t)) {
|
|
2580
|
+
dr.add(t), _(pr(new URL(t).origin));
|
|
2581
|
+
for (let e of fr) e.noteCspBlocked();
|
|
2504
2582
|
}
|
|
2505
2583
|
}
|
|
2506
|
-
function
|
|
2584
|
+
function hr(e, t) {
|
|
2507
2585
|
return _(t, e), { disabledReason: t };
|
|
2508
2586
|
}
|
|
2509
|
-
function
|
|
2510
|
-
if (n) return t && !
|
|
2587
|
+
function gr(e, t, n) {
|
|
2588
|
+
if (n) return t && !lr(t, n) && _(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
|
|
2511
2589
|
if (t) return { endpoint: t };
|
|
2512
|
-
if (t !== void 0) return
|
|
2513
|
-
let r =
|
|
2590
|
+
if (t !== void 0) return hr("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).");
|
|
2591
|
+
let r = cr(e);
|
|
2514
2592
|
if (r) return { endpoint: r };
|
|
2515
2593
|
let i;
|
|
2516
2594
|
try {
|
|
@@ -2518,9 +2596,9 @@ function or(e, t, n) {
|
|
|
2518
2596
|
} catch {
|
|
2519
2597
|
i = e;
|
|
2520
2598
|
}
|
|
2521
|
-
return
|
|
2599
|
+
return hr(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).`);
|
|
2522
2600
|
}
|
|
2523
|
-
var
|
|
2601
|
+
var _r = class {
|
|
2524
2602
|
opts;
|
|
2525
2603
|
url;
|
|
2526
2604
|
cspKey;
|
|
@@ -2602,8 +2680,8 @@ var sr = class {
|
|
|
2602
2680
|
constructor(e) {
|
|
2603
2681
|
this.opts = {
|
|
2604
2682
|
...e,
|
|
2605
|
-
heartbeatMs: e.heartbeatMs ??
|
|
2606
|
-
idleMs: e.idleMs ??
|
|
2683
|
+
heartbeatMs: e.heartbeatMs ?? Zn,
|
|
2684
|
+
idleMs: e.idleMs ?? Qn
|
|
2607
2685
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
|
|
2608
2686
|
try {
|
|
2609
2687
|
let e = new URL(this.url);
|
|
@@ -2620,11 +2698,11 @@ var sr = class {
|
|
|
2620
2698
|
sdkVersion: this.opts.sdkVersion,
|
|
2621
2699
|
...this.opts.environment
|
|
2622
2700
|
};
|
|
2623
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
2701
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), tr), 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 && ur.add(this.cspKey), document.addEventListener("securitypolicyviolation", mr), fr.add(this), this.noteCspBlocked(), this.onVisibility());
|
|
2624
2702
|
}
|
|
2625
2703
|
checkSuspension(e) {
|
|
2626
2704
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
2627
|
-
let t = Math.max(this.opts.idleMs,
|
|
2705
|
+
let t = Math.max(this.opts.idleMs, $n);
|
|
2628
2706
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
2629
2707
|
}
|
|
2630
2708
|
syncIdle(e) {
|
|
@@ -2638,21 +2716,21 @@ var sr = class {
|
|
|
2638
2716
|
noteStateChange(e, t, n, r) {
|
|
2639
2717
|
if (this.endedFlag || e === t) return;
|
|
2640
2718
|
let i = this.now();
|
|
2641
|
-
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(
|
|
2719
|
+
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(Z, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(Z, i - this.startupAnchorMs)), this.isMuted && this.mutedSinceMs === null && (this.mutedSinceMs = i)) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null, this.mutedSinceMs !== null && (this.mutedTotalMs += i - this.mutedSinceMs, this.mutedSinceMs = null)), this.isPlaying = t === "playing", this.syncActive(), t === "waiting" ? this.waitingSinceMs = i : this.waitingSinceMs !== null && (this.waitingTotalMs += i - this.waitingSinceMs, this.waitingSinceMs = null), t === "buffering" && e === "playing") {
|
|
2642
2720
|
this.stallIsSeekInduced = this.seekInduced(i);
|
|
2643
2721
|
let e = !this.isHidden && !this.stallIsSeekInduced;
|
|
2644
|
-
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(
|
|
2722
|
+
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(Z, Math.round(this.playingTotalMs)));
|
|
2645
2723
|
} else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
|
|
2646
2724
|
this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
|
|
2647
2725
|
let a = {
|
|
2648
|
-
fromState:
|
|
2649
|
-
toState:
|
|
2650
|
-
presentation:
|
|
2726
|
+
fromState: sr[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2727
|
+
toState: sr[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2728
|
+
presentation: ir[this.presentation]
|
|
2651
2729
|
}, o = this.causeOf(e, t, i);
|
|
2652
2730
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
2653
2731
|
}
|
|
2654
2732
|
seekInduced(e) {
|
|
2655
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
2733
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < rr;
|
|
2656
2734
|
}
|
|
2657
2735
|
causeOf(e, t, n) {
|
|
2658
2736
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -2689,25 +2767,25 @@ var sr = class {
|
|
|
2689
2767
|
}
|
|
2690
2768
|
this.muteChanges += 1;
|
|
2691
2769
|
let r = this.now();
|
|
2692
|
-
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(
|
|
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(Z, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
|
|
2693
2771
|
}
|
|
2694
2772
|
notePresentation(e) {
|
|
2695
2773
|
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
2696
2774
|
}
|
|
2697
2775
|
notePlayIntent() {
|
|
2698
|
-
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs =
|
|
2776
|
+
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = Z), this.firstPlaylistMs > 0 && (this.firstPlaylistMs = Z), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = Z), this.drmSetupMs > 0 && (this.drmSetupMs = Z));
|
|
2699
2777
|
}
|
|
2700
2778
|
noteReady() {
|
|
2701
|
-
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(
|
|
2779
|
+
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(Z, this.now() - this.startupAnchorMs));
|
|
2702
2780
|
}
|
|
2703
2781
|
noteFirstPlaylist() {
|
|
2704
|
-
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(
|
|
2782
|
+
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(Z, this.now() - this.startupAnchorMs));
|
|
2705
2783
|
}
|
|
2706
2784
|
noteDrmReady() {
|
|
2707
|
-
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(
|
|
2785
|
+
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(Z, this.now() - this.startupAnchorMs));
|
|
2708
2786
|
}
|
|
2709
2787
|
noteFirstBytes() {
|
|
2710
|
-
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(
|
|
2788
|
+
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(Z, this.now() - this.startupAnchorMs));
|
|
2711
2789
|
}
|
|
2712
2790
|
noteSeek() {
|
|
2713
2791
|
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
@@ -2726,7 +2804,7 @@ var sr = class {
|
|
|
2726
2804
|
let r = n ?? "";
|
|
2727
2805
|
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";
|
|
2728
2806
|
if (e === "DRM_CLIENT" || e === "DRM_DEVICE_REVOKED") return "ERROR_STAGE_DRM";
|
|
2729
|
-
if (
|
|
2807
|
+
if (or.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
2730
2808
|
let i = t ?? "";
|
|
2731
2809
|
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";
|
|
2732
2810
|
}
|
|
@@ -2758,7 +2836,7 @@ var sr = class {
|
|
|
2758
2836
|
let l = t.droppedFrames ?? 0;
|
|
2759
2837
|
l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
|
|
2760
2838
|
let u = t.renditionSwitches ?? 0;
|
|
2761
|
-
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 =
|
|
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 = sr[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
|
|
2762
2840
|
let d = this.mutedTotalMs;
|
|
2763
2841
|
this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
|
|
2764
2842
|
let f = t.upshifts ?? 0;
|
|
@@ -2773,20 +2851,20 @@ var sr = class {
|
|
|
2773
2851
|
if (this.lastRequestCount = g, _ > 0) {
|
|
2774
2852
|
o.requestCountDelta = _;
|
|
2775
2853
|
let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
|
|
2776
|
-
n.length > 0 && (o.requestTimeP50Ms =
|
|
2854
|
+
n.length > 0 && (o.requestTimeP50Ms = K(n, 50), o.requestTimeP95Ms = K(n, 95));
|
|
2777
2855
|
}
|
|
2778
2856
|
typeof t.latencySeconds == "number" && typeof t.targetLatencySeconds == "number" && (o.driftMs = Math.round((t.latencySeconds - t.targetLatencySeconds) * 1e3)), typeof t.playbackRate == "number" && t.playbackRate > 0 && (o.playbackRate = t.playbackRate), t.qualityPinned === !0 && (o.qualityPinned = !0), t.cdnHost && (o.cdnHost = t.cdnHost), this.maybeEmitMediaInfo(t), this.enqueue({ heartbeat: o }), this.flush(), s > 0 && this.noteFirstBytes();
|
|
2779
2857
|
}
|
|
2780
2858
|
maybeEmitMediaInfo(e) {
|
|
2781
2859
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
2782
2860
|
let t = {};
|
|
2783
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
2861
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = ar[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);
|
|
2784
2862
|
let n = JSON.stringify(t);
|
|
2785
2863
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
2786
2864
|
}
|
|
2787
2865
|
end(e, t) {
|
|
2788
2866
|
if (this.endedFlag) return;
|
|
2789
|
-
this.endedFlag = !0,
|
|
2867
|
+
this.endedFlag = !0, fr.delete(this);
|
|
2790
2868
|
let n = t ?? this.now();
|
|
2791
2869
|
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));
|
|
2792
2870
|
let r = this.safeSample();
|
|
@@ -2800,7 +2878,7 @@ var sr = class {
|
|
|
2800
2878
|
let c = r?.positionMs ?? 0;
|
|
2801
2879
|
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));
|
|
2802
2880
|
let l = e !== "END_REASON_ENDED";
|
|
2803
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
2881
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= nr && (i.abandonAfterStallMs = Math.max(Z, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= nr && (i.abandonAfterErrorMs = Math.max(Z, Math.round(n - this.lastErrorMs))), this.fullscreenTotalMs > 0 && (i.fullscreenTimeMs = Math.round(this.fullscreenTotalMs)), this.pipTotalMs > 0 && (i.pipTimeMs = Math.round(this.pipTotalMs)), this.volumeChanges > 0 && (i.volumeChanges = this.volumeChanges), this.muteChanges > 0 && (i.muteChanges = this.muteChanges);
|
|
2804
2882
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
2805
2883
|
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");
|
|
2806
2884
|
}
|
|
@@ -2820,13 +2898,13 @@ var sr = class {
|
|
|
2820
2898
|
};
|
|
2821
2899
|
}
|
|
2822
2900
|
noteCspBlocked() {
|
|
2823
|
-
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(
|
|
2901
|
+
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(pr(new URL(this.url).origin)));
|
|
2824
2902
|
}
|
|
2825
2903
|
cspBlocked() {
|
|
2826
|
-
return !!this.cspKey &&
|
|
2904
|
+
return !!this.cspKey && dr.has(this.cspKey);
|
|
2827
2905
|
}
|
|
2828
2906
|
enqueue(e) {
|
|
2829
|
-
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
2907
|
+
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > er;) {
|
|
2830
2908
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
2831
2909
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
2832
2910
|
}
|
|
@@ -2853,7 +2931,7 @@ var sr = class {
|
|
|
2853
2931
|
};
|
|
2854
2932
|
//#endregion
|
|
2855
2933
|
//#region src/core/environment.ts
|
|
2856
|
-
function
|
|
2934
|
+
function vr() {
|
|
2857
2935
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
2858
2936
|
let e;
|
|
2859
2937
|
try {
|
|
@@ -2878,14 +2956,14 @@ function cr() {
|
|
|
2878
2956
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
2879
2957
|
};
|
|
2880
2958
|
}
|
|
2881
|
-
function
|
|
2959
|
+
function yr() {
|
|
2882
2960
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
2883
2961
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
2884
2962
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
2885
2963
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
2886
2964
|
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";
|
|
2887
2965
|
}
|
|
2888
|
-
function
|
|
2966
|
+
function br() {
|
|
2889
2967
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
2890
2968
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
2891
2969
|
let t = {
|
|
@@ -2904,17 +2982,17 @@ function ur() {
|
|
|
2904
2982
|
}
|
|
2905
2983
|
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;
|
|
2906
2984
|
}
|
|
2907
|
-
function
|
|
2908
|
-
let t =
|
|
2909
|
-
deviceClass:
|
|
2985
|
+
function xr(e) {
|
|
2986
|
+
let t = vr(), n = {
|
|
2987
|
+
deviceClass: yr(),
|
|
2910
2988
|
integration: t.integration,
|
|
2911
|
-
...
|
|
2989
|
+
...br()
|
|
2912
2990
|
};
|
|
2913
2991
|
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);
|
|
2914
2992
|
let r = e.getBoundingClientRect?.();
|
|
2915
2993
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
2916
2994
|
}
|
|
2917
|
-
async function
|
|
2995
|
+
async function Sr() {
|
|
2918
2996
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
2919
2997
|
if (!e?.getHighEntropyValues) return {};
|
|
2920
2998
|
try {
|
|
@@ -2926,7 +3004,7 @@ async function fr() {
|
|
|
2926
3004
|
}
|
|
2927
3005
|
//#endregion
|
|
2928
3006
|
//#region src/core/version.ts
|
|
2929
|
-
var
|
|
3007
|
+
var Cr = "2.26.1", wr = {
|
|
2930
3008
|
accent: "#E1B600",
|
|
2931
3009
|
accentText: "#1B1C23",
|
|
2932
3010
|
background: "#0e0f13",
|
|
@@ -2937,7 +3015,7 @@ var pr = "2.25.1", mr = {
|
|
|
2937
3015
|
border: "rgba(255, 255, 255, 0.1)",
|
|
2938
3016
|
radius: "8px",
|
|
2939
3017
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
2940
|
-
},
|
|
3018
|
+
}, Tr = {
|
|
2941
3019
|
accent: "--havik-accent",
|
|
2942
3020
|
accentText: "--havik-accent-text",
|
|
2943
3021
|
background: "--havik-bg",
|
|
@@ -2949,26 +3027,26 @@ var pr = "2.25.1", mr = {
|
|
|
2949
3027
|
radius: "--havik-radius",
|
|
2950
3028
|
fontFamily: "--havik-font"
|
|
2951
3029
|
};
|
|
2952
|
-
function
|
|
3030
|
+
function Er(e, t) {
|
|
2953
3031
|
let n = {
|
|
2954
|
-
...
|
|
3032
|
+
...wr,
|
|
2955
3033
|
...t
|
|
2956
3034
|
};
|
|
2957
|
-
for (let t of Object.keys(
|
|
3035
|
+
for (let t of Object.keys(Tr)) e.style.setProperty(Tr[t], n[t]);
|
|
2958
3036
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
2959
3037
|
}
|
|
2960
3038
|
//#endregion
|
|
2961
3039
|
//#region src/ui/styles.ts
|
|
2962
|
-
var
|
|
2963
|
-
function
|
|
2964
|
-
let n = e.querySelector(`style#${
|
|
2965
|
-
if (n && (!t ||
|
|
3040
|
+
var Dr = "havik-player-styles", Or = "\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", kr = /* @__PURE__ */ new WeakMap();
|
|
3041
|
+
function Ar(e = document, t) {
|
|
3042
|
+
let n = e.querySelector(`style#${Dr}`);
|
|
3043
|
+
if (n && (!t || kr.get(n) === t)) return;
|
|
2966
3044
|
let r = e.createElement("style");
|
|
2967
|
-
r.id =
|
|
3045
|
+
r.id = Dr, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = Or, kr.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
|
|
2968
3046
|
}
|
|
2969
3047
|
//#endregion
|
|
2970
3048
|
//#region src/ui/icons.ts
|
|
2971
|
-
var
|
|
3049
|
+
var jr = {
|
|
2972
3050
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
2973
3051
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
2974
3052
|
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\"/>",
|
|
@@ -2981,12 +3059,12 @@ var xr = {
|
|
|
2981
3059
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
2982
3060
|
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\"/>"
|
|
2983
3061
|
};
|
|
2984
|
-
function
|
|
2985
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
3062
|
+
function Q(e) {
|
|
3063
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${jr[e]}</svg>`;
|
|
2986
3064
|
}
|
|
2987
3065
|
//#endregion
|
|
2988
3066
|
//#region src/ui/controls.ts
|
|
2989
|
-
var
|
|
3067
|
+
var Mr = 3e3, Nr = 250, Pr = /* @__PURE__ */ new Set([
|
|
2990
3068
|
"GONE",
|
|
2991
3069
|
"NOT_FOUND",
|
|
2992
3070
|
"GEO_DENIED",
|
|
@@ -2994,15 +3072,15 @@ var Sr = 3e3, Cr = 250, wr = /* @__PURE__ */ new Set([
|
|
|
2994
3072
|
"UNAUTHORIZED",
|
|
2995
3073
|
"DRM_DEVICE_REVOKED"
|
|
2996
3074
|
]);
|
|
2997
|
-
function
|
|
3075
|
+
function Fr(e) {
|
|
2998
3076
|
let t = "This match isn't available in your country";
|
|
2999
3077
|
return e ? `${t} (${e})` : t;
|
|
3000
3078
|
}
|
|
3001
|
-
var
|
|
3002
|
-
function
|
|
3003
|
-
return new
|
|
3079
|
+
var Ir = "This device can't play protected video";
|
|
3080
|
+
function Lr(e) {
|
|
3081
|
+
return new Rr(e);
|
|
3004
3082
|
}
|
|
3005
|
-
var
|
|
3083
|
+
var Rr = class {
|
|
3006
3084
|
root;
|
|
3007
3085
|
video;
|
|
3008
3086
|
player;
|
|
@@ -3051,7 +3129,7 @@ var Or = class {
|
|
|
3051
3129
|
scrubbing = !1;
|
|
3052
3130
|
offFns = [];
|
|
3053
3131
|
constructor(e) {
|
|
3054
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
3132
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Mr, 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", Ar(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");
|
|
3055
3133
|
let t = (e, t, n) => {
|
|
3056
3134
|
let r = this.doc.createElement(e);
|
|
3057
3135
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -3062,12 +3140,12 @@ var Or = class {
|
|
|
3062
3140
|
"aria-label": r,
|
|
3063
3141
|
title: r
|
|
3064
3142
|
});
|
|
3065
|
-
return i.innerHTML =
|
|
3143
|
+
return i.innerHTML = Q(n), i;
|
|
3066
3144
|
};
|
|
3067
3145
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
3068
3146
|
type: "button",
|
|
3069
3147
|
"aria-label": "Play"
|
|
3070
|
-
}), this.center.innerHTML =
|
|
3148
|
+
}), this.center.innerHTML = Q("play"), this.spinner = t("div", "havik-spinner"), this.spinner.style.display = "none", this.overlay.append(this.center, this.spinner), this.gradient = t("div", "havik-gradient"), this.bar = t("div", "havik-bar"), this.seek = t("div", "havik-seek", {
|
|
3071
3149
|
role: "slider",
|
|
3072
3150
|
"aria-label": "Seek",
|
|
3073
3151
|
"aria-valuemin": "0",
|
|
@@ -3085,7 +3163,7 @@ var Or = class {
|
|
|
3085
3163
|
"aria-label": "Volume"
|
|
3086
3164
|
});
|
|
3087
3165
|
let a = t("div", "havik-vol");
|
|
3088
|
-
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML =
|
|
3166
|
+
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Q("liveDot");
|
|
3089
3167
|
let o = this.doc.createElement("span");
|
|
3090
3168
|
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";
|
|
3091
3169
|
let s = t("div", "havik-spacer");
|
|
@@ -3137,7 +3215,7 @@ var Or = class {
|
|
|
3137
3215
|
let t = this.surfaceWasHidden;
|
|
3138
3216
|
this.tapTimer = setTimeout(() => {
|
|
3139
3217
|
this.tapTimer = void 0, this.toggleBar(t);
|
|
3140
|
-
},
|
|
3218
|
+
}, Nr);
|
|
3141
3219
|
}
|
|
3142
3220
|
toggleBar(e) {
|
|
3143
3221
|
e ? this.poke() : this.hideIfIdle();
|
|
@@ -3152,16 +3230,19 @@ var Or = class {
|
|
|
3152
3230
|
let t = e === "loading" || e === "buffering";
|
|
3153
3231
|
this.spinner.style.display = t && !this.statusBox ? "" : "none", (t || this.statusBox) && this.center.classList.add("havik-gone"), this.syncLive();
|
|
3154
3232
|
}
|
|
3233
|
+
isGone() {
|
|
3234
|
+
return this.player.state === "error" && this.lastError?.code === "GONE";
|
|
3235
|
+
}
|
|
3155
3236
|
syncStatus(e) {
|
|
3156
3237
|
let t = null;
|
|
3157
3238
|
if (this.statusOverlays) {
|
|
3158
|
-
let n = this.player.offline &&
|
|
3159
|
-
|
|
3239
|
+
let n = e === "ended" || this.isGone(), r = this.player.offline && !n && e !== "idle", i = !this.hasPlayed && (e === "paused" || e === "waiting");
|
|
3240
|
+
n ? t = "ended" : r && !i ? t = "offline" : e === "error" ? t = "error" : e === "waiting" ? t = "waiting" : !this.hasPlayed && (e === "idle" || e === "paused") && (t = "preplay");
|
|
3160
3241
|
}
|
|
3161
3242
|
this.renderStatus(t);
|
|
3162
3243
|
}
|
|
3163
3244
|
statusMessageFor(e) {
|
|
3164
|
-
return e === "ended" ? 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" ?
|
|
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" ? Fr(this.lastError.country) : this.lastError?.code === "DRM_DEVICE_REVOKED" ? Ir : this.lastError?.message ?? "Playback unavailable" : this.errorMessage : null;
|
|
3165
3246
|
}
|
|
3166
3247
|
renderStatus(e) {
|
|
3167
3248
|
let t = this.statusMessageFor(e);
|
|
@@ -3173,12 +3254,12 @@ var Or = class {
|
|
|
3173
3254
|
}
|
|
3174
3255
|
if (e === "preplay") {
|
|
3175
3256
|
let e = this.doc.createElement("button");
|
|
3176
|
-
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML =
|
|
3257
|
+
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = Q("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
|
|
3177
3258
|
} else {
|
|
3178
3259
|
let r = this.doc.createElement("div");
|
|
3179
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
3260
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Pr.has(this.lastError.code)) {
|
|
3180
3261
|
let e = this.doc.createElement("button");
|
|
3181
|
-
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${
|
|
3262
|
+
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${Q("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
|
|
3182
3263
|
}
|
|
3183
3264
|
}
|
|
3184
3265
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -3217,11 +3298,11 @@ var Or = class {
|
|
|
3217
3298
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
3218
3299
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
3219
3300
|
}
|
|
3220
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
3301
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${zr(this.video.currentTime)} / ${zr(this.video.duration)}`);
|
|
3221
3302
|
}
|
|
3222
3303
|
syncLive() {
|
|
3223
|
-
let e = this.player.getStats(), t = e.isLive !== !1, n = this.player.state === "ended",
|
|
3224
|
-
this.live.style.display = t && !
|
|
3304
|
+
let e = this.player.getStats(), t = e.isLive !== !1, n = this.isGone(), r = this.player.state === "ended" || n, i = !t && !this.streamEnded() && !n;
|
|
3305
|
+
this.live.style.display = t && !r ? "" : "none", this.time.style.display = i ? "" : "none", this.seek.style.display = i ? "" : "none", this.live.classList.toggle("is-live", e.atLiveEdge !== !1 && t);
|
|
3225
3306
|
}
|
|
3226
3307
|
onSeekDown(e) {
|
|
3227
3308
|
let t = this.seekableRange();
|
|
@@ -3267,17 +3348,17 @@ var Or = class {
|
|
|
3267
3348
|
renderQualityMenu() {
|
|
3268
3349
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
3269
3350
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
3270
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
3351
|
+
for (let n of e) this.menu.append(this.menuItem(Br(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
3271
3352
|
}
|
|
3272
3353
|
renderAudioMenu() {
|
|
3273
3354
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
3274
3355
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
3275
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
3356
|
+
for (let t of e) this.menu.append(this.menuItem(Vr(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
3276
3357
|
}
|
|
3277
3358
|
renderCcMenu() {
|
|
3278
3359
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
3279
3360
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
3280
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
3361
|
+
for (let t of e) this.menu.append(this.menuItem(Hr(t), !1, () => this.player.setTextTrack(t.id)));
|
|
3281
3362
|
}
|
|
3282
3363
|
onTracksChanged() {
|
|
3283
3364
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -3297,14 +3378,14 @@ var Or = class {
|
|
|
3297
3378
|
}
|
|
3298
3379
|
async toggleFullscreen() {
|
|
3299
3380
|
try {
|
|
3300
|
-
|
|
3381
|
+
S(this.video, this.root) ? await T(this.video, this.root) : await w(this.video, this.root);
|
|
3301
3382
|
} catch {}
|
|
3302
3383
|
}
|
|
3303
3384
|
syncFullscreenSupport() {
|
|
3304
|
-
this.fsSupported =
|
|
3385
|
+
this.fsSupported = C(this.video, this.root), this.fsBtn.style.display = this.fsSupported ? "" : "none";
|
|
3305
3386
|
}
|
|
3306
3387
|
syncFullscreen() {
|
|
3307
|
-
let e =
|
|
3388
|
+
let e = S(this.video, this.root);
|
|
3308
3389
|
this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
|
|
3309
3390
|
}
|
|
3310
3391
|
poke() {
|
|
@@ -3365,7 +3446,7 @@ var Or = class {
|
|
|
3365
3446
|
}
|
|
3366
3447
|
}
|
|
3367
3448
|
setIcon(e, t) {
|
|
3368
|
-
e.innerHTML =
|
|
3449
|
+
e.innerHTML = Q(t);
|
|
3369
3450
|
}
|
|
3370
3451
|
destroy() {
|
|
3371
3452
|
this.hideTimer && clearTimeout(this.hideTimer), this.tapTimer && clearTimeout(this.tapTimer);
|
|
@@ -3382,23 +3463,23 @@ var Or = class {
|
|
|
3382
3463
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
3383
3464
|
}
|
|
3384
3465
|
};
|
|
3385
|
-
function
|
|
3466
|
+
function zr(e) {
|
|
3386
3467
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
3387
3468
|
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");
|
|
3388
3469
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
3389
3470
|
}
|
|
3390
|
-
function
|
|
3471
|
+
function Br(e) {
|
|
3391
3472
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
3392
3473
|
}
|
|
3393
|
-
function
|
|
3474
|
+
function Vr(e) {
|
|
3394
3475
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3395
3476
|
}
|
|
3396
|
-
function
|
|
3477
|
+
function Hr(e) {
|
|
3397
3478
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3398
3479
|
}
|
|
3399
3480
|
//#endregion
|
|
3400
3481
|
//#region src/managed/index.ts
|
|
3401
|
-
var
|
|
3482
|
+
var Ur = 6e3, Wr = 45e3, Gr = 2e3, Kr = 3, qr = 5e3, Jr = 2e3, Yr = 48e4, Xr = "keySystemLicenseRequestFailed", Zr = /* @__PURE__ */ new Set([
|
|
3402
3483
|
"GONE",
|
|
3403
3484
|
"NOT_FOUND",
|
|
3404
3485
|
"INVALID_URN",
|
|
@@ -3406,27 +3487,27 @@ var Nr = 6e3, Pr = 45e3, Fr = 2e3, Ir = 3, Lr = 5e3, Rr = 2e3, zr = 48e4, Br = "
|
|
|
3406
3487
|
"GEO_DENIED",
|
|
3407
3488
|
"DRM_DEVICE_REVOKED"
|
|
3408
3489
|
]);
|
|
3409
|
-
function
|
|
3410
|
-
return !
|
|
3490
|
+
function Qr(e) {
|
|
3491
|
+
return !Zr.has(e);
|
|
3411
3492
|
}
|
|
3412
|
-
function
|
|
3493
|
+
function $r(e) {
|
|
3413
3494
|
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)})`);
|
|
3414
|
-
if (e.env !== void 0) return
|
|
3495
|
+
if (e.env !== void 0) return lt(e.env);
|
|
3415
3496
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
3416
3497
|
return e.baseUrl;
|
|
3417
3498
|
}
|
|
3418
|
-
async function
|
|
3499
|
+
async function ei(e) {
|
|
3419
3500
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
3420
|
-
let t =
|
|
3501
|
+
let t = $r(e);
|
|
3421
3502
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
3422
3503
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
3423
|
-
let r = new
|
|
3504
|
+
let r = new ti({
|
|
3424
3505
|
...e,
|
|
3425
3506
|
baseUrl: t
|
|
3426
3507
|
});
|
|
3427
3508
|
return await r.start(), r;
|
|
3428
3509
|
}
|
|
3429
|
-
var
|
|
3510
|
+
var ti = class {
|
|
3430
3511
|
opts;
|
|
3431
3512
|
abort = new AbortController();
|
|
3432
3513
|
listeners = {};
|
|
@@ -3470,7 +3551,7 @@ var Gr = class {
|
|
|
3470
3551
|
return this._state;
|
|
3471
3552
|
}
|
|
3472
3553
|
get offline() {
|
|
3473
|
-
return !
|
|
3554
|
+
return !L();
|
|
3474
3555
|
}
|
|
3475
3556
|
get descriptor() {
|
|
3476
3557
|
return this._descriptor;
|
|
@@ -3505,7 +3586,7 @@ var Gr = class {
|
|
|
3505
3586
|
};
|
|
3506
3587
|
}
|
|
3507
3588
|
beginArming(e, t, n = !1) {
|
|
3508
|
-
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ??
|
|
3589
|
+
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? O(this.opts.baseUrl);
|
|
3509
3590
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
3510
3591
|
}
|
|
3511
3592
|
beginArmingByPolling(e) {
|
|
@@ -3526,7 +3607,7 @@ var Gr = class {
|
|
|
3526
3607
|
setTimeout(() => {
|
|
3527
3608
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
3528
3609
|
phase: i ? "unavailable" : "tooEarly",
|
|
3529
|
-
retryInMs:
|
|
3610
|
+
retryInMs: Wr,
|
|
3530
3611
|
attempt: 1,
|
|
3531
3612
|
elapsedMs: 0,
|
|
3532
3613
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -3565,13 +3646,13 @@ var Gr = class {
|
|
|
3565
3646
|
!a && !p() && h();
|
|
3566
3647
|
}, e);
|
|
3567
3648
|
};
|
|
3568
|
-
_(
|
|
3649
|
+
_(Ur), this.armingSub = D({
|
|
3569
3650
|
eventsBaseUrl: t,
|
|
3570
3651
|
matchUrn: this.opts.matchUrn,
|
|
3571
3652
|
credential: this.opts.credential,
|
|
3572
|
-
onAlive: () => _(
|
|
3653
|
+
onAlive: () => _(Wr),
|
|
3573
3654
|
onState: (e) => {
|
|
3574
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
3655
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Gr);
|
|
3575
3656
|
},
|
|
3576
3657
|
onError: () => h()
|
|
3577
3658
|
});
|
|
@@ -3594,7 +3675,7 @@ var Gr = class {
|
|
|
3594
3675
|
let n = await c(this.opts.credential);
|
|
3595
3676
|
if (this.destroyed || t !== this.loadGen) return;
|
|
3596
3677
|
this.setState("loading");
|
|
3597
|
-
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a =
|
|
3678
|
+
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = gt(this.opts.video, (e) => {
|
|
3598
3679
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
3599
3680
|
});
|
|
3600
3681
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -3616,26 +3697,26 @@ var Gr = class {
|
|
|
3616
3697
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
3617
3698
|
let i = e.analytics?.sid;
|
|
3618
3699
|
if (!i) return;
|
|
3619
|
-
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } =
|
|
3700
|
+
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = gr(this.opts.baseUrl, a, e.analytics?.endpoint);
|
|
3620
3701
|
if (!o) {
|
|
3621
3702
|
s && setTimeout(() => {
|
|
3622
3703
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
|
|
3623
3704
|
}, 0);
|
|
3624
3705
|
return;
|
|
3625
3706
|
}
|
|
3626
|
-
let c = this.opts.video, l = new
|
|
3707
|
+
let c = this.opts.video, l = new _r({
|
|
3627
3708
|
endpoint: o,
|
|
3628
3709
|
sid: i,
|
|
3629
3710
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
3630
|
-
sdkVersion:
|
|
3631
|
-
environment:
|
|
3711
|
+
sdkVersion: Cr,
|
|
3712
|
+
environment: xr(c),
|
|
3632
3713
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
3633
3714
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
3634
3715
|
onBlocked: (e) => setTimeout(() => {
|
|
3635
3716
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, e));
|
|
3636
3717
|
}, 0),
|
|
3637
3718
|
sample: () => {
|
|
3638
|
-
let e = this.engine?.getStats() ??
|
|
3719
|
+
let e = this.engine?.getStats() ?? dt, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
|
|
3639
3720
|
return {
|
|
3640
3721
|
...e,
|
|
3641
3722
|
bufferedMs: Math.round(t * 1e3),
|
|
@@ -3649,7 +3730,7 @@ var Gr = class {
|
|
|
3649
3730
|
let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
|
|
3650
3731
|
c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
|
|
3651
3732
|
c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
|
|
3652
|
-
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()),
|
|
3733
|
+
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), Sr().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
3653
3734
|
}
|
|
3654
3735
|
currentPresentation() {
|
|
3655
3736
|
let e = this.opts.video;
|
|
@@ -3664,7 +3745,7 @@ var Gr = class {
|
|
|
3664
3745
|
video: this.opts.video,
|
|
3665
3746
|
descriptor: e,
|
|
3666
3747
|
credential: t,
|
|
3667
|
-
deviceId:
|
|
3748
|
+
deviceId: Oe(),
|
|
3668
3749
|
userId: this.opts.userId,
|
|
3669
3750
|
lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
|
|
3670
3751
|
snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
|
|
@@ -3680,11 +3761,11 @@ var Gr = class {
|
|
|
3680
3761
|
emit: (e) => this.onEngineEvent(e),
|
|
3681
3762
|
freshLicenseUrl: () => this.refreshLicense()
|
|
3682
3763
|
}, o = this.opts.engine ?? "auto";
|
|
3683
|
-
if (o === "native") return new
|
|
3684
|
-
if (o === "hls") return new
|
|
3685
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl &&
|
|
3686
|
-
if (
|
|
3687
|
-
if (
|
|
3764
|
+
if (o === "native") return new H(a);
|
|
3765
|
+
if (o === "hls") return new Xn(a);
|
|
3766
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && B(this.opts.video) && V() || !e.drmEnabled && Ot() && B(this.opts.video)) return new H(a);
|
|
3767
|
+
if (Wt()) return new Xn(a);
|
|
3768
|
+
if (B(this.opts.video)) return new H(a);
|
|
3688
3769
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
3689
3770
|
}
|
|
3690
3771
|
onEngineEvent(e) {
|
|
@@ -3734,11 +3815,11 @@ var Gr = class {
|
|
|
3734
3815
|
}
|
|
3735
3816
|
startLiveState(e) {
|
|
3736
3817
|
if (this.opts.liveStateEvents === !1) return;
|
|
3737
|
-
let t = this.opts.eventsBaseUrl ??
|
|
3818
|
+
let t = this.opts.eventsBaseUrl ?? O(this.opts.baseUrl);
|
|
3738
3819
|
if (!t) return;
|
|
3739
3820
|
this.closeLiveState();
|
|
3740
3821
|
let i = 0, a = !1;
|
|
3741
|
-
this.liveStateSub =
|
|
3822
|
+
this.liveStateSub = D({
|
|
3742
3823
|
eventsBaseUrl: t,
|
|
3743
3824
|
matchUrn: this.opts.matchUrn,
|
|
3744
3825
|
credential: this.opts.credential,
|
|
@@ -3750,11 +3831,11 @@ var Gr = class {
|
|
|
3750
3831
|
},
|
|
3751
3832
|
onError: (o) => {
|
|
3752
3833
|
if (!(this.destroyed || e !== this.loadGen || a) && !this.endedHandled) {
|
|
3753
|
-
if (o instanceof
|
|
3834
|
+
if (o instanceof E && (o.terminal || o.status === 404)) {
|
|
3754
3835
|
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."));
|
|
3755
3836
|
return;
|
|
3756
3837
|
}
|
|
3757
|
-
i += 1, i >=
|
|
3838
|
+
i += 1, i >= Kr && (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.`)));
|
|
3758
3839
|
}
|
|
3759
3840
|
}
|
|
3760
3841
|
});
|
|
@@ -3763,7 +3844,7 @@ var Gr = class {
|
|
|
3763
3844
|
this.liveStateSub?.close(), this.liveStateSub = null;
|
|
3764
3845
|
}
|
|
3765
3846
|
watchConnectivity() {
|
|
3766
|
-
this.connectivity || (this.connectivity =
|
|
3847
|
+
this.connectivity || (this.connectivity = ut(), this.connectivity.onChange((e) => {
|
|
3767
3848
|
if (this.destroyed) return;
|
|
3768
3849
|
if (!e) {
|
|
3769
3850
|
this.emit("offline");
|
|
@@ -3771,7 +3852,7 @@ var Gr = class {
|
|
|
3771
3852
|
}
|
|
3772
3853
|
if (this.emit("online"), this._state !== "error" || !this._lastError) return;
|
|
3773
3854
|
let t = this._lastError.code;
|
|
3774
|
-
|
|
3855
|
+
Qr(t) && (t === "NETWORK" || this.failedWhileOffline) && this.retry().catch(() => void 0);
|
|
3775
3856
|
}));
|
|
3776
3857
|
}
|
|
3777
3858
|
watchReturn() {
|
|
@@ -3781,7 +3862,7 @@ var Gr = class {
|
|
|
3781
3862
|
return;
|
|
3782
3863
|
}
|
|
3783
3864
|
let e = this.hiddenAtMs;
|
|
3784
|
-
this.hiddenAtMs = null, e != null && Date.now() - e >=
|
|
3865
|
+
this.hiddenAtMs = null, e != null && Date.now() - e >= qr && this.resyncLiveState();
|
|
3785
3866
|
}, this.onReturnPageShow = (e) => {
|
|
3786
3867
|
e.persisted && this.resyncLiveState();
|
|
3787
3868
|
}, document.addEventListener("visibilitychange", this.onReturnVisible), typeof window < "u" && window.addEventListener("pageshow", this.onReturnPageShow));
|
|
@@ -3813,7 +3894,7 @@ var Gr = class {
|
|
|
3813
3894
|
scheduleRejoin(e) {
|
|
3814
3895
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
3815
3896
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
3816
|
-
}, Math.random() *
|
|
3897
|
+
}, Math.random() * Gr));
|
|
3817
3898
|
}
|
|
3818
3899
|
cancelRejoin() {
|
|
3819
3900
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -3837,7 +3918,7 @@ var Gr = class {
|
|
|
3837
3918
|
}
|
|
3838
3919
|
t.controls = !1;
|
|
3839
3920
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
3840
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
3921
|
+
r && r.insertBefore(n, t), n.appendChild(t), Er(n, this.opts.theme), this.container = n, this.controlBar = Lr({
|
|
3841
3922
|
root: n,
|
|
3842
3923
|
video: t,
|
|
3843
3924
|
player: this,
|
|
@@ -3876,7 +3957,7 @@ var Gr = class {
|
|
|
3876
3957
|
}
|
|
3877
3958
|
startStats() {
|
|
3878
3959
|
this.stopStats();
|
|
3879
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
3960
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Jr);
|
|
3880
3961
|
this.statsTimer = setInterval(() => {
|
|
3881
3962
|
if (!this.engine) return;
|
|
3882
3963
|
let e = this.engine.getStats();
|
|
@@ -3887,14 +3968,14 @@ var Gr = class {
|
|
|
3887
3968
|
this.statsTimer && clearInterval(this.statsTimer), this.statsTimer = void 0;
|
|
3888
3969
|
}
|
|
3889
3970
|
isStaleLicenseDenial(e) {
|
|
3890
|
-
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !==
|
|
3971
|
+
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== Xr || e.error.httpStatus !== 403 || e.error.code !== "FORBIDDEN" || e.error.serverCode === "license_refused" ? !1 : W(this._descriptor?.drm?.widevine?.licenseUrl);
|
|
3891
3972
|
}
|
|
3892
3973
|
scheduleLicenseRefresh() {
|
|
3893
3974
|
if (this.stopRefresh(), !this._descriptor?.drmEnabled) return;
|
|
3894
3975
|
typeof document < "u" && this.engine?.name === "hls" && (this.onRefocus = () => {
|
|
3895
|
-
document.visibilityState !== "visible" || this.destroyed ||
|
|
3976
|
+
document.visibilityState !== "visible" || this.destroyed || W(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
|
|
3896
3977
|
}, document.addEventListener("visibilitychange", this.onRefocus));
|
|
3897
|
-
let e = this.opts.licenseRefreshMs ??
|
|
3978
|
+
let e = this.opts.licenseRefreshMs ?? Yr;
|
|
3898
3979
|
e && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
3899
3980
|
}
|
|
3900
3981
|
stopRefresh() {
|
|
@@ -3951,7 +4032,7 @@ var Gr = class {
|
|
|
3951
4032
|
this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
|
|
3952
4033
|
}
|
|
3953
4034
|
getStats() {
|
|
3954
|
-
return this.engine?.getStats() ??
|
|
4035
|
+
return this.engine?.getStats() ?? dt;
|
|
3955
4036
|
}
|
|
3956
4037
|
getQualityLevels() {
|
|
3957
4038
|
return this.engine?.getQualityLevels() ?? [];
|
|
@@ -3990,13 +4071,13 @@ var Gr = class {
|
|
|
3990
4071
|
e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
|
|
3991
4072
|
}
|
|
3992
4073
|
async enterFullscreen() {
|
|
3993
|
-
return !this.destroyed &&
|
|
4074
|
+
return !this.destroyed && w(this.opts.video, this.container ?? void 0);
|
|
3994
4075
|
}
|
|
3995
4076
|
async exitFullscreen() {
|
|
3996
|
-
await
|
|
4077
|
+
await T(this.opts.video, this.container ?? void 0);
|
|
3997
4078
|
}
|
|
3998
4079
|
fullscreenSupported() {
|
|
3999
|
-
return !this.destroyed &&
|
|
4080
|
+
return !this.destroyed && C(this.opts.video, this.container ?? void 0);
|
|
4000
4081
|
}
|
|
4001
4082
|
retry() {
|
|
4002
4083
|
return this.reload();
|
|
@@ -4027,7 +4108,7 @@ var Gr = class {
|
|
|
4027
4108
|
for (let e of Object.keys(this.listeners)) this.listeners[e]?.clear();
|
|
4028
4109
|
}
|
|
4029
4110
|
fail(e) {
|
|
4030
|
-
this._lastError = e, this.failedWhileOffline = !
|
|
4111
|
+
this._lastError = e, this.failedWhileOffline = !L(), this.setState("error"), this.analyticsSession?.noteFatal(), this.emit("error", e);
|
|
4031
4112
|
}
|
|
4032
4113
|
setState(e) {
|
|
4033
4114
|
if (e === this._state) return;
|
|
@@ -4059,12 +4140,12 @@ var Gr = class {
|
|
|
4059
4140
|
};
|
|
4060
4141
|
//#endregion
|
|
4061
4142
|
//#region src/embed/protocol.ts
|
|
4062
|
-
function
|
|
4143
|
+
function $(e) {
|
|
4063
4144
|
return !!e && typeof e == "object" && typeof e.type == "string" && e.type.startsWith("oddin:");
|
|
4064
4145
|
}
|
|
4065
4146
|
//#endregion
|
|
4066
4147
|
//#region src/embed/host.ts
|
|
4067
|
-
function
|
|
4148
|
+
function ni(e) {
|
|
4068
4149
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
4069
4150
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
4070
4151
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -4073,7 +4154,7 @@ function qr(e) {
|
|
|
4073
4154
|
let r = document.createElement("iframe");
|
|
4074
4155
|
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);
|
|
4075
4156
|
let i = /* @__PURE__ */ new Set(), a = (t) => {
|
|
4076
|
-
if (t.source !== r.contentWindow || t.origin !== n ||
|
|
4157
|
+
if (t.source !== r.contentWindow || t.origin !== n || !$(t.data)) return;
|
|
4077
4158
|
let a = t.data;
|
|
4078
4159
|
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));
|
|
4079
4160
|
};
|
|
@@ -4123,15 +4204,15 @@ function qr(e) {
|
|
|
4123
4204
|
}
|
|
4124
4205
|
//#endregion
|
|
4125
4206
|
//#region src/embed/page.ts
|
|
4126
|
-
var
|
|
4127
|
-
function
|
|
4207
|
+
var ri = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
4208
|
+
function ii(e) {
|
|
4128
4209
|
if (typeof e == "boolean") return e;
|
|
4129
4210
|
if (typeof e == "object" && e) {
|
|
4130
4211
|
let t = e.endpoint;
|
|
4131
4212
|
return typeof t == "string" ? { endpoint: t } : {};
|
|
4132
4213
|
}
|
|
4133
4214
|
}
|
|
4134
|
-
function
|
|
4215
|
+
function ai() {
|
|
4135
4216
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
4136
4217
|
if (e) return {
|
|
4137
4218
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -4141,7 +4222,7 @@ function Xr() {
|
|
|
4141
4222
|
autoplay: e.autoplay ?? !0,
|
|
4142
4223
|
muted: e.muted ?? !0,
|
|
4143
4224
|
waitForLive: e.waitForLive ?? !0,
|
|
4144
|
-
analytics:
|
|
4225
|
+
analytics: ii(e.analytics)
|
|
4145
4226
|
};
|
|
4146
4227
|
let t = new URLSearchParams(location.search);
|
|
4147
4228
|
return {
|
|
@@ -4154,9 +4235,9 @@ function Xr() {
|
|
|
4154
4235
|
waitForLive: !0
|
|
4155
4236
|
};
|
|
4156
4237
|
}
|
|
4157
|
-
async function
|
|
4158
|
-
let e =
|
|
4159
|
-
|
|
4238
|
+
async function oi() {
|
|
4239
|
+
let e = ai();
|
|
4240
|
+
ci();
|
|
4160
4241
|
let t = document.createElement("video");
|
|
4161
4242
|
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);
|
|
4162
4243
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -4212,12 +4293,12 @@ async function Zr() {
|
|
|
4212
4293
|
message: e.message,
|
|
4213
4294
|
...e.country === void 0 ? {} : { country: e.country }
|
|
4214
4295
|
})), e.on("autoplayblocked", () => {
|
|
4215
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
4296
|
+
i({ type: "oddin:autoplayblocked" }), si(t, e);
|
|
4216
4297
|
});
|
|
4217
4298
|
}, s = async (r) => {
|
|
4218
4299
|
a?.destroy(), a = null;
|
|
4219
4300
|
try {
|
|
4220
|
-
let n = await
|
|
4301
|
+
let n = await ei({
|
|
4221
4302
|
video: t,
|
|
4222
4303
|
baseUrl: e.baseUrl,
|
|
4223
4304
|
matchUrn: r,
|
|
@@ -4280,30 +4361,30 @@ async function Zr() {
|
|
|
4280
4361
|
a?.retry();
|
|
4281
4362
|
break;
|
|
4282
4363
|
case "oddin:load":
|
|
4283
|
-
typeof e.matchUrn == "string" &&
|
|
4364
|
+
typeof e.matchUrn == "string" && ri.test(e.matchUrn) && s(e.matchUrn);
|
|
4284
4365
|
break;
|
|
4285
4366
|
case "oddin:destroy": c();
|
|
4286
4367
|
}
|
|
4287
4368
|
}, u = (e) => {
|
|
4288
|
-
r && e.origin === r &&
|
|
4369
|
+
r && e.origin === r && $(e.data) && l(e.data);
|
|
4289
4370
|
};
|
|
4290
4371
|
r && window.addEventListener("message", u), window.addEventListener("pagehide", c, { once: !0 }), await s(e.matchUrn), i({
|
|
4291
4372
|
type: "oddin:ready",
|
|
4292
4373
|
protocol: 1
|
|
4293
4374
|
});
|
|
4294
4375
|
}
|
|
4295
|
-
function
|
|
4376
|
+
function si(e, t) {
|
|
4296
4377
|
if (document.getElementById("havik-tap")) return;
|
|
4297
4378
|
let n = document.createElement("button");
|
|
4298
4379
|
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", () => {
|
|
4299
4380
|
n.remove(), t.play();
|
|
4300
4381
|
}), document.body.appendChild(n);
|
|
4301
4382
|
}
|
|
4302
|
-
function
|
|
4383
|
+
function ci() {
|
|
4303
4384
|
let e = document.createElement("style");
|
|
4304
4385
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
4305
4386
|
}
|
|
4306
4387
|
//#endregion
|
|
4307
|
-
export {
|
|
4388
|
+
export { E as LiveStateHttpError, wr as ODDIN_THEME, n as PlaybackError, Er as applyTheme, lt as baseUrlForEnv, oi as bootEmbed, ke as clearDeviceId, He as clearRememberedBandwidth, ei as createPlayer, O as deriveEventsBaseUrl, at as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ve as fetchCatalog, be as fetchTournament, Se as flattenMatches, C as fullscreenSupported, Oe as getDeviceId, st as isLowLatencyManifest, $ as isOddinMessage, je as licenseRequestHeaders, ni as mountEmbed, fe as pollToLive, y as resolveStream, D as subscribeLiveState, S as videoFullscreenActive, we as watchStatus };
|
|
4308
4389
|
|
|
4309
4390
|
//# sourceMappingURL=index.js.map
|