@oddin-gg/havik-player 2.17.0 → 2.19.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/dist/havik-player.global.js +18 -18
- 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 +42 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +402 -326
- package/dist/index.js.map +1 -1
- package/docs/API.md +41 -2
- package/docs/STABILITY.md +1 -1
- package/embed/index.html +1 -1
- package/examples/vanilla.html +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -174,7 +174,7 @@ function ue(e, t) {
|
|
|
174
174
|
t?.addEventListener("abort", a, { once: !0 });
|
|
175
175
|
});
|
|
176
176
|
}
|
|
177
|
-
async function
|
|
177
|
+
async function de(e, t, r) {
|
|
178
178
|
let i = ae(t), a = Date.now(), s = i.timeoutMs == null ? Infinity : a + i.timeoutMs, c = 0, l;
|
|
179
179
|
for (;;) {
|
|
180
180
|
if (r?.aborted) throw new n("ABORTED", 0, "wait-for-live aborted");
|
|
@@ -200,21 +200,21 @@ async function v(e, t, r) {
|
|
|
200
200
|
}
|
|
201
201
|
//#endregion
|
|
202
202
|
//#region src/core/resolve.ts
|
|
203
|
-
async function
|
|
203
|
+
async function v(e) {
|
|
204
204
|
if (!e.matchUrn || typeof e.matchUrn != "string") throw new n("INVALID_URN", 0, "resolveStream: a non-empty matchUrn is required");
|
|
205
205
|
let t = await p(d(e.baseUrl, `/v1/playback/${encodeURIComponent(e.matchUrn)}`), {
|
|
206
206
|
credential: e.credential,
|
|
207
207
|
signal: e.signal,
|
|
208
208
|
apiHeaders: e.apiHeaders
|
|
209
209
|
});
|
|
210
|
-
if (!t.ok) throw await
|
|
211
|
-
return
|
|
210
|
+
if (!t.ok) throw await fe(t);
|
|
211
|
+
return he(await t.json(), e.matchUrn);
|
|
212
212
|
}
|
|
213
|
-
function
|
|
214
|
-
let t = () =>
|
|
215
|
-
return e.waitForLive ?
|
|
213
|
+
function y(e) {
|
|
214
|
+
let t = () => v(e);
|
|
215
|
+
return e.waitForLive ? de(t, e.waitForLive, e.signal) : t();
|
|
216
216
|
}
|
|
217
|
-
async function
|
|
217
|
+
async function fe(e) {
|
|
218
218
|
let t = f(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;
|
|
219
219
|
try {
|
|
220
220
|
let t = await e.json();
|
|
@@ -230,7 +230,7 @@ async function de(e) {
|
|
|
230
230
|
liveStartsAtMs: s
|
|
231
231
|
});
|
|
232
232
|
}
|
|
233
|
-
var
|
|
233
|
+
var pe = /* @__PURE__ */ new Set([
|
|
234
234
|
"matchUrn",
|
|
235
235
|
"protocol",
|
|
236
236
|
"drmEnabled",
|
|
@@ -241,7 +241,7 @@ var fe = /* @__PURE__ */ new Set([
|
|
|
241
241
|
"expiresAt",
|
|
242
242
|
"analytics"
|
|
243
243
|
]);
|
|
244
|
-
function
|
|
244
|
+
function b(e, t) {
|
|
245
245
|
let r;
|
|
246
246
|
try {
|
|
247
247
|
r = new URL(t);
|
|
@@ -251,7 +251,7 @@ function x(e, t) {
|
|
|
251
251
|
if (r.protocol !== "https:" && r.protocol !== "http:") throw new n("INTERNAL", 0, `playback ${e} has a disallowed scheme: ${r.protocol}`);
|
|
252
252
|
return t;
|
|
253
253
|
}
|
|
254
|
-
function
|
|
254
|
+
function me(e) {
|
|
255
255
|
if (e !== void 0) {
|
|
256
256
|
if (typeof e == "string" && !e.endsWith("/")) try {
|
|
257
257
|
let t = new URL(e);
|
|
@@ -260,57 +260,64 @@ function pe(e) {
|
|
|
260
260
|
g(`server analytics.endpoint ${JSON.stringify(e)} ignored: not a bare https origin.`);
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
|
-
function
|
|
263
|
+
function he(e, t) {
|
|
264
264
|
if (!e.manifestUrl) throw new n("INTERNAL", 0, "playback response is missing manifestUrl");
|
|
265
265
|
let r = e.drmEnabled ?? !!e.drm, i = {
|
|
266
266
|
matchUrn: e.matchUrn ?? t,
|
|
267
267
|
protocol: "hls",
|
|
268
268
|
drmEnabled: r,
|
|
269
|
-
manifestUrl:
|
|
269
|
+
manifestUrl: b("manifestUrl", e.manifestUrl),
|
|
270
270
|
serverTime: e.serverTime ?? ""
|
|
271
271
|
};
|
|
272
272
|
if (e.liveStartsAt && (i.liveStartsAt = e.liveStartsAt), typeof e.analytics?.sid == "string" && e.analytics.sid) {
|
|
273
273
|
i.analytics = { sid: e.analytics.sid };
|
|
274
|
-
let t =
|
|
274
|
+
let t = me(e.analytics.endpoint);
|
|
275
275
|
t && (i.analytics.endpoint = t);
|
|
276
276
|
}
|
|
277
277
|
if (r && e.drm) {
|
|
278
278
|
let t = {};
|
|
279
|
-
e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl:
|
|
280
|
-
licenseUrl:
|
|
281
|
-
certificateUrl:
|
|
279
|
+
e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl: b("widevine licenseUrl", e.drm.widevine.licenseUrl) }), e.drm.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && (t.fairplay = {
|
|
280
|
+
licenseUrl: b("fairplay licenseUrl", e.drm.fairplay.licenseUrl),
|
|
281
|
+
certificateUrl: b("fairplay certificateUrl", e.drm.fairplay.certificateUrl)
|
|
282
282
|
}), (t.widevine || t.fairplay) && (i.drm = t);
|
|
283
283
|
}
|
|
284
284
|
let a = {};
|
|
285
|
-
for (let [t, n] of Object.entries(e))
|
|
285
|
+
for (let [t, n] of Object.entries(e)) pe.has(t) || (a[t] = n);
|
|
286
286
|
return Object.keys(a).length > 0 && (i.extensions = a), i;
|
|
287
287
|
}
|
|
288
288
|
//#endregion
|
|
289
289
|
//#region src/core/fullscreen.ts
|
|
290
|
-
function
|
|
290
|
+
function x(e) {
|
|
291
291
|
return e.ownerDocument ?? document;
|
|
292
292
|
}
|
|
293
293
|
function ge(e) {
|
|
294
294
|
return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
|
|
295
295
|
}
|
|
296
296
|
function S(e, t) {
|
|
297
|
-
let n = ge(
|
|
297
|
+
let n = ge(x(e));
|
|
298
298
|
return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
|
|
299
299
|
}
|
|
300
|
-
|
|
300
|
+
function C(e, t) {
|
|
301
|
+
let n = t ?? e, r = x(e);
|
|
302
|
+
if (typeof n.requestFullscreen == "function") return r.fullscreenEnabled !== !1;
|
|
303
|
+
if (typeof n.webkitRequestFullscreen == "function") return r.webkitFullscreenEnabled !== !1;
|
|
304
|
+
let i = e;
|
|
305
|
+
return i.webkitSupportsFullscreen === !0 && typeof i.webkitEnterFullscreen == "function" || e.readyState < 1;
|
|
306
|
+
}
|
|
307
|
+
async function w(e, t) {
|
|
301
308
|
let n = t ?? e;
|
|
302
309
|
if (typeof n.requestFullscreen == "function") return await n.requestFullscreen(), !0;
|
|
303
310
|
if (typeof n.webkitRequestFullscreen == "function") return n.webkitRequestFullscreen(), !0;
|
|
304
311
|
let r = e;
|
|
305
312
|
return r.webkitSupportsFullscreen && typeof r.webkitEnterFullscreen == "function" ? (r.webkitEnterFullscreen(), !0) : !1;
|
|
306
313
|
}
|
|
307
|
-
async function
|
|
314
|
+
async function T(e, t) {
|
|
308
315
|
let n = e;
|
|
309
316
|
if (n.webkitDisplayingFullscreen) {
|
|
310
317
|
n.webkitExitFullscreen?.();
|
|
311
318
|
return;
|
|
312
319
|
}
|
|
313
|
-
let r =
|
|
320
|
+
let r = x(e), i = ge(r);
|
|
314
321
|
i != null && (i === e || t != null && i === t) && (typeof r.exitFullscreen == "function" ? await r.exitFullscreen() : r.webkitExitFullscreen?.());
|
|
315
322
|
}
|
|
316
323
|
//#endregion
|
|
@@ -462,7 +469,7 @@ function Ce(e) {
|
|
|
462
469
|
//#endregion
|
|
463
470
|
//#region src/core/events.ts
|
|
464
471
|
var we = 45e3;
|
|
465
|
-
function
|
|
472
|
+
function E(e) {
|
|
466
473
|
let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = e.idleTimeoutMs ?? we, i = Number.isFinite(r) && r > 0 ? r : 0, a = new AbortController(), o = !1, c = (e) => new Promise((t) => {
|
|
467
474
|
if (a.signal.aborted) return t();
|
|
468
475
|
let n = setTimeout(t, e);
|
|
@@ -545,7 +552,7 @@ function T(e) {
|
|
|
545
552
|
o || (o = !0, a.abort());
|
|
546
553
|
} };
|
|
547
554
|
}
|
|
548
|
-
function
|
|
555
|
+
function D(e) {
|
|
549
556
|
try {
|
|
550
557
|
let t = new URL(e);
|
|
551
558
|
return t.hostname = `events.${t.hostname}`, t.pathname = "", t.search = "", t.origin;
|
|
@@ -555,24 +562,24 @@ function E(e) {
|
|
|
555
562
|
}
|
|
556
563
|
//#endregion
|
|
557
564
|
//#region src/core/drm/deviceId.ts
|
|
558
|
-
var
|
|
559
|
-
function
|
|
560
|
-
if (
|
|
565
|
+
var O = "havik.player.deviceId", k;
|
|
566
|
+
function A() {
|
|
567
|
+
if (k) return k;
|
|
561
568
|
try {
|
|
562
|
-
let e = globalThis.localStorage?.getItem(
|
|
563
|
-
if (e) return
|
|
569
|
+
let e = globalThis.localStorage?.getItem(O);
|
|
570
|
+
if (e) return k = e, e;
|
|
564
571
|
} catch {}
|
|
565
572
|
let e = Ee();
|
|
566
|
-
|
|
573
|
+
k = e;
|
|
567
574
|
try {
|
|
568
|
-
globalThis.localStorage?.setItem(
|
|
575
|
+
globalThis.localStorage?.setItem(O, e);
|
|
569
576
|
} catch {}
|
|
570
577
|
return e;
|
|
571
578
|
}
|
|
572
579
|
function Te() {
|
|
573
|
-
|
|
580
|
+
k = void 0;
|
|
574
581
|
try {
|
|
575
|
-
globalThis.localStorage?.removeItem(
|
|
582
|
+
globalThis.localStorage?.removeItem(O);
|
|
576
583
|
} catch {}
|
|
577
584
|
}
|
|
578
585
|
function Ee() {
|
|
@@ -591,17 +598,65 @@ function De(e, t, n = {}) {
|
|
|
591
598
|
let r = {
|
|
592
599
|
"x-api-key": t.apiKey,
|
|
593
600
|
"X-Match-Urn": e.matchUrn,
|
|
594
|
-
"X-Device-Id": n.deviceId ??
|
|
601
|
+
"X-Device-Id": n.deviceId ?? A(),
|
|
595
602
|
"Content-Type": "application/octet-stream"
|
|
596
603
|
};
|
|
597
604
|
return n.userId && (r["X-User-Id"] = n.userId), r;
|
|
598
605
|
}
|
|
599
606
|
//#endregion
|
|
607
|
+
//#region src/core/bandwidthMemory.ts
|
|
608
|
+
var j = "havik.player.bandwidth", Oe = .8, ke = 2e7, Ae = 3e5;
|
|
609
|
+
function M() {
|
|
610
|
+
return globalThis.navigator?.connection;
|
|
611
|
+
}
|
|
612
|
+
function je() {
|
|
613
|
+
let e = M()?.type;
|
|
614
|
+
return typeof e == "string" && e !== "" && e !== "unknown" ? e : "any";
|
|
615
|
+
}
|
|
616
|
+
function Me() {
|
|
617
|
+
let e = M()?.downlink;
|
|
618
|
+
return typeof e == "number" && Number.isFinite(e) && e > 0 ? e * 1e6 : void 0;
|
|
619
|
+
}
|
|
620
|
+
function Ne() {
|
|
621
|
+
try {
|
|
622
|
+
let e = globalThis.localStorage?.getItem(j);
|
|
623
|
+
if (!e) return {};
|
|
624
|
+
let t = JSON.parse(e);
|
|
625
|
+
return t && typeof t == "object" && !Array.isArray(t) ? t : {};
|
|
626
|
+
} catch {
|
|
627
|
+
return {};
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
function Pe(e = Date.now()) {
|
|
631
|
+
let t = Ne()[je()];
|
|
632
|
+
if (!t || typeof t.bps != "number" || typeof t.at != "number" || !Number.isFinite(t.bps) || t.bps <= 0) return;
|
|
633
|
+
let n = e - t.at;
|
|
634
|
+
if (n < 0 || n > 2592e5) return;
|
|
635
|
+
let r = Me(), i = r === void 0 ? t.bps : Math.min(t.bps, r);
|
|
636
|
+
return Math.round(Math.min(ke, Math.max(Ae, i * Oe)));
|
|
637
|
+
}
|
|
638
|
+
function Fe(e, t = Date.now()) {
|
|
639
|
+
if (!Number.isFinite(e) || e <= 0) return;
|
|
640
|
+
let n = Ne();
|
|
641
|
+
n[je()] = {
|
|
642
|
+
bps: Math.round(e),
|
|
643
|
+
at: t
|
|
644
|
+
};
|
|
645
|
+
try {
|
|
646
|
+
globalThis.localStorage?.setItem(j, JSON.stringify(n));
|
|
647
|
+
} catch {}
|
|
648
|
+
}
|
|
649
|
+
function Ie() {
|
|
650
|
+
try {
|
|
651
|
+
globalThis.localStorage?.removeItem(j);
|
|
652
|
+
} catch {}
|
|
653
|
+
}
|
|
654
|
+
//#endregion
|
|
600
655
|
//#region src/core/drm/cdm.ts
|
|
601
|
-
var
|
|
602
|
-
function
|
|
603
|
-
let n =
|
|
604
|
-
n || (n = /* @__PURE__ */ new Map(),
|
|
656
|
+
var Le = /* @__PURE__ */ new WeakMap();
|
|
657
|
+
function Re(e, t) {
|
|
658
|
+
let n = Le.get(e);
|
|
659
|
+
n || (n = /* @__PURE__ */ new Map(), Le.set(e, n));
|
|
605
660
|
let r = n.get(t.keySystem);
|
|
606
661
|
if (r) return r;
|
|
607
662
|
let i = t.createMediaKeys().catch((e) => {
|
|
@@ -609,22 +664,22 @@ function Oe(e, t) {
|
|
|
609
664
|
});
|
|
610
665
|
return n.set(t.keySystem, i), i;
|
|
611
666
|
}
|
|
612
|
-
function
|
|
667
|
+
function N() {
|
|
613
668
|
return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
|
|
614
669
|
}
|
|
615
|
-
var
|
|
616
|
-
function
|
|
670
|
+
var P = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
|
|
671
|
+
function ze(e) {
|
|
617
672
|
return e.startsWith("com.widevine");
|
|
618
673
|
}
|
|
619
|
-
function
|
|
620
|
-
if (!
|
|
674
|
+
function F(e, t) {
|
|
675
|
+
if (!ze(e)) return t;
|
|
621
676
|
let n = (e, t) => {
|
|
622
677
|
let n = e.videoCapabilities;
|
|
623
678
|
return !n?.length || !n.some((e) => e.robustness) ? !1 : n.every((e) => {
|
|
624
|
-
let n =
|
|
625
|
-
return n === -1 ||
|
|
679
|
+
let n = P.indexOf(e.robustness);
|
|
680
|
+
return n === -1 || P.indexOf(t) > n;
|
|
626
681
|
});
|
|
627
|
-
}, r =
|
|
682
|
+
}, r = P.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
|
|
628
683
|
...t,
|
|
629
684
|
videoCapabilities: t.videoCapabilities?.map((t) => ({
|
|
630
685
|
...t,
|
|
@@ -633,53 +688,53 @@ function N(e, t) {
|
|
|
633
688
|
})));
|
|
634
689
|
return [...t, ...r];
|
|
635
690
|
}
|
|
636
|
-
function
|
|
637
|
-
return (t, n) =>
|
|
691
|
+
function Be(e) {
|
|
692
|
+
return (t, n) => N() ? navigator.requestMediaKeySystemAccess(t, F(t, n)).then((t) => ({
|
|
638
693
|
keySystem: t.keySystem,
|
|
639
694
|
getConfiguration: () => t.getConfiguration(),
|
|
640
|
-
createMediaKeys: () =>
|
|
695
|
+
createMediaKeys: () => Re(e, t)
|
|
641
696
|
})) : Promise.reject(/* @__PURE__ */ Error("navigator.requestMediaKeySystemAccess is unavailable — EME needs a secure context (https, or localhost)"));
|
|
642
697
|
}
|
|
643
|
-
var
|
|
698
|
+
var I = {
|
|
644
699
|
video: "SW_SECURE_DECODE",
|
|
645
700
|
audio: "SW_SECURE_CRYPTO",
|
|
646
701
|
scheme: "cbcs"
|
|
647
702
|
};
|
|
648
|
-
function
|
|
649
|
-
if (!
|
|
703
|
+
function Ve(e) {
|
|
704
|
+
if (!N()) return;
|
|
650
705
|
let t = (e, t) => ({
|
|
651
706
|
contentType: e,
|
|
652
707
|
robustness: t,
|
|
653
|
-
encryptionScheme:
|
|
708
|
+
encryptionScheme: I.scheme
|
|
654
709
|
});
|
|
655
|
-
|
|
710
|
+
Be(e)("com.widevine.alpha", [{
|
|
656
711
|
initDataTypes: ["cenc"],
|
|
657
712
|
distinctiveIdentifier: "optional",
|
|
658
713
|
persistentState: "optional",
|
|
659
714
|
sessionTypes: ["temporary"],
|
|
660
|
-
audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"",
|
|
661
|
-
videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"",
|
|
715
|
+
audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"", I.audio)],
|
|
716
|
+
videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"", I.video)]
|
|
662
717
|
}]).then((e) => e.createMediaKeys()).catch(() => {});
|
|
663
718
|
}
|
|
664
|
-
function
|
|
665
|
-
let t =
|
|
719
|
+
function L(e) {
|
|
720
|
+
let t = R(e);
|
|
666
721
|
if (/^avc[13]/.test(t)) return "avc";
|
|
667
722
|
if (/^(hvc1|hev1)/.test(t)) return "hevc";
|
|
668
723
|
if (/^(dvh1|dvhe)/.test(t)) return "dv";
|
|
669
724
|
if (t.startsWith("av01")) return "av1";
|
|
670
725
|
if (/^vp0?9/.test(t)) return "vp9";
|
|
671
726
|
}
|
|
672
|
-
function
|
|
727
|
+
function R(e) {
|
|
673
728
|
return (e ?? "").trim().toLowerCase();
|
|
674
729
|
}
|
|
675
|
-
var
|
|
730
|
+
var He = {
|
|
676
731
|
hevc: "hvc1.1.6.L93.90",
|
|
677
732
|
dv: "dvh1.05.06",
|
|
678
733
|
av1: "av01.0.05M.08",
|
|
679
734
|
vp9: "vp09.00.10.08"
|
|
680
|
-
},
|
|
681
|
-
function
|
|
682
|
-
let t =
|
|
735
|
+
}, Ue = /* @__PURE__ */ new Map(), z = /* @__PURE__ */ new Map();
|
|
736
|
+
function We(e) {
|
|
737
|
+
let t = R(e), n = Ue.get(t);
|
|
683
738
|
if (n) return n;
|
|
684
739
|
let r = {
|
|
685
740
|
initDataTypes: ["cenc"],
|
|
@@ -688,32 +743,32 @@ function Me(e) {
|
|
|
688
743
|
sessionTypes: ["temporary"],
|
|
689
744
|
videoCapabilities: [{
|
|
690
745
|
contentType: `video/mp4; codecs="${e.trim()}"`,
|
|
691
|
-
robustness:
|
|
692
|
-
encryptionScheme:
|
|
746
|
+
robustness: I.video,
|
|
747
|
+
encryptionScheme: I.scheme
|
|
693
748
|
}]
|
|
694
749
|
}, i = (async () => {
|
|
695
750
|
try {
|
|
696
|
-
return await navigator.requestMediaKeySystemAccess("com.widevine.alpha",
|
|
751
|
+
return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", F("com.widevine.alpha", [r])), !0;
|
|
697
752
|
} catch {
|
|
698
753
|
return !1;
|
|
699
754
|
}
|
|
700
755
|
})().then((e) => (z.set(t, e), e));
|
|
701
|
-
return
|
|
756
|
+
return Ue.set(t, i), i;
|
|
702
757
|
}
|
|
703
|
-
function
|
|
704
|
-
if (
|
|
758
|
+
function Ge() {
|
|
759
|
+
if (N()) for (let e of Object.values(He)) We(e);
|
|
705
760
|
}
|
|
706
|
-
function
|
|
707
|
-
let t =
|
|
708
|
-
if (t) return t === "avc" ? !0 : z.get(
|
|
761
|
+
function Ke(e) {
|
|
762
|
+
let t = L(e);
|
|
763
|
+
if (t) return t === "avc" ? !0 : z.get(R(e)) ?? z.get(R(He[t]));
|
|
709
764
|
}
|
|
710
765
|
//#endregion
|
|
711
766
|
//#region src/core/drm/support.ts
|
|
712
|
-
var
|
|
767
|
+
var qe = 5e3, Je = "video/mp4; codecs=\"avc1.42E01E\"", Ye = "audio/mp4; codecs=\"mp4a.40.2\"", Xe = {
|
|
713
768
|
widevine: ["com.widevine.alpha"],
|
|
714
769
|
fairplay: ["com.apple.fps"]
|
|
715
770
|
};
|
|
716
|
-
function
|
|
771
|
+
function Ze(e) {
|
|
717
772
|
return e === "fairplay" ? [{
|
|
718
773
|
initDataTypes: [
|
|
719
774
|
"sinf",
|
|
@@ -721,30 +776,30 @@ function ze(e) {
|
|
|
721
776
|
"cenc"
|
|
722
777
|
],
|
|
723
778
|
videoCapabilities: [{
|
|
724
|
-
contentType:
|
|
779
|
+
contentType: Je,
|
|
725
780
|
robustness: "",
|
|
726
781
|
encryptionScheme: "cbcs"
|
|
727
782
|
}],
|
|
728
783
|
audioCapabilities: [{
|
|
729
|
-
contentType:
|
|
784
|
+
contentType: Ye,
|
|
730
785
|
robustness: "",
|
|
731
786
|
encryptionScheme: "cbcs"
|
|
732
787
|
}]
|
|
733
|
-
}] :
|
|
788
|
+
}] : F("com.widevine.alpha", [{
|
|
734
789
|
initDataTypes: ["cenc"],
|
|
735
790
|
videoCapabilities: [{
|
|
736
|
-
contentType:
|
|
737
|
-
robustness:
|
|
738
|
-
encryptionScheme:
|
|
791
|
+
contentType: Je,
|
|
792
|
+
robustness: I.video,
|
|
793
|
+
encryptionScheme: I.scheme
|
|
739
794
|
}],
|
|
740
795
|
audioCapabilities: [{
|
|
741
|
-
contentType:
|
|
742
|
-
robustness:
|
|
743
|
-
encryptionScheme:
|
|
796
|
+
contentType: Ye,
|
|
797
|
+
robustness: I.audio,
|
|
798
|
+
encryptionScheme: I.scheme
|
|
744
799
|
}]
|
|
745
800
|
}]);
|
|
746
801
|
}
|
|
747
|
-
function
|
|
802
|
+
function Qe(e, t) {
|
|
748
803
|
return new Promise((n, r) => {
|
|
749
804
|
let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
|
|
750
805
|
e.then((e) => {
|
|
@@ -754,8 +809,8 @@ function Be(e, t) {
|
|
|
754
809
|
});
|
|
755
810
|
});
|
|
756
811
|
}
|
|
757
|
-
async function
|
|
758
|
-
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ??
|
|
812
|
+
async function $e(e = {}) {
|
|
813
|
+
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? qe, r = {};
|
|
759
814
|
if (typeof window < "u" && window.isSecureContext === !1) return {
|
|
760
815
|
verdict: "insecure-context",
|
|
761
816
|
detail: r
|
|
@@ -767,7 +822,7 @@ async function Ve(e = {}) {
|
|
|
767
822
|
};
|
|
768
823
|
let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
|
|
769
824
|
for (let e of t) {
|
|
770
|
-
let t =
|
|
825
|
+
let t = Xe[e];
|
|
771
826
|
if (!t) {
|
|
772
827
|
r[e] = "unknown system";
|
|
773
828
|
continue;
|
|
@@ -778,7 +833,7 @@ async function Ve(e = {}) {
|
|
|
778
833
|
break;
|
|
779
834
|
}
|
|
780
835
|
try {
|
|
781
|
-
return await
|
|
836
|
+
return await Qe((await Qe(i(n, Ze(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
|
|
782
837
|
verdict: "supported",
|
|
783
838
|
system: e,
|
|
784
839
|
detail: r
|
|
@@ -802,37 +857,37 @@ async function Ve(e = {}) {
|
|
|
802
857
|
}
|
|
803
858
|
//#endregion
|
|
804
859
|
//#region src/core/manifest.ts
|
|
805
|
-
var
|
|
806
|
-
function
|
|
807
|
-
return
|
|
860
|
+
var et = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
|
|
861
|
+
function tt(e) {
|
|
862
|
+
return et.test(e);
|
|
808
863
|
}
|
|
809
864
|
//#endregion
|
|
810
865
|
//#region src/core/env.ts
|
|
811
|
-
var
|
|
866
|
+
var nt = {
|
|
812
867
|
integration: "https://feed-dev.oddin-video.gg",
|
|
813
868
|
production: "https://feed.oddin-video.gg"
|
|
814
869
|
};
|
|
815
|
-
function
|
|
816
|
-
let t = Object.prototype.hasOwnProperty.call(
|
|
870
|
+
function rt(e) {
|
|
871
|
+
let t = Object.prototype.hasOwnProperty.call(nt, e) ? nt[e] : void 0;
|
|
817
872
|
if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
|
|
818
873
|
return t;
|
|
819
874
|
}
|
|
820
875
|
//#endregion
|
|
821
876
|
//#region src/core/stats.ts
|
|
822
|
-
var
|
|
823
|
-
function
|
|
877
|
+
var it = { droppedFrames: 0 };
|
|
878
|
+
function at(e) {
|
|
824
879
|
try {
|
|
825
880
|
return new URL(e).host;
|
|
826
881
|
} catch {
|
|
827
882
|
return "";
|
|
828
883
|
}
|
|
829
884
|
}
|
|
830
|
-
var
|
|
831
|
-
function
|
|
885
|
+
var ot = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
|
|
886
|
+
function st(e) {
|
|
832
887
|
if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
|
|
833
888
|
let t = "", n = -1, r = performance.getEntriesByType("resource");
|
|
834
|
-
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" ||
|
|
835
|
-
let e =
|
|
889
|
+
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || ot.test(i.name)) && i.startTime >= n) {
|
|
890
|
+
let e = at(i.name);
|
|
836
891
|
e && (t = e, n = i.startTime);
|
|
837
892
|
}
|
|
838
893
|
return t;
|
|
@@ -844,7 +899,7 @@ function B(e) {
|
|
|
844
899
|
totalFrames: t?.totalVideoFrames ?? 0
|
|
845
900
|
};
|
|
846
901
|
}
|
|
847
|
-
var
|
|
902
|
+
var ct = class {
|
|
848
903
|
video;
|
|
849
904
|
baseFrames = 0;
|
|
850
905
|
baseDropped = 0;
|
|
@@ -867,7 +922,7 @@ var Xe = class {
|
|
|
867
922
|
};
|
|
868
923
|
}
|
|
869
924
|
};
|
|
870
|
-
function
|
|
925
|
+
function lt(e, t) {
|
|
871
926
|
let n = [
|
|
872
927
|
["playing", () => t("playing")],
|
|
873
928
|
["waiting", () => t("buffering")],
|
|
@@ -884,8 +939,8 @@ function Ze(e, t) {
|
|
|
884
939
|
}
|
|
885
940
|
//#endregion
|
|
886
941
|
//#region src/core/engine/native.ts
|
|
887
|
-
var
|
|
888
|
-
function
|
|
942
|
+
var ut = 2e3, dt = 3, V = 500, ft = 6e3, pt = .25, mt = 250, ht = .05, gt = 4, _t = 12e3, vt = .25, yt = 1e3;
|
|
943
|
+
function bt(e) {
|
|
889
944
|
try {
|
|
890
945
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
891
946
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -901,7 +956,7 @@ function U() {
|
|
|
901
956
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
902
957
|
return e || t;
|
|
903
958
|
}
|
|
904
|
-
function
|
|
959
|
+
function xt() {
|
|
905
960
|
if (typeof navigator > "u" || !U()) return !1;
|
|
906
961
|
let e = navigator.userAgent ?? "";
|
|
907
962
|
return /iPhone|iPad|iPod/.test(e) ? !0 : /Macintosh/.test(e) && typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1;
|
|
@@ -936,7 +991,7 @@ var W = class {
|
|
|
936
991
|
frameCounter;
|
|
937
992
|
detachFrames = null;
|
|
938
993
|
constructor(e) {
|
|
939
|
-
this.deps = e, this.frameCounter = new
|
|
994
|
+
this.deps = e, this.frameCounter = new ct(e.video), this.loadStarted = e.deferLoad !== !0, this.builtAt = typeof performance < "u" ? performance.now() : 0;
|
|
940
995
|
}
|
|
941
996
|
async load() {
|
|
942
997
|
this.detachFrames ??= this.frameCounter.attach();
|
|
@@ -957,7 +1012,7 @@ var W = class {
|
|
|
957
1012
|
type: "error",
|
|
958
1013
|
error: new n("INTERNAL", 0, "native HLS playback error"),
|
|
959
1014
|
fatal: !0
|
|
960
|
-
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src =
|
|
1015
|
+
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = Ct(t.manifestUrl, t.analytics?.sid), e.load();
|
|
961
1016
|
}
|
|
962
1017
|
startLoad() {
|
|
963
1018
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -979,7 +1034,7 @@ var W = class {
|
|
|
979
1034
|
});
|
|
980
1035
|
this.onEncrypted = (n) => {
|
|
981
1036
|
let i = n;
|
|
982
|
-
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
1037
|
+
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = bt(i.initData), (async () => {
|
|
983
1038
|
try {
|
|
984
1039
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
985
1040
|
initDataTypes: [i.initDataType],
|
|
@@ -1078,10 +1133,10 @@ var W = class {
|
|
|
1078
1133
|
droppedFrames: t.dropped,
|
|
1079
1134
|
decodedFrames: t.totalFrames
|
|
1080
1135
|
};
|
|
1081
|
-
if (this.cdnHost ||=
|
|
1136
|
+
if (this.cdnHost ||= st(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
|
|
1082
1137
|
n.isLive = !0;
|
|
1083
1138
|
let t = this.liveEdgeEstimate(), r = t == null ? NaN : t - e.currentTime;
|
|
1084
|
-
Number.isFinite(r) && (n.atLiveEdge = r <=
|
|
1139
|
+
Number.isFinite(r) && (n.atLiveEdge = r <= gt, !e.paused && r >= 0 && (n.latencySeconds = r));
|
|
1085
1140
|
} else Number.isFinite(e.duration) && e.duration > 0 && (n.isLive = !1);
|
|
1086
1141
|
return n;
|
|
1087
1142
|
}
|
|
@@ -1099,7 +1154,7 @@ var W = class {
|
|
|
1099
1154
|
return;
|
|
1100
1155
|
}
|
|
1101
1156
|
let t = this.hiddenSince;
|
|
1102
|
-
this.hiddenSince = null, t != null && e - t >=
|
|
1157
|
+
this.hiddenSince = null, t != null && e - t >= ut && this.armRefocus();
|
|
1103
1158
|
}, this.onPageShow = (e) => {
|
|
1104
1159
|
e.persisted && this.armRefocus();
|
|
1105
1160
|
}, document.addEventListener("visibilitychange", this.onVisibility), typeof window < "u" && window.addEventListener("pageshow", this.onPageShow));
|
|
@@ -1109,7 +1164,7 @@ var W = class {
|
|
|
1109
1164
|
let e = this.liveEnd(), t = G, n = t(), r = 0, i = () => {
|
|
1110
1165
|
if (this.refocusTimer = null, Number.isFinite(this.deps.video.duration)) return;
|
|
1111
1166
|
r += V;
|
|
1112
|
-
let a = this.liveEnd(), o = a != null && (e == null || a >= e +
|
|
1167
|
+
let a = this.liveEnd(), o = a != null && (e == null || a >= e + pt), s = Math.max(r, t() - n) >= ft;
|
|
1113
1168
|
if (o || s && a != null) {
|
|
1114
1169
|
this.snapToLive();
|
|
1115
1170
|
return;
|
|
@@ -1129,9 +1184,9 @@ var W = class {
|
|
|
1129
1184
|
}, e.addEventListener("seeking", this.onEdgeReset), e.addEventListener("emptied", this.onEdgeReset), this.edgeTimer = setInterval(() => {
|
|
1130
1185
|
if (e.duration !== Infinity) return;
|
|
1131
1186
|
this.checkEndStale();
|
|
1132
|
-
let t =
|
|
1133
|
-
t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >=
|
|
1134
|
-
},
|
|
1187
|
+
let t = St(e, e.currentTime);
|
|
1188
|
+
t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >= ht) && (this.bufferedAdvancedAt = G()), this.lastBufferedEnd = t);
|
|
1189
|
+
}, mt);
|
|
1135
1190
|
}
|
|
1136
1191
|
checkEndStale() {
|
|
1137
1192
|
if (this.endedEmitted) return;
|
|
@@ -1139,14 +1194,14 @@ var W = class {
|
|
|
1139
1194
|
this.lastTickAt = e;
|
|
1140
1195
|
let n = this.liveEnd();
|
|
1141
1196
|
if (n == null) return;
|
|
1142
|
-
let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >=
|
|
1197
|
+
let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >= vt;
|
|
1143
1198
|
this.lastSeekableEnd = n;
|
|
1144
1199
|
let i = this.deps.video, a = typeof document < "u" && document.visibilityState === "hidden";
|
|
1145
|
-
if (r || t >
|
|
1200
|
+
if (r || t > yt || a || i.paused) {
|
|
1146
1201
|
this.edgeStampedAt = e;
|
|
1147
1202
|
return;
|
|
1148
1203
|
}
|
|
1149
|
-
e - (this.edgeStampedAt ?? e) >
|
|
1204
|
+
e - (this.edgeStampedAt ?? e) > _t && (this.endedEmitted = !0, this.deps.emit({
|
|
1150
1205
|
type: "ended",
|
|
1151
1206
|
reason: "stalled"
|
|
1152
1207
|
}));
|
|
@@ -1160,7 +1215,7 @@ var W = class {
|
|
|
1160
1215
|
liveEdgeEstimate() {
|
|
1161
1216
|
let e = this.deps.video;
|
|
1162
1217
|
if (e.duration !== Infinity) return null;
|
|
1163
|
-
let t = this.liveEnd(), n =
|
|
1218
|
+
let t = this.liveEnd(), n = St(e, e.currentTime) ?? this.lastBufferedEnd;
|
|
1164
1219
|
if (n != null) {
|
|
1165
1220
|
let e = this.bufferedAdvancedAt, r = n + (e == null ? 0 : Math.max(0, (G() - e) / 1e3));
|
|
1166
1221
|
(t == null || r > t) && (t = r);
|
|
@@ -1176,7 +1231,7 @@ var W = class {
|
|
|
1176
1231
|
snapToLive() {
|
|
1177
1232
|
let e = this.deps.video, t = this.liveEnd();
|
|
1178
1233
|
if (t == null) return;
|
|
1179
|
-
let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t -
|
|
1234
|
+
let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t - dt, r);
|
|
1180
1235
|
try {
|
|
1181
1236
|
e.currentTime = i;
|
|
1182
1237
|
} catch {}
|
|
@@ -1197,7 +1252,7 @@ var W = class {
|
|
|
1197
1252
|
function G() {
|
|
1198
1253
|
return typeof performance < "u" ? performance.now() : Date.now();
|
|
1199
1254
|
}
|
|
1200
|
-
function
|
|
1255
|
+
function St(e, t) {
|
|
1201
1256
|
let n = e.buffered;
|
|
1202
1257
|
if (!n || !Number.isFinite(t)) return null;
|
|
1203
1258
|
for (let e = 0; e < n.length; e += 1) if (n.start(e) <= t + .1 && n.end(e) > t) {
|
|
@@ -1206,7 +1261,7 @@ function ut(e, t) {
|
|
|
1206
1261
|
}
|
|
1207
1262
|
return null;
|
|
1208
1263
|
}
|
|
1209
|
-
function
|
|
1264
|
+
function Ct(e, t) {
|
|
1210
1265
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
1211
1266
|
}
|
|
1212
1267
|
//#endregion
|
|
@@ -1223,8 +1278,8 @@ function K(e, t = Date.now()) {
|
|
|
1223
1278
|
}
|
|
1224
1279
|
//#endregion
|
|
1225
1280
|
//#region src/core/engine/prefetch.ts
|
|
1226
|
-
var
|
|
1227
|
-
function
|
|
1281
|
+
var wt = 15e3, Tt = 5e3, Et = 6;
|
|
1282
|
+
function Dt(e) {
|
|
1228
1283
|
try {
|
|
1229
1284
|
let t = new URL(e);
|
|
1230
1285
|
return t.searchParams.delete("CMCD"), t.toString();
|
|
@@ -1232,7 +1287,7 @@ function ht(e) {
|
|
|
1232
1287
|
return e;
|
|
1233
1288
|
}
|
|
1234
1289
|
}
|
|
1235
|
-
var
|
|
1290
|
+
var Ot = class {
|
|
1236
1291
|
cmcd;
|
|
1237
1292
|
entries = /* @__PURE__ */ new Map();
|
|
1238
1293
|
keyed = /* @__PURE__ */ new Set();
|
|
@@ -1255,10 +1310,10 @@ var gt = class {
|
|
|
1255
1310
|
}
|
|
1256
1311
|
prefetch(e, t, n) {
|
|
1257
1312
|
if (!this.isActive(t)) return;
|
|
1258
|
-
let r =
|
|
1313
|
+
let r = Dt(e);
|
|
1259
1314
|
if (this.entries.has(r)) return;
|
|
1260
1315
|
let i = this.perTrack.get(t) ?? 0;
|
|
1261
|
-
if (i >=
|
|
1316
|
+
if (i >= Et) return;
|
|
1262
1317
|
this.perTrack.set(t, i + 1);
|
|
1263
1318
|
let a = new AbortController(), o = {
|
|
1264
1319
|
started: performance.now(),
|
|
@@ -1272,10 +1327,10 @@ var gt = class {
|
|
|
1272
1327
|
signal: a.signal
|
|
1273
1328
|
}).then(async (e) => (o.first = performance.now(), e.ok ? e.arrayBuffer() : null)).catch(() => null), this.entries.set(r, o), this.stats.started += 1, setTimeout(() => {
|
|
1274
1329
|
this.entries.get(r) === o && (this.entries.delete(r), a.abort(), this.stats.expired += 1);
|
|
1275
|
-
},
|
|
1330
|
+
}, wt);
|
|
1276
1331
|
}
|
|
1277
1332
|
take(e) {
|
|
1278
|
-
let t =
|
|
1333
|
+
let t = Dt(e), n = this.entries.get(t);
|
|
1279
1334
|
return n && this.entries.delete(t), n;
|
|
1280
1335
|
}
|
|
1281
1336
|
destroy() {
|
|
@@ -1295,13 +1350,13 @@ var gt = class {
|
|
|
1295
1350
|
}
|
|
1296
1351
|
}
|
|
1297
1352
|
};
|
|
1298
|
-
function
|
|
1353
|
+
function kt(t) {
|
|
1299
1354
|
let n = e.DefaultConfig?.loader;
|
|
1300
1355
|
if (typeof n != "function") return;
|
|
1301
1356
|
class r extends n {
|
|
1302
1357
|
served = !1;
|
|
1303
1358
|
cancelled = !1;
|
|
1304
|
-
stats =
|
|
1359
|
+
stats = At();
|
|
1305
1360
|
load(e, n, r) {
|
|
1306
1361
|
let i = e.rangeEnd ? void 0 : t.take(e.url);
|
|
1307
1362
|
if (!i) {
|
|
@@ -1309,7 +1364,7 @@ function _t(t) {
|
|
|
1309
1364
|
return;
|
|
1310
1365
|
}
|
|
1311
1366
|
this.served = !0;
|
|
1312
|
-
let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs ||
|
|
1367
|
+
let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs || Tt, s = setTimeout(() => {
|
|
1313
1368
|
!this.cancelled && this.served && (i.abort.abort(), t.stats.failed += 1, this.served = !1, super.load(e, n, r));
|
|
1314
1369
|
}, o);
|
|
1315
1370
|
i.bytes.then((o) => {
|
|
@@ -1336,7 +1391,7 @@ function _t(t) {
|
|
|
1336
1391
|
}
|
|
1337
1392
|
return r;
|
|
1338
1393
|
}
|
|
1339
|
-
function
|
|
1394
|
+
function At() {
|
|
1340
1395
|
return {
|
|
1341
1396
|
aborted: !1,
|
|
1342
1397
|
loaded: 0,
|
|
@@ -1360,10 +1415,10 @@ function vt() {
|
|
|
1360
1415
|
}
|
|
1361
1416
|
};
|
|
1362
1417
|
}
|
|
1363
|
-
function
|
|
1418
|
+
function jt(e) {
|
|
1364
1419
|
return e === "audio" ? "audio" : "main";
|
|
1365
1420
|
}
|
|
1366
|
-
function
|
|
1421
|
+
function Mt(e, t) {
|
|
1367
1422
|
let n = [];
|
|
1368
1423
|
t.initSegment?.url && !t.initSegment.data && n.push({
|
|
1369
1424
|
url: t.initSegment.url,
|
|
@@ -1382,24 +1437,24 @@ function yt(e, t) {
|
|
|
1382
1437
|
}
|
|
1383
1438
|
//#endregion
|
|
1384
1439
|
//#region src/core/engine/hls.ts
|
|
1385
|
-
function
|
|
1440
|
+
function Nt() {
|
|
1386
1441
|
return e.isSupported();
|
|
1387
1442
|
}
|
|
1388
|
-
var
|
|
1389
|
-
function
|
|
1443
|
+
var Pt = 1e6, Ft = 20, It = 1e4, Lt = 3, Rt = 5, zt = 3, Bt = 1e4, Vt = 3e4, Ht = 12e3, Ut = 3e3, Wt = .02, Gt = 6e3, Kt = .5, qt = 3, Jt = .5, Yt = 1.1, Xt = .25, Zt = 5e3, Qt = 4e3, $t = 2, en = 5, tn = 2, nn = 2, rn = 4, an = 4, on = 2e3, sn = 3e4, cn = .2, ln = 30, un = 2, dn = 2, fn = 9, pn = .5, mn = 64;
|
|
1444
|
+
function hn(e) {
|
|
1390
1445
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
1391
1446
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
1392
1447
|
return;
|
|
1393
1448
|
}
|
|
1394
|
-
e.liveSyncDuration ??=
|
|
1395
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
1396
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
1449
|
+
e.liveSyncDuration ??= dn;
|
|
1450
|
+
let t = Math.max(12, e.liveSyncDuration + fn);
|
|
1451
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), gn(e, e.liveSyncDuration);
|
|
1397
1452
|
}
|
|
1398
|
-
function
|
|
1453
|
+
function gn(e, t) {
|
|
1399
1454
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
1400
1455
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
1401
1456
|
}
|
|
1402
|
-
var
|
|
1457
|
+
var _n = class {
|
|
1403
1458
|
name = "hls";
|
|
1404
1459
|
hls = null;
|
|
1405
1460
|
deps;
|
|
@@ -1451,6 +1506,8 @@ var en = class {
|
|
|
1451
1506
|
starvedFrames = 0;
|
|
1452
1507
|
deadTicks = 0;
|
|
1453
1508
|
mainFragsSinceTick = 0;
|
|
1509
|
+
bwFragsLoaded = 0;
|
|
1510
|
+
bwSavedAt = 0;
|
|
1454
1511
|
recentMainFrags = [];
|
|
1455
1512
|
chaseSuspended = !1;
|
|
1456
1513
|
savedLiveMaxLatency;
|
|
@@ -1481,7 +1538,7 @@ var en = class {
|
|
|
1481
1538
|
frameCounter;
|
|
1482
1539
|
detachFrames = null;
|
|
1483
1540
|
constructor(e) {
|
|
1484
|
-
this.deps = e, this.frameCounter = new
|
|
1541
|
+
this.deps = e, this.frameCounter = new ct(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
1485
1542
|
}
|
|
1486
1543
|
async load() {
|
|
1487
1544
|
this.detachFrames ??= this.frameCounter.attach();
|
|
@@ -1494,7 +1551,7 @@ var en = class {
|
|
|
1494
1551
|
});
|
|
1495
1552
|
return;
|
|
1496
1553
|
}
|
|
1497
|
-
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (
|
|
1554
|
+
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ve(r), Ge()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
|
|
1498
1555
|
let e = this.hls;
|
|
1499
1556
|
if (document.visibilityState !== "visible" || !e) return;
|
|
1500
1557
|
let t = e.liveSyncPosition;
|
|
@@ -1517,7 +1574,7 @@ var en = class {
|
|
|
1517
1574
|
}
|
|
1518
1575
|
this.loadSuspended = !0;
|
|
1519
1576
|
}
|
|
1520
|
-
},
|
|
1577
|
+
}, Zt));
|
|
1521
1578
|
}
|
|
1522
1579
|
resumeLoading() {
|
|
1523
1580
|
if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.resetChaseWindow(), this.resetFrameDropWindow(), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
|
|
@@ -1549,7 +1606,7 @@ var en = class {
|
|
|
1549
1606
|
let t = e.liveSyncPosition;
|
|
1550
1607
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1551
1608
|
let { video: n } = this.deps;
|
|
1552
|
-
n.currentTime <= t +
|
|
1609
|
+
n.currentTime <= t + pn || (n.currentTime = t);
|
|
1553
1610
|
}
|
|
1554
1611
|
reanchorPartTimeline(e, t) {
|
|
1555
1612
|
let { frag: n, part: r } = t;
|
|
@@ -1561,7 +1618,7 @@ var en = class {
|
|
|
1561
1618
|
let o = n.sn, s = i.fragments.find((e) => e && e.sn === o) ?? (i.fragmentHint?.sn === o ? i.fragmentHint : void 0);
|
|
1562
1619
|
if (!s) return;
|
|
1563
1620
|
let c = a.startPTS - s.start;
|
|
1564
|
-
if (!(!Number.isFinite(c) || Math.abs(c) <
|
|
1621
|
+
if (!(!Number.isFinite(c) || Math.abs(c) < Wt)) {
|
|
1565
1622
|
for (let e of i.fragments) e && e.setStart(e.start + c);
|
|
1566
1623
|
i.fragmentHint?.setStart(i.fragmentHint.start + c), this.deps.debug === !0 && console.info(`havik-player: LL-HLS timeline re-anchored by ${c >= 0 ? "+" : ""}${c.toFixed(3)}s at sn ${n.sn} (level ${n.level})`);
|
|
1567
1624
|
}
|
|
@@ -1577,19 +1634,19 @@ var en = class {
|
|
|
1577
1634
|
liveDurationInfinity: !0,
|
|
1578
1635
|
maxBufferHole: .5,
|
|
1579
1636
|
maxLiveSyncPlaybackRate: d ? 1 : 1.1,
|
|
1580
|
-
abrEwmaDefaultEstimate:
|
|
1637
|
+
abrEwmaDefaultEstimate: this.startEstimate(),
|
|
1581
1638
|
capLevelToPlayerSize: !1,
|
|
1582
1639
|
...this.loadStarted ? {} : { autoStartLoad: !1 },
|
|
1583
1640
|
...u ? {
|
|
1584
1641
|
emeEnabled: !0,
|
|
1585
1642
|
drmSystems: { ...this.licenseUrl ? { "com.widevine.alpha": { licenseUrl: this.licenseUrl } } : {} },
|
|
1586
1643
|
drmSystemOptions: {
|
|
1587
|
-
videoRobustness:
|
|
1588
|
-
audioRobustness:
|
|
1589
|
-
videoEncryptionScheme:
|
|
1590
|
-
audioEncryptionScheme:
|
|
1644
|
+
videoRobustness: I.video,
|
|
1645
|
+
audioRobustness: I.audio,
|
|
1646
|
+
videoEncryptionScheme: I.scheme,
|
|
1647
|
+
audioEncryptionScheme: I.scheme
|
|
1591
1648
|
},
|
|
1592
|
-
...
|
|
1649
|
+
...N() ? { requestMediaKeySystemAccessFunc: Be(t) } : {},
|
|
1593
1650
|
licenseXhrSetup: (e, t) => {
|
|
1594
1651
|
let o = performance.now(), s = () => {
|
|
1595
1652
|
e.open("POST", this.licenseUrl ?? t, !0), e.setRequestHeader("x-api-key", r.apiKey), e.setRequestHeader("X-Match-Urn", n.matchUrn), e.setRequestHeader("X-Device-Id", i), a && e.setRequestHeader("X-User-Id", a), this.licenseRequested = !0, e.addEventListener("loadend", () => {
|
|
@@ -1601,7 +1658,7 @@ var en = class {
|
|
|
1601
1658
|
return;
|
|
1602
1659
|
}
|
|
1603
1660
|
let l = this.hls, u, d = new Promise((e) => {
|
|
1604
|
-
u = setTimeout(() => e(void 0),
|
|
1661
|
+
u = setTimeout(() => e(void 0), Bt);
|
|
1605
1662
|
});
|
|
1606
1663
|
return Promise.race([c().catch(() => void 0), d]).finally(() => clearTimeout(u)).then((e) => {
|
|
1607
1664
|
if (!this.hls || this.hls !== l) throw Error("havik-player: engine torn down during refresh");
|
|
@@ -1617,31 +1674,31 @@ var en = class {
|
|
|
1617
1674
|
...c
|
|
1618
1675
|
};
|
|
1619
1676
|
if (this.prefetch?.destroy(), this.prefetch = null, u && this.deps.mediaDuringKey !== !1 && !f.fLoader) {
|
|
1620
|
-
let e = new
|
|
1677
|
+
let e = new Ot({
|
|
1621
1678
|
sessionId: n.analytics?.sid,
|
|
1622
1679
|
contentId: n.matchUrn
|
|
1623
|
-
}), t =
|
|
1680
|
+
}), t = kt(e);
|
|
1624
1681
|
t && (this.prefetch = e, f.fLoader = t);
|
|
1625
1682
|
}
|
|
1626
|
-
|
|
1683
|
+
hn(f), this.catchUpRate = typeof f.maxLiveSyncPlaybackRate == "number" ? f.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (f.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = f.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = f.autoStartLoad !== !1;
|
|
1627
1684
|
let p = new e(f);
|
|
1628
1685
|
if (this.hls = p, p.on(e.Events.FRAG_PARSED, (e, t) => this.reanchorPartTimeline(p, t)), p.on(e.Events.MANIFEST_PARSED, () => {
|
|
1629
1686
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, u && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && this.dropLevelsWidevineCannotPlay(p), this.measureLadder(p), this.applySizeCap(), this.loadSuspended = !1, t.paused && this.schedulePauseSuspend(), l({ type: "ready" });
|
|
1630
1687
|
}), p.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1631
1688
|
t?.frag?.type === "main" && (this.kickKind !== "dead" && this.clearKick(), (this.mediaRecoveries > 0 || this.networkRecoveries > 0 || this.licenseRecoveries > 0 || this.starvationKicks > 0 || this.starvationRebuilds > 0) && !this.recoveryResetTimer && (this.recoveryResetTimer = setTimeout(() => {
|
|
1632
1689
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1633
|
-
},
|
|
1690
|
+
}, Vt)));
|
|
1634
1691
|
}), p.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1635
1692
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1636
1693
|
}), p.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
1637
|
-
t?.frag?.type === "main" && (this.mainFragsSinceTick += 1);
|
|
1694
|
+
t?.frag?.type === "main" && (this.mainFragsSinceTick += 1, this.bwFragsLoaded += 1, this.maybeRememberBandwidth(!1));
|
|
1638
1695
|
let n = t?.frag?.stats, r = n?.loaded;
|
|
1639
1696
|
typeof r == "number" && (this.bytesLoaded += r), !this.reportedFirstBytes && typeof r == "number" && r > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
|
|
1640
1697
|
let i = n?.loading;
|
|
1641
|
-
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 >
|
|
1698
|
+
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 > mn && this.requestTimesMs.shift());
|
|
1642
1699
|
let a = t?.frag?.url;
|
|
1643
1700
|
if (a) {
|
|
1644
|
-
let e =
|
|
1701
|
+
let e = at(a);
|
|
1645
1702
|
e && (this.cdnHost = e);
|
|
1646
1703
|
}
|
|
1647
1704
|
}), p.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1655,15 +1712,15 @@ var en = class {
|
|
|
1655
1712
|
}), p.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.prefetch) {
|
|
1656
1713
|
let t = this.prefetch;
|
|
1657
1714
|
p.on(e.Events.KEY_LOADING, (e, n) => {
|
|
1658
|
-
let r = n?.frag, i =
|
|
1659
|
-
if (r && t.isActive(i)) for (let e of
|
|
1660
|
-
}), p.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(
|
|
1715
|
+
let r = n?.frag, i = jt(r?.type);
|
|
1716
|
+
if (r && t.isActive(i)) for (let e of Mt(p, r)) t.prefetch(e.url, i, e.kind);
|
|
1717
|
+
}), p.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(jt(n?.frag?.type)));
|
|
1661
1718
|
}
|
|
1662
1719
|
p.on(e.Events.KEY_LOADED, () => {
|
|
1663
1720
|
u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
|
|
1664
1721
|
}), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1665
1722
|
this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.checkFrameDrops();
|
|
1666
|
-
},
|
|
1723
|
+
}, Ut), p.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1667
1724
|
this.renditionSwitches += 1;
|
|
1668
1725
|
let n = this.lastLevelIndex >= 0 ? p.levels[this.lastLevelIndex] : void 0, r = p.levels[t.level];
|
|
1669
1726
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
|
|
@@ -1727,7 +1784,7 @@ var en = class {
|
|
|
1727
1784
|
return;
|
|
1728
1785
|
}
|
|
1729
1786
|
this.capTimer && clearTimeout(this.capTimer);
|
|
1730
|
-
let t = e > this.sizeCapLevel ?
|
|
1787
|
+
let t = e > this.sizeCapLevel ? on : sn;
|
|
1731
1788
|
this.capTimer = setTimeout(() => {
|
|
1732
1789
|
this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
|
|
1733
1790
|
}, t);
|
|
@@ -1737,9 +1794,9 @@ var en = class {
|
|
|
1737
1794
|
this.ladderHeights = t.length ? [...new Set(t)].sort((e, t) => e - t) : void 0, this.ladderTopBitrateKbps = e.levels.length ? Math.round(Math.max(...e.levels.map((e) => e.bitrate)) / 1e3) : 0;
|
|
1738
1795
|
}
|
|
1739
1796
|
dropLevelsWidevineCannotPlay(e) {
|
|
1740
|
-
this.removeLevelsWhere(e, (e) =>
|
|
1741
|
-
let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e &&
|
|
1742
|
-
for (let n of t)
|
|
1797
|
+
this.removeLevelsWhere(e, (e) => Ke(e) !== !0);
|
|
1798
|
+
let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && L(e) !== "avc" && !!L(e)));
|
|
1799
|
+
for (let n of t) We(n).then((t) => {
|
|
1743
1800
|
t || this.hls !== e || this.removeLevelsWhere(e, (e) => e === n) && (this.measureLadder(e), this.applySizeCap());
|
|
1744
1801
|
});
|
|
1745
1802
|
}
|
|
@@ -1747,10 +1804,10 @@ var en = class {
|
|
|
1747
1804
|
let n = e.levels ?? [], r = [], i = /* @__PURE__ */ new Set();
|
|
1748
1805
|
if (n.forEach((e, n) => {
|
|
1749
1806
|
let a = e.videoCodec;
|
|
1750
|
-
a &&
|
|
1807
|
+
a && L(a) && t(a) && (r.push(n), i.add(a));
|
|
1751
1808
|
}), !r.length) return !1;
|
|
1752
1809
|
let a = [...i].join(", ");
|
|
1753
|
-
if (!n.some((e, t) => r.includes(t) ? !1 : !
|
|
1810
|
+
if (!n.some((e, t) => r.includes(t) ? !1 : !L(e.videoCodec) || Ke(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
|
|
1754
1811
|
for (let t = r.length - 1; t >= 0; --t) e.removeLevel(r[t]);
|
|
1755
1812
|
return console.info(`havik-player: skipped ${r.length} rendition(s) Widevine cannot play on this browser (${a})`), !0;
|
|
1756
1813
|
}
|
|
@@ -1856,7 +1913,7 @@ var en = class {
|
|
|
1856
1913
|
return;
|
|
1857
1914
|
}
|
|
1858
1915
|
let e = Date.now() - this.lastAdvanceMs;
|
|
1859
|
-
!this.chaseSuspended && e >
|
|
1916
|
+
!this.chaseSuspended && e > Gt && this.suspendChasing(), e > Ht && this.emitEnded("stalled");
|
|
1860
1917
|
}
|
|
1861
1918
|
resetStarvationWindow() {
|
|
1862
1919
|
this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
|
|
@@ -1871,7 +1928,7 @@ var en = class {
|
|
|
1871
1928
|
this.resetStarvationWindow();
|
|
1872
1929
|
return;
|
|
1873
1930
|
}
|
|
1874
|
-
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs <
|
|
1931
|
+
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < Gt, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > Qt, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = B(t), c = o - s, l = c !== this.starvedFrames;
|
|
1875
1932
|
if (this.starvedFrames = c, !a || l) {
|
|
1876
1933
|
(t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
|
|
1877
1934
|
return;
|
|
@@ -1880,12 +1937,12 @@ var en = class {
|
|
|
1880
1937
|
this.resetStarvationWindow();
|
|
1881
1938
|
return;
|
|
1882
1939
|
}
|
|
1883
|
-
if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length >
|
|
1940
|
+
if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length > rn && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= tn && (this.clearKick(), this.starvationRebuilds < nn)) {
|
|
1884
1941
|
this.starvationRebuilds += 1, this.resetStarvationWindow(), this.clearRecoveryReset(), console.warn("havik-player: restarting the load did not resume video (the wedge is in hls.js state that only a rebuild clears) — rebuilding the player"), this.rebuildInstance("starvation rebuild");
|
|
1885
1942
|
return;
|
|
1886
1943
|
}
|
|
1887
|
-
let u = i && this.starvedTicks >=
|
|
1888
|
-
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >=
|
|
1944
|
+
let u = i && this.starvedTicks >= $t, d = !i && this.deadTicks >= rn && this.recentMainFrags.reduce((e, t) => e + t, 0) >= an;
|
|
1945
|
+
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= en))) {
|
|
1889
1946
|
this.starvationKicks += 1, this.kickPending = !0, this.kickTicks = 0, this.kickKind = d ? "dead" : "quiet", this.clearRecoveryReset(), console.warn(d ? "havik-player: video starved while hls.js keeps loading media it never plays (dead pipeline at the live edge) — restarting the load" : "havik-player: video starved while the live playlist advances (wedged hls.js fragment pipeline) — restarting the load");
|
|
1890
1947
|
try {
|
|
1891
1948
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -1900,7 +1957,7 @@ var en = class {
|
|
|
1900
1957
|
let t = e.latency, n = e.targetLatency;
|
|
1901
1958
|
if (typeof t != "number" || typeof n != "number" || !Number.isFinite(t)) return;
|
|
1902
1959
|
let r = t - n;
|
|
1903
|
-
!this.catchUpEngaged && r >
|
|
1960
|
+
!this.catchUpEngaged && r > Kt ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= Kt && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
|
|
1904
1961
|
let i = this.catchUpEngaged ? this.catchUpRate : 1;
|
|
1905
1962
|
e.config.maxLiveSyncPlaybackRate !== i && (e.config.maxLiveSyncPlaybackRate = i);
|
|
1906
1963
|
}
|
|
@@ -1922,15 +1979,15 @@ var en = class {
|
|
|
1922
1979
|
return;
|
|
1923
1980
|
}
|
|
1924
1981
|
let { totalFrames: n, dropped: r } = B(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
|
|
1925
|
-
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a <
|
|
1982
|
+
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < ln || o < 0) {
|
|
1926
1983
|
this.fpsBadTicks = 0;
|
|
1927
1984
|
return;
|
|
1928
1985
|
}
|
|
1929
|
-
if (o <=
|
|
1986
|
+
if (o <= cn * a) {
|
|
1930
1987
|
this.fpsBadTicks = 0;
|
|
1931
1988
|
return;
|
|
1932
1989
|
}
|
|
1933
|
-
if (this.fpsBadTicks += 1, this.fpsBadTicks <
|
|
1990
|
+
if (this.fpsBadTicks += 1, this.fpsBadTicks < un) return;
|
|
1934
1991
|
this.fpsBadTicks = 0;
|
|
1935
1992
|
let s = e.levels, c = s[e.currentLevel];
|
|
1936
1993
|
if (!c) return;
|
|
@@ -1947,20 +2004,20 @@ var en = class {
|
|
|
1947
2004
|
return;
|
|
1948
2005
|
}
|
|
1949
2006
|
let n = e.latency, r = t.playbackRate, i = e.config.maxLiveSyncPlaybackRate;
|
|
1950
|
-
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(
|
|
2007
|
+
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(Yt, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
|
|
1951
2008
|
this.resetChaseWindow();
|
|
1952
2009
|
return;
|
|
1953
2010
|
}
|
|
1954
|
-
if (this.chaseLatency < 0 || this.chaseLatency - n >=
|
|
2011
|
+
if (this.chaseLatency < 0 || this.chaseLatency - n >= Jt) {
|
|
1955
2012
|
this.chaseLatency = n, this.chaseTicks = 0;
|
|
1956
2013
|
return;
|
|
1957
2014
|
}
|
|
1958
|
-
if (this.chaseTicks += 1, this.chaseTicks <
|
|
2015
|
+
if (this.chaseTicks += 1, this.chaseTicks < qt) return;
|
|
1959
2016
|
this.resetChaseWindow();
|
|
1960
2017
|
let a = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
|
|
1961
2018
|
if (!(a > 1)) return;
|
|
1962
2019
|
let o = typeof e.targetLatency == "number" ? e.targetLatency : 0, s = Math.min(n, a - 1);
|
|
1963
|
-
s < o +
|
|
2020
|
+
s < o + Xt || (console.warn(`havik-player: catch-up at ${r}x not gaining on the live edge (latency ${n.toFixed(1)}s); holding at ${s.toFixed(1)}s`), this.liveRetargets += 1, e.targetLatency = s);
|
|
1964
2021
|
}
|
|
1965
2022
|
suspendChasing() {
|
|
1966
2023
|
let e = this.hls;
|
|
@@ -1989,8 +2046,18 @@ var en = class {
|
|
|
1989
2046
|
this.deps.video.pause();
|
|
1990
2047
|
} catch {}
|
|
1991
2048
|
}
|
|
2049
|
+
startEstimate() {
|
|
2050
|
+
return this.deps.rememberBandwidth === !1 ? Pt : Pe() ?? Pt;
|
|
2051
|
+
}
|
|
2052
|
+
maybeRememberBandwidth(e) {
|
|
2053
|
+
if (this.deps.rememberBandwidth === !1 || this.bwFragsLoaded < Ft) return;
|
|
2054
|
+
let t = Date.now();
|
|
2055
|
+
if (!e && t - this.bwSavedAt < It) return;
|
|
2056
|
+
let n = this.hls?.bandwidthEstimate;
|
|
2057
|
+
typeof n != "number" || !Number.isFinite(n) || n <= 0 || (this.bwSavedAt = t, Fe(n));
|
|
2058
|
+
}
|
|
1992
2059
|
destroy() {
|
|
1993
|
-
if (this.detachFrames?.(), this.detachFrames = null, this.prefetch?.destroy(), this.prefetch = null, this.clearRecoveryReset(), this.capTimer &&= (clearTimeout(this.capTimer), null), this.capObserver &&= (this.capObserver.disconnect(), null), this.unwatchDprChanges(), this.endWatchdog &&= (clearInterval(this.endWatchdog), null), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onSeeking &&= (this.deps.video.removeEventListener("seeking", this.onSeeking), null), this.onTimeUpdate &&= (this.deps.video.removeEventListener("timeupdate", this.onTimeUpdate), null), this.onPause &&= (this.deps.video.removeEventListener("pause", this.onPause), null), this.onPlay &&= (this.deps.video.removeEventListener("play", this.onPlay), null), this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null), this.licenseRetryTimer &&= (clearTimeout(this.licenseRetryTimer), null), this.hls) {
|
|
2060
|
+
if (this.maybeRememberBandwidth(!0), this.detachFrames?.(), this.detachFrames = null, this.prefetch?.destroy(), this.prefetch = null, this.clearRecoveryReset(), this.capTimer &&= (clearTimeout(this.capTimer), null), this.capObserver &&= (this.capObserver.disconnect(), null), this.unwatchDprChanges(), this.endWatchdog &&= (clearInterval(this.endWatchdog), null), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onSeeking &&= (this.deps.video.removeEventListener("seeking", this.onSeeking), null), this.onTimeUpdate &&= (this.deps.video.removeEventListener("timeupdate", this.onTimeUpdate), null), this.onPause &&= (this.deps.video.removeEventListener("pause", this.onPause), null), this.onPlay &&= (this.deps.video.removeEventListener("play", this.onPlay), null), this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null), this.licenseRetryTimer &&= (clearTimeout(this.licenseRetryTimer), null), this.hls) {
|
|
1994
2061
|
try {
|
|
1995
2062
|
this.hls.destroy();
|
|
1996
2063
|
} catch (e) {
|
|
@@ -2005,7 +2072,7 @@ var en = class {
|
|
|
2005
2072
|
scheduleLicenseRetry(t) {
|
|
2006
2073
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
2007
2074
|
let n = t.response?.code ?? 0;
|
|
2008
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
2075
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= zt) return !1;
|
|
2009
2076
|
this.licenseRecoveries += 1;
|
|
2010
2077
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
2011
2078
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -2037,7 +2104,7 @@ var en = class {
|
|
|
2037
2104
|
return;
|
|
2038
2105
|
}
|
|
2039
2106
|
if (t.type === e.ErrorTypes.NETWORK_ERROR) {
|
|
2040
|
-
if (this.networkRecoveries <
|
|
2107
|
+
if (this.networkRecoveries < Rt) {
|
|
2041
2108
|
this.networkRecoveries += 1;
|
|
2042
2109
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
2043
2110
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -2054,7 +2121,7 @@ var en = class {
|
|
|
2054
2121
|
return;
|
|
2055
2122
|
}
|
|
2056
2123
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
2057
|
-
if (this.mediaRecoveries <
|
|
2124
|
+
if (this.mediaRecoveries < Lt) {
|
|
2058
2125
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
2059
2126
|
return;
|
|
2060
2127
|
}
|
|
@@ -2078,19 +2145,19 @@ var en = class {
|
|
|
2078
2145
|
let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
|
|
2079
2146
|
return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
|
|
2080
2147
|
}
|
|
2081
|
-
},
|
|
2148
|
+
}, vn = 15e3, yn = 6e5, bn = 3e5, xn = 100, q = 1, Sn = 1e3, Cn = 3e4, wn = 1e3, Tn = {
|
|
2082
2149
|
inline: "PRESENTATION_INLINE",
|
|
2083
2150
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
2084
2151
|
pip: "PRESENTATION_PIP"
|
|
2085
|
-
},
|
|
2152
|
+
}, En = {
|
|
2086
2153
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
2087
2154
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
2088
2155
|
none: "KEY_SYSTEM_NONE"
|
|
2089
2156
|
};
|
|
2090
|
-
function
|
|
2157
|
+
function Dn(e, t) {
|
|
2091
2158
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
2092
2159
|
}
|
|
2093
|
-
var
|
|
2160
|
+
var On = /* @__PURE__ */ new Set([
|
|
2094
2161
|
"INVALID_URN",
|
|
2095
2162
|
"NOT_FOUND",
|
|
2096
2163
|
"GONE",
|
|
@@ -2100,7 +2167,7 @@ var fn = /* @__PURE__ */ new Set([
|
|
|
2100
2167
|
"FORBIDDEN",
|
|
2101
2168
|
"RATE_LIMITED",
|
|
2102
2169
|
"TIMEOUT"
|
|
2103
|
-
]),
|
|
2170
|
+
]), J = {
|
|
2104
2171
|
idle: "PLAYER_STATE_IDLE",
|
|
2105
2172
|
waiting: "PLAYER_STATE_WAITING",
|
|
2106
2173
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -2110,7 +2177,7 @@ var fn = /* @__PURE__ */ new Set([
|
|
|
2110
2177
|
ended: "PLAYER_STATE_ENDED",
|
|
2111
2178
|
error: "PLAYER_STATE_ERROR"
|
|
2112
2179
|
};
|
|
2113
|
-
function
|
|
2180
|
+
function kn(e) {
|
|
2114
2181
|
try {
|
|
2115
2182
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
2116
2183
|
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);
|
|
@@ -2118,8 +2185,8 @@ function pn(e) {
|
|
|
2118
2185
|
return;
|
|
2119
2186
|
}
|
|
2120
2187
|
}
|
|
2121
|
-
var
|
|
2122
|
-
function
|
|
2188
|
+
var An = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), jn = /* @__PURE__ */ new Set(), Y = /* @__PURE__ */ new Set(), X = /* @__PURE__ */ new Set(), Mn = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
|
|
2189
|
+
function Nn(e) {
|
|
2123
2190
|
if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
|
|
2124
2191
|
let t;
|
|
2125
2192
|
try {
|
|
@@ -2128,19 +2195,19 @@ function _n(e) {
|
|
|
2128
2195
|
} catch {
|
|
2129
2196
|
return;
|
|
2130
2197
|
}
|
|
2131
|
-
if (
|
|
2132
|
-
|
|
2133
|
-
for (let e of
|
|
2198
|
+
if (jn.has(t) && !Y.has(t)) {
|
|
2199
|
+
Y.add(t), g(Mn(new URL(t).origin));
|
|
2200
|
+
for (let e of X) e.noteCspBlocked();
|
|
2134
2201
|
}
|
|
2135
2202
|
}
|
|
2136
|
-
function
|
|
2203
|
+
function Pn(e, t) {
|
|
2137
2204
|
return g(t, e), { disabledReason: t };
|
|
2138
2205
|
}
|
|
2139
|
-
function
|
|
2140
|
-
if (n) return t && !
|
|
2206
|
+
function Fn(e, t, n) {
|
|
2207
|
+
if (n) return t && !An(t, n) && g(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
|
|
2141
2208
|
if (t) return { endpoint: t };
|
|
2142
|
-
if (t !== void 0) return
|
|
2143
|
-
let r =
|
|
2209
|
+
if (t !== void 0) return Pn("empty-endpoint", "analytics is disabled: no QoE beacons will be sent. analytics.endpoint was supplied but empty. Pass a real beacons origin, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, or omit the option to derive it from baseUrl (or analytics: false to opt out).");
|
|
2210
|
+
let r = kn(e);
|
|
2144
2211
|
if (r) return { endpoint: r };
|
|
2145
2212
|
let i;
|
|
2146
2213
|
try {
|
|
@@ -2148,9 +2215,9 @@ function yn(e, t, n) {
|
|
|
2148
2215
|
} catch {
|
|
2149
2216
|
i = e;
|
|
2150
2217
|
}
|
|
2151
|
-
return
|
|
2218
|
+
return Pn(i, `analytics is disabled: no QoE beacons will be sent. The beacons endpoint cannot be derived from the baseUrl host "${i}" — the convention is feed[-dev].<domain> → beacons[-dev].<domain>. Pass an explicit endpoint, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, to createPlayer (or analytics: false to opt out deliberately).`);
|
|
2152
2219
|
}
|
|
2153
|
-
var
|
|
2220
|
+
var In = class {
|
|
2154
2221
|
opts;
|
|
2155
2222
|
url;
|
|
2156
2223
|
cspKey;
|
|
@@ -2232,8 +2299,8 @@ var bn = class {
|
|
|
2232
2299
|
constructor(e) {
|
|
2233
2300
|
this.opts = {
|
|
2234
2301
|
...e,
|
|
2235
|
-
heartbeatMs: e.heartbeatMs ??
|
|
2236
|
-
idleMs: e.idleMs ??
|
|
2302
|
+
heartbeatMs: e.heartbeatMs ?? vn,
|
|
2303
|
+
idleMs: e.idleMs ?? yn
|
|
2237
2304
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
|
|
2238
2305
|
try {
|
|
2239
2306
|
let e = new URL(this.url);
|
|
@@ -2250,11 +2317,11 @@ var bn = class {
|
|
|
2250
2317
|
sdkVersion: this.opts.sdkVersion,
|
|
2251
2318
|
...this.opts.environment
|
|
2252
2319
|
};
|
|
2253
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
2320
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), Sn), this.lastTickMs = this.now(), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), document.addEventListener("freeze", this.onFreeze), document.addEventListener("resume", this.onResume), this.cspKey && jn.add(this.cspKey), document.addEventListener("securitypolicyviolation", Nn), X.add(this), this.noteCspBlocked(), this.onVisibility());
|
|
2254
2321
|
}
|
|
2255
2322
|
checkSuspension(e) {
|
|
2256
2323
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
2257
|
-
let t = Math.max(this.opts.idleMs,
|
|
2324
|
+
let t = Math.max(this.opts.idleMs, bn);
|
|
2258
2325
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
2259
2326
|
}
|
|
2260
2327
|
syncIdle(e) {
|
|
@@ -2268,21 +2335,21 @@ var bn = class {
|
|
|
2268
2335
|
noteStateChange(e, t, n, r) {
|
|
2269
2336
|
if (this.endedFlag || e === t) return;
|
|
2270
2337
|
let i = this.now();
|
|
2271
|
-
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(
|
|
2338
|
+
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(q, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(q, i - this.startupAnchorMs)), this.isMuted && this.mutedSinceMs === null && (this.mutedSinceMs = i)) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null, this.mutedSinceMs !== null && (this.mutedTotalMs += i - this.mutedSinceMs, this.mutedSinceMs = null)), this.isPlaying = t === "playing", this.syncActive(), t === "waiting" ? this.waitingSinceMs = i : this.waitingSinceMs !== null && (this.waitingTotalMs += i - this.waitingSinceMs, this.waitingSinceMs = null), t === "buffering" && e === "playing") {
|
|
2272
2339
|
this.stallIsSeekInduced = this.seekInduced(i);
|
|
2273
2340
|
let e = !this.isHidden && !this.stallIsSeekInduced;
|
|
2274
|
-
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(
|
|
2341
|
+
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(q, Math.round(this.playingTotalMs)));
|
|
2275
2342
|
} else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
|
|
2276
2343
|
this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
|
|
2277
2344
|
let a = {
|
|
2278
|
-
fromState:
|
|
2279
|
-
toState:
|
|
2280
|
-
presentation:
|
|
2345
|
+
fromState: J[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2346
|
+
toState: J[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2347
|
+
presentation: Tn[this.presentation]
|
|
2281
2348
|
}, o = this.causeOf(e, t, i);
|
|
2282
2349
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
2283
2350
|
}
|
|
2284
2351
|
seekInduced(e) {
|
|
2285
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
2352
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < wn;
|
|
2286
2353
|
}
|
|
2287
2354
|
causeOf(e, t, n) {
|
|
2288
2355
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -2319,25 +2386,25 @@ var bn = class {
|
|
|
2319
2386
|
}
|
|
2320
2387
|
this.muteChanges += 1;
|
|
2321
2388
|
let r = this.now();
|
|
2322
|
-
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(
|
|
2389
|
+
n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(q, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
|
|
2323
2390
|
}
|
|
2324
2391
|
notePresentation(e) {
|
|
2325
2392
|
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
2326
2393
|
}
|
|
2327
2394
|
notePlayIntent() {
|
|
2328
|
-
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs =
|
|
2395
|
+
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = q), this.firstPlaylistMs > 0 && (this.firstPlaylistMs = q), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = q), this.drmSetupMs > 0 && (this.drmSetupMs = q));
|
|
2329
2396
|
}
|
|
2330
2397
|
noteReady() {
|
|
2331
|
-
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(
|
|
2398
|
+
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(q, this.now() - this.startupAnchorMs));
|
|
2332
2399
|
}
|
|
2333
2400
|
noteFirstPlaylist() {
|
|
2334
|
-
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(
|
|
2401
|
+
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(q, this.now() - this.startupAnchorMs));
|
|
2335
2402
|
}
|
|
2336
2403
|
noteDrmReady() {
|
|
2337
|
-
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(
|
|
2404
|
+
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(q, this.now() - this.startupAnchorMs));
|
|
2338
2405
|
}
|
|
2339
2406
|
noteFirstBytes() {
|
|
2340
|
-
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(
|
|
2407
|
+
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(q, this.now() - this.startupAnchorMs));
|
|
2341
2408
|
}
|
|
2342
2409
|
noteSeek() {
|
|
2343
2410
|
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
@@ -2356,7 +2423,7 @@ var bn = class {
|
|
|
2356
2423
|
let r = n ?? "";
|
|
2357
2424
|
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";
|
|
2358
2425
|
if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
|
|
2359
|
-
if (
|
|
2426
|
+
if (On.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
2360
2427
|
let i = t ?? "";
|
|
2361
2428
|
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";
|
|
2362
2429
|
}
|
|
@@ -2388,7 +2455,7 @@ var bn = class {
|
|
|
2388
2455
|
let l = t.droppedFrames ?? 0;
|
|
2389
2456
|
l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
|
|
2390
2457
|
let u = t.renditionSwitches ?? 0;
|
|
2391
|
-
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 =
|
|
2458
|
+
u > this.lastSwitches && (o.renditionSwitchesDelta = u - this.lastSwitches), this.lastSwitches = u, n > this.lastHbPlayingMs && (o.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (o.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, i > this.lastHbRebufferMs && (o.rebufferMsDelta = Math.round(i - this.lastHbRebufferMs)), this.lastHbRebufferMs = i, this.rebufferCount > this.lastHbRebufferCount && (o.rebufferCountDelta = this.rebufferCount - this.lastHbRebufferCount), this.lastHbRebufferCount = this.rebufferCount, a > this.lastHbActiveMs && (o.activeMsDelta = Math.round(a - this.lastHbActiveMs)), this.lastHbActiveMs = a, typeof t.latencySeconds == "number" && (o.latencyMs = Math.round(t.latencySeconds * 1e3)), typeof t.targetLatencySeconds == "number" && (o.targetLatencyMs = Math.round(t.targetLatencySeconds * 1e3)), typeof t.bandwidthKbps == "number" && (o.bandwidthEstKbps = t.bandwidthKbps), typeof t.levelHeight == "number" && (o.renditionHeight = t.levelHeight), typeof t.renditionBitrateKbps == "number" && (o.renditionBitrateKbps = t.renditionBitrateKbps), t.atLiveEdge === !0 && (o.atLiveEdge = !0), typeof t.bufferedMs == "number" && t.bufferedMs > 0 && (o.bufferedMs = Math.round(t.bufferedMs)), o.playerState = J[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
|
|
2392
2459
|
let d = this.mutedTotalMs;
|
|
2393
2460
|
this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
|
|
2394
2461
|
let f = t.upshifts ?? 0;
|
|
@@ -2403,20 +2470,20 @@ var bn = class {
|
|
|
2403
2470
|
if (this.lastRequestCount = g, _ > 0) {
|
|
2404
2471
|
o.requestCountDelta = _;
|
|
2405
2472
|
let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
|
|
2406
|
-
n.length > 0 && (o.requestTimeP50Ms =
|
|
2473
|
+
n.length > 0 && (o.requestTimeP50Ms = Dn(n, 50), o.requestTimeP95Ms = Dn(n, 95));
|
|
2407
2474
|
}
|
|
2408
2475
|
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();
|
|
2409
2476
|
}
|
|
2410
2477
|
maybeEmitMediaInfo(e) {
|
|
2411
2478
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
2412
2479
|
let t = {};
|
|
2413
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
2480
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = En[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);
|
|
2414
2481
|
let n = JSON.stringify(t);
|
|
2415
2482
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
2416
2483
|
}
|
|
2417
2484
|
end(e, t) {
|
|
2418
2485
|
if (this.endedFlag) return;
|
|
2419
|
-
this.endedFlag = !0,
|
|
2486
|
+
this.endedFlag = !0, X.delete(this);
|
|
2420
2487
|
let n = t ?? this.now();
|
|
2421
2488
|
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));
|
|
2422
2489
|
let r = this.safeSample();
|
|
@@ -2430,7 +2497,7 @@ var bn = class {
|
|
|
2430
2497
|
let c = r?.positionMs ?? 0;
|
|
2431
2498
|
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));
|
|
2432
2499
|
let l = e !== "END_REASON_ENDED";
|
|
2433
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
2500
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= Cn && (i.abandonAfterStallMs = Math.max(q, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= Cn && (i.abandonAfterErrorMs = Math.max(q, Math.round(n - this.lastErrorMs))), this.fullscreenTotalMs > 0 && (i.fullscreenTimeMs = Math.round(this.fullscreenTotalMs)), this.pipTotalMs > 0 && (i.pipTimeMs = Math.round(this.pipTotalMs)), this.volumeChanges > 0 && (i.volumeChanges = this.volumeChanges), this.muteChanges > 0 && (i.muteChanges = this.muteChanges);
|
|
2434
2501
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
2435
2502
|
u > 0 && (i.decodedFramesTotal = u), e === "END_REASON_STOPPED" && this.startupTimeMs === 0 && this.lastErrorStage === null && (e = "END_REASON_ABORTED", i.reason = e), this.startupTimeMs === 0 && e !== "END_REASON_ABORTED" && (i.failedStage = this.lastErrorStage ?? (this.manifestLoadMs === 0 ? "ERROR_STAGE_MANIFEST" : this.firstFragLoadMs === 0 ? "ERROR_STAGE_FIRST_SEGMENT" : "ERROR_STAGE_OTHER")), this.pending.push(this.wrap({ sessionEnd: i })), this.flush(e === "END_REASON_PAGEHIDE");
|
|
2436
2503
|
}
|
|
@@ -2450,13 +2517,13 @@ var bn = class {
|
|
|
2450
2517
|
};
|
|
2451
2518
|
}
|
|
2452
2519
|
noteCspBlocked() {
|
|
2453
|
-
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(
|
|
2520
|
+
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(Mn(new URL(this.url).origin)));
|
|
2454
2521
|
}
|
|
2455
2522
|
cspBlocked() {
|
|
2456
|
-
return !!this.cspKey &&
|
|
2523
|
+
return !!this.cspKey && Y.has(this.cspKey);
|
|
2457
2524
|
}
|
|
2458
2525
|
enqueue(e) {
|
|
2459
|
-
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
2526
|
+
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > xn;) {
|
|
2460
2527
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
2461
2528
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
2462
2529
|
}
|
|
@@ -2483,7 +2550,7 @@ var bn = class {
|
|
|
2483
2550
|
};
|
|
2484
2551
|
//#endregion
|
|
2485
2552
|
//#region src/core/environment.ts
|
|
2486
|
-
function
|
|
2553
|
+
function Ln() {
|
|
2487
2554
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
2488
2555
|
let e;
|
|
2489
2556
|
try {
|
|
@@ -2508,14 +2575,14 @@ function xn() {
|
|
|
2508
2575
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
2509
2576
|
};
|
|
2510
2577
|
}
|
|
2511
|
-
function
|
|
2578
|
+
function Rn() {
|
|
2512
2579
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
2513
2580
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
2514
2581
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
2515
2582
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
2516
2583
|
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";
|
|
2517
2584
|
}
|
|
2518
|
-
function
|
|
2585
|
+
function zn() {
|
|
2519
2586
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
2520
2587
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
2521
2588
|
let t = {
|
|
@@ -2534,17 +2601,17 @@ function Cn() {
|
|
|
2534
2601
|
}
|
|
2535
2602
|
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;
|
|
2536
2603
|
}
|
|
2537
|
-
function
|
|
2538
|
-
let t =
|
|
2539
|
-
deviceClass:
|
|
2604
|
+
function Bn(e) {
|
|
2605
|
+
let t = Ln(), n = {
|
|
2606
|
+
deviceClass: Rn(),
|
|
2540
2607
|
integration: t.integration,
|
|
2541
|
-
...
|
|
2608
|
+
...zn()
|
|
2542
2609
|
};
|
|
2543
2610
|
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);
|
|
2544
2611
|
let r = e.getBoundingClientRect?.();
|
|
2545
2612
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
2546
2613
|
}
|
|
2547
|
-
async function
|
|
2614
|
+
async function Vn() {
|
|
2548
2615
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
2549
2616
|
if (!e?.getHighEntropyValues) return {};
|
|
2550
2617
|
try {
|
|
@@ -2556,7 +2623,7 @@ async function Tn() {
|
|
|
2556
2623
|
}
|
|
2557
2624
|
//#endregion
|
|
2558
2625
|
//#region src/core/version.ts
|
|
2559
|
-
var
|
|
2626
|
+
var Hn = "2.19.0", Un = {
|
|
2560
2627
|
accent: "#E1B600",
|
|
2561
2628
|
accentText: "#1B1C23",
|
|
2562
2629
|
background: "#0e0f13",
|
|
@@ -2567,7 +2634,7 @@ var En = "2.17.0", Dn = {
|
|
|
2567
2634
|
border: "rgba(255, 255, 255, 0.1)",
|
|
2568
2635
|
radius: "8px",
|
|
2569
2636
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
2570
|
-
},
|
|
2637
|
+
}, Wn = {
|
|
2571
2638
|
accent: "--havik-accent",
|
|
2572
2639
|
accentText: "--havik-accent-text",
|
|
2573
2640
|
background: "--havik-bg",
|
|
@@ -2579,26 +2646,26 @@ var En = "2.17.0", Dn = {
|
|
|
2579
2646
|
radius: "--havik-radius",
|
|
2580
2647
|
fontFamily: "--havik-font"
|
|
2581
2648
|
};
|
|
2582
|
-
function
|
|
2649
|
+
function Z(e, t) {
|
|
2583
2650
|
let n = {
|
|
2584
|
-
...
|
|
2651
|
+
...Un,
|
|
2585
2652
|
...t
|
|
2586
2653
|
};
|
|
2587
|
-
for (let t of Object.keys(
|
|
2654
|
+
for (let t of Object.keys(Wn)) e.style.setProperty(Wn[t], n[t]);
|
|
2588
2655
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
2589
2656
|
}
|
|
2590
2657
|
//#endregion
|
|
2591
2658
|
//#region src/ui/styles.ts
|
|
2592
|
-
var
|
|
2593
|
-
function
|
|
2594
|
-
let n = e.querySelector(`style#${
|
|
2595
|
-
if (n && (!t ||
|
|
2659
|
+
var Gn = "havik-player-styles", Kn = "\n.havik-player{position:relative;display:block;width:100%;background:var(--havik-bg,#0e0f13);\n color:var(--havik-text,#fff);font-family:var(--havik-font,system-ui,sans-serif);\n overflow:hidden;line-height:1.4;-webkit-tap-highlight-color:transparent}\n.havik-player video{display:block;width:100%;height:auto;aspect-ratio:16/9;\n object-fit:contain;background:#000;outline:none}\n.havik-player:focus{outline:none}\n.havik-player *{box-sizing:border-box}\n\n.havik-player:fullscreen,.havik-player:-webkit-full-screen{display:flex;align-items:center;\n justify-content:center;width:100vw;height:100vh;aspect-ratio:auto}\n.havik-player:fullscreen video,.havik-player:-webkit-full-screen video{width:100%;height:100%;\n aspect-ratio:auto;object-fit:contain}\n\n.havik-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer;\n touch-action:manipulation}\n.havik-gradient{position:absolute;left:0;right:0;bottom:0;height:120px;pointer-events:none;\n background:linear-gradient(to top,rgba(0,0,0,.78),transparent);\n opacity:1;transition:opacity .25s}\n.havik-player.havik-hide .havik-gradient,\n.havik-player.havik-hide .havik-bar{opacity:0;pointer-events:none}\n.havik-player.havik-hide{cursor:none}\n\n.havik-center{width:74px;height:74px;border-radius:50%;border:0;cursor:pointer;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);\n display:flex;align-items:center;justify-content:center;\n box-shadow:0 6px 24px rgba(0,0,0,.45);transition:transform .15s,opacity .15s}\n.havik-center:hover{transform:scale(1.06)}\n.havik-center svg{width:38px;height:38px;margin-left:2px}\n.havik-center.havik-gone{opacity:0;pointer-events:none;transform:scale(.8)}\n\n/* Absolutely centred, NOT a flex sibling of .havik-center: the hidden center\n button (.havik-gone) still occupies its 74px in the row, which pushed an\n in-flow spinner 37px right of centre. */\n.havik-spinner{position:absolute;inset:0;margin:auto;width:56px;height:56px;border-radius:50%;\n border:4px solid rgba(255,255,255,.2);border-top-color:var(--havik-accent,#E1B600);\n animation:havik-spin .8s linear infinite}\n@keyframes havik-spin{to{transform:rotate(360deg)}}\n\n/* Status card — branded full-bleed overlay for the stopped/pre-play states\n (ended / fatal error / pre-play / armed-waiting). */\n.havik-status{position:absolute;inset:0;display:flex;flex-direction:column;gap:16px;\n align-items:center;justify-content:center;background:rgba(14,15,19,.82);text-align:center;padding:24px}\n.havik-status__logo{width:128px;height:46px;background:var(--havik-logo) center/contain no-repeat;opacity:.95}\n.havik-status__msg{color:var(--havik-text,#fff);font-size:15px;font-weight:600;max-width:480px}\n.havik-status__btn{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;\n padding:10px 18px;border-radius:var(--havik-radius,8px);font-weight:700;font-size:14px;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);transition:transform .15s}\n.havik-status__btn:hover{transform:scale(1.04)}\n.havik-status__btn svg{width:18px;height:18px}\n/* Pre-play: lighter scrim so the poster shows through, and a round play CTA. */\n.havik-status--preplay{background:rgba(14,15,19,.4)}\n.havik-status--preplay .havik-status__btn--play{width:74px;height:74px;border-radius:50%;padding:0;\n justify-content:center;box-shadow:0 6px 24px rgba(0,0,0,.45)}\n.havik-status--preplay .havik-status__btn--play svg{width:38px;height:38px;margin-left:3px}\n\n.havik-watermark{position:absolute;top:12px;right:14px;height:22px;opacity:.85;pointer-events:none;\n content:'';background:var(--havik-logo) center/contain no-repeat;width:90px}\n/* A status card carries its own logo — the corner watermark would duplicate it. */\n.havik-player.havik-has-status .havik-watermark{display:none}\n\n.havik-bar{position:absolute;left:0;right:0;bottom:0;padding:0 12px 8px;\n opacity:1;transition:opacity .25s;z-index:2}\n.havik-seek{position:relative;height:16px;display:flex;align-items:center;cursor:pointer;margin-bottom:2px}\n.havik-seek__track{position:relative;width:100%;height:4px;border-radius:3px;background:rgba(255,255,255,.25)}\n.havik-seek__buffered{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:rgba(255,255,255,.4)}\n.havik-seek__played{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-seek__thumb{position:absolute;top:50%;width:13px;height:13px;border-radius:50%;\n background:var(--havik-accent,#E1B600);transform:translate(-50%,-50%) scale(0);transition:transform .1s}\n.havik-seek:hover .havik-seek__thumb{transform:translate(-50%,-50%) scale(1)}\n\n.havik-controls{display:flex;align-items:center;gap:6px;height:40px}\n.havik-spacer{flex:1}\n.havik-btn{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;border-radius:var(--havik-radius,8px);\n padding:0;transition:background .12s,color .12s}\n.havik-btn:hover{background:rgba(255,255,255,.12)}\n.havik-btn:focus-visible{outline:2px solid var(--havik-accent,#E1B600);outline-offset:1px}\n.havik-btn svg{width:22px;height:22px}\n\n/* The volume level is filled in accent up to the thumb, like the seek bar's\n played span — a native range input paints no \"elapsed\" side, which left the\n level readable only from the dot's position. --havik-vol (0..1) is set by\n syncVolume(); the track width and thumb size live here as variables because\n the WebKit fill has to compute the thumb centre from both. */\n.havik-vol{display:flex;align-items:center}\n.havik-vol__slider{--havik-vol-w:70px;--havik-vol-thumb:12px;--havik-vol:1;\n --havik-vol-pos:calc(var(--havik-vol-thumb) / 2 + var(--havik-vol) * (var(--havik-vol-w) - var(--havik-vol-thumb)));\n width:0;opacity:0;transition:width .18s,opacity .18s;height:4px;cursor:pointer;\n appearance:none;-webkit-appearance:none;background:transparent;border-radius:3px;margin:0 4px}\n.havik-vol:hover .havik-vol__slider,.havik-vol:focus-within .havik-vol__slider{width:var(--havik-vol-w);opacity:1}\n/* WebKit/Blink have no progress pseudo-element: paint the fill as a hard-stop\n gradient that ends at the thumb centre. */\n.havik-vol__slider::-webkit-slider-runnable-track{height:4px;border-radius:3px;\n background:linear-gradient(to right,var(--havik-accent,#E1B600) var(--havik-vol-pos),\n rgba(255,255,255,.3) var(--havik-vol-pos))}\n/* Firefox fills natively, and tracks the thumb exactly. */\n.havik-vol__slider::-moz-range-track{height:4px;border-radius:3px;background:rgba(255,255,255,.3)}\n.havik-vol__slider::-moz-range-progress{height:4px;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-vol__slider::-webkit-slider-thumb{-webkit-appearance:none;width:var(--havik-vol-thumb);\n height:var(--havik-vol-thumb);border-radius:50%;background:var(--havik-accent,#E1B600);\n margin-top:calc((4px - var(--havik-vol-thumb)) / 2)}\n.havik-vol__slider::-moz-range-thumb{width:var(--havik-vol-thumb);height:var(--havik-vol-thumb);\n border:0;border-radius:50%;background:var(--havik-accent,#E1B600)}\n\n.havik-time{font-size:12px;color:var(--havik-text-muted,#9aa0ad);\n font-variant-numeric:tabular-nums;padding:0 6px;white-space:nowrap}\n.havik-live{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;\n letter-spacing:.4px;padding:0 8px;color:var(--havik-text,#fff)}\n.havik-live svg{width:9px;height:9px;color:var(--havik-text-muted,#9aa0ad)}\n.havik-live.is-live svg{color:var(--havik-accent,#E1B600)}\n.havik-live__go{margin-left:2px;border:0;cursor:pointer;background:transparent;color:var(--havik-text-muted,#9aa0ad);\n font:inherit;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 6px;border-radius:6px}\n.havik-live.is-live .havik-live__go{display:none}\n.havik-live__go:hover{color:var(--havik-accent,#E1B600)}\n\n.havik-menu{position:absolute;bottom:54px;right:12px;min-width:170px;max-height:230px;overflow:auto;\n background:var(--havik-surface,#1B1C23);border:1px solid var(--havik-border,rgba(255,255,255,.1));\n border-radius:var(--havik-radius,8px);box-shadow:0 10px 30px rgba(0,0,0,.5);padding:6px;z-index:3}\n.havik-menu[hidden]{display:none}\n.havik-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;\n color:var(--havik-text-muted,#9aa0ad);padding:6px 8px 4px}\n.havik-menu__item{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;font:inherit;font-size:13px;\n text-align:left;padding:7px 8px;border-radius:6px}\n.havik-menu__item:hover{background:var(--havik-surface-muted,#2a2c36)}\n.havik-menu__item[aria-checked=\"true\"]{color:var(--havik-accent,#E1B600);font-weight:600}\n.havik-menu__item[aria-checked=\"true\"]::after{content:'✓'}\n", qn = /* @__PURE__ */ new WeakMap();
|
|
2660
|
+
function Jn(e = document, t) {
|
|
2661
|
+
let n = e.querySelector(`style#${Gn}`);
|
|
2662
|
+
if (n && (!t || qn.get(n) === t)) return;
|
|
2596
2663
|
let r = e.createElement("style");
|
|
2597
|
-
r.id =
|
|
2664
|
+
r.id = Gn, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = Kn, qn.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
|
|
2598
2665
|
}
|
|
2599
2666
|
//#endregion
|
|
2600
2667
|
//#region src/ui/icons.ts
|
|
2601
|
-
var
|
|
2668
|
+
var Yn = {
|
|
2602
2669
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
2603
2670
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
2604
2671
|
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\"/>",
|
|
@@ -2612,20 +2679,20 @@ var Pn = {
|
|
|
2612
2679
|
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\"/>"
|
|
2613
2680
|
};
|
|
2614
2681
|
function Q(e) {
|
|
2615
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
2682
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Yn[e]}</svg>`;
|
|
2616
2683
|
}
|
|
2617
2684
|
//#endregion
|
|
2618
2685
|
//#region src/ui/controls.ts
|
|
2619
|
-
var
|
|
2686
|
+
var Xn = 3e3, Zn = 250, Qn = /* @__PURE__ */ new Set([
|
|
2620
2687
|
"GONE",
|
|
2621
2688
|
"NOT_FOUND",
|
|
2622
2689
|
"INVALID_URN",
|
|
2623
2690
|
"UNAUTHORIZED"
|
|
2624
2691
|
]);
|
|
2625
|
-
function
|
|
2626
|
-
return new
|
|
2692
|
+
function $n(e) {
|
|
2693
|
+
return new er(e);
|
|
2627
2694
|
}
|
|
2628
|
-
var
|
|
2695
|
+
var er = class {
|
|
2629
2696
|
root;
|
|
2630
2697
|
video;
|
|
2631
2698
|
player;
|
|
@@ -2656,6 +2723,7 @@ var zn = class {
|
|
|
2656
2723
|
statusKind = null;
|
|
2657
2724
|
statusMsg = null;
|
|
2658
2725
|
hasPlayed = !1;
|
|
2726
|
+
fsSupported = !0;
|
|
2659
2727
|
lastError = null;
|
|
2660
2728
|
logoUrl;
|
|
2661
2729
|
statusOverlays;
|
|
@@ -2672,7 +2740,7 @@ var zn = class {
|
|
|
2672
2740
|
scrubbing = !1;
|
|
2673
2741
|
offFns = [];
|
|
2674
2742
|
constructor(e) {
|
|
2675
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
2743
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Xn, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.streamEnded = e.streamEnded ?? (() => !1), this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, Jn(this.doc, e.cspNonce), this.root.classList.add("havik-player"), this.root.hasAttribute("tabindex") || (this.root.tabIndex = 0), this.root.setAttribute("role", "region"), this.root.setAttribute("aria-label", "Video player");
|
|
2676
2744
|
let t = (e, t, n) => {
|
|
2677
2745
|
let r = this.doc.createElement(e);
|
|
2678
2746
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -2710,7 +2778,7 @@ var zn = class {
|
|
|
2710
2778
|
let o = this.doc.createElement("span");
|
|
2711
2779
|
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";
|
|
2712
2780
|
let s = t("div", "havik-spacer");
|
|
2713
|
-
if (this.ccBtn = n("havik-btn", "cc", "Subtitles"), this.audioBtn = n("havik-btn", "settings", "Audio track"), this.qualityBtn = n("havik-btn", "settings", "Quality"), this.pipBtn = n("havik-btn", "pip", "Picture in picture"), this.fsBtn = n("havik-btn", "fullscreen", "Fullscreen"), this.ccBtn.style.display = "none", this.audioBtn.style.display = "none", this.qualityBtn.style.display = "none", this.pipSupported() || (this.pipBtn.style.display = "none"), i.append(this.playBtn, a, this.live, this.time, s, this.ccBtn, this.audioBtn, this.qualityBtn, this.pipBtn, this.fsBtn), this.bar.append(this.seek, i), this.menu = t("div", "havik-menu", { role: "menu" }), this.menu.hidden = !0, this.root.append(this.gradient, this.overlay, this.bar, this.menu), e.logoUrl) {
|
|
2781
|
+
if (this.ccBtn = n("havik-btn", "cc", "Subtitles"), this.audioBtn = n("havik-btn", "settings", "Audio track"), this.qualityBtn = n("havik-btn", "settings", "Quality"), this.pipBtn = n("havik-btn", "pip", "Picture in picture"), this.fsBtn = n("havik-btn", "fullscreen", "Fullscreen"), this.ccBtn.style.display = "none", this.audioBtn.style.display = "none", this.qualityBtn.style.display = "none", this.pipSupported() || (this.pipBtn.style.display = "none"), this.syncFullscreenSupport(), i.append(this.playBtn, a, this.live, this.time, s, this.ccBtn, this.audioBtn, this.qualityBtn, this.pipBtn, this.fsBtn), this.bar.append(this.seek, i), this.menu = t("div", "havik-menu", { role: "menu" }), this.menu.hidden = !0, this.root.append(this.gradient, this.overlay, this.bar, this.menu), e.logoUrl) {
|
|
2714
2782
|
let n = t("div", "havik-watermark");
|
|
2715
2783
|
n.style.backgroundImage = `url("${e.logoUrl}")`, this.root.append(n);
|
|
2716
2784
|
}
|
|
@@ -2728,7 +2796,7 @@ var zn = class {
|
|
|
2728
2796
|
}), this.on(this.muteBtn, "click", () => this.player.setMuted(!e.muted)), this.on(this.volSlider, "input", () => {
|
|
2729
2797
|
let t = Number(this.volSlider.value);
|
|
2730
2798
|
this.setVolumeFill(t), this.player.setVolume(t), t > 0 && e.muted && this.player.setMuted(!1);
|
|
2731
|
-
}), this.on(this.liveGo, "click", () => this.player.seekToLive()), this.on(this.pipBtn, "click", () => void this.togglePip()), this.on(this.fsBtn, "click", () => void this.toggleFullscreen()), this.on(this.ccBtn, "click", () => this.toggleMenu("cc")), this.on(this.audioBtn, "click", () => this.toggleMenu("audio")), this.on(this.qualityBtn, "click", () => this.toggleMenu("quality")), this.on(this.seek, "pointerdown", (e) => this.onSeekDown(e)), this.on(this.seek, "keydown", (e) => this.onSeekKey(e)), this.on(e, "play", () => this.syncPlayPause()), this.on(e, "pause", () => this.syncPlayPause()), this.on(e, "volumechange", () => this.syncVolume()), this.on(e, "timeupdate", () => this.syncProgress()), this.on(e, "progress", () => this.syncProgress()), this.on(e, "durationchange", () => this.syncProgress()), this.offFns.push(this.player.on("statechange", () => this.syncState())), this.offFns.push(this.player.on("ended", () => this.syncState())), this.offFns.push(this.player.on("ready", () => this.refreshTracks())), this.offFns.push(this.player.on("qualitychange", () => this.onTracksChanged())), this.offFns.push(this.player.on("audiotrackchange", () => this.onTracksChanged())), this.offFns.push(this.player.on("texttrackchange", () => this.onTracksChanged())), this.offFns.push(this.player.on("pipchange", (e) => this.syncPip(e))), this.offFns.push(this.player.on("stats", () => this.syncLive())), this.offFns.push(this.player.on("error", (e) => {
|
|
2799
|
+
}), this.on(this.liveGo, "click", () => this.player.seekToLive()), this.on(this.pipBtn, "click", () => void this.togglePip()), this.on(this.fsBtn, "click", () => void this.toggleFullscreen()), this.on(this.ccBtn, "click", () => this.toggleMenu("cc")), this.on(this.audioBtn, "click", () => this.toggleMenu("audio")), this.on(this.qualityBtn, "click", () => this.toggleMenu("quality")), this.on(this.seek, "pointerdown", (e) => this.onSeekDown(e)), this.on(this.seek, "keydown", (e) => this.onSeekKey(e)), this.on(e, "play", () => this.syncPlayPause()), this.on(e, "pause", () => this.syncPlayPause()), this.on(e, "volumechange", () => this.syncVolume()), this.on(e, "timeupdate", () => this.syncProgress()), this.on(e, "progress", () => this.syncProgress()), this.on(e, "durationchange", () => this.syncProgress()), this.on(e, "loadedmetadata", () => this.syncFullscreenSupport()), this.offFns.push(this.player.on("statechange", () => this.syncState())), this.offFns.push(this.player.on("ended", () => this.syncState())), this.offFns.push(this.player.on("ready", () => this.refreshTracks())), this.offFns.push(this.player.on("qualitychange", () => this.onTracksChanged())), this.offFns.push(this.player.on("audiotrackchange", () => this.onTracksChanged())), this.offFns.push(this.player.on("texttrackchange", () => this.onTracksChanged())), this.offFns.push(this.player.on("pipchange", (e) => this.syncPip(e))), this.offFns.push(this.player.on("stats", () => this.syncLive())), this.offFns.push(this.player.on("error", (e) => {
|
|
2732
2800
|
this.lastError = e, this.statusKind = null, this.syncState();
|
|
2733
2801
|
}));
|
|
2734
2802
|
let t = (e) => e.pointerType !== "touch";
|
|
@@ -2758,7 +2826,7 @@ var zn = class {
|
|
|
2758
2826
|
let t = this.surfaceWasHidden;
|
|
2759
2827
|
this.tapTimer = setTimeout(() => {
|
|
2760
2828
|
this.tapTimer = void 0, this.toggleBar(t);
|
|
2761
|
-
},
|
|
2829
|
+
}, Zn);
|
|
2762
2830
|
}
|
|
2763
2831
|
toggleBar(e) {
|
|
2764
2832
|
e ? this.poke() : this.hideIfIdle();
|
|
@@ -2793,7 +2861,7 @@ var zn = class {
|
|
|
2793
2861
|
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = Q("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
|
|
2794
2862
|
} else {
|
|
2795
2863
|
let r = this.doc.createElement("div");
|
|
2796
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
2864
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Qn.has(this.lastError.code)) {
|
|
2797
2865
|
let e = this.doc.createElement("button");
|
|
2798
2866
|
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${Q("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
|
|
2799
2867
|
}
|
|
@@ -2834,7 +2902,7 @@ var zn = class {
|
|
|
2834
2902
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
2835
2903
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
2836
2904
|
}
|
|
2837
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
2905
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${tr(this.video.currentTime)} / ${tr(this.video.duration)}`);
|
|
2838
2906
|
}
|
|
2839
2907
|
syncLive() {
|
|
2840
2908
|
let e = this.player.getStats(), t = e.isLive !== !1, n = this.player.state === "ended", r = !t && !this.streamEnded();
|
|
@@ -2884,17 +2952,17 @@ var zn = class {
|
|
|
2884
2952
|
renderQualityMenu() {
|
|
2885
2953
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
2886
2954
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
2887
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
2955
|
+
for (let n of e) this.menu.append(this.menuItem(nr(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
2888
2956
|
}
|
|
2889
2957
|
renderAudioMenu() {
|
|
2890
2958
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
2891
2959
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
2892
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2960
|
+
for (let t of e) this.menu.append(this.menuItem(rr(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
2893
2961
|
}
|
|
2894
2962
|
renderCcMenu() {
|
|
2895
2963
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
2896
2964
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
2897
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2965
|
+
for (let t of e) this.menu.append(this.menuItem(ir(t), !1, () => this.player.setTextTrack(t.id)));
|
|
2898
2966
|
}
|
|
2899
2967
|
onTracksChanged() {
|
|
2900
2968
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -2914,9 +2982,12 @@ var zn = class {
|
|
|
2914
2982
|
}
|
|
2915
2983
|
async toggleFullscreen() {
|
|
2916
2984
|
try {
|
|
2917
|
-
S(this.video, this.root) ? await
|
|
2985
|
+
S(this.video, this.root) ? await T(this.video, this.root) : await w(this.video, this.root);
|
|
2918
2986
|
} catch {}
|
|
2919
2987
|
}
|
|
2988
|
+
syncFullscreenSupport() {
|
|
2989
|
+
this.fsSupported = C(this.video, this.root), this.fsBtn.style.display = this.fsSupported ? "" : "none";
|
|
2990
|
+
}
|
|
2920
2991
|
syncFullscreen() {
|
|
2921
2992
|
let e = S(this.video, this.root);
|
|
2922
2993
|
this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
|
|
@@ -2952,6 +3023,7 @@ var zn = class {
|
|
|
2952
3023
|
this.player.setMuted(!this.video.muted);
|
|
2953
3024
|
break;
|
|
2954
3025
|
case "f":
|
|
3026
|
+
if (!this.fsSupported) return;
|
|
2955
3027
|
this.toggleFullscreen();
|
|
2956
3028
|
break;
|
|
2957
3029
|
case "c":
|
|
@@ -2995,41 +3067,41 @@ var zn = class {
|
|
|
2995
3067
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
2996
3068
|
}
|
|
2997
3069
|
};
|
|
2998
|
-
function
|
|
3070
|
+
function tr(e) {
|
|
2999
3071
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
3000
3072
|
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");
|
|
3001
3073
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
3002
3074
|
}
|
|
3003
|
-
function
|
|
3075
|
+
function nr(e) {
|
|
3004
3076
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
3005
3077
|
}
|
|
3006
|
-
function
|
|
3078
|
+
function rr(e) {
|
|
3007
3079
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3008
3080
|
}
|
|
3009
|
-
function
|
|
3081
|
+
function ir(e) {
|
|
3010
3082
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3011
3083
|
}
|
|
3012
3084
|
//#endregion
|
|
3013
3085
|
//#region src/managed/index.ts
|
|
3014
|
-
var
|
|
3015
|
-
function
|
|
3086
|
+
var ar = 6e3, or = 45e3, sr = 2e3, cr = 3, lr = 5e3, ur = 2e3, dr = 48e4, fr = "keySystemLicenseRequestFailed";
|
|
3087
|
+
function pr(e) {
|
|
3016
3088
|
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)})`);
|
|
3017
|
-
if (e.env !== void 0) return
|
|
3089
|
+
if (e.env !== void 0) return rt(e.env);
|
|
3018
3090
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
3019
3091
|
return e.baseUrl;
|
|
3020
3092
|
}
|
|
3021
|
-
async function
|
|
3093
|
+
async function mr(e) {
|
|
3022
3094
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
3023
|
-
let t =
|
|
3095
|
+
let t = pr(e);
|
|
3024
3096
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
3025
3097
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
3026
|
-
let r = new
|
|
3098
|
+
let r = new hr({
|
|
3027
3099
|
...e,
|
|
3028
3100
|
baseUrl: t
|
|
3029
3101
|
});
|
|
3030
3102
|
return await r.start(), r;
|
|
3031
3103
|
}
|
|
3032
|
-
var
|
|
3104
|
+
var hr = class {
|
|
3033
3105
|
opts;
|
|
3034
3106
|
abort = new AbortController();
|
|
3035
3107
|
listeners = {};
|
|
@@ -3080,7 +3152,7 @@ var er = class {
|
|
|
3080
3152
|
this.opts.muted && (this.opts.video.muted = !0), this.opts.poster && (this.opts.video.poster = this.opts.poster), this.mountControls(), this.attachPipListeners(), this.attachEndedPlayGuard(), this.setState("loading");
|
|
3081
3153
|
let e = ++this.loadGen, t = this.resolveOptions();
|
|
3082
3154
|
try {
|
|
3083
|
-
let n = await
|
|
3155
|
+
let n = await v(t);
|
|
3084
3156
|
if (await this.onResolved(n, e), e === this.loadGen && this._state === "error" && this._lastError) {
|
|
3085
3157
|
let e = this._lastError;
|
|
3086
3158
|
throw this.destroy(), e;
|
|
@@ -3103,11 +3175,11 @@ var er = class {
|
|
|
3103
3175
|
};
|
|
3104
3176
|
}
|
|
3105
3177
|
beginArming(e, t, n = !1) {
|
|
3106
|
-
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ??
|
|
3178
|
+
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
|
|
3107
3179
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
3108
3180
|
}
|
|
3109
3181
|
beginArmingByPolling(e) {
|
|
3110
|
-
|
|
3182
|
+
y({
|
|
3111
3183
|
...this.resolveOptions(),
|
|
3112
3184
|
signal: this.abort.signal,
|
|
3113
3185
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -3124,7 +3196,7 @@ var er = class {
|
|
|
3124
3196
|
setTimeout(() => {
|
|
3125
3197
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
3126
3198
|
phase: i ? "unavailable" : "tooEarly",
|
|
3127
|
-
retryInMs:
|
|
3199
|
+
retryInMs: or,
|
|
3128
3200
|
attempt: 1,
|
|
3129
3201
|
elapsedMs: 0,
|
|
3130
3202
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -3141,7 +3213,7 @@ var er = class {
|
|
|
3141
3213
|
}
|
|
3142
3214
|
}
|
|
3143
3215
|
}, h = () => {
|
|
3144
|
-
a || s || p() || (s = !0,
|
|
3216
|
+
a || s || p() || (s = !0, y({
|
|
3145
3217
|
...this.resolveOptions(),
|
|
3146
3218
|
signal: c.signal,
|
|
3147
3219
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -3149,7 +3221,7 @@ var er = class {
|
|
|
3149
3221
|
a || p() || c.signal.aborted || (a = !0, this.closeArming(), this.fail(e instanceof n ? e : new n("INTERNAL", 0, String(e))));
|
|
3150
3222
|
}));
|
|
3151
3223
|
}, g = () => {
|
|
3152
|
-
a || p() ||
|
|
3224
|
+
a || p() || v(this.resolveOptions()).then((e) => m(e)).catch((e) => {
|
|
3153
3225
|
if (!(a || p())) {
|
|
3154
3226
|
if (e instanceof n && o(e.code)) {
|
|
3155
3227
|
h();
|
|
@@ -3163,13 +3235,13 @@ var er = class {
|
|
|
3163
3235
|
!a && !p() && h();
|
|
3164
3236
|
}, e);
|
|
3165
3237
|
};
|
|
3166
|
-
_(
|
|
3238
|
+
_(ar), this.armingSub = E({
|
|
3167
3239
|
eventsBaseUrl: t,
|
|
3168
3240
|
matchUrn: this.opts.matchUrn,
|
|
3169
3241
|
credential: this.opts.credential,
|
|
3170
|
-
onAlive: () => _(
|
|
3242
|
+
onAlive: () => _(or),
|
|
3171
3243
|
onState: (e) => {
|
|
3172
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
3244
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * sr);
|
|
3173
3245
|
},
|
|
3174
3246
|
onError: () => h()
|
|
3175
3247
|
});
|
|
@@ -3192,7 +3264,7 @@ var er = class {
|
|
|
3192
3264
|
let n = await s(this.opts.credential);
|
|
3193
3265
|
if (this.destroyed || t !== this.loadGen) return;
|
|
3194
3266
|
this.setState("loading");
|
|
3195
|
-
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a =
|
|
3267
|
+
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = lt(this.opts.video, (e) => {
|
|
3196
3268
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
3197
3269
|
});
|
|
3198
3270
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -3214,26 +3286,26 @@ var er = class {
|
|
|
3214
3286
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
3215
3287
|
let i = e.analytics?.sid;
|
|
3216
3288
|
if (!i) return;
|
|
3217
|
-
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } =
|
|
3289
|
+
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = Fn(this.opts.baseUrl, a, e.analytics?.endpoint);
|
|
3218
3290
|
if (!o) {
|
|
3219
3291
|
s && setTimeout(() => {
|
|
3220
3292
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
|
|
3221
3293
|
}, 0);
|
|
3222
3294
|
return;
|
|
3223
3295
|
}
|
|
3224
|
-
let c = this.opts.video, l = new
|
|
3296
|
+
let c = this.opts.video, l = new In({
|
|
3225
3297
|
endpoint: o,
|
|
3226
3298
|
sid: i,
|
|
3227
3299
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
3228
|
-
sdkVersion:
|
|
3229
|
-
environment:
|
|
3300
|
+
sdkVersion: Hn,
|
|
3301
|
+
environment: Bn(c),
|
|
3230
3302
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
3231
3303
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
3232
3304
|
onBlocked: (e) => setTimeout(() => {
|
|
3233
3305
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, e));
|
|
3234
3306
|
}, 0),
|
|
3235
3307
|
sample: () => {
|
|
3236
|
-
let e = this.engine?.getStats() ??
|
|
3308
|
+
let e = this.engine?.getStats() ?? it, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
|
|
3237
3309
|
return {
|
|
3238
3310
|
...e,
|
|
3239
3311
|
bufferedMs: Math.round(t * 1e3),
|
|
@@ -3247,7 +3319,7 @@ var er = class {
|
|
|
3247
3319
|
let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
|
|
3248
3320
|
c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
|
|
3249
3321
|
c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
|
|
3250
|
-
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()),
|
|
3322
|
+
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), Vn().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
3251
3323
|
}
|
|
3252
3324
|
currentPresentation() {
|
|
3253
3325
|
let e = this.opts.video;
|
|
@@ -3262,10 +3334,11 @@ var er = class {
|
|
|
3262
3334
|
video: this.opts.video,
|
|
3263
3335
|
descriptor: e,
|
|
3264
3336
|
credential: t,
|
|
3265
|
-
deviceId:
|
|
3337
|
+
deviceId: A(),
|
|
3266
3338
|
userId: this.opts.userId,
|
|
3267
3339
|
lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
|
|
3268
3340
|
snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
|
|
3341
|
+
rememberBandwidth: this.opts.rememberBandwidth,
|
|
3269
3342
|
mediaDuringKey: this.opts.mediaDuringKey,
|
|
3270
3343
|
debug: this.opts.debug,
|
|
3271
3344
|
deferLoad: r,
|
|
@@ -3274,9 +3347,9 @@ var er = class {
|
|
|
3274
3347
|
freshLicenseUrl: () => this.refreshLicense()
|
|
3275
3348
|
}, o = this.opts.engine ?? "auto";
|
|
3276
3349
|
if (o === "native") return new W(a);
|
|
3277
|
-
if (o === "hls") return new
|
|
3278
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && H(this.opts.video) && U() || !e.drmEnabled &&
|
|
3279
|
-
if (
|
|
3350
|
+
if (o === "hls") return new _n(a);
|
|
3351
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && H(this.opts.video) && U() || !e.drmEnabled && xt() && H(this.opts.video)) return new W(a);
|
|
3352
|
+
if (Nt()) return new _n(a);
|
|
3280
3353
|
if (H(this.opts.video)) return new W(a);
|
|
3281
3354
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
3282
3355
|
}
|
|
@@ -3324,11 +3397,11 @@ var er = class {
|
|
|
3324
3397
|
}
|
|
3325
3398
|
startLiveState(e) {
|
|
3326
3399
|
if (this.opts.liveStateEvents === !1) return;
|
|
3327
|
-
let t = this.opts.eventsBaseUrl ??
|
|
3400
|
+
let t = this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
|
|
3328
3401
|
if (!t) return;
|
|
3329
3402
|
this.closeLiveState();
|
|
3330
3403
|
let r = 0, i = !1;
|
|
3331
|
-
this.liveStateSub =
|
|
3404
|
+
this.liveStateSub = E({
|
|
3332
3405
|
eventsBaseUrl: t,
|
|
3333
3406
|
matchUrn: this.opts.matchUrn,
|
|
3334
3407
|
credential: this.opts.credential,
|
|
@@ -3339,7 +3412,7 @@ var er = class {
|
|
|
3339
3412
|
r = 0, i = !1;
|
|
3340
3413
|
},
|
|
3341
3414
|
onError: () => {
|
|
3342
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
3415
|
+
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= cr && (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.`))));
|
|
3343
3416
|
}
|
|
3344
3417
|
});
|
|
3345
3418
|
}
|
|
@@ -3353,7 +3426,7 @@ var er = class {
|
|
|
3353
3426
|
return;
|
|
3354
3427
|
}
|
|
3355
3428
|
let e = this.hiddenAtMs;
|
|
3356
|
-
this.hiddenAtMs = null, e != null && Date.now() - e >=
|
|
3429
|
+
this.hiddenAtMs = null, e != null && Date.now() - e >= lr && this.resyncLiveState();
|
|
3357
3430
|
}, this.onReturnPageShow = (e) => {
|
|
3358
3431
|
e.persisted && this.resyncLiveState();
|
|
3359
3432
|
}, document.addEventListener("visibilitychange", this.onReturnVisible), typeof window < "u" && window.addEventListener("pageshow", this.onReturnPageShow));
|
|
@@ -3385,7 +3458,7 @@ var er = class {
|
|
|
3385
3458
|
scheduleRejoin(e) {
|
|
3386
3459
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
3387
3460
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
3388
|
-
}, Math.random() *
|
|
3461
|
+
}, Math.random() * sr));
|
|
3389
3462
|
}
|
|
3390
3463
|
cancelRejoin() {
|
|
3391
3464
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -3409,7 +3482,7 @@ var er = class {
|
|
|
3409
3482
|
}
|
|
3410
3483
|
t.controls = !1;
|
|
3411
3484
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
3412
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
3485
|
+
r && r.insertBefore(n, t), n.appendChild(t), Z(n, this.opts.theme), this.container = n, this.controlBar = $n({
|
|
3413
3486
|
root: n,
|
|
3414
3487
|
video: t,
|
|
3415
3488
|
player: this,
|
|
@@ -3447,7 +3520,7 @@ var er = class {
|
|
|
3447
3520
|
}
|
|
3448
3521
|
startStats() {
|
|
3449
3522
|
this.stopStats();
|
|
3450
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
3523
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? ur);
|
|
3451
3524
|
this.statsTimer = setInterval(() => {
|
|
3452
3525
|
if (!this.engine) return;
|
|
3453
3526
|
let e = this.engine.getStats();
|
|
@@ -3458,14 +3531,14 @@ var er = class {
|
|
|
3458
3531
|
this.statsTimer && clearInterval(this.statsTimer), this.statsTimer = void 0;
|
|
3459
3532
|
}
|
|
3460
3533
|
isStaleLicenseDenial(e) {
|
|
3461
|
-
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !==
|
|
3534
|
+
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== fr || e.error.httpStatus !== 403 ? !1 : K(this._descriptor?.drm?.widevine?.licenseUrl);
|
|
3462
3535
|
}
|
|
3463
3536
|
scheduleLicenseRefresh() {
|
|
3464
3537
|
if (this.stopRefresh(), !this._descriptor?.drmEnabled) return;
|
|
3465
3538
|
typeof document < "u" && this.engine?.name === "hls" && (this.onRefocus = () => {
|
|
3466
3539
|
document.visibilityState !== "visible" || this.destroyed || K(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
|
|
3467
3540
|
}, document.addEventListener("visibilitychange", this.onRefocus));
|
|
3468
|
-
let e = this.opts.licenseRefreshMs ??
|
|
3541
|
+
let e = this.opts.licenseRefreshMs ?? dr;
|
|
3469
3542
|
e && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
3470
3543
|
}
|
|
3471
3544
|
stopRefresh() {
|
|
@@ -3477,7 +3550,7 @@ var er = class {
|
|
|
3477
3550
|
if (this.refreshInFlight?.engine === e) return this.refreshInFlight.promise;
|
|
3478
3551
|
let t = (async () => {
|
|
3479
3552
|
try {
|
|
3480
|
-
let t = await
|
|
3553
|
+
let t = await v(this.resolveOptions());
|
|
3481
3554
|
if (this.destroyed || this.engine !== e) return;
|
|
3482
3555
|
let n = t.drm?.widevine?.licenseUrl, r = t.drm?.fairplay?.licenseUrl;
|
|
3483
3556
|
return (n || r) && (e.setLicenseUrls({
|
|
@@ -3522,7 +3595,7 @@ var er = class {
|
|
|
3522
3595
|
this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
|
|
3523
3596
|
}
|
|
3524
3597
|
getStats() {
|
|
3525
|
-
return this.engine?.getStats() ??
|
|
3598
|
+
return this.engine?.getStats() ?? it;
|
|
3526
3599
|
}
|
|
3527
3600
|
getQualityLevels() {
|
|
3528
3601
|
return this.engine?.getQualityLevels() ?? [];
|
|
@@ -3561,10 +3634,13 @@ var er = class {
|
|
|
3561
3634
|
e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
|
|
3562
3635
|
}
|
|
3563
3636
|
async enterFullscreen() {
|
|
3564
|
-
return !this.destroyed &&
|
|
3637
|
+
return !this.destroyed && w(this.opts.video, this.container ?? void 0);
|
|
3565
3638
|
}
|
|
3566
3639
|
async exitFullscreen() {
|
|
3567
|
-
await
|
|
3640
|
+
await T(this.opts.video, this.container ?? void 0);
|
|
3641
|
+
}
|
|
3642
|
+
fullscreenSupported() {
|
|
3643
|
+
return !this.destroyed && C(this.opts.video, this.container ?? void 0);
|
|
3568
3644
|
}
|
|
3569
3645
|
retry() {
|
|
3570
3646
|
return this.reload();
|
|
@@ -3574,7 +3650,7 @@ var er = class {
|
|
|
3574
3650
|
let e = ++this.loadGen;
|
|
3575
3651
|
this.teardownPlayback();
|
|
3576
3652
|
try {
|
|
3577
|
-
let t = await
|
|
3653
|
+
let t = await y({
|
|
3578
3654
|
...this.resolveOptions(),
|
|
3579
3655
|
waitForLive: this.opts.waitForLive ? this.buildWaitConfig(e) : void 0
|
|
3580
3656
|
});
|
|
@@ -3632,7 +3708,7 @@ function $(e) {
|
|
|
3632
3708
|
}
|
|
3633
3709
|
//#endregion
|
|
3634
3710
|
//#region src/embed/host.ts
|
|
3635
|
-
function
|
|
3711
|
+
function gr(e) {
|
|
3636
3712
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
3637
3713
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
3638
3714
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -3691,15 +3767,15 @@ function tr(e) {
|
|
|
3691
3767
|
}
|
|
3692
3768
|
//#endregion
|
|
3693
3769
|
//#region src/embed/page.ts
|
|
3694
|
-
var
|
|
3695
|
-
function
|
|
3770
|
+
var _r = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
3771
|
+
function vr(e) {
|
|
3696
3772
|
if (typeof e == "boolean") return e;
|
|
3697
3773
|
if (typeof e == "object" && e) {
|
|
3698
3774
|
let t = e.endpoint;
|
|
3699
3775
|
return typeof t == "string" ? { endpoint: t } : {};
|
|
3700
3776
|
}
|
|
3701
3777
|
}
|
|
3702
|
-
function
|
|
3778
|
+
function yr() {
|
|
3703
3779
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
3704
3780
|
if (e) return {
|
|
3705
3781
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -3709,7 +3785,7 @@ function ir() {
|
|
|
3709
3785
|
autoplay: e.autoplay ?? !0,
|
|
3710
3786
|
muted: e.muted ?? !0,
|
|
3711
3787
|
waitForLive: e.waitForLive ?? !0,
|
|
3712
|
-
analytics:
|
|
3788
|
+
analytics: vr(e.analytics)
|
|
3713
3789
|
};
|
|
3714
3790
|
let t = new URLSearchParams(location.search);
|
|
3715
3791
|
return {
|
|
@@ -3722,9 +3798,9 @@ function ir() {
|
|
|
3722
3798
|
waitForLive: !0
|
|
3723
3799
|
};
|
|
3724
3800
|
}
|
|
3725
|
-
async function
|
|
3726
|
-
let e =
|
|
3727
|
-
|
|
3801
|
+
async function br() {
|
|
3802
|
+
let e = yr();
|
|
3803
|
+
Sr();
|
|
3728
3804
|
let t = document.createElement("video");
|
|
3729
3805
|
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);
|
|
3730
3806
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -3779,12 +3855,12 @@ async function ar() {
|
|
|
3779
3855
|
code: e.code,
|
|
3780
3856
|
message: e.message
|
|
3781
3857
|
})), e.on("autoplayblocked", () => {
|
|
3782
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
3858
|
+
i({ type: "oddin:autoplayblocked" }), xr(t, e);
|
|
3783
3859
|
});
|
|
3784
3860
|
}, s = async (r) => {
|
|
3785
3861
|
a?.destroy(), a = null;
|
|
3786
3862
|
try {
|
|
3787
|
-
let n = await
|
|
3863
|
+
let n = await mr({
|
|
3788
3864
|
video: t,
|
|
3789
3865
|
baseUrl: e.baseUrl,
|
|
3790
3866
|
matchUrn: r,
|
|
@@ -3846,7 +3922,7 @@ async function ar() {
|
|
|
3846
3922
|
a?.retry();
|
|
3847
3923
|
break;
|
|
3848
3924
|
case "oddin:load":
|
|
3849
|
-
typeof e.matchUrn == "string" &&
|
|
3925
|
+
typeof e.matchUrn == "string" && _r.test(e.matchUrn) && s(e.matchUrn);
|
|
3850
3926
|
break;
|
|
3851
3927
|
case "oddin:destroy": c();
|
|
3852
3928
|
}
|
|
@@ -3858,18 +3934,18 @@ async function ar() {
|
|
|
3858
3934
|
protocol: 1
|
|
3859
3935
|
});
|
|
3860
3936
|
}
|
|
3861
|
-
function
|
|
3937
|
+
function xr(e, t) {
|
|
3862
3938
|
if (document.getElementById("havik-tap")) return;
|
|
3863
3939
|
let n = document.createElement("button");
|
|
3864
3940
|
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", () => {
|
|
3865
3941
|
n.remove(), t.play();
|
|
3866
3942
|
}), document.body.appendChild(n);
|
|
3867
3943
|
}
|
|
3868
|
-
function
|
|
3944
|
+
function Sr() {
|
|
3869
3945
|
let e = document.createElement("style");
|
|
3870
3946
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
3871
3947
|
}
|
|
3872
3948
|
//#endregion
|
|
3873
|
-
export {
|
|
3949
|
+
export { Un as ODDIN_THEME, n as PlaybackError, Z as applyTheme, rt as baseUrlForEnv, br as bootEmbed, Te as clearDeviceId, Ie as clearRememberedBandwidth, mr as createPlayer, D as deriveEventsBaseUrl, $e as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, _e as fetchCatalog, ye as fetchTournament, xe as flattenMatches, C as fullscreenSupported, A as getDeviceId, tt as isLowLatencyManifest, $ as isOddinMessage, De as licenseRequestHeaders, gr as mountEmbed, de as pollToLive, y as resolveStream, E as subscribeLiveState, S as videoFullscreenActive, Ce as watchStatus };
|
|
3874
3950
|
|
|
3875
3951
|
//# sourceMappingURL=index.js.map
|