@oddin-gg/havik-player 2.16.12 → 2.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/havik-player.global.js +17 -17
- package/dist/havik-player.global.js.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +343 -269
- package/dist/index.js.map +1 -1
- package/docs/API.md +23 -19
- package/embed/index.html +1 -1
- package/examples/vanilla.html +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -174,7 +174,7 @@ function ue(e, t) {
|
|
|
174
174
|
t?.addEventListener("abort", a, { once: !0 });
|
|
175
175
|
});
|
|
176
176
|
}
|
|
177
|
-
async function
|
|
177
|
+
async function v(e, t, r) {
|
|
178
178
|
let i = ae(t), a = Date.now(), s = i.timeoutMs == null ? Infinity : a + i.timeoutMs, c = 0, l;
|
|
179
179
|
for (;;) {
|
|
180
180
|
if (r?.aborted) throw new n("ABORTED", 0, "wait-for-live aborted");
|
|
@@ -200,21 +200,21 @@ async function de(e, t, r) {
|
|
|
200
200
|
}
|
|
201
201
|
//#endregion
|
|
202
202
|
//#region src/core/resolve.ts
|
|
203
|
-
async function
|
|
203
|
+
async function y(e) {
|
|
204
204
|
if (!e.matchUrn || typeof e.matchUrn != "string") throw new n("INVALID_URN", 0, "resolveStream: a non-empty matchUrn is required");
|
|
205
205
|
let t = await p(d(e.baseUrl, `/v1/playback/${encodeURIComponent(e.matchUrn)}`), {
|
|
206
206
|
credential: e.credential,
|
|
207
207
|
signal: e.signal,
|
|
208
208
|
apiHeaders: e.apiHeaders
|
|
209
209
|
});
|
|
210
|
-
if (!t.ok) throw await
|
|
211
|
-
return
|
|
210
|
+
if (!t.ok) throw await de(t);
|
|
211
|
+
return me(await t.json(), e.matchUrn);
|
|
212
212
|
}
|
|
213
|
-
function
|
|
214
|
-
let t = () =>
|
|
215
|
-
return e.waitForLive ?
|
|
213
|
+
function b(e) {
|
|
214
|
+
let t = () => y(e);
|
|
215
|
+
return e.waitForLive ? v(t, e.waitForLive, e.signal) : t();
|
|
216
216
|
}
|
|
217
|
-
async function
|
|
217
|
+
async function de(e) {
|
|
218
218
|
let t = f(e.headers.get("retry-after")), i = e.headers.get("x-request-id") ?? e.headers.get("x-amzn-requestid") ?? void 0, a = e.statusText || `HTTP ${e.status}`, o, s;
|
|
219
219
|
try {
|
|
220
220
|
let t = await e.json();
|
|
@@ -230,7 +230,7 @@ async function fe(e) {
|
|
|
230
230
|
liveStartsAtMs: s
|
|
231
231
|
});
|
|
232
232
|
}
|
|
233
|
-
var
|
|
233
|
+
var fe = /* @__PURE__ */ new Set([
|
|
234
234
|
"matchUrn",
|
|
235
235
|
"protocol",
|
|
236
236
|
"drmEnabled",
|
|
@@ -241,7 +241,7 @@ var pe = /* @__PURE__ */ new Set([
|
|
|
241
241
|
"expiresAt",
|
|
242
242
|
"analytics"
|
|
243
243
|
]);
|
|
244
|
-
function
|
|
244
|
+
function x(e, t) {
|
|
245
245
|
let r;
|
|
246
246
|
try {
|
|
247
247
|
r = new URL(t);
|
|
@@ -251,7 +251,7 @@ function b(e, t) {
|
|
|
251
251
|
if (r.protocol !== "https:" && r.protocol !== "http:") throw new n("INTERNAL", 0, `playback ${e} has a disallowed scheme: ${r.protocol}`);
|
|
252
252
|
return t;
|
|
253
253
|
}
|
|
254
|
-
function
|
|
254
|
+
function pe(e) {
|
|
255
255
|
if (e !== void 0) {
|
|
256
256
|
if (typeof e == "string" && !e.endsWith("/")) try {
|
|
257
257
|
let t = new URL(e);
|
|
@@ -260,41 +260,41 @@ function me(e) {
|
|
|
260
260
|
g(`server analytics.endpoint ${JSON.stringify(e)} ignored: not a bare https origin.`);
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
|
-
function
|
|
263
|
+
function me(e, t) {
|
|
264
264
|
if (!e.manifestUrl) throw new n("INTERNAL", 0, "playback response is missing manifestUrl");
|
|
265
265
|
let r = e.drmEnabled ?? !!e.drm, i = {
|
|
266
266
|
matchUrn: e.matchUrn ?? t,
|
|
267
267
|
protocol: "hls",
|
|
268
268
|
drmEnabled: r,
|
|
269
|
-
manifestUrl:
|
|
269
|
+
manifestUrl: x("manifestUrl", e.manifestUrl),
|
|
270
270
|
serverTime: e.serverTime ?? ""
|
|
271
271
|
};
|
|
272
272
|
if (e.liveStartsAt && (i.liveStartsAt = e.liveStartsAt), typeof e.analytics?.sid == "string" && e.analytics.sid) {
|
|
273
273
|
i.analytics = { sid: e.analytics.sid };
|
|
274
|
-
let t =
|
|
274
|
+
let t = pe(e.analytics.endpoint);
|
|
275
275
|
t && (i.analytics.endpoint = t);
|
|
276
276
|
}
|
|
277
277
|
if (r && e.drm) {
|
|
278
278
|
let t = {};
|
|
279
|
-
e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl:
|
|
280
|
-
licenseUrl:
|
|
281
|
-
certificateUrl:
|
|
279
|
+
e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl: x("widevine licenseUrl", e.drm.widevine.licenseUrl) }), e.drm.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && (t.fairplay = {
|
|
280
|
+
licenseUrl: x("fairplay licenseUrl", e.drm.fairplay.licenseUrl),
|
|
281
|
+
certificateUrl: x("fairplay certificateUrl", e.drm.fairplay.certificateUrl)
|
|
282
282
|
}), (t.widevine || t.fairplay) && (i.drm = t);
|
|
283
283
|
}
|
|
284
284
|
let a = {};
|
|
285
|
-
for (let [t, n] of Object.entries(e))
|
|
285
|
+
for (let [t, n] of Object.entries(e)) fe.has(t) || (a[t] = n);
|
|
286
286
|
return Object.keys(a).length > 0 && (i.extensions = a), i;
|
|
287
287
|
}
|
|
288
288
|
//#endregion
|
|
289
289
|
//#region src/core/fullscreen.ts
|
|
290
|
-
function
|
|
290
|
+
function he(e) {
|
|
291
291
|
return e.ownerDocument ?? document;
|
|
292
292
|
}
|
|
293
|
-
function
|
|
293
|
+
function ge(e) {
|
|
294
294
|
return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
|
|
295
295
|
}
|
|
296
296
|
function S(e, t) {
|
|
297
|
-
let n =
|
|
297
|
+
let n = ge(he(e));
|
|
298
298
|
return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
|
|
299
299
|
}
|
|
300
300
|
async function C(e, t) {
|
|
@@ -310,7 +310,7 @@ async function w(e, t) {
|
|
|
310
310
|
n.webkitExitFullscreen?.();
|
|
311
311
|
return;
|
|
312
312
|
}
|
|
313
|
-
let r =
|
|
313
|
+
let r = he(e), i = ge(r);
|
|
314
314
|
i != null && (i === e || t != null && i === t) && (typeof r.exitFullscreen == "function" ? await r.exitFullscreen() : r.webkitExitFullscreen?.());
|
|
315
315
|
}
|
|
316
316
|
//#endregion
|
|
@@ -470,6 +470,7 @@ function T(e) {
|
|
|
470
470
|
clearTimeout(n), t();
|
|
471
471
|
}, { once: !0 });
|
|
472
472
|
}), l = (t) => {
|
|
473
|
+
if (o) return;
|
|
473
474
|
e.onAlive?.();
|
|
474
475
|
let n = "message", r = [];
|
|
475
476
|
for (let e of t.split("\n")) {
|
|
@@ -671,14 +672,14 @@ function I(e) {
|
|
|
671
672
|
function L(e) {
|
|
672
673
|
return (e ?? "").trim().toLowerCase();
|
|
673
674
|
}
|
|
674
|
-
var
|
|
675
|
+
var R = {
|
|
675
676
|
hevc: "hvc1.1.6.L93.90",
|
|
676
677
|
dv: "dvh1.05.06",
|
|
677
678
|
av1: "av01.0.05M.08",
|
|
678
679
|
vp9: "vp09.00.10.08"
|
|
679
|
-
},
|
|
680
|
-
function
|
|
681
|
-
let t = L(e), n =
|
|
680
|
+
}, je = /* @__PURE__ */ new Map(), z = /* @__PURE__ */ new Map();
|
|
681
|
+
function Me(e) {
|
|
682
|
+
let t = L(e), n = je.get(t);
|
|
682
683
|
if (n) return n;
|
|
683
684
|
let r = {
|
|
684
685
|
initDataTypes: ["cenc"],
|
|
@@ -696,23 +697,23 @@ function Ne(e) {
|
|
|
696
697
|
} catch {
|
|
697
698
|
return !1;
|
|
698
699
|
}
|
|
699
|
-
})().then((e) => (
|
|
700
|
-
return
|
|
700
|
+
})().then((e) => (z.set(t, e), e));
|
|
701
|
+
return je.set(t, i), i;
|
|
701
702
|
}
|
|
702
|
-
function
|
|
703
|
-
if (j()) for (let e of Object.values(
|
|
703
|
+
function Ne() {
|
|
704
|
+
if (j()) for (let e of Object.values(R)) Me(e);
|
|
704
705
|
}
|
|
705
|
-
function
|
|
706
|
+
function Pe(e) {
|
|
706
707
|
let t = I(e);
|
|
707
|
-
if (t) return t === "avc" ? !0 :
|
|
708
|
+
if (t) return t === "avc" ? !0 : z.get(L(e)) ?? z.get(L(R[t]));
|
|
708
709
|
}
|
|
709
710
|
//#endregion
|
|
710
711
|
//#region src/core/drm/support.ts
|
|
711
|
-
var
|
|
712
|
+
var Fe = 5e3, Ie = "video/mp4; codecs=\"avc1.42E01E\"", Le = "audio/mp4; codecs=\"mp4a.40.2\"", Re = {
|
|
712
713
|
widevine: ["com.widevine.alpha"],
|
|
713
714
|
fairplay: ["com.apple.fps"]
|
|
714
715
|
};
|
|
715
|
-
function
|
|
716
|
+
function ze(e) {
|
|
716
717
|
return e === "fairplay" ? [{
|
|
717
718
|
initDataTypes: [
|
|
718
719
|
"sinf",
|
|
@@ -720,30 +721,30 @@ function Be(e) {
|
|
|
720
721
|
"cenc"
|
|
721
722
|
],
|
|
722
723
|
videoCapabilities: [{
|
|
723
|
-
contentType:
|
|
724
|
+
contentType: Ie,
|
|
724
725
|
robustness: "",
|
|
725
726
|
encryptionScheme: "cbcs"
|
|
726
727
|
}],
|
|
727
728
|
audioCapabilities: [{
|
|
728
|
-
contentType:
|
|
729
|
+
contentType: Le,
|
|
729
730
|
robustness: "",
|
|
730
731
|
encryptionScheme: "cbcs"
|
|
731
732
|
}]
|
|
732
733
|
}] : N("com.widevine.alpha", [{
|
|
733
734
|
initDataTypes: ["cenc"],
|
|
734
735
|
videoCapabilities: [{
|
|
735
|
-
contentType:
|
|
736
|
+
contentType: Ie,
|
|
736
737
|
robustness: F.video,
|
|
737
738
|
encryptionScheme: F.scheme
|
|
738
739
|
}],
|
|
739
740
|
audioCapabilities: [{
|
|
740
|
-
contentType:
|
|
741
|
+
contentType: Le,
|
|
741
742
|
robustness: F.audio,
|
|
742
743
|
encryptionScheme: F.scheme
|
|
743
744
|
}]
|
|
744
745
|
}]);
|
|
745
746
|
}
|
|
746
|
-
function
|
|
747
|
+
function Be(e, t) {
|
|
747
748
|
return new Promise((n, r) => {
|
|
748
749
|
let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
|
|
749
750
|
e.then((e) => {
|
|
@@ -753,8 +754,8 @@ function Ve(e, t) {
|
|
|
753
754
|
});
|
|
754
755
|
});
|
|
755
756
|
}
|
|
756
|
-
async function
|
|
757
|
-
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ??
|
|
757
|
+
async function Ve(e = {}) {
|
|
758
|
+
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Fe, r = {};
|
|
758
759
|
if (typeof window < "u" && window.isSecureContext === !1) return {
|
|
759
760
|
verdict: "insecure-context",
|
|
760
761
|
detail: r
|
|
@@ -766,7 +767,7 @@ async function He(e = {}) {
|
|
|
766
767
|
};
|
|
767
768
|
let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
|
|
768
769
|
for (let e of t) {
|
|
769
|
-
let t =
|
|
770
|
+
let t = Re[e];
|
|
770
771
|
if (!t) {
|
|
771
772
|
r[e] = "unknown system";
|
|
772
773
|
continue;
|
|
@@ -777,7 +778,7 @@ async function He(e = {}) {
|
|
|
777
778
|
break;
|
|
778
779
|
}
|
|
779
780
|
try {
|
|
780
|
-
return await
|
|
781
|
+
return await Be((await Be(i(n, ze(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
|
|
781
782
|
verdict: "supported",
|
|
782
783
|
system: e,
|
|
783
784
|
detail: r
|
|
@@ -801,49 +802,49 @@ async function He(e = {}) {
|
|
|
801
802
|
}
|
|
802
803
|
//#endregion
|
|
803
804
|
//#region src/core/manifest.ts
|
|
804
|
-
var
|
|
805
|
-
function
|
|
806
|
-
return
|
|
805
|
+
var He = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
|
|
806
|
+
function Ue(e) {
|
|
807
|
+
return He.test(e);
|
|
807
808
|
}
|
|
808
809
|
//#endregion
|
|
809
810
|
//#region src/core/env.ts
|
|
810
|
-
var
|
|
811
|
+
var We = {
|
|
811
812
|
integration: "https://feed-dev.oddin-video.gg",
|
|
812
813
|
production: "https://feed.oddin-video.gg"
|
|
813
814
|
};
|
|
814
|
-
function
|
|
815
|
-
let t = Object.prototype.hasOwnProperty.call(
|
|
815
|
+
function Ge(e) {
|
|
816
|
+
let t = Object.prototype.hasOwnProperty.call(We, e) ? We[e] : void 0;
|
|
816
817
|
if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
|
|
817
818
|
return t;
|
|
818
819
|
}
|
|
819
820
|
//#endregion
|
|
820
821
|
//#region src/core/stats.ts
|
|
821
|
-
var
|
|
822
|
-
function
|
|
822
|
+
var Ke = { droppedFrames: 0 };
|
|
823
|
+
function qe(e) {
|
|
823
824
|
try {
|
|
824
825
|
return new URL(e).host;
|
|
825
826
|
} catch {
|
|
826
827
|
return "";
|
|
827
828
|
}
|
|
828
829
|
}
|
|
829
|
-
var
|
|
830
|
-
function
|
|
830
|
+
var Je = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
|
|
831
|
+
function Ye(e) {
|
|
831
832
|
if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
|
|
832
833
|
let t = "", n = -1, r = performance.getEntriesByType("resource");
|
|
833
|
-
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" ||
|
|
834
|
-
let e =
|
|
834
|
+
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || Je.test(i.name)) && i.startTime >= n) {
|
|
835
|
+
let e = qe(i.name);
|
|
835
836
|
e && (t = e, n = i.startTime);
|
|
836
837
|
}
|
|
837
838
|
return t;
|
|
838
839
|
}
|
|
839
|
-
function
|
|
840
|
+
function B(e) {
|
|
840
841
|
let t = e.getVideoPlaybackQuality?.();
|
|
841
842
|
return {
|
|
842
843
|
dropped: t?.droppedVideoFrames ?? 0,
|
|
843
844
|
totalFrames: t?.totalVideoFrames ?? 0
|
|
844
845
|
};
|
|
845
846
|
}
|
|
846
|
-
var
|
|
847
|
+
var Xe = class {
|
|
847
848
|
video;
|
|
848
849
|
baseFrames = 0;
|
|
849
850
|
baseDropped = 0;
|
|
@@ -853,7 +854,7 @@ var B = class {
|
|
|
853
854
|
this.video = e;
|
|
854
855
|
}
|
|
855
856
|
read() {
|
|
856
|
-
let e =
|
|
857
|
+
let e = B(this.video);
|
|
857
858
|
return e.totalFrames < this.lastFrames && (this.baseFrames += this.lastFrames), e.dropped < this.lastDropped && (this.baseDropped += this.lastDropped), this.lastFrames = e.totalFrames, this.lastDropped = e.dropped, {
|
|
858
859
|
dropped: this.baseDropped + e.dropped,
|
|
859
860
|
totalFrames: this.baseFrames + e.totalFrames
|
|
@@ -883,8 +884,8 @@ function Ze(e, t) {
|
|
|
883
884
|
}
|
|
884
885
|
//#endregion
|
|
885
886
|
//#region src/core/engine/native.ts
|
|
886
|
-
var Qe = 2e3, $e = 3, V = 500, et = 6e3, tt = .25, nt = 250, rt = .05, it = 4;
|
|
887
|
-
function
|
|
887
|
+
var Qe = 2e3, $e = 3, V = 500, et = 6e3, tt = .25, nt = 250, rt = .05, it = 4, at = 12e3, ot = .25, st = 1e3;
|
|
888
|
+
function ct(e) {
|
|
888
889
|
try {
|
|
889
890
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
890
891
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -900,7 +901,7 @@ function U() {
|
|
|
900
901
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
901
902
|
return e || t;
|
|
902
903
|
}
|
|
903
|
-
function
|
|
904
|
+
function lt() {
|
|
904
905
|
if (typeof navigator > "u" || !U()) return !1;
|
|
905
906
|
let e = navigator.userAgent ?? "";
|
|
906
907
|
return /iPhone|iPad|iPod/.test(e) ? !0 : /Macintosh/.test(e) && typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1;
|
|
@@ -922,6 +923,10 @@ var W = class {
|
|
|
922
923
|
onEdgeReset = null;
|
|
923
924
|
lastBufferedEnd = null;
|
|
924
925
|
bufferedAdvancedAt = null;
|
|
926
|
+
lastSeekableEnd = null;
|
|
927
|
+
edgeStampedAt = null;
|
|
928
|
+
lastTickAt = null;
|
|
929
|
+
endedEmitted = !1;
|
|
925
930
|
fairplayKeyIV;
|
|
926
931
|
loadStarted;
|
|
927
932
|
preloadTouched = !1;
|
|
@@ -931,12 +936,12 @@ var W = class {
|
|
|
931
936
|
frameCounter;
|
|
932
937
|
detachFrames = null;
|
|
933
938
|
constructor(e) {
|
|
934
|
-
this.deps = e, this.frameCounter = new
|
|
939
|
+
this.deps = e, this.frameCounter = new Xe(e.video), this.loadStarted = e.deferLoad !== !0, this.builtAt = typeof performance < "u" ? performance.now() : 0;
|
|
935
940
|
}
|
|
936
941
|
async load() {
|
|
937
942
|
this.detachFrames ??= this.frameCounter.attach();
|
|
938
943
|
let { video: e, descriptor: t, emit: r } = this.deps;
|
|
939
|
-
if (this.watchRefocus(), this.watchBufferedEnd(), this.loadStarted || (this.preloadTouched = !0, this.savedPreload = e.getAttribute("preload"), e.preload = "none"), t.drmEnabled) {
|
|
944
|
+
if (this.endedEmitted = !1, this.watchRefocus(), this.watchBufferedEnd(), this.loadStarted || (this.preloadTouched = !0, this.savedPreload = e.getAttribute("preload"), e.preload = "none"), t.drmEnabled) {
|
|
940
945
|
if (!t.drm?.fairplay) {
|
|
941
946
|
r({
|
|
942
947
|
type: "error",
|
|
@@ -952,7 +957,7 @@ var W = class {
|
|
|
952
957
|
type: "error",
|
|
953
958
|
error: new n("INTERNAL", 0, "native HLS playback error"),
|
|
954
959
|
fatal: !0
|
|
955
|
-
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src =
|
|
960
|
+
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = dt(t.manifestUrl, t.analytics?.sid), e.load();
|
|
956
961
|
}
|
|
957
962
|
startLoad() {
|
|
958
963
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -974,7 +979,7 @@ var W = class {
|
|
|
974
979
|
});
|
|
975
980
|
this.onEncrypted = (n) => {
|
|
976
981
|
let i = n;
|
|
977
|
-
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
982
|
+
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = ct(i.initData), (async () => {
|
|
978
983
|
try {
|
|
979
984
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
980
985
|
initDataTypes: [i.initDataType],
|
|
@@ -1073,7 +1078,7 @@ var W = class {
|
|
|
1073
1078
|
droppedFrames: t.dropped,
|
|
1074
1079
|
decodedFrames: t.totalFrames
|
|
1075
1080
|
};
|
|
1076
|
-
if (this.cdnHost ||=
|
|
1081
|
+
if (this.cdnHost ||= Ye(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
|
|
1077
1082
|
n.isLive = !0;
|
|
1078
1083
|
let t = this.liveEdgeEstimate(), r = t == null ? NaN : t - e.currentTime;
|
|
1079
1084
|
Number.isFinite(r) && (n.atLiveEdge = r <= it, !e.paused && r >= 0 && (n.latencySeconds = r));
|
|
@@ -1119,21 +1124,43 @@ var W = class {
|
|
|
1119
1124
|
watchBufferedEnd() {
|
|
1120
1125
|
if (this.edgeTimer != null) return;
|
|
1121
1126
|
let { video: e } = this.deps;
|
|
1122
|
-
this.onEdgeReset = () => {
|
|
1123
|
-
this.lastBufferedEnd = null, this.bufferedAdvancedAt = null;
|
|
1127
|
+
this.onEdgeReset = (e) => {
|
|
1128
|
+
this.lastBufferedEnd = null, this.bufferedAdvancedAt = null, e.type === "emptied" && this.resetEndStale();
|
|
1124
1129
|
}, e.addEventListener("seeking", this.onEdgeReset), e.addEventListener("emptied", this.onEdgeReset), this.edgeTimer = setInterval(() => {
|
|
1125
1130
|
if (e.duration !== Infinity) return;
|
|
1126
|
-
|
|
1131
|
+
this.checkEndStale();
|
|
1132
|
+
let t = ut(e, e.currentTime);
|
|
1127
1133
|
t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >= rt) && (this.bufferedAdvancedAt = G()), this.lastBufferedEnd = t);
|
|
1128
1134
|
}, nt);
|
|
1129
1135
|
}
|
|
1136
|
+
checkEndStale() {
|
|
1137
|
+
if (this.endedEmitted) return;
|
|
1138
|
+
let e = G(), t = this.lastTickAt == null ? 0 : e - this.lastTickAt;
|
|
1139
|
+
this.lastTickAt = e;
|
|
1140
|
+
let n = this.liveEnd();
|
|
1141
|
+
if (n == null) return;
|
|
1142
|
+
let r = this.lastSeekableEnd == null || Math.abs(n - this.lastSeekableEnd) >= ot;
|
|
1143
|
+
this.lastSeekableEnd = n;
|
|
1144
|
+
let i = this.deps.video, a = typeof document < "u" && document.visibilityState === "hidden";
|
|
1145
|
+
if (r || t > st || a || i.paused) {
|
|
1146
|
+
this.edgeStampedAt = e;
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
e - (this.edgeStampedAt ?? e) > at && (this.endedEmitted = !0, this.deps.emit({
|
|
1150
|
+
type: "ended",
|
|
1151
|
+
reason: "stalled"
|
|
1152
|
+
}));
|
|
1153
|
+
}
|
|
1154
|
+
resetEndStale() {
|
|
1155
|
+
this.lastSeekableEnd = null, this.edgeStampedAt = null, this.lastTickAt = null;
|
|
1156
|
+
}
|
|
1130
1157
|
unwatchBufferedEnd() {
|
|
1131
|
-
this.edgeTimer != null && clearInterval(this.edgeTimer), this.edgeTimer = null, this.onEdgeReset &&= (this.deps.video.removeEventListener("seeking", this.onEdgeReset), this.deps.video.removeEventListener("emptied", this.onEdgeReset), null), this.lastBufferedEnd = null, this.bufferedAdvancedAt = null;
|
|
1158
|
+
this.edgeTimer != null && clearInterval(this.edgeTimer), this.edgeTimer = null, this.onEdgeReset &&= (this.deps.video.removeEventListener("seeking", this.onEdgeReset), this.deps.video.removeEventListener("emptied", this.onEdgeReset), null), this.resetEndStale(), this.lastBufferedEnd = null, this.bufferedAdvancedAt = null;
|
|
1132
1159
|
}
|
|
1133
1160
|
liveEdgeEstimate() {
|
|
1134
1161
|
let e = this.deps.video;
|
|
1135
1162
|
if (e.duration !== Infinity) return null;
|
|
1136
|
-
let t = this.liveEnd(), n =
|
|
1163
|
+
let t = this.liveEnd(), n = ut(e, e.currentTime) ?? this.lastBufferedEnd;
|
|
1137
1164
|
if (n != null) {
|
|
1138
1165
|
let e = this.bufferedAdvancedAt, r = n + (e == null ? 0 : Math.max(0, (G() - e) / 1e3));
|
|
1139
1166
|
(t == null || r > t) && (t = r);
|
|
@@ -1170,7 +1197,7 @@ var W = class {
|
|
|
1170
1197
|
function G() {
|
|
1171
1198
|
return typeof performance < "u" ? performance.now() : Date.now();
|
|
1172
1199
|
}
|
|
1173
|
-
function
|
|
1200
|
+
function ut(e, t) {
|
|
1174
1201
|
let n = e.buffered;
|
|
1175
1202
|
if (!n || !Number.isFinite(t)) return null;
|
|
1176
1203
|
for (let e = 0; e < n.length; e += 1) if (n.start(e) <= t + .1 && n.end(e) > t) {
|
|
@@ -1179,7 +1206,7 @@ function st(e, t) {
|
|
|
1179
1206
|
}
|
|
1180
1207
|
return null;
|
|
1181
1208
|
}
|
|
1182
|
-
function
|
|
1209
|
+
function dt(e, t) {
|
|
1183
1210
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
1184
1211
|
}
|
|
1185
1212
|
//#endregion
|
|
@@ -1196,8 +1223,8 @@ function K(e, t = Date.now()) {
|
|
|
1196
1223
|
}
|
|
1197
1224
|
//#endregion
|
|
1198
1225
|
//#region src/core/engine/prefetch.ts
|
|
1199
|
-
var
|
|
1200
|
-
function
|
|
1226
|
+
var ft = 15e3, pt = 5e3, mt = 6;
|
|
1227
|
+
function ht(e) {
|
|
1201
1228
|
try {
|
|
1202
1229
|
let t = new URL(e);
|
|
1203
1230
|
return t.searchParams.delete("CMCD"), t.toString();
|
|
@@ -1205,7 +1232,7 @@ function ft(e) {
|
|
|
1205
1232
|
return e;
|
|
1206
1233
|
}
|
|
1207
1234
|
}
|
|
1208
|
-
var
|
|
1235
|
+
var gt = class {
|
|
1209
1236
|
cmcd;
|
|
1210
1237
|
entries = /* @__PURE__ */ new Map();
|
|
1211
1238
|
keyed = /* @__PURE__ */ new Set();
|
|
@@ -1228,10 +1255,10 @@ var pt = class {
|
|
|
1228
1255
|
}
|
|
1229
1256
|
prefetch(e, t, n) {
|
|
1230
1257
|
if (!this.isActive(t)) return;
|
|
1231
|
-
let r =
|
|
1258
|
+
let r = ht(e);
|
|
1232
1259
|
if (this.entries.has(r)) return;
|
|
1233
1260
|
let i = this.perTrack.get(t) ?? 0;
|
|
1234
|
-
if (i >=
|
|
1261
|
+
if (i >= mt) return;
|
|
1235
1262
|
this.perTrack.set(t, i + 1);
|
|
1236
1263
|
let a = new AbortController(), o = {
|
|
1237
1264
|
started: performance.now(),
|
|
@@ -1245,10 +1272,10 @@ var pt = class {
|
|
|
1245
1272
|
signal: a.signal
|
|
1246
1273
|
}).then(async (e) => (o.first = performance.now(), e.ok ? e.arrayBuffer() : null)).catch(() => null), this.entries.set(r, o), this.stats.started += 1, setTimeout(() => {
|
|
1247
1274
|
this.entries.get(r) === o && (this.entries.delete(r), a.abort(), this.stats.expired += 1);
|
|
1248
|
-
},
|
|
1275
|
+
}, ft);
|
|
1249
1276
|
}
|
|
1250
1277
|
take(e) {
|
|
1251
|
-
let t =
|
|
1278
|
+
let t = ht(e), n = this.entries.get(t);
|
|
1252
1279
|
return n && this.entries.delete(t), n;
|
|
1253
1280
|
}
|
|
1254
1281
|
destroy() {
|
|
@@ -1268,13 +1295,13 @@ var pt = class {
|
|
|
1268
1295
|
}
|
|
1269
1296
|
}
|
|
1270
1297
|
};
|
|
1271
|
-
function
|
|
1298
|
+
function _t(t) {
|
|
1272
1299
|
let n = e.DefaultConfig?.loader;
|
|
1273
1300
|
if (typeof n != "function") return;
|
|
1274
1301
|
class r extends n {
|
|
1275
1302
|
served = !1;
|
|
1276
1303
|
cancelled = !1;
|
|
1277
|
-
stats =
|
|
1304
|
+
stats = vt();
|
|
1278
1305
|
load(e, n, r) {
|
|
1279
1306
|
let i = e.rangeEnd ? void 0 : t.take(e.url);
|
|
1280
1307
|
if (!i) {
|
|
@@ -1282,7 +1309,7 @@ function mt(t) {
|
|
|
1282
1309
|
return;
|
|
1283
1310
|
}
|
|
1284
1311
|
this.served = !0;
|
|
1285
|
-
let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs ||
|
|
1312
|
+
let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs || pt, s = setTimeout(() => {
|
|
1286
1313
|
!this.cancelled && this.served && (i.abort.abort(), t.stats.failed += 1, this.served = !1, super.load(e, n, r));
|
|
1287
1314
|
}, o);
|
|
1288
1315
|
i.bytes.then((o) => {
|
|
@@ -1309,7 +1336,7 @@ function mt(t) {
|
|
|
1309
1336
|
}
|
|
1310
1337
|
return r;
|
|
1311
1338
|
}
|
|
1312
|
-
function
|
|
1339
|
+
function vt() {
|
|
1313
1340
|
return {
|
|
1314
1341
|
aborted: !1,
|
|
1315
1342
|
loaded: 0,
|
|
@@ -1333,10 +1360,10 @@ function ht() {
|
|
|
1333
1360
|
}
|
|
1334
1361
|
};
|
|
1335
1362
|
}
|
|
1336
|
-
function
|
|
1363
|
+
function q(e) {
|
|
1337
1364
|
return e === "audio" ? "audio" : "main";
|
|
1338
1365
|
}
|
|
1339
|
-
function
|
|
1366
|
+
function yt(e, t) {
|
|
1340
1367
|
let n = [];
|
|
1341
1368
|
t.initSegment?.url && !t.initSegment.data && n.push({
|
|
1342
1369
|
url: t.initSegment.url,
|
|
@@ -1355,24 +1382,24 @@ function _t(e, t) {
|
|
|
1355
1382
|
}
|
|
1356
1383
|
//#endregion
|
|
1357
1384
|
//#region src/core/engine/hls.ts
|
|
1358
|
-
function
|
|
1385
|
+
function bt() {
|
|
1359
1386
|
return e.isSupported();
|
|
1360
1387
|
}
|
|
1361
|
-
var
|
|
1362
|
-
function
|
|
1388
|
+
var xt = 3, St = 5, Ct = 3, wt = 1e4, Tt = 3e4, Et = 12e3, Dt = 3e3, Ot = .02, kt = 6e3, At = .5, jt = 3, Mt = .5, Nt = 1.1, Pt = .25, Ft = 5e3, It = 4e3, Lt = 2, Rt = 5, zt = 2, Bt = 2, Vt = 4, Ht = 4, Ut = 2e3, Wt = 3e4, Gt = .2, Kt = 30, qt = 2, Jt = 2, Yt = 9, Xt = .5, Zt = 64;
|
|
1389
|
+
function Qt(e) {
|
|
1363
1390
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
1364
1391
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
1365
1392
|
return;
|
|
1366
1393
|
}
|
|
1367
|
-
e.liveSyncDuration ??=
|
|
1368
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
1369
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
1394
|
+
e.liveSyncDuration ??= Jt;
|
|
1395
|
+
let t = Math.max(12, e.liveSyncDuration + Yt);
|
|
1396
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), $t(e, e.liveSyncDuration);
|
|
1370
1397
|
}
|
|
1371
|
-
function
|
|
1398
|
+
function $t(e, t) {
|
|
1372
1399
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
1373
1400
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
1374
1401
|
}
|
|
1375
|
-
var
|
|
1402
|
+
var en = class {
|
|
1376
1403
|
name = "hls";
|
|
1377
1404
|
hls = null;
|
|
1378
1405
|
deps;
|
|
@@ -1438,6 +1465,8 @@ var Qt = class {
|
|
|
1438
1465
|
capTimer = null;
|
|
1439
1466
|
sizeCapLevel = null;
|
|
1440
1467
|
bitrateCapLevel = -1;
|
|
1468
|
+
pushedCapLevel = -1;
|
|
1469
|
+
pushedCapReason = null;
|
|
1441
1470
|
fpsCapBitrate = null;
|
|
1442
1471
|
fpsCapFailedHeight = null;
|
|
1443
1472
|
fpsCapManaged = !0;
|
|
@@ -1452,7 +1481,7 @@ var Qt = class {
|
|
|
1452
1481
|
frameCounter;
|
|
1453
1482
|
detachFrames = null;
|
|
1454
1483
|
constructor(e) {
|
|
1455
|
-
this.deps = e, this.frameCounter = new
|
|
1484
|
+
this.deps = e, this.frameCounter = new Xe(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
1456
1485
|
}
|
|
1457
1486
|
async load() {
|
|
1458
1487
|
this.detachFrames ??= this.frameCounter.attach();
|
|
@@ -1465,7 +1494,7 @@ var Qt = class {
|
|
|
1465
1494
|
});
|
|
1466
1495
|
return;
|
|
1467
1496
|
}
|
|
1468
|
-
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ae(r),
|
|
1497
|
+
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ae(r), Ne()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
|
|
1469
1498
|
let e = this.hls;
|
|
1470
1499
|
if (document.visibilityState !== "visible" || !e) return;
|
|
1471
1500
|
let t = e.liveSyncPosition;
|
|
@@ -1488,7 +1517,7 @@ var Qt = class {
|
|
|
1488
1517
|
}
|
|
1489
1518
|
this.loadSuspended = !0;
|
|
1490
1519
|
}
|
|
1491
|
-
},
|
|
1520
|
+
}, Ft));
|
|
1492
1521
|
}
|
|
1493
1522
|
resumeLoading() {
|
|
1494
1523
|
if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.resetChaseWindow(), this.resetFrameDropWindow(), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
|
|
@@ -1520,7 +1549,7 @@ var Qt = class {
|
|
|
1520
1549
|
let t = e.liveSyncPosition;
|
|
1521
1550
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1522
1551
|
let { video: n } = this.deps;
|
|
1523
|
-
n.currentTime <= t +
|
|
1552
|
+
n.currentTime <= t + Xt || (n.currentTime = t);
|
|
1524
1553
|
}
|
|
1525
1554
|
reanchorPartTimeline(e, t) {
|
|
1526
1555
|
let { frag: n, part: r } = t;
|
|
@@ -1532,7 +1561,7 @@ var Qt = class {
|
|
|
1532
1561
|
let o = n.sn, s = i.fragments.find((e) => e && e.sn === o) ?? (i.fragmentHint?.sn === o ? i.fragmentHint : void 0);
|
|
1533
1562
|
if (!s) return;
|
|
1534
1563
|
let c = a.startPTS - s.start;
|
|
1535
|
-
if (!(!Number.isFinite(c) || Math.abs(c) <
|
|
1564
|
+
if (!(!Number.isFinite(c) || Math.abs(c) < Ot)) {
|
|
1536
1565
|
for (let e of i.fragments) e && e.setStart(e.start + c);
|
|
1537
1566
|
i.fragmentHint?.setStart(i.fragmentHint.start + c), this.deps.debug === !0 && console.info(`havik-player: LL-HLS timeline re-anchored by ${c >= 0 ? "+" : ""}${c.toFixed(3)}s at sn ${n.sn} (level ${n.level})`);
|
|
1538
1567
|
}
|
|
@@ -1572,7 +1601,7 @@ var Qt = class {
|
|
|
1572
1601
|
return;
|
|
1573
1602
|
}
|
|
1574
1603
|
let l = this.hls, u, d = new Promise((e) => {
|
|
1575
|
-
u = setTimeout(() => e(void 0),
|
|
1604
|
+
u = setTimeout(() => e(void 0), wt);
|
|
1576
1605
|
});
|
|
1577
1606
|
return Promise.race([c().catch(() => void 0), d]).finally(() => clearTimeout(u)).then((e) => {
|
|
1578
1607
|
if (!this.hls || this.hls !== l) throw Error("havik-player: engine torn down during refresh");
|
|
@@ -1588,20 +1617,20 @@ var Qt = class {
|
|
|
1588
1617
|
...c
|
|
1589
1618
|
};
|
|
1590
1619
|
if (this.prefetch?.destroy(), this.prefetch = null, u && this.deps.mediaDuringKey !== !1 && !f.fLoader) {
|
|
1591
|
-
let e = new
|
|
1620
|
+
let e = new gt({
|
|
1592
1621
|
sessionId: n.analytics?.sid,
|
|
1593
1622
|
contentId: n.matchUrn
|
|
1594
|
-
}), t =
|
|
1623
|
+
}), t = _t(e);
|
|
1595
1624
|
t && (this.prefetch = e, f.fLoader = t);
|
|
1596
1625
|
}
|
|
1597
|
-
|
|
1626
|
+
Qt(f), this.catchUpRate = typeof f.maxLiveSyncPlaybackRate == "number" ? f.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (f.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = f.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = f.autoStartLoad !== !1;
|
|
1598
1627
|
let p = new e(f);
|
|
1599
1628
|
if (this.hls = p, p.on(e.Events.FRAG_PARSED, (e, t) => this.reanchorPartTimeline(p, t)), p.on(e.Events.MANIFEST_PARSED, () => {
|
|
1600
1629
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, u && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && this.dropLevelsWidevineCannotPlay(p), this.measureLadder(p), this.applySizeCap(), this.loadSuspended = !1, t.paused && this.schedulePauseSuspend(), l({ type: "ready" });
|
|
1601
1630
|
}), p.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1602
1631
|
t?.frag?.type === "main" && (this.kickKind !== "dead" && this.clearKick(), (this.mediaRecoveries > 0 || this.networkRecoveries > 0 || this.licenseRecoveries > 0 || this.starvationKicks > 0 || this.starvationRebuilds > 0) && !this.recoveryResetTimer && (this.recoveryResetTimer = setTimeout(() => {
|
|
1603
1632
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1604
|
-
},
|
|
1633
|
+
}, Tt)));
|
|
1605
1634
|
}), p.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1606
1635
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1607
1636
|
}), p.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
@@ -1609,10 +1638,10 @@ var Qt = class {
|
|
|
1609
1638
|
let n = t?.frag?.stats, r = n?.loaded;
|
|
1610
1639
|
typeof r == "number" && (this.bytesLoaded += r), !this.reportedFirstBytes && typeof r == "number" && r > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
|
|
1611
1640
|
let i = n?.loading;
|
|
1612
|
-
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 >
|
|
1641
|
+
i && i.end > 0 && i.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(i.end - i.start))), this.requestTimesMs.length > Zt && this.requestTimesMs.shift());
|
|
1613
1642
|
let a = t?.frag?.url;
|
|
1614
1643
|
if (a) {
|
|
1615
|
-
let e =
|
|
1644
|
+
let e = qe(a);
|
|
1616
1645
|
e && (this.cdnHost = e);
|
|
1617
1646
|
}
|
|
1618
1647
|
}), p.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1626,15 +1655,15 @@ var Qt = class {
|
|
|
1626
1655
|
}), p.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.prefetch) {
|
|
1627
1656
|
let t = this.prefetch;
|
|
1628
1657
|
p.on(e.Events.KEY_LOADING, (e, n) => {
|
|
1629
|
-
let r = n?.frag, i =
|
|
1630
|
-
if (r && t.isActive(i)) for (let e of
|
|
1631
|
-
}), p.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(
|
|
1658
|
+
let r = n?.frag, i = q(r?.type);
|
|
1659
|
+
if (r && t.isActive(i)) for (let e of yt(p, r)) t.prefetch(e.url, i, e.kind);
|
|
1660
|
+
}), p.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(q(n?.frag?.type)));
|
|
1632
1661
|
}
|
|
1633
1662
|
p.on(e.Events.KEY_LOADED, () => {
|
|
1634
1663
|
u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
|
|
1635
1664
|
}), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1636
1665
|
this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.checkFrameDrops();
|
|
1637
|
-
},
|
|
1666
|
+
}, Dt), p.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1638
1667
|
this.renditionSwitches += 1;
|
|
1639
1668
|
let n = this.lastLevelIndex >= 0 ? p.levels[this.lastLevelIndex] : void 0, r = p.levels[t.level];
|
|
1640
1669
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
|
|
@@ -1698,7 +1727,7 @@ var Qt = class {
|
|
|
1698
1727
|
return;
|
|
1699
1728
|
}
|
|
1700
1729
|
this.capTimer && clearTimeout(this.capTimer);
|
|
1701
|
-
let t = e > this.sizeCapLevel ?
|
|
1730
|
+
let t = e > this.sizeCapLevel ? Ut : Wt;
|
|
1702
1731
|
this.capTimer = setTimeout(() => {
|
|
1703
1732
|
this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
|
|
1704
1733
|
}, t);
|
|
@@ -1708,9 +1737,9 @@ var Qt = class {
|
|
|
1708
1737
|
this.ladderHeights = t.length ? [...new Set(t)].sort((e, t) => e - t) : void 0, this.ladderTopBitrateKbps = e.levels.length ? Math.round(Math.max(...e.levels.map((e) => e.bitrate)) / 1e3) : 0;
|
|
1709
1738
|
}
|
|
1710
1739
|
dropLevelsWidevineCannotPlay(e) {
|
|
1711
|
-
this.removeLevelsWhere(e, (e) =>
|
|
1740
|
+
this.removeLevelsWhere(e, (e) => Pe(e) !== !0);
|
|
1712
1741
|
let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && I(e) !== "avc" && !!I(e)));
|
|
1713
|
-
for (let n of t)
|
|
1742
|
+
for (let n of t) Me(n).then((t) => {
|
|
1714
1743
|
t || this.hls !== e || this.removeLevelsWhere(e, (e) => e === n) && (this.measureLadder(e), this.applySizeCap());
|
|
1715
1744
|
});
|
|
1716
1745
|
}
|
|
@@ -1721,7 +1750,7 @@ var Qt = class {
|
|
|
1721
1750
|
a && I(a) && t(a) && (r.push(n), i.add(a));
|
|
1722
1751
|
}), !r.length) return !1;
|
|
1723
1752
|
let a = [...i].join(", ");
|
|
1724
|
-
if (!n.some((e, t) => r.includes(t) ? !1 : !I(e.videoCodec) ||
|
|
1753
|
+
if (!n.some((e, t) => r.includes(t) ? !1 : !I(e.videoCodec) || Pe(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
|
|
1725
1754
|
for (let t = r.length - 1; t >= 0; --t) e.removeLevel(r[t]);
|
|
1726
1755
|
return console.info(`havik-player: skipped ${r.length} rendition(s) Widevine cannot play on this browser (${a})`), !0;
|
|
1727
1756
|
}
|
|
@@ -1735,11 +1764,12 @@ var Qt = class {
|
|
|
1735
1764
|
let e = this.hls;
|
|
1736
1765
|
if (!e) return;
|
|
1737
1766
|
let t = [
|
|
1738
|
-
this.sizeCapLevel ?? -1,
|
|
1739
|
-
this.bitrateCapLevel,
|
|
1740
|
-
this.fpsCapLevel(e)
|
|
1741
|
-
]
|
|
1742
|
-
e
|
|
1767
|
+
["size", this.sizeCapLevel ?? -1],
|
|
1768
|
+
["bitrate", this.bitrateCapLevel],
|
|
1769
|
+
["fps", this.fpsCapLevel(e)]
|
|
1770
|
+
], n = -1, r = null;
|
|
1771
|
+
for (let [e, i] of t) i >= 0 && (n < 0 || i < n) && (n = i, r = e);
|
|
1772
|
+
e.autoLevelCapping = n, this.pushedCapLevel = n, this.pushedCapReason = r;
|
|
1743
1773
|
}
|
|
1744
1774
|
getAudioTracks() {
|
|
1745
1775
|
return this.hls ? this.hls.audioTracks.map((e) => ({
|
|
@@ -1792,7 +1822,14 @@ var Qt = class {
|
|
|
1792
1822
|
if (this.cdnHost && (n.cdnHost = this.cdnHost), this.licenseRequested && (n.keySystem = "widevine", n.drmSecurityLevel = "L3"), e) {
|
|
1793
1823
|
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));
|
|
1794
1824
|
let t = e.currentLevel >= 0 ? e.levels[e.currentLevel] : void 0;
|
|
1795
|
-
t && (n.levelHeight = t.height)
|
|
1825
|
+
t && (n.levelHeight = t.height);
|
|
1826
|
+
let r = e.autoLevelCapping, i = r >= 0 ? e.levels[r] : void 0;
|
|
1827
|
+
if (i && i.height > 0) {
|
|
1828
|
+
n.maxLevelHeight = i.height;
|
|
1829
|
+
let t = e.config ?? {};
|
|
1830
|
+
t.capLevelToPlayerSize !== !0 && t.capLevelOnFPSDrop !== !0 && r === this.pushedCapLevel && this.pushedCapReason && (n.capReason = this.pushedCapReason);
|
|
1831
|
+
}
|
|
1832
|
+
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));
|
|
1796
1833
|
}
|
|
1797
1834
|
return n;
|
|
1798
1835
|
}
|
|
@@ -1819,7 +1856,7 @@ var Qt = class {
|
|
|
1819
1856
|
return;
|
|
1820
1857
|
}
|
|
1821
1858
|
let e = Date.now() - this.lastAdvanceMs;
|
|
1822
|
-
!this.chaseSuspended && e >
|
|
1859
|
+
!this.chaseSuspended && e > kt && this.suspendChasing(), e > Et && this.emitEnded("stalled");
|
|
1823
1860
|
}
|
|
1824
1861
|
resetStarvationWindow() {
|
|
1825
1862
|
this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
|
|
@@ -1834,7 +1871,7 @@ var Qt = class {
|
|
|
1834
1871
|
this.resetStarvationWindow();
|
|
1835
1872
|
return;
|
|
1836
1873
|
}
|
|
1837
|
-
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs <
|
|
1874
|
+
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < kt, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > It, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = B(t), c = o - s, l = c !== this.starvedFrames;
|
|
1838
1875
|
if (this.starvedFrames = c, !a || l) {
|
|
1839
1876
|
(t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
|
|
1840
1877
|
return;
|
|
@@ -1843,12 +1880,12 @@ var Qt = class {
|
|
|
1843
1880
|
this.resetStarvationWindow();
|
|
1844
1881
|
return;
|
|
1845
1882
|
}
|
|
1846
|
-
if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length >
|
|
1883
|
+
if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length > Vt && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= zt && (this.clearKick(), this.starvationRebuilds < Bt)) {
|
|
1847
1884
|
this.starvationRebuilds += 1, this.resetStarvationWindow(), this.clearRecoveryReset(), console.warn("havik-player: restarting the load did not resume video (the wedge is in hls.js state that only a rebuild clears) — rebuilding the player"), this.rebuildInstance("starvation rebuild");
|
|
1848
1885
|
return;
|
|
1849
1886
|
}
|
|
1850
|
-
let u = i && this.starvedTicks >=
|
|
1851
|
-
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >=
|
|
1887
|
+
let u = i && this.starvedTicks >= Lt, d = !i && this.deadTicks >= Vt && this.recentMainFrags.reduce((e, t) => e + t, 0) >= Ht;
|
|
1888
|
+
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= Rt))) {
|
|
1852
1889
|
this.starvationKicks += 1, this.kickPending = !0, this.kickTicks = 0, this.kickKind = d ? "dead" : "quiet", this.clearRecoveryReset(), console.warn(d ? "havik-player: video starved while hls.js keeps loading media it never plays (dead pipeline at the live edge) — restarting the load" : "havik-player: video starved while the live playlist advances (wedged hls.js fragment pipeline) — restarting the load");
|
|
1853
1890
|
try {
|
|
1854
1891
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -1863,7 +1900,7 @@ var Qt = class {
|
|
|
1863
1900
|
let t = e.latency, n = e.targetLatency;
|
|
1864
1901
|
if (typeof t != "number" || typeof n != "number" || !Number.isFinite(t)) return;
|
|
1865
1902
|
let r = t - n;
|
|
1866
|
-
!this.catchUpEngaged && r >
|
|
1903
|
+
!this.catchUpEngaged && r > At ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= At && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
|
|
1867
1904
|
let i = this.catchUpEngaged ? this.catchUpRate : 1;
|
|
1868
1905
|
e.config.maxLiveSyncPlaybackRate !== i && (e.config.maxLiveSyncPlaybackRate = i);
|
|
1869
1906
|
}
|
|
@@ -1884,16 +1921,16 @@ var Qt = class {
|
|
|
1884
1921
|
this.resetFrameDropWindow();
|
|
1885
1922
|
return;
|
|
1886
1923
|
}
|
|
1887
|
-
let { totalFrames: n, dropped: r } =
|
|
1888
|
-
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a <
|
|
1924
|
+
let { totalFrames: n, dropped: r } = B(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
|
|
1925
|
+
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < Kt || o < 0) {
|
|
1889
1926
|
this.fpsBadTicks = 0;
|
|
1890
1927
|
return;
|
|
1891
1928
|
}
|
|
1892
|
-
if (o <=
|
|
1929
|
+
if (o <= Gt * a) {
|
|
1893
1930
|
this.fpsBadTicks = 0;
|
|
1894
1931
|
return;
|
|
1895
1932
|
}
|
|
1896
|
-
if (this.fpsBadTicks += 1, this.fpsBadTicks <
|
|
1933
|
+
if (this.fpsBadTicks += 1, this.fpsBadTicks < qt) return;
|
|
1897
1934
|
this.fpsBadTicks = 0;
|
|
1898
1935
|
let s = e.levels, c = s[e.currentLevel];
|
|
1899
1936
|
if (!c) return;
|
|
@@ -1910,20 +1947,20 @@ var Qt = class {
|
|
|
1910
1947
|
return;
|
|
1911
1948
|
}
|
|
1912
1949
|
let n = e.latency, r = t.playbackRate, i = e.config.maxLiveSyncPlaybackRate;
|
|
1913
|
-
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(
|
|
1950
|
+
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(Nt, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
|
|
1914
1951
|
this.resetChaseWindow();
|
|
1915
1952
|
return;
|
|
1916
1953
|
}
|
|
1917
|
-
if (this.chaseLatency < 0 || this.chaseLatency - n >=
|
|
1954
|
+
if (this.chaseLatency < 0 || this.chaseLatency - n >= Mt) {
|
|
1918
1955
|
this.chaseLatency = n, this.chaseTicks = 0;
|
|
1919
1956
|
return;
|
|
1920
1957
|
}
|
|
1921
|
-
if (this.chaseTicks += 1, this.chaseTicks <
|
|
1958
|
+
if (this.chaseTicks += 1, this.chaseTicks < jt) return;
|
|
1922
1959
|
this.resetChaseWindow();
|
|
1923
1960
|
let a = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
|
|
1924
1961
|
if (!(a > 1)) return;
|
|
1925
1962
|
let o = typeof e.targetLatency == "number" ? e.targetLatency : 0, s = Math.min(n, a - 1);
|
|
1926
|
-
s < o +
|
|
1963
|
+
s < o + Pt || (console.warn(`havik-player: catch-up at ${r}x not gaining on the live edge (latency ${n.toFixed(1)}s); holding at ${s.toFixed(1)}s`), this.liveRetargets += 1, e.targetLatency = s);
|
|
1927
1964
|
}
|
|
1928
1965
|
suspendChasing() {
|
|
1929
1966
|
let e = this.hls;
|
|
@@ -1968,7 +2005,7 @@ var Qt = class {
|
|
|
1968
2005
|
scheduleLicenseRetry(t) {
|
|
1969
2006
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
1970
2007
|
let n = t.response?.code ?? 0;
|
|
1971
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
2008
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= Ct) return !1;
|
|
1972
2009
|
this.licenseRecoveries += 1;
|
|
1973
2010
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
1974
2011
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -2000,7 +2037,7 @@ var Qt = class {
|
|
|
2000
2037
|
return;
|
|
2001
2038
|
}
|
|
2002
2039
|
if (t.type === e.ErrorTypes.NETWORK_ERROR) {
|
|
2003
|
-
if (this.networkRecoveries <
|
|
2040
|
+
if (this.networkRecoveries < St) {
|
|
2004
2041
|
this.networkRecoveries += 1;
|
|
2005
2042
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
2006
2043
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -2017,7 +2054,7 @@ var Qt = class {
|
|
|
2017
2054
|
return;
|
|
2018
2055
|
}
|
|
2019
2056
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
2020
|
-
if (this.mediaRecoveries <
|
|
2057
|
+
if (this.mediaRecoveries < xt) {
|
|
2021
2058
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
2022
2059
|
return;
|
|
2023
2060
|
}
|
|
@@ -2041,19 +2078,19 @@ var Qt = class {
|
|
|
2041
2078
|
let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
|
|
2042
2079
|
return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
|
|
2043
2080
|
}
|
|
2044
|
-
},
|
|
2081
|
+
}, tn = 15e3, nn = 6e5, rn = 3e5, an = 100, J = 1, on = 1e3, sn = 3e4, cn = 1e3, ln = {
|
|
2045
2082
|
inline: "PRESENTATION_INLINE",
|
|
2046
2083
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
2047
2084
|
pip: "PRESENTATION_PIP"
|
|
2048
|
-
},
|
|
2085
|
+
}, un = {
|
|
2049
2086
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
2050
2087
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
2051
2088
|
none: "KEY_SYSTEM_NONE"
|
|
2052
2089
|
};
|
|
2053
|
-
function
|
|
2090
|
+
function dn(e, t) {
|
|
2054
2091
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
2055
2092
|
}
|
|
2056
|
-
var
|
|
2093
|
+
var fn = /* @__PURE__ */ new Set([
|
|
2057
2094
|
"INVALID_URN",
|
|
2058
2095
|
"NOT_FOUND",
|
|
2059
2096
|
"GONE",
|
|
@@ -2063,7 +2100,7 @@ var un = /* @__PURE__ */ new Set([
|
|
|
2063
2100
|
"FORBIDDEN",
|
|
2064
2101
|
"RATE_LIMITED",
|
|
2065
2102
|
"TIMEOUT"
|
|
2066
|
-
]),
|
|
2103
|
+
]), Y = {
|
|
2067
2104
|
idle: "PLAYER_STATE_IDLE",
|
|
2068
2105
|
waiting: "PLAYER_STATE_WAITING",
|
|
2069
2106
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -2073,7 +2110,7 @@ var un = /* @__PURE__ */ new Set([
|
|
|
2073
2110
|
ended: "PLAYER_STATE_ENDED",
|
|
2074
2111
|
error: "PLAYER_STATE_ERROR"
|
|
2075
2112
|
};
|
|
2076
|
-
function
|
|
2113
|
+
function pn(e) {
|
|
2077
2114
|
try {
|
|
2078
2115
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
2079
2116
|
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);
|
|
@@ -2081,8 +2118,8 @@ function dn(e) {
|
|
|
2081
2118
|
return;
|
|
2082
2119
|
}
|
|
2083
2120
|
}
|
|
2084
|
-
var
|
|
2085
|
-
function
|
|
2121
|
+
var mn = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), hn = /* @__PURE__ */ new Set(), X = /* @__PURE__ */ new Set(), Z = /* @__PURE__ */ new Set(), gn = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
|
|
2122
|
+
function _n(e) {
|
|
2086
2123
|
if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
|
|
2087
2124
|
let t;
|
|
2088
2125
|
try {
|
|
@@ -2091,19 +2128,19 @@ function hn(e) {
|
|
|
2091
2128
|
} catch {
|
|
2092
2129
|
return;
|
|
2093
2130
|
}
|
|
2094
|
-
if (
|
|
2095
|
-
|
|
2096
|
-
for (let e of
|
|
2131
|
+
if (hn.has(t) && !X.has(t)) {
|
|
2132
|
+
X.add(t), g(gn(new URL(t).origin));
|
|
2133
|
+
for (let e of Z) e.noteCspBlocked();
|
|
2097
2134
|
}
|
|
2098
2135
|
}
|
|
2099
|
-
function
|
|
2136
|
+
function vn(e, t) {
|
|
2100
2137
|
return g(t, e), { disabledReason: t };
|
|
2101
2138
|
}
|
|
2102
|
-
function
|
|
2103
|
-
if (n) return t && !
|
|
2139
|
+
function yn(e, t, n) {
|
|
2140
|
+
if (n) return t && !mn(t, n) && g(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
|
|
2104
2141
|
if (t) return { endpoint: t };
|
|
2105
|
-
if (t !== void 0) return
|
|
2106
|
-
let r =
|
|
2142
|
+
if (t !== void 0) return vn("empty-endpoint", "analytics is disabled: no QoE beacons will be sent. analytics.endpoint was supplied but empty. Pass a real beacons origin, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, or omit the option to derive it from baseUrl (or analytics: false to opt out).");
|
|
2143
|
+
let r = pn(e);
|
|
2107
2144
|
if (r) return { endpoint: r };
|
|
2108
2145
|
let i;
|
|
2109
2146
|
try {
|
|
@@ -2111,9 +2148,9 @@ function gn(e, t, n) {
|
|
|
2111
2148
|
} catch {
|
|
2112
2149
|
i = e;
|
|
2113
2150
|
}
|
|
2114
|
-
return
|
|
2151
|
+
return vn(i, `analytics is disabled: no QoE beacons will be sent. The beacons endpoint cannot be derived from the baseUrl host "${i}" — the convention is feed[-dev].<domain> → beacons[-dev].<domain>. Pass an explicit endpoint, analytics: { endpoint: 'https://beacons[-dev].<domain>' }, to createPlayer (or analytics: false to opt out deliberately).`);
|
|
2115
2152
|
}
|
|
2116
|
-
var
|
|
2153
|
+
var bn = class {
|
|
2117
2154
|
opts;
|
|
2118
2155
|
url;
|
|
2119
2156
|
cspKey;
|
|
@@ -2195,8 +2232,8 @@ var _n = class {
|
|
|
2195
2232
|
constructor(e) {
|
|
2196
2233
|
this.opts = {
|
|
2197
2234
|
...e,
|
|
2198
|
-
heartbeatMs: e.heartbeatMs ??
|
|
2199
|
-
idleMs: e.idleMs ??
|
|
2235
|
+
heartbeatMs: e.heartbeatMs ?? tn,
|
|
2236
|
+
idleMs: e.idleMs ?? nn
|
|
2200
2237
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
|
|
2201
2238
|
try {
|
|
2202
2239
|
let e = new URL(this.url);
|
|
@@ -2213,11 +2250,11 @@ var _n = class {
|
|
|
2213
2250
|
sdkVersion: this.opts.sdkVersion,
|
|
2214
2251
|
...this.opts.environment
|
|
2215
2252
|
};
|
|
2216
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
2253
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), on), this.lastTickMs = this.now(), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), document.addEventListener("freeze", this.onFreeze), document.addEventListener("resume", this.onResume), this.cspKey && hn.add(this.cspKey), document.addEventListener("securitypolicyviolation", _n), Z.add(this), this.noteCspBlocked(), this.onVisibility());
|
|
2217
2254
|
}
|
|
2218
2255
|
checkSuspension(e) {
|
|
2219
2256
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
2220
|
-
let t = Math.max(this.opts.idleMs,
|
|
2257
|
+
let t = Math.max(this.opts.idleMs, rn);
|
|
2221
2258
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
2222
2259
|
}
|
|
2223
2260
|
syncIdle(e) {
|
|
@@ -2231,21 +2268,21 @@ var _n = class {
|
|
|
2231
2268
|
noteStateChange(e, t, n, r) {
|
|
2232
2269
|
if (this.endedFlag || e === t) return;
|
|
2233
2270
|
let i = this.now();
|
|
2234
|
-
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(
|
|
2271
|
+
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(J, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(J, i - this.startupAnchorMs)), this.isMuted && this.mutedSinceMs === null && (this.mutedSinceMs = i)) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null, this.mutedSinceMs !== null && (this.mutedTotalMs += i - this.mutedSinceMs, this.mutedSinceMs = null)), this.isPlaying = t === "playing", this.syncActive(), t === "waiting" ? this.waitingSinceMs = i : this.waitingSinceMs !== null && (this.waitingTotalMs += i - this.waitingSinceMs, this.waitingSinceMs = null), t === "buffering" && e === "playing") {
|
|
2235
2272
|
this.stallIsSeekInduced = this.seekInduced(i);
|
|
2236
2273
|
let e = !this.isHidden && !this.stallIsSeekInduced;
|
|
2237
|
-
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(
|
|
2274
|
+
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(J, Math.round(this.playingTotalMs)));
|
|
2238
2275
|
} else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
|
|
2239
2276
|
this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
|
|
2240
2277
|
let a = {
|
|
2241
|
-
fromState:
|
|
2242
|
-
toState:
|
|
2243
|
-
presentation:
|
|
2278
|
+
fromState: Y[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2279
|
+
toState: Y[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2280
|
+
presentation: ln[this.presentation]
|
|
2244
2281
|
}, o = this.causeOf(e, t, i);
|
|
2245
2282
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
2246
2283
|
}
|
|
2247
2284
|
seekInduced(e) {
|
|
2248
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
2285
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < cn;
|
|
2249
2286
|
}
|
|
2250
2287
|
causeOf(e, t, n) {
|
|
2251
2288
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -2282,25 +2319,25 @@ var _n = class {
|
|
|
2282
2319
|
}
|
|
2283
2320
|
this.muteChanges += 1;
|
|
2284
2321
|
let r = this.now();
|
|
2285
|
-
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(
|
|
2322
|
+
n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(J, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
|
|
2286
2323
|
}
|
|
2287
2324
|
notePresentation(e) {
|
|
2288
2325
|
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
2289
2326
|
}
|
|
2290
2327
|
notePlayIntent() {
|
|
2291
|
-
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs =
|
|
2328
|
+
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = J), this.firstPlaylistMs > 0 && (this.firstPlaylistMs = J), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = J), this.drmSetupMs > 0 && (this.drmSetupMs = J));
|
|
2292
2329
|
}
|
|
2293
2330
|
noteReady() {
|
|
2294
|
-
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(
|
|
2331
|
+
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(J, this.now() - this.startupAnchorMs));
|
|
2295
2332
|
}
|
|
2296
2333
|
noteFirstPlaylist() {
|
|
2297
|
-
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(
|
|
2334
|
+
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(J, this.now() - this.startupAnchorMs));
|
|
2298
2335
|
}
|
|
2299
2336
|
noteDrmReady() {
|
|
2300
|
-
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(
|
|
2337
|
+
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(J, this.now() - this.startupAnchorMs));
|
|
2301
2338
|
}
|
|
2302
2339
|
noteFirstBytes() {
|
|
2303
|
-
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(
|
|
2340
|
+
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(J, this.now() - this.startupAnchorMs));
|
|
2304
2341
|
}
|
|
2305
2342
|
noteSeek() {
|
|
2306
2343
|
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
@@ -2319,7 +2356,7 @@ var _n = class {
|
|
|
2319
2356
|
let r = n ?? "";
|
|
2320
2357
|
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";
|
|
2321
2358
|
if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
|
|
2322
|
-
if (
|
|
2359
|
+
if (fn.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
2323
2360
|
let i = t ?? "";
|
|
2324
2361
|
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";
|
|
2325
2362
|
}
|
|
@@ -2351,7 +2388,7 @@ var _n = class {
|
|
|
2351
2388
|
let l = t.droppedFrames ?? 0;
|
|
2352
2389
|
l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
|
|
2353
2390
|
let u = t.renditionSwitches ?? 0;
|
|
2354
|
-
u > this.lastSwitches && (o.renditionSwitchesDelta = u - this.lastSwitches), this.lastSwitches = u, n > this.lastHbPlayingMs && (o.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (o.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, i > this.lastHbRebufferMs && (o.rebufferMsDelta = Math.round(i - this.lastHbRebufferMs)), this.lastHbRebufferMs = i, this.rebufferCount > this.lastHbRebufferCount && (o.rebufferCountDelta = this.rebufferCount - this.lastHbRebufferCount), this.lastHbRebufferCount = this.rebufferCount, a > this.lastHbActiveMs && (o.activeMsDelta = Math.round(a - this.lastHbActiveMs)), this.lastHbActiveMs = a, typeof t.latencySeconds == "number" && (o.latencyMs = Math.round(t.latencySeconds * 1e3)), typeof t.targetLatencySeconds == "number" && (o.targetLatencyMs = Math.round(t.targetLatencySeconds * 1e3)), typeof t.bandwidthKbps == "number" && (o.bandwidthEstKbps = t.bandwidthKbps), typeof t.levelHeight == "number" && (o.renditionHeight = t.levelHeight), typeof t.renditionBitrateKbps == "number" && (o.renditionBitrateKbps = t.renditionBitrateKbps), t.atLiveEdge === !0 && (o.atLiveEdge = !0), typeof t.bufferedMs == "number" && t.bufferedMs > 0 && (o.bufferedMs = Math.round(t.bufferedMs)), o.playerState =
|
|
2391
|
+
u > this.lastSwitches && (o.renditionSwitchesDelta = u - this.lastSwitches), this.lastSwitches = u, n > this.lastHbPlayingMs && (o.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (o.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, i > this.lastHbRebufferMs && (o.rebufferMsDelta = Math.round(i - this.lastHbRebufferMs)), this.lastHbRebufferMs = i, this.rebufferCount > this.lastHbRebufferCount && (o.rebufferCountDelta = this.rebufferCount - this.lastHbRebufferCount), this.lastHbRebufferCount = this.rebufferCount, a > this.lastHbActiveMs && (o.activeMsDelta = Math.round(a - this.lastHbActiveMs)), this.lastHbActiveMs = a, typeof t.latencySeconds == "number" && (o.latencyMs = Math.round(t.latencySeconds * 1e3)), typeof t.targetLatencySeconds == "number" && (o.targetLatencyMs = Math.round(t.targetLatencySeconds * 1e3)), typeof t.bandwidthKbps == "number" && (o.bandwidthEstKbps = t.bandwidthKbps), typeof t.levelHeight == "number" && (o.renditionHeight = t.levelHeight), typeof t.renditionBitrateKbps == "number" && (o.renditionBitrateKbps = t.renditionBitrateKbps), t.atLiveEdge === !0 && (o.atLiveEdge = !0), typeof t.bufferedMs == "number" && t.bufferedMs > 0 && (o.bufferedMs = Math.round(t.bufferedMs)), o.playerState = Y[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
|
|
2355
2392
|
let d = this.mutedTotalMs;
|
|
2356
2393
|
this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
|
|
2357
2394
|
let f = t.upshifts ?? 0;
|
|
@@ -2366,20 +2403,20 @@ var _n = class {
|
|
|
2366
2403
|
if (this.lastRequestCount = g, _ > 0) {
|
|
2367
2404
|
o.requestCountDelta = _;
|
|
2368
2405
|
let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
|
|
2369
|
-
n.length > 0 && (o.requestTimeP50Ms =
|
|
2406
|
+
n.length > 0 && (o.requestTimeP50Ms = dn(n, 50), o.requestTimeP95Ms = dn(n, 95));
|
|
2370
2407
|
}
|
|
2371
2408
|
typeof t.latencySeconds == "number" && typeof t.targetLatencySeconds == "number" && (o.driftMs = Math.round((t.latencySeconds - t.targetLatencySeconds) * 1e3)), typeof t.playbackRate == "number" && t.playbackRate > 0 && (o.playbackRate = t.playbackRate), t.qualityPinned === !0 && (o.qualityPinned = !0), t.cdnHost && (o.cdnHost = t.cdnHost), this.maybeEmitMediaInfo(t), this.enqueue({ heartbeat: o }), this.flush(), s > 0 && this.noteFirstBytes();
|
|
2372
2409
|
}
|
|
2373
2410
|
maybeEmitMediaInfo(e) {
|
|
2374
2411
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
2375
2412
|
let t = {};
|
|
2376
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
2413
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = un[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);
|
|
2377
2414
|
let n = JSON.stringify(t);
|
|
2378
2415
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
2379
2416
|
}
|
|
2380
2417
|
end(e, t) {
|
|
2381
2418
|
if (this.endedFlag) return;
|
|
2382
|
-
this.endedFlag = !0,
|
|
2419
|
+
this.endedFlag = !0, Z.delete(this);
|
|
2383
2420
|
let n = t ?? this.now();
|
|
2384
2421
|
this.playingSinceMs !== null && (this.playingTotalMs += n - this.playingSinceMs, this.playingSinceMs = null), this.hiddenSinceMs !== null && (this.hiddenTotalMs += n - this.hiddenSinceMs, this.hiddenSinceMs = null), this.bufferingSinceMs !== null && (this.rebufferTotalMs += n - this.bufferingSinceMs, this.bufferingSinceMs = null), this.mutedSinceMs !== null && (this.mutedTotalMs += n - this.mutedSinceMs, this.mutedSinceMs = null), this.waitingSinceMs !== null && (this.waitingTotalMs += n - this.waitingSinceMs, this.waitingSinceMs = null), this.isPlaying = !1, this.syncActive(n), this.closePresentation(n), this.firstFlushTimer &&= (clearTimeout(this.firstFlushTimer), null), this.timer &&= (clearInterval(this.timer), null), this.idleTimer &&= (clearTimeout(this.idleTimer), null), typeof window < "u" && window.removeEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), document.removeEventListener("freeze", this.onFreeze), document.removeEventListener("resume", this.onResume));
|
|
2385
2422
|
let r = this.safeSample();
|
|
@@ -2393,7 +2430,7 @@ var _n = class {
|
|
|
2393
2430
|
let c = r?.positionMs ?? 0;
|
|
2394
2431
|
c > 0 && (i.exitPositionMs = Math.round(c)), this.activeTotalMs > 0 && (i.activeWatchTimeMs = Math.round(this.activeTotalMs)), this.mutedTotalMs > 0 && (i.mutedTimeMs = Math.round(this.mutedTotalMs));
|
|
2395
2432
|
let l = e !== "END_REASON_ENDED";
|
|
2396
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
2433
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= sn && (i.abandonAfterStallMs = Math.max(J, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= sn && (i.abandonAfterErrorMs = Math.max(J, Math.round(n - this.lastErrorMs))), this.fullscreenTotalMs > 0 && (i.fullscreenTimeMs = Math.round(this.fullscreenTotalMs)), this.pipTotalMs > 0 && (i.pipTimeMs = Math.round(this.pipTotalMs)), this.volumeChanges > 0 && (i.volumeChanges = this.volumeChanges), this.muteChanges > 0 && (i.muteChanges = this.muteChanges);
|
|
2397
2434
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
2398
2435
|
u > 0 && (i.decodedFramesTotal = u), e === "END_REASON_STOPPED" && this.startupTimeMs === 0 && this.lastErrorStage === null && (e = "END_REASON_ABORTED", i.reason = e), this.startupTimeMs === 0 && e !== "END_REASON_ABORTED" && (i.failedStage = this.lastErrorStage ?? (this.manifestLoadMs === 0 ? "ERROR_STAGE_MANIFEST" : this.firstFragLoadMs === 0 ? "ERROR_STAGE_FIRST_SEGMENT" : "ERROR_STAGE_OTHER")), this.pending.push(this.wrap({ sessionEnd: i })), this.flush(e === "END_REASON_PAGEHIDE");
|
|
2399
2436
|
}
|
|
@@ -2413,13 +2450,13 @@ var _n = class {
|
|
|
2413
2450
|
};
|
|
2414
2451
|
}
|
|
2415
2452
|
noteCspBlocked() {
|
|
2416
|
-
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(
|
|
2453
|
+
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(gn(new URL(this.url).origin)));
|
|
2417
2454
|
}
|
|
2418
2455
|
cspBlocked() {
|
|
2419
|
-
return !!this.cspKey &&
|
|
2456
|
+
return !!this.cspKey && X.has(this.cspKey);
|
|
2420
2457
|
}
|
|
2421
2458
|
enqueue(e) {
|
|
2422
|
-
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
2459
|
+
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > an;) {
|
|
2423
2460
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
2424
2461
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
2425
2462
|
}
|
|
@@ -2446,7 +2483,7 @@ var _n = class {
|
|
|
2446
2483
|
};
|
|
2447
2484
|
//#endregion
|
|
2448
2485
|
//#region src/core/environment.ts
|
|
2449
|
-
function
|
|
2486
|
+
function xn() {
|
|
2450
2487
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
2451
2488
|
let e;
|
|
2452
2489
|
try {
|
|
@@ -2471,14 +2508,14 @@ function vn() {
|
|
|
2471
2508
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
2472
2509
|
};
|
|
2473
2510
|
}
|
|
2474
|
-
function
|
|
2511
|
+
function Sn() {
|
|
2475
2512
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
2476
2513
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
2477
2514
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
2478
2515
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
2479
2516
|
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";
|
|
2480
2517
|
}
|
|
2481
|
-
function
|
|
2518
|
+
function Cn() {
|
|
2482
2519
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
2483
2520
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
2484
2521
|
let t = {
|
|
@@ -2497,17 +2534,17 @@ function bn() {
|
|
|
2497
2534
|
}
|
|
2498
2535
|
return typeof e.downlink == "number" && e.downlink > 0 && (i.downlinkKbps = Math.round(e.downlink * 1e3)), typeof e.rtt == "number" && e.rtt > 0 && (i.rttMs = Math.round(e.rtt)), e.saveData && (i.saveData = !0), i;
|
|
2499
2536
|
}
|
|
2500
|
-
function
|
|
2501
|
-
let t =
|
|
2502
|
-
deviceClass:
|
|
2537
|
+
function wn(e) {
|
|
2538
|
+
let t = xn(), n = {
|
|
2539
|
+
deviceClass: Sn(),
|
|
2503
2540
|
integration: t.integration,
|
|
2504
|
-
...
|
|
2541
|
+
...Cn()
|
|
2505
2542
|
};
|
|
2506
2543
|
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);
|
|
2507
2544
|
let r = e.getBoundingClientRect?.();
|
|
2508
2545
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
2509
2546
|
}
|
|
2510
|
-
async function
|
|
2547
|
+
async function Tn() {
|
|
2511
2548
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
2512
2549
|
if (!e?.getHighEntropyValues) return {};
|
|
2513
2550
|
try {
|
|
@@ -2519,7 +2556,7 @@ async function Sn() {
|
|
|
2519
2556
|
}
|
|
2520
2557
|
//#endregion
|
|
2521
2558
|
//#region src/core/version.ts
|
|
2522
|
-
var
|
|
2559
|
+
var En = "2.17.0", Dn = {
|
|
2523
2560
|
accent: "#E1B600",
|
|
2524
2561
|
accentText: "#1B1C23",
|
|
2525
2562
|
background: "#0e0f13",
|
|
@@ -2530,7 +2567,7 @@ var Cn = "2.16.12", wn = {
|
|
|
2530
2567
|
border: "rgba(255, 255, 255, 0.1)",
|
|
2531
2568
|
radius: "8px",
|
|
2532
2569
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
2533
|
-
},
|
|
2570
|
+
}, On = {
|
|
2534
2571
|
accent: "--havik-accent",
|
|
2535
2572
|
accentText: "--havik-accent-text",
|
|
2536
2573
|
background: "--havik-bg",
|
|
@@ -2542,26 +2579,26 @@ var Cn = "2.16.12", wn = {
|
|
|
2542
2579
|
radius: "--havik-radius",
|
|
2543
2580
|
fontFamily: "--havik-font"
|
|
2544
2581
|
};
|
|
2545
|
-
function
|
|
2582
|
+
function kn(e, t) {
|
|
2546
2583
|
let n = {
|
|
2547
|
-
...
|
|
2584
|
+
...Dn,
|
|
2548
2585
|
...t
|
|
2549
2586
|
};
|
|
2550
|
-
for (let t of Object.keys(
|
|
2587
|
+
for (let t of Object.keys(On)) e.style.setProperty(On[t], n[t]);
|
|
2551
2588
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
2552
2589
|
}
|
|
2553
2590
|
//#endregion
|
|
2554
2591
|
//#region src/ui/styles.ts
|
|
2555
|
-
var
|
|
2556
|
-
function
|
|
2557
|
-
let n = e.querySelector(`style#${
|
|
2558
|
-
if (n && (!t ||
|
|
2592
|
+
var An = "havik-player-styles", jn = "\n.havik-player{position:relative;display:block;width:100%;background:var(--havik-bg,#0e0f13);\n color:var(--havik-text,#fff);font-family:var(--havik-font,system-ui,sans-serif);\n overflow:hidden;line-height:1.4;-webkit-tap-highlight-color:transparent}\n.havik-player video{display:block;width:100%;height:auto;aspect-ratio:16/9;\n object-fit:contain;background:#000;outline:none}\n.havik-player:focus{outline:none}\n.havik-player *{box-sizing:border-box}\n\n.havik-player:fullscreen,.havik-player:-webkit-full-screen{display:flex;align-items:center;\n justify-content:center;width:100vw;height:100vh;aspect-ratio:auto}\n.havik-player:fullscreen video,.havik-player:-webkit-full-screen video{width:100%;height:100%;\n aspect-ratio:auto;object-fit:contain}\n\n.havik-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer;\n touch-action:manipulation}\n.havik-gradient{position:absolute;left:0;right:0;bottom:0;height:120px;pointer-events:none;\n background:linear-gradient(to top,rgba(0,0,0,.78),transparent);\n opacity:1;transition:opacity .25s}\n.havik-player.havik-hide .havik-gradient,\n.havik-player.havik-hide .havik-bar{opacity:0;pointer-events:none}\n.havik-player.havik-hide{cursor:none}\n\n.havik-center{width:74px;height:74px;border-radius:50%;border:0;cursor:pointer;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);\n display:flex;align-items:center;justify-content:center;\n box-shadow:0 6px 24px rgba(0,0,0,.45);transition:transform .15s,opacity .15s}\n.havik-center:hover{transform:scale(1.06)}\n.havik-center svg{width:38px;height:38px;margin-left:2px}\n.havik-center.havik-gone{opacity:0;pointer-events:none;transform:scale(.8)}\n\n/* Absolutely centred, NOT a flex sibling of .havik-center: the hidden center\n button (.havik-gone) still occupies its 74px in the row, which pushed an\n in-flow spinner 37px right of centre. */\n.havik-spinner{position:absolute;inset:0;margin:auto;width:56px;height:56px;border-radius:50%;\n border:4px solid rgba(255,255,255,.2);border-top-color:var(--havik-accent,#E1B600);\n animation:havik-spin .8s linear infinite}\n@keyframes havik-spin{to{transform:rotate(360deg)}}\n\n/* Status card — branded full-bleed overlay for the stopped/pre-play states\n (ended / fatal error / pre-play / armed-waiting). */\n.havik-status{position:absolute;inset:0;display:flex;flex-direction:column;gap:16px;\n align-items:center;justify-content:center;background:rgba(14,15,19,.82);text-align:center;padding:24px}\n.havik-status__logo{width:128px;height:46px;background:var(--havik-logo) center/contain no-repeat;opacity:.95}\n.havik-status__msg{color:var(--havik-text,#fff);font-size:15px;font-weight:600;max-width:480px}\n.havik-status__btn{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;\n padding:10px 18px;border-radius:var(--havik-radius,8px);font-weight:700;font-size:14px;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);transition:transform .15s}\n.havik-status__btn:hover{transform:scale(1.04)}\n.havik-status__btn svg{width:18px;height:18px}\n/* Pre-play: lighter scrim so the poster shows through, and a round play CTA. */\n.havik-status--preplay{background:rgba(14,15,19,.4)}\n.havik-status--preplay .havik-status__btn--play{width:74px;height:74px;border-radius:50%;padding:0;\n justify-content:center;box-shadow:0 6px 24px rgba(0,0,0,.45)}\n.havik-status--preplay .havik-status__btn--play svg{width:38px;height:38px;margin-left:3px}\n\n.havik-watermark{position:absolute;top:12px;right:14px;height:22px;opacity:.85;pointer-events:none;\n content:'';background:var(--havik-logo) center/contain no-repeat;width:90px}\n/* A status card carries its own logo — the corner watermark would duplicate it. */\n.havik-player.havik-has-status .havik-watermark{display:none}\n\n.havik-bar{position:absolute;left:0;right:0;bottom:0;padding:0 12px 8px;\n opacity:1;transition:opacity .25s;z-index:2}\n.havik-seek{position:relative;height:16px;display:flex;align-items:center;cursor:pointer;margin-bottom:2px}\n.havik-seek__track{position:relative;width:100%;height:4px;border-radius:3px;background:rgba(255,255,255,.25)}\n.havik-seek__buffered{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:rgba(255,255,255,.4)}\n.havik-seek__played{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-seek__thumb{position:absolute;top:50%;width:13px;height:13px;border-radius:50%;\n background:var(--havik-accent,#E1B600);transform:translate(-50%,-50%) scale(0);transition:transform .1s}\n.havik-seek:hover .havik-seek__thumb{transform:translate(-50%,-50%) scale(1)}\n\n.havik-controls{display:flex;align-items:center;gap:6px;height:40px}\n.havik-spacer{flex:1}\n.havik-btn{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;border-radius:var(--havik-radius,8px);\n padding:0;transition:background .12s,color .12s}\n.havik-btn:hover{background:rgba(255,255,255,.12)}\n.havik-btn:focus-visible{outline:2px solid var(--havik-accent,#E1B600);outline-offset:1px}\n.havik-btn svg{width:22px;height:22px}\n\n/* The volume level is filled in accent up to the thumb, like the seek bar's\n played span — a native range input paints no \"elapsed\" side, which left the\n level readable only from the dot's position. --havik-vol (0..1) is set by\n syncVolume(); the track width and thumb size live here as variables because\n the WebKit fill has to compute the thumb centre from both. */\n.havik-vol{display:flex;align-items:center}\n.havik-vol__slider{--havik-vol-w:70px;--havik-vol-thumb:12px;--havik-vol:1;\n --havik-vol-pos:calc(var(--havik-vol-thumb) / 2 + var(--havik-vol) * (var(--havik-vol-w) - var(--havik-vol-thumb)));\n width:0;opacity:0;transition:width .18s,opacity .18s;height:4px;cursor:pointer;\n appearance:none;-webkit-appearance:none;background:transparent;border-radius:3px;margin:0 4px}\n.havik-vol:hover .havik-vol__slider,.havik-vol:focus-within .havik-vol__slider{width:var(--havik-vol-w);opacity:1}\n/* WebKit/Blink have no progress pseudo-element: paint the fill as a hard-stop\n gradient that ends at the thumb centre. */\n.havik-vol__slider::-webkit-slider-runnable-track{height:4px;border-radius:3px;\n background:linear-gradient(to right,var(--havik-accent,#E1B600) var(--havik-vol-pos),\n rgba(255,255,255,.3) var(--havik-vol-pos))}\n/* Firefox fills natively, and tracks the thumb exactly. */\n.havik-vol__slider::-moz-range-track{height:4px;border-radius:3px;background:rgba(255,255,255,.3)}\n.havik-vol__slider::-moz-range-progress{height:4px;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-vol__slider::-webkit-slider-thumb{-webkit-appearance:none;width:var(--havik-vol-thumb);\n height:var(--havik-vol-thumb);border-radius:50%;background:var(--havik-accent,#E1B600);\n margin-top:calc((4px - var(--havik-vol-thumb)) / 2)}\n.havik-vol__slider::-moz-range-thumb{width:var(--havik-vol-thumb);height:var(--havik-vol-thumb);\n border:0;border-radius:50%;background:var(--havik-accent,#E1B600)}\n\n.havik-time{font-size:12px;color:var(--havik-text-muted,#9aa0ad);\n font-variant-numeric:tabular-nums;padding:0 6px;white-space:nowrap}\n.havik-live{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;\n letter-spacing:.4px;padding:0 8px;color:var(--havik-text,#fff)}\n.havik-live svg{width:9px;height:9px;color:var(--havik-text-muted,#9aa0ad)}\n.havik-live.is-live svg{color:var(--havik-accent,#E1B600)}\n.havik-live__go{margin-left:2px;border:0;cursor:pointer;background:transparent;color:var(--havik-text-muted,#9aa0ad);\n font:inherit;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 6px;border-radius:6px}\n.havik-live.is-live .havik-live__go{display:none}\n.havik-live__go:hover{color:var(--havik-accent,#E1B600)}\n\n.havik-menu{position:absolute;bottom:54px;right:12px;min-width:170px;max-height:230px;overflow:auto;\n background:var(--havik-surface,#1B1C23);border:1px solid var(--havik-border,rgba(255,255,255,.1));\n border-radius:var(--havik-radius,8px);box-shadow:0 10px 30px rgba(0,0,0,.5);padding:6px;z-index:3}\n.havik-menu[hidden]{display:none}\n.havik-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;\n color:var(--havik-text-muted,#9aa0ad);padding:6px 8px 4px}\n.havik-menu__item{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;font:inherit;font-size:13px;\n text-align:left;padding:7px 8px;border-radius:6px}\n.havik-menu__item:hover{background:var(--havik-surface-muted,#2a2c36)}\n.havik-menu__item[aria-checked=\"true\"]{color:var(--havik-accent,#E1B600);font-weight:600}\n.havik-menu__item[aria-checked=\"true\"]::after{content:'✓'}\n", Mn = /* @__PURE__ */ new WeakMap();
|
|
2593
|
+
function Nn(e = document, t) {
|
|
2594
|
+
let n = e.querySelector(`style#${An}`);
|
|
2595
|
+
if (n && (!t || Mn.get(n) === t)) return;
|
|
2559
2596
|
let r = e.createElement("style");
|
|
2560
|
-
r.id =
|
|
2597
|
+
r.id = An, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = jn, Mn.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
|
|
2561
2598
|
}
|
|
2562
2599
|
//#endregion
|
|
2563
2600
|
//#region src/ui/icons.ts
|
|
2564
|
-
var
|
|
2601
|
+
var Pn = {
|
|
2565
2602
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
2566
2603
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
2567
2604
|
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\"/>",
|
|
@@ -2575,20 +2612,20 @@ var jn = {
|
|
|
2575
2612
|
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\"/>"
|
|
2576
2613
|
};
|
|
2577
2614
|
function Q(e) {
|
|
2578
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
2615
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Pn[e]}</svg>`;
|
|
2579
2616
|
}
|
|
2580
2617
|
//#endregion
|
|
2581
2618
|
//#region src/ui/controls.ts
|
|
2582
|
-
var
|
|
2619
|
+
var Fn = 3e3, In = 250, Ln = /* @__PURE__ */ new Set([
|
|
2583
2620
|
"GONE",
|
|
2584
2621
|
"NOT_FOUND",
|
|
2585
2622
|
"INVALID_URN",
|
|
2586
2623
|
"UNAUTHORIZED"
|
|
2587
2624
|
]);
|
|
2588
|
-
function
|
|
2589
|
-
return new
|
|
2625
|
+
function Rn(e) {
|
|
2626
|
+
return new zn(e);
|
|
2590
2627
|
}
|
|
2591
|
-
var
|
|
2628
|
+
var zn = class {
|
|
2592
2629
|
root;
|
|
2593
2630
|
video;
|
|
2594
2631
|
player;
|
|
@@ -2622,6 +2659,7 @@ var In = class {
|
|
|
2622
2659
|
lastError = null;
|
|
2623
2660
|
logoUrl;
|
|
2624
2661
|
statusOverlays;
|
|
2662
|
+
streamEnded;
|
|
2625
2663
|
endedMessage;
|
|
2626
2664
|
interruptedMessage;
|
|
2627
2665
|
errorMessage;
|
|
@@ -2634,7 +2672,7 @@ var In = class {
|
|
|
2634
2672
|
scrubbing = !1;
|
|
2635
2673
|
offFns = [];
|
|
2636
2674
|
constructor(e) {
|
|
2637
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
2675
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Fn, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.streamEnded = e.streamEnded ?? (() => !1), this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, Nn(this.doc, e.cspNonce), this.root.classList.add("havik-player"), this.root.hasAttribute("tabindex") || (this.root.tabIndex = 0), this.root.setAttribute("role", "region"), this.root.setAttribute("aria-label", "Video player");
|
|
2638
2676
|
let t = (e, t, n) => {
|
|
2639
2677
|
let r = this.doc.createElement(e);
|
|
2640
2678
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -2720,7 +2758,7 @@ var In = class {
|
|
|
2720
2758
|
let t = this.surfaceWasHidden;
|
|
2721
2759
|
this.tapTimer = setTimeout(() => {
|
|
2722
2760
|
this.tapTimer = void 0, this.toggleBar(t);
|
|
2723
|
-
},
|
|
2761
|
+
}, In);
|
|
2724
2762
|
}
|
|
2725
2763
|
toggleBar(e) {
|
|
2726
2764
|
e ? this.poke() : this.hideIfIdle();
|
|
@@ -2755,7 +2793,7 @@ var In = class {
|
|
|
2755
2793
|
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = Q("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
|
|
2756
2794
|
} else {
|
|
2757
2795
|
let r = this.doc.createElement("div");
|
|
2758
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
2796
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Ln.has(this.lastError.code)) {
|
|
2759
2797
|
let e = this.doc.createElement("button");
|
|
2760
2798
|
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${Q("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
|
|
2761
2799
|
}
|
|
@@ -2796,11 +2834,11 @@ var In = class {
|
|
|
2796
2834
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
2797
2835
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
2798
2836
|
}
|
|
2799
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
2837
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Bn(this.video.currentTime)} / ${Bn(this.video.duration)}`);
|
|
2800
2838
|
}
|
|
2801
2839
|
syncLive() {
|
|
2802
|
-
let e = this.player.getStats(), t = e.isLive !== !1;
|
|
2803
|
-
this.live.style.display = t ? "" : "none", this.time.style.display =
|
|
2840
|
+
let e = this.player.getStats(), t = e.isLive !== !1, n = this.player.state === "ended", r = !t && !this.streamEnded();
|
|
2841
|
+
this.live.style.display = t && !n ? "" : "none", this.time.style.display = r ? "" : "none", this.seek.style.display = r ? "" : "none", this.live.classList.toggle("is-live", e.atLiveEdge !== !1 && t);
|
|
2804
2842
|
}
|
|
2805
2843
|
onSeekDown(e) {
|
|
2806
2844
|
let t = this.seekableRange();
|
|
@@ -2846,17 +2884,17 @@ var In = class {
|
|
|
2846
2884
|
renderQualityMenu() {
|
|
2847
2885
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
2848
2886
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
2849
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
2887
|
+
for (let n of e) this.menu.append(this.menuItem(Vn(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
2850
2888
|
}
|
|
2851
2889
|
renderAudioMenu() {
|
|
2852
2890
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
2853
2891
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
2854
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2892
|
+
for (let t of e) this.menu.append(this.menuItem(Hn(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
2855
2893
|
}
|
|
2856
2894
|
renderCcMenu() {
|
|
2857
2895
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
2858
2896
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
2859
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2897
|
+
for (let t of e) this.menu.append(this.menuItem(Un(t), !1, () => this.player.setTextTrack(t.id)));
|
|
2860
2898
|
}
|
|
2861
2899
|
onTracksChanged() {
|
|
2862
2900
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -2957,41 +2995,41 @@ var In = class {
|
|
|
2957
2995
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
2958
2996
|
}
|
|
2959
2997
|
};
|
|
2960
|
-
function
|
|
2998
|
+
function Bn(e) {
|
|
2961
2999
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
2962
3000
|
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");
|
|
2963
3001
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
2964
3002
|
}
|
|
2965
|
-
function
|
|
3003
|
+
function Vn(e) {
|
|
2966
3004
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
2967
3005
|
}
|
|
2968
|
-
function
|
|
3006
|
+
function Hn(e) {
|
|
2969
3007
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2970
3008
|
}
|
|
2971
|
-
function
|
|
3009
|
+
function Un(e) {
|
|
2972
3010
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2973
3011
|
}
|
|
2974
3012
|
//#endregion
|
|
2975
3013
|
//#region src/managed/index.ts
|
|
2976
|
-
var
|
|
2977
|
-
function
|
|
3014
|
+
var Wn = 6e3, Gn = 45e3, Kn = 2e3, qn = 3, Jn = 5e3, Yn = 2e3, Xn = 48e4, Zn = "keySystemLicenseRequestFailed";
|
|
3015
|
+
function Qn(e) {
|
|
2978
3016
|
if (e.env !== void 0 && e.baseUrl !== void 0) throw new n("INTERNAL", 0, `createPlayer: pass env OR baseUrl, not both (got env=${JSON.stringify(e.env)} and baseUrl=${JSON.stringify(e.baseUrl)})`);
|
|
2979
|
-
if (e.env !== void 0) return
|
|
3017
|
+
if (e.env !== void 0) return Ge(e.env);
|
|
2980
3018
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
2981
3019
|
return e.baseUrl;
|
|
2982
3020
|
}
|
|
2983
|
-
async function
|
|
3021
|
+
async function $n(e) {
|
|
2984
3022
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
2985
|
-
let t =
|
|
3023
|
+
let t = Qn(e);
|
|
2986
3024
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
2987
3025
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
2988
|
-
let r = new
|
|
3026
|
+
let r = new er({
|
|
2989
3027
|
...e,
|
|
2990
3028
|
baseUrl: t
|
|
2991
3029
|
});
|
|
2992
3030
|
return await r.start(), r;
|
|
2993
3031
|
}
|
|
2994
|
-
var
|
|
3032
|
+
var er = class {
|
|
2995
3033
|
opts;
|
|
2996
3034
|
abort = new AbortController();
|
|
2997
3035
|
listeners = {};
|
|
@@ -3000,10 +3038,14 @@ var Xn = class {
|
|
|
3000
3038
|
container = null;
|
|
3001
3039
|
detachMedia;
|
|
3002
3040
|
detachPip;
|
|
3041
|
+
detachEndedPlayGuard;
|
|
3003
3042
|
statsTimer;
|
|
3004
3043
|
refreshTimer;
|
|
3005
3044
|
refreshInFlight;
|
|
3006
3045
|
onRefocus;
|
|
3046
|
+
onReturnVisible = null;
|
|
3047
|
+
onReturnPageShow = null;
|
|
3048
|
+
hiddenAtMs = null;
|
|
3007
3049
|
staleLicenseReloaded = !1;
|
|
3008
3050
|
_state = "idle";
|
|
3009
3051
|
_descriptor = null;
|
|
@@ -3035,10 +3077,10 @@ var Xn = class {
|
|
|
3035
3077
|
return this._endedReason;
|
|
3036
3078
|
}
|
|
3037
3079
|
async start() {
|
|
3038
|
-
this.opts.muted && (this.opts.video.muted = !0), this.opts.poster && (this.opts.video.poster = this.opts.poster), this.mountControls(), this.attachPipListeners(), this.setState("loading");
|
|
3080
|
+
this.opts.muted && (this.opts.video.muted = !0), this.opts.poster && (this.opts.video.poster = this.opts.poster), this.mountControls(), this.attachPipListeners(), this.attachEndedPlayGuard(), this.setState("loading");
|
|
3039
3081
|
let e = ++this.loadGen, t = this.resolveOptions();
|
|
3040
3082
|
try {
|
|
3041
|
-
let n = await
|
|
3083
|
+
let n = await y(t);
|
|
3042
3084
|
if (await this.onResolved(n, e), e === this.loadGen && this._state === "error" && this._lastError) {
|
|
3043
3085
|
let e = this._lastError;
|
|
3044
3086
|
throw this.destroy(), e;
|
|
@@ -3065,7 +3107,7 @@ var Xn = class {
|
|
|
3065
3107
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
3066
3108
|
}
|
|
3067
3109
|
beginArmingByPolling(e) {
|
|
3068
|
-
|
|
3110
|
+
b({
|
|
3069
3111
|
...this.resolveOptions(),
|
|
3070
3112
|
signal: this.abort.signal,
|
|
3071
3113
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -3082,7 +3124,7 @@ var Xn = class {
|
|
|
3082
3124
|
setTimeout(() => {
|
|
3083
3125
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
3084
3126
|
phase: i ? "unavailable" : "tooEarly",
|
|
3085
|
-
retryInMs:
|
|
3127
|
+
retryInMs: Gn,
|
|
3086
3128
|
attempt: 1,
|
|
3087
3129
|
elapsedMs: 0,
|
|
3088
3130
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -3099,7 +3141,7 @@ var Xn = class {
|
|
|
3099
3141
|
}
|
|
3100
3142
|
}
|
|
3101
3143
|
}, h = () => {
|
|
3102
|
-
a || s || p() || (s = !0,
|
|
3144
|
+
a || s || p() || (s = !0, b({
|
|
3103
3145
|
...this.resolveOptions(),
|
|
3104
3146
|
signal: c.signal,
|
|
3105
3147
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -3107,7 +3149,7 @@ var Xn = class {
|
|
|
3107
3149
|
a || p() || c.signal.aborted || (a = !0, this.closeArming(), this.fail(e instanceof n ? e : new n("INTERNAL", 0, String(e))));
|
|
3108
3150
|
}));
|
|
3109
3151
|
}, g = () => {
|
|
3110
|
-
a || p() ||
|
|
3152
|
+
a || p() || y(this.resolveOptions()).then((e) => m(e)).catch((e) => {
|
|
3111
3153
|
if (!(a || p())) {
|
|
3112
3154
|
if (e instanceof n && o(e.code)) {
|
|
3113
3155
|
h();
|
|
@@ -3121,13 +3163,13 @@ var Xn = class {
|
|
|
3121
3163
|
!a && !p() && h();
|
|
3122
3164
|
}, e);
|
|
3123
3165
|
};
|
|
3124
|
-
_(
|
|
3166
|
+
_(Wn), this.armingSub = T({
|
|
3125
3167
|
eventsBaseUrl: t,
|
|
3126
3168
|
matchUrn: this.opts.matchUrn,
|
|
3127
3169
|
credential: this.opts.credential,
|
|
3128
|
-
onAlive: () => _(
|
|
3170
|
+
onAlive: () => _(Gn),
|
|
3129
3171
|
onState: (e) => {
|
|
3130
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
3172
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Kn);
|
|
3131
3173
|
},
|
|
3132
3174
|
onError: () => h()
|
|
3133
3175
|
});
|
|
@@ -3161,7 +3203,7 @@ var Xn = class {
|
|
|
3161
3203
|
a(), i.destroy();
|
|
3162
3204
|
return;
|
|
3163
3205
|
}
|
|
3164
|
-
this.engine = i, this.detachMedia = a, this.opts.maxBitrate != null && i.setMaxBitrate(this.opts.maxBitrate), this.startStats(), this.scheduleLicenseRefresh(), this.startLiveState(t), this.startAnalytics(e, i, t), r && (this.pendingStartLoad = !0, this.setState("paused"), i.name === "native" && setTimeout(() => {
|
|
3206
|
+
this.engine = i, this.detachMedia = a, this.opts.maxBitrate != null && i.setMaxBitrate(this.opts.maxBitrate), this.startStats(), this.scheduleLicenseRefresh(), this.startLiveState(t), this.watchReturn(), this.startAnalytics(e, i, t), r && (this.pendingStartLoad = !0, this.setState("paused"), i.name === "native" && setTimeout(() => {
|
|
3165
3207
|
this.destroyed || t !== this.loadGen || this.engine !== i || (this.analyticsSession?.noteReady(), this.emit("ready"));
|
|
3166
3208
|
}, 0));
|
|
3167
3209
|
}
|
|
@@ -3172,26 +3214,26 @@ var Xn = class {
|
|
|
3172
3214
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
3173
3215
|
let i = e.analytics?.sid;
|
|
3174
3216
|
if (!i) return;
|
|
3175
|
-
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } =
|
|
3217
|
+
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = yn(this.opts.baseUrl, a, e.analytics?.endpoint);
|
|
3176
3218
|
if (!o) {
|
|
3177
3219
|
s && setTimeout(() => {
|
|
3178
3220
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
|
|
3179
3221
|
}, 0);
|
|
3180
3222
|
return;
|
|
3181
3223
|
}
|
|
3182
|
-
let c = this.opts.video, l = new
|
|
3224
|
+
let c = this.opts.video, l = new bn({
|
|
3183
3225
|
endpoint: o,
|
|
3184
3226
|
sid: i,
|
|
3185
3227
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
3186
|
-
sdkVersion:
|
|
3187
|
-
environment:
|
|
3228
|
+
sdkVersion: En,
|
|
3229
|
+
environment: wn(c),
|
|
3188
3230
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
3189
3231
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
3190
3232
|
onBlocked: (e) => setTimeout(() => {
|
|
3191
3233
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, e));
|
|
3192
3234
|
}, 0),
|
|
3193
3235
|
sample: () => {
|
|
3194
|
-
let e = this.engine?.getStats() ??
|
|
3236
|
+
let e = this.engine?.getStats() ?? Ke, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
|
|
3195
3237
|
return {
|
|
3196
3238
|
...e,
|
|
3197
3239
|
bufferedMs: Math.round(t * 1e3),
|
|
@@ -3205,7 +3247,7 @@ var Xn = class {
|
|
|
3205
3247
|
let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
|
|
3206
3248
|
c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
|
|
3207
3249
|
c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
|
|
3208
|
-
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()),
|
|
3250
|
+
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), Tn().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
3209
3251
|
}
|
|
3210
3252
|
currentPresentation() {
|
|
3211
3253
|
let e = this.opts.video;
|
|
@@ -3232,9 +3274,9 @@ var Xn = class {
|
|
|
3232
3274
|
freshLicenseUrl: () => this.refreshLicense()
|
|
3233
3275
|
}, o = this.opts.engine ?? "auto";
|
|
3234
3276
|
if (o === "native") return new W(a);
|
|
3235
|
-
if (o === "hls") return new
|
|
3236
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && H(this.opts.video) && U() || !e.drmEnabled &&
|
|
3237
|
-
if (
|
|
3277
|
+
if (o === "hls") return new en(a);
|
|
3278
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && H(this.opts.video) && U() || !e.drmEnabled && lt() && H(this.opts.video)) return new W(a);
|
|
3279
|
+
if (bt()) return new en(a);
|
|
3238
3280
|
if (H(this.opts.video)) return new W(a);
|
|
3239
3281
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
3240
3282
|
}
|
|
@@ -3297,29 +3339,53 @@ var Xn = class {
|
|
|
3297
3339
|
r = 0, i = !1;
|
|
3298
3340
|
},
|
|
3299
3341
|
onError: () => {
|
|
3300
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
3342
|
+
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= qn && (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.`))));
|
|
3301
3343
|
}
|
|
3302
3344
|
});
|
|
3303
3345
|
}
|
|
3304
3346
|
closeLiveState() {
|
|
3305
3347
|
this.liveStateSub?.close(), this.liveStateSub = null;
|
|
3306
3348
|
}
|
|
3349
|
+
watchReturn() {
|
|
3350
|
+
this.onReturnVisible || typeof document > "u" || this.opts.liveStateEvents !== !1 && (document.visibilityState === "hidden" && (this.hiddenAtMs = Date.now()), this.onReturnVisible = () => {
|
|
3351
|
+
if (document.visibilityState === "hidden") {
|
|
3352
|
+
this.hiddenAtMs ??= Date.now();
|
|
3353
|
+
return;
|
|
3354
|
+
}
|
|
3355
|
+
let e = this.hiddenAtMs;
|
|
3356
|
+
this.hiddenAtMs = null, e != null && Date.now() - e >= Jn && this.resyncLiveState();
|
|
3357
|
+
}, this.onReturnPageShow = (e) => {
|
|
3358
|
+
e.persisted && this.resyncLiveState();
|
|
3359
|
+
}, document.addEventListener("visibilitychange", this.onReturnVisible), typeof window < "u" && window.addEventListener("pageshow", this.onReturnPageShow));
|
|
3360
|
+
}
|
|
3361
|
+
unwatchReturn() {
|
|
3362
|
+
this.onReturnVisible && typeof document < "u" && document.removeEventListener("visibilitychange", this.onReturnVisible), this.onReturnPageShow && typeof window < "u" && window.removeEventListener("pageshow", this.onReturnPageShow), this.onReturnVisible = null, this.onReturnPageShow = null, this.hiddenAtMs = null;
|
|
3363
|
+
}
|
|
3364
|
+
resyncLiveState() {
|
|
3365
|
+
!this.destroyed && this.liveStateSub && this.startLiveState(this.loadGen);
|
|
3366
|
+
}
|
|
3307
3367
|
onStreamEnded(e = !1, t) {
|
|
3308
3368
|
if (!this.destroyed) {
|
|
3309
3369
|
if ((e || !this.rejoinEnabled()) && (this.cancelRejoin(), this.closeLiveState()), this.endedHandled) {
|
|
3310
|
-
t === "match_ended" && this._endedReason !== "match_ended" && (this._endedReason = t, this.emit("ended", t));
|
|
3370
|
+
t === "match_ended" && this._endedReason !== "match_ended" && (this._endedReason = t, this.emit("ended", t), this.leavePipOnEnd());
|
|
3311
3371
|
return;
|
|
3312
3372
|
}
|
|
3313
|
-
this.endedHandled = !0, this._endedReason = t ?? null, this.stopRefresh(), this.pendingStartLoad = !1, this.engine?.stop(), this.setState("ended");
|
|
3373
|
+
this.endedHandled = !0, this._endedReason = t ?? null, this.stopRefresh(), this.pendingStartLoad = !1, this.engine?.stop(), this.setState("ended"), this.leavePipOnEnd();
|
|
3314
3374
|
}
|
|
3315
3375
|
}
|
|
3376
|
+
leavePipOnEnd() {
|
|
3377
|
+
this._endedReason === "interrupted" && this.rejoinEnabled() || this.exitPictureInPicture().catch(() => {});
|
|
3378
|
+
}
|
|
3379
|
+
get streamEnded() {
|
|
3380
|
+
return this._state === "ended" && this.endedHandled;
|
|
3381
|
+
}
|
|
3316
3382
|
rejoinEnabled() {
|
|
3317
3383
|
return this.opts.rejoinOnLive !== !1 && this.opts.liveStateEvents !== !1;
|
|
3318
3384
|
}
|
|
3319
3385
|
scheduleRejoin(e) {
|
|
3320
3386
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
3321
3387
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
3322
|
-
}, Math.random() *
|
|
3388
|
+
}, Math.random() * Kn));
|
|
3323
3389
|
}
|
|
3324
3390
|
cancelRejoin() {
|
|
3325
3391
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -3343,13 +3409,14 @@ var Xn = class {
|
|
|
3343
3409
|
}
|
|
3344
3410
|
t.controls = !1;
|
|
3345
3411
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
3346
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
3412
|
+
r && r.insertBefore(n, t), n.appendChild(t), kn(n, this.opts.theme), this.container = n, this.controlBar = Rn({
|
|
3347
3413
|
root: n,
|
|
3348
3414
|
video: t,
|
|
3349
3415
|
player: this,
|
|
3350
3416
|
logoUrl: this.opts.theme?.logoUrl,
|
|
3351
3417
|
statusOverlays: this.opts.statusOverlays,
|
|
3352
3418
|
endedMessage: this.opts.endedMessage,
|
|
3419
|
+
streamEnded: () => this.streamEnded,
|
|
3353
3420
|
interruptedMessage: this.opts.interruptedMessage,
|
|
3354
3421
|
errorMessage: this.opts.errorMessage,
|
|
3355
3422
|
cspNonce: this.opts.cspNonce
|
|
@@ -3372,9 +3439,15 @@ var Xn = class {
|
|
|
3372
3439
|
e.removeEventListener("enterpictureinpicture", n), e.removeEventListener("leavepictureinpicture", r), i?.removeEventListener("fullscreenchange", t), i?.removeEventListener("webkitfullscreenchange", t);
|
|
3373
3440
|
};
|
|
3374
3441
|
}
|
|
3442
|
+
attachEndedPlayGuard() {
|
|
3443
|
+
let e = this.opts.video, t = () => {
|
|
3444
|
+
this.streamEnded && e.pause();
|
|
3445
|
+
};
|
|
3446
|
+
e.addEventListener("play", t), this.detachEndedPlayGuard = () => e.removeEventListener("play", t);
|
|
3447
|
+
}
|
|
3375
3448
|
startStats() {
|
|
3376
3449
|
this.stopStats();
|
|
3377
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
3450
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Yn);
|
|
3378
3451
|
this.statsTimer = setInterval(() => {
|
|
3379
3452
|
if (!this.engine) return;
|
|
3380
3453
|
let e = this.engine.getStats();
|
|
@@ -3385,14 +3458,14 @@ var Xn = class {
|
|
|
3385
3458
|
this.statsTimer && clearInterval(this.statsTimer), this.statsTimer = void 0;
|
|
3386
3459
|
}
|
|
3387
3460
|
isStaleLicenseDenial(e) {
|
|
3388
|
-
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !==
|
|
3461
|
+
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== Zn || e.error.httpStatus !== 403 ? !1 : K(this._descriptor?.drm?.widevine?.licenseUrl);
|
|
3389
3462
|
}
|
|
3390
3463
|
scheduleLicenseRefresh() {
|
|
3391
3464
|
if (this.stopRefresh(), !this._descriptor?.drmEnabled) return;
|
|
3392
3465
|
typeof document < "u" && this.engine?.name === "hls" && (this.onRefocus = () => {
|
|
3393
3466
|
document.visibilityState !== "visible" || this.destroyed || K(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
|
|
3394
3467
|
}, document.addEventListener("visibilitychange", this.onRefocus));
|
|
3395
|
-
let e = this.opts.licenseRefreshMs ??
|
|
3468
|
+
let e = this.opts.licenseRefreshMs ?? Xn;
|
|
3396
3469
|
e && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
3397
3470
|
}
|
|
3398
3471
|
stopRefresh() {
|
|
@@ -3404,7 +3477,7 @@ var Xn = class {
|
|
|
3404
3477
|
if (this.refreshInFlight?.engine === e) return this.refreshInFlight.promise;
|
|
3405
3478
|
let t = (async () => {
|
|
3406
3479
|
try {
|
|
3407
|
-
let t = await
|
|
3480
|
+
let t = await y(this.resolveOptions());
|
|
3408
3481
|
if (this.destroyed || this.engine !== e) return;
|
|
3409
3482
|
let n = t.drm?.widevine?.licenseUrl, r = t.drm?.fairplay?.licenseUrl;
|
|
3410
3483
|
return (n || r) && (e.setLicenseUrls({
|
|
@@ -3430,6 +3503,7 @@ var Xn = class {
|
|
|
3430
3503
|
this.idleClosed = !1, await this.reload();
|
|
3431
3504
|
return;
|
|
3432
3505
|
}
|
|
3506
|
+
if (this.streamEnded) return;
|
|
3433
3507
|
let t = this.pendingStartLoad && this._state !== "ended" && this._state !== "error";
|
|
3434
3508
|
this.opts.autoplay === !1 && this.analyticsSession?.notePlayIntent(), t && (this.pendingStartLoad = !1, this.setState("loading"), this.engine?.startLoad());
|
|
3435
3509
|
try {
|
|
@@ -3448,7 +3522,7 @@ var Xn = class {
|
|
|
3448
3522
|
this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
|
|
3449
3523
|
}
|
|
3450
3524
|
getStats() {
|
|
3451
|
-
return this.engine?.getStats() ??
|
|
3525
|
+
return this.engine?.getStats() ?? Ke;
|
|
3452
3526
|
}
|
|
3453
3527
|
getQualityLevels() {
|
|
3454
3528
|
return this.engine?.getQualityLevels() ?? [];
|
|
@@ -3500,7 +3574,7 @@ var Xn = class {
|
|
|
3500
3574
|
let e = ++this.loadGen;
|
|
3501
3575
|
this.teardownPlayback();
|
|
3502
3576
|
try {
|
|
3503
|
-
let t = await
|
|
3577
|
+
let t = await b({
|
|
3504
3578
|
...this.resolveOptions(),
|
|
3505
3579
|
waitForLive: this.opts.waitForLive ? this.buildWaitConfig(e) : void 0
|
|
3506
3580
|
});
|
|
@@ -3515,7 +3589,7 @@ var Xn = class {
|
|
|
3515
3589
|
return n.add(t), () => n.delete(t);
|
|
3516
3590
|
}
|
|
3517
3591
|
destroy() {
|
|
3518
|
-
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());
|
|
3592
|
+
this.destroyed || (this.destroyed = !0, this.loadGen += 1, this.abort.abort(), this.stopStats(), this.stopRefresh(), this.unmountControls(), this.cancelRejoin(), this.closeArming(), this.closeLiveState(), this.unwatchReturn(), this.detachMedia?.(), this.detachPip?.(), this.detachEndedPlayGuard?.(), this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.engine?.destroy(), this.engine = null, this.setState("idle"), this.clearListeners());
|
|
3519
3593
|
}
|
|
3520
3594
|
clearListeners() {
|
|
3521
3595
|
for (let e of Object.keys(this.listeners)) this.listeners[e]?.clear();
|
|
@@ -3558,7 +3632,7 @@ function $(e) {
|
|
|
3558
3632
|
}
|
|
3559
3633
|
//#endregion
|
|
3560
3634
|
//#region src/embed/host.ts
|
|
3561
|
-
function
|
|
3635
|
+
function tr(e) {
|
|
3562
3636
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
3563
3637
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
3564
3638
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -3617,15 +3691,15 @@ function Zn(e) {
|
|
|
3617
3691
|
}
|
|
3618
3692
|
//#endregion
|
|
3619
3693
|
//#region src/embed/page.ts
|
|
3620
|
-
var
|
|
3621
|
-
function
|
|
3694
|
+
var nr = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
3695
|
+
function rr(e) {
|
|
3622
3696
|
if (typeof e == "boolean") return e;
|
|
3623
3697
|
if (typeof e == "object" && e) {
|
|
3624
3698
|
let t = e.endpoint;
|
|
3625
3699
|
return typeof t == "string" ? { endpoint: t } : {};
|
|
3626
3700
|
}
|
|
3627
3701
|
}
|
|
3628
|
-
function
|
|
3702
|
+
function ir() {
|
|
3629
3703
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
3630
3704
|
if (e) return {
|
|
3631
3705
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -3635,7 +3709,7 @@ function er() {
|
|
|
3635
3709
|
autoplay: e.autoplay ?? !0,
|
|
3636
3710
|
muted: e.muted ?? !0,
|
|
3637
3711
|
waitForLive: e.waitForLive ?? !0,
|
|
3638
|
-
analytics:
|
|
3712
|
+
analytics: rr(e.analytics)
|
|
3639
3713
|
};
|
|
3640
3714
|
let t = new URLSearchParams(location.search);
|
|
3641
3715
|
return {
|
|
@@ -3648,9 +3722,9 @@ function er() {
|
|
|
3648
3722
|
waitForLive: !0
|
|
3649
3723
|
};
|
|
3650
3724
|
}
|
|
3651
|
-
async function
|
|
3652
|
-
let e =
|
|
3653
|
-
|
|
3725
|
+
async function ar() {
|
|
3726
|
+
let e = ir();
|
|
3727
|
+
sr();
|
|
3654
3728
|
let t = document.createElement("video");
|
|
3655
3729
|
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);
|
|
3656
3730
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -3705,12 +3779,12 @@ async function tr() {
|
|
|
3705
3779
|
code: e.code,
|
|
3706
3780
|
message: e.message
|
|
3707
3781
|
})), e.on("autoplayblocked", () => {
|
|
3708
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
3782
|
+
i({ type: "oddin:autoplayblocked" }), or(t, e);
|
|
3709
3783
|
});
|
|
3710
3784
|
}, s = async (r) => {
|
|
3711
3785
|
a?.destroy(), a = null;
|
|
3712
3786
|
try {
|
|
3713
|
-
let n = await
|
|
3787
|
+
let n = await $n({
|
|
3714
3788
|
video: t,
|
|
3715
3789
|
baseUrl: e.baseUrl,
|
|
3716
3790
|
matchUrn: r,
|
|
@@ -3772,7 +3846,7 @@ async function tr() {
|
|
|
3772
3846
|
a?.retry();
|
|
3773
3847
|
break;
|
|
3774
3848
|
case "oddin:load":
|
|
3775
|
-
typeof e.matchUrn == "string" &&
|
|
3849
|
+
typeof e.matchUrn == "string" && nr.test(e.matchUrn) && s(e.matchUrn);
|
|
3776
3850
|
break;
|
|
3777
3851
|
case "oddin:destroy": c();
|
|
3778
3852
|
}
|
|
@@ -3784,18 +3858,18 @@ async function tr() {
|
|
|
3784
3858
|
protocol: 1
|
|
3785
3859
|
});
|
|
3786
3860
|
}
|
|
3787
|
-
function
|
|
3861
|
+
function or(e, t) {
|
|
3788
3862
|
if (document.getElementById("havik-tap")) return;
|
|
3789
3863
|
let n = document.createElement("button");
|
|
3790
3864
|
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", () => {
|
|
3791
3865
|
n.remove(), t.play();
|
|
3792
3866
|
}), document.body.appendChild(n);
|
|
3793
3867
|
}
|
|
3794
|
-
function
|
|
3868
|
+
function sr() {
|
|
3795
3869
|
let e = document.createElement("style");
|
|
3796
3870
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
3797
3871
|
}
|
|
3798
3872
|
//#endregion
|
|
3799
|
-
export {
|
|
3873
|
+
export { Dn as ODDIN_THEME, n as PlaybackError, kn as applyTheme, Ge as baseUrlForEnv, ar as bootEmbed, Te as clearDeviceId, $n as createPlayer, E as deriveEventsBaseUrl, Ve as detectDrmSupport, C as enterVideoFullscreen, w as exitVideoFullscreen, _e as fetchCatalog, ye as fetchTournament, xe as flattenMatches, k as getDeviceId, Ue as isLowLatencyManifest, $ as isOddinMessage, De as licenseRequestHeaders, tr as mountEmbed, v as pollToLive, b as resolveStream, T as subscribeLiveState, S as videoFullscreenActive, Ce as watchStatus };
|
|
3800
3874
|
|
|
3801
3875
|
//# sourceMappingURL=index.js.map
|