@oddin-gg/havik-player 2.8.0 → 2.9.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/README.md +61 -0
- package/dist/havik-player.global.js +2 -2
- package/dist/havik-player.global.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +219 -188
- package/dist/index.js.map +1 -1
- package/docs/API.md +12 -10
- package/embed/index.html +6 -1
- package/examples/vanilla.html +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -551,7 +551,7 @@ var N = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
|
|
|
551
551
|
function xe(e) {
|
|
552
552
|
return e.startsWith("com.widevine");
|
|
553
553
|
}
|
|
554
|
-
function
|
|
554
|
+
function Se(e, t) {
|
|
555
555
|
if (!xe(e)) return t;
|
|
556
556
|
let n = (e, t) => {
|
|
557
557
|
let n = e.videoCapabilities;
|
|
@@ -568,8 +568,8 @@ function P(e, t) {
|
|
|
568
568
|
})));
|
|
569
569
|
return [...t, ...r];
|
|
570
570
|
}
|
|
571
|
-
function
|
|
572
|
-
return (t, n) => M() ? navigator.requestMediaKeySystemAccess(t,
|
|
571
|
+
function Ce(e) {
|
|
572
|
+
return (t, n) => M() ? navigator.requestMediaKeySystemAccess(t, Se(t, n)).then((t) => ({
|
|
573
573
|
keySystem: t.keySystem,
|
|
574
574
|
getConfiguration: () => t.getConfiguration(),
|
|
575
575
|
createMediaKeys: () => be(e, t)
|
|
@@ -577,11 +577,11 @@ function Se(e) {
|
|
|
577
577
|
}
|
|
578
578
|
//#endregion
|
|
579
579
|
//#region src/core/drm/support.ts
|
|
580
|
-
var
|
|
580
|
+
var we = 5e3, Te = "video/mp4; codecs=\"avc1.42E01E\"", Ee = "audio/mp4; codecs=\"mp4a.40.2\"", De = {
|
|
581
581
|
widevine: ["com.widevine.alpha"],
|
|
582
582
|
fairplay: ["com.apple.fps"]
|
|
583
583
|
};
|
|
584
|
-
function
|
|
584
|
+
function Oe(e) {
|
|
585
585
|
return e === "fairplay" ? [{
|
|
586
586
|
initDataTypes: [
|
|
587
587
|
"sinf",
|
|
@@ -589,30 +589,30 @@ function Te(e) {
|
|
|
589
589
|
"cenc"
|
|
590
590
|
],
|
|
591
591
|
videoCapabilities: [{
|
|
592
|
-
contentType:
|
|
592
|
+
contentType: Te,
|
|
593
593
|
robustness: "",
|
|
594
594
|
encryptionScheme: "cbcs"
|
|
595
595
|
}],
|
|
596
596
|
audioCapabilities: [{
|
|
597
|
-
contentType:
|
|
597
|
+
contentType: Ee,
|
|
598
598
|
robustness: "",
|
|
599
599
|
encryptionScheme: "cbcs"
|
|
600
600
|
}]
|
|
601
|
-
}] :
|
|
601
|
+
}] : Se("com.widevine.alpha", [{
|
|
602
602
|
initDataTypes: ["cenc"],
|
|
603
603
|
videoCapabilities: [{
|
|
604
|
-
contentType:
|
|
604
|
+
contentType: Te,
|
|
605
605
|
robustness: "SW_SECURE_DECODE",
|
|
606
606
|
encryptionScheme: "cbcs"
|
|
607
607
|
}],
|
|
608
608
|
audioCapabilities: [{
|
|
609
|
-
contentType:
|
|
609
|
+
contentType: Ee,
|
|
610
610
|
robustness: "SW_SECURE_CRYPTO",
|
|
611
611
|
encryptionScheme: "cbcs"
|
|
612
612
|
}]
|
|
613
613
|
}]);
|
|
614
614
|
}
|
|
615
|
-
function
|
|
615
|
+
function P(e, t) {
|
|
616
616
|
return new Promise((n, r) => {
|
|
617
617
|
let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
|
|
618
618
|
e.then((e) => {
|
|
@@ -622,8 +622,8 @@ function L(e, t) {
|
|
|
622
622
|
});
|
|
623
623
|
});
|
|
624
624
|
}
|
|
625
|
-
async function
|
|
626
|
-
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ??
|
|
625
|
+
async function ke(e = {}) {
|
|
626
|
+
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? we, r = {};
|
|
627
627
|
if (typeof window < "u" && window.isSecureContext === !1) return {
|
|
628
628
|
verdict: "insecure-context",
|
|
629
629
|
detail: r
|
|
@@ -635,7 +635,7 @@ async function Ee(e = {}) {
|
|
|
635
635
|
};
|
|
636
636
|
let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
|
|
637
637
|
for (let e of t) {
|
|
638
|
-
let t =
|
|
638
|
+
let t = De[e];
|
|
639
639
|
if (!t) {
|
|
640
640
|
r[e] = "unknown system";
|
|
641
641
|
continue;
|
|
@@ -646,7 +646,7 @@ async function Ee(e = {}) {
|
|
|
646
646
|
break;
|
|
647
647
|
}
|
|
648
648
|
try {
|
|
649
|
-
return await
|
|
649
|
+
return await P((await P(i(n, Oe(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
|
|
650
650
|
verdict: "supported",
|
|
651
651
|
system: e,
|
|
652
652
|
detail: r
|
|
@@ -670,49 +670,49 @@ async function Ee(e = {}) {
|
|
|
670
670
|
}
|
|
671
671
|
//#endregion
|
|
672
672
|
//#region src/core/manifest.ts
|
|
673
|
-
var
|
|
674
|
-
function
|
|
675
|
-
return
|
|
673
|
+
var Ae = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
|
|
674
|
+
function je(e) {
|
|
675
|
+
return Ae.test(e);
|
|
676
676
|
}
|
|
677
677
|
//#endregion
|
|
678
678
|
//#region src/core/env.ts
|
|
679
|
-
var
|
|
679
|
+
var F = {
|
|
680
680
|
integration: "https://feed-dev.oddin-video.gg",
|
|
681
681
|
production: "https://feed.oddin-video.gg"
|
|
682
682
|
};
|
|
683
|
-
function
|
|
684
|
-
let t = Object.prototype.hasOwnProperty.call(
|
|
683
|
+
function I(e) {
|
|
684
|
+
let t = Object.prototype.hasOwnProperty.call(F, e) ? F[e] : void 0;
|
|
685
685
|
if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
|
|
686
686
|
return t;
|
|
687
687
|
}
|
|
688
688
|
//#endregion
|
|
689
689
|
//#region src/core/stats.ts
|
|
690
|
-
var
|
|
691
|
-
function
|
|
690
|
+
var L = { droppedFrames: 0 };
|
|
691
|
+
function R(e) {
|
|
692
692
|
try {
|
|
693
693
|
return new URL(e).host;
|
|
694
694
|
} catch {
|
|
695
695
|
return "";
|
|
696
696
|
}
|
|
697
697
|
}
|
|
698
|
-
var
|
|
699
|
-
function
|
|
698
|
+
var Me = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
|
|
699
|
+
function Ne(e) {
|
|
700
700
|
if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
|
|
701
701
|
let t = "", n = -1, r = performance.getEntriesByType("resource");
|
|
702
|
-
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" ||
|
|
703
|
-
let e =
|
|
702
|
+
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || Me.test(i.name)) && i.startTime >= n) {
|
|
703
|
+
let e = R(i.name);
|
|
704
704
|
e && (t = e, n = i.startTime);
|
|
705
705
|
}
|
|
706
706
|
return t;
|
|
707
707
|
}
|
|
708
|
-
function
|
|
708
|
+
function z(e) {
|
|
709
709
|
let t = e.getVideoPlaybackQuality?.();
|
|
710
710
|
return {
|
|
711
711
|
dropped: t?.droppedVideoFrames ?? 0,
|
|
712
712
|
totalFrames: t?.totalVideoFrames ?? 0
|
|
713
713
|
};
|
|
714
714
|
}
|
|
715
|
-
function
|
|
715
|
+
function Pe(e, t) {
|
|
716
716
|
let n = [
|
|
717
717
|
["playing", () => t("playing")],
|
|
718
718
|
["waiting", () => t("buffering")],
|
|
@@ -729,7 +729,7 @@ function je(e, t) {
|
|
|
729
729
|
}
|
|
730
730
|
//#endregion
|
|
731
731
|
//#region src/core/engine/native.ts
|
|
732
|
-
function
|
|
732
|
+
function Fe(e) {
|
|
733
733
|
try {
|
|
734
734
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
735
735
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -737,15 +737,15 @@ function Me(e) {
|
|
|
737
737
|
return;
|
|
738
738
|
}
|
|
739
739
|
}
|
|
740
|
-
function
|
|
740
|
+
function B(e) {
|
|
741
741
|
return !!(e ?? (typeof document < "u" ? document.createElement("video") : void 0))?.canPlayType("application/vnd.apple.mpegurl");
|
|
742
742
|
}
|
|
743
|
-
function
|
|
743
|
+
function V() {
|
|
744
744
|
if (typeof window > "u") return !1;
|
|
745
745
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
746
746
|
return e || t;
|
|
747
747
|
}
|
|
748
|
-
var
|
|
748
|
+
var H = class {
|
|
749
749
|
name = "native";
|
|
750
750
|
deps;
|
|
751
751
|
onLoaded;
|
|
@@ -781,7 +781,7 @@ var G = class {
|
|
|
781
781
|
type: "error",
|
|
782
782
|
error: new n("INTERNAL", 0, "native HLS playback error"),
|
|
783
783
|
fatal: !0
|
|
784
|
-
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src =
|
|
784
|
+
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = Ie(t.manifestUrl, t.analytics?.sid), e.load();
|
|
785
785
|
}
|
|
786
786
|
startLoad() {
|
|
787
787
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -803,7 +803,7 @@ var G = class {
|
|
|
803
803
|
});
|
|
804
804
|
this.onEncrypted = (n) => {
|
|
805
805
|
let i = n;
|
|
806
|
-
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
806
|
+
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Fe(i.initData), (async () => {
|
|
807
807
|
try {
|
|
808
808
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
809
809
|
initDataTypes: [i.initDataType],
|
|
@@ -898,11 +898,11 @@ var G = class {
|
|
|
898
898
|
e.seekable.length > 0 && (e.currentTime = e.seekable.end(e.seekable.length - 1));
|
|
899
899
|
}
|
|
900
900
|
getStats() {
|
|
901
|
-
let e = this.deps.video, t =
|
|
901
|
+
let e = this.deps.video, t = z(e), n = {
|
|
902
902
|
droppedFrames: t.dropped,
|
|
903
903
|
decodedFrames: t.totalFrames
|
|
904
904
|
};
|
|
905
|
-
return this.cdnHost ||=
|
|
905
|
+
return this.cdnHost ||= Ne(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity && (n.isLive = !0, e.seekable.length > 0 && (n.atLiveEdge = e.currentTime >= e.seekable.end(e.seekable.length - 1) - 2)), n;
|
|
906
906
|
}
|
|
907
907
|
stop() {
|
|
908
908
|
try {
|
|
@@ -921,29 +921,29 @@ var G = class {
|
|
|
921
921
|
} catch {}
|
|
922
922
|
}
|
|
923
923
|
};
|
|
924
|
-
function
|
|
924
|
+
function Ie(e, t) {
|
|
925
925
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
926
926
|
}
|
|
927
927
|
//#endregion
|
|
928
928
|
//#region src/core/engine/hls.ts
|
|
929
|
-
function
|
|
929
|
+
function Le() {
|
|
930
930
|
return e.isSupported();
|
|
931
931
|
}
|
|
932
|
-
var
|
|
933
|
-
function
|
|
932
|
+
var Re = 3, ze = 5, Be = 3, Ve = 3e4, He = 12e3, Ue = 3e3, U = 6e3, We = 5e3, Ge = 4e3, Ke = 2, qe = 5, Je = 2, Ye = 2, Xe = 2e3, Ze = 3e4, Qe = 2, $e = 9, et = .5, tt = 64;
|
|
933
|
+
function nt(e) {
|
|
934
934
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
935
935
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
936
936
|
return;
|
|
937
937
|
}
|
|
938
|
-
e.liveSyncDuration ??=
|
|
939
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
940
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
938
|
+
e.liveSyncDuration ??= Qe;
|
|
939
|
+
let t = Math.max(12, e.liveSyncDuration + $e);
|
|
940
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), rt(e, e.liveSyncDuration);
|
|
941
941
|
}
|
|
942
|
-
function
|
|
942
|
+
function rt(e, t) {
|
|
943
943
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
944
944
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
945
945
|
}
|
|
946
|
-
var
|
|
946
|
+
var W = class {
|
|
947
947
|
name = "hls";
|
|
948
948
|
hls = null;
|
|
949
949
|
deps;
|
|
@@ -1002,7 +1002,7 @@ var q = class {
|
|
|
1002
1002
|
this.deps = e, this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
1003
1003
|
}
|
|
1004
1004
|
async load() {
|
|
1005
|
-
let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a =
|
|
1005
|
+
let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = B(r) && V(), o = !!e.drm?.widevine?.licenseUrl && !a;
|
|
1006
1006
|
if (e.drmEnabled && !o) {
|
|
1007
1007
|
i({
|
|
1008
1008
|
type: "error",
|
|
@@ -1034,7 +1034,7 @@ var q = class {
|
|
|
1034
1034
|
}
|
|
1035
1035
|
this.loadSuspended = !0;
|
|
1036
1036
|
}
|
|
1037
|
-
},
|
|
1037
|
+
}, We));
|
|
1038
1038
|
}
|
|
1039
1039
|
resumeLoading() {
|
|
1040
1040
|
if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
|
|
@@ -1066,7 +1066,7 @@ var q = class {
|
|
|
1066
1066
|
let t = e.liveSyncPosition;
|
|
1067
1067
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1068
1068
|
let { video: n } = this.deps;
|
|
1069
|
-
n.currentTime <= t +
|
|
1069
|
+
n.currentTime <= t + et || (n.currentTime = t);
|
|
1070
1070
|
}
|
|
1071
1071
|
startHls() {
|
|
1072
1072
|
let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
|
|
@@ -1090,7 +1090,7 @@ var q = class {
|
|
|
1090
1090
|
videoEncryptionScheme: "cbcs",
|
|
1091
1091
|
audioEncryptionScheme: "cbcs"
|
|
1092
1092
|
},
|
|
1093
|
-
...M() ? { requestMediaKeySystemAccessFunc:
|
|
1093
|
+
...M() ? { requestMediaKeySystemAccessFunc: Ce(t) } : {},
|
|
1094
1094
|
licenseXhrSetup: (e, t) => {
|
|
1095
1095
|
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;
|
|
1096
1096
|
let o = performance.now();
|
|
@@ -1106,7 +1106,7 @@ var q = class {
|
|
|
1106
1106
|
} } : {},
|
|
1107
1107
|
...c
|
|
1108
1108
|
};
|
|
1109
|
-
|
|
1109
|
+
nt(d), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.loadStarted = d.autoStartLoad !== !1;
|
|
1110
1110
|
let f = new e(d);
|
|
1111
1111
|
this.hls = f, f.on(e.Events.MANIFEST_PARSED, () => {
|
|
1112
1112
|
this.mediaRecoveries = 0, this.networkRecoveries = 0;
|
|
@@ -1115,17 +1115,17 @@ var q = class {
|
|
|
1115
1115
|
}), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1116
1116
|
t?.frag?.type === "main" && (this.kickPending = !1, this.kickTicks = 0, (this.mediaRecoveries > 0 || this.networkRecoveries > 0 || this.licenseRecoveries > 0 || this.starvationKicks > 0 || this.starvationRebuilds > 0) && !this.recoveryResetTimer && (this.recoveryResetTimer = setTimeout(() => {
|
|
1117
1117
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1118
|
-
},
|
|
1118
|
+
}, Ve)));
|
|
1119
1119
|
}), f.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1120
1120
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1121
1121
|
}), f.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
1122
1122
|
let n = t?.frag?.stats, r = n?.loaded;
|
|
1123
1123
|
typeof r == "number" && (this.bytesLoaded += r);
|
|
1124
1124
|
let i = n?.loading;
|
|
1125
|
-
i && i.end > 0 && i.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(i.end - i.start))), this.requestTimesMs.length >
|
|
1125
|
+
i && i.end > 0 && i.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(i.end - i.start))), this.requestTimesMs.length > tt && this.requestTimesMs.shift());
|
|
1126
1126
|
let a = t?.frag?.url;
|
|
1127
1127
|
if (a) {
|
|
1128
|
-
let e =
|
|
1128
|
+
let e = R(a);
|
|
1129
1129
|
e && (this.cdnHost = e);
|
|
1130
1130
|
}
|
|
1131
1131
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1138,7 +1138,7 @@ var q = class {
|
|
|
1138
1138
|
}));
|
|
1139
1139
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1140
1140
|
this.checkEndStale(), this.checkStarvation();
|
|
1141
|
-
},
|
|
1141
|
+
}, Ue), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1142
1142
|
this.renditionSwitches += 1;
|
|
1143
1143
|
let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
|
|
1144
1144
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
|
|
@@ -1202,7 +1202,7 @@ var q = class {
|
|
|
1202
1202
|
return;
|
|
1203
1203
|
}
|
|
1204
1204
|
this.capTimer && clearTimeout(this.capTimer);
|
|
1205
|
-
let t = e > this.sizeCapLevel ?
|
|
1205
|
+
let t = e > this.sizeCapLevel ? Xe : Ze;
|
|
1206
1206
|
this.capTimer = setTimeout(() => {
|
|
1207
1207
|
this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
|
|
1208
1208
|
}, t);
|
|
@@ -1249,7 +1249,7 @@ var q = class {
|
|
|
1249
1249
|
e.widevine && (this.licenseUrl = e.widevine);
|
|
1250
1250
|
}
|
|
1251
1251
|
getStats() {
|
|
1252
|
-
let e = this.hls, t =
|
|
1252
|
+
let e = this.hls, t = z(this.deps.video), n = {
|
|
1253
1253
|
droppedFrames: t.dropped,
|
|
1254
1254
|
decodedFrames: t.totalFrames,
|
|
1255
1255
|
lowLatency: this.detectedLowLatency,
|
|
@@ -1295,7 +1295,7 @@ var q = class {
|
|
|
1295
1295
|
return;
|
|
1296
1296
|
}
|
|
1297
1297
|
let e = Date.now() - this.lastAdvanceMs;
|
|
1298
|
-
!this.chaseSuspended && e >
|
|
1298
|
+
!this.chaseSuspended && e > U && this.suspendChasing(), e > He && this.emitEnded("stalled");
|
|
1299
1299
|
}
|
|
1300
1300
|
checkStarvation() {
|
|
1301
1301
|
let e = this.hls, { video: t } = this.deps;
|
|
@@ -1304,17 +1304,17 @@ var q = class {
|
|
|
1304
1304
|
this.starvedTicks = 0;
|
|
1305
1305
|
return;
|
|
1306
1306
|
}
|
|
1307
|
-
let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs <
|
|
1307
|
+
let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs < U, r = this.lastFragLoadingMs !== 0 && Date.now() - this.lastFragLoadingMs > Ge;
|
|
1308
1308
|
if (!(t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused && n && r)) {
|
|
1309
1309
|
this.starvedTicks = 0;
|
|
1310
1310
|
return;
|
|
1311
1311
|
}
|
|
1312
|
-
if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks <
|
|
1313
|
-
if (this.starvedTicks = 0, this.kickPending && this.kickTicks >=
|
|
1312
|
+
if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks < Ke)) {
|
|
1313
|
+
if (this.starvedTicks = 0, this.kickPending && this.kickTicks >= Je && (this.kickPending = !1, this.kickTicks = 0, this.starvationRebuilds < Ye)) {
|
|
1314
1314
|
this.starvationRebuilds += 1, console.warn("havik-player: restarting the load did not resume video (the wedge is in hls.js state that only a rebuild clears) — rebuilding the player"), this.rebuildInstance("starvation rebuild");
|
|
1315
1315
|
return;
|
|
1316
1316
|
}
|
|
1317
|
-
if (!(this.starvationKicks >=
|
|
1317
|
+
if (!(this.starvationKicks >= qe)) {
|
|
1318
1318
|
this.starvationKicks += 1, this.kickPending = !0, this.kickTicks = 0, console.warn("havik-player: video starved while the live playlist advances (wedged hls.js fragment pipeline) — restarting the load");
|
|
1319
1319
|
try {
|
|
1320
1320
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -1364,7 +1364,7 @@ var q = class {
|
|
|
1364
1364
|
scheduleLicenseRetry(t) {
|
|
1365
1365
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
1366
1366
|
let n = t.response?.code ?? 0;
|
|
1367
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
1367
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Be) return !1;
|
|
1368
1368
|
this.licenseRecoveries += 1;
|
|
1369
1369
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
1370
1370
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -1396,7 +1396,7 @@ var q = class {
|
|
|
1396
1396
|
return;
|
|
1397
1397
|
}
|
|
1398
1398
|
if (t.type === e.ErrorTypes.NETWORK_ERROR) {
|
|
1399
|
-
if (this.networkRecoveries <
|
|
1399
|
+
if (this.networkRecoveries < ze) {
|
|
1400
1400
|
this.networkRecoveries += 1;
|
|
1401
1401
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
1402
1402
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -1413,7 +1413,7 @@ var q = class {
|
|
|
1413
1413
|
return;
|
|
1414
1414
|
}
|
|
1415
1415
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
1416
|
-
if (this.mediaRecoveries <
|
|
1416
|
+
if (this.mediaRecoveries < Re) {
|
|
1417
1417
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
1418
1418
|
return;
|
|
1419
1419
|
}
|
|
@@ -1437,19 +1437,19 @@ var q = class {
|
|
|
1437
1437
|
let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
|
|
1438
1438
|
return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
|
|
1439
1439
|
}
|
|
1440
|
-
},
|
|
1440
|
+
}, it = 15e3, at = 6e5, ot = 3e5, st = 100, G = 1, ct = 1e3, K = 3e4, lt = 1e3, ut = {
|
|
1441
1441
|
inline: "PRESENTATION_INLINE",
|
|
1442
1442
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
1443
1443
|
pip: "PRESENTATION_PIP"
|
|
1444
|
-
},
|
|
1444
|
+
}, dt = {
|
|
1445
1445
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
1446
1446
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
1447
1447
|
none: "KEY_SYSTEM_NONE"
|
|
1448
1448
|
};
|
|
1449
|
-
function
|
|
1449
|
+
function q(e, t) {
|
|
1450
1450
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
1451
1451
|
}
|
|
1452
|
-
var
|
|
1452
|
+
var ft = /* @__PURE__ */ new Set([
|
|
1453
1453
|
"INVALID_URN",
|
|
1454
1454
|
"NOT_FOUND",
|
|
1455
1455
|
"GONE",
|
|
@@ -1459,7 +1459,7 @@ var dt = /* @__PURE__ */ new Set([
|
|
|
1459
1459
|
"FORBIDDEN",
|
|
1460
1460
|
"RATE_LIMITED",
|
|
1461
1461
|
"TIMEOUT"
|
|
1462
|
-
]),
|
|
1462
|
+
]), J = {
|
|
1463
1463
|
idle: "PLAYER_STATE_IDLE",
|
|
1464
1464
|
waiting: "PLAYER_STATE_WAITING",
|
|
1465
1465
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -1469,7 +1469,7 @@ var dt = /* @__PURE__ */ new Set([
|
|
|
1469
1469
|
ended: "PLAYER_STATE_ENDED",
|
|
1470
1470
|
error: "PLAYER_STATE_ERROR"
|
|
1471
1471
|
};
|
|
1472
|
-
function
|
|
1472
|
+
function pt(e) {
|
|
1473
1473
|
try {
|
|
1474
1474
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
1475
1475
|
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);
|
|
@@ -1477,7 +1477,24 @@ function ft(e) {
|
|
|
1477
1477
|
return;
|
|
1478
1478
|
}
|
|
1479
1479
|
}
|
|
1480
|
-
var
|
|
1480
|
+
var Y = /* @__PURE__ */ new Set();
|
|
1481
|
+
function X(e, t) {
|
|
1482
|
+
return Y.has(e) || (Y.add(e), console.warn(`havik-player: ${t}`)), { disabledReason: t };
|
|
1483
|
+
}
|
|
1484
|
+
function mt(e, t) {
|
|
1485
|
+
if (t) return { endpoint: t };
|
|
1486
|
+
if (t !== void 0) return X("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).");
|
|
1487
|
+
let n = pt(e);
|
|
1488
|
+
if (n) return { endpoint: n };
|
|
1489
|
+
let r;
|
|
1490
|
+
try {
|
|
1491
|
+
r = new URL(e).hostname || e;
|
|
1492
|
+
} catch {
|
|
1493
|
+
r = e;
|
|
1494
|
+
}
|
|
1495
|
+
return X(r, `analytics is disabled: no QoE beacons will be sent. The beacons endpoint cannot be derived from the baseUrl host "${r}" — 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).`);
|
|
1496
|
+
}
|
|
1497
|
+
var ht = class {
|
|
1481
1498
|
opts;
|
|
1482
1499
|
url;
|
|
1483
1500
|
now;
|
|
@@ -1555,8 +1572,8 @@ var pt = class {
|
|
|
1555
1572
|
constructor(e) {
|
|
1556
1573
|
this.opts = {
|
|
1557
1574
|
...e,
|
|
1558
|
-
heartbeatMs: e.heartbeatMs ??
|
|
1559
|
-
idleMs: e.idleMs ??
|
|
1575
|
+
heartbeatMs: e.heartbeatMs ?? it,
|
|
1576
|
+
idleMs: e.idleMs ?? at
|
|
1560
1577
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`, this.now = e.now ?? (() => Date.now()), this.bornMs = this.now(), this.presentationSinceMs = this.bornMs, this.startupAnchorMs = this.bornMs;
|
|
1561
1578
|
}
|
|
1562
1579
|
start() {
|
|
@@ -1566,11 +1583,11 @@ var pt = class {
|
|
|
1566
1583
|
sdkVersion: this.opts.sdkVersion,
|
|
1567
1584
|
...this.opts.environment
|
|
1568
1585
|
};
|
|
1569
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
1586
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), ct), 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.onVisibility());
|
|
1570
1587
|
}
|
|
1571
1588
|
checkSuspension(e) {
|
|
1572
1589
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
1573
|
-
let t = Math.max(this.opts.idleMs,
|
|
1590
|
+
let t = Math.max(this.opts.idleMs, ot);
|
|
1574
1591
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
1575
1592
|
}
|
|
1576
1593
|
syncIdle(e) {
|
|
@@ -1584,21 +1601,21 @@ var pt = class {
|
|
|
1584
1601
|
noteStateChange(e, t, n, r) {
|
|
1585
1602
|
if (this.endedFlag || e === t) return;
|
|
1586
1603
|
let i = this.now();
|
|
1587
|
-
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(
|
|
1604
|
+
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(G, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(G, 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") {
|
|
1588
1605
|
this.stallIsSeekInduced = this.seekInduced(i);
|
|
1589
1606
|
let e = !this.isHidden && !this.stallIsSeekInduced;
|
|
1590
|
-
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(
|
|
1607
|
+
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(G, Math.round(this.playingTotalMs)));
|
|
1591
1608
|
} else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
|
|
1592
1609
|
this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
|
|
1593
1610
|
let a = {
|
|
1594
|
-
fromState:
|
|
1595
|
-
toState:
|
|
1596
|
-
presentation:
|
|
1611
|
+
fromState: J[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1612
|
+
toState: J[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1613
|
+
presentation: ut[this.presentation]
|
|
1597
1614
|
}, o = this.causeOf(e, t, i);
|
|
1598
1615
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
1599
1616
|
}
|
|
1600
1617
|
seekInduced(e) {
|
|
1601
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
1618
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < lt;
|
|
1602
1619
|
}
|
|
1603
1620
|
causeOf(e, t, n) {
|
|
1604
1621
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -1635,19 +1652,19 @@ var pt = class {
|
|
|
1635
1652
|
}
|
|
1636
1653
|
this.muteChanges += 1;
|
|
1637
1654
|
let r = this.now();
|
|
1638
|
-
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(
|
|
1655
|
+
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(G, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
|
|
1639
1656
|
}
|
|
1640
1657
|
notePresentation(e) {
|
|
1641
1658
|
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
1642
1659
|
}
|
|
1643
1660
|
notePlayIntent() {
|
|
1644
|
-
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs =
|
|
1661
|
+
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = G), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = G));
|
|
1645
1662
|
}
|
|
1646
1663
|
noteReady() {
|
|
1647
|
-
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(
|
|
1664
|
+
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(G, this.now() - this.startupAnchorMs));
|
|
1648
1665
|
}
|
|
1649
1666
|
noteFirstBytes() {
|
|
1650
|
-
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(
|
|
1667
|
+
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(G, this.now() - this.startupAnchorMs));
|
|
1651
1668
|
}
|
|
1652
1669
|
noteSeek() {
|
|
1653
1670
|
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
@@ -1666,7 +1683,7 @@ var pt = class {
|
|
|
1666
1683
|
let r = n ?? "";
|
|
1667
1684
|
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";
|
|
1668
1685
|
if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
|
|
1669
|
-
if (
|
|
1686
|
+
if (ft.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
1670
1687
|
let i = t ?? "";
|
|
1671
1688
|
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";
|
|
1672
1689
|
}
|
|
@@ -1698,7 +1715,7 @@ var pt = class {
|
|
|
1698
1715
|
let l = t.droppedFrames ?? 0;
|
|
1699
1716
|
l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
|
|
1700
1717
|
let u = t.renditionSwitches ?? 0;
|
|
1701
|
-
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 =
|
|
1718
|
+
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 = J[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
|
|
1702
1719
|
let d = this.mutedTotalMs;
|
|
1703
1720
|
this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
|
|
1704
1721
|
let f = t.upshifts ?? 0;
|
|
@@ -1713,14 +1730,14 @@ var pt = class {
|
|
|
1713
1730
|
if (this.lastRequestCount = g, _ > 0) {
|
|
1714
1731
|
o.requestCountDelta = _;
|
|
1715
1732
|
let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
|
|
1716
|
-
n.length > 0 && (o.requestTimeP50Ms =
|
|
1733
|
+
n.length > 0 && (o.requestTimeP50Ms = q(n, 50), o.requestTimeP95Ms = q(n, 95));
|
|
1717
1734
|
}
|
|
1718
1735
|
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();
|
|
1719
1736
|
}
|
|
1720
1737
|
maybeEmitMediaInfo(e) {
|
|
1721
1738
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
1722
1739
|
let t = {};
|
|
1723
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
1740
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = dt[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);
|
|
1724
1741
|
let n = JSON.stringify(t);
|
|
1725
1742
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
1726
1743
|
}
|
|
@@ -1740,7 +1757,7 @@ var pt = class {
|
|
|
1740
1757
|
let c = r?.positionMs ?? 0;
|
|
1741
1758
|
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));
|
|
1742
1759
|
let l = e !== "END_REASON_ENDED";
|
|
1743
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
1760
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= K && (i.abandonAfterStallMs = Math.max(G, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= K && (i.abandonAfterErrorMs = Math.max(G, 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);
|
|
1744
1761
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
1745
1762
|
u > 0 && (i.decodedFramesTotal = u), this.startupTimeMs === 0 && (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");
|
|
1746
1763
|
}
|
|
@@ -1760,7 +1777,7 @@ var pt = class {
|
|
|
1760
1777
|
};
|
|
1761
1778
|
}
|
|
1762
1779
|
enqueue(e) {
|
|
1763
|
-
for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
1780
|
+
for (this.pending.push(this.wrap(e)); this.pending.length > st;) {
|
|
1764
1781
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
1765
1782
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
1766
1783
|
}
|
|
@@ -1783,7 +1800,7 @@ var pt = class {
|
|
|
1783
1800
|
};
|
|
1784
1801
|
//#endregion
|
|
1785
1802
|
//#region src/core/environment.ts
|
|
1786
|
-
function
|
|
1803
|
+
function gt() {
|
|
1787
1804
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
1788
1805
|
let e;
|
|
1789
1806
|
try {
|
|
@@ -1808,14 +1825,14 @@ function mt() {
|
|
|
1808
1825
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
1809
1826
|
};
|
|
1810
1827
|
}
|
|
1811
|
-
function
|
|
1828
|
+
function _t() {
|
|
1812
1829
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
1813
1830
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
1814
1831
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
1815
1832
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
1816
1833
|
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";
|
|
1817
1834
|
}
|
|
1818
|
-
function
|
|
1835
|
+
function vt() {
|
|
1819
1836
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
1820
1837
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
1821
1838
|
let t = {
|
|
@@ -1834,17 +1851,17 @@ function gt() {
|
|
|
1834
1851
|
}
|
|
1835
1852
|
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;
|
|
1836
1853
|
}
|
|
1837
|
-
function
|
|
1838
|
-
let t =
|
|
1839
|
-
deviceClass:
|
|
1854
|
+
function yt(e) {
|
|
1855
|
+
let t = gt(), n = {
|
|
1856
|
+
deviceClass: _t(),
|
|
1840
1857
|
integration: t.integration,
|
|
1841
|
-
...
|
|
1858
|
+
...vt()
|
|
1842
1859
|
};
|
|
1843
1860
|
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);
|
|
1844
1861
|
let r = e.getBoundingClientRect?.();
|
|
1845
1862
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
1846
1863
|
}
|
|
1847
|
-
async function
|
|
1864
|
+
async function bt() {
|
|
1848
1865
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
1849
1866
|
if (!e?.getHighEntropyValues) return {};
|
|
1850
1867
|
try {
|
|
@@ -1856,7 +1873,7 @@ async function vt() {
|
|
|
1856
1873
|
}
|
|
1857
1874
|
//#endregion
|
|
1858
1875
|
//#region src/core/version.ts
|
|
1859
|
-
var
|
|
1876
|
+
var xt = "2.9.1", St = {
|
|
1860
1877
|
accent: "#E1B600",
|
|
1861
1878
|
accentText: "#1B1C23",
|
|
1862
1879
|
background: "#0e0f13",
|
|
@@ -1867,7 +1884,7 @@ var yt = "2.8.0", bt = {
|
|
|
1867
1884
|
border: "rgba(255, 255, 255, 0.1)",
|
|
1868
1885
|
radius: "8px",
|
|
1869
1886
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
1870
|
-
},
|
|
1887
|
+
}, Ct = {
|
|
1871
1888
|
accent: "--havik-accent",
|
|
1872
1889
|
accentText: "--havik-accent-text",
|
|
1873
1890
|
background: "--havik-bg",
|
|
@@ -1879,25 +1896,25 @@ var yt = "2.8.0", bt = {
|
|
|
1879
1896
|
radius: "--havik-radius",
|
|
1880
1897
|
fontFamily: "--havik-font"
|
|
1881
1898
|
};
|
|
1882
|
-
function
|
|
1899
|
+
function wt(e, t) {
|
|
1883
1900
|
let n = {
|
|
1884
|
-
...
|
|
1901
|
+
...St,
|
|
1885
1902
|
...t
|
|
1886
1903
|
};
|
|
1887
|
-
for (let t of Object.keys(
|
|
1904
|
+
for (let t of Object.keys(Ct)) e.style.setProperty(Ct[t], n[t]);
|
|
1888
1905
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
1889
1906
|
}
|
|
1890
1907
|
//#endregion
|
|
1891
1908
|
//#region src/ui/styles.ts
|
|
1892
|
-
var
|
|
1893
|
-
function
|
|
1894
|
-
if (e.getElementById(
|
|
1909
|
+
var Tt = "havik-player-styles", Et = "\n.havik-player{position:relative;display:block;width:100%;background:var(--havik-bg,#0e0f13);\n color:var(--havik-text,#fff);font-family:var(--havik-font,system-ui,sans-serif);\n overflow:hidden;line-height:1.4;-webkit-tap-highlight-color:transparent}\n.havik-player video{display:block;width:100%;height:auto;aspect-ratio:16/9;\n object-fit:contain;background:#000;outline:none}\n.havik-player:focus{outline:none}\n.havik-player *{box-sizing:border-box}\n\n.havik-player:fullscreen,.havik-player:-webkit-full-screen{display:flex;align-items:center;\n justify-content:center;width:100vw;height:100vh;aspect-ratio:auto}\n.havik-player:fullscreen video,.havik-player:-webkit-full-screen video{width:100%;height:100%;\n aspect-ratio:auto;object-fit:contain}\n\n.havik-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer}\n.havik-gradient{position:absolute;left:0;right:0;bottom:0;height:120px;pointer-events:none;\n background:linear-gradient(to top,rgba(0,0,0,.78),transparent);\n opacity:1;transition:opacity .25s}\n.havik-player.havik-hide .havik-gradient,\n.havik-player.havik-hide .havik-bar{opacity:0;pointer-events:none}\n.havik-player.havik-hide{cursor:none}\n\n.havik-center{width:74px;height:74px;border-radius:50%;border:0;cursor:pointer;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);\n display:flex;align-items:center;justify-content:center;\n box-shadow:0 6px 24px rgba(0,0,0,.45);transition:transform .15s,opacity .15s}\n.havik-center:hover{transform:scale(1.06)}\n.havik-center svg{width:38px;height:38px;margin-left:2px}\n.havik-center.havik-gone{opacity:0;pointer-events:none;transform:scale(.8)}\n\n.havik-spinner{width:56px;height:56px;border-radius:50%;\n border:4px solid rgba(255,255,255,.2);border-top-color:var(--havik-accent,#E1B600);\n animation:havik-spin .8s linear infinite}\n@keyframes havik-spin{to{transform:rotate(360deg)}}\n\n/* Status card — branded full-bleed overlay for the stopped/pre-play states\n (ended / fatal error / pre-play / armed-waiting). */\n.havik-status{position:absolute;inset:0;display:flex;flex-direction:column;gap:16px;\n align-items:center;justify-content:center;background:rgba(14,15,19,.82);text-align:center;padding:24px}\n.havik-status__logo{width:128px;height:46px;background:var(--havik-logo) center/contain no-repeat;opacity:.95}\n.havik-status__msg{color:var(--havik-text,#fff);font-size:15px;font-weight:600;max-width:480px}\n.havik-status__btn{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;\n padding:10px 18px;border-radius:var(--havik-radius,8px);font-weight:700;font-size:14px;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);transition:transform .15s}\n.havik-status__btn:hover{transform:scale(1.04)}\n.havik-status__btn svg{width:18px;height:18px}\n/* Pre-play: lighter scrim so the poster shows through, and a round play CTA. */\n.havik-status--preplay{background:rgba(14,15,19,.4)}\n.havik-status--preplay .havik-status__btn--play{width:74px;height:74px;border-radius:50%;padding:0;\n justify-content:center;box-shadow:0 6px 24px rgba(0,0,0,.45)}\n.havik-status--preplay .havik-status__btn--play svg{width:38px;height:38px;margin-left:3px}\n\n.havik-watermark{position:absolute;top:12px;right:14px;height:22px;opacity:.85;pointer-events:none;\n content:'';background:var(--havik-logo) center/contain no-repeat;width:90px}\n/* A status card carries its own logo — the corner watermark would duplicate it. */\n.havik-player.havik-has-status .havik-watermark{display:none}\n\n.havik-bar{position:absolute;left:0;right:0;bottom:0;padding:0 12px 8px;\n opacity:1;transition:opacity .25s;z-index:2}\n.havik-seek{position:relative;height:16px;display:flex;align-items:center;cursor:pointer;margin-bottom:2px}\n.havik-seek__track{position:relative;width:100%;height:4px;border-radius:3px;background:rgba(255,255,255,.25)}\n.havik-seek__buffered{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:rgba(255,255,255,.4)}\n.havik-seek__played{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-seek__thumb{position:absolute;top:50%;width:13px;height:13px;border-radius:50%;\n background:var(--havik-accent,#E1B600);transform:translate(-50%,-50%) scale(0);transition:transform .1s}\n.havik-seek:hover .havik-seek__thumb{transform:translate(-50%,-50%) scale(1)}\n\n.havik-controls{display:flex;align-items:center;gap:6px;height:40px}\n.havik-spacer{flex:1}\n.havik-btn{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;border-radius:var(--havik-radius,8px);\n padding:0;transition:background .12s,color .12s}\n.havik-btn:hover{background:rgba(255,255,255,.12)}\n.havik-btn:focus-visible{outline:2px solid var(--havik-accent,#E1B600);outline-offset:1px}\n.havik-btn svg{width:22px;height:22px}\n\n/* The volume level is filled in accent up to the thumb, like the seek bar's\n played span — a native range input paints no \"elapsed\" side, which left the\n level readable only from the dot's position. --havik-vol (0..1) is set by\n syncVolume(); the track width and thumb size live here as variables because\n the WebKit fill has to compute the thumb centre from both. */\n.havik-vol{display:flex;align-items:center}\n.havik-vol__slider{--havik-vol-w:70px;--havik-vol-thumb:12px;--havik-vol:1;\n --havik-vol-pos:calc(var(--havik-vol-thumb) / 2 + var(--havik-vol) * (var(--havik-vol-w) - var(--havik-vol-thumb)));\n width:0;opacity:0;transition:width .18s,opacity .18s;height:4px;cursor:pointer;\n appearance:none;-webkit-appearance:none;background:transparent;border-radius:3px;margin:0 4px}\n.havik-vol:hover .havik-vol__slider,.havik-vol:focus-within .havik-vol__slider{width:var(--havik-vol-w);opacity:1}\n/* WebKit/Blink have no progress pseudo-element: paint the fill as a hard-stop\n gradient that ends at the thumb centre. */\n.havik-vol__slider::-webkit-slider-runnable-track{height:4px;border-radius:3px;\n background:linear-gradient(to right,var(--havik-accent,#E1B600) var(--havik-vol-pos),\n rgba(255,255,255,.3) var(--havik-vol-pos))}\n/* Firefox fills natively, and tracks the thumb exactly. */\n.havik-vol__slider::-moz-range-track{height:4px;border-radius:3px;background:rgba(255,255,255,.3)}\n.havik-vol__slider::-moz-range-progress{height:4px;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-vol__slider::-webkit-slider-thumb{-webkit-appearance:none;width:var(--havik-vol-thumb);\n height:var(--havik-vol-thumb);border-radius:50%;background:var(--havik-accent,#E1B600);\n margin-top:calc((4px - var(--havik-vol-thumb)) / 2)}\n.havik-vol__slider::-moz-range-thumb{width:var(--havik-vol-thumb);height:var(--havik-vol-thumb);\n border:0;border-radius:50%;background:var(--havik-accent,#E1B600)}\n\n.havik-time{font-size:12px;color:var(--havik-text-muted,#9aa0ad);\n font-variant-numeric:tabular-nums;padding:0 6px;white-space:nowrap}\n.havik-live{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;\n letter-spacing:.4px;padding:0 8px;color:var(--havik-text,#fff)}\n.havik-live svg{width:9px;height:9px;color:var(--havik-text-muted,#9aa0ad)}\n.havik-live.is-live svg{color:var(--havik-accent,#E1B600)}\n.havik-live__go{margin-left:2px;border:0;cursor:pointer;background:transparent;color:var(--havik-text-muted,#9aa0ad);\n font:inherit;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 6px;border-radius:6px}\n.havik-live.is-live .havik-live__go{display:none}\n.havik-live__go:hover{color:var(--havik-accent,#E1B600)}\n\n.havik-menu{position:absolute;bottom:54px;right:12px;min-width:170px;max-height:230px;overflow:auto;\n background:var(--havik-surface,#1B1C23);border:1px solid var(--havik-border,rgba(255,255,255,.1));\n border-radius:var(--havik-radius,8px);box-shadow:0 10px 30px rgba(0,0,0,.5);padding:6px;z-index:3}\n.havik-menu[hidden]{display:none}\n.havik-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;\n color:var(--havik-text-muted,#9aa0ad);padding:6px 8px 4px}\n.havik-menu__item{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;font:inherit;font-size:13px;\n text-align:left;padding:7px 8px;border-radius:6px}\n.havik-menu__item:hover{background:var(--havik-surface-muted,#2a2c36)}\n.havik-menu__item[aria-checked=\"true\"]{color:var(--havik-accent,#E1B600);font-weight:600}\n.havik-menu__item[aria-checked=\"true\"]::after{content:'✓'}\n";
|
|
1910
|
+
function Dt(e = document) {
|
|
1911
|
+
if (e.getElementById(Tt)) return;
|
|
1895
1912
|
let t = e.createElement("style");
|
|
1896
|
-
t.id =
|
|
1913
|
+
t.id = Tt, t.textContent = Et, e.head.appendChild(t);
|
|
1897
1914
|
}
|
|
1898
1915
|
//#endregion
|
|
1899
1916
|
//#region src/ui/icons.ts
|
|
1900
|
-
var
|
|
1917
|
+
var Ot = {
|
|
1901
1918
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
1902
1919
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
1903
1920
|
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\"/>",
|
|
@@ -1910,21 +1927,21 @@ var Et = {
|
|
|
1910
1927
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
1911
1928
|
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\"/>"
|
|
1912
1929
|
};
|
|
1913
|
-
function
|
|
1914
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
1930
|
+
function Z(e) {
|
|
1931
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Ot[e]}</svg>`;
|
|
1915
1932
|
}
|
|
1916
1933
|
//#endregion
|
|
1917
1934
|
//#region src/ui/controls.ts
|
|
1918
|
-
var
|
|
1935
|
+
var kt = 3e3, At = /* @__PURE__ */ new Set([
|
|
1919
1936
|
"GONE",
|
|
1920
1937
|
"NOT_FOUND",
|
|
1921
1938
|
"INVALID_URN",
|
|
1922
1939
|
"UNAUTHORIZED"
|
|
1923
1940
|
]);
|
|
1924
|
-
function
|
|
1925
|
-
return new
|
|
1941
|
+
function jt(e) {
|
|
1942
|
+
return new Mt(e);
|
|
1926
1943
|
}
|
|
1927
|
-
var
|
|
1944
|
+
var Mt = class {
|
|
1928
1945
|
root;
|
|
1929
1946
|
video;
|
|
1930
1947
|
player;
|
|
@@ -1966,7 +1983,7 @@ var At = class {
|
|
|
1966
1983
|
scrubbing = !1;
|
|
1967
1984
|
offFns = [];
|
|
1968
1985
|
constructor(e) {
|
|
1969
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
1986
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? kt, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, Dt(this.doc), this.root.classList.add("havik-player"), this.root.hasAttribute("tabindex") || (this.root.tabIndex = 0), this.root.setAttribute("role", "region"), this.root.setAttribute("aria-label", "Video player");
|
|
1970
1987
|
let t = (e, t, n) => {
|
|
1971
1988
|
let r = this.doc.createElement(e);
|
|
1972
1989
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -1977,12 +1994,12 @@ var At = class {
|
|
|
1977
1994
|
"aria-label": r,
|
|
1978
1995
|
title: r
|
|
1979
1996
|
});
|
|
1980
|
-
return i.innerHTML =
|
|
1997
|
+
return i.innerHTML = Z(n), i;
|
|
1981
1998
|
};
|
|
1982
1999
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
1983
2000
|
type: "button",
|
|
1984
2001
|
"aria-label": "Play"
|
|
1985
|
-
}), this.center.innerHTML =
|
|
2002
|
+
}), this.center.innerHTML = Z("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", {
|
|
1986
2003
|
role: "slider",
|
|
1987
2004
|
"aria-label": "Seek",
|
|
1988
2005
|
"aria-valuemin": "0",
|
|
@@ -2000,7 +2017,7 @@ var At = class {
|
|
|
2000
2017
|
"aria-label": "Volume"
|
|
2001
2018
|
});
|
|
2002
2019
|
let a = t("div", "havik-vol");
|
|
2003
|
-
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML =
|
|
2020
|
+
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Z("liveDot");
|
|
2004
2021
|
let o = this.doc.createElement("span");
|
|
2005
2022
|
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";
|
|
2006
2023
|
let s = t("div", "havik-spacer");
|
|
@@ -2054,12 +2071,12 @@ var At = class {
|
|
|
2054
2071
|
}
|
|
2055
2072
|
if (e === "preplay") {
|
|
2056
2073
|
let e = this.doc.createElement("button");
|
|
2057
|
-
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML =
|
|
2074
|
+
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = Z("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
|
|
2058
2075
|
} else {
|
|
2059
2076
|
let r = this.doc.createElement("div");
|
|
2060
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
2077
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !At.has(this.lastError.code)) {
|
|
2061
2078
|
let e = this.doc.createElement("button");
|
|
2062
|
-
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${
|
|
2079
|
+
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${Z("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
|
|
2063
2080
|
}
|
|
2064
2081
|
}
|
|
2065
2082
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -2098,7 +2115,7 @@ var At = class {
|
|
|
2098
2115
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
2099
2116
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
2100
2117
|
}
|
|
2101
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
2118
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Nt(this.video.currentTime)} / ${Nt(this.video.duration)}`);
|
|
2102
2119
|
}
|
|
2103
2120
|
syncLive() {
|
|
2104
2121
|
let e = this.player.getStats(), t = e.isLive !== !1;
|
|
@@ -2148,17 +2165,17 @@ var At = class {
|
|
|
2148
2165
|
renderQualityMenu() {
|
|
2149
2166
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
2150
2167
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
2151
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
2168
|
+
for (let n of e) this.menu.append(this.menuItem(Pt(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
2152
2169
|
}
|
|
2153
2170
|
renderAudioMenu() {
|
|
2154
2171
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
2155
2172
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
2156
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2173
|
+
for (let t of e) this.menu.append(this.menuItem(Ft(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
2157
2174
|
}
|
|
2158
2175
|
renderCcMenu() {
|
|
2159
2176
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
2160
2177
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
2161
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2178
|
+
for (let t of e) this.menu.append(this.menuItem(It(t), !1, () => this.player.setTextTrack(t.id)));
|
|
2162
2179
|
}
|
|
2163
2180
|
onTracksChanged() {
|
|
2164
2181
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -2241,7 +2258,7 @@ var At = class {
|
|
|
2241
2258
|
}
|
|
2242
2259
|
}
|
|
2243
2260
|
setIcon(e, t) {
|
|
2244
|
-
e.innerHTML =
|
|
2261
|
+
e.innerHTML = Z(t);
|
|
2245
2262
|
}
|
|
2246
2263
|
destroy() {
|
|
2247
2264
|
this.hideTimer && clearTimeout(this.hideTimer);
|
|
@@ -2258,41 +2275,41 @@ var At = class {
|
|
|
2258
2275
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
2259
2276
|
}
|
|
2260
2277
|
};
|
|
2261
|
-
function
|
|
2278
|
+
function Nt(e) {
|
|
2262
2279
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
2263
2280
|
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");
|
|
2264
2281
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
2265
2282
|
}
|
|
2266
|
-
function
|
|
2283
|
+
function Pt(e) {
|
|
2267
2284
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
2268
2285
|
}
|
|
2269
|
-
function
|
|
2286
|
+
function Ft(e) {
|
|
2270
2287
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2271
2288
|
}
|
|
2272
|
-
function
|
|
2289
|
+
function It(e) {
|
|
2273
2290
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2274
2291
|
}
|
|
2275
2292
|
//#endregion
|
|
2276
2293
|
//#region src/managed/index.ts
|
|
2277
|
-
var
|
|
2278
|
-
function
|
|
2294
|
+
var Lt = 6e3, Q = 45e3, Rt = 2e3, zt = 3, Bt = 2e3, Vt = 48e4;
|
|
2295
|
+
function Ht(e) {
|
|
2279
2296
|
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)})`);
|
|
2280
|
-
if (e.env !== void 0) return
|
|
2297
|
+
if (e.env !== void 0) return I(e.env);
|
|
2281
2298
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
2282
2299
|
return e.baseUrl;
|
|
2283
2300
|
}
|
|
2284
|
-
async function
|
|
2301
|
+
async function Ut(e) {
|
|
2285
2302
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
2286
|
-
let t =
|
|
2303
|
+
let t = Ht(e);
|
|
2287
2304
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
2288
2305
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
2289
|
-
let r = new
|
|
2306
|
+
let r = new Wt({
|
|
2290
2307
|
...e,
|
|
2291
2308
|
baseUrl: t
|
|
2292
2309
|
});
|
|
2293
2310
|
return await r.start(), r;
|
|
2294
2311
|
}
|
|
2295
|
-
var
|
|
2312
|
+
var Wt = class {
|
|
2296
2313
|
opts;
|
|
2297
2314
|
abort = new AbortController();
|
|
2298
2315
|
listeners = {};
|
|
@@ -2380,7 +2397,7 @@ var Vt = class {
|
|
|
2380
2397
|
setTimeout(() => {
|
|
2381
2398
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
2382
2399
|
phase: i ? "unavailable" : "tooEarly",
|
|
2383
|
-
retryInMs:
|
|
2400
|
+
retryInMs: Q,
|
|
2384
2401
|
attempt: 1,
|
|
2385
2402
|
elapsedMs: 0,
|
|
2386
2403
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -2419,13 +2436,13 @@ var Vt = class {
|
|
|
2419
2436
|
!a && !p() && h();
|
|
2420
2437
|
}, e);
|
|
2421
2438
|
};
|
|
2422
|
-
_(
|
|
2439
|
+
_(Lt), this.armingSub = E({
|
|
2423
2440
|
eventsBaseUrl: t,
|
|
2424
2441
|
matchUrn: this.opts.matchUrn,
|
|
2425
2442
|
credential: this.opts.credential,
|
|
2426
|
-
onAlive: () => _(
|
|
2443
|
+
onAlive: () => _(Q),
|
|
2427
2444
|
onState: (e) => {
|
|
2428
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
2445
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Rt);
|
|
2429
2446
|
},
|
|
2430
2447
|
onError: () => h()
|
|
2431
2448
|
});
|
|
@@ -2448,7 +2465,7 @@ var Vt = class {
|
|
|
2448
2465
|
let n = await s(this.opts.credential);
|
|
2449
2466
|
if (this.destroyed || t !== this.loadGen) return;
|
|
2450
2467
|
this.setState("loading");
|
|
2451
|
-
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a =
|
|
2468
|
+
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = Pe(this.opts.video, (e) => {
|
|
2452
2469
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
2453
2470
|
});
|
|
2454
2471
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -2459,43 +2476,48 @@ var Vt = class {
|
|
|
2459
2476
|
a(), i.destroy();
|
|
2460
2477
|
return;
|
|
2461
2478
|
}
|
|
2462
|
-
this.engine = i, this.detachMedia = a, this.opts.maxBitrate != null && i.setMaxBitrate(this.opts.maxBitrate), this.startStats(), this.scheduleLicenseRefresh(), this.startLiveState(t), this.startAnalytics(e, i), r && (this.pendingStartLoad = !0, this.setState("paused"), i.name === "native" && setTimeout(() => {
|
|
2479
|
+
this.engine = i, this.detachMedia = a, this.opts.maxBitrate != null && i.setMaxBitrate(this.opts.maxBitrate), this.startStats(), this.scheduleLicenseRefresh(), this.startLiveState(t), this.startAnalytics(e, i, t), r && (this.pendingStartLoad = !0, this.setState("paused"), i.name === "native" && setTimeout(() => {
|
|
2463
2480
|
this.destroyed || t !== this.loadGen || this.engine !== i || (this.analyticsSession?.noteReady(), this.emit("ready"));
|
|
2464
2481
|
}, 0));
|
|
2465
2482
|
}
|
|
2466
2483
|
onAnalyticsIdle(e) {
|
|
2467
2484
|
this.destroyed || this.engine !== e || (this.idleClosed = !0, this.pendingStartLoad = !1, e.stop());
|
|
2468
2485
|
}
|
|
2469
|
-
startAnalytics(e, t) {
|
|
2486
|
+
startAnalytics(e, t, r) {
|
|
2470
2487
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
2471
|
-
let
|
|
2472
|
-
if (!
|
|
2473
|
-
let
|
|
2474
|
-
if (!
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2488
|
+
let i = e.analytics?.sid;
|
|
2489
|
+
if (!i) return;
|
|
2490
|
+
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = mt(this.opts.baseUrl, a);
|
|
2491
|
+
if (!o) {
|
|
2492
|
+
s && setTimeout(() => {
|
|
2493
|
+
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
|
|
2494
|
+
}, 0);
|
|
2495
|
+
return;
|
|
2496
|
+
}
|
|
2497
|
+
let c = this.opts.video, l = new ht({
|
|
2498
|
+
endpoint: o,
|
|
2499
|
+
sid: i,
|
|
2478
2500
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
2479
|
-
sdkVersion:
|
|
2480
|
-
environment:
|
|
2501
|
+
sdkVersion: xt,
|
|
2502
|
+
environment: yt(c),
|
|
2481
2503
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
2482
2504
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
2483
2505
|
sample: () => {
|
|
2484
|
-
let e = this.engine?.getStats() ??
|
|
2506
|
+
let e = this.engine?.getStats() ?? L, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
|
|
2485
2507
|
return {
|
|
2486
2508
|
...e,
|
|
2487
2509
|
bufferedMs: Math.round(t * 1e3),
|
|
2488
2510
|
state: this._state,
|
|
2489
|
-
positionMs: Math.round(
|
|
2490
|
-
playbackRate:
|
|
2511
|
+
positionMs: Math.round(c.currentTime * 1e3),
|
|
2512
|
+
playbackRate: c.playbackRate
|
|
2491
2513
|
};
|
|
2492
2514
|
}
|
|
2493
2515
|
});
|
|
2494
|
-
this.analyticsSession =
|
|
2495
|
-
let
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
},
|
|
2516
|
+
this.analyticsSession = l;
|
|
2517
|
+
let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
|
|
2518
|
+
c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
|
|
2519
|
+
c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
|
|
2520
|
+
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), bt().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
2499
2521
|
}
|
|
2500
2522
|
currentPresentation() {
|
|
2501
2523
|
let e = this.opts.video;
|
|
@@ -2519,11 +2541,11 @@ var Vt = class {
|
|
|
2519
2541
|
hlsConfig: i,
|
|
2520
2542
|
emit: (e) => this.onEngineEvent(e)
|
|
2521
2543
|
}, o = this.opts.engine ?? "auto";
|
|
2522
|
-
if (o === "native") return new
|
|
2523
|
-
if (o === "hls") return new
|
|
2524
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl &&
|
|
2525
|
-
if (
|
|
2526
|
-
if (
|
|
2544
|
+
if (o === "native") return new H(a);
|
|
2545
|
+
if (o === "hls") return new W(a);
|
|
2546
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && B(this.opts.video) && V()) return new H(a);
|
|
2547
|
+
if (Le()) return new W(a);
|
|
2548
|
+
if (B(this.opts.video)) return new H(a);
|
|
2527
2549
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
2528
2550
|
}
|
|
2529
2551
|
onEngineEvent(e) {
|
|
@@ -2566,7 +2588,7 @@ var Vt = class {
|
|
|
2566
2588
|
r = 0, i = !1;
|
|
2567
2589
|
},
|
|
2568
2590
|
onError: () => {
|
|
2569
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
2591
|
+
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= zt && (i = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${r} attempts — end-of-stream detection degraded to the HLS staleness watchdog. Check the events host, the api-key's allowed origins, and CSP connect-src.`))));
|
|
2570
2592
|
}
|
|
2571
2593
|
});
|
|
2572
2594
|
}
|
|
@@ -2588,7 +2610,7 @@ var Vt = class {
|
|
|
2588
2610
|
scheduleRejoin(e) {
|
|
2589
2611
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
2590
2612
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
2591
|
-
}, Math.random() *
|
|
2613
|
+
}, Math.random() * Rt));
|
|
2592
2614
|
}
|
|
2593
2615
|
cancelRejoin() {
|
|
2594
2616
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -2612,7 +2634,7 @@ var Vt = class {
|
|
|
2612
2634
|
}
|
|
2613
2635
|
t.controls = !1;
|
|
2614
2636
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
2615
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
2637
|
+
r && r.insertBefore(n, t), n.appendChild(t), wt(n, this.opts.theme), this.container = n, this.controlBar = jt({
|
|
2616
2638
|
root: n,
|
|
2617
2639
|
video: t,
|
|
2618
2640
|
player: this,
|
|
@@ -2642,7 +2664,7 @@ var Vt = class {
|
|
|
2642
2664
|
}
|
|
2643
2665
|
startStats() {
|
|
2644
2666
|
this.stopStats();
|
|
2645
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
2667
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Bt);
|
|
2646
2668
|
this.statsTimer = setInterval(() => {
|
|
2647
2669
|
if (!this.engine) return;
|
|
2648
2670
|
let e = this.engine.getStats();
|
|
@@ -2654,7 +2676,7 @@ var Vt = class {
|
|
|
2654
2676
|
}
|
|
2655
2677
|
scheduleLicenseRefresh() {
|
|
2656
2678
|
this.stopRefresh();
|
|
2657
|
-
let e = this.opts.licenseRefreshMs ??
|
|
2679
|
+
let e = this.opts.licenseRefreshMs ?? Vt;
|
|
2658
2680
|
e && this._descriptor?.drmEnabled && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
2659
2681
|
}
|
|
2660
2682
|
stopRefresh() {
|
|
@@ -2699,7 +2721,7 @@ var Vt = class {
|
|
|
2699
2721
|
this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
|
|
2700
2722
|
}
|
|
2701
2723
|
getStats() {
|
|
2702
|
-
return this.engine?.getStats() ??
|
|
2724
|
+
return this.engine?.getStats() ?? L;
|
|
2703
2725
|
}
|
|
2704
2726
|
getQualityLevels() {
|
|
2705
2727
|
return this.engine?.getQualityLevels() ?? [];
|
|
@@ -2809,7 +2831,7 @@ function $(e) {
|
|
|
2809
2831
|
}
|
|
2810
2832
|
//#endregion
|
|
2811
2833
|
//#region src/embed/host.ts
|
|
2812
|
-
function
|
|
2834
|
+
function Gt(e) {
|
|
2813
2835
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
2814
2836
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
2815
2837
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -2868,8 +2890,15 @@ function Ht(e) {
|
|
|
2868
2890
|
}
|
|
2869
2891
|
//#endregion
|
|
2870
2892
|
//#region src/embed/page.ts
|
|
2871
|
-
var
|
|
2872
|
-
function
|
|
2893
|
+
var Kt = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
2894
|
+
function qt(e) {
|
|
2895
|
+
if (typeof e == "boolean") return e;
|
|
2896
|
+
if (typeof e == "object" && e) {
|
|
2897
|
+
let t = e.endpoint;
|
|
2898
|
+
return typeof t == "string" ? { endpoint: t } : {};
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
function Jt() {
|
|
2873
2902
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
2874
2903
|
if (e) return {
|
|
2875
2904
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -2878,7 +2907,8 @@ function Wt() {
|
|
|
2878
2907
|
parentOrigin: e.parentOrigin,
|
|
2879
2908
|
autoplay: e.autoplay ?? !0,
|
|
2880
2909
|
muted: e.muted ?? !0,
|
|
2881
|
-
waitForLive: e.waitForLive ?? !0
|
|
2910
|
+
waitForLive: e.waitForLive ?? !0,
|
|
2911
|
+
analytics: qt(e.analytics)
|
|
2882
2912
|
};
|
|
2883
2913
|
let t = new URLSearchParams(location.search);
|
|
2884
2914
|
return {
|
|
@@ -2891,9 +2921,9 @@ function Wt() {
|
|
|
2891
2921
|
waitForLive: !0
|
|
2892
2922
|
};
|
|
2893
2923
|
}
|
|
2894
|
-
async function
|
|
2895
|
-
let e =
|
|
2896
|
-
|
|
2924
|
+
async function Yt() {
|
|
2925
|
+
let e = Jt();
|
|
2926
|
+
Zt();
|
|
2897
2927
|
let t = document.createElement("video");
|
|
2898
2928
|
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);
|
|
2899
2929
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -2948,19 +2978,20 @@ async function Gt() {
|
|
|
2948
2978
|
code: e.code,
|
|
2949
2979
|
message: e.message
|
|
2950
2980
|
})), e.on("autoplayblocked", () => {
|
|
2951
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
2981
|
+
i({ type: "oddin:autoplayblocked" }), Xt(t, e);
|
|
2952
2982
|
});
|
|
2953
2983
|
}, s = async (r) => {
|
|
2954
2984
|
a?.destroy(), a = null;
|
|
2955
2985
|
try {
|
|
2956
|
-
let n = await
|
|
2986
|
+
let n = await Ut({
|
|
2957
2987
|
video: t,
|
|
2958
2988
|
baseUrl: e.baseUrl,
|
|
2959
2989
|
matchUrn: r,
|
|
2960
2990
|
credential: { apiKey: e.apiKey },
|
|
2961
2991
|
autoplay: e.autoplay,
|
|
2962
2992
|
muted: e.muted,
|
|
2963
|
-
waitForLive: e.waitForLive
|
|
2993
|
+
waitForLive: e.waitForLive,
|
|
2994
|
+
analytics: e.analytics
|
|
2964
2995
|
});
|
|
2965
2996
|
a = n;
|
|
2966
2997
|
let i = t.parentElement;
|
|
@@ -3014,7 +3045,7 @@ async function Gt() {
|
|
|
3014
3045
|
a?.retry();
|
|
3015
3046
|
break;
|
|
3016
3047
|
case "oddin:load":
|
|
3017
|
-
typeof e.matchUrn == "string" &&
|
|
3048
|
+
typeof e.matchUrn == "string" && Kt.test(e.matchUrn) && s(e.matchUrn);
|
|
3018
3049
|
break;
|
|
3019
3050
|
case "oddin:destroy": c();
|
|
3020
3051
|
}
|
|
@@ -3026,18 +3057,18 @@ async function Gt() {
|
|
|
3026
3057
|
protocol: 1
|
|
3027
3058
|
});
|
|
3028
3059
|
}
|
|
3029
|
-
function
|
|
3060
|
+
function Xt(e, t) {
|
|
3030
3061
|
if (document.getElementById("havik-tap")) return;
|
|
3031
3062
|
let n = document.createElement("button");
|
|
3032
3063
|
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", () => {
|
|
3033
3064
|
n.remove(), t.play();
|
|
3034
3065
|
}), document.body.appendChild(n);
|
|
3035
3066
|
}
|
|
3036
|
-
function
|
|
3067
|
+
function Zt() {
|
|
3037
3068
|
let e = document.createElement("style");
|
|
3038
3069
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
3039
3070
|
}
|
|
3040
3071
|
//#endregion
|
|
3041
|
-
export {
|
|
3072
|
+
export { St as ODDIN_THEME, n as PlaybackError, wt as applyTheme, I as baseUrlForEnv, Yt as bootEmbed, _e as clearDeviceId, Ut as createPlayer, D as deriveEventsBaseUrl, ke as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ue as fetchCatalog, fe as fetchTournament, me as flattenMatches, A as getDeviceId, je as isLowLatencyManifest, $ as isOddinMessage, ye as licenseRequestHeaders, Gt as mountEmbed, v as pollToLive, b as resolveStream, E as subscribeLiveState, C as videoFullscreenActive, he as watchStatus };
|
|
3042
3073
|
|
|
3043
3074
|
//# sourceMappingURL=index.js.map
|