@oddin-gg/havik-player 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/havik-player.global.js +2 -2
- package/dist/havik-player.global.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +219 -190
- package/dist/index.js.map +1 -1
- package/docs/API.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
|
@@ -244,32 +244,32 @@ function ce(e, t) {
|
|
|
244
244
|
function S(e) {
|
|
245
245
|
return e.ownerDocument ?? document;
|
|
246
246
|
}
|
|
247
|
-
function
|
|
247
|
+
function le(e) {
|
|
248
248
|
return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
|
|
249
249
|
}
|
|
250
|
-
function
|
|
251
|
-
let n =
|
|
250
|
+
function C(e, t) {
|
|
251
|
+
let n = le(S(e));
|
|
252
252
|
return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
|
|
253
253
|
}
|
|
254
|
-
async function
|
|
254
|
+
async function w(e, t) {
|
|
255
255
|
let n = t ?? e;
|
|
256
256
|
if (typeof n.requestFullscreen == "function") return await n.requestFullscreen(), !0;
|
|
257
257
|
if (typeof n.webkitRequestFullscreen == "function") return n.webkitRequestFullscreen(), !0;
|
|
258
258
|
let r = e;
|
|
259
259
|
return r.webkitSupportsFullscreen && typeof r.webkitEnterFullscreen == "function" ? (r.webkitEnterFullscreen(), !0) : !1;
|
|
260
260
|
}
|
|
261
|
-
async function
|
|
261
|
+
async function T(e, t) {
|
|
262
262
|
let n = e;
|
|
263
263
|
if (n.webkitDisplayingFullscreen) {
|
|
264
264
|
n.webkitExitFullscreen?.();
|
|
265
265
|
return;
|
|
266
266
|
}
|
|
267
|
-
let r = S(e), i =
|
|
267
|
+
let r = S(e), i = le(r);
|
|
268
268
|
i != null && (i === e || t != null && i === t) && (typeof r.exitFullscreen == "function" ? await r.exitFullscreen() : r.webkitExitFullscreen?.());
|
|
269
269
|
}
|
|
270
270
|
//#endregion
|
|
271
271
|
//#region src/core/catalog.ts
|
|
272
|
-
async function
|
|
272
|
+
async function ue(e) {
|
|
273
273
|
let t = new URLSearchParams();
|
|
274
274
|
e.status && t.set("status", Array.isArray(e.status) ? e.status.join(",") : e.status), e.sport && t.set("sport", e.sport);
|
|
275
275
|
let i = t.toString(), a = c(e.baseUrl, "/v1/catalog" + (i ? `?${i}` : "")), o = new Headers();
|
|
@@ -287,12 +287,12 @@ async function le(e) {
|
|
|
287
287
|
};
|
|
288
288
|
if (!s.ok) throw new n(r(s.status), s.status, `catalog request failed (HTTP ${s.status})`);
|
|
289
289
|
return {
|
|
290
|
-
tournaments:
|
|
290
|
+
tournaments: de(await s.json()),
|
|
291
291
|
etag: s.headers.get("etag") ?? void 0,
|
|
292
292
|
notModified: !1
|
|
293
293
|
};
|
|
294
294
|
}
|
|
295
|
-
function
|
|
295
|
+
function de(e) {
|
|
296
296
|
return (e.tournaments ?? []).map((e) => {
|
|
297
297
|
let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
|
|
298
298
|
return {
|
|
@@ -312,7 +312,7 @@ function ue(e) {
|
|
|
312
312
|
};
|
|
313
313
|
});
|
|
314
314
|
}
|
|
315
|
-
async function
|
|
315
|
+
async function fe(e) {
|
|
316
316
|
let t = c(e.baseUrl, `/v1/tournaments/${encodeURIComponent(e.urn)}`), i = new Headers();
|
|
317
317
|
e.etag && i.set("If-None-Match", e.etag);
|
|
318
318
|
let a = await u(t, {
|
|
@@ -332,13 +332,13 @@ async function de(e) {
|
|
|
332
332
|
};
|
|
333
333
|
if (!a.ok) throw new n(r(a.status), a.status, `tournament request failed (HTTP ${a.status})`);
|
|
334
334
|
return {
|
|
335
|
-
tournament:
|
|
335
|
+
tournament: pe(await a.json()),
|
|
336
336
|
etag: a.headers.get("etag") ?? void 0,
|
|
337
337
|
notModified: !1,
|
|
338
338
|
notFound: !1
|
|
339
339
|
};
|
|
340
340
|
}
|
|
341
|
-
function
|
|
341
|
+
function pe(e) {
|
|
342
342
|
let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
|
|
343
343
|
return {
|
|
344
344
|
urn: t,
|
|
@@ -356,12 +356,12 @@ function fe(e) {
|
|
|
356
356
|
}))
|
|
357
357
|
};
|
|
358
358
|
}
|
|
359
|
-
function
|
|
359
|
+
function me(e) {
|
|
360
360
|
return e.tournaments.flatMap((e) => e.matches);
|
|
361
361
|
}
|
|
362
362
|
//#endregion
|
|
363
363
|
//#region src/core/poll.ts
|
|
364
|
-
function
|
|
364
|
+
function he(e) {
|
|
365
365
|
let t = Math.max(2e3, e.intervalMs ?? 1e4), i = new AbortController(), a, o, s, l = !1, d = () => {
|
|
366
366
|
l || (a = setTimeout(f, t));
|
|
367
367
|
}, f = async () => {
|
|
@@ -397,7 +397,7 @@ function me(e) {
|
|
|
397
397
|
}
|
|
398
398
|
//#endregion
|
|
399
399
|
//#region src/core/events.ts
|
|
400
|
-
function
|
|
400
|
+
function E(e) {
|
|
401
401
|
let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = new AbortController(), i = !1, a = (e) => new Promise((t) => {
|
|
402
402
|
if (r.signal.aborted) return t();
|
|
403
403
|
let n = setTimeout(t, e);
|
|
@@ -464,7 +464,7 @@ function D(e) {
|
|
|
464
464
|
i || (i = !0, r.abort());
|
|
465
465
|
} };
|
|
466
466
|
}
|
|
467
|
-
function
|
|
467
|
+
function D(e) {
|
|
468
468
|
try {
|
|
469
469
|
let t = new URL(e);
|
|
470
470
|
return t.hostname = `events.${t.hostname}`, t.pathname = "", t.search = "", t.origin;
|
|
@@ -474,27 +474,27 @@ function O(e) {
|
|
|
474
474
|
}
|
|
475
475
|
//#endregion
|
|
476
476
|
//#region src/core/drm/deviceId.ts
|
|
477
|
-
var
|
|
478
|
-
function
|
|
479
|
-
if (
|
|
477
|
+
var O = "havik.player.deviceId", k;
|
|
478
|
+
function A() {
|
|
479
|
+
if (k) return k;
|
|
480
480
|
try {
|
|
481
|
-
let e = globalThis.localStorage?.getItem(
|
|
482
|
-
if (e) return
|
|
481
|
+
let e = globalThis.localStorage?.getItem(O);
|
|
482
|
+
if (e) return k = e, e;
|
|
483
483
|
} catch {}
|
|
484
|
-
let e =
|
|
485
|
-
|
|
484
|
+
let e = _e();
|
|
485
|
+
k = e;
|
|
486
486
|
try {
|
|
487
|
-
globalThis.localStorage?.setItem(
|
|
487
|
+
globalThis.localStorage?.setItem(O, e);
|
|
488
488
|
} catch {}
|
|
489
489
|
return e;
|
|
490
490
|
}
|
|
491
|
-
function
|
|
492
|
-
|
|
491
|
+
function ge() {
|
|
492
|
+
k = void 0;
|
|
493
493
|
try {
|
|
494
|
-
globalThis.localStorage?.removeItem(
|
|
494
|
+
globalThis.localStorage?.removeItem(O);
|
|
495
495
|
} catch {}
|
|
496
496
|
}
|
|
497
|
-
function
|
|
497
|
+
function _e() {
|
|
498
498
|
let e = globalThis.crypto;
|
|
499
499
|
if (e && typeof e.randomUUID == "function") return e.randomUUID();
|
|
500
500
|
let t = /* @__PURE__ */ new Uint8Array(16);
|
|
@@ -506,22 +506,22 @@ function ge() {
|
|
|
506
506
|
}
|
|
507
507
|
//#endregion
|
|
508
508
|
//#region src/core/drm/headers.ts
|
|
509
|
-
function
|
|
509
|
+
function ve(e, t, n = {}) {
|
|
510
510
|
let r = {
|
|
511
511
|
"x-api-key": t.apiKey,
|
|
512
512
|
"X-Match-Urn": e.matchUrn,
|
|
513
|
-
"X-Device-Id": n.deviceId ??
|
|
513
|
+
"X-Device-Id": n.deviceId ?? A(),
|
|
514
514
|
"Content-Type": "application/octet-stream"
|
|
515
515
|
};
|
|
516
516
|
return n.userId && (r["X-User-Id"] = n.userId), r;
|
|
517
517
|
}
|
|
518
518
|
//#endregion
|
|
519
519
|
//#region src/core/drm/support.ts
|
|
520
|
-
var
|
|
520
|
+
var ye = 5e3, j = "video/mp4; codecs=\"avc1.42E01E\"", M = "audio/mp4; codecs=\"mp4a.40.2\"", be = {
|
|
521
521
|
widevine: ["com.widevine.alpha"],
|
|
522
522
|
fairplay: ["com.apple.fps"]
|
|
523
523
|
};
|
|
524
|
-
function
|
|
524
|
+
function xe(e) {
|
|
525
525
|
return e === "fairplay" ? [{
|
|
526
526
|
initDataTypes: [
|
|
527
527
|
"sinf",
|
|
@@ -529,30 +529,30 @@ function be(e) {
|
|
|
529
529
|
"cenc"
|
|
530
530
|
],
|
|
531
531
|
videoCapabilities: [{
|
|
532
|
-
contentType:
|
|
532
|
+
contentType: j,
|
|
533
533
|
robustness: "",
|
|
534
534
|
encryptionScheme: "cbcs"
|
|
535
535
|
}],
|
|
536
536
|
audioCapabilities: [{
|
|
537
|
-
contentType:
|
|
537
|
+
contentType: M,
|
|
538
538
|
robustness: "",
|
|
539
539
|
encryptionScheme: "cbcs"
|
|
540
540
|
}]
|
|
541
541
|
}] : [{
|
|
542
542
|
initDataTypes: ["cenc"],
|
|
543
543
|
videoCapabilities: [{
|
|
544
|
-
contentType:
|
|
544
|
+
contentType: j,
|
|
545
545
|
robustness: "SW_SECURE_DECODE",
|
|
546
546
|
encryptionScheme: "cbcs"
|
|
547
547
|
}],
|
|
548
548
|
audioCapabilities: [{
|
|
549
|
-
contentType:
|
|
549
|
+
contentType: M,
|
|
550
550
|
robustness: "SW_SECURE_CRYPTO",
|
|
551
551
|
encryptionScheme: "cbcs"
|
|
552
552
|
}]
|
|
553
553
|
}];
|
|
554
554
|
}
|
|
555
|
-
function
|
|
555
|
+
function N(e, t) {
|
|
556
556
|
return new Promise((n, r) => {
|
|
557
557
|
let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
|
|
558
558
|
e.then((e) => {
|
|
@@ -562,8 +562,8 @@ function P(e, t) {
|
|
|
562
562
|
});
|
|
563
563
|
});
|
|
564
564
|
}
|
|
565
|
-
async function
|
|
566
|
-
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ??
|
|
565
|
+
async function Se(e = {}) {
|
|
566
|
+
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? ye, r = {};
|
|
567
567
|
if (typeof window < "u" && window.isSecureContext === !1) return {
|
|
568
568
|
verdict: "insecure-context",
|
|
569
569
|
detail: r
|
|
@@ -575,7 +575,7 @@ async function xe(e = {}) {
|
|
|
575
575
|
};
|
|
576
576
|
let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
|
|
577
577
|
for (let e of t) {
|
|
578
|
-
let t =
|
|
578
|
+
let t = be[e];
|
|
579
579
|
if (!t) {
|
|
580
580
|
r[e] = "unknown system";
|
|
581
581
|
continue;
|
|
@@ -586,7 +586,7 @@ async function xe(e = {}) {
|
|
|
586
586
|
break;
|
|
587
587
|
}
|
|
588
588
|
try {
|
|
589
|
-
return await
|
|
589
|
+
return await N((await N(i(n, xe(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
|
|
590
590
|
verdict: "supported",
|
|
591
591
|
system: e,
|
|
592
592
|
detail: r
|
|
@@ -610,21 +610,44 @@ async function xe(e = {}) {
|
|
|
610
610
|
}
|
|
611
611
|
//#endregion
|
|
612
612
|
//#region src/core/manifest.ts
|
|
613
|
-
var
|
|
614
|
-
function
|
|
615
|
-
return
|
|
613
|
+
var Ce = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
|
|
614
|
+
function we(e) {
|
|
615
|
+
return Ce.test(e);
|
|
616
|
+
}
|
|
617
|
+
//#endregion
|
|
618
|
+
//#region src/core/drm/cdm.ts
|
|
619
|
+
var Te = /* @__PURE__ */ new WeakMap();
|
|
620
|
+
function Ee(e, t) {
|
|
621
|
+
let n = Te.get(e);
|
|
622
|
+
n || (n = /* @__PURE__ */ new Map(), Te.set(e, n));
|
|
623
|
+
let r = n.get(t.keySystem);
|
|
624
|
+
if (r) return r;
|
|
625
|
+
let i = t.createMediaKeys().catch((e) => {
|
|
626
|
+
throw n.get(t.keySystem) === i && n.delete(t.keySystem), e;
|
|
627
|
+
});
|
|
628
|
+
return n.set(t.keySystem, i), i;
|
|
629
|
+
}
|
|
630
|
+
function P() {
|
|
631
|
+
return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
|
|
632
|
+
}
|
|
633
|
+
function De(e) {
|
|
634
|
+
return (t, n) => P() ? navigator.requestMediaKeySystemAccess(t, n).then((t) => ({
|
|
635
|
+
keySystem: t.keySystem,
|
|
636
|
+
getConfiguration: () => t.getConfiguration(),
|
|
637
|
+
createMediaKeys: () => Ee(e, t)
|
|
638
|
+
})) : Promise.reject(/* @__PURE__ */ Error("navigator.requestMediaKeySystemAccess is unavailable — EME needs a secure context (https, or localhost)"));
|
|
616
639
|
}
|
|
617
640
|
//#endregion
|
|
618
641
|
//#region src/core/stats.ts
|
|
619
|
-
var
|
|
620
|
-
function
|
|
642
|
+
var F = { droppedFrames: 0 };
|
|
643
|
+
function I(e) {
|
|
621
644
|
let t = e.getVideoPlaybackQuality?.();
|
|
622
645
|
return {
|
|
623
646
|
dropped: t?.droppedVideoFrames ?? 0,
|
|
624
647
|
decoded: t?.totalVideoFrames ?? 0
|
|
625
648
|
};
|
|
626
649
|
}
|
|
627
|
-
function
|
|
650
|
+
function Oe(e, t) {
|
|
628
651
|
let n = [
|
|
629
652
|
["playing", () => t("playing")],
|
|
630
653
|
["waiting", () => t("buffering")],
|
|
@@ -641,7 +664,7 @@ function Te(e, t) {
|
|
|
641
664
|
}
|
|
642
665
|
//#endregion
|
|
643
666
|
//#region src/core/engine/native.ts
|
|
644
|
-
function
|
|
667
|
+
function ke(e) {
|
|
645
668
|
try {
|
|
646
669
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
647
670
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -649,15 +672,15 @@ function Ee(e) {
|
|
|
649
672
|
return;
|
|
650
673
|
}
|
|
651
674
|
}
|
|
652
|
-
function
|
|
675
|
+
function L(e) {
|
|
653
676
|
return !!(e ?? (typeof document < "u" ? document.createElement("video") : void 0))?.canPlayType("application/vnd.apple.mpegurl");
|
|
654
677
|
}
|
|
655
|
-
function
|
|
678
|
+
function R() {
|
|
656
679
|
if (typeof window > "u") return !1;
|
|
657
680
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
658
681
|
return e || t;
|
|
659
682
|
}
|
|
660
|
-
var
|
|
683
|
+
var z = class {
|
|
661
684
|
name = "native";
|
|
662
685
|
deps;
|
|
663
686
|
onLoaded;
|
|
@@ -691,7 +714,7 @@ var R = class {
|
|
|
691
714
|
type: "error",
|
|
692
715
|
error: new n("INTERNAL", 0, "native HLS playback error"),
|
|
693
716
|
fatal: !0
|
|
694
|
-
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src =
|
|
717
|
+
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = Ae(t.manifestUrl, t.analytics?.sid), e.load();
|
|
695
718
|
}
|
|
696
719
|
startLoad() {
|
|
697
720
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -713,7 +736,7 @@ var R = class {
|
|
|
713
736
|
});
|
|
714
737
|
this.onEncrypted = (n) => {
|
|
715
738
|
let i = n;
|
|
716
|
-
!i.initData || this.fairplayArmed || (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
739
|
+
!i.initData || this.fairplayArmed || (this.fairplayArmed = !0, this.fairplayKeyIV = ke(i.initData), (async () => {
|
|
717
740
|
try {
|
|
718
741
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
719
742
|
initDataTypes: [i.initDataType],
|
|
@@ -808,7 +831,7 @@ var R = class {
|
|
|
808
831
|
e.seekable.length > 0 && (e.currentTime = e.seekable.end(e.seekable.length - 1));
|
|
809
832
|
}
|
|
810
833
|
getStats() {
|
|
811
|
-
let e = this.deps.video, t =
|
|
834
|
+
let e = this.deps.video, t = I(e), n = {
|
|
812
835
|
droppedFrames: t.dropped,
|
|
813
836
|
decodedFrames: t.decoded
|
|
814
837
|
};
|
|
@@ -831,36 +854,36 @@ var R = class {
|
|
|
831
854
|
} catch {}
|
|
832
855
|
}
|
|
833
856
|
};
|
|
834
|
-
function
|
|
857
|
+
function Ae(e, t) {
|
|
835
858
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
836
859
|
}
|
|
837
860
|
//#endregion
|
|
838
861
|
//#region src/core/engine/hls.ts
|
|
839
|
-
function
|
|
862
|
+
function je() {
|
|
840
863
|
return e.isSupported();
|
|
841
864
|
}
|
|
842
|
-
var
|
|
843
|
-
function
|
|
865
|
+
var Me = 3, Ne = 5, Pe = 3, Fe = 3e4, Ie = 12e3, Le = 3e3, B = 6e3, Re = 4e3, ze = 2, Be = 5, Ve = 2, He = 2, Ue = 2e3, We = 3e4, Ge = 2, Ke = 9, qe = .5, Je = 64;
|
|
866
|
+
function Ye(e) {
|
|
844
867
|
try {
|
|
845
868
|
return new URL(e).host;
|
|
846
869
|
} catch {
|
|
847
870
|
return "";
|
|
848
871
|
}
|
|
849
872
|
}
|
|
850
|
-
function
|
|
873
|
+
function Xe(e) {
|
|
851
874
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
852
875
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
853
876
|
return;
|
|
854
877
|
}
|
|
855
|
-
e.liveSyncDuration ??=
|
|
856
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
857
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
878
|
+
e.liveSyncDuration ??= Ge;
|
|
879
|
+
let t = Math.max(12, e.liveSyncDuration + Ke);
|
|
880
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Ze(e, e.liveSyncDuration);
|
|
858
881
|
}
|
|
859
|
-
function
|
|
882
|
+
function Ze(e, t) {
|
|
860
883
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
861
884
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
862
885
|
}
|
|
863
|
-
var
|
|
886
|
+
var V = class {
|
|
864
887
|
name = "hls";
|
|
865
888
|
hls = null;
|
|
866
889
|
deps;
|
|
@@ -914,7 +937,7 @@ var B = class {
|
|
|
914
937
|
this.deps = e, this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
915
938
|
}
|
|
916
939
|
async load() {
|
|
917
|
-
let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a =
|
|
940
|
+
let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = L(r) && R(), o = !!e.drm?.widevine?.licenseUrl && !a;
|
|
918
941
|
if (e.drmEnabled && !o) {
|
|
919
942
|
i({
|
|
920
943
|
type: "error",
|
|
@@ -954,7 +977,7 @@ var B = class {
|
|
|
954
977
|
let t = e.liveSyncPosition;
|
|
955
978
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
956
979
|
let { video: n } = this.deps;
|
|
957
|
-
n.currentTime <= t +
|
|
980
|
+
n.currentTime <= t + qe || (n.currentTime = t);
|
|
958
981
|
}
|
|
959
982
|
startHls() {
|
|
960
983
|
let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
|
|
@@ -978,6 +1001,7 @@ var B = class {
|
|
|
978
1001
|
videoEncryptionScheme: "cbcs",
|
|
979
1002
|
audioEncryptionScheme: "cbcs"
|
|
980
1003
|
},
|
|
1004
|
+
...P() ? { requestMediaKeySystemAccessFunc: De(t) } : {},
|
|
981
1005
|
licenseXhrSetup: (e, t) => {
|
|
982
1006
|
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;
|
|
983
1007
|
let o = performance.now();
|
|
@@ -993,7 +1017,7 @@ var B = class {
|
|
|
993
1017
|
} } : {},
|
|
994
1018
|
...c
|
|
995
1019
|
};
|
|
996
|
-
|
|
1020
|
+
Xe(d), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.loadStarted = d.autoStartLoad !== !1;
|
|
997
1021
|
let f = new e(d);
|
|
998
1022
|
this.hls = f, f.on(e.Events.MANIFEST_PARSED, () => {
|
|
999
1023
|
this.mediaRecoveries = 0, this.networkRecoveries = 0;
|
|
@@ -1002,17 +1026,17 @@ var B = class {
|
|
|
1002
1026
|
}), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1003
1027
|
t?.frag?.type === "main" && (this.kickPending = !1, this.kickTicks = 0, (this.mediaRecoveries > 0 || this.networkRecoveries > 0 || this.licenseRecoveries > 0 || this.starvationKicks > 0 || this.starvationRebuilds > 0) && !this.recoveryResetTimer && (this.recoveryResetTimer = setTimeout(() => {
|
|
1004
1028
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1005
|
-
},
|
|
1029
|
+
}, Fe)));
|
|
1006
1030
|
}), f.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1007
1031
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1008
1032
|
}), f.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
1009
1033
|
let n = t?.frag?.stats, r = n?.loaded;
|
|
1010
1034
|
typeof r == "number" && (this.bytesLoaded += r);
|
|
1011
1035
|
let i = n?.loading;
|
|
1012
|
-
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 >
|
|
1036
|
+
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 > Je && this.requestTimesMs.shift());
|
|
1013
1037
|
let a = t?.frag?.url;
|
|
1014
1038
|
if (a) {
|
|
1015
|
-
let e =
|
|
1039
|
+
let e = Ye(a);
|
|
1016
1040
|
e && (this.cdnHost = e);
|
|
1017
1041
|
}
|
|
1018
1042
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1025,7 +1049,7 @@ var B = class {
|
|
|
1025
1049
|
}));
|
|
1026
1050
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1027
1051
|
this.checkEndStale(), this.checkStarvation();
|
|
1028
|
-
},
|
|
1052
|
+
}, Le), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1029
1053
|
this.renditionSwitches += 1;
|
|
1030
1054
|
let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
|
|
1031
1055
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
|
|
@@ -1089,7 +1113,7 @@ var B = class {
|
|
|
1089
1113
|
return;
|
|
1090
1114
|
}
|
|
1091
1115
|
this.capTimer && clearTimeout(this.capTimer);
|
|
1092
|
-
let t = e > this.sizeCapLevel ?
|
|
1116
|
+
let t = e > this.sizeCapLevel ? Ue : We;
|
|
1093
1117
|
this.capTimer = setTimeout(() => {
|
|
1094
1118
|
this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
|
|
1095
1119
|
}, t);
|
|
@@ -1136,7 +1160,7 @@ var B = class {
|
|
|
1136
1160
|
e.widevine && (this.licenseUrl = e.widevine);
|
|
1137
1161
|
}
|
|
1138
1162
|
getStats() {
|
|
1139
|
-
let e = this.hls, t =
|
|
1163
|
+
let e = this.hls, t = I(this.deps.video), n = {
|
|
1140
1164
|
droppedFrames: t.dropped,
|
|
1141
1165
|
decodedFrames: t.decoded,
|
|
1142
1166
|
lowLatency: this.detectedLowLatency,
|
|
@@ -1178,7 +1202,7 @@ var B = class {
|
|
|
1178
1202
|
return;
|
|
1179
1203
|
}
|
|
1180
1204
|
let e = Date.now() - this.lastAdvanceMs;
|
|
1181
|
-
!this.chaseSuspended && e >
|
|
1205
|
+
!this.chaseSuspended && e > B && this.suspendChasing(), e > Ie && this.emitEnded("stalled");
|
|
1182
1206
|
}
|
|
1183
1207
|
checkStarvation() {
|
|
1184
1208
|
let e = this.hls, { video: t } = this.deps;
|
|
@@ -1187,17 +1211,17 @@ var B = class {
|
|
|
1187
1211
|
this.starvedTicks = 0;
|
|
1188
1212
|
return;
|
|
1189
1213
|
}
|
|
1190
|
-
let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs <
|
|
1214
|
+
let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs < B, r = this.lastFragLoadingMs !== 0 && Date.now() - this.lastFragLoadingMs > Re;
|
|
1191
1215
|
if (!(t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused && n && r)) {
|
|
1192
1216
|
this.starvedTicks = 0;
|
|
1193
1217
|
return;
|
|
1194
1218
|
}
|
|
1195
|
-
if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks <
|
|
1196
|
-
if (this.starvedTicks = 0, this.kickPending && this.kickTicks >=
|
|
1219
|
+
if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks < ze)) {
|
|
1220
|
+
if (this.starvedTicks = 0, this.kickPending && this.kickTicks >= Ve && (this.kickPending = !1, this.kickTicks = 0, this.starvationRebuilds < He)) {
|
|
1197
1221
|
this.starvationRebuilds += 1, console.warn("havik-player: restarting the load did not resume video (the wedge is in hls.js state that only a rebuild clears) — rebuilding the player"), this.rebuildInstance("starvation rebuild");
|
|
1198
1222
|
return;
|
|
1199
1223
|
}
|
|
1200
|
-
if (!(this.starvationKicks >=
|
|
1224
|
+
if (!(this.starvationKicks >= Be)) {
|
|
1201
1225
|
this.starvationKicks += 1, this.kickPending = !0, this.kickTicks = 0, console.warn("havik-player: video starved while the live playlist advances (wedged hls.js fragment pipeline) — restarting the load");
|
|
1202
1226
|
try {
|
|
1203
1227
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -1247,7 +1271,7 @@ var B = class {
|
|
|
1247
1271
|
scheduleLicenseRetry(t) {
|
|
1248
1272
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
1249
1273
|
let n = t.response?.code ?? 0;
|
|
1250
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
1274
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Pe) return !1;
|
|
1251
1275
|
this.licenseRecoveries += 1;
|
|
1252
1276
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
1253
1277
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -1279,7 +1303,7 @@ var B = class {
|
|
|
1279
1303
|
return;
|
|
1280
1304
|
}
|
|
1281
1305
|
if (t.type === e.ErrorTypes.NETWORK_ERROR) {
|
|
1282
|
-
if (this.networkRecoveries <
|
|
1306
|
+
if (this.networkRecoveries < Ne) {
|
|
1283
1307
|
this.networkRecoveries += 1;
|
|
1284
1308
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
1285
1309
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -1296,7 +1320,7 @@ var B = class {
|
|
|
1296
1320
|
return;
|
|
1297
1321
|
}
|
|
1298
1322
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
1299
|
-
if (this.mediaRecoveries <
|
|
1323
|
+
if (this.mediaRecoveries < Me) {
|
|
1300
1324
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
1301
1325
|
return;
|
|
1302
1326
|
}
|
|
@@ -1320,19 +1344,19 @@ var B = class {
|
|
|
1320
1344
|
let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
|
|
1321
1345
|
return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
|
|
1322
1346
|
}
|
|
1323
|
-
},
|
|
1347
|
+
}, Qe = 15e3, $e = 100, H = 1, et = 1e3, U = 3e4, tt = {
|
|
1324
1348
|
inline: "PRESENTATION_INLINE",
|
|
1325
1349
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
1326
1350
|
pip: "PRESENTATION_PIP"
|
|
1327
|
-
},
|
|
1351
|
+
}, nt = {
|
|
1328
1352
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
1329
1353
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
1330
1354
|
none: "KEY_SYSTEM_NONE"
|
|
1331
1355
|
};
|
|
1332
|
-
function
|
|
1356
|
+
function W(e, t) {
|
|
1333
1357
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
1334
1358
|
}
|
|
1335
|
-
var
|
|
1359
|
+
var rt = /* @__PURE__ */ new Set([
|
|
1336
1360
|
"INVALID_URN",
|
|
1337
1361
|
"NOT_FOUND",
|
|
1338
1362
|
"GONE",
|
|
@@ -1342,7 +1366,7 @@ var et = /* @__PURE__ */ new Set([
|
|
|
1342
1366
|
"FORBIDDEN",
|
|
1343
1367
|
"RATE_LIMITED",
|
|
1344
1368
|
"TIMEOUT"
|
|
1345
|
-
]),
|
|
1369
|
+
]), G = {
|
|
1346
1370
|
idle: "PLAYER_STATE_IDLE",
|
|
1347
1371
|
waiting: "PLAYER_STATE_WAITING",
|
|
1348
1372
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -1352,7 +1376,7 @@ var et = /* @__PURE__ */ new Set([
|
|
|
1352
1376
|
ended: "PLAYER_STATE_ENDED",
|
|
1353
1377
|
error: "PLAYER_STATE_ERROR"
|
|
1354
1378
|
};
|
|
1355
|
-
function
|
|
1379
|
+
function it(e) {
|
|
1356
1380
|
try {
|
|
1357
1381
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
1358
1382
|
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);
|
|
@@ -1360,7 +1384,7 @@ function tt(e) {
|
|
|
1360
1384
|
return;
|
|
1361
1385
|
}
|
|
1362
1386
|
}
|
|
1363
|
-
var
|
|
1387
|
+
var at = class {
|
|
1364
1388
|
opts;
|
|
1365
1389
|
url;
|
|
1366
1390
|
now;
|
|
@@ -1381,6 +1405,7 @@ var nt = class {
|
|
|
1381
1405
|
rebufferCount = 0;
|
|
1382
1406
|
rebufferTotalMs = 0;
|
|
1383
1407
|
bufferingSinceMs = null;
|
|
1408
|
+
isBuffering = !1;
|
|
1384
1409
|
errorCount = 0;
|
|
1385
1410
|
seekCount = 0;
|
|
1386
1411
|
pauseCount = 0;
|
|
@@ -1421,12 +1446,12 @@ var nt = class {
|
|
|
1421
1446
|
firstFragLoadMs = 0;
|
|
1422
1447
|
onPagehide = () => this.end("END_REASON_PAGEHIDE");
|
|
1423
1448
|
onVisibility = () => {
|
|
1424
|
-
typeof document > "u" || (document.visibilityState === "hidden" ? (this.hiddenSinceMs === null && (this.hiddenSinceMs = this.now()), this.isHidden = !0) : (this.hiddenSinceMs !== null && (this.hiddenTotalMs += this.now() - this.hiddenSinceMs, this.hiddenSinceMs = null), this.isHidden = !1), this.syncActive());
|
|
1449
|
+
typeof document > "u" || (document.visibilityState === "hidden" ? (this.hiddenSinceMs === null && (this.hiddenSinceMs = this.now()), this.isHidden = !0) : (this.hiddenSinceMs !== null && (this.hiddenTotalMs += this.now() - this.hiddenSinceMs, this.hiddenSinceMs = null), this.isHidden = !1), this.syncActive(), this.syncBuffering());
|
|
1425
1450
|
};
|
|
1426
1451
|
constructor(e) {
|
|
1427
1452
|
this.opts = {
|
|
1428
1453
|
...e,
|
|
1429
|
-
heartbeatMs: e.heartbeatMs ??
|
|
1454
|
+
heartbeatMs: e.heartbeatMs ?? Qe
|
|
1430
1455
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`, this.now = e.now ?? (() => Date.now()), this.bornMs = this.now(), this.presentationSinceMs = this.bornMs;
|
|
1431
1456
|
}
|
|
1432
1457
|
start() {
|
|
@@ -1436,16 +1461,16 @@ var nt = class {
|
|
|
1436
1461
|
sdkVersion: this.opts.sdkVersion,
|
|
1437
1462
|
...this.opts.environment
|
|
1438
1463
|
};
|
|
1439
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
1464
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), et), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), this.onVisibility());
|
|
1440
1465
|
}
|
|
1441
1466
|
noteStateChange(e, t, n, r) {
|
|
1442
1467
|
if (this.endedFlag || e === t) return;
|
|
1443
1468
|
let i = this.now();
|
|
1444
|
-
t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(
|
|
1469
|
+
t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(H, i - this.bornMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(H, i - this.bornMs)), 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" ? (this.isHidden || (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(H, Math.round(this.playingTotalMs)))) : e === "buffering" && (this.isBuffering = !1), this.syncBuffering(), t === "paused" && (this.pauseCount += 1);
|
|
1445
1470
|
let a = {
|
|
1446
|
-
fromState:
|
|
1447
|
-
toState:
|
|
1448
|
-
presentation:
|
|
1471
|
+
fromState: G[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1472
|
+
toState: G[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1473
|
+
presentation: tt[this.presentation]
|
|
1449
1474
|
}, o = this.causeOf(e, t, i);
|
|
1450
1475
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
1451
1476
|
}
|
|
@@ -1458,6 +1483,10 @@ var nt = class {
|
|
|
1458
1483
|
let e = this.isPlaying && !this.isHidden && !this.isMuted;
|
|
1459
1484
|
e && this.activeSinceMs === null ? this.activeSinceMs = this.now() : !e && this.activeSinceMs !== null && (this.activeTotalMs += this.now() - this.activeSinceMs, this.activeSinceMs = null);
|
|
1460
1485
|
}
|
|
1486
|
+
syncBuffering() {
|
|
1487
|
+
let e = this.isBuffering && !this.isHidden;
|
|
1488
|
+
e && this.bufferingSinceMs === null ? this.bufferingSinceMs = this.now() : !e && this.bufferingSinceMs !== null && (this.rebufferTotalMs += this.now() - this.bufferingSinceMs, this.bufferingSinceMs = null);
|
|
1489
|
+
}
|
|
1461
1490
|
closePresentation() {
|
|
1462
1491
|
let e = this.now(), t = e - this.presentationSinceMs;
|
|
1463
1492
|
this.presentation === "fullscreen" ? this.fullscreenTotalMs += t : this.presentation === "pip" && (this.pipTotalMs += t), this.presentationSinceMs = e;
|
|
@@ -1480,16 +1509,16 @@ var nt = class {
|
|
|
1480
1509
|
}
|
|
1481
1510
|
this.muteChanges += 1;
|
|
1482
1511
|
let r = this.now();
|
|
1483
|
-
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(
|
|
1512
|
+
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(H, r - this.bornMs))), this.isMuted = n, this.syncActive();
|
|
1484
1513
|
}
|
|
1485
1514
|
notePresentation(e) {
|
|
1486
1515
|
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
1487
1516
|
}
|
|
1488
1517
|
noteReady() {
|
|
1489
|
-
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(
|
|
1518
|
+
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(H, this.now() - this.bornMs));
|
|
1490
1519
|
}
|
|
1491
1520
|
noteFirstBytes() {
|
|
1492
|
-
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(
|
|
1521
|
+
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(H, this.now() - this.bornMs));
|
|
1493
1522
|
}
|
|
1494
1523
|
noteSeek() {
|
|
1495
1524
|
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
@@ -1508,7 +1537,7 @@ var nt = class {
|
|
|
1508
1537
|
let r = n ?? "";
|
|
1509
1538
|
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";
|
|
1510
1539
|
if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
|
|
1511
|
-
if (
|
|
1540
|
+
if (rt.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
1512
1541
|
let i = t ?? "";
|
|
1513
1542
|
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";
|
|
1514
1543
|
}
|
|
@@ -1534,7 +1563,7 @@ var nt = class {
|
|
|
1534
1563
|
let s = e.droppedFrames ?? 0;
|
|
1535
1564
|
s > this.lastDropped && (i.droppedFramesDelta = s - this.lastDropped), this.lastDropped = s;
|
|
1536
1565
|
let c = e.renditionSwitches ?? 0;
|
|
1537
|
-
c > this.lastSwitches && (i.renditionSwitchesDelta = c - this.lastSwitches), this.lastSwitches = c, n > this.lastHbPlayingMs && (i.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (i.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, typeof e.latencySeconds == "number" && (i.latencyMs = Math.round(e.latencySeconds * 1e3)), typeof e.targetLatencySeconds == "number" && (i.targetLatencyMs = Math.round(e.targetLatencySeconds * 1e3)), typeof e.bandwidthKbps == "number" && (i.bandwidthEstKbps = e.bandwidthKbps), typeof e.levelHeight == "number" && (i.renditionHeight = e.levelHeight), typeof e.renditionBitrateKbps == "number" && (i.renditionBitrateKbps = e.renditionBitrateKbps), e.atLiveEdge === !0 && (i.atLiveEdge = !0), typeof e.bufferedMs == "number" && e.bufferedMs > 0 && (i.bufferedMs = Math.round(e.bufferedMs)), i.playerState =
|
|
1566
|
+
c > this.lastSwitches && (i.renditionSwitchesDelta = c - this.lastSwitches), this.lastSwitches = c, n > this.lastHbPlayingMs && (i.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (i.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, typeof e.latencySeconds == "number" && (i.latencyMs = Math.round(e.latencySeconds * 1e3)), typeof e.targetLatencySeconds == "number" && (i.targetLatencyMs = Math.round(e.targetLatencySeconds * 1e3)), typeof e.bandwidthKbps == "number" && (i.bandwidthEstKbps = e.bandwidthKbps), typeof e.levelHeight == "number" && (i.renditionHeight = e.levelHeight), typeof e.renditionBitrateKbps == "number" && (i.renditionBitrateKbps = e.renditionBitrateKbps), e.atLiveEdge === !0 && (i.atLiveEdge = !0), typeof e.bufferedMs == "number" && e.bufferedMs > 0 && (i.bufferedMs = Math.round(e.bufferedMs)), i.playerState = G[e.state] ?? "PLAYER_STATE_UNSPECIFIED";
|
|
1538
1567
|
let l = this.mutedTotalMs;
|
|
1539
1568
|
this.mutedSinceMs !== null && (l += t - this.mutedSinceMs), l > this.lastHbMutedMs && (i.mutedMsDelta = Math.round(l - this.lastHbMutedMs)), this.lastHbMutedMs = l;
|
|
1540
1569
|
let u = e.upshifts ?? 0;
|
|
@@ -1549,14 +1578,14 @@ var nt = class {
|
|
|
1549
1578
|
if (this.lastRequestCount = m, h > 0) {
|
|
1550
1579
|
i.requestCountDelta = h;
|
|
1551
1580
|
let t = e.requestTimesMs ?? [], n = t.slice(Math.max(0, t.length - h)).sort((e, t) => e - t);
|
|
1552
|
-
n.length > 0 && (i.requestTimeP50Ms =
|
|
1581
|
+
n.length > 0 && (i.requestTimeP50Ms = W(n, 50), i.requestTimeP95Ms = W(n, 95));
|
|
1553
1582
|
}
|
|
1554
1583
|
typeof e.latencySeconds == "number" && typeof e.targetLatencySeconds == "number" && (i.driftMs = Math.round((e.latencySeconds - e.targetLatencySeconds) * 1e3)), typeof e.playbackRate == "number" && e.playbackRate > 0 && (i.playbackRate = e.playbackRate), e.qualityPinned === !0 && (i.qualityPinned = !0), e.cdnHost && (i.cdnHost = e.cdnHost), this.maybeEmitMediaInfo(e), this.enqueue({ heartbeat: i }), this.flush(), a > 0 && this.noteFirstBytes();
|
|
1555
1584
|
}
|
|
1556
1585
|
maybeEmitMediaInfo(e) {
|
|
1557
1586
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
1558
1587
|
let t = {};
|
|
1559
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
1588
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = nt[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);
|
|
1560
1589
|
let n = JSON.stringify(t);
|
|
1561
1590
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
1562
1591
|
}
|
|
@@ -1576,7 +1605,7 @@ var nt = class {
|
|
|
1576
1605
|
let s = n?.positionMs ?? 0;
|
|
1577
1606
|
s > 0 && (r.exitPositionMs = Math.round(s)), this.activeTotalMs > 0 && (r.activeWatchTimeMs = Math.round(this.activeTotalMs)), this.mutedTotalMs > 0 && (r.mutedTimeMs = Math.round(this.mutedTotalMs));
|
|
1578
1607
|
let c = e !== "END_REASON_ENDED";
|
|
1579
|
-
c && this.lastStallMs > 0 && t - this.lastStallMs <=
|
|
1608
|
+
c && this.lastStallMs > 0 && t - this.lastStallMs <= U && (r.abandonAfterStallMs = Math.max(H, Math.round(t - this.lastStallMs))), c && this.lastErrorMs > 0 && t - this.lastErrorMs <= U && (r.abandonAfterErrorMs = Math.max(H, Math.round(t - this.lastErrorMs))), this.fullscreenTotalMs > 0 && (r.fullscreenTimeMs = Math.round(this.fullscreenTotalMs)), this.pipTotalMs > 0 && (r.pipTimeMs = Math.round(this.pipTotalMs)), this.volumeChanges > 0 && (r.volumeChanges = this.volumeChanges), this.muteChanges > 0 && (r.muteChanges = this.muteChanges);
|
|
1580
1609
|
let l = n?.decodedFrames ?? this.lastDecoded;
|
|
1581
1610
|
l > 0 && (r.decodedFramesTotal = l), this.startupTimeMs === 0 && (r.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: r })), this.flush(e === "END_REASON_PAGEHIDE");
|
|
1582
1611
|
}
|
|
@@ -1596,7 +1625,7 @@ var nt = class {
|
|
|
1596
1625
|
};
|
|
1597
1626
|
}
|
|
1598
1627
|
enqueue(e) {
|
|
1599
|
-
for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
1628
|
+
for (this.pending.push(this.wrap(e)); this.pending.length > $e;) {
|
|
1600
1629
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
1601
1630
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
1602
1631
|
}
|
|
@@ -1621,7 +1650,7 @@ var nt = class {
|
|
|
1621
1650
|
};
|
|
1622
1651
|
//#endregion
|
|
1623
1652
|
//#region src/core/environment.ts
|
|
1624
|
-
function
|
|
1653
|
+
function ot() {
|
|
1625
1654
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
1626
1655
|
let e;
|
|
1627
1656
|
try {
|
|
@@ -1646,14 +1675,14 @@ function rt() {
|
|
|
1646
1675
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
1647
1676
|
};
|
|
1648
1677
|
}
|
|
1649
|
-
function
|
|
1678
|
+
function st() {
|
|
1650
1679
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
1651
1680
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
1652
1681
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
1653
1682
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
1654
1683
|
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";
|
|
1655
1684
|
}
|
|
1656
|
-
function
|
|
1685
|
+
function ct() {
|
|
1657
1686
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
1658
1687
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
1659
1688
|
let t = { connectionType: e.type ? {
|
|
@@ -1663,17 +1692,17 @@ function at() {
|
|
|
1663
1692
|
}[e.type] ?? "CONNECTION_TYPE_OTHER" : "CONNECTION_TYPE_UNKNOWN" };
|
|
1664
1693
|
return typeof e.downlink == "number" && e.downlink > 0 && (t.downlinkKbps = Math.round(e.downlink * 1e3)), e.saveData && (t.saveData = !0), t;
|
|
1665
1694
|
}
|
|
1666
|
-
function
|
|
1667
|
-
let t =
|
|
1668
|
-
deviceClass:
|
|
1695
|
+
function lt(e) {
|
|
1696
|
+
let t = ot(), n = {
|
|
1697
|
+
deviceClass: st(),
|
|
1669
1698
|
integration: t.integration,
|
|
1670
|
-
...
|
|
1699
|
+
...ct()
|
|
1671
1700
|
};
|
|
1672
1701
|
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);
|
|
1673
1702
|
let r = e.getBoundingClientRect?.();
|
|
1674
1703
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
1675
1704
|
}
|
|
1676
|
-
async function
|
|
1705
|
+
async function ut() {
|
|
1677
1706
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
1678
1707
|
if (!e?.getHighEntropyValues) return {};
|
|
1679
1708
|
try {
|
|
@@ -1685,7 +1714,7 @@ async function st() {
|
|
|
1685
1714
|
}
|
|
1686
1715
|
//#endregion
|
|
1687
1716
|
//#region src/core/version.ts
|
|
1688
|
-
var
|
|
1717
|
+
var dt = "2.1.2", K = {
|
|
1689
1718
|
accent: "#E1B600",
|
|
1690
1719
|
accentText: "#1B1C23",
|
|
1691
1720
|
background: "#0e0f13",
|
|
@@ -1696,7 +1725,7 @@ var ct = "2.1.0", G = {
|
|
|
1696
1725
|
border: "rgba(255, 255, 255, 0.1)",
|
|
1697
1726
|
radius: "8px",
|
|
1698
1727
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
1699
|
-
},
|
|
1728
|
+
}, q = {
|
|
1700
1729
|
accent: "--havik-accent",
|
|
1701
1730
|
accentText: "--havik-accent-text",
|
|
1702
1731
|
background: "--havik-bg",
|
|
@@ -1708,25 +1737,25 @@ var ct = "2.1.0", G = {
|
|
|
1708
1737
|
radius: "--havik-radius",
|
|
1709
1738
|
fontFamily: "--havik-font"
|
|
1710
1739
|
};
|
|
1711
|
-
function
|
|
1740
|
+
function J(e, t) {
|
|
1712
1741
|
let n = {
|
|
1713
|
-
...
|
|
1742
|
+
...K,
|
|
1714
1743
|
...t
|
|
1715
1744
|
};
|
|
1716
|
-
for (let t of Object.keys(
|
|
1745
|
+
for (let t of Object.keys(q)) e.style.setProperty(q[t], n[t]);
|
|
1717
1746
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
1718
1747
|
}
|
|
1719
1748
|
//#endregion
|
|
1720
1749
|
//#region src/ui/styles.ts
|
|
1721
|
-
var
|
|
1722
|
-
function
|
|
1723
|
-
if (e.getElementById(
|
|
1750
|
+
var Y = "havik-player-styles", ft = "\n.havik-player{position:relative;display:block;width:100%;background:var(--havik-bg,#0e0f13);\n color:var(--havik-text,#fff);font-family:var(--havik-font,system-ui,sans-serif);\n overflow:hidden;line-height:1.4;-webkit-tap-highlight-color:transparent}\n.havik-player video{display:block;width:100%;height:auto;aspect-ratio:16/9;\n object-fit:contain;background:#000;outline:none}\n.havik-player:focus{outline:none}\n.havik-player *{box-sizing:border-box}\n\n.havik-player:fullscreen,.havik-player:-webkit-full-screen{display:flex;align-items:center;\n justify-content:center;width:100vw;height:100vh;aspect-ratio:auto}\n.havik-player:fullscreen video,.havik-player:-webkit-full-screen video{width:100%;height:100%;\n aspect-ratio:auto;object-fit:contain}\n\n.havik-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer}\n.havik-gradient{position:absolute;left:0;right:0;bottom:0;height:120px;pointer-events:none;\n background:linear-gradient(to top,rgba(0,0,0,.78),transparent);\n opacity:1;transition:opacity .25s}\n.havik-player.havik-hide .havik-gradient,\n.havik-player.havik-hide .havik-bar{opacity:0;pointer-events:none}\n.havik-player.havik-hide{cursor:none}\n\n.havik-center{width:74px;height:74px;border-radius:50%;border:0;cursor:pointer;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);\n display:flex;align-items:center;justify-content:center;\n box-shadow:0 6px 24px rgba(0,0,0,.45);transition:transform .15s,opacity .15s}\n.havik-center:hover{transform:scale(1.06)}\n.havik-center svg{width:38px;height:38px;margin-left:2px}\n.havik-center.havik-gone{opacity:0;pointer-events:none;transform:scale(.8)}\n\n.havik-spinner{width:56px;height:56px;border-radius:50%;\n border:4px solid rgba(255,255,255,.2);border-top-color:var(--havik-accent,#E1B600);\n animation:havik-spin .8s linear infinite}\n@keyframes havik-spin{to{transform:rotate(360deg)}}\n\n/* Status card — branded full-bleed overlay for the stopped/pre-play states\n (ended / fatal error / pre-play / armed-waiting). */\n.havik-status{position:absolute;inset:0;display:flex;flex-direction:column;gap:16px;\n align-items:center;justify-content:center;background:rgba(14,15,19,.82);text-align:center;padding:24px}\n.havik-status__logo{width:128px;height:46px;background:var(--havik-logo) center/contain no-repeat;opacity:.95}\n.havik-status__msg{color:var(--havik-text,#fff);font-size:15px;font-weight:600;max-width:480px}\n.havik-status__btn{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;\n padding:10px 18px;border-radius:var(--havik-radius,8px);font-weight:700;font-size:14px;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);transition:transform .15s}\n.havik-status__btn:hover{transform:scale(1.04)}\n.havik-status__btn svg{width:18px;height:18px}\n/* Pre-play: lighter scrim so the poster shows through, and a round play CTA. */\n.havik-status--preplay{background:rgba(14,15,19,.4)}\n.havik-status--preplay .havik-status__btn--play{width:74px;height:74px;border-radius:50%;padding:0;\n justify-content:center;box-shadow:0 6px 24px rgba(0,0,0,.45)}\n.havik-status--preplay .havik-status__btn--play svg{width:38px;height:38px;margin-left:3px}\n\n.havik-watermark{position:absolute;top:12px;right:14px;height:22px;opacity:.85;pointer-events:none;\n content:'';background:var(--havik-logo) center/contain no-repeat;width:90px}\n/* A status card carries its own logo — the corner watermark would duplicate it. */\n.havik-player.havik-has-status .havik-watermark{display:none}\n\n.havik-bar{position:absolute;left:0;right:0;bottom:0;padding:0 12px 8px;\n opacity:1;transition:opacity .25s;z-index:2}\n.havik-seek{position:relative;height:16px;display:flex;align-items:center;cursor:pointer;margin-bottom:2px}\n.havik-seek__track{position:relative;width:100%;height:4px;border-radius:3px;background:rgba(255,255,255,.25)}\n.havik-seek__buffered{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:rgba(255,255,255,.4)}\n.havik-seek__played{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-seek__thumb{position:absolute;top:50%;width:13px;height:13px;border-radius:50%;\n background:var(--havik-accent,#E1B600);transform:translate(-50%,-50%) scale(0);transition:transform .1s}\n.havik-seek:hover .havik-seek__thumb{transform:translate(-50%,-50%) scale(1)}\n\n.havik-controls{display:flex;align-items:center;gap:6px;height:40px}\n.havik-spacer{flex:1}\n.havik-btn{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;border-radius:var(--havik-radius,8px);\n padding:0;transition:background .12s,color .12s}\n.havik-btn:hover{background:rgba(255,255,255,.12)}\n.havik-btn:focus-visible{outline:2px solid var(--havik-accent,#E1B600);outline-offset:1px}\n.havik-btn svg{width:22px;height:22px}\n\n/* The volume level is filled in accent up to the thumb, like the seek bar's\n played span — a native range input paints no \"elapsed\" side, which left the\n level readable only from the dot's position. --havik-vol (0..1) is set by\n syncVolume(); the track width and thumb size live here as variables because\n the WebKit fill has to compute the thumb centre from both. */\n.havik-vol{display:flex;align-items:center}\n.havik-vol__slider{--havik-vol-w:70px;--havik-vol-thumb:12px;--havik-vol:1;\n --havik-vol-pos:calc(var(--havik-vol-thumb) / 2 + var(--havik-vol) * (var(--havik-vol-w) - var(--havik-vol-thumb)));\n width:0;opacity:0;transition:width .18s,opacity .18s;height:4px;cursor:pointer;\n appearance:none;-webkit-appearance:none;background:transparent;border-radius:3px;margin:0 4px}\n.havik-vol:hover .havik-vol__slider,.havik-vol:focus-within .havik-vol__slider{width:var(--havik-vol-w);opacity:1}\n/* WebKit/Blink have no progress pseudo-element: paint the fill as a hard-stop\n gradient that ends at the thumb centre. */\n.havik-vol__slider::-webkit-slider-runnable-track{height:4px;border-radius:3px;\n background:linear-gradient(to right,var(--havik-accent,#E1B600) var(--havik-vol-pos),\n rgba(255,255,255,.3) var(--havik-vol-pos))}\n/* Firefox fills natively, and tracks the thumb exactly. */\n.havik-vol__slider::-moz-range-track{height:4px;border-radius:3px;background:rgba(255,255,255,.3)}\n.havik-vol__slider::-moz-range-progress{height:4px;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-vol__slider::-webkit-slider-thumb{-webkit-appearance:none;width:var(--havik-vol-thumb);\n height:var(--havik-vol-thumb);border-radius:50%;background:var(--havik-accent,#E1B600);\n margin-top:calc((4px - var(--havik-vol-thumb)) / 2)}\n.havik-vol__slider::-moz-range-thumb{width:var(--havik-vol-thumb);height:var(--havik-vol-thumb);\n border:0;border-radius:50%;background:var(--havik-accent,#E1B600)}\n\n.havik-time{font-size:12px;color:var(--havik-text-muted,#9aa0ad);\n font-variant-numeric:tabular-nums;padding:0 6px;white-space:nowrap}\n.havik-live{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;\n letter-spacing:.4px;padding:0 8px;color:var(--havik-text,#fff)}\n.havik-live svg{width:9px;height:9px;color:var(--havik-text-muted,#9aa0ad)}\n.havik-live.is-live svg{color:var(--havik-accent,#E1B600)}\n.havik-live__go{margin-left:2px;border:0;cursor:pointer;background:transparent;color:var(--havik-text-muted,#9aa0ad);\n font:inherit;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 6px;border-radius:6px}\n.havik-live.is-live .havik-live__go{display:none}\n.havik-live__go:hover{color:var(--havik-accent,#E1B600)}\n\n.havik-menu{position:absolute;bottom:54px;right:12px;min-width:170px;max-height:230px;overflow:auto;\n background:var(--havik-surface,#1B1C23);border:1px solid var(--havik-border,rgba(255,255,255,.1));\n border-radius:var(--havik-radius,8px);box-shadow:0 10px 30px rgba(0,0,0,.5);padding:6px;z-index:3}\n.havik-menu[hidden]{display:none}\n.havik-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;\n color:var(--havik-text-muted,#9aa0ad);padding:6px 8px 4px}\n.havik-menu__item{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;font:inherit;font-size:13px;\n text-align:left;padding:7px 8px;border-radius:6px}\n.havik-menu__item:hover{background:var(--havik-surface-muted,#2a2c36)}\n.havik-menu__item[aria-checked=\"true\"]{color:var(--havik-accent,#E1B600);font-weight:600}\n.havik-menu__item[aria-checked=\"true\"]::after{content:'✓'}\n";
|
|
1751
|
+
function pt(e = document) {
|
|
1752
|
+
if (e.getElementById(Y)) return;
|
|
1724
1753
|
let t = e.createElement("style");
|
|
1725
|
-
t.id =
|
|
1754
|
+
t.id = Y, t.textContent = ft, e.head.appendChild(t);
|
|
1726
1755
|
}
|
|
1727
1756
|
//#endregion
|
|
1728
1757
|
//#region src/ui/icons.ts
|
|
1729
|
-
var
|
|
1758
|
+
var mt = {
|
|
1730
1759
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
1731
1760
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
1732
1761
|
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\"/>",
|
|
@@ -1739,21 +1768,21 @@ var dt = {
|
|
|
1739
1768
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
1740
1769
|
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\"/>"
|
|
1741
1770
|
};
|
|
1742
|
-
function
|
|
1743
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
1771
|
+
function X(e) {
|
|
1772
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${mt[e]}</svg>`;
|
|
1744
1773
|
}
|
|
1745
1774
|
//#endregion
|
|
1746
1775
|
//#region src/ui/controls.ts
|
|
1747
|
-
var
|
|
1776
|
+
var ht = 3e3, gt = /* @__PURE__ */ new Set([
|
|
1748
1777
|
"GONE",
|
|
1749
1778
|
"NOT_FOUND",
|
|
1750
1779
|
"INVALID_URN",
|
|
1751
1780
|
"UNAUTHORIZED"
|
|
1752
1781
|
]);
|
|
1753
|
-
function
|
|
1754
|
-
return new
|
|
1782
|
+
function _t(e) {
|
|
1783
|
+
return new vt(e);
|
|
1755
1784
|
}
|
|
1756
|
-
var
|
|
1785
|
+
var vt = class {
|
|
1757
1786
|
root;
|
|
1758
1787
|
video;
|
|
1759
1788
|
player;
|
|
@@ -1795,7 +1824,7 @@ var ht = class {
|
|
|
1795
1824
|
scrubbing = !1;
|
|
1796
1825
|
offFns = [];
|
|
1797
1826
|
constructor(e) {
|
|
1798
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
1827
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? ht, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, pt(this.doc), this.root.classList.add("havik-player"), this.root.hasAttribute("tabindex") || (this.root.tabIndex = 0), this.root.setAttribute("role", "region"), this.root.setAttribute("aria-label", "Video player");
|
|
1799
1828
|
let t = (e, t, n) => {
|
|
1800
1829
|
let r = this.doc.createElement(e);
|
|
1801
1830
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -1806,12 +1835,12 @@ var ht = class {
|
|
|
1806
1835
|
"aria-label": r,
|
|
1807
1836
|
title: r
|
|
1808
1837
|
});
|
|
1809
|
-
return i.innerHTML =
|
|
1838
|
+
return i.innerHTML = X(n), i;
|
|
1810
1839
|
};
|
|
1811
1840
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
1812
1841
|
type: "button",
|
|
1813
1842
|
"aria-label": "Play"
|
|
1814
|
-
}), this.center.innerHTML =
|
|
1843
|
+
}), this.center.innerHTML = X("play"), this.spinner = t("div", "havik-spinner"), this.spinner.style.display = "none", this.overlay.append(this.center, this.spinner), this.gradient = t("div", "havik-gradient"), this.bar = t("div", "havik-bar"), this.seek = t("div", "havik-seek", {
|
|
1815
1844
|
role: "slider",
|
|
1816
1845
|
"aria-label": "Seek",
|
|
1817
1846
|
"aria-valuemin": "0",
|
|
@@ -1829,7 +1858,7 @@ var ht = class {
|
|
|
1829
1858
|
"aria-label": "Volume"
|
|
1830
1859
|
});
|
|
1831
1860
|
let a = t("div", "havik-vol");
|
|
1832
|
-
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML =
|
|
1861
|
+
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = X("liveDot");
|
|
1833
1862
|
let o = this.doc.createElement("span");
|
|
1834
1863
|
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";
|
|
1835
1864
|
let s = t("div", "havik-spacer");
|
|
@@ -1883,12 +1912,12 @@ var ht = class {
|
|
|
1883
1912
|
}
|
|
1884
1913
|
if (e === "preplay") {
|
|
1885
1914
|
let e = this.doc.createElement("button");
|
|
1886
|
-
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML =
|
|
1915
|
+
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = X("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
|
|
1887
1916
|
} else {
|
|
1888
1917
|
let r = this.doc.createElement("div");
|
|
1889
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
1918
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !gt.has(this.lastError.code)) {
|
|
1890
1919
|
let e = this.doc.createElement("button");
|
|
1891
|
-
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${
|
|
1920
|
+
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${X("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
|
|
1892
1921
|
}
|
|
1893
1922
|
}
|
|
1894
1923
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -1927,7 +1956,7 @@ var ht = class {
|
|
|
1927
1956
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
1928
1957
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
1929
1958
|
}
|
|
1930
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
1959
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Z(this.video.currentTime)} / ${Z(this.video.duration)}`);
|
|
1931
1960
|
}
|
|
1932
1961
|
syncLive() {
|
|
1933
1962
|
let e = this.player.getStats(), t = e.isLive !== !1;
|
|
@@ -1977,17 +2006,17 @@ var ht = class {
|
|
|
1977
2006
|
renderQualityMenu() {
|
|
1978
2007
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
1979
2008
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
1980
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
2009
|
+
for (let n of e) this.menu.append(this.menuItem(yt(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
1981
2010
|
}
|
|
1982
2011
|
renderAudioMenu() {
|
|
1983
2012
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
1984
2013
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
1985
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2014
|
+
for (let t of e) this.menu.append(this.menuItem(bt(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
1986
2015
|
}
|
|
1987
2016
|
renderCcMenu() {
|
|
1988
2017
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
1989
2018
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
1990
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2019
|
+
for (let t of e) this.menu.append(this.menuItem(xt(t), !1, () => this.player.setTextTrack(t.id)));
|
|
1991
2020
|
}
|
|
1992
2021
|
onTracksChanged() {
|
|
1993
2022
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -2007,11 +2036,11 @@ var ht = class {
|
|
|
2007
2036
|
}
|
|
2008
2037
|
async toggleFullscreen() {
|
|
2009
2038
|
try {
|
|
2010
|
-
|
|
2039
|
+
C(this.video, this.root) ? await T(this.video, this.root) : await w(this.video, this.root);
|
|
2011
2040
|
} catch {}
|
|
2012
2041
|
}
|
|
2013
2042
|
syncFullscreen() {
|
|
2014
|
-
let e =
|
|
2043
|
+
let e = C(this.video, this.root);
|
|
2015
2044
|
this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
|
|
2016
2045
|
}
|
|
2017
2046
|
poke() {
|
|
@@ -2070,7 +2099,7 @@ var ht = class {
|
|
|
2070
2099
|
}
|
|
2071
2100
|
}
|
|
2072
2101
|
setIcon(e, t) {
|
|
2073
|
-
e.innerHTML =
|
|
2102
|
+
e.innerHTML = X(t);
|
|
2074
2103
|
}
|
|
2075
2104
|
destroy() {
|
|
2076
2105
|
this.hideTimer && clearTimeout(this.hideTimer);
|
|
@@ -2087,32 +2116,32 @@ var ht = class {
|
|
|
2087
2116
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
2088
2117
|
}
|
|
2089
2118
|
};
|
|
2090
|
-
function
|
|
2119
|
+
function Z(e) {
|
|
2091
2120
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
2092
2121
|
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");
|
|
2093
2122
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
2094
2123
|
}
|
|
2095
|
-
function
|
|
2124
|
+
function yt(e) {
|
|
2096
2125
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
2097
2126
|
}
|
|
2098
|
-
function
|
|
2127
|
+
function bt(e) {
|
|
2099
2128
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2100
2129
|
}
|
|
2101
|
-
function
|
|
2130
|
+
function xt(e) {
|
|
2102
2131
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2103
2132
|
}
|
|
2104
2133
|
//#endregion
|
|
2105
2134
|
//#region src/managed/index.ts
|
|
2106
|
-
var
|
|
2107
|
-
async function
|
|
2135
|
+
var St = 6e3, Q = 45e3, Ct = 2e3, wt = 3, Tt = 2e3, Et = 48e4;
|
|
2136
|
+
async function Dt(e) {
|
|
2108
2137
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
2109
2138
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: baseUrl is required");
|
|
2110
2139
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
2111
2140
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
2112
|
-
let t = new
|
|
2141
|
+
let t = new Ot(e);
|
|
2113
2142
|
return await t.start(), t;
|
|
2114
2143
|
}
|
|
2115
|
-
var
|
|
2144
|
+
var Ot = class {
|
|
2116
2145
|
opts;
|
|
2117
2146
|
abort = new AbortController();
|
|
2118
2147
|
listeners = {};
|
|
@@ -2178,7 +2207,7 @@ var wt = class {
|
|
|
2178
2207
|
};
|
|
2179
2208
|
}
|
|
2180
2209
|
beginArming(e, t, n = !1) {
|
|
2181
|
-
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ??
|
|
2210
|
+
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
|
|
2182
2211
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
2183
2212
|
}
|
|
2184
2213
|
beginArmingByPolling(e) {
|
|
@@ -2199,7 +2228,7 @@ var wt = class {
|
|
|
2199
2228
|
setTimeout(() => {
|
|
2200
2229
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
2201
2230
|
phase: i ? "unavailable" : "tooEarly",
|
|
2202
|
-
retryInMs:
|
|
2231
|
+
retryInMs: Q,
|
|
2203
2232
|
attempt: 1,
|
|
2204
2233
|
elapsedMs: 0,
|
|
2205
2234
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -2238,13 +2267,13 @@ var wt = class {
|
|
|
2238
2267
|
!a && !p() && h();
|
|
2239
2268
|
}, e);
|
|
2240
2269
|
};
|
|
2241
|
-
_(
|
|
2270
|
+
_(St), this.armingSub = E({
|
|
2242
2271
|
eventsBaseUrl: t,
|
|
2243
2272
|
matchUrn: this.opts.matchUrn,
|
|
2244
2273
|
credential: this.opts.credential,
|
|
2245
|
-
onAlive: () => _(
|
|
2274
|
+
onAlive: () => _(Q),
|
|
2246
2275
|
onState: (e) => {
|
|
2247
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
2276
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Ct);
|
|
2248
2277
|
},
|
|
2249
2278
|
onError: () => h()
|
|
2250
2279
|
});
|
|
@@ -2267,7 +2296,7 @@ var wt = class {
|
|
|
2267
2296
|
let n = await s(this.opts.credential);
|
|
2268
2297
|
if (this.destroyed || t !== this.loadGen) return;
|
|
2269
2298
|
this.setState("loading");
|
|
2270
|
-
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a =
|
|
2299
|
+
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = Oe(this.opts.video, (e) => {
|
|
2271
2300
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
2272
2301
|
});
|
|
2273
2302
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -2286,17 +2315,17 @@ var wt = class {
|
|
|
2286
2315
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
2287
2316
|
let r = e.analytics?.sid;
|
|
2288
2317
|
if (!r) return;
|
|
2289
|
-
let i = (typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0) ??
|
|
2318
|
+
let i = (typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0) ?? it(this.opts.baseUrl);
|
|
2290
2319
|
if (!i) return;
|
|
2291
|
-
let a = this.opts.video, o = new
|
|
2320
|
+
let a = this.opts.video, o = new at({
|
|
2292
2321
|
endpoint: i,
|
|
2293
2322
|
sid: r,
|
|
2294
2323
|
apiKey: n,
|
|
2295
2324
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
2296
|
-
sdkVersion:
|
|
2297
|
-
environment:
|
|
2325
|
+
sdkVersion: dt,
|
|
2326
|
+
environment: lt(a),
|
|
2298
2327
|
sample: () => {
|
|
2299
|
-
let e = this.engine?.getStats() ??
|
|
2328
|
+
let e = this.engine?.getStats() ?? F, t = a.buffered.length ? Math.max(0, a.buffered.end(a.buffered.length - 1) - a.currentTime) : 0;
|
|
2300
2329
|
return {
|
|
2301
2330
|
...e,
|
|
2302
2331
|
bufferedMs: Math.round(t * 1e3),
|
|
@@ -2310,7 +2339,7 @@ var wt = class {
|
|
|
2310
2339
|
let s = () => o.noteSeek(), c = () => o.noteVolume(a.muted, a.volume);
|
|
2311
2340
|
a.addEventListener("seeking", s), a.addEventListener("volumechange", c), this.detachMediaListeners = () => {
|
|
2312
2341
|
a.removeEventListener("seeking", s), a.removeEventListener("volumechange", c);
|
|
2313
|
-
}, o.start(), o.seedVolume(a.muted, a.volume), o.notePresentation(this.currentPresentation()),
|
|
2342
|
+
}, o.start(), o.seedVolume(a.muted, a.volume), o.notePresentation(this.currentPresentation()), ut().then((e) => o.noteEnvironment(e)), this.opts.autoplay === !1 && o.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
2314
2343
|
}
|
|
2315
2344
|
currentPresentation() {
|
|
2316
2345
|
let e = this.opts.video;
|
|
@@ -2325,7 +2354,7 @@ var wt = class {
|
|
|
2325
2354
|
video: this.opts.video,
|
|
2326
2355
|
descriptor: e,
|
|
2327
2356
|
credential: t,
|
|
2328
|
-
deviceId:
|
|
2357
|
+
deviceId: A(),
|
|
2329
2358
|
userId: this.opts.userId,
|
|
2330
2359
|
lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
|
|
2331
2360
|
snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
|
|
@@ -2334,11 +2363,11 @@ var wt = class {
|
|
|
2334
2363
|
hlsConfig: i,
|
|
2335
2364
|
emit: (e) => this.onEngineEvent(e)
|
|
2336
2365
|
}, o = this.opts.engine ?? "auto";
|
|
2337
|
-
if (o === "native") return new
|
|
2338
|
-
if (o === "hls") return new
|
|
2339
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl &&
|
|
2340
|
-
if (
|
|
2341
|
-
if (
|
|
2366
|
+
if (o === "native") return new z(a);
|
|
2367
|
+
if (o === "hls") return new V(a);
|
|
2368
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && L(this.opts.video) && R()) return new z(a);
|
|
2369
|
+
if (je()) return new V(a);
|
|
2370
|
+
if (L(this.opts.video)) return new z(a);
|
|
2342
2371
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
2343
2372
|
}
|
|
2344
2373
|
onEngineEvent(e) {
|
|
@@ -2366,11 +2395,11 @@ var wt = class {
|
|
|
2366
2395
|
}
|
|
2367
2396
|
startLiveState(e) {
|
|
2368
2397
|
if (this.opts.liveStateEvents === !1) return;
|
|
2369
|
-
let t = this.opts.eventsBaseUrl ??
|
|
2398
|
+
let t = this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
|
|
2370
2399
|
if (!t) return;
|
|
2371
2400
|
this.closeLiveState();
|
|
2372
2401
|
let r = 0, i = !1;
|
|
2373
|
-
this.liveStateSub =
|
|
2402
|
+
this.liveStateSub = E({
|
|
2374
2403
|
eventsBaseUrl: t,
|
|
2375
2404
|
matchUrn: this.opts.matchUrn,
|
|
2376
2405
|
credential: this.opts.credential,
|
|
@@ -2381,7 +2410,7 @@ var wt = class {
|
|
|
2381
2410
|
r = 0, i = !1;
|
|
2382
2411
|
},
|
|
2383
2412
|
onError: () => {
|
|
2384
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
2413
|
+
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= wt && (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.`))));
|
|
2385
2414
|
}
|
|
2386
2415
|
});
|
|
2387
2416
|
}
|
|
@@ -2403,7 +2432,7 @@ var wt = class {
|
|
|
2403
2432
|
scheduleRejoin(e) {
|
|
2404
2433
|
!this.rejoinEnabled() || this.rejoinTimer || (this.rejoinTimer = setTimeout(() => {
|
|
2405
2434
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
2406
|
-
}, Math.random() *
|
|
2435
|
+
}, Math.random() * Ct));
|
|
2407
2436
|
}
|
|
2408
2437
|
cancelRejoin() {
|
|
2409
2438
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -2427,7 +2456,7 @@ var wt = class {
|
|
|
2427
2456
|
}
|
|
2428
2457
|
t.controls = !1;
|
|
2429
2458
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
2430
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
2459
|
+
r && r.insertBefore(n, t), n.appendChild(t), J(n, this.opts.theme), this.container = n, this.controlBar = _t({
|
|
2431
2460
|
root: n,
|
|
2432
2461
|
video: t,
|
|
2433
2462
|
player: this,
|
|
@@ -2457,7 +2486,7 @@ var wt = class {
|
|
|
2457
2486
|
}
|
|
2458
2487
|
startStats() {
|
|
2459
2488
|
this.stopStats();
|
|
2460
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
2489
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Tt);
|
|
2461
2490
|
this.statsTimer = setInterval(() => {
|
|
2462
2491
|
if (!this.engine) return;
|
|
2463
2492
|
let e = this.engine.getStats();
|
|
@@ -2469,7 +2498,7 @@ var wt = class {
|
|
|
2469
2498
|
}
|
|
2470
2499
|
scheduleLicenseRefresh() {
|
|
2471
2500
|
this.stopRefresh();
|
|
2472
|
-
let e = this.opts.licenseRefreshMs ??
|
|
2501
|
+
let e = this.opts.licenseRefreshMs ?? Et;
|
|
2473
2502
|
!e || !this._descriptor?.drmEnabled || (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
2474
2503
|
}
|
|
2475
2504
|
stopRefresh() {
|
|
@@ -2511,7 +2540,7 @@ var wt = class {
|
|
|
2511
2540
|
this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
|
|
2512
2541
|
}
|
|
2513
2542
|
getStats() {
|
|
2514
|
-
return this.engine?.getStats() ??
|
|
2543
|
+
return this.engine?.getStats() ?? F;
|
|
2515
2544
|
}
|
|
2516
2545
|
getQualityLevels() {
|
|
2517
2546
|
return this.engine?.getQualityLevels() ?? [];
|
|
@@ -2550,10 +2579,10 @@ var wt = class {
|
|
|
2550
2579
|
e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
|
|
2551
2580
|
}
|
|
2552
2581
|
async enterFullscreen() {
|
|
2553
|
-
return !this.destroyed &&
|
|
2582
|
+
return !this.destroyed && w(this.opts.video, this.container ?? void 0);
|
|
2554
2583
|
}
|
|
2555
2584
|
async exitFullscreen() {
|
|
2556
|
-
await
|
|
2585
|
+
await T(this.opts.video, this.container ?? void 0);
|
|
2557
2586
|
}
|
|
2558
2587
|
retry() {
|
|
2559
2588
|
return this.reload();
|
|
@@ -2621,7 +2650,7 @@ function $(e) {
|
|
|
2621
2650
|
}
|
|
2622
2651
|
//#endregion
|
|
2623
2652
|
//#region src/embed/host.ts
|
|
2624
|
-
function
|
|
2653
|
+
function kt(e) {
|
|
2625
2654
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
2626
2655
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
2627
2656
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -2680,8 +2709,8 @@ function Tt(e) {
|
|
|
2680
2709
|
}
|
|
2681
2710
|
//#endregion
|
|
2682
2711
|
//#region src/embed/page.ts
|
|
2683
|
-
var
|
|
2684
|
-
function
|
|
2712
|
+
var At = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
2713
|
+
function jt() {
|
|
2685
2714
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
2686
2715
|
if (e) return {
|
|
2687
2716
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -2703,9 +2732,9 @@ function Dt() {
|
|
|
2703
2732
|
waitForLive: !0
|
|
2704
2733
|
};
|
|
2705
2734
|
}
|
|
2706
|
-
async function
|
|
2707
|
-
let e =
|
|
2708
|
-
|
|
2735
|
+
async function Mt() {
|
|
2736
|
+
let e = jt();
|
|
2737
|
+
Pt();
|
|
2709
2738
|
let t = document.createElement("video");
|
|
2710
2739
|
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);
|
|
2711
2740
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -2760,12 +2789,12 @@ async function Ot() {
|
|
|
2760
2789
|
code: e.code,
|
|
2761
2790
|
message: e.message
|
|
2762
2791
|
})), e.on("autoplayblocked", () => {
|
|
2763
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
2792
|
+
i({ type: "oddin:autoplayblocked" }), Nt(t, e);
|
|
2764
2793
|
});
|
|
2765
2794
|
}, s = async (r) => {
|
|
2766
2795
|
a?.destroy(), a = null;
|
|
2767
2796
|
try {
|
|
2768
|
-
let n = await
|
|
2797
|
+
let n = await Dt({
|
|
2769
2798
|
video: t,
|
|
2770
2799
|
baseUrl: e.baseUrl,
|
|
2771
2800
|
matchUrn: r,
|
|
@@ -2826,7 +2855,7 @@ async function Ot() {
|
|
|
2826
2855
|
a?.retry();
|
|
2827
2856
|
break;
|
|
2828
2857
|
case "oddin:load":
|
|
2829
|
-
typeof e.matchUrn == "string" &&
|
|
2858
|
+
typeof e.matchUrn == "string" && At.test(e.matchUrn) && s(e.matchUrn);
|
|
2830
2859
|
break;
|
|
2831
2860
|
case "oddin:destroy": c();
|
|
2832
2861
|
}
|
|
@@ -2838,18 +2867,18 @@ async function Ot() {
|
|
|
2838
2867
|
protocol: 1
|
|
2839
2868
|
});
|
|
2840
2869
|
}
|
|
2841
|
-
function
|
|
2870
|
+
function Nt(e, t) {
|
|
2842
2871
|
if (document.getElementById("havik-tap")) return;
|
|
2843
2872
|
let n = document.createElement("button");
|
|
2844
2873
|
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", () => {
|
|
2845
2874
|
n.remove(), t.play();
|
|
2846
2875
|
}), document.body.appendChild(n);
|
|
2847
2876
|
}
|
|
2848
|
-
function
|
|
2877
|
+
function Pt() {
|
|
2849
2878
|
let e = document.createElement("style");
|
|
2850
2879
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
2851
2880
|
}
|
|
2852
2881
|
//#endregion
|
|
2853
|
-
export {
|
|
2882
|
+
export { K as ODDIN_THEME, n as PlaybackError, J as applyTheme, Mt as bootEmbed, ge as clearDeviceId, Dt as createPlayer, D as deriveEventsBaseUrl, Se as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ue as fetchCatalog, fe as fetchTournament, me as flattenMatches, A as getDeviceId, we as isLowLatencyManifest, $ as isOddinMessage, ve as licenseRequestHeaders, kt as mountEmbed, v as pollToLive, b as resolveStream, E as subscribeLiveState, C as videoFullscreenActive, he as watchStatus };
|
|
2854
2883
|
|
|
2855
2884
|
//# sourceMappingURL=index.js.map
|