@oddin-gg/havik-player 2.7.0 → 2.9.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 +57 -1
- 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 +98 -7
- package/dist/index.d.ts +98 -7
- package/dist/index.js +209 -180
- package/dist/index.js.map +1 -1
- package/docs/API.md +39 -11
- package/embed/index.html +6 -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,16 +1437,16 @@ 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
1452
|
var dt = /* @__PURE__ */ new Set([
|
|
@@ -1448,7 +1459,7 @@ var dt = /* @__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",
|
|
@@ -1544,8 +1555,8 @@ var pt = class {
|
|
|
1544
1555
|
constructor(e) {
|
|
1545
1556
|
this.opts = {
|
|
1546
1557
|
...e,
|
|
1547
|
-
heartbeatMs: e.heartbeatMs ??
|
|
1548
|
-
idleMs: e.idleMs ??
|
|
1558
|
+
heartbeatMs: e.heartbeatMs ?? tt,
|
|
1559
|
+
idleMs: e.idleMs ?? nt
|
|
1549
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;
|
|
1550
1561
|
}
|
|
1551
1562
|
start() {
|
|
@@ -1555,11 +1566,11 @@ var pt = class {
|
|
|
1555
1566
|
sdkVersion: this.opts.sdkVersion,
|
|
1556
1567
|
...this.opts.environment
|
|
1557
1568
|
};
|
|
1558
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
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());
|
|
1559
1570
|
}
|
|
1560
1571
|
checkSuspension(e) {
|
|
1561
1572
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
1562
|
-
let t = Math.max(this.opts.idleMs,
|
|
1573
|
+
let t = Math.max(this.opts.idleMs, rt);
|
|
1563
1574
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
1564
1575
|
}
|
|
1565
1576
|
syncIdle(e) {
|
|
@@ -1573,21 +1584,21 @@ var pt = class {
|
|
|
1573
1584
|
noteStateChange(e, t, n, r) {
|
|
1574
1585
|
if (this.endedFlag || e === t) return;
|
|
1575
1586
|
let i = this.now();
|
|
1576
|
-
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") {
|
|
1577
1588
|
this.stallIsSeekInduced = this.seekInduced(i);
|
|
1578
1589
|
let e = !this.isHidden && !this.stallIsSeekInduced;
|
|
1579
|
-
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)));
|
|
1580
1591
|
} else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
|
|
1581
1592
|
this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
|
|
1582
1593
|
let a = {
|
|
1583
|
-
fromState:
|
|
1584
|
-
toState:
|
|
1585
|
-
presentation:
|
|
1594
|
+
fromState: Y[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1595
|
+
toState: Y[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1596
|
+
presentation: ct[this.presentation]
|
|
1586
1597
|
}, o = this.causeOf(e, t, i);
|
|
1587
1598
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
1588
1599
|
}
|
|
1589
1600
|
seekInduced(e) {
|
|
1590
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
1601
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < st;
|
|
1591
1602
|
}
|
|
1592
1603
|
causeOf(e, t, n) {
|
|
1593
1604
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -1624,19 +1635,19 @@ var pt = class {
|
|
|
1624
1635
|
}
|
|
1625
1636
|
this.muteChanges += 1;
|
|
1626
1637
|
let r = this.now();
|
|
1627
|
-
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();
|
|
1628
1639
|
}
|
|
1629
1640
|
notePresentation(e) {
|
|
1630
1641
|
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
1631
1642
|
}
|
|
1632
1643
|
notePlayIntent() {
|
|
1633
|
-
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));
|
|
1634
1645
|
}
|
|
1635
1646
|
noteReady() {
|
|
1636
|
-
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(
|
|
1647
|
+
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(J, this.now() - this.startupAnchorMs));
|
|
1637
1648
|
}
|
|
1638
1649
|
noteFirstBytes() {
|
|
1639
|
-
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));
|
|
1640
1651
|
}
|
|
1641
1652
|
noteSeek() {
|
|
1642
1653
|
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
@@ -1687,7 +1698,7 @@ var pt = class {
|
|
|
1687
1698
|
let l = t.droppedFrames ?? 0;
|
|
1688
1699
|
l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
|
|
1689
1700
|
let u = t.renditionSwitches ?? 0;
|
|
1690
|
-
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 =
|
|
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";
|
|
1691
1702
|
let d = this.mutedTotalMs;
|
|
1692
1703
|
this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
|
|
1693
1704
|
let f = t.upshifts ?? 0;
|
|
@@ -1702,14 +1713,14 @@ var pt = class {
|
|
|
1702
1713
|
if (this.lastRequestCount = g, _ > 0) {
|
|
1703
1714
|
o.requestCountDelta = _;
|
|
1704
1715
|
let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
|
|
1705
|
-
n.length > 0 && (o.requestTimeP50Ms =
|
|
1716
|
+
n.length > 0 && (o.requestTimeP50Ms = ut(n, 50), o.requestTimeP95Ms = ut(n, 95));
|
|
1706
1717
|
}
|
|
1707
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();
|
|
1708
1719
|
}
|
|
1709
1720
|
maybeEmitMediaInfo(e) {
|
|
1710
1721
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
1711
1722
|
let t = {};
|
|
1712
|
-
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);
|
|
1713
1724
|
let n = JSON.stringify(t);
|
|
1714
1725
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
1715
1726
|
}
|
|
@@ -1729,7 +1740,7 @@ var pt = class {
|
|
|
1729
1740
|
let c = r?.positionMs ?? 0;
|
|
1730
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));
|
|
1731
1742
|
let l = e !== "END_REASON_ENDED";
|
|
1732
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
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);
|
|
1733
1744
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
1734
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");
|
|
1735
1746
|
}
|
|
@@ -1749,7 +1760,7 @@ var pt = class {
|
|
|
1749
1760
|
};
|
|
1750
1761
|
}
|
|
1751
1762
|
enqueue(e) {
|
|
1752
|
-
for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
1763
|
+
for (this.pending.push(this.wrap(e)); this.pending.length > it;) {
|
|
1753
1764
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
1754
1765
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
1755
1766
|
}
|
|
@@ -1845,7 +1856,7 @@ async function vt() {
|
|
|
1845
1856
|
}
|
|
1846
1857
|
//#endregion
|
|
1847
1858
|
//#region src/core/version.ts
|
|
1848
|
-
var yt = "2.
|
|
1859
|
+
var yt = "2.9.0", bt = {
|
|
1849
1860
|
accent: "#E1B600",
|
|
1850
1861
|
accentText: "#1B1C23",
|
|
1851
1862
|
background: "#0e0f13",
|
|
@@ -1856,7 +1867,7 @@ var yt = "2.7.0", J = {
|
|
|
1856
1867
|
border: "rgba(255, 255, 255, 0.1)",
|
|
1857
1868
|
radius: "8px",
|
|
1858
1869
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
1859
|
-
},
|
|
1870
|
+
}, xt = {
|
|
1860
1871
|
accent: "--havik-accent",
|
|
1861
1872
|
accentText: "--havik-accent-text",
|
|
1862
1873
|
background: "--havik-bg",
|
|
@@ -1868,25 +1879,25 @@ var yt = "2.7.0", J = {
|
|
|
1868
1879
|
radius: "--havik-radius",
|
|
1869
1880
|
fontFamily: "--havik-font"
|
|
1870
1881
|
};
|
|
1871
|
-
function
|
|
1882
|
+
function St(e, t) {
|
|
1872
1883
|
let n = {
|
|
1873
|
-
...
|
|
1884
|
+
...bt,
|
|
1874
1885
|
...t
|
|
1875
1886
|
};
|
|
1876
|
-
for (let t of Object.keys(
|
|
1887
|
+
for (let t of Object.keys(xt)) e.style.setProperty(xt[t], n[t]);
|
|
1877
1888
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
1878
1889
|
}
|
|
1879
1890
|
//#endregion
|
|
1880
1891
|
//#region src/ui/styles.ts
|
|
1881
|
-
var
|
|
1882
|
-
function
|
|
1883
|
-
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;
|
|
1884
1895
|
let t = e.createElement("style");
|
|
1885
|
-
t.id =
|
|
1896
|
+
t.id = Ct, t.textContent = wt, e.head.appendChild(t);
|
|
1886
1897
|
}
|
|
1887
1898
|
//#endregion
|
|
1888
1899
|
//#region src/ui/icons.ts
|
|
1889
|
-
var
|
|
1900
|
+
var Et = {
|
|
1890
1901
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
1891
1902
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
1892
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\"/>",
|
|
@@ -1899,21 +1910,21 @@ var St = {
|
|
|
1899
1910
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
1900
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\"/>"
|
|
1901
1912
|
};
|
|
1902
|
-
function
|
|
1903
|
-
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>`;
|
|
1904
1915
|
}
|
|
1905
1916
|
//#endregion
|
|
1906
1917
|
//#region src/ui/controls.ts
|
|
1907
|
-
var
|
|
1918
|
+
var Dt = 3e3, Ot = /* @__PURE__ */ new Set([
|
|
1908
1919
|
"GONE",
|
|
1909
1920
|
"NOT_FOUND",
|
|
1910
1921
|
"INVALID_URN",
|
|
1911
1922
|
"UNAUTHORIZED"
|
|
1912
1923
|
]);
|
|
1913
|
-
function
|
|
1914
|
-
return new
|
|
1924
|
+
function kt(e) {
|
|
1925
|
+
return new At(e);
|
|
1915
1926
|
}
|
|
1916
|
-
var
|
|
1927
|
+
var At = class {
|
|
1917
1928
|
root;
|
|
1918
1929
|
video;
|
|
1919
1930
|
player;
|
|
@@ -1955,7 +1966,7 @@ var Et = class {
|
|
|
1955
1966
|
scrubbing = !1;
|
|
1956
1967
|
offFns = [];
|
|
1957
1968
|
constructor(e) {
|
|
1958
|
-
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");
|
|
1959
1970
|
let t = (e, t, n) => {
|
|
1960
1971
|
let r = this.doc.createElement(e);
|
|
1961
1972
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -1966,12 +1977,12 @@ var Et = class {
|
|
|
1966
1977
|
"aria-label": r,
|
|
1967
1978
|
title: r
|
|
1968
1979
|
});
|
|
1969
|
-
return i.innerHTML =
|
|
1980
|
+
return i.innerHTML = X(n), i;
|
|
1970
1981
|
};
|
|
1971
1982
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
1972
1983
|
type: "button",
|
|
1973
1984
|
"aria-label": "Play"
|
|
1974
|
-
}), 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", {
|
|
1975
1986
|
role: "slider",
|
|
1976
1987
|
"aria-label": "Seek",
|
|
1977
1988
|
"aria-valuemin": "0",
|
|
@@ -1989,7 +2000,7 @@ var Et = class {
|
|
|
1989
2000
|
"aria-label": "Volume"
|
|
1990
2001
|
});
|
|
1991
2002
|
let a = t("div", "havik-vol");
|
|
1992
|
-
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");
|
|
1993
2004
|
let o = this.doc.createElement("span");
|
|
1994
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";
|
|
1995
2006
|
let s = t("div", "havik-spacer");
|
|
@@ -2043,12 +2054,12 @@ var Et = class {
|
|
|
2043
2054
|
}
|
|
2044
2055
|
if (e === "preplay") {
|
|
2045
2056
|
let e = this.doc.createElement("button");
|
|
2046
|
-
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);
|
|
2047
2058
|
} else {
|
|
2048
2059
|
let r = this.doc.createElement("div");
|
|
2049
|
-
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)) {
|
|
2050
2061
|
let e = this.doc.createElement("button");
|
|
2051
|
-
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);
|
|
2052
2063
|
}
|
|
2053
2064
|
}
|
|
2054
2065
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -2087,7 +2098,7 @@ var Et = class {
|
|
|
2087
2098
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
2088
2099
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
2089
2100
|
}
|
|
2090
|
-
!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)}`);
|
|
2091
2102
|
}
|
|
2092
2103
|
syncLive() {
|
|
2093
2104
|
let e = this.player.getStats(), t = e.isLive !== !1;
|
|
@@ -2137,17 +2148,17 @@ var Et = class {
|
|
|
2137
2148
|
renderQualityMenu() {
|
|
2138
2149
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
2139
2150
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
2140
|
-
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)));
|
|
2141
2152
|
}
|
|
2142
2153
|
renderAudioMenu() {
|
|
2143
2154
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
2144
2155
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
2145
|
-
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)));
|
|
2146
2157
|
}
|
|
2147
2158
|
renderCcMenu() {
|
|
2148
2159
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
2149
2160
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
2150
|
-
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)));
|
|
2151
2162
|
}
|
|
2152
2163
|
onTracksChanged() {
|
|
2153
2164
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -2230,7 +2241,7 @@ var Et = class {
|
|
|
2230
2241
|
}
|
|
2231
2242
|
}
|
|
2232
2243
|
setIcon(e, t) {
|
|
2233
|
-
e.innerHTML =
|
|
2244
|
+
e.innerHTML = X(t);
|
|
2234
2245
|
}
|
|
2235
2246
|
destroy() {
|
|
2236
2247
|
this.hideTimer && clearTimeout(this.hideTimer);
|
|
@@ -2247,32 +2258,41 @@ var Et = class {
|
|
|
2247
2258
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
2248
2259
|
}
|
|
2249
2260
|
};
|
|
2250
|
-
function
|
|
2261
|
+
function jt(e) {
|
|
2251
2262
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
2252
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");
|
|
2253
2264
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
2254
2265
|
}
|
|
2255
|
-
function
|
|
2266
|
+
function Mt(e) {
|
|
2256
2267
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
2257
2268
|
}
|
|
2258
|
-
function
|
|
2269
|
+
function Nt(e) {
|
|
2259
2270
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2260
2271
|
}
|
|
2261
|
-
function
|
|
2272
|
+
function Pt(e) {
|
|
2262
2273
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2263
2274
|
}
|
|
2264
2275
|
//#endregion
|
|
2265
2276
|
//#region src/managed/index.ts
|
|
2266
|
-
var
|
|
2267
|
-
|
|
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) {
|
|
2268
2285
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
2269
|
-
|
|
2286
|
+
let t = Bt(e);
|
|
2270
2287
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
2271
2288
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
2272
|
-
let
|
|
2273
|
-
|
|
2289
|
+
let r = new Vt({
|
|
2290
|
+
...e,
|
|
2291
|
+
baseUrl: t
|
|
2292
|
+
});
|
|
2293
|
+
return await r.start(), r;
|
|
2274
2294
|
}
|
|
2275
|
-
var
|
|
2295
|
+
var Vt = class {
|
|
2276
2296
|
opts;
|
|
2277
2297
|
abort = new AbortController();
|
|
2278
2298
|
listeners = {};
|
|
@@ -2316,7 +2336,7 @@ var Rt = class {
|
|
|
2316
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");
|
|
2317
2337
|
let e = ++this.loadGen, t = this.resolveOptions();
|
|
2318
2338
|
try {
|
|
2319
|
-
let n = await
|
|
2339
|
+
let n = await y(t);
|
|
2320
2340
|
if (await this.onResolved(n, e), e === this.loadGen && this._state === "error" && this._lastError) {
|
|
2321
2341
|
let e = this._lastError;
|
|
2322
2342
|
throw this.destroy(), e;
|
|
@@ -2343,7 +2363,7 @@ var Rt = class {
|
|
|
2343
2363
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
2344
2364
|
}
|
|
2345
2365
|
beginArmingByPolling(e) {
|
|
2346
|
-
|
|
2366
|
+
b({
|
|
2347
2367
|
...this.resolveOptions(),
|
|
2348
2368
|
signal: this.abort.signal,
|
|
2349
2369
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -2360,7 +2380,7 @@ var Rt = class {
|
|
|
2360
2380
|
setTimeout(() => {
|
|
2361
2381
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
2362
2382
|
phase: i ? "unavailable" : "tooEarly",
|
|
2363
|
-
retryInMs:
|
|
2383
|
+
retryInMs: Z,
|
|
2364
2384
|
attempt: 1,
|
|
2365
2385
|
elapsedMs: 0,
|
|
2366
2386
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -2377,7 +2397,7 @@ var Rt = class {
|
|
|
2377
2397
|
}
|
|
2378
2398
|
}
|
|
2379
2399
|
}, h = () => {
|
|
2380
|
-
a || s || p() || (s = !0,
|
|
2400
|
+
a || s || p() || (s = !0, b({
|
|
2381
2401
|
...this.resolveOptions(),
|
|
2382
2402
|
signal: c.signal,
|
|
2383
2403
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -2385,7 +2405,7 @@ var Rt = class {
|
|
|
2385
2405
|
a || p() || c.signal.aborted || (a = !0, this.closeArming(), this.fail(e instanceof n ? e : new n("INTERNAL", 0, String(e))));
|
|
2386
2406
|
}));
|
|
2387
2407
|
}, g = () => {
|
|
2388
|
-
a || p() ||
|
|
2408
|
+
a || p() || y(this.resolveOptions()).then((e) => m(e)).catch((e) => {
|
|
2389
2409
|
if (!(a || p())) {
|
|
2390
2410
|
if (e instanceof n && o(e.code)) {
|
|
2391
2411
|
h();
|
|
@@ -2399,13 +2419,13 @@ var Rt = class {
|
|
|
2399
2419
|
!a && !p() && h();
|
|
2400
2420
|
}, e);
|
|
2401
2421
|
};
|
|
2402
|
-
_(
|
|
2422
|
+
_(Ft), this.armingSub = E({
|
|
2403
2423
|
eventsBaseUrl: t,
|
|
2404
2424
|
matchUrn: this.opts.matchUrn,
|
|
2405
2425
|
credential: this.opts.credential,
|
|
2406
|
-
onAlive: () => _(
|
|
2426
|
+
onAlive: () => _(Z),
|
|
2407
2427
|
onState: (e) => {
|
|
2408
|
-
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);
|
|
2409
2429
|
},
|
|
2410
2430
|
onError: () => h()
|
|
2411
2431
|
});
|
|
@@ -2428,7 +2448,7 @@ var Rt = class {
|
|
|
2428
2448
|
let n = await s(this.opts.credential);
|
|
2429
2449
|
if (this.destroyed || t !== this.loadGen) return;
|
|
2430
2450
|
this.setState("loading");
|
|
2431
|
-
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) => {
|
|
2432
2452
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
2433
2453
|
});
|
|
2434
2454
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -2461,7 +2481,7 @@ var Rt = class {
|
|
|
2461
2481
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
2462
2482
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
2463
2483
|
sample: () => {
|
|
2464
|
-
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;
|
|
2465
2485
|
return {
|
|
2466
2486
|
...e,
|
|
2467
2487
|
bufferedMs: Math.round(t * 1e3),
|
|
@@ -2499,11 +2519,11 @@ var Rt = class {
|
|
|
2499
2519
|
hlsConfig: i,
|
|
2500
2520
|
emit: (e) => this.onEngineEvent(e)
|
|
2501
2521
|
}, o = this.opts.engine ?? "auto";
|
|
2502
|
-
if (o === "native") return new
|
|
2503
|
-
if (o === "hls") return new
|
|
2504
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl &&
|
|
2505
|
-
if (
|
|
2506
|
-
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);
|
|
2507
2527
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
2508
2528
|
}
|
|
2509
2529
|
onEngineEvent(e) {
|
|
@@ -2546,7 +2566,7 @@ var Rt = class {
|
|
|
2546
2566
|
r = 0, i = !1;
|
|
2547
2567
|
},
|
|
2548
2568
|
onError: () => {
|
|
2549
|
-
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.`))));
|
|
2550
2570
|
}
|
|
2551
2571
|
});
|
|
2552
2572
|
}
|
|
@@ -2568,7 +2588,7 @@ var Rt = class {
|
|
|
2568
2588
|
scheduleRejoin(e) {
|
|
2569
2589
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
2570
2590
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
2571
|
-
}, Math.random() *
|
|
2591
|
+
}, Math.random() * It));
|
|
2572
2592
|
}
|
|
2573
2593
|
cancelRejoin() {
|
|
2574
2594
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -2592,7 +2612,7 @@ var Rt = class {
|
|
|
2592
2612
|
}
|
|
2593
2613
|
t.controls = !1;
|
|
2594
2614
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
2595
|
-
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({
|
|
2596
2616
|
root: n,
|
|
2597
2617
|
video: t,
|
|
2598
2618
|
player: this,
|
|
@@ -2622,7 +2642,7 @@ var Rt = class {
|
|
|
2622
2642
|
}
|
|
2623
2643
|
startStats() {
|
|
2624
2644
|
this.stopStats();
|
|
2625
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
2645
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Rt);
|
|
2626
2646
|
this.statsTimer = setInterval(() => {
|
|
2627
2647
|
if (!this.engine) return;
|
|
2628
2648
|
let e = this.engine.getStats();
|
|
@@ -2634,7 +2654,7 @@ var Rt = class {
|
|
|
2634
2654
|
}
|
|
2635
2655
|
scheduleLicenseRefresh() {
|
|
2636
2656
|
this.stopRefresh();
|
|
2637
|
-
let e = this.opts.licenseRefreshMs ??
|
|
2657
|
+
let e = this.opts.licenseRefreshMs ?? zt;
|
|
2638
2658
|
e && this._descriptor?.drmEnabled && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
2639
2659
|
}
|
|
2640
2660
|
stopRefresh() {
|
|
@@ -2643,7 +2663,7 @@ var Rt = class {
|
|
|
2643
2663
|
async refreshLicense() {
|
|
2644
2664
|
let e = this.engine;
|
|
2645
2665
|
if (!this.destroyed && e) try {
|
|
2646
|
-
let t = await
|
|
2666
|
+
let t = await y(this.resolveOptions());
|
|
2647
2667
|
if (this.destroyed || this.engine !== e) return;
|
|
2648
2668
|
let n = t.drm?.widevine?.licenseUrl, r = t.drm?.fairplay?.licenseUrl;
|
|
2649
2669
|
(n || r) && (e.setLicenseUrls({
|
|
@@ -2679,7 +2699,7 @@ var Rt = class {
|
|
|
2679
2699
|
this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
|
|
2680
2700
|
}
|
|
2681
2701
|
getStats() {
|
|
2682
|
-
return this.engine?.getStats() ??
|
|
2702
|
+
return this.engine?.getStats() ?? B;
|
|
2683
2703
|
}
|
|
2684
2704
|
getQualityLevels() {
|
|
2685
2705
|
return this.engine?.getQualityLevels() ?? [];
|
|
@@ -2731,7 +2751,7 @@ var Rt = class {
|
|
|
2731
2751
|
let e = ++this.loadGen;
|
|
2732
2752
|
this.teardownPlayback();
|
|
2733
2753
|
try {
|
|
2734
|
-
let t = await
|
|
2754
|
+
let t = await b({
|
|
2735
2755
|
...this.resolveOptions(),
|
|
2736
2756
|
waitForLive: this.opts.waitForLive ? this.buildWaitConfig(e) : void 0
|
|
2737
2757
|
});
|
|
@@ -2789,7 +2809,7 @@ function $(e) {
|
|
|
2789
2809
|
}
|
|
2790
2810
|
//#endregion
|
|
2791
2811
|
//#region src/embed/host.ts
|
|
2792
|
-
function
|
|
2812
|
+
function Ht(e) {
|
|
2793
2813
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
2794
2814
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
2795
2815
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -2848,8 +2868,15 @@ function zt(e) {
|
|
|
2848
2868
|
}
|
|
2849
2869
|
//#endregion
|
|
2850
2870
|
//#region src/embed/page.ts
|
|
2851
|
-
var
|
|
2852
|
-
function
|
|
2871
|
+
var Ut = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
2872
|
+
function Wt(e) {
|
|
2873
|
+
if (typeof e == "boolean") return e;
|
|
2874
|
+
if (typeof e == "object" && e) {
|
|
2875
|
+
let t = e.endpoint;
|
|
2876
|
+
return typeof t == "string" ? { endpoint: t } : {};
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
function Gt() {
|
|
2853
2880
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
2854
2881
|
if (e) return {
|
|
2855
2882
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -2858,7 +2885,8 @@ function Vt() {
|
|
|
2858
2885
|
parentOrigin: e.parentOrigin,
|
|
2859
2886
|
autoplay: e.autoplay ?? !0,
|
|
2860
2887
|
muted: e.muted ?? !0,
|
|
2861
|
-
waitForLive: e.waitForLive ?? !0
|
|
2888
|
+
waitForLive: e.waitForLive ?? !0,
|
|
2889
|
+
analytics: Wt(e.analytics)
|
|
2862
2890
|
};
|
|
2863
2891
|
let t = new URLSearchParams(location.search);
|
|
2864
2892
|
return {
|
|
@@ -2871,9 +2899,9 @@ function Vt() {
|
|
|
2871
2899
|
waitForLive: !0
|
|
2872
2900
|
};
|
|
2873
2901
|
}
|
|
2874
|
-
async function
|
|
2875
|
-
let e =
|
|
2876
|
-
|
|
2902
|
+
async function Kt() {
|
|
2903
|
+
let e = Gt();
|
|
2904
|
+
Jt();
|
|
2877
2905
|
let t = document.createElement("video");
|
|
2878
2906
|
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);
|
|
2879
2907
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -2928,19 +2956,20 @@ async function Ht() {
|
|
|
2928
2956
|
code: e.code,
|
|
2929
2957
|
message: e.message
|
|
2930
2958
|
})), e.on("autoplayblocked", () => {
|
|
2931
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
2959
|
+
i({ type: "oddin:autoplayblocked" }), qt(t, e);
|
|
2932
2960
|
});
|
|
2933
2961
|
}, s = async (r) => {
|
|
2934
2962
|
a?.destroy(), a = null;
|
|
2935
2963
|
try {
|
|
2936
|
-
let n = await
|
|
2964
|
+
let n = await Q({
|
|
2937
2965
|
video: t,
|
|
2938
2966
|
baseUrl: e.baseUrl,
|
|
2939
2967
|
matchUrn: r,
|
|
2940
2968
|
credential: { apiKey: e.apiKey },
|
|
2941
2969
|
autoplay: e.autoplay,
|
|
2942
2970
|
muted: e.muted,
|
|
2943
|
-
waitForLive: e.waitForLive
|
|
2971
|
+
waitForLive: e.waitForLive,
|
|
2972
|
+
analytics: e.analytics
|
|
2944
2973
|
});
|
|
2945
2974
|
a = n;
|
|
2946
2975
|
let i = t.parentElement;
|
|
@@ -2994,7 +3023,7 @@ async function Ht() {
|
|
|
2994
3023
|
a?.retry();
|
|
2995
3024
|
break;
|
|
2996
3025
|
case "oddin:load":
|
|
2997
|
-
typeof e.matchUrn == "string" &&
|
|
3026
|
+
typeof e.matchUrn == "string" && Ut.test(e.matchUrn) && s(e.matchUrn);
|
|
2998
3027
|
break;
|
|
2999
3028
|
case "oddin:destroy": c();
|
|
3000
3029
|
}
|
|
@@ -3006,18 +3035,18 @@ async function Ht() {
|
|
|
3006
3035
|
protocol: 1
|
|
3007
3036
|
});
|
|
3008
3037
|
}
|
|
3009
|
-
function
|
|
3038
|
+
function qt(e, t) {
|
|
3010
3039
|
if (document.getElementById("havik-tap")) return;
|
|
3011
3040
|
let n = document.createElement("button");
|
|
3012
3041
|
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", () => {
|
|
3013
3042
|
n.remove(), t.play();
|
|
3014
3043
|
}), document.body.appendChild(n);
|
|
3015
3044
|
}
|
|
3016
|
-
function
|
|
3045
|
+
function Jt() {
|
|
3017
3046
|
let e = document.createElement("style");
|
|
3018
3047
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
3019
3048
|
}
|
|
3020
3049
|
//#endregion
|
|
3021
|
-
export {
|
|
3050
|
+
export { bt as ODDIN_THEME, n as PlaybackError, St as applyTheme, z as baseUrlForEnv, Kt 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 };
|
|
3022
3051
|
|
|
3023
3052
|
//# sourceMappingURL=index.js.map
|