@oddin-gg/havik-player 2.16.9 → 2.16.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/havik-player.global.js +2 -2
- package/dist/havik-player.global.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +203 -202
- package/dist/index.js.map +1 -1
- package/embed/index.html +1 -1
- package/examples/vanilla.html +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -174,7 +174,7 @@ function ue(e, t) {
|
|
|
174
174
|
t?.addEventListener("abort", a, { once: !0 });
|
|
175
175
|
});
|
|
176
176
|
}
|
|
177
|
-
async function
|
|
177
|
+
async function de(e, t, r) {
|
|
178
178
|
let i = ae(t), a = Date.now(), s = i.timeoutMs == null ? Infinity : a + i.timeoutMs, c = 0, l;
|
|
179
179
|
for (;;) {
|
|
180
180
|
if (r?.aborted) throw new n("ABORTED", 0, "wait-for-live aborted");
|
|
@@ -200,21 +200,21 @@ async function v(e, t, r) {
|
|
|
200
200
|
}
|
|
201
201
|
//#endregion
|
|
202
202
|
//#region src/core/resolve.ts
|
|
203
|
-
async function
|
|
203
|
+
async function v(e) {
|
|
204
204
|
if (!e.matchUrn || typeof e.matchUrn != "string") throw new n("INVALID_URN", 0, "resolveStream: a non-empty matchUrn is required");
|
|
205
205
|
let t = await p(d(e.baseUrl, `/v1/playback/${encodeURIComponent(e.matchUrn)}`), {
|
|
206
206
|
credential: e.credential,
|
|
207
207
|
signal: e.signal,
|
|
208
208
|
apiHeaders: e.apiHeaders
|
|
209
209
|
});
|
|
210
|
-
if (!t.ok) throw await
|
|
211
|
-
return
|
|
210
|
+
if (!t.ok) throw await fe(t);
|
|
211
|
+
return he(await t.json(), e.matchUrn);
|
|
212
212
|
}
|
|
213
|
-
function
|
|
214
|
-
let t = () =>
|
|
215
|
-
return e.waitForLive ?
|
|
213
|
+
function y(e) {
|
|
214
|
+
let t = () => v(e);
|
|
215
|
+
return e.waitForLive ? de(t, e.waitForLive, e.signal) : t();
|
|
216
216
|
}
|
|
217
|
-
async function
|
|
217
|
+
async function fe(e) {
|
|
218
218
|
let t = f(e.headers.get("retry-after")), i = e.headers.get("x-request-id") ?? e.headers.get("x-amzn-requestid") ?? void 0, a = e.statusText || `HTTP ${e.status}`, o, s;
|
|
219
219
|
try {
|
|
220
220
|
let t = await e.json();
|
|
@@ -230,7 +230,7 @@ async function de(e) {
|
|
|
230
230
|
liveStartsAtMs: s
|
|
231
231
|
});
|
|
232
232
|
}
|
|
233
|
-
var
|
|
233
|
+
var pe = /* @__PURE__ */ new Set([
|
|
234
234
|
"matchUrn",
|
|
235
235
|
"protocol",
|
|
236
236
|
"drmEnabled",
|
|
@@ -241,7 +241,7 @@ var fe = /* @__PURE__ */ new Set([
|
|
|
241
241
|
"expiresAt",
|
|
242
242
|
"analytics"
|
|
243
243
|
]);
|
|
244
|
-
function
|
|
244
|
+
function b(e, t) {
|
|
245
245
|
let r;
|
|
246
246
|
try {
|
|
247
247
|
r = new URL(t);
|
|
@@ -251,7 +251,7 @@ function x(e, t) {
|
|
|
251
251
|
if (r.protocol !== "https:" && r.protocol !== "http:") throw new n("INTERNAL", 0, `playback ${e} has a disallowed scheme: ${r.protocol}`);
|
|
252
252
|
return t;
|
|
253
253
|
}
|
|
254
|
-
function
|
|
254
|
+
function me(e) {
|
|
255
255
|
if (e !== void 0) {
|
|
256
256
|
if (typeof e == "string" && !e.endsWith("/")) try {
|
|
257
257
|
let t = new URL(e);
|
|
@@ -260,41 +260,41 @@ function pe(e) {
|
|
|
260
260
|
g(`server analytics.endpoint ${JSON.stringify(e)} ignored: not a bare https origin.`);
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
|
-
function
|
|
263
|
+
function he(e, t) {
|
|
264
264
|
if (!e.manifestUrl) throw new n("INTERNAL", 0, "playback response is missing manifestUrl");
|
|
265
265
|
let r = e.drmEnabled ?? !!e.drm, i = {
|
|
266
266
|
matchUrn: e.matchUrn ?? t,
|
|
267
267
|
protocol: "hls",
|
|
268
268
|
drmEnabled: r,
|
|
269
|
-
manifestUrl:
|
|
269
|
+
manifestUrl: b("manifestUrl", e.manifestUrl),
|
|
270
270
|
serverTime: e.serverTime ?? ""
|
|
271
271
|
};
|
|
272
272
|
if (e.liveStartsAt && (i.liveStartsAt = e.liveStartsAt), typeof e.analytics?.sid == "string" && e.analytics.sid) {
|
|
273
273
|
i.analytics = { sid: e.analytics.sid };
|
|
274
|
-
let t =
|
|
274
|
+
let t = me(e.analytics.endpoint);
|
|
275
275
|
t && (i.analytics.endpoint = t);
|
|
276
276
|
}
|
|
277
277
|
if (r && e.drm) {
|
|
278
278
|
let t = {};
|
|
279
|
-
e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl:
|
|
280
|
-
licenseUrl:
|
|
281
|
-
certificateUrl:
|
|
279
|
+
e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl: b("widevine licenseUrl", e.drm.widevine.licenseUrl) }), e.drm.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && (t.fairplay = {
|
|
280
|
+
licenseUrl: b("fairplay licenseUrl", e.drm.fairplay.licenseUrl),
|
|
281
|
+
certificateUrl: b("fairplay certificateUrl", e.drm.fairplay.certificateUrl)
|
|
282
282
|
}), (t.widevine || t.fairplay) && (i.drm = t);
|
|
283
283
|
}
|
|
284
284
|
let a = {};
|
|
285
|
-
for (let [t, n] of Object.entries(e))
|
|
285
|
+
for (let [t, n] of Object.entries(e)) pe.has(t) || (a[t] = n);
|
|
286
286
|
return Object.keys(a).length > 0 && (i.extensions = a), i;
|
|
287
287
|
}
|
|
288
288
|
//#endregion
|
|
289
289
|
//#region src/core/fullscreen.ts
|
|
290
|
-
function
|
|
290
|
+
function ge(e) {
|
|
291
291
|
return e.ownerDocument ?? document;
|
|
292
292
|
}
|
|
293
|
-
function
|
|
293
|
+
function x(e) {
|
|
294
294
|
return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
|
|
295
295
|
}
|
|
296
296
|
function S(e, t) {
|
|
297
|
-
let n = ge(
|
|
297
|
+
let n = x(ge(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 = ge(e), i = x(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
|
|
@@ -671,14 +671,14 @@ function I(e) {
|
|
|
671
671
|
function L(e) {
|
|
672
672
|
return (e ?? "").trim().toLowerCase();
|
|
673
673
|
}
|
|
674
|
-
var
|
|
674
|
+
var je = {
|
|
675
675
|
hevc: "hvc1.1.6.L93.90",
|
|
676
676
|
dv: "dvh1.05.06",
|
|
677
677
|
av1: "av01.0.05M.08",
|
|
678
678
|
vp9: "vp09.00.10.08"
|
|
679
|
-
},
|
|
680
|
-
function
|
|
681
|
-
let t = L(e), n =
|
|
679
|
+
}, Me = /* @__PURE__ */ new Map(), R = /* @__PURE__ */ new Map();
|
|
680
|
+
function Ne(e) {
|
|
681
|
+
let t = L(e), n = Me.get(t);
|
|
682
682
|
if (n) return n;
|
|
683
683
|
let r = {
|
|
684
684
|
initDataTypes: ["cenc"],
|
|
@@ -696,23 +696,23 @@ function Me(e) {
|
|
|
696
696
|
} catch {
|
|
697
697
|
return !1;
|
|
698
698
|
}
|
|
699
|
-
})().then((e) => (
|
|
700
|
-
return
|
|
699
|
+
})().then((e) => (R.set(t, e), e));
|
|
700
|
+
return Me.set(t, i), i;
|
|
701
701
|
}
|
|
702
|
-
function
|
|
703
|
-
if (j()) for (let e of Object.values(
|
|
702
|
+
function Pe() {
|
|
703
|
+
if (j()) for (let e of Object.values(je)) Ne(e);
|
|
704
704
|
}
|
|
705
|
-
function
|
|
705
|
+
function Fe(e) {
|
|
706
706
|
let t = I(e);
|
|
707
|
-
if (t) return t === "avc" ? !0 :
|
|
707
|
+
if (t) return t === "avc" ? !0 : R.get(L(e)) ?? R.get(L(je[t]));
|
|
708
708
|
}
|
|
709
709
|
//#endregion
|
|
710
710
|
//#region src/core/drm/support.ts
|
|
711
|
-
var
|
|
711
|
+
var Ie = 5e3, Le = "video/mp4; codecs=\"avc1.42E01E\"", Re = "audio/mp4; codecs=\"mp4a.40.2\"", ze = {
|
|
712
712
|
widevine: ["com.widevine.alpha"],
|
|
713
713
|
fairplay: ["com.apple.fps"]
|
|
714
714
|
};
|
|
715
|
-
function
|
|
715
|
+
function Be(e) {
|
|
716
716
|
return e === "fairplay" ? [{
|
|
717
717
|
initDataTypes: [
|
|
718
718
|
"sinf",
|
|
@@ -720,30 +720,30 @@ function ze(e) {
|
|
|
720
720
|
"cenc"
|
|
721
721
|
],
|
|
722
722
|
videoCapabilities: [{
|
|
723
|
-
contentType:
|
|
723
|
+
contentType: Le,
|
|
724
724
|
robustness: "",
|
|
725
725
|
encryptionScheme: "cbcs"
|
|
726
726
|
}],
|
|
727
727
|
audioCapabilities: [{
|
|
728
|
-
contentType:
|
|
728
|
+
contentType: Re,
|
|
729
729
|
robustness: "",
|
|
730
730
|
encryptionScheme: "cbcs"
|
|
731
731
|
}]
|
|
732
732
|
}] : N("com.widevine.alpha", [{
|
|
733
733
|
initDataTypes: ["cenc"],
|
|
734
734
|
videoCapabilities: [{
|
|
735
|
-
contentType:
|
|
735
|
+
contentType: Le,
|
|
736
736
|
robustness: F.video,
|
|
737
737
|
encryptionScheme: F.scheme
|
|
738
738
|
}],
|
|
739
739
|
audioCapabilities: [{
|
|
740
|
-
contentType:
|
|
740
|
+
contentType: Re,
|
|
741
741
|
robustness: F.audio,
|
|
742
742
|
encryptionScheme: F.scheme
|
|
743
743
|
}]
|
|
744
744
|
}]);
|
|
745
745
|
}
|
|
746
|
-
function
|
|
746
|
+
function Ve(e, t) {
|
|
747
747
|
return new Promise((n, r) => {
|
|
748
748
|
let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
|
|
749
749
|
e.then((e) => {
|
|
@@ -753,8 +753,8 @@ function Be(e, t) {
|
|
|
753
753
|
});
|
|
754
754
|
});
|
|
755
755
|
}
|
|
756
|
-
async function
|
|
757
|
-
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ??
|
|
756
|
+
async function He(e = {}) {
|
|
757
|
+
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Ie, r = {};
|
|
758
758
|
if (typeof window < "u" && window.isSecureContext === !1) return {
|
|
759
759
|
verdict: "insecure-context",
|
|
760
760
|
detail: r
|
|
@@ -766,7 +766,7 @@ async function Ve(e = {}) {
|
|
|
766
766
|
};
|
|
767
767
|
let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
|
|
768
768
|
for (let e of t) {
|
|
769
|
-
let t =
|
|
769
|
+
let t = ze[e];
|
|
770
770
|
if (!t) {
|
|
771
771
|
r[e] = "unknown system";
|
|
772
772
|
continue;
|
|
@@ -777,7 +777,7 @@ async function Ve(e = {}) {
|
|
|
777
777
|
break;
|
|
778
778
|
}
|
|
779
779
|
try {
|
|
780
|
-
return await
|
|
780
|
+
return await Ve((await Ve(i(n, Be(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
|
|
781
781
|
verdict: "supported",
|
|
782
782
|
system: e,
|
|
783
783
|
detail: r
|
|
@@ -801,49 +801,49 @@ async function Ve(e = {}) {
|
|
|
801
801
|
}
|
|
802
802
|
//#endregion
|
|
803
803
|
//#region src/core/manifest.ts
|
|
804
|
-
var
|
|
805
|
-
function
|
|
806
|
-
return
|
|
804
|
+
var Ue = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
|
|
805
|
+
function We(e) {
|
|
806
|
+
return Ue.test(e);
|
|
807
807
|
}
|
|
808
808
|
//#endregion
|
|
809
809
|
//#region src/core/env.ts
|
|
810
|
-
var
|
|
810
|
+
var Ge = {
|
|
811
811
|
integration: "https://feed-dev.oddin-video.gg",
|
|
812
812
|
production: "https://feed.oddin-video.gg"
|
|
813
813
|
};
|
|
814
|
-
function
|
|
815
|
-
let t = Object.prototype.hasOwnProperty.call(
|
|
814
|
+
function Ke(e) {
|
|
815
|
+
let t = Object.prototype.hasOwnProperty.call(Ge, e) ? Ge[e] : void 0;
|
|
816
816
|
if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
|
|
817
817
|
return t;
|
|
818
818
|
}
|
|
819
819
|
//#endregion
|
|
820
820
|
//#region src/core/stats.ts
|
|
821
|
-
var
|
|
822
|
-
function
|
|
821
|
+
var qe = { droppedFrames: 0 };
|
|
822
|
+
function Je(e) {
|
|
823
823
|
try {
|
|
824
824
|
return new URL(e).host;
|
|
825
825
|
} catch {
|
|
826
826
|
return "";
|
|
827
827
|
}
|
|
828
828
|
}
|
|
829
|
-
var
|
|
830
|
-
function
|
|
829
|
+
var Ye = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
|
|
830
|
+
function Xe(e) {
|
|
831
831
|
if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
|
|
832
832
|
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 =
|
|
833
|
+
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || Ye.test(i.name)) && i.startTime >= n) {
|
|
834
|
+
let e = Je(i.name);
|
|
835
835
|
e && (t = e, n = i.startTime);
|
|
836
836
|
}
|
|
837
837
|
return t;
|
|
838
838
|
}
|
|
839
|
-
function
|
|
839
|
+
function z(e) {
|
|
840
840
|
let t = e.getVideoPlaybackQuality?.();
|
|
841
841
|
return {
|
|
842
842
|
dropped: t?.droppedVideoFrames ?? 0,
|
|
843
843
|
totalFrames: t?.totalVideoFrames ?? 0
|
|
844
844
|
};
|
|
845
845
|
}
|
|
846
|
-
var
|
|
846
|
+
var B = class {
|
|
847
847
|
video;
|
|
848
848
|
baseFrames = 0;
|
|
849
849
|
baseDropped = 0;
|
|
@@ -853,7 +853,7 @@ var Xe = class {
|
|
|
853
853
|
this.video = e;
|
|
854
854
|
}
|
|
855
855
|
read() {
|
|
856
|
-
let e =
|
|
856
|
+
let e = z(this.video);
|
|
857
857
|
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
858
|
dropped: this.baseDropped + e.dropped,
|
|
859
859
|
totalFrames: this.baseFrames + e.totalFrames
|
|
@@ -883,8 +883,8 @@ function Ze(e, t) {
|
|
|
883
883
|
}
|
|
884
884
|
//#endregion
|
|
885
885
|
//#region src/core/engine/native.ts
|
|
886
|
-
var Qe = 2e3, $e = 3, V = 500, et = 6e3, tt = .25, nt = 250, rt = .05;
|
|
887
|
-
function
|
|
886
|
+
var Qe = 2e3, $e = 3, V = 500, et = 6e3, tt = .25, nt = 250, rt = .05, it = 4;
|
|
887
|
+
function at(e) {
|
|
888
888
|
try {
|
|
889
889
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
890
890
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -900,7 +900,7 @@ function U() {
|
|
|
900
900
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
901
901
|
return e || t;
|
|
902
902
|
}
|
|
903
|
-
function
|
|
903
|
+
function ot() {
|
|
904
904
|
if (typeof navigator > "u" || !U()) return !1;
|
|
905
905
|
let e = navigator.userAgent ?? "";
|
|
906
906
|
return /iPhone|iPad|iPod/.test(e) ? !0 : /Macintosh/.test(e) && typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1;
|
|
@@ -931,7 +931,7 @@ var W = class {
|
|
|
931
931
|
frameCounter;
|
|
932
932
|
detachFrames = null;
|
|
933
933
|
constructor(e) {
|
|
934
|
-
this.deps = e, this.frameCounter = new
|
|
934
|
+
this.deps = e, this.frameCounter = new B(e.video), this.loadStarted = e.deferLoad !== !0, this.builtAt = typeof performance < "u" ? performance.now() : 0;
|
|
935
935
|
}
|
|
936
936
|
async load() {
|
|
937
937
|
this.detachFrames ??= this.frameCounter.attach();
|
|
@@ -952,7 +952,7 @@ var W = class {
|
|
|
952
952
|
type: "error",
|
|
953
953
|
error: new n("INTERNAL", 0, "native HLS playback error"),
|
|
954
954
|
fatal: !0
|
|
955
|
-
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src =
|
|
955
|
+
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = ct(t.manifestUrl, t.analytics?.sid), e.load();
|
|
956
956
|
}
|
|
957
957
|
startLoad() {
|
|
958
958
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -974,7 +974,7 @@ var W = class {
|
|
|
974
974
|
});
|
|
975
975
|
this.onEncrypted = (n) => {
|
|
976
976
|
let i = n;
|
|
977
|
-
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
977
|
+
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = at(i.initData), (async () => {
|
|
978
978
|
try {
|
|
979
979
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
980
980
|
initDataTypes: [i.initDataType],
|
|
@@ -1073,10 +1073,10 @@ var W = class {
|
|
|
1073
1073
|
droppedFrames: t.dropped,
|
|
1074
1074
|
decodedFrames: t.totalFrames
|
|
1075
1075
|
};
|
|
1076
|
-
if (this.cdnHost ||=
|
|
1076
|
+
if (this.cdnHost ||= Xe(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
|
|
1077
1077
|
n.isLive = !0;
|
|
1078
1078
|
let t = this.liveEdgeEstimate(), r = t == null ? NaN : t - e.currentTime;
|
|
1079
|
-
Number.isFinite(r) && (n.atLiveEdge = r <=
|
|
1079
|
+
Number.isFinite(r) && (n.atLiveEdge = r <= it, !e.paused && r >= 0 && (n.latencySeconds = r));
|
|
1080
1080
|
} else Number.isFinite(e.duration) && e.duration > 0 && (n.isLive = !1);
|
|
1081
1081
|
return n;
|
|
1082
1082
|
}
|
|
@@ -1123,7 +1123,7 @@ var W = class {
|
|
|
1123
1123
|
this.lastBufferedEnd = null, this.bufferedAdvancedAt = null;
|
|
1124
1124
|
}, e.addEventListener("seeking", this.onEdgeReset), e.addEventListener("emptied", this.onEdgeReset), this.edgeTimer = setInterval(() => {
|
|
1125
1125
|
if (e.duration !== Infinity) return;
|
|
1126
|
-
let t =
|
|
1126
|
+
let t = st(e, e.currentTime);
|
|
1127
1127
|
t != null && ((this.lastBufferedEnd == null || Math.abs(t - this.lastBufferedEnd) >= rt) && (this.bufferedAdvancedAt = G()), this.lastBufferedEnd = t);
|
|
1128
1128
|
}, nt);
|
|
1129
1129
|
}
|
|
@@ -1133,7 +1133,7 @@ var W = class {
|
|
|
1133
1133
|
liveEdgeEstimate() {
|
|
1134
1134
|
let e = this.deps.video;
|
|
1135
1135
|
if (e.duration !== Infinity) return null;
|
|
1136
|
-
let t = this.liveEnd(), n =
|
|
1136
|
+
let t = this.liveEnd(), n = st(e, e.currentTime) ?? this.lastBufferedEnd;
|
|
1137
1137
|
if (n != null) {
|
|
1138
1138
|
let e = this.bufferedAdvancedAt, r = n + (e == null ? 0 : Math.max(0, (G() - e) / 1e3));
|
|
1139
1139
|
(t == null || r > t) && (t = r);
|
|
@@ -1170,7 +1170,7 @@ var W = class {
|
|
|
1170
1170
|
function G() {
|
|
1171
1171
|
return typeof performance < "u" ? performance.now() : Date.now();
|
|
1172
1172
|
}
|
|
1173
|
-
function
|
|
1173
|
+
function st(e, t) {
|
|
1174
1174
|
let n = e.buffered;
|
|
1175
1175
|
if (!n || !Number.isFinite(t)) return null;
|
|
1176
1176
|
for (let e = 0; e < n.length; e += 1) if (n.start(e) <= t + .1 && n.end(e) > t) {
|
|
@@ -1179,7 +1179,7 @@ function ot(e, t) {
|
|
|
1179
1179
|
}
|
|
1180
1180
|
return null;
|
|
1181
1181
|
}
|
|
1182
|
-
function
|
|
1182
|
+
function ct(e, t) {
|
|
1183
1183
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
1184
1184
|
}
|
|
1185
1185
|
//#endregion
|
|
@@ -1196,8 +1196,8 @@ function K(e, t = Date.now()) {
|
|
|
1196
1196
|
}
|
|
1197
1197
|
//#endregion
|
|
1198
1198
|
//#region src/core/engine/prefetch.ts
|
|
1199
|
-
var
|
|
1200
|
-
function
|
|
1199
|
+
var lt = 15e3, ut = 5e3, dt = 6;
|
|
1200
|
+
function ft(e) {
|
|
1201
1201
|
try {
|
|
1202
1202
|
let t = new URL(e);
|
|
1203
1203
|
return t.searchParams.delete("CMCD"), t.toString();
|
|
@@ -1205,7 +1205,7 @@ function dt(e) {
|
|
|
1205
1205
|
return e;
|
|
1206
1206
|
}
|
|
1207
1207
|
}
|
|
1208
|
-
var
|
|
1208
|
+
var pt = class {
|
|
1209
1209
|
cmcd;
|
|
1210
1210
|
entries = /* @__PURE__ */ new Map();
|
|
1211
1211
|
keyed = /* @__PURE__ */ new Set();
|
|
@@ -1228,10 +1228,10 @@ var ft = class {
|
|
|
1228
1228
|
}
|
|
1229
1229
|
prefetch(e, t, n) {
|
|
1230
1230
|
if (!this.isActive(t)) return;
|
|
1231
|
-
let r =
|
|
1231
|
+
let r = ft(e);
|
|
1232
1232
|
if (this.entries.has(r)) return;
|
|
1233
1233
|
let i = this.perTrack.get(t) ?? 0;
|
|
1234
|
-
if (i >=
|
|
1234
|
+
if (i >= dt) return;
|
|
1235
1235
|
this.perTrack.set(t, i + 1);
|
|
1236
1236
|
let a = new AbortController(), o = {
|
|
1237
1237
|
started: performance.now(),
|
|
@@ -1245,10 +1245,10 @@ var ft = class {
|
|
|
1245
1245
|
signal: a.signal
|
|
1246
1246
|
}).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
1247
|
this.entries.get(r) === o && (this.entries.delete(r), a.abort(), this.stats.expired += 1);
|
|
1248
|
-
},
|
|
1248
|
+
}, lt);
|
|
1249
1249
|
}
|
|
1250
1250
|
take(e) {
|
|
1251
|
-
let t =
|
|
1251
|
+
let t = ft(e), n = this.entries.get(t);
|
|
1252
1252
|
return n && this.entries.delete(t), n;
|
|
1253
1253
|
}
|
|
1254
1254
|
destroy() {
|
|
@@ -1268,13 +1268,13 @@ var ft = class {
|
|
|
1268
1268
|
}
|
|
1269
1269
|
}
|
|
1270
1270
|
};
|
|
1271
|
-
function
|
|
1271
|
+
function mt(t) {
|
|
1272
1272
|
let n = e.DefaultConfig?.loader;
|
|
1273
1273
|
if (typeof n != "function") return;
|
|
1274
1274
|
class r extends n {
|
|
1275
1275
|
served = !1;
|
|
1276
1276
|
cancelled = !1;
|
|
1277
|
-
stats =
|
|
1277
|
+
stats = ht();
|
|
1278
1278
|
load(e, n, r) {
|
|
1279
1279
|
let i = e.rangeEnd ? void 0 : t.take(e.url);
|
|
1280
1280
|
if (!i) {
|
|
@@ -1282,7 +1282,7 @@ function pt(t) {
|
|
|
1282
1282
|
return;
|
|
1283
1283
|
}
|
|
1284
1284
|
this.served = !0;
|
|
1285
|
-
let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs ||
|
|
1285
|
+
let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs || ut, s = setTimeout(() => {
|
|
1286
1286
|
!this.cancelled && this.served && (i.abort.abort(), t.stats.failed += 1, this.served = !1, super.load(e, n, r));
|
|
1287
1287
|
}, o);
|
|
1288
1288
|
i.bytes.then((o) => {
|
|
@@ -1309,7 +1309,7 @@ function pt(t) {
|
|
|
1309
1309
|
}
|
|
1310
1310
|
return r;
|
|
1311
1311
|
}
|
|
1312
|
-
function
|
|
1312
|
+
function ht() {
|
|
1313
1313
|
return {
|
|
1314
1314
|
aborted: !1,
|
|
1315
1315
|
loaded: 0,
|
|
@@ -1333,10 +1333,10 @@ function mt() {
|
|
|
1333
1333
|
}
|
|
1334
1334
|
};
|
|
1335
1335
|
}
|
|
1336
|
-
function
|
|
1336
|
+
function gt(e) {
|
|
1337
1337
|
return e === "audio" ? "audio" : "main";
|
|
1338
1338
|
}
|
|
1339
|
-
function
|
|
1339
|
+
function _t(e, t) {
|
|
1340
1340
|
let n = [];
|
|
1341
1341
|
t.initSegment?.url && !t.initSegment.data && n.push({
|
|
1342
1342
|
url: t.initSegment.url,
|
|
@@ -1355,24 +1355,24 @@ function gt(e, t) {
|
|
|
1355
1355
|
}
|
|
1356
1356
|
//#endregion
|
|
1357
1357
|
//#region src/core/engine/hls.ts
|
|
1358
|
-
function
|
|
1358
|
+
function vt() {
|
|
1359
1359
|
return e.isSupported();
|
|
1360
1360
|
}
|
|
1361
|
-
var
|
|
1362
|
-
function
|
|
1361
|
+
var yt = 3, bt = 5, xt = 3, St = 1e4, Ct = 3e4, wt = 12e3, Tt = 3e3, Et = .02, Dt = 6e3, Ot = .5, kt = 3, At = .5, jt = 1.1, Mt = .25, Nt = 5e3, Pt = 4e3, Ft = 2, It = 5, Lt = 2, Rt = 2, zt = 4, Bt = 4, Vt = 2e3, Ht = 3e4, Ut = .2, Wt = 30, Gt = 2, Kt = 2, qt = 9, Jt = .5, Yt = 64;
|
|
1362
|
+
function Xt(e) {
|
|
1363
1363
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
1364
1364
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
1365
1365
|
return;
|
|
1366
1366
|
}
|
|
1367
|
-
e.liveSyncDuration ??=
|
|
1368
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
1369
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
1367
|
+
e.liveSyncDuration ??= Kt;
|
|
1368
|
+
let t = Math.max(12, e.liveSyncDuration + qt);
|
|
1369
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Zt(e, e.liveSyncDuration);
|
|
1370
1370
|
}
|
|
1371
|
-
function
|
|
1371
|
+
function Zt(e, t) {
|
|
1372
1372
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
1373
1373
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
1374
1374
|
}
|
|
1375
|
-
var
|
|
1375
|
+
var Qt = class {
|
|
1376
1376
|
name = "hls";
|
|
1377
1377
|
hls = null;
|
|
1378
1378
|
deps;
|
|
@@ -1452,7 +1452,7 @@ var Zt = class {
|
|
|
1452
1452
|
frameCounter;
|
|
1453
1453
|
detachFrames = null;
|
|
1454
1454
|
constructor(e) {
|
|
1455
|
-
this.deps = e, this.frameCounter = new
|
|
1455
|
+
this.deps = e, this.frameCounter = new B(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
1456
1456
|
}
|
|
1457
1457
|
async load() {
|
|
1458
1458
|
this.detachFrames ??= this.frameCounter.attach();
|
|
@@ -1465,7 +1465,7 @@ var Zt = class {
|
|
|
1465
1465
|
});
|
|
1466
1466
|
return;
|
|
1467
1467
|
}
|
|
1468
|
-
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ae(r),
|
|
1468
|
+
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ae(r), Pe()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
|
|
1469
1469
|
let e = this.hls;
|
|
1470
1470
|
if (document.visibilityState !== "visible" || !e) return;
|
|
1471
1471
|
let t = e.liveSyncPosition;
|
|
@@ -1488,7 +1488,7 @@ var Zt = class {
|
|
|
1488
1488
|
}
|
|
1489
1489
|
this.loadSuspended = !0;
|
|
1490
1490
|
}
|
|
1491
|
-
},
|
|
1491
|
+
}, Nt));
|
|
1492
1492
|
}
|
|
1493
1493
|
resumeLoading() {
|
|
1494
1494
|
if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.resetChaseWindow(), this.resetFrameDropWindow(), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
|
|
@@ -1520,7 +1520,7 @@ var Zt = class {
|
|
|
1520
1520
|
let t = e.liveSyncPosition;
|
|
1521
1521
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1522
1522
|
let { video: n } = this.deps;
|
|
1523
|
-
n.currentTime <= t +
|
|
1523
|
+
n.currentTime <= t + Jt || (n.currentTime = t);
|
|
1524
1524
|
}
|
|
1525
1525
|
reanchorPartTimeline(e, t) {
|
|
1526
1526
|
let { frag: n, part: r } = t;
|
|
@@ -1532,7 +1532,7 @@ var Zt = class {
|
|
|
1532
1532
|
let o = n.sn, s = i.fragments.find((e) => e && e.sn === o) ?? (i.fragmentHint?.sn === o ? i.fragmentHint : void 0);
|
|
1533
1533
|
if (!s) return;
|
|
1534
1534
|
let c = a.startPTS - s.start;
|
|
1535
|
-
if (!(!Number.isFinite(c) || Math.abs(c) <
|
|
1535
|
+
if (!(!Number.isFinite(c) || Math.abs(c) < Et)) {
|
|
1536
1536
|
for (let e of i.fragments) e && e.setStart(e.start + c);
|
|
1537
1537
|
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
1538
|
}
|
|
@@ -1545,6 +1545,7 @@ var Zt = class {
|
|
|
1545
1545
|
enableWorker: !o,
|
|
1546
1546
|
lowLatencyMode: o,
|
|
1547
1547
|
backBufferLength: 90,
|
|
1548
|
+
liveDurationInfinity: !0,
|
|
1548
1549
|
maxBufferHole: .5,
|
|
1549
1550
|
maxLiveSyncPlaybackRate: 1.1,
|
|
1550
1551
|
abrEwmaDefaultEstimate: 1e6,
|
|
@@ -1571,7 +1572,7 @@ var Zt = class {
|
|
|
1571
1572
|
return;
|
|
1572
1573
|
}
|
|
1573
1574
|
let l = this.hls, u, d = new Promise((e) => {
|
|
1574
|
-
u = setTimeout(() => e(void 0),
|
|
1575
|
+
u = setTimeout(() => e(void 0), St);
|
|
1575
1576
|
});
|
|
1576
1577
|
return Promise.race([c().catch(() => void 0), d]).finally(() => clearTimeout(u)).then((e) => {
|
|
1577
1578
|
if (!this.hls || this.hls !== l) throw Error("havik-player: engine torn down during refresh");
|
|
@@ -1587,20 +1588,20 @@ var Zt = class {
|
|
|
1587
1588
|
...c
|
|
1588
1589
|
};
|
|
1589
1590
|
if (this.prefetch?.destroy(), this.prefetch = null, u && this.deps.mediaDuringKey !== !1 && !d.fLoader) {
|
|
1590
|
-
let e = new
|
|
1591
|
+
let e = new pt({
|
|
1591
1592
|
sessionId: n.analytics?.sid,
|
|
1592
1593
|
contentId: n.matchUrn
|
|
1593
|
-
}), t =
|
|
1594
|
+
}), t = mt(e);
|
|
1594
1595
|
t && (this.prefetch = e, d.fLoader = t);
|
|
1595
1596
|
}
|
|
1596
|
-
|
|
1597
|
+
Xt(d), this.catchUpRate = typeof d.maxLiveSyncPlaybackRate == "number" ? d.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (d.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = d.autoStartLoad !== !1;
|
|
1597
1598
|
let f = new e(d);
|
|
1598
1599
|
if (this.hls = f, f.on(e.Events.FRAG_PARSED, (e, t) => this.reanchorPartTimeline(f, t)), f.on(e.Events.MANIFEST_PARSED, () => {
|
|
1599
1600
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, u && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && this.dropLevelsWidevineCannotPlay(f), this.measureLadder(f), this.applySizeCap(), this.loadSuspended = !1, t.paused && this.schedulePauseSuspend(), l({ type: "ready" });
|
|
1600
1601
|
}), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1601
1602
|
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(() => {
|
|
1602
1603
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1603
|
-
},
|
|
1604
|
+
}, Ct)));
|
|
1604
1605
|
}), f.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1605
1606
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1606
1607
|
}), f.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
@@ -1608,10 +1609,10 @@ var Zt = class {
|
|
|
1608
1609
|
let n = t?.frag?.stats, r = n?.loaded;
|
|
1609
1610
|
typeof r == "number" && (this.bytesLoaded += r), !this.reportedFirstBytes && typeof r == "number" && r > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
|
|
1610
1611
|
let i = n?.loading;
|
|
1611
|
-
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 >
|
|
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 > Yt && this.requestTimesMs.shift());
|
|
1612
1613
|
let a = t?.frag?.url;
|
|
1613
1614
|
if (a) {
|
|
1614
|
-
let e =
|
|
1615
|
+
let e = Je(a);
|
|
1615
1616
|
e && (this.cdnHost = e);
|
|
1616
1617
|
}
|
|
1617
1618
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1625,15 +1626,15 @@ var Zt = class {
|
|
|
1625
1626
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.prefetch) {
|
|
1626
1627
|
let t = this.prefetch;
|
|
1627
1628
|
f.on(e.Events.KEY_LOADING, (e, n) => {
|
|
1628
|
-
let r = n?.frag, i =
|
|
1629
|
-
if (r && t.isActive(i)) for (let e of
|
|
1630
|
-
}), f.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(
|
|
1629
|
+
let r = n?.frag, i = gt(r?.type);
|
|
1630
|
+
if (r && t.isActive(i)) for (let e of _t(f, r)) t.prefetch(e.url, i, e.kind);
|
|
1631
|
+
}), f.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(gt(n?.frag?.type)));
|
|
1631
1632
|
}
|
|
1632
1633
|
f.on(e.Events.KEY_LOADED, () => {
|
|
1633
1634
|
u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
|
|
1634
1635
|
}), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1635
1636
|
this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.checkFrameDrops();
|
|
1636
|
-
},
|
|
1637
|
+
}, Tt), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1637
1638
|
this.renditionSwitches += 1;
|
|
1638
1639
|
let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
|
|
1639
1640
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
|
|
@@ -1697,7 +1698,7 @@ var Zt = class {
|
|
|
1697
1698
|
return;
|
|
1698
1699
|
}
|
|
1699
1700
|
this.capTimer && clearTimeout(this.capTimer);
|
|
1700
|
-
let t = e > this.sizeCapLevel ?
|
|
1701
|
+
let t = e > this.sizeCapLevel ? Vt : Ht;
|
|
1701
1702
|
this.capTimer = setTimeout(() => {
|
|
1702
1703
|
this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
|
|
1703
1704
|
}, t);
|
|
@@ -1707,9 +1708,9 @@ var Zt = class {
|
|
|
1707
1708
|
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;
|
|
1708
1709
|
}
|
|
1709
1710
|
dropLevelsWidevineCannotPlay(e) {
|
|
1710
|
-
this.removeLevelsWhere(e, (e) =>
|
|
1711
|
+
this.removeLevelsWhere(e, (e) => Fe(e) !== !0);
|
|
1711
1712
|
let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && I(e) !== "avc" && !!I(e)));
|
|
1712
|
-
for (let n of t)
|
|
1713
|
+
for (let n of t) Ne(n).then((t) => {
|
|
1713
1714
|
t || this.hls !== e || this.removeLevelsWhere(e, (e) => e === n) && (this.measureLadder(e), this.applySizeCap());
|
|
1714
1715
|
});
|
|
1715
1716
|
}
|
|
@@ -1720,7 +1721,7 @@ var Zt = class {
|
|
|
1720
1721
|
a && I(a) && t(a) && (r.push(n), i.add(a));
|
|
1721
1722
|
}), !r.length) return !1;
|
|
1722
1723
|
let a = [...i].join(", ");
|
|
1723
|
-
if (!n.some((e, t) => r.includes(t) ? !1 : !I(e.videoCodec) ||
|
|
1724
|
+
if (!n.some((e, t) => r.includes(t) ? !1 : !I(e.videoCodec) || Fe(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
|
|
1724
1725
|
for (let t = r.length - 1; t >= 0; --t) e.removeLevel(r[t]);
|
|
1725
1726
|
return console.info(`havik-player: skipped ${r.length} rendition(s) Widevine cannot play on this browser (${a})`), !0;
|
|
1726
1727
|
}
|
|
@@ -1818,7 +1819,7 @@ var Zt = class {
|
|
|
1818
1819
|
return;
|
|
1819
1820
|
}
|
|
1820
1821
|
let e = Date.now() - this.lastAdvanceMs;
|
|
1821
|
-
!this.chaseSuspended && e >
|
|
1822
|
+
!this.chaseSuspended && e > Dt && this.suspendChasing(), e > wt && this.emitEnded("stalled");
|
|
1822
1823
|
}
|
|
1823
1824
|
resetStarvationWindow() {
|
|
1824
1825
|
this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
|
|
@@ -1833,7 +1834,7 @@ var Zt = class {
|
|
|
1833
1834
|
this.resetStarvationWindow();
|
|
1834
1835
|
return;
|
|
1835
1836
|
}
|
|
1836
|
-
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs <
|
|
1837
|
+
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < Dt, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > Pt, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = z(t), c = o - s, l = c !== this.starvedFrames;
|
|
1837
1838
|
if (this.starvedFrames = c, !a || l) {
|
|
1838
1839
|
(t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
|
|
1839
1840
|
return;
|
|
@@ -1842,12 +1843,12 @@ var Zt = class {
|
|
|
1842
1843
|
this.resetStarvationWindow();
|
|
1843
1844
|
return;
|
|
1844
1845
|
}
|
|
1845
|
-
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 >
|
|
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 > zt && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= Lt && (this.clearKick(), this.starvationRebuilds < Rt)) {
|
|
1846
1847
|
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");
|
|
1847
1848
|
return;
|
|
1848
1849
|
}
|
|
1849
|
-
let u = i && this.starvedTicks >=
|
|
1850
|
-
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >=
|
|
1850
|
+
let u = i && this.starvedTicks >= Ft, d = !i && this.deadTicks >= zt && this.recentMainFrags.reduce((e, t) => e + t, 0) >= Bt;
|
|
1851
|
+
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= It))) {
|
|
1851
1852
|
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");
|
|
1852
1853
|
try {
|
|
1853
1854
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -1862,7 +1863,7 @@ var Zt = class {
|
|
|
1862
1863
|
let t = e.latency, n = e.targetLatency;
|
|
1863
1864
|
if (typeof t != "number" || typeof n != "number" || !Number.isFinite(t)) return;
|
|
1864
1865
|
let r = t - n;
|
|
1865
|
-
!this.catchUpEngaged && r >
|
|
1866
|
+
!this.catchUpEngaged && r > Ot ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= Ot && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
|
|
1866
1867
|
let i = this.catchUpEngaged ? this.catchUpRate : 1;
|
|
1867
1868
|
e.config.maxLiveSyncPlaybackRate !== i && (e.config.maxLiveSyncPlaybackRate = i);
|
|
1868
1869
|
}
|
|
@@ -1883,16 +1884,16 @@ var Zt = class {
|
|
|
1883
1884
|
this.resetFrameDropWindow();
|
|
1884
1885
|
return;
|
|
1885
1886
|
}
|
|
1886
|
-
let { totalFrames: n, dropped: r } =
|
|
1887
|
-
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a <
|
|
1887
|
+
let { totalFrames: n, dropped: r } = z(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
|
|
1888
|
+
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < Wt || o < 0) {
|
|
1888
1889
|
this.fpsBadTicks = 0;
|
|
1889
1890
|
return;
|
|
1890
1891
|
}
|
|
1891
|
-
if (o <=
|
|
1892
|
+
if (o <= Ut * a) {
|
|
1892
1893
|
this.fpsBadTicks = 0;
|
|
1893
1894
|
return;
|
|
1894
1895
|
}
|
|
1895
|
-
if (this.fpsBadTicks += 1, this.fpsBadTicks <
|
|
1896
|
+
if (this.fpsBadTicks += 1, this.fpsBadTicks < Gt) return;
|
|
1896
1897
|
this.fpsBadTicks = 0;
|
|
1897
1898
|
let s = e.levels, c = s[e.currentLevel];
|
|
1898
1899
|
if (!c) return;
|
|
@@ -1909,20 +1910,20 @@ var Zt = class {
|
|
|
1909
1910
|
return;
|
|
1910
1911
|
}
|
|
1911
1912
|
let n = e.latency, r = t.playbackRate, i = e.config.maxLiveSyncPlaybackRate;
|
|
1912
|
-
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(
|
|
1913
|
+
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(jt, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
|
|
1913
1914
|
this.resetChaseWindow();
|
|
1914
1915
|
return;
|
|
1915
1916
|
}
|
|
1916
|
-
if (this.chaseLatency < 0 || this.chaseLatency - n >=
|
|
1917
|
+
if (this.chaseLatency < 0 || this.chaseLatency - n >= At) {
|
|
1917
1918
|
this.chaseLatency = n, this.chaseTicks = 0;
|
|
1918
1919
|
return;
|
|
1919
1920
|
}
|
|
1920
|
-
if (this.chaseTicks += 1, this.chaseTicks <
|
|
1921
|
+
if (this.chaseTicks += 1, this.chaseTicks < kt) return;
|
|
1921
1922
|
this.resetChaseWindow();
|
|
1922
1923
|
let a = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
|
|
1923
1924
|
if (!(a > 1)) return;
|
|
1924
1925
|
let o = typeof e.targetLatency == "number" ? e.targetLatency : 0, s = Math.min(n, a - 1);
|
|
1925
|
-
s < o +
|
|
1926
|
+
s < o + Mt || (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);
|
|
1926
1927
|
}
|
|
1927
1928
|
suspendChasing() {
|
|
1928
1929
|
let e = this.hls;
|
|
@@ -1967,7 +1968,7 @@ var Zt = class {
|
|
|
1967
1968
|
scheduleLicenseRetry(t) {
|
|
1968
1969
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
1969
1970
|
let n = t.response?.code ?? 0;
|
|
1970
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
1971
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= xt) return !1;
|
|
1971
1972
|
this.licenseRecoveries += 1;
|
|
1972
1973
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
1973
1974
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -1999,7 +2000,7 @@ var Zt = class {
|
|
|
1999
2000
|
return;
|
|
2000
2001
|
}
|
|
2001
2002
|
if (t.type === e.ErrorTypes.NETWORK_ERROR) {
|
|
2002
|
-
if (this.networkRecoveries <
|
|
2003
|
+
if (this.networkRecoveries < bt) {
|
|
2003
2004
|
this.networkRecoveries += 1;
|
|
2004
2005
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
2005
2006
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -2016,7 +2017,7 @@ var Zt = class {
|
|
|
2016
2017
|
return;
|
|
2017
2018
|
}
|
|
2018
2019
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
2019
|
-
if (this.mediaRecoveries <
|
|
2020
|
+
if (this.mediaRecoveries < yt) {
|
|
2020
2021
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
2021
2022
|
return;
|
|
2022
2023
|
}
|
|
@@ -2040,19 +2041,19 @@ var Zt = class {
|
|
|
2040
2041
|
let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
|
|
2041
2042
|
return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
|
|
2042
2043
|
}
|
|
2043
|
-
},
|
|
2044
|
+
}, $t = 15e3, en = 6e5, tn = 3e5, nn = 100, q = 1, rn = 1e3, an = 3e4, on = 1e3, sn = {
|
|
2044
2045
|
inline: "PRESENTATION_INLINE",
|
|
2045
2046
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
2046
2047
|
pip: "PRESENTATION_PIP"
|
|
2047
|
-
},
|
|
2048
|
+
}, cn = {
|
|
2048
2049
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
2049
2050
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
2050
2051
|
none: "KEY_SYSTEM_NONE"
|
|
2051
2052
|
};
|
|
2052
|
-
function
|
|
2053
|
+
function ln(e, t) {
|
|
2053
2054
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
2054
2055
|
}
|
|
2055
|
-
var
|
|
2056
|
+
var un = /* @__PURE__ */ new Set([
|
|
2056
2057
|
"INVALID_URN",
|
|
2057
2058
|
"NOT_FOUND",
|
|
2058
2059
|
"GONE",
|
|
@@ -2072,7 +2073,7 @@ var ln = /* @__PURE__ */ new Set([
|
|
|
2072
2073
|
ended: "PLAYER_STATE_ENDED",
|
|
2073
2074
|
error: "PLAYER_STATE_ERROR"
|
|
2074
2075
|
};
|
|
2075
|
-
function
|
|
2076
|
+
function dn(e) {
|
|
2076
2077
|
try {
|
|
2077
2078
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
2078
2079
|
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);
|
|
@@ -2080,8 +2081,8 @@ function un(e) {
|
|
|
2080
2081
|
return;
|
|
2081
2082
|
}
|
|
2082
2083
|
}
|
|
2083
|
-
var
|
|
2084
|
-
function
|
|
2084
|
+
var fn = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), pn = /* @__PURE__ */ new Set(), Y = /* @__PURE__ */ new Set(), X = /* @__PURE__ */ new Set(), mn = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
|
|
2085
|
+
function hn(e) {
|
|
2085
2086
|
if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
|
|
2086
2087
|
let t;
|
|
2087
2088
|
try {
|
|
@@ -2090,19 +2091,19 @@ function mn(e) {
|
|
|
2090
2091
|
} catch {
|
|
2091
2092
|
return;
|
|
2092
2093
|
}
|
|
2093
|
-
if (
|
|
2094
|
-
Y.add(t), g(
|
|
2094
|
+
if (pn.has(t) && !Y.has(t)) {
|
|
2095
|
+
Y.add(t), g(mn(new URL(t).origin));
|
|
2095
2096
|
for (let e of X) e.noteCspBlocked();
|
|
2096
2097
|
}
|
|
2097
2098
|
}
|
|
2098
|
-
function
|
|
2099
|
+
function Z(e, t) {
|
|
2099
2100
|
return g(t, e), { disabledReason: t };
|
|
2100
2101
|
}
|
|
2101
2102
|
function gn(e, t, n) {
|
|
2102
|
-
if (n) return t && !
|
|
2103
|
+
if (n) return t && !fn(t, n) && g(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
|
|
2103
2104
|
if (t) return { endpoint: t };
|
|
2104
|
-
if (t !== void 0) return
|
|
2105
|
-
let r =
|
|
2105
|
+
if (t !== void 0) return Z("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).");
|
|
2106
|
+
let r = dn(e);
|
|
2106
2107
|
if (r) return { endpoint: r };
|
|
2107
2108
|
let i;
|
|
2108
2109
|
try {
|
|
@@ -2110,7 +2111,7 @@ function gn(e, t, n) {
|
|
|
2110
2111
|
} catch {
|
|
2111
2112
|
i = e;
|
|
2112
2113
|
}
|
|
2113
|
-
return
|
|
2114
|
+
return Z(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).`);
|
|
2114
2115
|
}
|
|
2115
2116
|
var _n = class {
|
|
2116
2117
|
opts;
|
|
@@ -2194,8 +2195,8 @@ var _n = class {
|
|
|
2194
2195
|
constructor(e) {
|
|
2195
2196
|
this.opts = {
|
|
2196
2197
|
...e,
|
|
2197
|
-
heartbeatMs: e.heartbeatMs ??
|
|
2198
|
-
idleMs: e.idleMs ??
|
|
2198
|
+
heartbeatMs: e.heartbeatMs ?? $t,
|
|
2199
|
+
idleMs: e.idleMs ?? en
|
|
2199
2200
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
|
|
2200
2201
|
try {
|
|
2201
2202
|
let e = new URL(this.url);
|
|
@@ -2212,11 +2213,11 @@ var _n = class {
|
|
|
2212
2213
|
sdkVersion: this.opts.sdkVersion,
|
|
2213
2214
|
...this.opts.environment
|
|
2214
2215
|
};
|
|
2215
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
2216
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), rn), 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 && pn.add(this.cspKey), document.addEventListener("securitypolicyviolation", hn), X.add(this), this.noteCspBlocked(), this.onVisibility());
|
|
2216
2217
|
}
|
|
2217
2218
|
checkSuspension(e) {
|
|
2218
2219
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
2219
|
-
let t = Math.max(this.opts.idleMs,
|
|
2220
|
+
let t = Math.max(this.opts.idleMs, tn);
|
|
2220
2221
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
2221
2222
|
}
|
|
2222
2223
|
syncIdle(e) {
|
|
@@ -2239,12 +2240,12 @@ var _n = class {
|
|
|
2239
2240
|
let a = {
|
|
2240
2241
|
fromState: J[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2241
2242
|
toState: J[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2242
|
-
presentation:
|
|
2243
|
+
presentation: sn[this.presentation]
|
|
2243
2244
|
}, o = this.causeOf(e, t, i);
|
|
2244
2245
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
2245
2246
|
}
|
|
2246
2247
|
seekInduced(e) {
|
|
2247
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
2248
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < on;
|
|
2248
2249
|
}
|
|
2249
2250
|
causeOf(e, t, n) {
|
|
2250
2251
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -2318,7 +2319,7 @@ var _n = class {
|
|
|
2318
2319
|
let r = n ?? "";
|
|
2319
2320
|
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";
|
|
2320
2321
|
if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
|
|
2321
|
-
if (
|
|
2322
|
+
if (un.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
2322
2323
|
let i = t ?? "";
|
|
2323
2324
|
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";
|
|
2324
2325
|
}
|
|
@@ -2365,14 +2366,14 @@ var _n = class {
|
|
|
2365
2366
|
if (this.lastRequestCount = g, _ > 0) {
|
|
2366
2367
|
o.requestCountDelta = _;
|
|
2367
2368
|
let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
|
|
2368
|
-
n.length > 0 && (o.requestTimeP50Ms =
|
|
2369
|
+
n.length > 0 && (o.requestTimeP50Ms = ln(n, 50), o.requestTimeP95Ms = ln(n, 95));
|
|
2369
2370
|
}
|
|
2370
2371
|
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();
|
|
2371
2372
|
}
|
|
2372
2373
|
maybeEmitMediaInfo(e) {
|
|
2373
2374
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
2374
2375
|
let t = {};
|
|
2375
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
2376
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = cn[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);
|
|
2376
2377
|
let n = JSON.stringify(t);
|
|
2377
2378
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
2378
2379
|
}
|
|
@@ -2392,7 +2393,7 @@ var _n = class {
|
|
|
2392
2393
|
let c = r?.positionMs ?? 0;
|
|
2393
2394
|
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));
|
|
2394
2395
|
let l = e !== "END_REASON_ENDED";
|
|
2395
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
2396
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= an && (i.abandonAfterStallMs = Math.max(q, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= an && (i.abandonAfterErrorMs = Math.max(q, Math.round(n - this.lastErrorMs))), this.fullscreenTotalMs > 0 && (i.fullscreenTimeMs = Math.round(this.fullscreenTotalMs)), this.pipTotalMs > 0 && (i.pipTimeMs = Math.round(this.pipTotalMs)), this.volumeChanges > 0 && (i.volumeChanges = this.volumeChanges), this.muteChanges > 0 && (i.muteChanges = this.muteChanges);
|
|
2396
2397
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
2397
2398
|
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");
|
|
2398
2399
|
}
|
|
@@ -2412,13 +2413,13 @@ var _n = class {
|
|
|
2412
2413
|
};
|
|
2413
2414
|
}
|
|
2414
2415
|
noteCspBlocked() {
|
|
2415
|
-
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(
|
|
2416
|
+
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(mn(new URL(this.url).origin)));
|
|
2416
2417
|
}
|
|
2417
2418
|
cspBlocked() {
|
|
2418
2419
|
return !!this.cspKey && Y.has(this.cspKey);
|
|
2419
2420
|
}
|
|
2420
2421
|
enqueue(e) {
|
|
2421
|
-
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
2422
|
+
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > nn;) {
|
|
2422
2423
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
2423
2424
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
2424
2425
|
}
|
|
@@ -2518,7 +2519,7 @@ async function Sn() {
|
|
|
2518
2519
|
}
|
|
2519
2520
|
//#endregion
|
|
2520
2521
|
//#region src/core/version.ts
|
|
2521
|
-
var Cn = "2.16.
|
|
2522
|
+
var Cn = "2.16.11", wn = {
|
|
2522
2523
|
accent: "#E1B600",
|
|
2523
2524
|
accentText: "#1B1C23",
|
|
2524
2525
|
background: "#0e0f13",
|
|
@@ -2573,7 +2574,7 @@ var jn = {
|
|
|
2573
2574
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
2574
2575
|
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\"/>"
|
|
2575
2576
|
};
|
|
2576
|
-
function
|
|
2577
|
+
function Q(e) {
|
|
2577
2578
|
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${jn[e]}</svg>`;
|
|
2578
2579
|
}
|
|
2579
2580
|
//#endregion
|
|
@@ -2644,12 +2645,12 @@ var In = class {
|
|
|
2644
2645
|
"aria-label": r,
|
|
2645
2646
|
title: r
|
|
2646
2647
|
});
|
|
2647
|
-
return i.innerHTML =
|
|
2648
|
+
return i.innerHTML = Q(n), i;
|
|
2648
2649
|
};
|
|
2649
2650
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
2650
2651
|
type: "button",
|
|
2651
2652
|
"aria-label": "Play"
|
|
2652
|
-
}), this.center.innerHTML =
|
|
2653
|
+
}), this.center.innerHTML = Q("play"), this.spinner = t("div", "havik-spinner"), this.spinner.style.display = "none", this.overlay.append(this.center, this.spinner), this.gradient = t("div", "havik-gradient"), this.bar = t("div", "havik-bar"), this.seek = t("div", "havik-seek", {
|
|
2653
2654
|
role: "slider",
|
|
2654
2655
|
"aria-label": "Seek",
|
|
2655
2656
|
"aria-valuemin": "0",
|
|
@@ -2667,7 +2668,7 @@ var In = class {
|
|
|
2667
2668
|
"aria-label": "Volume"
|
|
2668
2669
|
});
|
|
2669
2670
|
let a = t("div", "havik-vol");
|
|
2670
|
-
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML =
|
|
2671
|
+
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Q("liveDot");
|
|
2671
2672
|
let o = this.doc.createElement("span");
|
|
2672
2673
|
o.textContent = "LIVE", this.liveGo = t("button", "havik-live__go", { type: "button" }), this.liveGo.textContent = "Go live", this.live.append(o, this.liveGo), this.time = t("div", "havik-time"), this.time.textContent = "0:00", this.time.style.display = "none";
|
|
2673
2674
|
let s = t("div", "havik-spacer");
|
|
@@ -2751,12 +2752,12 @@ var In = class {
|
|
|
2751
2752
|
}
|
|
2752
2753
|
if (e === "preplay") {
|
|
2753
2754
|
let e = this.doc.createElement("button");
|
|
2754
|
-
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML =
|
|
2755
|
+
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);
|
|
2755
2756
|
} else {
|
|
2756
2757
|
let r = this.doc.createElement("div");
|
|
2757
2758
|
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Pn.has(this.lastError.code)) {
|
|
2758
2759
|
let e = this.doc.createElement("button");
|
|
2759
|
-
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${
|
|
2760
|
+
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);
|
|
2760
2761
|
}
|
|
2761
2762
|
}
|
|
2762
2763
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -2939,7 +2940,7 @@ var In = class {
|
|
|
2939
2940
|
}
|
|
2940
2941
|
}
|
|
2941
2942
|
setIcon(e, t) {
|
|
2942
|
-
e.innerHTML =
|
|
2943
|
+
e.innerHTML = Q(t);
|
|
2943
2944
|
}
|
|
2944
2945
|
destroy() {
|
|
2945
2946
|
this.hideTimer && clearTimeout(this.hideTimer), this.tapTimer && clearTimeout(this.tapTimer);
|
|
@@ -2972,25 +2973,25 @@ function Bn(e) {
|
|
|
2972
2973
|
}
|
|
2973
2974
|
//#endregion
|
|
2974
2975
|
//#region src/managed/index.ts
|
|
2975
|
-
var Vn = 6e3,
|
|
2976
|
-
function
|
|
2976
|
+
var Vn = 6e3, Hn = 45e3, Un = 2e3, Wn = 3, Gn = 2e3, Kn = 48e4, qn = "keySystemLicenseRequestFailed";
|
|
2977
|
+
function Jn(e) {
|
|
2977
2978
|
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)})`);
|
|
2978
|
-
if (e.env !== void 0) return
|
|
2979
|
+
if (e.env !== void 0) return Ke(e.env);
|
|
2979
2980
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
2980
2981
|
return e.baseUrl;
|
|
2981
2982
|
}
|
|
2982
|
-
async function
|
|
2983
|
+
async function Yn(e) {
|
|
2983
2984
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
2984
|
-
let t =
|
|
2985
|
+
let t = Jn(e);
|
|
2985
2986
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
2986
2987
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
2987
|
-
let r = new
|
|
2988
|
+
let r = new Xn({
|
|
2988
2989
|
...e,
|
|
2989
2990
|
baseUrl: t
|
|
2990
2991
|
});
|
|
2991
2992
|
return await r.start(), r;
|
|
2992
2993
|
}
|
|
2993
|
-
var
|
|
2994
|
+
var Xn = class {
|
|
2994
2995
|
opts;
|
|
2995
2996
|
abort = new AbortController();
|
|
2996
2997
|
listeners = {};
|
|
@@ -3037,7 +3038,7 @@ var Yn = class {
|
|
|
3037
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");
|
|
3038
3039
|
let e = ++this.loadGen, t = this.resolveOptions();
|
|
3039
3040
|
try {
|
|
3040
|
-
let n = await
|
|
3041
|
+
let n = await v(t);
|
|
3041
3042
|
if (await this.onResolved(n, e), e === this.loadGen && this._state === "error" && this._lastError) {
|
|
3042
3043
|
let e = this._lastError;
|
|
3043
3044
|
throw this.destroy(), e;
|
|
@@ -3064,7 +3065,7 @@ var Yn = class {
|
|
|
3064
3065
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
3065
3066
|
}
|
|
3066
3067
|
beginArmingByPolling(e) {
|
|
3067
|
-
|
|
3068
|
+
y({
|
|
3068
3069
|
...this.resolveOptions(),
|
|
3069
3070
|
signal: this.abort.signal,
|
|
3070
3071
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -3081,7 +3082,7 @@ var Yn = class {
|
|
|
3081
3082
|
setTimeout(() => {
|
|
3082
3083
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
3083
3084
|
phase: i ? "unavailable" : "tooEarly",
|
|
3084
|
-
retryInMs:
|
|
3085
|
+
retryInMs: Hn,
|
|
3085
3086
|
attempt: 1,
|
|
3086
3087
|
elapsedMs: 0,
|
|
3087
3088
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -3098,7 +3099,7 @@ var Yn = class {
|
|
|
3098
3099
|
}
|
|
3099
3100
|
}
|
|
3100
3101
|
}, h = () => {
|
|
3101
|
-
a || s || p() || (s = !0,
|
|
3102
|
+
a || s || p() || (s = !0, y({
|
|
3102
3103
|
...this.resolveOptions(),
|
|
3103
3104
|
signal: c.signal,
|
|
3104
3105
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -3106,7 +3107,7 @@ var Yn = class {
|
|
|
3106
3107
|
a || p() || c.signal.aborted || (a = !0, this.closeArming(), this.fail(e instanceof n ? e : new n("INTERNAL", 0, String(e))));
|
|
3107
3108
|
}));
|
|
3108
3109
|
}, g = () => {
|
|
3109
|
-
a || p() ||
|
|
3110
|
+
a || p() || v(this.resolveOptions()).then((e) => m(e)).catch((e) => {
|
|
3110
3111
|
if (!(a || p())) {
|
|
3111
3112
|
if (e instanceof n && o(e.code)) {
|
|
3112
3113
|
h();
|
|
@@ -3124,9 +3125,9 @@ var Yn = class {
|
|
|
3124
3125
|
eventsBaseUrl: t,
|
|
3125
3126
|
matchUrn: this.opts.matchUrn,
|
|
3126
3127
|
credential: this.opts.credential,
|
|
3127
|
-
onAlive: () => _(
|
|
3128
|
+
onAlive: () => _(Hn),
|
|
3128
3129
|
onState: (e) => {
|
|
3129
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
3130
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Un);
|
|
3130
3131
|
},
|
|
3131
3132
|
onError: () => h()
|
|
3132
3133
|
});
|
|
@@ -3190,7 +3191,7 @@ var Yn = class {
|
|
|
3190
3191
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, e));
|
|
3191
3192
|
}, 0),
|
|
3192
3193
|
sample: () => {
|
|
3193
|
-
let e = this.engine?.getStats() ??
|
|
3194
|
+
let e = this.engine?.getStats() ?? qe, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
|
|
3194
3195
|
return {
|
|
3195
3196
|
...e,
|
|
3196
3197
|
bufferedMs: Math.round(t * 1e3),
|
|
@@ -3231,9 +3232,9 @@ var Yn = class {
|
|
|
3231
3232
|
freshLicenseUrl: () => this.refreshLicense()
|
|
3232
3233
|
}, o = this.opts.engine ?? "auto";
|
|
3233
3234
|
if (o === "native") return new W(a);
|
|
3234
|
-
if (o === "hls") return new
|
|
3235
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && H(this.opts.video) && U() || !e.drmEnabled &&
|
|
3236
|
-
if (
|
|
3235
|
+
if (o === "hls") return new Qt(a);
|
|
3236
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && H(this.opts.video) && U() || !e.drmEnabled && ot() && H(this.opts.video)) return new W(a);
|
|
3237
|
+
if (vt()) return new Qt(a);
|
|
3237
3238
|
if (H(this.opts.video)) return new W(a);
|
|
3238
3239
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
3239
3240
|
}
|
|
@@ -3296,7 +3297,7 @@ var Yn = class {
|
|
|
3296
3297
|
r = 0, i = !1;
|
|
3297
3298
|
},
|
|
3298
3299
|
onError: () => {
|
|
3299
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
3300
|
+
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= Wn && (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.`))));
|
|
3300
3301
|
}
|
|
3301
3302
|
});
|
|
3302
3303
|
}
|
|
@@ -3318,7 +3319,7 @@ var Yn = class {
|
|
|
3318
3319
|
scheduleRejoin(e) {
|
|
3319
3320
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
3320
3321
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
3321
|
-
}, Math.random() *
|
|
3322
|
+
}, Math.random() * Un));
|
|
3322
3323
|
}
|
|
3323
3324
|
cancelRejoin() {
|
|
3324
3325
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -3373,7 +3374,7 @@ var Yn = class {
|
|
|
3373
3374
|
}
|
|
3374
3375
|
startStats() {
|
|
3375
3376
|
this.stopStats();
|
|
3376
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
3377
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Gn);
|
|
3377
3378
|
this.statsTimer = setInterval(() => {
|
|
3378
3379
|
if (!this.engine) return;
|
|
3379
3380
|
let e = this.engine.getStats();
|
|
@@ -3384,14 +3385,14 @@ var Yn = class {
|
|
|
3384
3385
|
this.statsTimer && clearInterval(this.statsTimer), this.statsTimer = void 0;
|
|
3385
3386
|
}
|
|
3386
3387
|
isStaleLicenseDenial(e) {
|
|
3387
|
-
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !==
|
|
3388
|
+
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== qn || e.error.httpStatus !== 403 ? !1 : K(this._descriptor?.drm?.widevine?.licenseUrl);
|
|
3388
3389
|
}
|
|
3389
3390
|
scheduleLicenseRefresh() {
|
|
3390
3391
|
if (this.stopRefresh(), !this._descriptor?.drmEnabled) return;
|
|
3391
3392
|
typeof document < "u" && this.engine?.name === "hls" && (this.onRefocus = () => {
|
|
3392
3393
|
document.visibilityState !== "visible" || this.destroyed || K(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
|
|
3393
3394
|
}, document.addEventListener("visibilitychange", this.onRefocus));
|
|
3394
|
-
let e = this.opts.licenseRefreshMs ??
|
|
3395
|
+
let e = this.opts.licenseRefreshMs ?? Kn;
|
|
3395
3396
|
e && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
3396
3397
|
}
|
|
3397
3398
|
stopRefresh() {
|
|
@@ -3403,7 +3404,7 @@ var Yn = class {
|
|
|
3403
3404
|
if (this.refreshInFlight?.engine === e) return this.refreshInFlight.promise;
|
|
3404
3405
|
let t = (async () => {
|
|
3405
3406
|
try {
|
|
3406
|
-
let t = await
|
|
3407
|
+
let t = await v(this.resolveOptions());
|
|
3407
3408
|
if (this.destroyed || this.engine !== e) return;
|
|
3408
3409
|
let n = t.drm?.widevine?.licenseUrl, r = t.drm?.fairplay?.licenseUrl;
|
|
3409
3410
|
return (n || r) && (e.setLicenseUrls({
|
|
@@ -3447,7 +3448,7 @@ var Yn = class {
|
|
|
3447
3448
|
this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
|
|
3448
3449
|
}
|
|
3449
3450
|
getStats() {
|
|
3450
|
-
return this.engine?.getStats() ??
|
|
3451
|
+
return this.engine?.getStats() ?? qe;
|
|
3451
3452
|
}
|
|
3452
3453
|
getQualityLevels() {
|
|
3453
3454
|
return this.engine?.getQualityLevels() ?? [];
|
|
@@ -3499,7 +3500,7 @@ var Yn = class {
|
|
|
3499
3500
|
let e = ++this.loadGen;
|
|
3500
3501
|
this.teardownPlayback();
|
|
3501
3502
|
try {
|
|
3502
|
-
let t = await
|
|
3503
|
+
let t = await y({
|
|
3503
3504
|
...this.resolveOptions(),
|
|
3504
3505
|
waitForLive: this.opts.waitForLive ? this.buildWaitConfig(e) : void 0
|
|
3505
3506
|
});
|
|
@@ -3557,7 +3558,7 @@ function $(e) {
|
|
|
3557
3558
|
}
|
|
3558
3559
|
//#endregion
|
|
3559
3560
|
//#region src/embed/host.ts
|
|
3560
|
-
function
|
|
3561
|
+
function Zn(e) {
|
|
3561
3562
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
3562
3563
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
3563
3564
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -3616,15 +3617,15 @@ function Xn(e) {
|
|
|
3616
3617
|
}
|
|
3617
3618
|
//#endregion
|
|
3618
3619
|
//#region src/embed/page.ts
|
|
3619
|
-
var
|
|
3620
|
-
function
|
|
3620
|
+
var Qn = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
3621
|
+
function $n(e) {
|
|
3621
3622
|
if (typeof e == "boolean") return e;
|
|
3622
3623
|
if (typeof e == "object" && e) {
|
|
3623
3624
|
let t = e.endpoint;
|
|
3624
3625
|
return typeof t == "string" ? { endpoint: t } : {};
|
|
3625
3626
|
}
|
|
3626
3627
|
}
|
|
3627
|
-
function
|
|
3628
|
+
function er() {
|
|
3628
3629
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
3629
3630
|
if (e) return {
|
|
3630
3631
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -3634,7 +3635,7 @@ function $n() {
|
|
|
3634
3635
|
autoplay: e.autoplay ?? !0,
|
|
3635
3636
|
muted: e.muted ?? !0,
|
|
3636
3637
|
waitForLive: e.waitForLive ?? !0,
|
|
3637
|
-
analytics:
|
|
3638
|
+
analytics: $n(e.analytics)
|
|
3638
3639
|
};
|
|
3639
3640
|
let t = new URLSearchParams(location.search);
|
|
3640
3641
|
return {
|
|
@@ -3647,9 +3648,9 @@ function $n() {
|
|
|
3647
3648
|
waitForLive: !0
|
|
3648
3649
|
};
|
|
3649
3650
|
}
|
|
3650
|
-
async function
|
|
3651
|
-
let e =
|
|
3652
|
-
|
|
3651
|
+
async function tr() {
|
|
3652
|
+
let e = er();
|
|
3653
|
+
rr();
|
|
3653
3654
|
let t = document.createElement("video");
|
|
3654
3655
|
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);
|
|
3655
3656
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -3704,12 +3705,12 @@ async function er() {
|
|
|
3704
3705
|
code: e.code,
|
|
3705
3706
|
message: e.message
|
|
3706
3707
|
})), e.on("autoplayblocked", () => {
|
|
3707
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
3708
|
+
i({ type: "oddin:autoplayblocked" }), nr(t, e);
|
|
3708
3709
|
});
|
|
3709
3710
|
}, s = async (r) => {
|
|
3710
3711
|
a?.destroy(), a = null;
|
|
3711
3712
|
try {
|
|
3712
|
-
let n = await
|
|
3713
|
+
let n = await Yn({
|
|
3713
3714
|
video: t,
|
|
3714
3715
|
baseUrl: e.baseUrl,
|
|
3715
3716
|
matchUrn: r,
|
|
@@ -3771,7 +3772,7 @@ async function er() {
|
|
|
3771
3772
|
a?.retry();
|
|
3772
3773
|
break;
|
|
3773
3774
|
case "oddin:load":
|
|
3774
|
-
typeof e.matchUrn == "string" &&
|
|
3775
|
+
typeof e.matchUrn == "string" && Qn.test(e.matchUrn) && s(e.matchUrn);
|
|
3775
3776
|
break;
|
|
3776
3777
|
case "oddin:destroy": c();
|
|
3777
3778
|
}
|
|
@@ -3783,18 +3784,18 @@ async function er() {
|
|
|
3783
3784
|
protocol: 1
|
|
3784
3785
|
});
|
|
3785
3786
|
}
|
|
3786
|
-
function
|
|
3787
|
+
function nr(e, t) {
|
|
3787
3788
|
if (document.getElementById("havik-tap")) return;
|
|
3788
3789
|
let n = document.createElement("button");
|
|
3789
3790
|
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", () => {
|
|
3790
3791
|
n.remove(), t.play();
|
|
3791
3792
|
}), document.body.appendChild(n);
|
|
3792
3793
|
}
|
|
3793
|
-
function
|
|
3794
|
+
function rr() {
|
|
3794
3795
|
let e = document.createElement("style");
|
|
3795
3796
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
3796
3797
|
}
|
|
3797
3798
|
//#endregion
|
|
3798
|
-
export { wn as ODDIN_THEME, n as PlaybackError, En as applyTheme,
|
|
3799
|
+
export { wn as ODDIN_THEME, n as PlaybackError, En as applyTheme, Ke as baseUrlForEnv, tr as bootEmbed, Te as clearDeviceId, Yn as createPlayer, E as deriveEventsBaseUrl, He as detectDrmSupport, C as enterVideoFullscreen, w as exitVideoFullscreen, _e as fetchCatalog, ye as fetchTournament, xe as flattenMatches, k as getDeviceId, We as isLowLatencyManifest, $ as isOddinMessage, De as licenseRequestHeaders, Zn as mountEmbed, de as pollToLive, y as resolveStream, T as subscribeLiveState, S as videoFullscreenActive, Ce as watchStatus };
|
|
3799
3800
|
|
|
3800
3801
|
//# sourceMappingURL=index.js.map
|