@oddin-gg/havik-player 2.0.4 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +28 -2
- package/dist/index.d.ts +28 -2
- package/dist/index.js +488 -203
- package/dist/index.js.map +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,17 +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
642
|
var F = { droppedFrames: 0 };
|
|
620
643
|
function I(e) {
|
|
621
|
-
|
|
644
|
+
let t = e.getVideoPlaybackQuality?.();
|
|
645
|
+
return {
|
|
646
|
+
dropped: t?.droppedVideoFrames ?? 0,
|
|
647
|
+
decoded: t?.totalVideoFrames ?? 0
|
|
648
|
+
};
|
|
622
649
|
}
|
|
623
|
-
function
|
|
650
|
+
function Oe(e, t) {
|
|
624
651
|
let n = [
|
|
625
652
|
["playing", () => t("playing")],
|
|
626
653
|
["waiting", () => t("buffering")],
|
|
@@ -637,7 +664,7 @@ function we(e, t) {
|
|
|
637
664
|
}
|
|
638
665
|
//#endregion
|
|
639
666
|
//#region src/core/engine/native.ts
|
|
640
|
-
function
|
|
667
|
+
function ke(e) {
|
|
641
668
|
try {
|
|
642
669
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
643
670
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -687,7 +714,7 @@ var z = class {
|
|
|
687
714
|
type: "error",
|
|
688
715
|
error: new n("INTERNAL", 0, "native HLS playback error"),
|
|
689
716
|
fatal: !0
|
|
690
|
-
}), 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();
|
|
691
718
|
}
|
|
692
719
|
startLoad() {
|
|
693
720
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -709,7 +736,7 @@ var z = class {
|
|
|
709
736
|
});
|
|
710
737
|
this.onEncrypted = (n) => {
|
|
711
738
|
let i = n;
|
|
712
|
-
!i.initData || this.fairplayArmed || (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
739
|
+
!i.initData || this.fairplayArmed || (this.fairplayArmed = !0, this.fairplayKeyIV = ke(i.initData), (async () => {
|
|
713
740
|
try {
|
|
714
741
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
715
742
|
initDataTypes: [i.initDataType],
|
|
@@ -804,8 +831,11 @@ var z = class {
|
|
|
804
831
|
e.seekable.length > 0 && (e.currentTime = e.seekable.end(e.seekable.length - 1));
|
|
805
832
|
}
|
|
806
833
|
getStats() {
|
|
807
|
-
let e = this.deps.video, t =
|
|
808
|
-
|
|
834
|
+
let e = this.deps.video, t = I(e), n = {
|
|
835
|
+
droppedFrames: t.dropped,
|
|
836
|
+
decodedFrames: t.decoded
|
|
837
|
+
};
|
|
838
|
+
return this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity && (n.isLive = !0, e.seekable.length > 0 && (n.atLiveEdge = e.currentTime >= e.seekable.end(e.seekable.length - 1) - 2)), n;
|
|
809
839
|
}
|
|
810
840
|
stop() {
|
|
811
841
|
try {
|
|
@@ -824,25 +854,32 @@ var z = class {
|
|
|
824
854
|
} catch {}
|
|
825
855
|
}
|
|
826
856
|
};
|
|
827
|
-
function
|
|
857
|
+
function Ae(e, t) {
|
|
828
858
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
829
859
|
}
|
|
830
860
|
//#endregion
|
|
831
861
|
//#region src/core/engine/hls.ts
|
|
832
|
-
function
|
|
862
|
+
function je() {
|
|
833
863
|
return e.isSupported();
|
|
834
864
|
}
|
|
835
|
-
var
|
|
836
|
-
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) {
|
|
867
|
+
try {
|
|
868
|
+
return new URL(e).host;
|
|
869
|
+
} catch {
|
|
870
|
+
return "";
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
function Xe(e) {
|
|
837
874
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
838
875
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
839
876
|
return;
|
|
840
877
|
}
|
|
841
|
-
e.liveSyncDuration ??=
|
|
842
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
843
|
-
(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);
|
|
844
881
|
}
|
|
845
|
-
function
|
|
882
|
+
function Ze(e, t) {
|
|
846
883
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
847
884
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
848
885
|
}
|
|
@@ -856,6 +893,16 @@ var V = class {
|
|
|
856
893
|
playlistBytesLoaded = 0;
|
|
857
894
|
renditionSwitches = 0;
|
|
858
895
|
licenseTimeMs = 0;
|
|
896
|
+
licenseRequested = !1;
|
|
897
|
+
upshifts = 0;
|
|
898
|
+
downshifts = 0;
|
|
899
|
+
lastLevelIndex = -1;
|
|
900
|
+
requestCount = 0;
|
|
901
|
+
requestErrors = 0;
|
|
902
|
+
requestTimesMs = [];
|
|
903
|
+
cdnHost = "";
|
|
904
|
+
ladderHeights;
|
|
905
|
+
ladderTopBitrateKbps = 0;
|
|
859
906
|
mediaRecoveries = 0;
|
|
860
907
|
networkRecoveries = 0;
|
|
861
908
|
licenseRecoveries = 0;
|
|
@@ -930,7 +977,7 @@ var V = class {
|
|
|
930
977
|
let t = e.liveSyncPosition;
|
|
931
978
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
932
979
|
let { video: n } = this.deps;
|
|
933
|
-
n.currentTime <= t +
|
|
980
|
+
n.currentTime <= t + qe || (n.currentTime = t);
|
|
934
981
|
}
|
|
935
982
|
startHls() {
|
|
936
983
|
let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
|
|
@@ -954,8 +1001,9 @@ var V = class {
|
|
|
954
1001
|
videoEncryptionScheme: "cbcs",
|
|
955
1002
|
audioEncryptionScheme: "cbcs"
|
|
956
1003
|
},
|
|
1004
|
+
...P() ? { requestMediaKeySystemAccessFunc: De(t) } : {},
|
|
957
1005
|
licenseXhrSetup: (e, t) => {
|
|
958
|
-
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);
|
|
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;
|
|
959
1007
|
let o = performance.now();
|
|
960
1008
|
e.addEventListener("loadend", () => {
|
|
961
1009
|
this.licenseTimeMs = Math.max(1, Math.round(performance.now() - o));
|
|
@@ -969,19 +1017,28 @@ var V = class {
|
|
|
969
1017
|
} } : {},
|
|
970
1018
|
...c
|
|
971
1019
|
};
|
|
972
|
-
|
|
1020
|
+
Xe(d), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.loadStarted = d.autoStartLoad !== !1;
|
|
973
1021
|
let f = new e(d);
|
|
974
1022
|
this.hls = f, f.on(e.Events.MANIFEST_PARSED, () => {
|
|
975
|
-
this.mediaRecoveries = 0, this.networkRecoveries = 0
|
|
1023
|
+
this.mediaRecoveries = 0, this.networkRecoveries = 0;
|
|
1024
|
+
let e = f.levels.map((e) => e.height).filter((e) => !!e);
|
|
1025
|
+
this.ladderHeights = e.length ? [...new Set(e)].sort((e, t) => e - t) : void 0, this.ladderTopBitrateKbps = f.levels.length ? Math.round(Math.max(...f.levels.map((e) => e.bitrate)) / 1e3) : 0, this.applySizeCap(), l({ type: "ready" });
|
|
976
1026
|
}), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
977
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(() => {
|
|
978
1028
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
979
|
-
},
|
|
1029
|
+
}, Fe)));
|
|
980
1030
|
}), f.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
981
1031
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
982
1032
|
}), f.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
983
|
-
let n = t?.frag?.stats?.loaded;
|
|
984
|
-
typeof
|
|
1033
|
+
let n = t?.frag?.stats, r = n?.loaded;
|
|
1034
|
+
typeof r == "number" && (this.bytesLoaded += r);
|
|
1035
|
+
let i = n?.loading;
|
|
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());
|
|
1037
|
+
let a = t?.frag?.url;
|
|
1038
|
+
if (a) {
|
|
1039
|
+
let e = Ye(a);
|
|
1040
|
+
e && (this.cdnHost = e);
|
|
1041
|
+
}
|
|
985
1042
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
986
1043
|
let n = t?.stats?.loaded;
|
|
987
1044
|
if (typeof n == "number" && (this.playlistBytesLoaded += n), this.detectedLowLatency) return;
|
|
@@ -992,8 +1049,10 @@ var V = class {
|
|
|
992
1049
|
}));
|
|
993
1050
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
994
1051
|
this.checkEndStale(), this.checkStarvation();
|
|
995
|
-
},
|
|
996
|
-
this.renditionSwitches += 1
|
|
1052
|
+
}, Le), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1053
|
+
this.renditionSwitches += 1;
|
|
1054
|
+
let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
|
|
1055
|
+
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
|
|
997
1056
|
type: "qualitychange",
|
|
998
1057
|
index: t.level
|
|
999
1058
|
});
|
|
@@ -1054,7 +1113,7 @@ var V = class {
|
|
|
1054
1113
|
return;
|
|
1055
1114
|
}
|
|
1056
1115
|
this.capTimer && clearTimeout(this.capTimer);
|
|
1057
|
-
let t = e > this.sizeCapLevel ?
|
|
1116
|
+
let t = e > this.sizeCapLevel ? Ue : We;
|
|
1058
1117
|
this.capTimer = setTimeout(() => {
|
|
1059
1118
|
this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
|
|
1060
1119
|
}, t);
|
|
@@ -1101,20 +1160,28 @@ var V = class {
|
|
|
1101
1160
|
e.widevine && (this.licenseUrl = e.widevine);
|
|
1102
1161
|
}
|
|
1103
1162
|
getStats() {
|
|
1104
|
-
let e = this.hls, t = {
|
|
1105
|
-
droppedFrames:
|
|
1163
|
+
let e = this.hls, t = I(this.deps.video), n = {
|
|
1164
|
+
droppedFrames: t.dropped,
|
|
1165
|
+
decodedFrames: t.decoded,
|
|
1106
1166
|
lowLatency: this.detectedLowLatency,
|
|
1107
1167
|
bytesLoaded: this.bytesLoaded,
|
|
1108
1168
|
playlistBytesLoaded: this.playlistBytesLoaded,
|
|
1109
1169
|
renditionSwitches: this.renditionSwitches,
|
|
1110
|
-
licenseTimeMs: this.licenseTimeMs
|
|
1170
|
+
licenseTimeMs: this.licenseTimeMs,
|
|
1171
|
+
upshifts: this.upshifts,
|
|
1172
|
+
downshifts: this.downshifts,
|
|
1173
|
+
requestCount: this.requestCount,
|
|
1174
|
+
requestErrors: this.requestErrors,
|
|
1175
|
+
requestTimesMs: [...this.requestTimesMs],
|
|
1176
|
+
ladderHeights: this.ladderHeights,
|
|
1177
|
+
ladderTopBitrateKbps: this.ladderTopBitrateKbps || void 0
|
|
1111
1178
|
};
|
|
1112
|
-
if (e) {
|
|
1113
|
-
typeof e.latency == "number" && (
|
|
1114
|
-
let
|
|
1115
|
-
|
|
1179
|
+
if (this.cdnHost && (n.cdnHost = this.cdnHost), this.licenseRequested && (n.keySystem = "widevine", n.drmSecurityLevel = "L3"), e) {
|
|
1180
|
+
n.qualityPinned = !e.autoLevelEnabled, typeof e.latency == "number" && (n.latencySeconds = e.latency), typeof e.targetLatency == "number" && e.targetLatency > 0 && (n.targetLatencySeconds = e.targetLatency), typeof e.bandwidthEstimate == "number" && (n.bandwidthKbps = Math.round(e.bandwidthEstimate / 1e3));
|
|
1181
|
+
let t = e.currentLevel >= 0 ? e.levels[e.currentLevel] : void 0;
|
|
1182
|
+
t && (n.levelHeight = t.height), t?.videoCodec && (n.videoCodec = t.videoCodec), t?.audioCodec && (n.audioCodec = t.audioCodec), t && typeof t.bitrate == "number" && (n.renditionBitrateKbps = Math.round(t.bitrate / 1e3)), typeof t?.details?.live == "boolean" && (n.isLive = t.details.live, typeof e.liveSyncPosition == "number" && (n.atLiveEdge = this.deps.video.currentTime >= e.liveSyncPosition - 1.5));
|
|
1116
1183
|
}
|
|
1117
|
-
return
|
|
1184
|
+
return n;
|
|
1118
1185
|
}
|
|
1119
1186
|
trackEnd(e) {
|
|
1120
1187
|
let t = e.details;
|
|
@@ -1135,7 +1202,7 @@ var V = class {
|
|
|
1135
1202
|
return;
|
|
1136
1203
|
}
|
|
1137
1204
|
let e = Date.now() - this.lastAdvanceMs;
|
|
1138
|
-
!this.chaseSuspended && e > B && this.suspendChasing(), e >
|
|
1205
|
+
!this.chaseSuspended && e > B && this.suspendChasing(), e > Ie && this.emitEnded("stalled");
|
|
1139
1206
|
}
|
|
1140
1207
|
checkStarvation() {
|
|
1141
1208
|
let e = this.hls, { video: t } = this.deps;
|
|
@@ -1144,17 +1211,17 @@ var V = class {
|
|
|
1144
1211
|
this.starvedTicks = 0;
|
|
1145
1212
|
return;
|
|
1146
1213
|
}
|
|
1147
|
-
let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs < B, r = this.lastFragLoadingMs !== 0 && Date.now() - this.lastFragLoadingMs >
|
|
1214
|
+
let n = this.lastAdvanceMs !== 0 && Date.now() - this.lastAdvanceMs < B, r = this.lastFragLoadingMs !== 0 && Date.now() - this.lastFragLoadingMs > Re;
|
|
1148
1215
|
if (!(t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused && n && r)) {
|
|
1149
1216
|
this.starvedTicks = 0;
|
|
1150
1217
|
return;
|
|
1151
1218
|
}
|
|
1152
|
-
if (this.kickPending && (this.kickTicks += 1), !(++this.starvedTicks <
|
|
1153
|
-
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)) {
|
|
1154
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");
|
|
1155
1222
|
return;
|
|
1156
1223
|
}
|
|
1157
|
-
if (!(this.starvationKicks >=
|
|
1224
|
+
if (!(this.starvationKicks >= Be)) {
|
|
1158
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");
|
|
1159
1226
|
try {
|
|
1160
1227
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -1204,7 +1271,7 @@ var V = class {
|
|
|
1204
1271
|
scheduleLicenseRetry(t) {
|
|
1205
1272
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
1206
1273
|
let n = t.response?.code ?? 0;
|
|
1207
|
-
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;
|
|
1208
1275
|
this.licenseRecoveries += 1;
|
|
1209
1276
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
1210
1277
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -1222,7 +1289,7 @@ var V = class {
|
|
|
1222
1289
|
}
|
|
1223
1290
|
}
|
|
1224
1291
|
onError(t) {
|
|
1225
|
-
if (!t.fatal) return;
|
|
1292
|
+
if (t.type === e.ErrorTypes.NETWORK_ERROR && String(t.details ?? "").startsWith("frag") && (this.requestErrors += 1), !t.fatal) return;
|
|
1226
1293
|
let n = this.hls;
|
|
1227
1294
|
if (n) {
|
|
1228
1295
|
if (this.clearRecoveryReset(), t.type === e.ErrorTypes.KEY_SYSTEM_ERROR) {
|
|
@@ -1230,12 +1297,13 @@ var V = class {
|
|
|
1230
1297
|
this.deps.emit({
|
|
1231
1298
|
type: "error",
|
|
1232
1299
|
error: this.toError(t, "DRM"),
|
|
1233
|
-
fatal: !0
|
|
1300
|
+
fatal: !0,
|
|
1301
|
+
detail: t.details
|
|
1234
1302
|
});
|
|
1235
1303
|
return;
|
|
1236
1304
|
}
|
|
1237
1305
|
if (t.type === e.ErrorTypes.NETWORK_ERROR) {
|
|
1238
|
-
if (this.networkRecoveries <
|
|
1306
|
+
if (this.networkRecoveries < Ne) {
|
|
1239
1307
|
this.networkRecoveries += 1;
|
|
1240
1308
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
1241
1309
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -1246,26 +1314,29 @@ var V = class {
|
|
|
1246
1314
|
this.deps.emit({
|
|
1247
1315
|
type: "error",
|
|
1248
1316
|
error: this.toError(t, "NETWORK"),
|
|
1249
|
-
fatal: !0
|
|
1317
|
+
fatal: !0,
|
|
1318
|
+
detail: t.details
|
|
1250
1319
|
});
|
|
1251
1320
|
return;
|
|
1252
1321
|
}
|
|
1253
1322
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
1254
|
-
if (this.mediaRecoveries <
|
|
1323
|
+
if (this.mediaRecoveries < Me) {
|
|
1255
1324
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
1256
1325
|
return;
|
|
1257
1326
|
}
|
|
1258
1327
|
this.deps.emit({
|
|
1259
1328
|
type: "error",
|
|
1260
1329
|
error: this.toError(t),
|
|
1261
|
-
fatal: !0
|
|
1330
|
+
fatal: !0,
|
|
1331
|
+
detail: t.details
|
|
1262
1332
|
});
|
|
1263
1333
|
return;
|
|
1264
1334
|
}
|
|
1265
1335
|
this.deps.emit({
|
|
1266
1336
|
type: "error",
|
|
1267
1337
|
error: this.toError(t),
|
|
1268
|
-
fatal: !0
|
|
1338
|
+
fatal: !0,
|
|
1339
|
+
detail: t.details
|
|
1269
1340
|
});
|
|
1270
1341
|
}
|
|
1271
1342
|
}
|
|
@@ -1273,7 +1344,29 @@ var V = class {
|
|
|
1273
1344
|
let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
|
|
1274
1345
|
return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
|
|
1275
1346
|
}
|
|
1276
|
-
},
|
|
1347
|
+
}, Qe = 15e3, $e = 100, H = 1, et = 1e3, U = 3e4, tt = {
|
|
1348
|
+
inline: "PRESENTATION_INLINE",
|
|
1349
|
+
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
1350
|
+
pip: "PRESENTATION_PIP"
|
|
1351
|
+
}, nt = {
|
|
1352
|
+
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
1353
|
+
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
1354
|
+
none: "KEY_SYSTEM_NONE"
|
|
1355
|
+
};
|
|
1356
|
+
function W(e, t) {
|
|
1357
|
+
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
1358
|
+
}
|
|
1359
|
+
var rt = /* @__PURE__ */ new Set([
|
|
1360
|
+
"INVALID_URN",
|
|
1361
|
+
"NOT_FOUND",
|
|
1362
|
+
"GONE",
|
|
1363
|
+
"TOO_EARLY",
|
|
1364
|
+
"UNAVAILABLE",
|
|
1365
|
+
"UNAUTHORIZED",
|
|
1366
|
+
"FORBIDDEN",
|
|
1367
|
+
"RATE_LIMITED",
|
|
1368
|
+
"TIMEOUT"
|
|
1369
|
+
]), G = {
|
|
1277
1370
|
idle: "PLAYER_STATE_IDLE",
|
|
1278
1371
|
waiting: "PLAYER_STATE_WAITING",
|
|
1279
1372
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -1283,7 +1376,7 @@ var V = class {
|
|
|
1283
1376
|
ended: "PLAYER_STATE_ENDED",
|
|
1284
1377
|
error: "PLAYER_STATE_ERROR"
|
|
1285
1378
|
};
|
|
1286
|
-
function
|
|
1379
|
+
function it(e) {
|
|
1287
1380
|
try {
|
|
1288
1381
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
1289
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);
|
|
@@ -1291,7 +1384,7 @@ function Je(e) {
|
|
|
1291
1384
|
return;
|
|
1292
1385
|
}
|
|
1293
1386
|
}
|
|
1294
|
-
var
|
|
1387
|
+
var at = class {
|
|
1295
1388
|
opts;
|
|
1296
1389
|
url;
|
|
1297
1390
|
now;
|
|
@@ -1315,50 +1408,133 @@ var Ye = class {
|
|
|
1315
1408
|
errorCount = 0;
|
|
1316
1409
|
seekCount = 0;
|
|
1317
1410
|
pauseCount = 0;
|
|
1411
|
+
isPlaying = !1;
|
|
1412
|
+
isHidden = !1;
|
|
1413
|
+
isMuted = !1;
|
|
1414
|
+
activeSinceMs = null;
|
|
1415
|
+
activeTotalMs = 0;
|
|
1416
|
+
mutedSinceMs = null;
|
|
1417
|
+
mutedTotalMs = 0;
|
|
1418
|
+
lastHbMutedMs = 0;
|
|
1419
|
+
volumeChanges = 0;
|
|
1420
|
+
muteChanges = 0;
|
|
1421
|
+
presentation = "inline";
|
|
1422
|
+
presentationSinceMs;
|
|
1423
|
+
fullscreenTotalMs = 0;
|
|
1424
|
+
pipTotalMs = 0;
|
|
1425
|
+
waitingSinceMs = null;
|
|
1426
|
+
waitingTotalMs = 0;
|
|
1427
|
+
firstAudioMs = 0;
|
|
1428
|
+
timeToFirstStallMs = 0;
|
|
1429
|
+
lastStallMs = 0;
|
|
1430
|
+
lastErrorMs = 0;
|
|
1431
|
+
lastSeekMs = 0;
|
|
1432
|
+
lastErrorStage = null;
|
|
1433
|
+
sawFirstBytes = !1;
|
|
1434
|
+
mediaInfoSignature = "";
|
|
1435
|
+
lastUpshifts = 0;
|
|
1436
|
+
lastDownshifts = 0;
|
|
1437
|
+
lastDecoded = 0;
|
|
1438
|
+
lastRequestCount = 0;
|
|
1439
|
+
lastRequestErrors = 0;
|
|
1440
|
+
pendingStart = null;
|
|
1441
|
+
firstFlushTimer = null;
|
|
1318
1442
|
bornMs;
|
|
1319
1443
|
startupTimeMs = 0;
|
|
1320
1444
|
manifestLoadMs = 0;
|
|
1321
1445
|
firstFragLoadMs = 0;
|
|
1322
1446
|
onPagehide = () => this.end("END_REASON_PAGEHIDE");
|
|
1323
1447
|
onVisibility = () => {
|
|
1324
|
-
typeof document > "u" || (document.visibilityState === "hidden" ? this.hiddenSinceMs === null && (this.hiddenSinceMs = this.now()) : this.hiddenSinceMs !== null && (this.hiddenTotalMs += this.now() - this.hiddenSinceMs, this.hiddenSinceMs = null));
|
|
1448
|
+
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());
|
|
1325
1449
|
};
|
|
1326
1450
|
constructor(e) {
|
|
1327
1451
|
this.opts = {
|
|
1328
1452
|
...e,
|
|
1329
|
-
heartbeatMs: e.heartbeatMs ??
|
|
1330
|
-
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`, this.now = e.now ?? (() => Date.now()), this.bornMs = this.now();
|
|
1453
|
+
heartbeatMs: e.heartbeatMs ?? Qe
|
|
1454
|
+
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`, this.now = e.now ?? (() => Date.now()), this.bornMs = this.now(), this.presentationSinceMs = this.bornMs;
|
|
1331
1455
|
}
|
|
1332
1456
|
start() {
|
|
1333
|
-
|
|
1457
|
+
if (this.endedFlag) return;
|
|
1458
|
+
let e = {
|
|
1334
1459
|
player: this.opts.player,
|
|
1335
|
-
sdkVersion: this.opts.sdkVersion
|
|
1336
|
-
|
|
1460
|
+
sdkVersion: this.opts.sdkVersion,
|
|
1461
|
+
...this.opts.environment
|
|
1462
|
+
};
|
|
1463
|
+
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());
|
|
1337
1464
|
}
|
|
1338
1465
|
noteStateChange(e, t, n, r) {
|
|
1339
1466
|
if (this.endedFlag || e === t) return;
|
|
1340
1467
|
let i = this.now();
|
|
1341
|
-
t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(H, i - this.bornMs))) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null), t === "buffering" && e === "playing" ? (this.rebufferCount += 1, this.bufferingSinceMs = i) : e === "buffering" && this.bufferingSinceMs !== null && (this.rebufferTotalMs += i - this.bufferingSinceMs, this.bufferingSinceMs = null), t === "paused" && (this.pauseCount += 1);
|
|
1468
|
+
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.rebufferCount += 1, this.bufferingSinceMs = i, this.lastStallMs = i, this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(H, Math.round(this.playingTotalMs)))) : e === "buffering" && this.bufferingSinceMs !== null && (this.rebufferTotalMs += i - this.bufferingSinceMs, this.bufferingSinceMs = null), t === "paused" && (this.pauseCount += 1);
|
|
1342
1469
|
let a = {
|
|
1343
|
-
fromState:
|
|
1344
|
-
toState:
|
|
1345
|
-
|
|
1346
|
-
|
|
1470
|
+
fromState: G[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1471
|
+
toState: G[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1472
|
+
presentation: tt[this.presentation]
|
|
1473
|
+
}, o = this.causeOf(e, t, i);
|
|
1474
|
+
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
1475
|
+
}
|
|
1476
|
+
causeOf(e, t, n) {
|
|
1477
|
+
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
1478
|
+
if (t === "buffering") return n - this.lastSeekMs < 1e3 ? "TRANSITION_CAUSE_SEEK" : "TRANSITION_CAUSE_NETWORK_STALL";
|
|
1479
|
+
if (t === "paused" || t === "playing" && e === "paused") return "TRANSITION_CAUSE_USER";
|
|
1480
|
+
}
|
|
1481
|
+
syncActive() {
|
|
1482
|
+
let e = this.isPlaying && !this.isHidden && !this.isMuted;
|
|
1483
|
+
e && this.activeSinceMs === null ? this.activeSinceMs = this.now() : !e && this.activeSinceMs !== null && (this.activeTotalMs += this.now() - this.activeSinceMs, this.activeSinceMs = null);
|
|
1484
|
+
}
|
|
1485
|
+
closePresentation() {
|
|
1486
|
+
let e = this.now(), t = e - this.presentationSinceMs;
|
|
1487
|
+
this.presentation === "fullscreen" ? this.fullscreenTotalMs += t : this.presentation === "pip" && (this.pipTotalMs += t), this.presentationSinceMs = e;
|
|
1488
|
+
}
|
|
1489
|
+
noteAutoplay(e) {
|
|
1490
|
+
this.pendingStart && (this.pendingStart.autoplay = e);
|
|
1491
|
+
}
|
|
1492
|
+
noteEnvironment(e) {
|
|
1493
|
+
this.pendingStart && Object.assign(this.pendingStart, e);
|
|
1494
|
+
}
|
|
1495
|
+
seedVolume(e, t) {
|
|
1496
|
+
this.endedFlag || (this.isMuted = e || t === 0, this.isMuted && this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = this.now()), this.syncActive());
|
|
1497
|
+
}
|
|
1498
|
+
noteVolume(e, t) {
|
|
1499
|
+
if (this.endedFlag) return;
|
|
1500
|
+
let n = e || t === 0;
|
|
1501
|
+
if (n === this.isMuted) {
|
|
1502
|
+
this.volumeChanges += 1;
|
|
1503
|
+
return;
|
|
1504
|
+
}
|
|
1505
|
+
this.muteChanges += 1;
|
|
1506
|
+
let r = this.now();
|
|
1507
|
+
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();
|
|
1508
|
+
}
|
|
1509
|
+
notePresentation(e) {
|
|
1510
|
+
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
1347
1511
|
}
|
|
1348
1512
|
noteReady() {
|
|
1349
1513
|
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(H, this.now() - this.bornMs));
|
|
1350
1514
|
}
|
|
1351
1515
|
noteFirstBytes() {
|
|
1352
|
-
this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(H, this.now() - this.bornMs));
|
|
1516
|
+
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(H, this.now() - this.bornMs));
|
|
1353
1517
|
}
|
|
1354
1518
|
noteSeek() {
|
|
1355
|
-
this.endedFlag || (this.seekCount += 1);
|
|
1519
|
+
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
1356
1520
|
}
|
|
1357
|
-
noteError(e, t, n, r, i) {
|
|
1521
|
+
noteError(e, t, n, r, i, a) {
|
|
1358
1522
|
if (this.endedFlag) return;
|
|
1359
|
-
this.errorCount += 1;
|
|
1360
|
-
let
|
|
1361
|
-
t && (
|
|
1523
|
+
this.errorCount += 1, this.lastErrorMs = this.now();
|
|
1524
|
+
let o = { code: e };
|
|
1525
|
+
t && (o.detail = t), n && (o.fatal = !0), r > 0 && (o.httpStatus = r), i > 0 && (o.positionMs = Math.round(i));
|
|
1526
|
+
let s = this.stageOf(e, t, a);
|
|
1527
|
+
o.stage = s, this.lastErrorStage = s;
|
|
1528
|
+
let c = this.safeSample()?.cdnHost;
|
|
1529
|
+
c && (o.cdnHost = c), this.enqueue({ error: o }), this.flush();
|
|
1530
|
+
}
|
|
1531
|
+
stageOf(e, t, n) {
|
|
1532
|
+
let r = n ?? "";
|
|
1533
|
+
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";
|
|
1534
|
+
if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
|
|
1535
|
+
if (rt.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
1536
|
+
let i = t ?? "";
|
|
1537
|
+
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";
|
|
1362
1538
|
}
|
|
1363
1539
|
noteEnded() {
|
|
1364
1540
|
this.end("END_REASON_ENDED");
|
|
@@ -1382,25 +1558,51 @@ var Ye = class {
|
|
|
1382
1558
|
let s = e.droppedFrames ?? 0;
|
|
1383
1559
|
s > this.lastDropped && (i.droppedFramesDelta = s - this.lastDropped), this.lastDropped = s;
|
|
1384
1560
|
let c = e.renditionSwitches ?? 0;
|
|
1385
|
-
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);
|
|
1386
|
-
let l = this.
|
|
1387
|
-
|
|
1561
|
+
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";
|
|
1562
|
+
let l = this.mutedTotalMs;
|
|
1563
|
+
this.mutedSinceMs !== null && (l += t - this.mutedSinceMs), l > this.lastHbMutedMs && (i.mutedMsDelta = Math.round(l - this.lastHbMutedMs)), this.lastHbMutedMs = l;
|
|
1564
|
+
let u = e.upshifts ?? 0;
|
|
1565
|
+
u > this.lastUpshifts && (i.upshiftsDelta = u - this.lastUpshifts), this.lastUpshifts = u;
|
|
1566
|
+
let d = e.downshifts ?? 0;
|
|
1567
|
+
d > this.lastDownshifts && (i.downshiftsDelta = d - this.lastDownshifts), this.lastDownshifts = d;
|
|
1568
|
+
let f = e.decodedFrames ?? 0;
|
|
1569
|
+
f > this.lastDecoded && (i.decodedFramesDelta = f - this.lastDecoded), this.lastDecoded = f;
|
|
1570
|
+
let p = e.requestErrors ?? 0;
|
|
1571
|
+
p > this.lastRequestErrors && (i.requestErrorsDelta = p - this.lastRequestErrors), this.lastRequestErrors = p;
|
|
1572
|
+
let m = e.requestCount ?? 0, h = m - this.lastRequestCount;
|
|
1573
|
+
if (this.lastRequestCount = m, h > 0) {
|
|
1574
|
+
i.requestCountDelta = h;
|
|
1575
|
+
let t = e.requestTimesMs ?? [], n = t.slice(Math.max(0, t.length - h)).sort((e, t) => e - t);
|
|
1576
|
+
n.length > 0 && (i.requestTimeP50Ms = W(n, 50), i.requestTimeP95Ms = W(n, 95));
|
|
1577
|
+
}
|
|
1578
|
+
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();
|
|
1388
1579
|
}
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1580
|
+
maybeEmitMediaInfo(e) {
|
|
1581
|
+
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
1582
|
+
let t = {};
|
|
1583
|
+
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);
|
|
1584
|
+
let n = JSON.stringify(t);
|
|
1585
|
+
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
1392
1586
|
}
|
|
1393
1587
|
end(e) {
|
|
1394
1588
|
if (this.endedFlag) return;
|
|
1395
1589
|
this.endedFlag = !0;
|
|
1396
1590
|
let t = this.now();
|
|
1397
|
-
this.playingSinceMs !== null && (this.playingTotalMs += t - this.playingSinceMs, this.playingSinceMs = null), this.hiddenSinceMs !== null && (this.hiddenTotalMs += t - this.hiddenSinceMs, this.hiddenSinceMs = null), this.bufferingSinceMs !== null && (this.rebufferTotalMs += t - this.bufferingSinceMs, this.bufferingSinceMs = null), this.timer &&= (clearInterval(this.timer), null), typeof window < "u" && window.removeEventListener("pagehide", this.onPagehide), typeof document < "u" && document.removeEventListener("visibilitychange", this.onVisibility);
|
|
1398
|
-
let n = this.safeSample()
|
|
1591
|
+
this.playingSinceMs !== null && (this.playingTotalMs += t - this.playingSinceMs, this.playingSinceMs = null), this.hiddenSinceMs !== null && (this.hiddenTotalMs += t - this.hiddenSinceMs, this.hiddenSinceMs = null), this.bufferingSinceMs !== null && (this.rebufferTotalMs += t - this.bufferingSinceMs, this.bufferingSinceMs = null), this.mutedSinceMs !== null && (this.mutedTotalMs += t - this.mutedSinceMs, this.mutedSinceMs = null), this.waitingSinceMs !== null && (this.waitingTotalMs += t - this.waitingSinceMs, this.waitingSinceMs = null), this.isPlaying = !1, this.syncActive(), this.closePresentation(), this.firstFlushTimer &&= (clearTimeout(this.firstFlushTimer), null), this.timer &&= (clearInterval(this.timer), null), typeof window < "u" && window.removeEventListener("pagehide", this.onPagehide), typeof document < "u" && document.removeEventListener("visibilitychange", this.onVisibility);
|
|
1592
|
+
let n = this.safeSample();
|
|
1593
|
+
n && this.maybeEmitMediaInfo(n);
|
|
1594
|
+
let r = { reason: e }, i = n?.bytesLoaded ?? this.lastBytes;
|
|
1399
1595
|
i > 0 && (r.bytesDownloadedTotal = i), this.playingTotalMs > 0 && (r.watchTimeMs = Math.round(this.playingTotalMs)), this.rebufferCount > 0 && (r.rebufferCount = this.rebufferCount), this.rebufferTotalMs > 0 && (r.rebufferTimeMs = Math.round(this.rebufferTotalMs)), this.startupTimeMs > 0 && (r.startupTimeMs = Math.round(this.startupTimeMs)), this.manifestLoadMs > 0 && (r.manifestLoadMs = Math.round(this.manifestLoadMs)), this.firstFragLoadMs > 0 && (r.firstFragLoadMs = Math.round(this.firstFragLoadMs));
|
|
1400
1596
|
let a = n?.licenseTimeMs ?? 0;
|
|
1401
1597
|
a > 0 && (r.licenseTimeMs = Math.round(a));
|
|
1402
1598
|
let o = n?.droppedFrames ?? this.lastDropped;
|
|
1403
|
-
o > 0 && (r.droppedFramesTotal = o), this.errorCount > 0 && (r.errorCount = this.errorCount), this.hiddenTotalMs > 0 && (r.hiddenTimeMs = Math.round(this.hiddenTotalMs)), this.seekCount > 0 && (r.seekCount = this.seekCount), this.pauseCount > 0 && (r.pauseCount = this.pauseCount), this.
|
|
1599
|
+
o > 0 && (r.droppedFramesTotal = o), this.errorCount > 0 && (r.errorCount = this.errorCount), this.hiddenTotalMs > 0 && (r.hiddenTimeMs = Math.round(this.hiddenTotalMs)), this.seekCount > 0 && (r.seekCount = this.seekCount), this.pauseCount > 0 && (r.pauseCount = this.pauseCount), this.firstAudioMs > 0 && (r.firstAudioMs = Math.round(this.firstAudioMs)), this.waitingTotalMs > 0 && (r.waitingForLiveMs = Math.round(this.waitingTotalMs)), this.timeToFirstStallMs > 0 && (r.timeToFirstStallMs = Math.round(this.timeToFirstStallMs));
|
|
1600
|
+
let s = n?.positionMs ?? 0;
|
|
1601
|
+
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));
|
|
1602
|
+
let c = e !== "END_REASON_ENDED";
|
|
1603
|
+
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);
|
|
1604
|
+
let l = n?.decodedFrames ?? this.lastDecoded;
|
|
1605
|
+
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");
|
|
1404
1606
|
}
|
|
1405
1607
|
safeSample() {
|
|
1406
1608
|
try {
|
|
@@ -1418,13 +1620,13 @@ var Ye = class {
|
|
|
1418
1620
|
};
|
|
1419
1621
|
}
|
|
1420
1622
|
enqueue(e) {
|
|
1421
|
-
for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
1623
|
+
for (this.pending.push(this.wrap(e)); this.pending.length > $e;) {
|
|
1422
1624
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
1423
1625
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
1424
1626
|
}
|
|
1425
1627
|
}
|
|
1426
1628
|
flush(e = !1) {
|
|
1427
|
-
if (this.pending.length === 0) return;
|
|
1629
|
+
if (this.firstFlushTimer &&= (clearTimeout(this.firstFlushTimer), null), this.pendingStart = null, this.pending.length === 0) return;
|
|
1428
1630
|
let t = JSON.stringify({ beacons: this.pending });
|
|
1429
1631
|
if (this.pending = [], e) {
|
|
1430
1632
|
let e = this.opts.sendBeacon ?? (typeof navigator < "u" && navigator.sendBeacon ? navigator.sendBeacon.bind(navigator) : void 0);
|
|
@@ -1440,7 +1642,74 @@ var Ye = class {
|
|
|
1440
1642
|
keepalive: !0
|
|
1441
1643
|
}).catch(() => {});
|
|
1442
1644
|
}
|
|
1443
|
-
}
|
|
1645
|
+
};
|
|
1646
|
+
//#endregion
|
|
1647
|
+
//#region src/core/environment.ts
|
|
1648
|
+
function ot() {
|
|
1649
|
+
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
1650
|
+
let e;
|
|
1651
|
+
try {
|
|
1652
|
+
e = window.top !== window.self;
|
|
1653
|
+
} catch {
|
|
1654
|
+
e = !0;
|
|
1655
|
+
}
|
|
1656
|
+
let t = window.location?.origin;
|
|
1657
|
+
if (!e) return {
|
|
1658
|
+
host: t && t !== "null" ? t : void 0,
|
|
1659
|
+
integration: "INTEGRATION_KIND_SDK"
|
|
1660
|
+
};
|
|
1661
|
+
let n;
|
|
1662
|
+
try {
|
|
1663
|
+
let e = window.location.ancestorOrigins;
|
|
1664
|
+
e && e.length > 0 && (n = e[e.length - 1] ?? void 0), !n && typeof document < "u" && document.referrer && (n = new URL(document.referrer).origin);
|
|
1665
|
+
} catch {
|
|
1666
|
+
n = void 0;
|
|
1667
|
+
}
|
|
1668
|
+
return n === "null" && (n = void 0), {
|
|
1669
|
+
host: n,
|
|
1670
|
+
integration: "INTEGRATION_KIND_IFRAME"
|
|
1671
|
+
};
|
|
1672
|
+
}
|
|
1673
|
+
function st() {
|
|
1674
|
+
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
1675
|
+
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
1676
|
+
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
1677
|
+
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
1678
|
+
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";
|
|
1679
|
+
}
|
|
1680
|
+
function ct() {
|
|
1681
|
+
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
1682
|
+
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
1683
|
+
let t = { connectionType: e.type ? {
|
|
1684
|
+
wifi: "CONNECTION_TYPE_WIFI",
|
|
1685
|
+
cellular: "CONNECTION_TYPE_CELLULAR",
|
|
1686
|
+
ethernet: "CONNECTION_TYPE_ETHERNET"
|
|
1687
|
+
}[e.type] ?? "CONNECTION_TYPE_OTHER" : "CONNECTION_TYPE_UNKNOWN" };
|
|
1688
|
+
return typeof e.downlink == "number" && e.downlink > 0 && (t.downlinkKbps = Math.round(e.downlink * 1e3)), e.saveData && (t.saveData = !0), t;
|
|
1689
|
+
}
|
|
1690
|
+
function lt(e) {
|
|
1691
|
+
let t = ot(), n = {
|
|
1692
|
+
deviceClass: st(),
|
|
1693
|
+
integration: t.integration,
|
|
1694
|
+
...ct()
|
|
1695
|
+
};
|
|
1696
|
+
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);
|
|
1697
|
+
let r = e.getBoundingClientRect?.();
|
|
1698
|
+
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
1699
|
+
}
|
|
1700
|
+
async function ut() {
|
|
1701
|
+
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
1702
|
+
if (!e?.getHighEntropyValues) return {};
|
|
1703
|
+
try {
|
|
1704
|
+
let t = await e.getHighEntropyValues(["model", "platformVersion"]), n = {};
|
|
1705
|
+
return t.model && (n.deviceModel = t.model), t.platformVersion && (n.osVersion = t.platformVersion), n;
|
|
1706
|
+
} catch {
|
|
1707
|
+
return {};
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
//#endregion
|
|
1711
|
+
//#region src/core/version.ts
|
|
1712
|
+
var dt = "2.1.1", K = {
|
|
1444
1713
|
accent: "#E1B600",
|
|
1445
1714
|
accentText: "#1B1C23",
|
|
1446
1715
|
background: "#0e0f13",
|
|
@@ -1451,7 +1720,7 @@ var Ye = class {
|
|
|
1451
1720
|
border: "rgba(255, 255, 255, 0.1)",
|
|
1452
1721
|
radius: "8px",
|
|
1453
1722
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
1454
|
-
},
|
|
1723
|
+
}, q = {
|
|
1455
1724
|
accent: "--havik-accent",
|
|
1456
1725
|
accentText: "--havik-accent-text",
|
|
1457
1726
|
background: "--havik-bg",
|
|
@@ -1463,25 +1732,25 @@ var Ye = class {
|
|
|
1463
1732
|
radius: "--havik-radius",
|
|
1464
1733
|
fontFamily: "--havik-font"
|
|
1465
1734
|
};
|
|
1466
|
-
function
|
|
1735
|
+
function J(e, t) {
|
|
1467
1736
|
let n = {
|
|
1468
|
-
...
|
|
1737
|
+
...K,
|
|
1469
1738
|
...t
|
|
1470
1739
|
};
|
|
1471
|
-
for (let t of Object.keys(
|
|
1740
|
+
for (let t of Object.keys(q)) e.style.setProperty(q[t], n[t]);
|
|
1472
1741
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
1473
1742
|
}
|
|
1474
1743
|
//#endregion
|
|
1475
1744
|
//#region src/ui/styles.ts
|
|
1476
|
-
var
|
|
1477
|
-
function
|
|
1478
|
-
if (e.getElementById(
|
|
1745
|
+
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";
|
|
1746
|
+
function pt(e = document) {
|
|
1747
|
+
if (e.getElementById(Y)) return;
|
|
1479
1748
|
let t = e.createElement("style");
|
|
1480
|
-
t.id =
|
|
1749
|
+
t.id = Y, t.textContent = ft, e.head.appendChild(t);
|
|
1481
1750
|
}
|
|
1482
1751
|
//#endregion
|
|
1483
1752
|
//#region src/ui/icons.ts
|
|
1484
|
-
var
|
|
1753
|
+
var mt = {
|
|
1485
1754
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
1486
1755
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
1487
1756
|
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\"/>",
|
|
@@ -1494,21 +1763,21 @@ var $e = {
|
|
|
1494
1763
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
1495
1764
|
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\"/>"
|
|
1496
1765
|
};
|
|
1497
|
-
function
|
|
1498
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
1766
|
+
function X(e) {
|
|
1767
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${mt[e]}</svg>`;
|
|
1499
1768
|
}
|
|
1500
1769
|
//#endregion
|
|
1501
1770
|
//#region src/ui/controls.ts
|
|
1502
|
-
var
|
|
1771
|
+
var ht = 3e3, gt = /* @__PURE__ */ new Set([
|
|
1503
1772
|
"GONE",
|
|
1504
1773
|
"NOT_FOUND",
|
|
1505
1774
|
"INVALID_URN",
|
|
1506
1775
|
"UNAUTHORIZED"
|
|
1507
1776
|
]);
|
|
1508
|
-
function
|
|
1509
|
-
return new
|
|
1777
|
+
function _t(e) {
|
|
1778
|
+
return new vt(e);
|
|
1510
1779
|
}
|
|
1511
|
-
var
|
|
1780
|
+
var vt = class {
|
|
1512
1781
|
root;
|
|
1513
1782
|
video;
|
|
1514
1783
|
player;
|
|
@@ -1550,7 +1819,7 @@ var rt = class {
|
|
|
1550
1819
|
scrubbing = !1;
|
|
1551
1820
|
offFns = [];
|
|
1552
1821
|
constructor(e) {
|
|
1553
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
1822
|
+
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");
|
|
1554
1823
|
let t = (e, t, n) => {
|
|
1555
1824
|
let r = this.doc.createElement(e);
|
|
1556
1825
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -1561,12 +1830,12 @@ var rt = class {
|
|
|
1561
1830
|
"aria-label": r,
|
|
1562
1831
|
title: r
|
|
1563
1832
|
});
|
|
1564
|
-
return i.innerHTML =
|
|
1833
|
+
return i.innerHTML = X(n), i;
|
|
1565
1834
|
};
|
|
1566
1835
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
1567
1836
|
type: "button",
|
|
1568
1837
|
"aria-label": "Play"
|
|
1569
|
-
}), this.center.innerHTML =
|
|
1838
|
+
}), 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", {
|
|
1570
1839
|
role: "slider",
|
|
1571
1840
|
"aria-label": "Seek",
|
|
1572
1841
|
"aria-valuemin": "0",
|
|
@@ -1584,7 +1853,7 @@ var rt = class {
|
|
|
1584
1853
|
"aria-label": "Volume"
|
|
1585
1854
|
});
|
|
1586
1855
|
let a = t("div", "havik-vol");
|
|
1587
|
-
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML =
|
|
1856
|
+
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = X("liveDot");
|
|
1588
1857
|
let o = this.doc.createElement("span");
|
|
1589
1858
|
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";
|
|
1590
1859
|
let s = t("div", "havik-spacer");
|
|
@@ -1638,12 +1907,12 @@ var rt = class {
|
|
|
1638
1907
|
}
|
|
1639
1908
|
if (e === "preplay") {
|
|
1640
1909
|
let e = this.doc.createElement("button");
|
|
1641
|
-
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML =
|
|
1910
|
+
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);
|
|
1642
1911
|
} else {
|
|
1643
1912
|
let r = this.doc.createElement("div");
|
|
1644
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
1913
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !gt.has(this.lastError.code)) {
|
|
1645
1914
|
let e = this.doc.createElement("button");
|
|
1646
|
-
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${
|
|
1915
|
+
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);
|
|
1647
1916
|
}
|
|
1648
1917
|
}
|
|
1649
1918
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -1682,7 +1951,7 @@ var rt = class {
|
|
|
1682
1951
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
1683
1952
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
1684
1953
|
}
|
|
1685
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
1954
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Z(this.video.currentTime)} / ${Z(this.video.duration)}`);
|
|
1686
1955
|
}
|
|
1687
1956
|
syncLive() {
|
|
1688
1957
|
let e = this.player.getStats(), t = e.isLive !== !1;
|
|
@@ -1732,17 +2001,17 @@ var rt = class {
|
|
|
1732
2001
|
renderQualityMenu() {
|
|
1733
2002
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
1734
2003
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
1735
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
2004
|
+
for (let n of e) this.menu.append(this.menuItem(yt(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
1736
2005
|
}
|
|
1737
2006
|
renderAudioMenu() {
|
|
1738
2007
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
1739
2008
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
1740
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2009
|
+
for (let t of e) this.menu.append(this.menuItem(bt(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
1741
2010
|
}
|
|
1742
2011
|
renderCcMenu() {
|
|
1743
2012
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
1744
2013
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
1745
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2014
|
+
for (let t of e) this.menu.append(this.menuItem(xt(t), !1, () => this.player.setTextTrack(t.id)));
|
|
1746
2015
|
}
|
|
1747
2016
|
onTracksChanged() {
|
|
1748
2017
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -1762,11 +2031,11 @@ var rt = class {
|
|
|
1762
2031
|
}
|
|
1763
2032
|
async toggleFullscreen() {
|
|
1764
2033
|
try {
|
|
1765
|
-
|
|
2034
|
+
C(this.video, this.root) ? await T(this.video, this.root) : await w(this.video, this.root);
|
|
1766
2035
|
} catch {}
|
|
1767
2036
|
}
|
|
1768
2037
|
syncFullscreen() {
|
|
1769
|
-
let e =
|
|
2038
|
+
let e = C(this.video, this.root);
|
|
1770
2039
|
this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
|
|
1771
2040
|
}
|
|
1772
2041
|
poke() {
|
|
@@ -1825,7 +2094,7 @@ var rt = class {
|
|
|
1825
2094
|
}
|
|
1826
2095
|
}
|
|
1827
2096
|
setIcon(e, t) {
|
|
1828
|
-
e.innerHTML =
|
|
2097
|
+
e.innerHTML = X(t);
|
|
1829
2098
|
}
|
|
1830
2099
|
destroy() {
|
|
1831
2100
|
this.hideTimer && clearTimeout(this.hideTimer);
|
|
@@ -1842,32 +2111,32 @@ var rt = class {
|
|
|
1842
2111
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
1843
2112
|
}
|
|
1844
2113
|
};
|
|
1845
|
-
function
|
|
2114
|
+
function Z(e) {
|
|
1846
2115
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
1847
2116
|
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");
|
|
1848
2117
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
1849
2118
|
}
|
|
1850
|
-
function
|
|
2119
|
+
function yt(e) {
|
|
1851
2120
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
1852
2121
|
}
|
|
1853
|
-
function
|
|
2122
|
+
function bt(e) {
|
|
1854
2123
|
return e.name || e.lang || `Track ${e.id}`;
|
|
1855
2124
|
}
|
|
1856
|
-
function
|
|
2125
|
+
function xt(e) {
|
|
1857
2126
|
return e.name || e.lang || `Track ${e.id}`;
|
|
1858
2127
|
}
|
|
1859
2128
|
//#endregion
|
|
1860
2129
|
//#region src/managed/index.ts
|
|
1861
|
-
var
|
|
1862
|
-
async function
|
|
2130
|
+
var St = 6e3, Q = 45e3, Ct = 2e3, wt = 3, Tt = 2e3, Et = 48e4;
|
|
2131
|
+
async function Dt(e) {
|
|
1863
2132
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
1864
2133
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: baseUrl is required");
|
|
1865
2134
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
1866
2135
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
1867
|
-
let t = new
|
|
2136
|
+
let t = new Ot(e);
|
|
1868
2137
|
return await t.start(), t;
|
|
1869
2138
|
}
|
|
1870
|
-
var
|
|
2139
|
+
var Ot = class {
|
|
1871
2140
|
opts;
|
|
1872
2141
|
abort = new AbortController();
|
|
1873
2142
|
listeners = {};
|
|
@@ -1891,7 +2160,7 @@ var dt = class {
|
|
|
1891
2160
|
armFallbackCtrl = null;
|
|
1892
2161
|
_lastError = null;
|
|
1893
2162
|
analyticsSession = null;
|
|
1894
|
-
|
|
2163
|
+
detachMediaListeners;
|
|
1895
2164
|
playRequested = !1;
|
|
1896
2165
|
pendingStartLoad = !1;
|
|
1897
2166
|
constructor(e) {
|
|
@@ -1933,7 +2202,7 @@ var dt = class {
|
|
|
1933
2202
|
};
|
|
1934
2203
|
}
|
|
1935
2204
|
beginArming(e, t, n = !1) {
|
|
1936
|
-
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ??
|
|
2205
|
+
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
|
|
1937
2206
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
1938
2207
|
}
|
|
1939
2208
|
beginArmingByPolling(e) {
|
|
@@ -1954,7 +2223,7 @@ var dt = class {
|
|
|
1954
2223
|
setTimeout(() => {
|
|
1955
2224
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
1956
2225
|
phase: i ? "unavailable" : "tooEarly",
|
|
1957
|
-
retryInMs:
|
|
2226
|
+
retryInMs: Q,
|
|
1958
2227
|
attempt: 1,
|
|
1959
2228
|
elapsedMs: 0,
|
|
1960
2229
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -1993,13 +2262,13 @@ var dt = class {
|
|
|
1993
2262
|
!a && !p() && h();
|
|
1994
2263
|
}, e);
|
|
1995
2264
|
};
|
|
1996
|
-
_(
|
|
2265
|
+
_(St), this.armingSub = E({
|
|
1997
2266
|
eventsBaseUrl: t,
|
|
1998
2267
|
matchUrn: this.opts.matchUrn,
|
|
1999
2268
|
credential: this.opts.credential,
|
|
2000
|
-
onAlive: () => _(
|
|
2269
|
+
onAlive: () => _(Q),
|
|
2001
2270
|
onState: (e) => {
|
|
2002
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
2271
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Ct);
|
|
2003
2272
|
},
|
|
2004
2273
|
onError: () => h()
|
|
2005
2274
|
});
|
|
@@ -2022,7 +2291,7 @@ var dt = class {
|
|
|
2022
2291
|
let n = await s(this.opts.credential);
|
|
2023
2292
|
if (this.destroyed || t !== this.loadGen) return;
|
|
2024
2293
|
this.setState("loading");
|
|
2025
|
-
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a =
|
|
2294
|
+
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = Oe(this.opts.video, (e) => {
|
|
2026
2295
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
2027
2296
|
});
|
|
2028
2297
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -2038,30 +2307,40 @@ var dt = class {
|
|
|
2038
2307
|
}, 0));
|
|
2039
2308
|
}
|
|
2040
2309
|
startAnalytics(e, t, n) {
|
|
2041
|
-
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.
|
|
2310
|
+
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
2042
2311
|
let r = e.analytics?.sid;
|
|
2043
2312
|
if (!r) return;
|
|
2044
|
-
let i = (typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0) ??
|
|
2313
|
+
let i = (typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0) ?? it(this.opts.baseUrl);
|
|
2045
2314
|
if (!i) return;
|
|
2046
|
-
let a = this.opts.video, o = new
|
|
2315
|
+
let a = this.opts.video, o = new at({
|
|
2047
2316
|
endpoint: i,
|
|
2048
2317
|
sid: r,
|
|
2049
2318
|
apiKey: n,
|
|
2050
2319
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
2051
|
-
sdkVersion:
|
|
2320
|
+
sdkVersion: dt,
|
|
2321
|
+
environment: lt(a),
|
|
2052
2322
|
sample: () => {
|
|
2053
2323
|
let e = this.engine?.getStats() ?? F, t = a.buffered.length ? Math.max(0, a.buffered.end(a.buffered.length - 1) - a.currentTime) : 0;
|
|
2054
2324
|
return {
|
|
2055
2325
|
...e,
|
|
2056
2326
|
bufferedMs: Math.round(t * 1e3),
|
|
2057
2327
|
state: this._state,
|
|
2058
|
-
positionMs: Math.round(a.currentTime * 1e3)
|
|
2328
|
+
positionMs: Math.round(a.currentTime * 1e3),
|
|
2329
|
+
playbackRate: a.playbackRate
|
|
2059
2330
|
};
|
|
2060
2331
|
}
|
|
2061
2332
|
});
|
|
2062
2333
|
this.analyticsSession = o;
|
|
2063
|
-
let s = () => o.noteSeek();
|
|
2064
|
-
a.addEventListener("seeking", s),
|
|
2334
|
+
let s = () => o.noteSeek(), c = () => o.noteVolume(a.muted, a.volume);
|
|
2335
|
+
a.addEventListener("seeking", s), a.addEventListener("volumechange", c), this.detachMediaListeners = () => {
|
|
2336
|
+
a.removeEventListener("seeking", s), a.removeEventListener("volumechange", c);
|
|
2337
|
+
}, 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");
|
|
2338
|
+
}
|
|
2339
|
+
currentPresentation() {
|
|
2340
|
+
let e = this.opts.video;
|
|
2341
|
+
if (typeof document < "u" && document.pictureInPictureElement === e) return "pip";
|
|
2342
|
+
let t = typeof document < "u" ? document.fullscreenElement : null;
|
|
2343
|
+
return e.webkitDisplayingFullscreen === !0 || t && (t === e || t.contains(e)) ? "fullscreen" : "inline";
|
|
2065
2344
|
}
|
|
2066
2345
|
createEngine(e, t, r = !1) {
|
|
2067
2346
|
let i = { ...this.opts.hlsConfig };
|
|
@@ -2070,7 +2349,7 @@ var dt = class {
|
|
|
2070
2349
|
video: this.opts.video,
|
|
2071
2350
|
descriptor: e,
|
|
2072
2351
|
credential: t,
|
|
2073
|
-
deviceId:
|
|
2352
|
+
deviceId: A(),
|
|
2074
2353
|
userId: this.opts.userId,
|
|
2075
2354
|
lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
|
|
2076
2355
|
snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
|
|
@@ -2082,7 +2361,7 @@ var dt = class {
|
|
|
2082
2361
|
if (o === "native") return new z(a);
|
|
2083
2362
|
if (o === "hls") return new V(a);
|
|
2084
2363
|
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && L(this.opts.video) && R()) return new z(a);
|
|
2085
|
-
if (
|
|
2364
|
+
if (je()) return new V(a);
|
|
2086
2365
|
if (L(this.opts.video)) return new z(a);
|
|
2087
2366
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
2088
2367
|
}
|
|
@@ -2106,16 +2385,16 @@ var dt = class {
|
|
|
2106
2385
|
case "ended":
|
|
2107
2386
|
this.onStreamEnded();
|
|
2108
2387
|
break;
|
|
2109
|
-
case "error": this.analyticsSession?.noteError(e.error.code, e.error.message, e.fatal, e.error.httpStatus ?? 0, Math.round(this.opts.video.currentTime * 1e3)), e.fatal ? this.fail(e.error) : this.emit("warning", e.error);
|
|
2388
|
+
case "error": this.analyticsSession?.noteError(e.error.code, e.error.message, e.fatal, e.error.httpStatus ?? 0, Math.round(this.opts.video.currentTime * 1e3), e.detail), e.fatal ? this.fail(e.error) : this.emit("warning", e.error);
|
|
2110
2389
|
}
|
|
2111
2390
|
}
|
|
2112
2391
|
startLiveState(e) {
|
|
2113
2392
|
if (this.opts.liveStateEvents === !1) return;
|
|
2114
|
-
let t = this.opts.eventsBaseUrl ??
|
|
2393
|
+
let t = this.opts.eventsBaseUrl ?? D(this.opts.baseUrl);
|
|
2115
2394
|
if (!t) return;
|
|
2116
2395
|
this.closeLiveState();
|
|
2117
2396
|
let r = 0, i = !1;
|
|
2118
|
-
this.liveStateSub =
|
|
2397
|
+
this.liveStateSub = E({
|
|
2119
2398
|
eventsBaseUrl: t,
|
|
2120
2399
|
matchUrn: this.opts.matchUrn,
|
|
2121
2400
|
credential: this.opts.credential,
|
|
@@ -2126,7 +2405,7 @@ var dt = class {
|
|
|
2126
2405
|
r = 0, i = !1;
|
|
2127
2406
|
},
|
|
2128
2407
|
onError: () => {
|
|
2129
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
2408
|
+
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.`))));
|
|
2130
2409
|
}
|
|
2131
2410
|
});
|
|
2132
2411
|
}
|
|
@@ -2148,7 +2427,7 @@ var dt = class {
|
|
|
2148
2427
|
scheduleRejoin(e) {
|
|
2149
2428
|
!this.rejoinEnabled() || this.rejoinTimer || (this.rejoinTimer = setTimeout(() => {
|
|
2150
2429
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
2151
|
-
}, Math.random() *
|
|
2430
|
+
}, Math.random() * Ct));
|
|
2152
2431
|
}
|
|
2153
2432
|
cancelRejoin() {
|
|
2154
2433
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -2172,7 +2451,7 @@ var dt = class {
|
|
|
2172
2451
|
}
|
|
2173
2452
|
t.controls = !1;
|
|
2174
2453
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
2175
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
2454
|
+
r && r.insertBefore(n, t), n.appendChild(t), J(n, this.opts.theme), this.container = n, this.controlBar = _t({
|
|
2176
2455
|
root: n,
|
|
2177
2456
|
video: t,
|
|
2178
2457
|
player: this,
|
|
@@ -2189,14 +2468,20 @@ var dt = class {
|
|
|
2189
2468
|
e && (e.parentNode ? (e.parentNode.insertBefore(this.opts.video, e), e.remove()) : this.opts.video.parentNode === e && e.removeChild(this.opts.video)), this.container = null;
|
|
2190
2469
|
}
|
|
2191
2470
|
attachPipListeners() {
|
|
2192
|
-
let e = this.opts.video, t = () => this.
|
|
2193
|
-
|
|
2194
|
-
|
|
2471
|
+
let e = this.opts.video, t = () => this.analyticsSession?.notePresentation(this.currentPresentation()), n = () => {
|
|
2472
|
+
t(), this.emit("pipchange", !0);
|
|
2473
|
+
}, r = () => {
|
|
2474
|
+
t(), this.emit("pipchange", !1);
|
|
2475
|
+
};
|
|
2476
|
+
e.addEventListener("enterpictureinpicture", n), e.addEventListener("leavepictureinpicture", r);
|
|
2477
|
+
let i = typeof document < "u" ? document : void 0;
|
|
2478
|
+
i?.addEventListener("fullscreenchange", t), i?.addEventListener("webkitfullscreenchange", t), this.detachPip = () => {
|
|
2479
|
+
e.removeEventListener("enterpictureinpicture", n), e.removeEventListener("leavepictureinpicture", r), i?.removeEventListener("fullscreenchange", t), i?.removeEventListener("webkitfullscreenchange", t);
|
|
2195
2480
|
};
|
|
2196
2481
|
}
|
|
2197
2482
|
startStats() {
|
|
2198
2483
|
this.stopStats();
|
|
2199
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
2484
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Tt);
|
|
2200
2485
|
this.statsTimer = setInterval(() => {
|
|
2201
2486
|
if (!this.engine) return;
|
|
2202
2487
|
let e = this.engine.getStats();
|
|
@@ -2208,7 +2493,7 @@ var dt = class {
|
|
|
2208
2493
|
}
|
|
2209
2494
|
scheduleLicenseRefresh() {
|
|
2210
2495
|
this.stopRefresh();
|
|
2211
|
-
let e = this.opts.licenseRefreshMs ??
|
|
2496
|
+
let e = this.opts.licenseRefreshMs ?? Et;
|
|
2212
2497
|
!e || !this._descriptor?.drmEnabled || (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
2213
2498
|
}
|
|
2214
2499
|
stopRefresh() {
|
|
@@ -2235,9 +2520,9 @@ var dt = class {
|
|
|
2235
2520
|
let t = this.pendingStartLoad && this._state !== "ended" && this._state !== "error";
|
|
2236
2521
|
t && (this.pendingStartLoad = !1, this.setState("loading"), this.engine?.startLoad());
|
|
2237
2522
|
try {
|
|
2238
|
-
await this.opts.video.play();
|
|
2523
|
+
await this.opts.video.play(), e && this.analyticsSession?.noteAutoplay(this.opts.video.muted ? "AUTOPLAY_RESULT_ALLOWED_MUTED" : "AUTOPLAY_RESULT_ALLOWED");
|
|
2239
2524
|
} catch (n) {
|
|
2240
|
-
n instanceof DOMException && n.name === "NotAllowedError" && (e && (this.playRequested = !1), t && !this.destroyed && this._state === "loading" && this.setState("paused"), this.emit("autoplayblocked"));
|
|
2525
|
+
n instanceof DOMException && n.name === "NotAllowedError" && (this.analyticsSession?.noteAutoplay("AUTOPLAY_RESULT_BLOCKED"), e && (this.playRequested = !1), t && !this.destroyed && this._state === "loading" && this.setState("paused"), this.emit("autoplayblocked"));
|
|
2241
2526
|
}
|
|
2242
2527
|
}
|
|
2243
2528
|
pause() {
|
|
@@ -2289,10 +2574,10 @@ var dt = class {
|
|
|
2289
2574
|
e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
|
|
2290
2575
|
}
|
|
2291
2576
|
async enterFullscreen() {
|
|
2292
|
-
return !this.destroyed &&
|
|
2577
|
+
return !this.destroyed && w(this.opts.video, this.container ?? void 0);
|
|
2293
2578
|
}
|
|
2294
2579
|
async exitFullscreen() {
|
|
2295
|
-
await
|
|
2580
|
+
await T(this.opts.video, this.container ?? void 0);
|
|
2296
2581
|
}
|
|
2297
2582
|
retry() {
|
|
2298
2583
|
return this.reload();
|
|
@@ -2317,7 +2602,7 @@ var dt = class {
|
|
|
2317
2602
|
return n.add(t), () => n.delete(t);
|
|
2318
2603
|
}
|
|
2319
2604
|
destroy() {
|
|
2320
|
-
this.destroyed || (this.destroyed = !0, this.loadGen += 1, this.abort.abort(), this.stopStats(), this.stopRefresh(), this.unmountControls(), this.cancelRejoin(), this.closeArming(), this.closeLiveState(), this.detachMedia?.(), this.detachPip?.(), this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.
|
|
2605
|
+
this.destroyed || (this.destroyed = !0, this.loadGen += 1, this.abort.abort(), this.stopStats(), this.stopRefresh(), this.unmountControls(), this.cancelRejoin(), this.closeArming(), this.closeLiveState(), this.detachMedia?.(), this.detachPip?.(), this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.engine?.destroy(), this.engine = null, this.setState("idle"), this.clearListeners());
|
|
2321
2606
|
}
|
|
2322
2607
|
clearListeners() {
|
|
2323
2608
|
for (let e of Object.keys(this.listeners)) this.listeners[e]?.clear();
|
|
@@ -2360,7 +2645,7 @@ function $(e) {
|
|
|
2360
2645
|
}
|
|
2361
2646
|
//#endregion
|
|
2362
2647
|
//#region src/embed/host.ts
|
|
2363
|
-
function
|
|
2648
|
+
function kt(e) {
|
|
2364
2649
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
2365
2650
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
2366
2651
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -2419,8 +2704,8 @@ function ft(e) {
|
|
|
2419
2704
|
}
|
|
2420
2705
|
//#endregion
|
|
2421
2706
|
//#region src/embed/page.ts
|
|
2422
|
-
var
|
|
2423
|
-
function
|
|
2707
|
+
var At = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
2708
|
+
function jt() {
|
|
2424
2709
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
2425
2710
|
if (e) return {
|
|
2426
2711
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -2442,9 +2727,9 @@ function mt() {
|
|
|
2442
2727
|
waitForLive: !0
|
|
2443
2728
|
};
|
|
2444
2729
|
}
|
|
2445
|
-
async function
|
|
2446
|
-
let e =
|
|
2447
|
-
|
|
2730
|
+
async function Mt() {
|
|
2731
|
+
let e = jt();
|
|
2732
|
+
Pt();
|
|
2448
2733
|
let t = document.createElement("video");
|
|
2449
2734
|
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);
|
|
2450
2735
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -2499,12 +2784,12 @@ async function ht() {
|
|
|
2499
2784
|
code: e.code,
|
|
2500
2785
|
message: e.message
|
|
2501
2786
|
})), e.on("autoplayblocked", () => {
|
|
2502
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
2787
|
+
i({ type: "oddin:autoplayblocked" }), Nt(t, e);
|
|
2503
2788
|
});
|
|
2504
2789
|
}, s = async (r) => {
|
|
2505
2790
|
a?.destroy(), a = null;
|
|
2506
2791
|
try {
|
|
2507
|
-
let n = await
|
|
2792
|
+
let n = await Dt({
|
|
2508
2793
|
video: t,
|
|
2509
2794
|
baseUrl: e.baseUrl,
|
|
2510
2795
|
matchUrn: r,
|
|
@@ -2565,7 +2850,7 @@ async function ht() {
|
|
|
2565
2850
|
a?.retry();
|
|
2566
2851
|
break;
|
|
2567
2852
|
case "oddin:load":
|
|
2568
|
-
typeof e.matchUrn == "string" &&
|
|
2853
|
+
typeof e.matchUrn == "string" && At.test(e.matchUrn) && s(e.matchUrn);
|
|
2569
2854
|
break;
|
|
2570
2855
|
case "oddin:destroy": c();
|
|
2571
2856
|
}
|
|
@@ -2577,18 +2862,18 @@ async function ht() {
|
|
|
2577
2862
|
protocol: 1
|
|
2578
2863
|
});
|
|
2579
2864
|
}
|
|
2580
|
-
function
|
|
2865
|
+
function Nt(e, t) {
|
|
2581
2866
|
if (document.getElementById("havik-tap")) return;
|
|
2582
2867
|
let n = document.createElement("button");
|
|
2583
2868
|
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", () => {
|
|
2584
2869
|
n.remove(), t.play();
|
|
2585
2870
|
}), document.body.appendChild(n);
|
|
2586
2871
|
}
|
|
2587
|
-
function
|
|
2872
|
+
function Pt() {
|
|
2588
2873
|
let e = document.createElement("style");
|
|
2589
2874
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
2590
2875
|
}
|
|
2591
2876
|
//#endregion
|
|
2592
|
-
export {
|
|
2877
|
+
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 };
|
|
2593
2878
|
|
|
2594
2879
|
//# sourceMappingURL=index.js.map
|