@oddin-gg/havik-player 2.6.4 → 2.8.0
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 +43 -3
- package/dist/havik-player.global.js +17 -17
- 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 +79 -7
- package/dist/index.d.ts +79 -7
- package/dist/index.js +284 -233
- package/dist/index.js.map +1 -1
- package/docs/API.md +29 -2
- package/embed/index.html +1 -1
- package/examples/vanilla.html +1 -1
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -142,7 +142,7 @@ function ae(e, t) {
|
|
|
142
142
|
t?.addEventListener("abort", a, { once: !0 });
|
|
143
143
|
});
|
|
144
144
|
}
|
|
145
|
-
async function
|
|
145
|
+
async function v(e, t, r) {
|
|
146
146
|
let i = ee(t), a = Date.now(), s = i.timeoutMs == null ? Infinity : a + i.timeoutMs, c = 0, l;
|
|
147
147
|
for (;;) {
|
|
148
148
|
if (r?.aborted) throw new n("ABORTED", 0, "wait-for-live aborted");
|
|
@@ -168,21 +168,21 @@ async function oe(e, t, r) {
|
|
|
168
168
|
}
|
|
169
169
|
//#endregion
|
|
170
170
|
//#region src/core/resolve.ts
|
|
171
|
-
async function
|
|
171
|
+
async function y(e) {
|
|
172
172
|
if (!e.matchUrn || typeof e.matchUrn != "string") throw new n("INVALID_URN", 0, "resolveStream: a non-empty matchUrn is required");
|
|
173
173
|
let t = await u(c(e.baseUrl, `/v1/playback/${encodeURIComponent(e.matchUrn)}`), {
|
|
174
174
|
credential: e.credential,
|
|
175
175
|
signal: e.signal,
|
|
176
176
|
apiHeaders: e.apiHeaders
|
|
177
177
|
});
|
|
178
|
-
if (!t.ok) throw await
|
|
179
|
-
return
|
|
178
|
+
if (!t.ok) throw await oe(t);
|
|
179
|
+
return ce(await t.json(), e.matchUrn);
|
|
180
180
|
}
|
|
181
|
-
function
|
|
182
|
-
let t = () =>
|
|
183
|
-
return e.waitForLive ?
|
|
181
|
+
function b(e) {
|
|
182
|
+
let t = () => y(e);
|
|
183
|
+
return e.waitForLive ? v(t, e.waitForLive, e.signal) : t();
|
|
184
184
|
}
|
|
185
|
-
async function
|
|
185
|
+
async function oe(e) {
|
|
186
186
|
let t = l(e.headers.get("retry-after")), i = e.headers.get("x-request-id") ?? e.headers.get("x-amzn-requestid") ?? void 0, a = e.statusText || `HTTP ${e.status}`, o, s;
|
|
187
187
|
try {
|
|
188
188
|
let t = await e.json();
|
|
@@ -198,7 +198,7 @@ async function se(e) {
|
|
|
198
198
|
liveStartsAtMs: s
|
|
199
199
|
});
|
|
200
200
|
}
|
|
201
|
-
var
|
|
201
|
+
var se = /* @__PURE__ */ new Set([
|
|
202
202
|
"matchUrn",
|
|
203
203
|
"protocol",
|
|
204
204
|
"drmEnabled",
|
|
@@ -209,7 +209,7 @@ var ce = /* @__PURE__ */ new Set([
|
|
|
209
209
|
"expiresAt",
|
|
210
210
|
"analytics"
|
|
211
211
|
]);
|
|
212
|
-
function
|
|
212
|
+
function x(e, t) {
|
|
213
213
|
let r;
|
|
214
214
|
try {
|
|
215
215
|
r = new URL(t);
|
|
@@ -219,36 +219,36 @@ function b(e, t) {
|
|
|
219
219
|
if (r.protocol !== "https:" && r.protocol !== "http:") throw new n("INTERNAL", 0, `playback ${e} has a disallowed scheme: ${r.protocol}`);
|
|
220
220
|
return t;
|
|
221
221
|
}
|
|
222
|
-
function
|
|
222
|
+
function ce(e, t) {
|
|
223
223
|
if (!e.manifestUrl) throw new n("INTERNAL", 0, "playback response is missing manifestUrl");
|
|
224
224
|
let r = e.drmEnabled ?? !!e.drm, i = {
|
|
225
225
|
matchUrn: e.matchUrn ?? t,
|
|
226
226
|
protocol: "hls",
|
|
227
227
|
drmEnabled: r,
|
|
228
|
-
manifestUrl:
|
|
228
|
+
manifestUrl: x("manifestUrl", e.manifestUrl),
|
|
229
229
|
serverTime: e.serverTime ?? ""
|
|
230
230
|
};
|
|
231
231
|
if (e.liveStartsAt && (i.liveStartsAt = e.liveStartsAt), typeof e.analytics?.sid == "string" && e.analytics.sid && (i.analytics = { sid: e.analytics.sid }), r && e.drm) {
|
|
232
232
|
let t = {};
|
|
233
|
-
e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl:
|
|
234
|
-
licenseUrl:
|
|
235
|
-
certificateUrl:
|
|
233
|
+
e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl: x("widevine licenseUrl", e.drm.widevine.licenseUrl) }), e.drm.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && (t.fairplay = {
|
|
234
|
+
licenseUrl: x("fairplay licenseUrl", e.drm.fairplay.licenseUrl),
|
|
235
|
+
certificateUrl: x("fairplay certificateUrl", e.drm.fairplay.certificateUrl)
|
|
236
236
|
}), (t.widevine || t.fairplay) && (i.drm = t);
|
|
237
237
|
}
|
|
238
238
|
let a = {};
|
|
239
|
-
for (let [t, n] of Object.entries(e))
|
|
239
|
+
for (let [t, n] of Object.entries(e)) se.has(t) || (a[t] = n);
|
|
240
240
|
return Object.keys(a).length > 0 && (i.extensions = a), i;
|
|
241
241
|
}
|
|
242
242
|
//#endregion
|
|
243
243
|
//#region src/core/fullscreen.ts
|
|
244
|
-
function
|
|
244
|
+
function S(e) {
|
|
245
245
|
return e.ownerDocument ?? document;
|
|
246
246
|
}
|
|
247
|
-
function
|
|
247
|
+
function le(e) {
|
|
248
248
|
return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
|
|
249
249
|
}
|
|
250
250
|
function C(e, t) {
|
|
251
|
-
let n = S(
|
|
251
|
+
let n = le(S(e));
|
|
252
252
|
return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
|
|
253
253
|
}
|
|
254
254
|
async function w(e, t) {
|
|
@@ -264,7 +264,7 @@ async function T(e, t) {
|
|
|
264
264
|
n.webkitExitFullscreen?.();
|
|
265
265
|
return;
|
|
266
266
|
}
|
|
267
|
-
let r =
|
|
267
|
+
let r = S(e), i = le(r);
|
|
268
268
|
i != null && (i === e || t != null && i === t) && (typeof r.exitFullscreen == "function" ? await r.exitFullscreen() : r.webkitExitFullscreen?.());
|
|
269
269
|
}
|
|
270
270
|
//#endregion
|
|
@@ -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 P(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 Se(e, t) {
|
|
|
568
568
|
})));
|
|
569
569
|
return [...t, ...r];
|
|
570
570
|
}
|
|
571
|
-
function
|
|
572
|
-
return (t, n) => M() ? navigator.requestMediaKeySystemAccess(t,
|
|
571
|
+
function Se(e) {
|
|
572
|
+
return (t, n) => M() ? navigator.requestMediaKeySystemAccess(t, P(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 Ce(e) {
|
|
|
577
577
|
}
|
|
578
578
|
//#endregion
|
|
579
579
|
//#region src/core/drm/support.ts
|
|
580
|
-
var
|
|
580
|
+
var Ce = 5e3, F = "video/mp4; codecs=\"avc1.42E01E\"", I = "audio/mp4; codecs=\"mp4a.40.2\"", we = {
|
|
581
581
|
widevine: ["com.widevine.alpha"],
|
|
582
582
|
fairplay: ["com.apple.fps"]
|
|
583
583
|
};
|
|
584
|
-
function
|
|
584
|
+
function Te(e) {
|
|
585
585
|
return e === "fairplay" ? [{
|
|
586
586
|
initDataTypes: [
|
|
587
587
|
"sinf",
|
|
@@ -589,30 +589,30 @@ function De(e) {
|
|
|
589
589
|
"cenc"
|
|
590
590
|
],
|
|
591
591
|
videoCapabilities: [{
|
|
592
|
-
contentType:
|
|
592
|
+
contentType: F,
|
|
593
593
|
robustness: "",
|
|
594
594
|
encryptionScheme: "cbcs"
|
|
595
595
|
}],
|
|
596
596
|
audioCapabilities: [{
|
|
597
|
-
contentType:
|
|
597
|
+
contentType: I,
|
|
598
598
|
robustness: "",
|
|
599
599
|
encryptionScheme: "cbcs"
|
|
600
600
|
}]
|
|
601
|
-
}] :
|
|
601
|
+
}] : P("com.widevine.alpha", [{
|
|
602
602
|
initDataTypes: ["cenc"],
|
|
603
603
|
videoCapabilities: [{
|
|
604
|
-
contentType:
|
|
604
|
+
contentType: F,
|
|
605
605
|
robustness: "SW_SECURE_DECODE",
|
|
606
606
|
encryptionScheme: "cbcs"
|
|
607
607
|
}],
|
|
608
608
|
audioCapabilities: [{
|
|
609
|
-
contentType:
|
|
609
|
+
contentType: I,
|
|
610
610
|
robustness: "SW_SECURE_CRYPTO",
|
|
611
611
|
encryptionScheme: "cbcs"
|
|
612
612
|
}]
|
|
613
613
|
}]);
|
|
614
614
|
}
|
|
615
|
-
function
|
|
615
|
+
function L(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 F(e, t) {
|
|
|
622
622
|
});
|
|
623
623
|
});
|
|
624
624
|
}
|
|
625
|
-
async function
|
|
626
|
-
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ??
|
|
625
|
+
async function Ee(e = {}) {
|
|
626
|
+
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Ce, 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 Oe(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 = we[e];
|
|
639
639
|
if (!t) {
|
|
640
640
|
r[e] = "unknown system";
|
|
641
641
|
continue;
|
|
@@ -646,7 +646,7 @@ async function Oe(e = {}) {
|
|
|
646
646
|
break;
|
|
647
647
|
}
|
|
648
648
|
try {
|
|
649
|
-
return await
|
|
649
|
+
return await L((await L(i(n, Te(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
|
|
650
650
|
verdict: "supported",
|
|
651
651
|
system: e,
|
|
652
652
|
detail: r
|
|
@@ -670,38 +670,49 @@ async function Oe(e = {}) {
|
|
|
670
670
|
}
|
|
671
671
|
//#endregion
|
|
672
672
|
//#region src/core/manifest.ts
|
|
673
|
-
var
|
|
674
|
-
function
|
|
675
|
-
return
|
|
673
|
+
var De = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
|
|
674
|
+
function Oe(e) {
|
|
675
|
+
return De.test(e);
|
|
676
|
+
}
|
|
677
|
+
//#endregion
|
|
678
|
+
//#region src/core/env.ts
|
|
679
|
+
var R = {
|
|
680
|
+
integration: "https://feed-dev.oddin-video.gg",
|
|
681
|
+
production: "https://feed.oddin-video.gg"
|
|
682
|
+
};
|
|
683
|
+
function z(e) {
|
|
684
|
+
let t = Object.prototype.hasOwnProperty.call(R, e) ? R[e] : void 0;
|
|
685
|
+
if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
|
|
686
|
+
return t;
|
|
676
687
|
}
|
|
677
688
|
//#endregion
|
|
678
689
|
//#region src/core/stats.ts
|
|
679
|
-
var
|
|
680
|
-
function
|
|
690
|
+
var B = { droppedFrames: 0 };
|
|
691
|
+
function V(e) {
|
|
681
692
|
try {
|
|
682
693
|
return new URL(e).host;
|
|
683
694
|
} catch {
|
|
684
695
|
return "";
|
|
685
696
|
}
|
|
686
697
|
}
|
|
687
|
-
var
|
|
688
|
-
function
|
|
698
|
+
var ke = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
|
|
699
|
+
function Ae(e) {
|
|
689
700
|
if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
|
|
690
701
|
let t = "", n = -1, r = performance.getEntriesByType("resource");
|
|
691
|
-
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" ||
|
|
692
|
-
let e =
|
|
702
|
+
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || ke.test(i.name)) && i.startTime >= n) {
|
|
703
|
+
let e = V(i.name);
|
|
693
704
|
e && (t = e, n = i.startTime);
|
|
694
705
|
}
|
|
695
706
|
return t;
|
|
696
707
|
}
|
|
697
|
-
function
|
|
708
|
+
function H(e) {
|
|
698
709
|
let t = e.getVideoPlaybackQuality?.();
|
|
699
710
|
return {
|
|
700
711
|
dropped: t?.droppedVideoFrames ?? 0,
|
|
701
712
|
totalFrames: t?.totalVideoFrames ?? 0
|
|
702
713
|
};
|
|
703
714
|
}
|
|
704
|
-
function
|
|
715
|
+
function je(e, t) {
|
|
705
716
|
let n = [
|
|
706
717
|
["playing", () => t("playing")],
|
|
707
718
|
["waiting", () => t("buffering")],
|
|
@@ -718,7 +729,7 @@ function Ne(e, t) {
|
|
|
718
729
|
}
|
|
719
730
|
//#endregion
|
|
720
731
|
//#region src/core/engine/native.ts
|
|
721
|
-
function
|
|
732
|
+
function Me(e) {
|
|
722
733
|
try {
|
|
723
734
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
724
735
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -726,15 +737,15 @@ function Pe(e) {
|
|
|
726
737
|
return;
|
|
727
738
|
}
|
|
728
739
|
}
|
|
729
|
-
function
|
|
740
|
+
function U(e) {
|
|
730
741
|
return !!(e ?? (typeof document < "u" ? document.createElement("video") : void 0))?.canPlayType("application/vnd.apple.mpegurl");
|
|
731
742
|
}
|
|
732
|
-
function
|
|
743
|
+
function W() {
|
|
733
744
|
if (typeof window > "u") return !1;
|
|
734
745
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
735
746
|
return e || t;
|
|
736
747
|
}
|
|
737
|
-
var
|
|
748
|
+
var G = class {
|
|
738
749
|
name = "native";
|
|
739
750
|
deps;
|
|
740
751
|
onLoaded;
|
|
@@ -770,7 +781,7 @@ var V = class {
|
|
|
770
781
|
type: "error",
|
|
771
782
|
error: new n("INTERNAL", 0, "native HLS playback error"),
|
|
772
783
|
fatal: !0
|
|
773
|
-
}), 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 = Ne(t.manifestUrl, t.analytics?.sid), e.load();
|
|
774
785
|
}
|
|
775
786
|
startLoad() {
|
|
776
787
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -792,7 +803,7 @@ var V = class {
|
|
|
792
803
|
});
|
|
793
804
|
this.onEncrypted = (n) => {
|
|
794
805
|
let i = n;
|
|
795
|
-
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
806
|
+
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Me(i.initData), (async () => {
|
|
796
807
|
try {
|
|
797
808
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
798
809
|
initDataTypes: [i.initDataType],
|
|
@@ -887,11 +898,11 @@ var V = class {
|
|
|
887
898
|
e.seekable.length > 0 && (e.currentTime = e.seekable.end(e.seekable.length - 1));
|
|
888
899
|
}
|
|
889
900
|
getStats() {
|
|
890
|
-
let e = this.deps.video, t =
|
|
901
|
+
let e = this.deps.video, t = H(e), n = {
|
|
891
902
|
droppedFrames: t.dropped,
|
|
892
903
|
decodedFrames: t.totalFrames
|
|
893
904
|
};
|
|
894
|
-
return this.cdnHost ||=
|
|
905
|
+
return this.cdnHost ||= Ae(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;
|
|
895
906
|
}
|
|
896
907
|
stop() {
|
|
897
908
|
try {
|
|
@@ -910,29 +921,29 @@ var V = class {
|
|
|
910
921
|
} catch {}
|
|
911
922
|
}
|
|
912
923
|
};
|
|
913
|
-
function
|
|
924
|
+
function Ne(e, t) {
|
|
914
925
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
915
926
|
}
|
|
916
927
|
//#endregion
|
|
917
928
|
//#region src/core/engine/hls.ts
|
|
918
|
-
function
|
|
929
|
+
function Pe() {
|
|
919
930
|
return e.isSupported();
|
|
920
931
|
}
|
|
921
|
-
var
|
|
922
|
-
function
|
|
932
|
+
var Fe = 3, Ie = 5, Le = 3, Re = 3e4, ze = 12e3, Be = 3e3, K = 6e3, Ve = 5e3, He = 4e3, Ue = 2, We = 5, Ge = 2, Ke = 2, qe = 2e3, Je = 3e4, Ye = 2, Xe = 9, Ze = .5, Qe = 64;
|
|
933
|
+
function $e(e) {
|
|
923
934
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
924
935
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
925
936
|
return;
|
|
926
937
|
}
|
|
927
|
-
e.liveSyncDuration ??=
|
|
928
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
929
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
938
|
+
e.liveSyncDuration ??= Ye;
|
|
939
|
+
let t = Math.max(12, e.liveSyncDuration + Xe);
|
|
940
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), et(e, e.liveSyncDuration);
|
|
930
941
|
}
|
|
931
|
-
function
|
|
942
|
+
function et(e, t) {
|
|
932
943
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
933
944
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
934
945
|
}
|
|
935
|
-
var
|
|
946
|
+
var q = class {
|
|
936
947
|
name = "hls";
|
|
937
948
|
hls = null;
|
|
938
949
|
deps;
|
|
@@ -991,7 +1002,7 @@ var U = class {
|
|
|
991
1002
|
this.deps = e, this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
992
1003
|
}
|
|
993
1004
|
async load() {
|
|
994
|
-
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 = U(r) && W(), o = !!e.drm?.widevine?.licenseUrl && !a;
|
|
995
1006
|
if (e.drmEnabled && !o) {
|
|
996
1007
|
i({
|
|
997
1008
|
type: "error",
|
|
@@ -1023,7 +1034,7 @@ var U = class {
|
|
|
1023
1034
|
}
|
|
1024
1035
|
this.loadSuspended = !0;
|
|
1025
1036
|
}
|
|
1026
|
-
},
|
|
1037
|
+
}, Ve));
|
|
1027
1038
|
}
|
|
1028
1039
|
resumeLoading() {
|
|
1029
1040
|
if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
|
|
@@ -1055,7 +1066,7 @@ var U = class {
|
|
|
1055
1066
|
let t = e.liveSyncPosition;
|
|
1056
1067
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1057
1068
|
let { video: n } = this.deps;
|
|
1058
|
-
n.currentTime <= t +
|
|
1069
|
+
n.currentTime <= t + Ze || (n.currentTime = t);
|
|
1059
1070
|
}
|
|
1060
1071
|
startHls() {
|
|
1061
1072
|
let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
|
|
@@ -1079,7 +1090,7 @@ var U = class {
|
|
|
1079
1090
|
videoEncryptionScheme: "cbcs",
|
|
1080
1091
|
audioEncryptionScheme: "cbcs"
|
|
1081
1092
|
},
|
|
1082
|
-
...M() ? { requestMediaKeySystemAccessFunc:
|
|
1093
|
+
...M() ? { requestMediaKeySystemAccessFunc: Se(t) } : {},
|
|
1083
1094
|
licenseXhrSetup: (e, t) => {
|
|
1084
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;
|
|
1085
1096
|
let o = performance.now();
|
|
@@ -1095,7 +1106,7 @@ var U = class {
|
|
|
1095
1106
|
} } : {},
|
|
1096
1107
|
...c
|
|
1097
1108
|
};
|
|
1098
|
-
|
|
1109
|
+
$e(d), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.loadStarted = d.autoStartLoad !== !1;
|
|
1099
1110
|
let f = new e(d);
|
|
1100
1111
|
this.hls = f, f.on(e.Events.MANIFEST_PARSED, () => {
|
|
1101
1112
|
this.mediaRecoveries = 0, this.networkRecoveries = 0;
|
|
@@ -1104,17 +1115,17 @@ var U = class {
|
|
|
1104
1115
|
}), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1105
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(() => {
|
|
1106
1117
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1107
|
-
},
|
|
1118
|
+
}, Re)));
|
|
1108
1119
|
}), f.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1109
1120
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1110
1121
|
}), f.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
1111
1122
|
let n = t?.frag?.stats, r = n?.loaded;
|
|
1112
1123
|
typeof r == "number" && (this.bytesLoaded += r);
|
|
1113
1124
|
let i = n?.loading;
|
|
1114
|
-
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 > Qe && this.requestTimesMs.shift());
|
|
1115
1126
|
let a = t?.frag?.url;
|
|
1116
1127
|
if (a) {
|
|
1117
|
-
let e =
|
|
1128
|
+
let e = V(a);
|
|
1118
1129
|
e && (this.cdnHost = e);
|
|
1119
1130
|
}
|
|
1120
1131
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1127,7 +1138,7 @@ var U = class {
|
|
|
1127
1138
|
}));
|
|
1128
1139
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1129
1140
|
this.checkEndStale(), this.checkStarvation();
|
|
1130
|
-
},
|
|
1141
|
+
}, Be), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1131
1142
|
this.renditionSwitches += 1;
|
|
1132
1143
|
let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
|
|
1133
1144
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
|
|
@@ -1191,7 +1202,7 @@ var U = class {
|
|
|
1191
1202
|
return;
|
|
1192
1203
|
}
|
|
1193
1204
|
this.capTimer && clearTimeout(this.capTimer);
|
|
1194
|
-
let t = e > this.sizeCapLevel ?
|
|
1205
|
+
let t = e > this.sizeCapLevel ? qe : Je;
|
|
1195
1206
|
this.capTimer = setTimeout(() => {
|
|
1196
1207
|
this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
|
|
1197
1208
|
}, t);
|
|
@@ -1238,7 +1249,7 @@ var U = class {
|
|
|
1238
1249
|
e.widevine && (this.licenseUrl = e.widevine);
|
|
1239
1250
|
}
|
|
1240
1251
|
getStats() {
|
|
1241
|
-
let e = this.hls, t =
|
|
1252
|
+
let e = this.hls, t = H(this.deps.video), n = {
|
|
1242
1253
|
droppedFrames: t.dropped,
|
|
1243
1254
|
decodedFrames: t.totalFrames,
|
|
1244
1255
|
lowLatency: this.detectedLowLatency,
|
|
@@ -1284,7 +1295,7 @@ var U = class {
|
|
|
1284
1295
|
return;
|
|
1285
1296
|
}
|
|
1286
1297
|
let e = Date.now() - this.lastAdvanceMs;
|
|
1287
|
-
!this.chaseSuspended && e >
|
|
1298
|
+
!this.chaseSuspended && e > K && this.suspendChasing(), e > ze && this.emitEnded("stalled");
|
|
1288
1299
|
}
|
|
1289
1300
|
checkStarvation() {
|
|
1290
1301
|
let e = this.hls, { video: t } = this.deps;
|
|
@@ -1293,17 +1304,17 @@ var U = class {
|
|
|
1293
1304
|
this.starvedTicks = 0;
|
|
1294
1305
|
return;
|
|
1295
1306
|
}
|
|
1296
|
-
let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs <
|
|
1307
|
+
let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs < K, r = this.lastFragLoadingMs !== 0 && Date.now() - this.lastFragLoadingMs > He;
|
|
1297
1308
|
if (!(t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused && n && r)) {
|
|
1298
1309
|
this.starvedTicks = 0;
|
|
1299
1310
|
return;
|
|
1300
1311
|
}
|
|
1301
|
-
if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks <
|
|
1302
|
-
if (this.starvedTicks = 0, this.kickPending && this.kickTicks >=
|
|
1312
|
+
if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks < Ue)) {
|
|
1313
|
+
if (this.starvedTicks = 0, this.kickPending && this.kickTicks >= Ge && (this.kickPending = !1, this.kickTicks = 0, this.starvationRebuilds < Ke)) {
|
|
1303
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");
|
|
1304
1315
|
return;
|
|
1305
1316
|
}
|
|
1306
|
-
if (!(this.starvationKicks >=
|
|
1317
|
+
if (!(this.starvationKicks >= We)) {
|
|
1307
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");
|
|
1308
1319
|
try {
|
|
1309
1320
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -1353,7 +1364,7 @@ var U = class {
|
|
|
1353
1364
|
scheduleLicenseRetry(t) {
|
|
1354
1365
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
1355
1366
|
let n = t.response?.code ?? 0;
|
|
1356
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
1367
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Le) return !1;
|
|
1357
1368
|
this.licenseRecoveries += 1;
|
|
1358
1369
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
1359
1370
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -1385,7 +1396,7 @@ var U = class {
|
|
|
1385
1396
|
return;
|
|
1386
1397
|
}
|
|
1387
1398
|
if (t.type === e.ErrorTypes.NETWORK_ERROR) {
|
|
1388
|
-
if (this.networkRecoveries <
|
|
1399
|
+
if (this.networkRecoveries < Ie) {
|
|
1389
1400
|
this.networkRecoveries += 1;
|
|
1390
1401
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
1391
1402
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -1402,7 +1413,7 @@ var U = class {
|
|
|
1402
1413
|
return;
|
|
1403
1414
|
}
|
|
1404
1415
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
1405
|
-
if (this.mediaRecoveries <
|
|
1416
|
+
if (this.mediaRecoveries < Fe) {
|
|
1406
1417
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
1407
1418
|
return;
|
|
1408
1419
|
}
|
|
@@ -1426,19 +1437,19 @@ var U = class {
|
|
|
1426
1437
|
let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
|
|
1427
1438
|
return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
|
|
1428
1439
|
}
|
|
1429
|
-
},
|
|
1440
|
+
}, tt = 15e3, nt = 6e5, rt = 3e5, it = 100, J = 1, at = 1e3, ot = 3e4, st = 1e3, ct = {
|
|
1430
1441
|
inline: "PRESENTATION_INLINE",
|
|
1431
1442
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
1432
1443
|
pip: "PRESENTATION_PIP"
|
|
1433
|
-
},
|
|
1444
|
+
}, lt = {
|
|
1434
1445
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
1435
1446
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
1436
1447
|
none: "KEY_SYSTEM_NONE"
|
|
1437
1448
|
};
|
|
1438
|
-
function
|
|
1449
|
+
function ut(e, t) {
|
|
1439
1450
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
1440
1451
|
}
|
|
1441
|
-
var
|
|
1452
|
+
var dt = /* @__PURE__ */ new Set([
|
|
1442
1453
|
"INVALID_URN",
|
|
1443
1454
|
"NOT_FOUND",
|
|
1444
1455
|
"GONE",
|
|
@@ -1448,7 +1459,7 @@ var lt = /* @__PURE__ */ new Set([
|
|
|
1448
1459
|
"FORBIDDEN",
|
|
1449
1460
|
"RATE_LIMITED",
|
|
1450
1461
|
"TIMEOUT"
|
|
1451
|
-
]),
|
|
1462
|
+
]), Y = {
|
|
1452
1463
|
idle: "PLAYER_STATE_IDLE",
|
|
1453
1464
|
waiting: "PLAYER_STATE_WAITING",
|
|
1454
1465
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -1458,7 +1469,7 @@ var lt = /* @__PURE__ */ new Set([
|
|
|
1458
1469
|
ended: "PLAYER_STATE_ENDED",
|
|
1459
1470
|
error: "PLAYER_STATE_ERROR"
|
|
1460
1471
|
};
|
|
1461
|
-
function
|
|
1472
|
+
function ft(e) {
|
|
1462
1473
|
try {
|
|
1463
1474
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
1464
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);
|
|
@@ -1466,7 +1477,7 @@ function ut(e) {
|
|
|
1466
1477
|
return;
|
|
1467
1478
|
}
|
|
1468
1479
|
}
|
|
1469
|
-
var
|
|
1480
|
+
var pt = class {
|
|
1470
1481
|
opts;
|
|
1471
1482
|
url;
|
|
1472
1483
|
now;
|
|
@@ -1526,19 +1537,26 @@ var dt = class {
|
|
|
1526
1537
|
lastRequestErrors = 0;
|
|
1527
1538
|
pendingStart = null;
|
|
1528
1539
|
firstFlushTimer = null;
|
|
1540
|
+
idleTimer = null;
|
|
1541
|
+
lastTickMs = 0;
|
|
1529
1542
|
bornMs;
|
|
1530
1543
|
startupAnchorMs;
|
|
1531
1544
|
startupTimeMs = 0;
|
|
1532
1545
|
manifestLoadMs = 0;
|
|
1533
1546
|
firstFragLoadMs = 0;
|
|
1534
1547
|
onPagehide = () => this.end("END_REASON_PAGEHIDE");
|
|
1548
|
+
onFreeze = () => {
|
|
1549
|
+
this.endedFlag || this.flush(!0);
|
|
1550
|
+
};
|
|
1551
|
+
onResume = () => this.checkSuspension(this.now());
|
|
1535
1552
|
onVisibility = () => {
|
|
1536
1553
|
typeof document > "u" || (document.visibilityState === "hidden" ? (this.hiddenSinceMs === null && (this.hiddenSinceMs = this.now()), this.isHidden = !0) : (this.hiddenSinceMs !== null && (this.hiddenTotalMs += this.now() - this.hiddenSinceMs, this.hiddenSinceMs = null), this.isHidden = !1), this.syncActive(), this.syncBuffering());
|
|
1537
1554
|
};
|
|
1538
1555
|
constructor(e) {
|
|
1539
1556
|
this.opts = {
|
|
1540
1557
|
...e,
|
|
1541
|
-
heartbeatMs: e.heartbeatMs ??
|
|
1558
|
+
heartbeatMs: e.heartbeatMs ?? tt,
|
|
1559
|
+
idleMs: e.idleMs ?? nt
|
|
1542
1560
|
}, 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;
|
|
1543
1561
|
}
|
|
1544
1562
|
start() {
|
|
@@ -1548,42 +1566,55 @@ var dt = class {
|
|
|
1548
1566
|
sdkVersion: this.opts.sdkVersion,
|
|
1549
1567
|
...this.opts.environment
|
|
1550
1568
|
};
|
|
1551
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), at), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), this.onVisibility());
|
|
1569
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), at), 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
|
+
}
|
|
1571
|
+
checkSuspension(e) {
|
|
1572
|
+
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
1573
|
+
let t = Math.max(this.opts.idleMs, rt);
|
|
1574
|
+
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
1575
|
+
}
|
|
1576
|
+
syncIdle(e) {
|
|
1577
|
+
e === "paused" && this.opts.idleMs ? this.idleTimer === null && (this.idleTimer = setTimeout(() => {
|
|
1578
|
+
this.idleTimer = null, this.endIdle();
|
|
1579
|
+
}, this.opts.idleMs)) : this.idleTimer !== null && (clearTimeout(this.idleTimer), this.idleTimer = null);
|
|
1580
|
+
}
|
|
1581
|
+
endIdle(e) {
|
|
1582
|
+
this.endedFlag || (this.end("END_REASON_IDLE", e), this.opts.onIdle?.());
|
|
1552
1583
|
}
|
|
1553
1584
|
noteStateChange(e, t, n, r) {
|
|
1554
1585
|
if (this.endedFlag || e === t) return;
|
|
1555
1586
|
let i = this.now();
|
|
1556
|
-
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(
|
|
1587
|
+
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(J, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(J, 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") {
|
|
1557
1588
|
this.stallIsSeekInduced = this.seekInduced(i);
|
|
1558
1589
|
let e = !this.isHidden && !this.stallIsSeekInduced;
|
|
1559
|
-
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(
|
|
1590
|
+
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(J, Math.round(this.playingTotalMs)));
|
|
1560
1591
|
} else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
|
|
1561
|
-
this.syncBuffering(), t === "paused" && (this.pauseCount += 1);
|
|
1592
|
+
this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
|
|
1562
1593
|
let a = {
|
|
1563
|
-
fromState:
|
|
1564
|
-
toState:
|
|
1565
|
-
presentation:
|
|
1594
|
+
fromState: Y[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1595
|
+
toState: Y[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1596
|
+
presentation: ct[this.presentation]
|
|
1566
1597
|
}, o = this.causeOf(e, t, i);
|
|
1567
1598
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
1568
1599
|
}
|
|
1569
1600
|
seekInduced(e) {
|
|
1570
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
1601
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < st;
|
|
1571
1602
|
}
|
|
1572
1603
|
causeOf(e, t, n) {
|
|
1573
1604
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
1574
1605
|
if (t === "buffering") return this.seekInduced(n) ? "TRANSITION_CAUSE_SEEK" : "TRANSITION_CAUSE_NETWORK_STALL";
|
|
1575
1606
|
if (t === "paused" || t === "playing" && e === "paused") return "TRANSITION_CAUSE_USER";
|
|
1576
1607
|
}
|
|
1577
|
-
syncActive() {
|
|
1578
|
-
let
|
|
1579
|
-
|
|
1608
|
+
syncActive(e = this.now()) {
|
|
1609
|
+
let t = this.isPlaying && !this.isHidden && !this.isMuted;
|
|
1610
|
+
t && this.activeSinceMs === null ? this.activeSinceMs = e : !t && this.activeSinceMs !== null && (this.activeTotalMs += e - this.activeSinceMs, this.activeSinceMs = null);
|
|
1580
1611
|
}
|
|
1581
1612
|
syncBuffering() {
|
|
1582
1613
|
let e = this.isBuffering && !this.isHidden && !this.stallIsSeekInduced;
|
|
1583
1614
|
e && this.bufferingSinceMs === null ? this.bufferingSinceMs = this.now() : !e && this.bufferingSinceMs !== null && (this.rebufferTotalMs += this.now() - this.bufferingSinceMs, this.bufferingSinceMs = null);
|
|
1584
1615
|
}
|
|
1585
|
-
closePresentation() {
|
|
1586
|
-
let
|
|
1616
|
+
closePresentation(e = this.now()) {
|
|
1617
|
+
let t = e - this.presentationSinceMs;
|
|
1587
1618
|
this.presentation === "fullscreen" ? this.fullscreenTotalMs += t : this.presentation === "pip" && (this.pipTotalMs += t), this.presentationSinceMs = e;
|
|
1588
1619
|
}
|
|
1589
1620
|
noteAutoplay(e) {
|
|
@@ -1604,19 +1635,19 @@ var dt = class {
|
|
|
1604
1635
|
}
|
|
1605
1636
|
this.muteChanges += 1;
|
|
1606
1637
|
let r = this.now();
|
|
1607
|
-
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(
|
|
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(J, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
|
|
1608
1639
|
}
|
|
1609
1640
|
notePresentation(e) {
|
|
1610
1641
|
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
1611
1642
|
}
|
|
1612
1643
|
notePlayIntent() {
|
|
1613
|
-
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs =
|
|
1644
|
+
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = J), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = J));
|
|
1614
1645
|
}
|
|
1615
1646
|
noteReady() {
|
|
1616
|
-
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(
|
|
1647
|
+
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(J, this.now() - this.startupAnchorMs));
|
|
1617
1648
|
}
|
|
1618
1649
|
noteFirstBytes() {
|
|
1619
|
-
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(
|
|
1650
|
+
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(J, this.now() - this.startupAnchorMs));
|
|
1620
1651
|
}
|
|
1621
1652
|
noteSeek() {
|
|
1622
1653
|
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
@@ -1635,7 +1666,7 @@ var dt = class {
|
|
|
1635
1666
|
let r = n ?? "";
|
|
1636
1667
|
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";
|
|
1637
1668
|
if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
|
|
1638
|
-
if (
|
|
1669
|
+
if (dt.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
1639
1670
|
let i = t ?? "";
|
|
1640
1671
|
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";
|
|
1641
1672
|
}
|
|
@@ -1650,66 +1681,68 @@ var dt = class {
|
|
|
1650
1681
|
}
|
|
1651
1682
|
heartbeat() {
|
|
1652
1683
|
if (this.endedFlag) return;
|
|
1653
|
-
let e = this.
|
|
1654
|
-
|
|
1684
|
+
let e = this.now();
|
|
1685
|
+
if (this.checkSuspension(e)) return;
|
|
1686
|
+
let t = this.opts.sample(), n = this.playingTotalMs;
|
|
1687
|
+
this.playingSinceMs !== null && (n += e - this.playingSinceMs);
|
|
1655
1688
|
let r = this.hiddenTotalMs;
|
|
1656
|
-
this.hiddenSinceMs !== null && (r +=
|
|
1689
|
+
this.hiddenSinceMs !== null && (r += e - this.hiddenSinceMs);
|
|
1657
1690
|
let i = this.rebufferTotalMs;
|
|
1658
|
-
this.bufferingSinceMs !== null && (i +=
|
|
1691
|
+
this.bufferingSinceMs !== null && (i += e - this.bufferingSinceMs);
|
|
1659
1692
|
let a = this.activeTotalMs;
|
|
1660
|
-
this.activeSinceMs !== null && (a +=
|
|
1661
|
-
let o = {}, s =
|
|
1693
|
+
this.activeSinceMs !== null && (a += e - this.activeSinceMs);
|
|
1694
|
+
let o = {}, s = t.bytesLoaded ?? 0;
|
|
1662
1695
|
s > this.lastBytes && (o.bytesDownloadedDelta = s - this.lastBytes), this.lastBytes = s;
|
|
1663
|
-
let c =
|
|
1696
|
+
let c = t.playlistBytesLoaded ?? 0;
|
|
1664
1697
|
c > this.lastPlaylistBytes && (o.playlistBytesDelta = c - this.lastPlaylistBytes), this.lastPlaylistBytes = c;
|
|
1665
|
-
let l =
|
|
1698
|
+
let l = t.droppedFrames ?? 0;
|
|
1666
1699
|
l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
|
|
1667
|
-
let u =
|
|
1668
|
-
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
|
|
1700
|
+
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 = Y[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
|
|
1669
1702
|
let d = this.mutedTotalMs;
|
|
1670
|
-
this.mutedSinceMs !== null && (d +=
|
|
1671
|
-
let f =
|
|
1703
|
+
this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
|
|
1704
|
+
let f = t.upshifts ?? 0;
|
|
1672
1705
|
f > this.lastUpshifts && (o.upshiftsDelta = f - this.lastUpshifts), this.lastUpshifts = f;
|
|
1673
|
-
let p =
|
|
1706
|
+
let p = t.downshifts ?? 0;
|
|
1674
1707
|
p > this.lastDownshifts && (o.downshiftsDelta = p - this.lastDownshifts), this.lastDownshifts = p;
|
|
1675
|
-
let m =
|
|
1708
|
+
let m = t.decodedFrames ?? 0;
|
|
1676
1709
|
m > this.lastDecoded && (o.decodedFramesDelta = m - this.lastDecoded), this.lastDecoded = m;
|
|
1677
|
-
let h =
|
|
1710
|
+
let h = t.requestErrors ?? 0;
|
|
1678
1711
|
h > this.lastRequestErrors && (o.requestErrorsDelta = h - this.lastRequestErrors), this.lastRequestErrors = h;
|
|
1679
|
-
let g =
|
|
1712
|
+
let g = t.requestCount ?? 0, _ = g - this.lastRequestCount;
|
|
1680
1713
|
if (this.lastRequestCount = g, _ > 0) {
|
|
1681
1714
|
o.requestCountDelta = _;
|
|
1682
|
-
let
|
|
1683
|
-
n.length > 0 && (o.requestTimeP50Ms =
|
|
1715
|
+
let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
|
|
1716
|
+
n.length > 0 && (o.requestTimeP50Ms = ut(n, 50), o.requestTimeP95Ms = ut(n, 95));
|
|
1684
1717
|
}
|
|
1685
|
-
typeof
|
|
1718
|
+
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();
|
|
1686
1719
|
}
|
|
1687
1720
|
maybeEmitMediaInfo(e) {
|
|
1688
1721
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
1689
1722
|
let t = {};
|
|
1690
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
1723
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = lt[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);
|
|
1691
1724
|
let n = JSON.stringify(t);
|
|
1692
1725
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
1693
1726
|
}
|
|
1694
|
-
end(e) {
|
|
1727
|
+
end(e, t) {
|
|
1695
1728
|
if (this.endedFlag) return;
|
|
1696
1729
|
this.endedFlag = !0;
|
|
1697
|
-
let
|
|
1698
|
-
this.playingSinceMs !== null && (this.playingTotalMs +=
|
|
1699
|
-
let
|
|
1700
|
-
|
|
1701
|
-
let
|
|
1702
|
-
|
|
1703
|
-
let
|
|
1704
|
-
|
|
1705
|
-
let
|
|
1706
|
-
|
|
1707
|
-
let
|
|
1708
|
-
|
|
1709
|
-
let
|
|
1710
|
-
|
|
1711
|
-
let
|
|
1712
|
-
|
|
1730
|
+
let n = t ?? this.now();
|
|
1731
|
+
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));
|
|
1732
|
+
let r = this.safeSample();
|
|
1733
|
+
r && this.maybeEmitMediaInfo(r);
|
|
1734
|
+
let i = { reason: e }, a = r?.bytesLoaded ?? this.lastBytes;
|
|
1735
|
+
a > 0 && (i.bytesDownloadedTotal = a), this.playingTotalMs > 0 && (i.watchTimeMs = Math.round(this.playingTotalMs)), this.rebufferCount > 0 && (i.rebufferCount = this.rebufferCount), this.rebufferTotalMs > 0 && (i.rebufferTimeMs = Math.round(this.rebufferTotalMs)), this.startupTimeMs > 0 && (i.startupTimeMs = Math.round(this.startupTimeMs)), this.manifestLoadMs > 0 && (i.manifestLoadMs = Math.round(this.manifestLoadMs)), this.firstFragLoadMs > 0 && (i.firstFragLoadMs = Math.round(this.firstFragLoadMs));
|
|
1736
|
+
let o = r?.licenseTimeMs ?? 0;
|
|
1737
|
+
o > 0 && (i.licenseTimeMs = Math.round(o));
|
|
1738
|
+
let s = r?.droppedFrames ?? this.lastDropped;
|
|
1739
|
+
s > 0 && (i.droppedFramesTotal = s), this.errorCount > 0 && (i.errorCount = this.errorCount), this.hiddenTotalMs > 0 && (i.hiddenTimeMs = Math.round(this.hiddenTotalMs)), this.seekCount > 0 && (i.seekCount = this.seekCount), this.pauseCount > 0 && (i.pauseCount = this.pauseCount), this.firstAudioMs > 0 && (i.firstAudioMs = Math.round(this.firstAudioMs)), this.waitingTotalMs > 0 && (i.waitingForLiveMs = Math.round(this.waitingTotalMs)), this.timeToFirstStallMs > 0 && (i.timeToFirstStallMs = Math.round(this.timeToFirstStallMs));
|
|
1740
|
+
let c = r?.positionMs ?? 0;
|
|
1741
|
+
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
|
+
let l = e !== "END_REASON_ENDED";
|
|
1743
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= ot && (i.abandonAfterStallMs = Math.max(J, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= ot && (i.abandonAfterErrorMs = Math.max(J, 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
|
+
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
1745
|
+
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");
|
|
1713
1746
|
}
|
|
1714
1747
|
safeSample() {
|
|
1715
1748
|
try {
|
|
@@ -1750,7 +1783,7 @@ var dt = class {
|
|
|
1750
1783
|
};
|
|
1751
1784
|
//#endregion
|
|
1752
1785
|
//#region src/core/environment.ts
|
|
1753
|
-
function
|
|
1786
|
+
function mt() {
|
|
1754
1787
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
1755
1788
|
let e;
|
|
1756
1789
|
try {
|
|
@@ -1775,14 +1808,14 @@ function ft() {
|
|
|
1775
1808
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
1776
1809
|
};
|
|
1777
1810
|
}
|
|
1778
|
-
function
|
|
1811
|
+
function ht() {
|
|
1779
1812
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
1780
1813
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
1781
1814
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
1782
1815
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
1783
1816
|
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";
|
|
1784
1817
|
}
|
|
1785
|
-
function
|
|
1818
|
+
function gt() {
|
|
1786
1819
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
1787
1820
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
1788
1821
|
let t = {
|
|
@@ -1801,17 +1834,17 @@ function mt() {
|
|
|
1801
1834
|
}
|
|
1802
1835
|
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;
|
|
1803
1836
|
}
|
|
1804
|
-
function
|
|
1805
|
-
let t =
|
|
1806
|
-
deviceClass:
|
|
1837
|
+
function _t(e) {
|
|
1838
|
+
let t = mt(), n = {
|
|
1839
|
+
deviceClass: ht(),
|
|
1807
1840
|
integration: t.integration,
|
|
1808
|
-
...
|
|
1841
|
+
...gt()
|
|
1809
1842
|
};
|
|
1810
1843
|
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);
|
|
1811
1844
|
let r = e.getBoundingClientRect?.();
|
|
1812
1845
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
1813
1846
|
}
|
|
1814
|
-
async function
|
|
1847
|
+
async function vt() {
|
|
1815
1848
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
1816
1849
|
if (!e?.getHighEntropyValues) return {};
|
|
1817
1850
|
try {
|
|
@@ -1823,7 +1856,7 @@ async function gt() {
|
|
|
1823
1856
|
}
|
|
1824
1857
|
//#endregion
|
|
1825
1858
|
//#region src/core/version.ts
|
|
1826
|
-
var
|
|
1859
|
+
var yt = "2.8.0", bt = {
|
|
1827
1860
|
accent: "#E1B600",
|
|
1828
1861
|
accentText: "#1B1C23",
|
|
1829
1862
|
background: "#0e0f13",
|
|
@@ -1834,7 +1867,7 @@ var _t = "2.6.4", J = {
|
|
|
1834
1867
|
border: "rgba(255, 255, 255, 0.1)",
|
|
1835
1868
|
radius: "8px",
|
|
1836
1869
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
1837
|
-
},
|
|
1870
|
+
}, xt = {
|
|
1838
1871
|
accent: "--havik-accent",
|
|
1839
1872
|
accentText: "--havik-accent-text",
|
|
1840
1873
|
background: "--havik-bg",
|
|
@@ -1846,25 +1879,25 @@ var _t = "2.6.4", J = {
|
|
|
1846
1879
|
radius: "--havik-radius",
|
|
1847
1880
|
fontFamily: "--havik-font"
|
|
1848
1881
|
};
|
|
1849
|
-
function
|
|
1882
|
+
function St(e, t) {
|
|
1850
1883
|
let n = {
|
|
1851
|
-
...
|
|
1884
|
+
...bt,
|
|
1852
1885
|
...t
|
|
1853
1886
|
};
|
|
1854
|
-
for (let t of Object.keys(
|
|
1887
|
+
for (let t of Object.keys(xt)) e.style.setProperty(xt[t], n[t]);
|
|
1855
1888
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
1856
1889
|
}
|
|
1857
1890
|
//#endregion
|
|
1858
1891
|
//#region src/ui/styles.ts
|
|
1859
|
-
var
|
|
1860
|
-
function
|
|
1861
|
-
if (e.getElementById(
|
|
1892
|
+
var Ct = "havik-player-styles", wt = "\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";
|
|
1893
|
+
function Tt(e = document) {
|
|
1894
|
+
if (e.getElementById(Ct)) return;
|
|
1862
1895
|
let t = e.createElement("style");
|
|
1863
|
-
t.id =
|
|
1896
|
+
t.id = Ct, t.textContent = wt, e.head.appendChild(t);
|
|
1864
1897
|
}
|
|
1865
1898
|
//#endregion
|
|
1866
1899
|
//#region src/ui/icons.ts
|
|
1867
|
-
var
|
|
1900
|
+
var Et = {
|
|
1868
1901
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
1869
1902
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
1870
1903
|
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\"/>",
|
|
@@ -1877,21 +1910,21 @@ var bt = {
|
|
|
1877
1910
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
1878
1911
|
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\"/>"
|
|
1879
1912
|
};
|
|
1880
|
-
function
|
|
1881
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
1913
|
+
function X(e) {
|
|
1914
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Et[e]}</svg>`;
|
|
1882
1915
|
}
|
|
1883
1916
|
//#endregion
|
|
1884
1917
|
//#region src/ui/controls.ts
|
|
1885
|
-
var
|
|
1918
|
+
var Dt = 3e3, Ot = /* @__PURE__ */ new Set([
|
|
1886
1919
|
"GONE",
|
|
1887
1920
|
"NOT_FOUND",
|
|
1888
1921
|
"INVALID_URN",
|
|
1889
1922
|
"UNAUTHORIZED"
|
|
1890
1923
|
]);
|
|
1891
|
-
function
|
|
1892
|
-
return new
|
|
1924
|
+
function kt(e) {
|
|
1925
|
+
return new At(e);
|
|
1893
1926
|
}
|
|
1894
|
-
var
|
|
1927
|
+
var At = class {
|
|
1895
1928
|
root;
|
|
1896
1929
|
video;
|
|
1897
1930
|
player;
|
|
@@ -1933,7 +1966,7 @@ var wt = class {
|
|
|
1933
1966
|
scrubbing = !1;
|
|
1934
1967
|
offFns = [];
|
|
1935
1968
|
constructor(e) {
|
|
1936
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
1969
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Dt, 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, Tt(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");
|
|
1937
1970
|
let t = (e, t, n) => {
|
|
1938
1971
|
let r = this.doc.createElement(e);
|
|
1939
1972
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -1944,12 +1977,12 @@ var wt = class {
|
|
|
1944
1977
|
"aria-label": r,
|
|
1945
1978
|
title: r
|
|
1946
1979
|
});
|
|
1947
|
-
return i.innerHTML =
|
|
1980
|
+
return i.innerHTML = X(n), i;
|
|
1948
1981
|
};
|
|
1949
1982
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
1950
1983
|
type: "button",
|
|
1951
1984
|
"aria-label": "Play"
|
|
1952
|
-
}), this.center.innerHTML =
|
|
1985
|
+
}), this.center.innerHTML = X("play"), this.spinner = t("div", "havik-spinner"), this.spinner.style.display = "none", this.overlay.append(this.center, this.spinner), this.gradient = t("div", "havik-gradient"), this.bar = t("div", "havik-bar"), this.seek = t("div", "havik-seek", {
|
|
1953
1986
|
role: "slider",
|
|
1954
1987
|
"aria-label": "Seek",
|
|
1955
1988
|
"aria-valuemin": "0",
|
|
@@ -1967,7 +2000,7 @@ var wt = class {
|
|
|
1967
2000
|
"aria-label": "Volume"
|
|
1968
2001
|
});
|
|
1969
2002
|
let a = t("div", "havik-vol");
|
|
1970
|
-
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML =
|
|
2003
|
+
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = X("liveDot");
|
|
1971
2004
|
let o = this.doc.createElement("span");
|
|
1972
2005
|
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";
|
|
1973
2006
|
let s = t("div", "havik-spacer");
|
|
@@ -2021,12 +2054,12 @@ var wt = class {
|
|
|
2021
2054
|
}
|
|
2022
2055
|
if (e === "preplay") {
|
|
2023
2056
|
let e = this.doc.createElement("button");
|
|
2024
|
-
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML =
|
|
2057
|
+
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = X("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
|
|
2025
2058
|
} else {
|
|
2026
2059
|
let r = this.doc.createElement("div");
|
|
2027
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
2060
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Ot.has(this.lastError.code)) {
|
|
2028
2061
|
let e = this.doc.createElement("button");
|
|
2029
|
-
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${
|
|
2062
|
+
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${X("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
|
|
2030
2063
|
}
|
|
2031
2064
|
}
|
|
2032
2065
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -2065,7 +2098,7 @@ var wt = class {
|
|
|
2065
2098
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
2066
2099
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
2067
2100
|
}
|
|
2068
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
2101
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${jt(this.video.currentTime)} / ${jt(this.video.duration)}`);
|
|
2069
2102
|
}
|
|
2070
2103
|
syncLive() {
|
|
2071
2104
|
let e = this.player.getStats(), t = e.isLive !== !1;
|
|
@@ -2115,17 +2148,17 @@ var wt = class {
|
|
|
2115
2148
|
renderQualityMenu() {
|
|
2116
2149
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
2117
2150
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
2118
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
2151
|
+
for (let n of e) this.menu.append(this.menuItem(Mt(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
2119
2152
|
}
|
|
2120
2153
|
renderAudioMenu() {
|
|
2121
2154
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
2122
2155
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
2123
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2156
|
+
for (let t of e) this.menu.append(this.menuItem(Nt(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
2124
2157
|
}
|
|
2125
2158
|
renderCcMenu() {
|
|
2126
2159
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
2127
2160
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
2128
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2161
|
+
for (let t of e) this.menu.append(this.menuItem(Pt(t), !1, () => this.player.setTextTrack(t.id)));
|
|
2129
2162
|
}
|
|
2130
2163
|
onTracksChanged() {
|
|
2131
2164
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -2208,7 +2241,7 @@ var wt = class {
|
|
|
2208
2241
|
}
|
|
2209
2242
|
}
|
|
2210
2243
|
setIcon(e, t) {
|
|
2211
|
-
e.innerHTML =
|
|
2244
|
+
e.innerHTML = X(t);
|
|
2212
2245
|
}
|
|
2213
2246
|
destroy() {
|
|
2214
2247
|
this.hideTimer && clearTimeout(this.hideTimer);
|
|
@@ -2225,32 +2258,41 @@ var wt = class {
|
|
|
2225
2258
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
2226
2259
|
}
|
|
2227
2260
|
};
|
|
2228
|
-
function
|
|
2261
|
+
function jt(e) {
|
|
2229
2262
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
2230
2263
|
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");
|
|
2231
2264
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
2232
2265
|
}
|
|
2233
|
-
function
|
|
2266
|
+
function Mt(e) {
|
|
2234
2267
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
2235
2268
|
}
|
|
2236
|
-
function
|
|
2269
|
+
function Nt(e) {
|
|
2237
2270
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2238
2271
|
}
|
|
2239
|
-
function
|
|
2272
|
+
function Pt(e) {
|
|
2240
2273
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2241
2274
|
}
|
|
2242
2275
|
//#endregion
|
|
2243
2276
|
//#region src/managed/index.ts
|
|
2244
|
-
var
|
|
2245
|
-
|
|
2277
|
+
var Ft = 6e3, Z = 45e3, It = 2e3, Lt = 3, Rt = 2e3, zt = 48e4;
|
|
2278
|
+
function Bt(e) {
|
|
2279
|
+
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 z(e.env);
|
|
2281
|
+
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
2282
|
+
return e.baseUrl;
|
|
2283
|
+
}
|
|
2284
|
+
async function Q(e) {
|
|
2246
2285
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
2247
|
-
|
|
2286
|
+
let t = Bt(e);
|
|
2248
2287
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
2249
2288
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
2250
|
-
let
|
|
2251
|
-
|
|
2289
|
+
let r = new Vt({
|
|
2290
|
+
...e,
|
|
2291
|
+
baseUrl: t
|
|
2292
|
+
});
|
|
2293
|
+
return await r.start(), r;
|
|
2252
2294
|
}
|
|
2253
|
-
var
|
|
2295
|
+
var Vt = class {
|
|
2254
2296
|
opts;
|
|
2255
2297
|
abort = new AbortController();
|
|
2256
2298
|
listeners = {};
|
|
@@ -2276,6 +2318,7 @@ var It = class {
|
|
|
2276
2318
|
analyticsSession = null;
|
|
2277
2319
|
detachMediaListeners;
|
|
2278
2320
|
playRequested = !1;
|
|
2321
|
+
idleClosed = !1;
|
|
2279
2322
|
pendingStartLoad = !1;
|
|
2280
2323
|
constructor(e) {
|
|
2281
2324
|
this.opts = e;
|
|
@@ -2293,7 +2336,7 @@ var It = class {
|
|
|
2293
2336
|
this.opts.muted && (this.opts.video.muted = !0), this.opts.poster && (this.opts.video.poster = this.opts.poster), this.mountControls(), this.attachPipListeners(), this.setState("loading");
|
|
2294
2337
|
let e = ++this.loadGen, t = this.resolveOptions();
|
|
2295
2338
|
try {
|
|
2296
|
-
let n = await
|
|
2339
|
+
let n = await y(t);
|
|
2297
2340
|
if (await this.onResolved(n, e), e === this.loadGen && this._state === "error" && this._lastError) {
|
|
2298
2341
|
let e = this._lastError;
|
|
2299
2342
|
throw this.destroy(), e;
|
|
@@ -2320,7 +2363,7 @@ var It = class {
|
|
|
2320
2363
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
2321
2364
|
}
|
|
2322
2365
|
beginArmingByPolling(e) {
|
|
2323
|
-
|
|
2366
|
+
b({
|
|
2324
2367
|
...this.resolveOptions(),
|
|
2325
2368
|
signal: this.abort.signal,
|
|
2326
2369
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -2337,7 +2380,7 @@ var It = class {
|
|
|
2337
2380
|
setTimeout(() => {
|
|
2338
2381
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
2339
2382
|
phase: i ? "unavailable" : "tooEarly",
|
|
2340
|
-
retryInMs:
|
|
2383
|
+
retryInMs: Z,
|
|
2341
2384
|
attempt: 1,
|
|
2342
2385
|
elapsedMs: 0,
|
|
2343
2386
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -2354,7 +2397,7 @@ var It = class {
|
|
|
2354
2397
|
}
|
|
2355
2398
|
}
|
|
2356
2399
|
}, h = () => {
|
|
2357
|
-
a || s || p() || (s = !0,
|
|
2400
|
+
a || s || p() || (s = !0, b({
|
|
2358
2401
|
...this.resolveOptions(),
|
|
2359
2402
|
signal: c.signal,
|
|
2360
2403
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -2362,7 +2405,7 @@ var It = class {
|
|
|
2362
2405
|
a || p() || c.signal.aborted || (a = !0, this.closeArming(), this.fail(e instanceof n ? e : new n("INTERNAL", 0, String(e))));
|
|
2363
2406
|
}));
|
|
2364
2407
|
}, g = () => {
|
|
2365
|
-
a || p() ||
|
|
2408
|
+
a || p() || y(this.resolveOptions()).then((e) => m(e)).catch((e) => {
|
|
2366
2409
|
if (!(a || p())) {
|
|
2367
2410
|
if (e instanceof n && o(e.code)) {
|
|
2368
2411
|
h();
|
|
@@ -2376,13 +2419,13 @@ var It = class {
|
|
|
2376
2419
|
!a && !p() && h();
|
|
2377
2420
|
}, e);
|
|
2378
2421
|
};
|
|
2379
|
-
_(
|
|
2422
|
+
_(Ft), this.armingSub = E({
|
|
2380
2423
|
eventsBaseUrl: t,
|
|
2381
2424
|
matchUrn: this.opts.matchUrn,
|
|
2382
2425
|
credential: this.opts.credential,
|
|
2383
|
-
onAlive: () => _(
|
|
2426
|
+
onAlive: () => _(Z),
|
|
2384
2427
|
onState: (e) => {
|
|
2385
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
2428
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * It);
|
|
2386
2429
|
},
|
|
2387
2430
|
onError: () => h()
|
|
2388
2431
|
});
|
|
@@ -2405,7 +2448,7 @@ var It = class {
|
|
|
2405
2448
|
let n = await s(this.opts.credential);
|
|
2406
2449
|
if (this.destroyed || t !== this.loadGen) return;
|
|
2407
2450
|
this.setState("loading");
|
|
2408
|
-
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a =
|
|
2451
|
+
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = je(this.opts.video, (e) => {
|
|
2409
2452
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
2410
2453
|
});
|
|
2411
2454
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -2420,20 +2463,25 @@ var It = class {
|
|
|
2420
2463
|
this.destroyed || t !== this.loadGen || this.engine !== i || (this.analyticsSession?.noteReady(), this.emit("ready"));
|
|
2421
2464
|
}, 0));
|
|
2422
2465
|
}
|
|
2466
|
+
onAnalyticsIdle(e) {
|
|
2467
|
+
this.destroyed || this.engine !== e || (this.idleClosed = !0, this.pendingStartLoad = !1, e.stop());
|
|
2468
|
+
}
|
|
2423
2469
|
startAnalytics(e, t) {
|
|
2424
2470
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
2425
2471
|
let n = e.analytics?.sid;
|
|
2426
2472
|
if (!n) return;
|
|
2427
|
-
let r = (typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0) ??
|
|
2473
|
+
let r = (typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0) ?? ft(this.opts.baseUrl);
|
|
2428
2474
|
if (!r) return;
|
|
2429
|
-
let i = this.opts.video, a = new
|
|
2475
|
+
let i = this.opts.video, a = new pt({
|
|
2430
2476
|
endpoint: r,
|
|
2431
2477
|
sid: n,
|
|
2432
2478
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
2433
|
-
sdkVersion:
|
|
2434
|
-
environment:
|
|
2479
|
+
sdkVersion: yt,
|
|
2480
|
+
environment: _t(i),
|
|
2481
|
+
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
2482
|
+
onIdle: () => this.onAnalyticsIdle(t),
|
|
2435
2483
|
sample: () => {
|
|
2436
|
-
let e = this.engine?.getStats() ??
|
|
2484
|
+
let e = this.engine?.getStats() ?? B, t = i.buffered.length ? Math.max(0, i.buffered.end(i.buffered.length - 1) - i.currentTime) : 0;
|
|
2437
2485
|
return {
|
|
2438
2486
|
...e,
|
|
2439
2487
|
bufferedMs: Math.round(t * 1e3),
|
|
@@ -2447,7 +2495,7 @@ var It = class {
|
|
|
2447
2495
|
let o = () => a.noteSeek(), s = () => a.noteVolume(i.muted, i.volume);
|
|
2448
2496
|
i.addEventListener("seeking", o), i.addEventListener("volumechange", s), this.detachMediaListeners = () => {
|
|
2449
2497
|
i.removeEventListener("seeking", o), i.removeEventListener("volumechange", s);
|
|
2450
|
-
}, a.start(), a.seedVolume(i.muted, i.volume), a.notePresentation(this.currentPresentation()),
|
|
2498
|
+
}, a.start(), a.seedVolume(i.muted, i.volume), a.notePresentation(this.currentPresentation()), vt().then((e) => a.noteEnvironment(e)), this.opts.autoplay === !1 && a.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
2451
2499
|
}
|
|
2452
2500
|
currentPresentation() {
|
|
2453
2501
|
let e = this.opts.video;
|
|
@@ -2471,11 +2519,11 @@ var It = class {
|
|
|
2471
2519
|
hlsConfig: i,
|
|
2472
2520
|
emit: (e) => this.onEngineEvent(e)
|
|
2473
2521
|
}, o = this.opts.engine ?? "auto";
|
|
2474
|
-
if (o === "native") return new
|
|
2475
|
-
if (o === "hls") return new
|
|
2476
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl &&
|
|
2477
|
-
if (
|
|
2478
|
-
if (
|
|
2522
|
+
if (o === "native") return new G(a);
|
|
2523
|
+
if (o === "hls") return new q(a);
|
|
2524
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && U(this.opts.video) && W()) return new G(a);
|
|
2525
|
+
if (Pe()) return new q(a);
|
|
2526
|
+
if (U(this.opts.video)) return new G(a);
|
|
2479
2527
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
2480
2528
|
}
|
|
2481
2529
|
onEngineEvent(e) {
|
|
@@ -2518,7 +2566,7 @@ var It = class {
|
|
|
2518
2566
|
r = 0, i = !1;
|
|
2519
2567
|
},
|
|
2520
2568
|
onError: () => {
|
|
2521
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
2569
|
+
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= Lt && (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.`))));
|
|
2522
2570
|
}
|
|
2523
2571
|
});
|
|
2524
2572
|
}
|
|
@@ -2540,7 +2588,7 @@ var It = class {
|
|
|
2540
2588
|
scheduleRejoin(e) {
|
|
2541
2589
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
2542
2590
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
2543
|
-
}, Math.random() *
|
|
2591
|
+
}, Math.random() * It));
|
|
2544
2592
|
}
|
|
2545
2593
|
cancelRejoin() {
|
|
2546
2594
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -2550,7 +2598,7 @@ var It = class {
|
|
|
2550
2598
|
this.teardownPlayback(), this.setState("waiting"), this.beginArming(e, void 0, !0);
|
|
2551
2599
|
}
|
|
2552
2600
|
teardownPlayback() {
|
|
2553
|
-
this.stopStats(), this.stopRefresh(), this.cancelRejoin(), this.closeArming(), this.closeLiveState(), this.detachMedia?.(), this.engine?.destroy(), this.engine = null, this.pendingStartLoad = !1;
|
|
2601
|
+
this.stopStats(), this.stopRefresh(), this.cancelRejoin(), this.closeArming(), this.closeLiveState(), this.detachMedia?.(), this.engine?.destroy(), this.engine = null, this.pendingStartLoad = !1, this.idleClosed = !1;
|
|
2554
2602
|
}
|
|
2555
2603
|
mountControls() {
|
|
2556
2604
|
let e = this.opts.controls ?? "custom", t = this.opts.video;
|
|
@@ -2564,7 +2612,7 @@ var It = class {
|
|
|
2564
2612
|
}
|
|
2565
2613
|
t.controls = !1;
|
|
2566
2614
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
2567
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
2615
|
+
r && r.insertBefore(n, t), n.appendChild(t), St(n, this.opts.theme), this.container = n, this.controlBar = kt({
|
|
2568
2616
|
root: n,
|
|
2569
2617
|
video: t,
|
|
2570
2618
|
player: this,
|
|
@@ -2594,7 +2642,7 @@ var It = class {
|
|
|
2594
2642
|
}
|
|
2595
2643
|
startStats() {
|
|
2596
2644
|
this.stopStats();
|
|
2597
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
2645
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Rt);
|
|
2598
2646
|
this.statsTimer = setInterval(() => {
|
|
2599
2647
|
if (!this.engine) return;
|
|
2600
2648
|
let e = this.engine.getStats();
|
|
@@ -2606,7 +2654,7 @@ var It = class {
|
|
|
2606
2654
|
}
|
|
2607
2655
|
scheduleLicenseRefresh() {
|
|
2608
2656
|
this.stopRefresh();
|
|
2609
|
-
let e = this.opts.licenseRefreshMs ??
|
|
2657
|
+
let e = this.opts.licenseRefreshMs ?? zt;
|
|
2610
2658
|
e && this._descriptor?.drmEnabled && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
2611
2659
|
}
|
|
2612
2660
|
stopRefresh() {
|
|
@@ -2615,7 +2663,7 @@ var It = class {
|
|
|
2615
2663
|
async refreshLicense() {
|
|
2616
2664
|
let e = this.engine;
|
|
2617
2665
|
if (!this.destroyed && e) try {
|
|
2618
|
-
let t = await
|
|
2666
|
+
let t = await y(this.resolveOptions());
|
|
2619
2667
|
if (this.destroyed || this.engine !== e) return;
|
|
2620
2668
|
let n = t.drm?.widevine?.licenseUrl, r = t.drm?.fairplay?.licenseUrl;
|
|
2621
2669
|
(n || r) && (e.setLicenseUrls({
|
|
@@ -2629,7 +2677,10 @@ var It = class {
|
|
|
2629
2677
|
async play() {
|
|
2630
2678
|
if (this.destroyed) return;
|
|
2631
2679
|
let e = !this.playRequested;
|
|
2632
|
-
this.playRequested = !0
|
|
2680
|
+
if (this.playRequested = !0, this.idleClosed && this._state !== "ended" && this._state !== "error") {
|
|
2681
|
+
this.idleClosed = !1, await this.reload();
|
|
2682
|
+
return;
|
|
2683
|
+
}
|
|
2633
2684
|
let t = this.pendingStartLoad && this._state !== "ended" && this._state !== "error";
|
|
2634
2685
|
this.opts.autoplay === !1 && this.analyticsSession?.notePlayIntent(), t && (this.pendingStartLoad = !1, this.setState("loading"), this.engine?.startLoad());
|
|
2635
2686
|
try {
|
|
@@ -2648,7 +2699,7 @@ var It = class {
|
|
|
2648
2699
|
this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
|
|
2649
2700
|
}
|
|
2650
2701
|
getStats() {
|
|
2651
|
-
return this.engine?.getStats() ??
|
|
2702
|
+
return this.engine?.getStats() ?? B;
|
|
2652
2703
|
}
|
|
2653
2704
|
getQualityLevels() {
|
|
2654
2705
|
return this.engine?.getQualityLevels() ?? [];
|
|
@@ -2700,7 +2751,7 @@ var It = class {
|
|
|
2700
2751
|
let e = ++this.loadGen;
|
|
2701
2752
|
this.teardownPlayback();
|
|
2702
2753
|
try {
|
|
2703
|
-
let t = await
|
|
2754
|
+
let t = await b({
|
|
2704
2755
|
...this.resolveOptions(),
|
|
2705
2756
|
waitForLive: this.opts.waitForLive ? this.buildWaitConfig(e) : void 0
|
|
2706
2757
|
});
|
|
@@ -2758,7 +2809,7 @@ function $(e) {
|
|
|
2758
2809
|
}
|
|
2759
2810
|
//#endregion
|
|
2760
2811
|
//#region src/embed/host.ts
|
|
2761
|
-
function
|
|
2812
|
+
function Ht(e) {
|
|
2762
2813
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
2763
2814
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
2764
2815
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -2817,8 +2868,8 @@ function Lt(e) {
|
|
|
2817
2868
|
}
|
|
2818
2869
|
//#endregion
|
|
2819
2870
|
//#region src/embed/page.ts
|
|
2820
|
-
var
|
|
2821
|
-
function
|
|
2871
|
+
var Ut = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
2872
|
+
function Wt() {
|
|
2822
2873
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
2823
2874
|
if (e) return {
|
|
2824
2875
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -2840,9 +2891,9 @@ function zt() {
|
|
|
2840
2891
|
waitForLive: !0
|
|
2841
2892
|
};
|
|
2842
2893
|
}
|
|
2843
|
-
async function
|
|
2844
|
-
let e =
|
|
2845
|
-
|
|
2894
|
+
async function Gt() {
|
|
2895
|
+
let e = Wt();
|
|
2896
|
+
qt();
|
|
2846
2897
|
let t = document.createElement("video");
|
|
2847
2898
|
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);
|
|
2848
2899
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -2897,12 +2948,12 @@ async function Bt() {
|
|
|
2897
2948
|
code: e.code,
|
|
2898
2949
|
message: e.message
|
|
2899
2950
|
})), e.on("autoplayblocked", () => {
|
|
2900
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
2951
|
+
i({ type: "oddin:autoplayblocked" }), Kt(t, e);
|
|
2901
2952
|
});
|
|
2902
2953
|
}, s = async (r) => {
|
|
2903
2954
|
a?.destroy(), a = null;
|
|
2904
2955
|
try {
|
|
2905
|
-
let n = await
|
|
2956
|
+
let n = await Q({
|
|
2906
2957
|
video: t,
|
|
2907
2958
|
baseUrl: e.baseUrl,
|
|
2908
2959
|
matchUrn: r,
|
|
@@ -2963,7 +3014,7 @@ async function Bt() {
|
|
|
2963
3014
|
a?.retry();
|
|
2964
3015
|
break;
|
|
2965
3016
|
case "oddin:load":
|
|
2966
|
-
typeof e.matchUrn == "string" &&
|
|
3017
|
+
typeof e.matchUrn == "string" && Ut.test(e.matchUrn) && s(e.matchUrn);
|
|
2967
3018
|
break;
|
|
2968
3019
|
case "oddin:destroy": c();
|
|
2969
3020
|
}
|
|
@@ -2975,18 +3026,18 @@ async function Bt() {
|
|
|
2975
3026
|
protocol: 1
|
|
2976
3027
|
});
|
|
2977
3028
|
}
|
|
2978
|
-
function
|
|
3029
|
+
function Kt(e, t) {
|
|
2979
3030
|
if (document.getElementById("havik-tap")) return;
|
|
2980
3031
|
let n = document.createElement("button");
|
|
2981
3032
|
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", () => {
|
|
2982
3033
|
n.remove(), t.play();
|
|
2983
3034
|
}), document.body.appendChild(n);
|
|
2984
3035
|
}
|
|
2985
|
-
function
|
|
3036
|
+
function qt() {
|
|
2986
3037
|
let e = document.createElement("style");
|
|
2987
3038
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
2988
3039
|
}
|
|
2989
3040
|
//#endregion
|
|
2990
|
-
export {
|
|
3041
|
+
export { bt as ODDIN_THEME, n as PlaybackError, St as applyTheme, z as baseUrlForEnv, Gt as bootEmbed, _e as clearDeviceId, Q as createPlayer, D as deriveEventsBaseUrl, Ee as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ue as fetchCatalog, fe as fetchTournament, me as flattenMatches, A as getDeviceId, Oe as isLowLatencyManifest, $ as isOddinMessage, ye as licenseRequestHeaders, Ht as mountEmbed, v as pollToLive, b as resolveStream, E as subscribeLiveState, C as videoFullscreenActive, he as watchStatus };
|
|
2991
3042
|
|
|
2992
3043
|
//# sourceMappingURL=index.js.map
|