@oddin-gg/havik-player 2.16.2 → 2.16.3
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 +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +249 -220
- package/dist/index.js.map +1 -1
- package/docs/API.md +2 -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 V(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 Le(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 Re(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 ze(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 ze(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,72 @@ async function ze(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 z = { droppedFrames: 0 };
|
|
822
|
+
function B(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 qe = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
|
|
830
|
+
function Je(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" || qe.test(i.name)) && i.startTime >= n) {
|
|
834
|
+
let e = B(i.name);
|
|
835
835
|
e && (t = e, n = i.startTime);
|
|
836
836
|
}
|
|
837
837
|
return t;
|
|
838
838
|
}
|
|
839
|
-
function
|
|
839
|
+
function V(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
|
-
|
|
846
|
+
var H = class {
|
|
847
|
+
video;
|
|
848
|
+
baseFrames = 0;
|
|
849
|
+
baseDropped = 0;
|
|
850
|
+
lastFrames = 0;
|
|
851
|
+
lastDropped = 0;
|
|
852
|
+
constructor(e) {
|
|
853
|
+
this.video = e;
|
|
854
|
+
}
|
|
855
|
+
read() {
|
|
856
|
+
let e = V(this.video);
|
|
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
|
+
dropped: this.baseDropped + e.dropped,
|
|
859
|
+
totalFrames: this.baseFrames + e.totalFrames
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
attach() {
|
|
863
|
+
let e = () => void this.read();
|
|
864
|
+
return this.video.addEventListener("timeupdate", e), this.video.addEventListener("seeking", e), () => {
|
|
865
|
+
this.video.removeEventListener("timeupdate", e), this.video.removeEventListener("seeking", e);
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
function Ye(e, t) {
|
|
847
870
|
let n = [
|
|
848
871
|
["playing", () => t("playing")],
|
|
849
872
|
["waiting", () => t("buffering")],
|
|
@@ -860,8 +883,8 @@ function Je(e, t) {
|
|
|
860
883
|
}
|
|
861
884
|
//#endregion
|
|
862
885
|
//#region src/core/engine/native.ts
|
|
863
|
-
var
|
|
864
|
-
function
|
|
886
|
+
var Xe = 2e3, Ze = 3, U = 500, Qe = 6e3, $e = .25;
|
|
887
|
+
function et(e) {
|
|
865
888
|
try {
|
|
866
889
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
867
890
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -877,7 +900,7 @@ function G() {
|
|
|
877
900
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
878
901
|
return e || t;
|
|
879
902
|
}
|
|
880
|
-
function
|
|
903
|
+
function tt() {
|
|
881
904
|
if (typeof navigator > "u" || !G()) return !1;
|
|
882
905
|
let e = navigator.userAgent ?? "";
|
|
883
906
|
return /iPhone|iPad|iPod/.test(e) ? !0 : /Macintosh/.test(e) && typeof navigator.maxTouchPoints == "number" && navigator.maxTouchPoints > 1;
|
|
@@ -901,10 +924,13 @@ var K = class {
|
|
|
901
924
|
savedPreload = null;
|
|
902
925
|
cdnHost = "";
|
|
903
926
|
builtAt;
|
|
927
|
+
frameCounter;
|
|
928
|
+
detachFrames = null;
|
|
904
929
|
constructor(e) {
|
|
905
|
-
this.deps = e, this.loadStarted = e.deferLoad !== !0, this.builtAt = typeof performance < "u" ? performance.now() : 0;
|
|
930
|
+
this.deps = e, this.frameCounter = new H(e.video), this.loadStarted = e.deferLoad !== !0, this.builtAt = typeof performance < "u" ? performance.now() : 0;
|
|
906
931
|
}
|
|
907
932
|
async load() {
|
|
933
|
+
this.detachFrames ??= this.frameCounter.attach();
|
|
908
934
|
let { video: e, descriptor: t, emit: r } = this.deps;
|
|
909
935
|
if (this.watchRefocus(), this.loadStarted || (this.preloadTouched = !0, this.savedPreload = e.getAttribute("preload"), e.preload = "none"), t.drmEnabled) {
|
|
910
936
|
if (!t.drm?.fairplay) {
|
|
@@ -922,7 +948,7 @@ var K = class {
|
|
|
922
948
|
type: "error",
|
|
923
949
|
error: new n("INTERNAL", 0, "native HLS playback error"),
|
|
924
950
|
fatal: !0
|
|
925
|
-
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src =
|
|
951
|
+
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = nt(t.manifestUrl, t.analytics?.sid), e.load();
|
|
926
952
|
}
|
|
927
953
|
startLoad() {
|
|
928
954
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -944,7 +970,7 @@ var K = class {
|
|
|
944
970
|
});
|
|
945
971
|
this.onEncrypted = (n) => {
|
|
946
972
|
let i = n;
|
|
947
|
-
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
973
|
+
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = et(i.initData), (async () => {
|
|
948
974
|
try {
|
|
949
975
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
950
976
|
initDataTypes: [i.initDataType],
|
|
@@ -1039,11 +1065,11 @@ var K = class {
|
|
|
1039
1065
|
e.seekable.length > 0 && (e.currentTime = e.seekable.end(e.seekable.length - 1));
|
|
1040
1066
|
}
|
|
1041
1067
|
getStats() {
|
|
1042
|
-
let e = this.deps.video, t =
|
|
1068
|
+
let e = this.deps.video, t = this.frameCounter.read(), n = {
|
|
1043
1069
|
droppedFrames: t.dropped,
|
|
1044
1070
|
decodedFrames: t.totalFrames
|
|
1045
1071
|
};
|
|
1046
|
-
if (this.cdnHost ||=
|
|
1072
|
+
if (this.cdnHost ||= Je(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity) {
|
|
1047
1073
|
if (n.isLive = !0, e.seekable.length > 0) {
|
|
1048
1074
|
let t = e.seekable.end(e.seekable.length - 1);
|
|
1049
1075
|
n.atLiveEdge = e.currentTime >= t - 2;
|
|
@@ -1066,7 +1092,7 @@ var K = class {
|
|
|
1066
1092
|
return;
|
|
1067
1093
|
}
|
|
1068
1094
|
let t = this.hiddenSince;
|
|
1069
|
-
this.hiddenSince = null, t != null && e - t >=
|
|
1095
|
+
this.hiddenSince = null, t != null && e - t >= Xe && this.armRefocus();
|
|
1070
1096
|
}, this.onPageShow = (e) => {
|
|
1071
1097
|
e.persisted && this.armRefocus();
|
|
1072
1098
|
}, document.addEventListener("visibilitychange", this.onVisibility), typeof window < "u" && window.addEventListener("pageshow", this.onPageShow));
|
|
@@ -1076,7 +1102,7 @@ var K = class {
|
|
|
1076
1102
|
let e = this.liveEnd(), t = () => typeof performance < "u" ? performance.now() : Date.now(), n = t(), r = 0, i = () => {
|
|
1077
1103
|
if (this.refocusTimer = null, Number.isFinite(this.deps.video.duration)) return;
|
|
1078
1104
|
r += U;
|
|
1079
|
-
let a = this.liveEnd(), o = a != null && (e == null || a >= e +
|
|
1105
|
+
let a = this.liveEnd(), o = a != null && (e == null || a >= e + $e), s = Math.max(r, t() - n) >= Qe;
|
|
1080
1106
|
if (o || s && a != null) {
|
|
1081
1107
|
this.snapToLive();
|
|
1082
1108
|
return;
|
|
@@ -1097,13 +1123,13 @@ var K = class {
|
|
|
1097
1123
|
snapToLive() {
|
|
1098
1124
|
let e = this.deps.video, t = this.liveEnd();
|
|
1099
1125
|
if (t == null) return;
|
|
1100
|
-
let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t -
|
|
1126
|
+
let n = e.seekable.start(e.seekable.length - 1), r = Math.min(e.currentTime, t), i = Math.max(n, t - Ze, r);
|
|
1101
1127
|
try {
|
|
1102
1128
|
e.currentTime = i;
|
|
1103
1129
|
} catch {}
|
|
1104
1130
|
}
|
|
1105
1131
|
destroy() {
|
|
1106
|
-
this.cancelRefocus(), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onPageShow && typeof window < "u" && (window.removeEventListener("pageshow", this.onPageShow), this.onPageShow = null);
|
|
1132
|
+
this.detachFrames?.(), this.detachFrames = null, this.cancelRefocus(), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onPageShow && typeof window < "u" && (window.removeEventListener("pageshow", this.onPageShow), this.onPageShow = null);
|
|
1107
1133
|
let { video: e } = this.deps;
|
|
1108
1134
|
this.onLoaded && e.removeEventListener("loadedmetadata", this.onLoaded), this.onError && e.removeEventListener("error", this.onError), this.onEncrypted && e.removeEventListener("encrypted", this.onEncrypted), this.keySession?.close().catch(() => {}), this.keySession = null, this.fairplayArmed = !1, this.fairplayKeyIV = void 0;
|
|
1109
1135
|
try {
|
|
@@ -1115,13 +1141,13 @@ var K = class {
|
|
|
1115
1141
|
} catch {}
|
|
1116
1142
|
}
|
|
1117
1143
|
};
|
|
1118
|
-
function
|
|
1144
|
+
function nt(e, t) {
|
|
1119
1145
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
1120
1146
|
}
|
|
1121
1147
|
//#endregion
|
|
1122
1148
|
//#region src/core/engine/prefetch.ts
|
|
1123
|
-
var
|
|
1124
|
-
function
|
|
1149
|
+
var rt = 15e3, it = 5e3, at = 6;
|
|
1150
|
+
function ot(e) {
|
|
1125
1151
|
try {
|
|
1126
1152
|
let t = new URL(e);
|
|
1127
1153
|
return t.searchParams.delete("CMCD"), t.toString();
|
|
@@ -1129,7 +1155,7 @@ function at(e) {
|
|
|
1129
1155
|
return e;
|
|
1130
1156
|
}
|
|
1131
1157
|
}
|
|
1132
|
-
var
|
|
1158
|
+
var st = class {
|
|
1133
1159
|
cmcd;
|
|
1134
1160
|
entries = /* @__PURE__ */ new Map();
|
|
1135
1161
|
keyed = /* @__PURE__ */ new Set();
|
|
@@ -1152,10 +1178,10 @@ var ot = class {
|
|
|
1152
1178
|
}
|
|
1153
1179
|
prefetch(e, t, n) {
|
|
1154
1180
|
if (!this.isActive(t)) return;
|
|
1155
|
-
let r =
|
|
1181
|
+
let r = ot(e);
|
|
1156
1182
|
if (this.entries.has(r)) return;
|
|
1157
1183
|
let i = this.perTrack.get(t) ?? 0;
|
|
1158
|
-
if (i >=
|
|
1184
|
+
if (i >= at) return;
|
|
1159
1185
|
this.perTrack.set(t, i + 1);
|
|
1160
1186
|
let a = new AbortController(), o = {
|
|
1161
1187
|
started: performance.now(),
|
|
@@ -1169,10 +1195,10 @@ var ot = class {
|
|
|
1169
1195
|
signal: a.signal
|
|
1170
1196
|
}).then(async (e) => (o.first = performance.now(), e.ok ? e.arrayBuffer() : null)).catch(() => null), this.entries.set(r, o), this.stats.started += 1, setTimeout(() => {
|
|
1171
1197
|
this.entries.get(r) === o && (this.entries.delete(r), a.abort(), this.stats.expired += 1);
|
|
1172
|
-
},
|
|
1198
|
+
}, rt);
|
|
1173
1199
|
}
|
|
1174
1200
|
take(e) {
|
|
1175
|
-
let t =
|
|
1201
|
+
let t = ot(e), n = this.entries.get(t);
|
|
1176
1202
|
return n && this.entries.delete(t), n;
|
|
1177
1203
|
}
|
|
1178
1204
|
destroy() {
|
|
@@ -1192,13 +1218,13 @@ var ot = class {
|
|
|
1192
1218
|
}
|
|
1193
1219
|
}
|
|
1194
1220
|
};
|
|
1195
|
-
function
|
|
1221
|
+
function ct(t) {
|
|
1196
1222
|
let n = e.DefaultConfig?.loader;
|
|
1197
1223
|
if (typeof n != "function") return;
|
|
1198
1224
|
class r extends n {
|
|
1199
1225
|
served = !1;
|
|
1200
1226
|
cancelled = !1;
|
|
1201
|
-
stats =
|
|
1227
|
+
stats = lt();
|
|
1202
1228
|
load(e, n, r) {
|
|
1203
1229
|
let i = e.rangeEnd ? void 0 : t.take(e.url);
|
|
1204
1230
|
if (!i) {
|
|
@@ -1206,7 +1232,7 @@ function st(t) {
|
|
|
1206
1232
|
return;
|
|
1207
1233
|
}
|
|
1208
1234
|
this.served = !0;
|
|
1209
|
-
let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs ||
|
|
1235
|
+
let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs || it, s = setTimeout(() => {
|
|
1210
1236
|
!this.cancelled && this.served && (i.abort.abort(), t.stats.failed += 1, this.served = !1, super.load(e, n, r));
|
|
1211
1237
|
}, o);
|
|
1212
1238
|
i.bytes.then((o) => {
|
|
@@ -1233,7 +1259,7 @@ function st(t) {
|
|
|
1233
1259
|
}
|
|
1234
1260
|
return r;
|
|
1235
1261
|
}
|
|
1236
|
-
function
|
|
1262
|
+
function lt() {
|
|
1237
1263
|
return {
|
|
1238
1264
|
aborted: !1,
|
|
1239
1265
|
loaded: 0,
|
|
@@ -1257,10 +1283,10 @@ function ct() {
|
|
|
1257
1283
|
}
|
|
1258
1284
|
};
|
|
1259
1285
|
}
|
|
1260
|
-
function
|
|
1286
|
+
function ut(e) {
|
|
1261
1287
|
return e === "audio" ? "audio" : "main";
|
|
1262
1288
|
}
|
|
1263
|
-
function
|
|
1289
|
+
function dt(e, t) {
|
|
1264
1290
|
let n = [];
|
|
1265
1291
|
t.initSegment?.url && !t.initSegment.data && n.push({
|
|
1266
1292
|
url: t.initSegment.url,
|
|
@@ -1279,24 +1305,24 @@ function ut(e, t) {
|
|
|
1279
1305
|
}
|
|
1280
1306
|
//#endregion
|
|
1281
1307
|
//#region src/core/engine/hls.ts
|
|
1282
|
-
function
|
|
1308
|
+
function ft() {
|
|
1283
1309
|
return e.isSupported();
|
|
1284
1310
|
}
|
|
1285
|
-
var
|
|
1286
|
-
function
|
|
1311
|
+
var pt = 3, mt = 5, ht = 3, gt = 3e4, _t = 12e3, vt = 3e3, yt = 6e3, bt = .5, xt = 3, St = .5, Ct = 1.1, wt = .25, Tt = 5e3, Et = 4e3, Dt = 2, Ot = 5, kt = 2, At = 2, jt = 4, Mt = 4, Nt = 2e3, Pt = 3e4, Ft = .2, It = 30, Lt = 2, Rt = 2, zt = 9, Bt = .5, Vt = 64;
|
|
1312
|
+
function Ht(e) {
|
|
1287
1313
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
1288
1314
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
1289
1315
|
return;
|
|
1290
1316
|
}
|
|
1291
|
-
e.liveSyncDuration ??=
|
|
1292
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
1293
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
1317
|
+
e.liveSyncDuration ??= Rt;
|
|
1318
|
+
let t = Math.max(12, e.liveSyncDuration + zt);
|
|
1319
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Ut(e, e.liveSyncDuration);
|
|
1294
1320
|
}
|
|
1295
|
-
function
|
|
1321
|
+
function Ut(e, t) {
|
|
1296
1322
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
1297
1323
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
1298
1324
|
}
|
|
1299
|
-
var
|
|
1325
|
+
var Wt = class {
|
|
1300
1326
|
name = "hls";
|
|
1301
1327
|
hls = null;
|
|
1302
1328
|
deps;
|
|
@@ -1373,10 +1399,13 @@ var Ut = class {
|
|
|
1373
1399
|
dprMedia = null;
|
|
1374
1400
|
onDprChange = null;
|
|
1375
1401
|
loadStarted;
|
|
1402
|
+
frameCounter;
|
|
1403
|
+
detachFrames = null;
|
|
1376
1404
|
constructor(e) {
|
|
1377
|
-
this.deps = e, this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
1405
|
+
this.deps = e, this.frameCounter = new H(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
1378
1406
|
}
|
|
1379
1407
|
async load() {
|
|
1408
|
+
this.detachFrames ??= this.frameCounter.attach();
|
|
1380
1409
|
let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = W(r) && G(), o = !!e.drm?.widevine?.licenseUrl && !a;
|
|
1381
1410
|
if (e.drmEnabled && !o) {
|
|
1382
1411
|
i({
|
|
@@ -1386,7 +1415,7 @@ var Ut = class {
|
|
|
1386
1415
|
});
|
|
1387
1416
|
return;
|
|
1388
1417
|
}
|
|
1389
|
-
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ae(r),
|
|
1418
|
+
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ae(r), Pe()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
|
|
1390
1419
|
let e = this.hls;
|
|
1391
1420
|
if (document.visibilityState !== "visible" || !e) return;
|
|
1392
1421
|
let t = e.liveSyncPosition;
|
|
@@ -1409,7 +1438,7 @@ var Ut = class {
|
|
|
1409
1438
|
}
|
|
1410
1439
|
this.loadSuspended = !0;
|
|
1411
1440
|
}
|
|
1412
|
-
},
|
|
1441
|
+
}, Tt));
|
|
1413
1442
|
}
|
|
1414
1443
|
resumeLoading() {
|
|
1415
1444
|
if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.resetChaseWindow(), this.resetFrameDropWindow(), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
|
|
@@ -1441,7 +1470,7 @@ var Ut = class {
|
|
|
1441
1470
|
let t = e.liveSyncPosition;
|
|
1442
1471
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1443
1472
|
let { video: n } = this.deps;
|
|
1444
|
-
n.currentTime <= t +
|
|
1473
|
+
n.currentTime <= t + Bt || (n.currentTime = t);
|
|
1445
1474
|
}
|
|
1446
1475
|
startHls() {
|
|
1447
1476
|
let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
|
|
@@ -1482,20 +1511,20 @@ var Ut = class {
|
|
|
1482
1511
|
...c
|
|
1483
1512
|
};
|
|
1484
1513
|
if (this.prefetch?.destroy(), this.prefetch = null, u && this.deps.mediaDuringKey !== !1 && !d.fLoader) {
|
|
1485
|
-
let e = new
|
|
1514
|
+
let e = new st({
|
|
1486
1515
|
sessionId: n.analytics?.sid,
|
|
1487
1516
|
contentId: n.matchUrn
|
|
1488
|
-
}), t =
|
|
1517
|
+
}), t = ct(e);
|
|
1489
1518
|
t && (this.prefetch = e, d.fLoader = t);
|
|
1490
1519
|
}
|
|
1491
|
-
|
|
1520
|
+
Ht(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;
|
|
1492
1521
|
let f = new e(d);
|
|
1493
1522
|
if (this.hls = f, f.on(e.Events.MANIFEST_PARSED, () => {
|
|
1494
1523
|
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" });
|
|
1495
1524
|
}), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1496
1525
|
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(() => {
|
|
1497
1526
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1498
|
-
},
|
|
1527
|
+
}, gt)));
|
|
1499
1528
|
}), f.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1500
1529
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1501
1530
|
}), f.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
@@ -1503,10 +1532,10 @@ var Ut = class {
|
|
|
1503
1532
|
let n = t?.frag?.stats, r = n?.loaded;
|
|
1504
1533
|
typeof r == "number" && (this.bytesLoaded += r), !this.reportedFirstBytes && typeof r == "number" && r > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
|
|
1505
1534
|
let i = n?.loading;
|
|
1506
|
-
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 >
|
|
1535
|
+
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 > Vt && this.requestTimesMs.shift());
|
|
1507
1536
|
let a = t?.frag?.url;
|
|
1508
1537
|
if (a) {
|
|
1509
|
-
let e =
|
|
1538
|
+
let e = B(a);
|
|
1510
1539
|
e && (this.cdnHost = e);
|
|
1511
1540
|
}
|
|
1512
1541
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1520,15 +1549,15 @@ var Ut = class {
|
|
|
1520
1549
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.prefetch) {
|
|
1521
1550
|
let t = this.prefetch;
|
|
1522
1551
|
f.on(e.Events.KEY_LOADING, (e, n) => {
|
|
1523
|
-
let r = n?.frag, i =
|
|
1524
|
-
if (r && t.isActive(i)) for (let e of
|
|
1525
|
-
}), f.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(
|
|
1552
|
+
let r = n?.frag, i = ut(r?.type);
|
|
1553
|
+
if (r && t.isActive(i)) for (let e of dt(f, r)) t.prefetch(e.url, i, e.kind);
|
|
1554
|
+
}), f.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(ut(n?.frag?.type)));
|
|
1526
1555
|
}
|
|
1527
1556
|
f.on(e.Events.KEY_LOADED, () => {
|
|
1528
1557
|
u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
|
|
1529
1558
|
}), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1530
1559
|
this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.checkFrameDrops();
|
|
1531
|
-
},
|
|
1560
|
+
}, vt), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1532
1561
|
this.renditionSwitches += 1;
|
|
1533
1562
|
let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
|
|
1534
1563
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
|
|
@@ -1592,7 +1621,7 @@ var Ut = class {
|
|
|
1592
1621
|
return;
|
|
1593
1622
|
}
|
|
1594
1623
|
this.capTimer && clearTimeout(this.capTimer);
|
|
1595
|
-
let t = e > this.sizeCapLevel ?
|
|
1624
|
+
let t = e > this.sizeCapLevel ? Nt : Pt;
|
|
1596
1625
|
this.capTimer = setTimeout(() => {
|
|
1597
1626
|
this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
|
|
1598
1627
|
}, t);
|
|
@@ -1602,9 +1631,9 @@ var Ut = class {
|
|
|
1602
1631
|
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;
|
|
1603
1632
|
}
|
|
1604
1633
|
dropLevelsWidevineCannotPlay(e) {
|
|
1605
|
-
this.removeLevelsWhere(e, (e) =>
|
|
1634
|
+
this.removeLevelsWhere(e, (e) => Fe(e) !== !0);
|
|
1606
1635
|
let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && I(e) !== "avc" && !!I(e)));
|
|
1607
|
-
for (let n of t)
|
|
1636
|
+
for (let n of t) Ne(n).then((t) => {
|
|
1608
1637
|
t || this.hls !== e || this.removeLevelsWhere(e, (e) => e === n) && (this.measureLadder(e), this.applySizeCap());
|
|
1609
1638
|
});
|
|
1610
1639
|
}
|
|
@@ -1615,7 +1644,7 @@ var Ut = class {
|
|
|
1615
1644
|
a && I(a) && t(a) && (r.push(n), i.add(a));
|
|
1616
1645
|
}), !r.length) return !1;
|
|
1617
1646
|
let a = [...i].join(", ");
|
|
1618
|
-
if (!n.some((e, t) => r.includes(t) ? !1 : !I(e.videoCodec) ||
|
|
1647
|
+
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;
|
|
1619
1648
|
for (let t = r.length - 1; t >= 0; --t) e.removeLevel(r[t]);
|
|
1620
1649
|
return console.info(`havik-player: skipped ${r.length} rendition(s) Widevine cannot play on this browser (${a})`), !0;
|
|
1621
1650
|
}
|
|
@@ -1665,7 +1694,7 @@ var Ut = class {
|
|
|
1665
1694
|
e.widevine && (this.licenseUrl = e.widevine);
|
|
1666
1695
|
}
|
|
1667
1696
|
getStats() {
|
|
1668
|
-
let e = this.hls, t =
|
|
1697
|
+
let e = this.hls, t = this.frameCounter.read(), n = {
|
|
1669
1698
|
droppedFrames: t.dropped,
|
|
1670
1699
|
decodedFrames: t.totalFrames,
|
|
1671
1700
|
lowLatency: this.detectedLowLatency,
|
|
@@ -1713,7 +1742,7 @@ var Ut = class {
|
|
|
1713
1742
|
return;
|
|
1714
1743
|
}
|
|
1715
1744
|
let e = Date.now() - this.lastAdvanceMs;
|
|
1716
|
-
!this.chaseSuspended && e >
|
|
1745
|
+
!this.chaseSuspended && e > yt && this.suspendChasing(), e > _t && this.emitEnded("stalled");
|
|
1717
1746
|
}
|
|
1718
1747
|
resetStarvationWindow() {
|
|
1719
1748
|
this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
|
|
@@ -1728,7 +1757,7 @@ var Ut = class {
|
|
|
1728
1757
|
this.resetStarvationWindow();
|
|
1729
1758
|
return;
|
|
1730
1759
|
}
|
|
1731
|
-
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs <
|
|
1760
|
+
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < yt, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > Et, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = V(t), c = o - s, l = c !== this.starvedFrames;
|
|
1732
1761
|
if (this.starvedFrames = c, !a || l) {
|
|
1733
1762
|
(t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
|
|
1734
1763
|
return;
|
|
@@ -1737,12 +1766,12 @@ var Ut = class {
|
|
|
1737
1766
|
this.resetStarvationWindow();
|
|
1738
1767
|
return;
|
|
1739
1768
|
}
|
|
1740
|
-
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 >
|
|
1769
|
+
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 > jt && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= kt && (this.clearKick(), this.starvationRebuilds < At)) {
|
|
1741
1770
|
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");
|
|
1742
1771
|
return;
|
|
1743
1772
|
}
|
|
1744
|
-
let u = i && this.starvedTicks >=
|
|
1745
|
-
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >=
|
|
1773
|
+
let u = i && this.starvedTicks >= Dt, d = !i && this.deadTicks >= jt && this.recentMainFrags.reduce((e, t) => e + t, 0) >= Mt;
|
|
1774
|
+
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= Ot))) {
|
|
1746
1775
|
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");
|
|
1747
1776
|
try {
|
|
1748
1777
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -1757,7 +1786,7 @@ var Ut = class {
|
|
|
1757
1786
|
let t = e.latency, n = e.targetLatency;
|
|
1758
1787
|
if (typeof t != "number" || typeof n != "number" || !Number.isFinite(t)) return;
|
|
1759
1788
|
let r = t - n;
|
|
1760
|
-
!this.catchUpEngaged && r >
|
|
1789
|
+
!this.catchUpEngaged && r > bt ? this.catchUpEngaged = !0 : this.catchUpEngaged && r <= bt && this.deps.video.playbackRate === 1 && (this.catchUpEngaged = !1);
|
|
1761
1790
|
let i = this.catchUpEngaged ? this.catchUpRate : 1;
|
|
1762
1791
|
e.config.maxLiveSyncPlaybackRate !== i && (e.config.maxLiveSyncPlaybackRate = i);
|
|
1763
1792
|
}
|
|
@@ -1778,16 +1807,16 @@ var Ut = class {
|
|
|
1778
1807
|
this.resetFrameDropWindow();
|
|
1779
1808
|
return;
|
|
1780
1809
|
}
|
|
1781
|
-
let { totalFrames: n, dropped: r } =
|
|
1782
|
-
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a <
|
|
1810
|
+
let { totalFrames: n, dropped: r } = V(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
|
|
1811
|
+
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < It || o < 0) {
|
|
1783
1812
|
this.fpsBadTicks = 0;
|
|
1784
1813
|
return;
|
|
1785
1814
|
}
|
|
1786
|
-
if (o <=
|
|
1815
|
+
if (o <= Ft * a) {
|
|
1787
1816
|
this.fpsBadTicks = 0;
|
|
1788
1817
|
return;
|
|
1789
1818
|
}
|
|
1790
|
-
if (this.fpsBadTicks += 1, this.fpsBadTicks <
|
|
1819
|
+
if (this.fpsBadTicks += 1, this.fpsBadTicks < Lt) return;
|
|
1791
1820
|
this.fpsBadTicks = 0;
|
|
1792
1821
|
let s = e.levels, c = s[e.currentLevel];
|
|
1793
1822
|
if (!c) return;
|
|
@@ -1804,20 +1833,20 @@ var Ut = class {
|
|
|
1804
1833
|
return;
|
|
1805
1834
|
}
|
|
1806
1835
|
let n = e.latency, r = t.playbackRate, i = e.config.maxLiveSyncPlaybackRate;
|
|
1807
|
-
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(
|
|
1836
|
+
if (!(!t.paused && typeof i == "number" && i > 1 && r >= Math.min(Ct, i) && r <= i && typeof n == "number" && Number.isFinite(n))) {
|
|
1808
1837
|
this.resetChaseWindow();
|
|
1809
1838
|
return;
|
|
1810
1839
|
}
|
|
1811
|
-
if (this.chaseLatency < 0 || this.chaseLatency - n >=
|
|
1840
|
+
if (this.chaseLatency < 0 || this.chaseLatency - n >= St) {
|
|
1812
1841
|
this.chaseLatency = n, this.chaseTicks = 0;
|
|
1813
1842
|
return;
|
|
1814
1843
|
}
|
|
1815
|
-
if (this.chaseTicks += 1, this.chaseTicks <
|
|
1844
|
+
if (this.chaseTicks += 1, this.chaseTicks < xt) return;
|
|
1816
1845
|
this.resetChaseWindow();
|
|
1817
1846
|
let a = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
|
|
1818
1847
|
if (!(a > 1)) return;
|
|
1819
1848
|
let o = typeof e.targetLatency == "number" ? e.targetLatency : 0, s = Math.min(n, a - 1);
|
|
1820
|
-
s < o +
|
|
1849
|
+
s < o + wt || (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);
|
|
1821
1850
|
}
|
|
1822
1851
|
suspendChasing() {
|
|
1823
1852
|
let e = this.hls;
|
|
@@ -1847,7 +1876,7 @@ var Ut = class {
|
|
|
1847
1876
|
} catch {}
|
|
1848
1877
|
}
|
|
1849
1878
|
destroy() {
|
|
1850
|
-
if (this.prefetch?.destroy(), this.prefetch = null, this.clearRecoveryReset(), this.capTimer &&= (clearTimeout(this.capTimer), null), this.capObserver &&= (this.capObserver.disconnect(), null), this.unwatchDprChanges(), this.endWatchdog &&= (clearInterval(this.endWatchdog), null), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onSeeking &&= (this.deps.video.removeEventListener("seeking", this.onSeeking), null), this.onTimeUpdate &&= (this.deps.video.removeEventListener("timeupdate", this.onTimeUpdate), null), this.onPause &&= (this.deps.video.removeEventListener("pause", this.onPause), null), this.onPlay &&= (this.deps.video.removeEventListener("play", this.onPlay), null), this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null), this.licenseRetryTimer &&= (clearTimeout(this.licenseRetryTimer), null), this.hls) {
|
|
1879
|
+
if (this.detachFrames?.(), this.detachFrames = null, this.prefetch?.destroy(), this.prefetch = null, this.clearRecoveryReset(), this.capTimer &&= (clearTimeout(this.capTimer), null), this.capObserver &&= (this.capObserver.disconnect(), null), this.unwatchDprChanges(), this.endWatchdog &&= (clearInterval(this.endWatchdog), null), this.onVisibility && typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), this.onVisibility = null), this.onSeeking &&= (this.deps.video.removeEventListener("seeking", this.onSeeking), null), this.onTimeUpdate &&= (this.deps.video.removeEventListener("timeupdate", this.onTimeUpdate), null), this.onPause &&= (this.deps.video.removeEventListener("pause", this.onPause), null), this.onPlay &&= (this.deps.video.removeEventListener("play", this.onPlay), null), this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.networkRetryTimer &&= (clearTimeout(this.networkRetryTimer), null), this.licenseRetryTimer &&= (clearTimeout(this.licenseRetryTimer), null), this.hls) {
|
|
1851
1880
|
try {
|
|
1852
1881
|
this.hls.destroy();
|
|
1853
1882
|
} catch (e) {
|
|
@@ -1862,7 +1891,7 @@ var Ut = class {
|
|
|
1862
1891
|
scheduleLicenseRetry(t) {
|
|
1863
1892
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
1864
1893
|
let n = t.response?.code ?? 0;
|
|
1865
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
1894
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= ht) return !1;
|
|
1866
1895
|
this.licenseRecoveries += 1;
|
|
1867
1896
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
1868
1897
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -1894,7 +1923,7 @@ var Ut = class {
|
|
|
1894
1923
|
return;
|
|
1895
1924
|
}
|
|
1896
1925
|
if (t.type === e.ErrorTypes.NETWORK_ERROR) {
|
|
1897
|
-
if (this.networkRecoveries <
|
|
1926
|
+
if (this.networkRecoveries < mt) {
|
|
1898
1927
|
this.networkRecoveries += 1;
|
|
1899
1928
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
1900
1929
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -1911,7 +1940,7 @@ var Ut = class {
|
|
|
1911
1940
|
return;
|
|
1912
1941
|
}
|
|
1913
1942
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
1914
|
-
if (this.mediaRecoveries <
|
|
1943
|
+
if (this.mediaRecoveries < pt) {
|
|
1915
1944
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
1916
1945
|
return;
|
|
1917
1946
|
}
|
|
@@ -1935,19 +1964,19 @@ var Ut = class {
|
|
|
1935
1964
|
let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
|
|
1936
1965
|
return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
|
|
1937
1966
|
}
|
|
1938
|
-
},
|
|
1967
|
+
}, Gt = 15e3, Kt = 6e5, qt = 3e5, Jt = 100, q = 1, Yt = 1e3, Xt = 3e4, Zt = 1e3, Qt = {
|
|
1939
1968
|
inline: "PRESENTATION_INLINE",
|
|
1940
1969
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
1941
1970
|
pip: "PRESENTATION_PIP"
|
|
1942
|
-
},
|
|
1971
|
+
}, $t = {
|
|
1943
1972
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
1944
1973
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
1945
1974
|
none: "KEY_SYSTEM_NONE"
|
|
1946
1975
|
};
|
|
1947
|
-
function
|
|
1976
|
+
function en(e, t) {
|
|
1948
1977
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
1949
1978
|
}
|
|
1950
|
-
var
|
|
1979
|
+
var tn = /* @__PURE__ */ new Set([
|
|
1951
1980
|
"INVALID_URN",
|
|
1952
1981
|
"NOT_FOUND",
|
|
1953
1982
|
"GONE",
|
|
@@ -1967,7 +1996,7 @@ var en = /* @__PURE__ */ new Set([
|
|
|
1967
1996
|
ended: "PLAYER_STATE_ENDED",
|
|
1968
1997
|
error: "PLAYER_STATE_ERROR"
|
|
1969
1998
|
};
|
|
1970
|
-
function
|
|
1999
|
+
function nn(e) {
|
|
1971
2000
|
try {
|
|
1972
2001
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
1973
2002
|
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);
|
|
@@ -1975,8 +2004,8 @@ function tn(e) {
|
|
|
1975
2004
|
return;
|
|
1976
2005
|
}
|
|
1977
2006
|
}
|
|
1978
|
-
var
|
|
1979
|
-
function
|
|
2007
|
+
var rn = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), an = /* @__PURE__ */ new Set(), Y = /* @__PURE__ */ new Set(), X = /* @__PURE__ */ new Set(), on = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
|
|
2008
|
+
function sn(e) {
|
|
1980
2009
|
if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
|
|
1981
2010
|
let t;
|
|
1982
2011
|
try {
|
|
@@ -1985,19 +2014,19 @@ function on(e) {
|
|
|
1985
2014
|
} catch {
|
|
1986
2015
|
return;
|
|
1987
2016
|
}
|
|
1988
|
-
if (
|
|
1989
|
-
Y.add(t), g(
|
|
2017
|
+
if (an.has(t) && !Y.has(t)) {
|
|
2018
|
+
Y.add(t), g(on(new URL(t).origin));
|
|
1990
2019
|
for (let e of X) e.noteCspBlocked();
|
|
1991
2020
|
}
|
|
1992
2021
|
}
|
|
1993
|
-
function
|
|
2022
|
+
function cn(e, t) {
|
|
1994
2023
|
return g(t, e), { disabledReason: t };
|
|
1995
2024
|
}
|
|
1996
|
-
function
|
|
1997
|
-
if (n) return t && !
|
|
2025
|
+
function ln(e, t, n) {
|
|
2026
|
+
if (n) return t && !rn(t, n) && g(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
|
|
1998
2027
|
if (t) return { endpoint: t };
|
|
1999
|
-
if (t !== void 0) return
|
|
2000
|
-
let r =
|
|
2028
|
+
if (t !== void 0) return cn("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).");
|
|
2029
|
+
let r = nn(e);
|
|
2001
2030
|
if (r) return { endpoint: r };
|
|
2002
2031
|
let i;
|
|
2003
2032
|
try {
|
|
@@ -2005,9 +2034,9 @@ function cn(e, t, n) {
|
|
|
2005
2034
|
} catch {
|
|
2006
2035
|
i = e;
|
|
2007
2036
|
}
|
|
2008
|
-
return
|
|
2037
|
+
return cn(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).`);
|
|
2009
2038
|
}
|
|
2010
|
-
var
|
|
2039
|
+
var un = class {
|
|
2011
2040
|
opts;
|
|
2012
2041
|
url;
|
|
2013
2042
|
cspKey;
|
|
@@ -2089,8 +2118,8 @@ var ln = class {
|
|
|
2089
2118
|
constructor(e) {
|
|
2090
2119
|
this.opts = {
|
|
2091
2120
|
...e,
|
|
2092
|
-
heartbeatMs: e.heartbeatMs ??
|
|
2093
|
-
idleMs: e.idleMs ??
|
|
2121
|
+
heartbeatMs: e.heartbeatMs ?? Gt,
|
|
2122
|
+
idleMs: e.idleMs ?? Kt
|
|
2094
2123
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
|
|
2095
2124
|
try {
|
|
2096
2125
|
let e = new URL(this.url);
|
|
@@ -2107,11 +2136,11 @@ var ln = class {
|
|
|
2107
2136
|
sdkVersion: this.opts.sdkVersion,
|
|
2108
2137
|
...this.opts.environment
|
|
2109
2138
|
};
|
|
2110
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
2139
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), Yt), 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 && an.add(this.cspKey), document.addEventListener("securitypolicyviolation", sn), X.add(this), this.noteCspBlocked(), this.onVisibility());
|
|
2111
2140
|
}
|
|
2112
2141
|
checkSuspension(e) {
|
|
2113
2142
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
2114
|
-
let t = Math.max(this.opts.idleMs,
|
|
2143
|
+
let t = Math.max(this.opts.idleMs, qt);
|
|
2115
2144
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
2116
2145
|
}
|
|
2117
2146
|
syncIdle(e) {
|
|
@@ -2134,12 +2163,12 @@ var ln = class {
|
|
|
2134
2163
|
let a = {
|
|
2135
2164
|
fromState: J[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2136
2165
|
toState: J[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2137
|
-
presentation:
|
|
2166
|
+
presentation: Qt[this.presentation]
|
|
2138
2167
|
}, o = this.causeOf(e, t, i);
|
|
2139
2168
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
2140
2169
|
}
|
|
2141
2170
|
seekInduced(e) {
|
|
2142
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
2171
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < Zt;
|
|
2143
2172
|
}
|
|
2144
2173
|
causeOf(e, t, n) {
|
|
2145
2174
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -2213,7 +2242,7 @@ var ln = class {
|
|
|
2213
2242
|
let r = n ?? "";
|
|
2214
2243
|
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";
|
|
2215
2244
|
if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
|
|
2216
|
-
if (
|
|
2245
|
+
if (tn.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
2217
2246
|
let i = t ?? "";
|
|
2218
2247
|
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";
|
|
2219
2248
|
}
|
|
@@ -2260,14 +2289,14 @@ var ln = class {
|
|
|
2260
2289
|
if (this.lastRequestCount = g, _ > 0) {
|
|
2261
2290
|
o.requestCountDelta = _;
|
|
2262
2291
|
let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
|
|
2263
|
-
n.length > 0 && (o.requestTimeP50Ms =
|
|
2292
|
+
n.length > 0 && (o.requestTimeP50Ms = en(n, 50), o.requestTimeP95Ms = en(n, 95));
|
|
2264
2293
|
}
|
|
2265
2294
|
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();
|
|
2266
2295
|
}
|
|
2267
2296
|
maybeEmitMediaInfo(e) {
|
|
2268
2297
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
2269
2298
|
let t = {};
|
|
2270
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
2299
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = $t[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);
|
|
2271
2300
|
let n = JSON.stringify(t);
|
|
2272
2301
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
2273
2302
|
}
|
|
@@ -2287,7 +2316,7 @@ var ln = class {
|
|
|
2287
2316
|
let c = r?.positionMs ?? 0;
|
|
2288
2317
|
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));
|
|
2289
2318
|
let l = e !== "END_REASON_ENDED";
|
|
2290
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
2319
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= Xt && (i.abandonAfterStallMs = Math.max(q, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= Xt && (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);
|
|
2291
2320
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
2292
2321
|
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");
|
|
2293
2322
|
}
|
|
@@ -2307,13 +2336,13 @@ var ln = class {
|
|
|
2307
2336
|
};
|
|
2308
2337
|
}
|
|
2309
2338
|
noteCspBlocked() {
|
|
2310
|
-
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(
|
|
2339
|
+
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(on(new URL(this.url).origin)));
|
|
2311
2340
|
}
|
|
2312
2341
|
cspBlocked() {
|
|
2313
2342
|
return !!this.cspKey && Y.has(this.cspKey);
|
|
2314
2343
|
}
|
|
2315
2344
|
enqueue(e) {
|
|
2316
|
-
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
2345
|
+
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > Jt;) {
|
|
2317
2346
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
2318
2347
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
2319
2348
|
}
|
|
@@ -2340,7 +2369,7 @@ var ln = class {
|
|
|
2340
2369
|
};
|
|
2341
2370
|
//#endregion
|
|
2342
2371
|
//#region src/core/environment.ts
|
|
2343
|
-
function
|
|
2372
|
+
function dn() {
|
|
2344
2373
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
2345
2374
|
let e;
|
|
2346
2375
|
try {
|
|
@@ -2365,14 +2394,14 @@ function un() {
|
|
|
2365
2394
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
2366
2395
|
};
|
|
2367
2396
|
}
|
|
2368
|
-
function
|
|
2397
|
+
function fn() {
|
|
2369
2398
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
2370
2399
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
2371
2400
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
2372
2401
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
2373
2402
|
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";
|
|
2374
2403
|
}
|
|
2375
|
-
function
|
|
2404
|
+
function pn() {
|
|
2376
2405
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
2377
2406
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
2378
2407
|
let t = {
|
|
@@ -2391,17 +2420,17 @@ function fn() {
|
|
|
2391
2420
|
}
|
|
2392
2421
|
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;
|
|
2393
2422
|
}
|
|
2394
|
-
function
|
|
2395
|
-
let t =
|
|
2396
|
-
deviceClass:
|
|
2423
|
+
function mn(e) {
|
|
2424
|
+
let t = dn(), n = {
|
|
2425
|
+
deviceClass: fn(),
|
|
2397
2426
|
integration: t.integration,
|
|
2398
|
-
...
|
|
2427
|
+
...pn()
|
|
2399
2428
|
};
|
|
2400
2429
|
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);
|
|
2401
2430
|
let r = e.getBoundingClientRect?.();
|
|
2402
2431
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
2403
2432
|
}
|
|
2404
|
-
async function
|
|
2433
|
+
async function hn() {
|
|
2405
2434
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
2406
2435
|
if (!e?.getHighEntropyValues) return {};
|
|
2407
2436
|
try {
|
|
@@ -2413,7 +2442,7 @@ async function mn() {
|
|
|
2413
2442
|
}
|
|
2414
2443
|
//#endregion
|
|
2415
2444
|
//#region src/core/version.ts
|
|
2416
|
-
var
|
|
2445
|
+
var gn = "2.16.3", _n = {
|
|
2417
2446
|
accent: "#E1B600",
|
|
2418
2447
|
accentText: "#1B1C23",
|
|
2419
2448
|
background: "#0e0f13",
|
|
@@ -2424,7 +2453,7 @@ var hn = "2.16.2", gn = {
|
|
|
2424
2453
|
border: "rgba(255, 255, 255, 0.1)",
|
|
2425
2454
|
radius: "8px",
|
|
2426
2455
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
2427
|
-
},
|
|
2456
|
+
}, vn = {
|
|
2428
2457
|
accent: "--havik-accent",
|
|
2429
2458
|
accentText: "--havik-accent-text",
|
|
2430
2459
|
background: "--havik-bg",
|
|
@@ -2436,12 +2465,12 @@ var hn = "2.16.2", gn = {
|
|
|
2436
2465
|
radius: "--havik-radius",
|
|
2437
2466
|
fontFamily: "--havik-font"
|
|
2438
2467
|
};
|
|
2439
|
-
function
|
|
2468
|
+
function Z(e, t) {
|
|
2440
2469
|
let n = {
|
|
2441
|
-
...
|
|
2470
|
+
..._n,
|
|
2442
2471
|
...t
|
|
2443
2472
|
};
|
|
2444
|
-
for (let t of Object.keys(
|
|
2473
|
+
for (let t of Object.keys(vn)) e.style.setProperty(vn[t], n[t]);
|
|
2445
2474
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
2446
2475
|
}
|
|
2447
2476
|
//#endregion
|
|
@@ -2468,7 +2497,7 @@ var Cn = {
|
|
|
2468
2497
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
2469
2498
|
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\"/>"
|
|
2470
2499
|
};
|
|
2471
|
-
function
|
|
2500
|
+
function Q(e) {
|
|
2472
2501
|
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Cn[e]}</svg>`;
|
|
2473
2502
|
}
|
|
2474
2503
|
//#endregion
|
|
@@ -2539,12 +2568,12 @@ var On = class {
|
|
|
2539
2568
|
"aria-label": r,
|
|
2540
2569
|
title: r
|
|
2541
2570
|
});
|
|
2542
|
-
return i.innerHTML =
|
|
2571
|
+
return i.innerHTML = Q(n), i;
|
|
2543
2572
|
};
|
|
2544
2573
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
2545
2574
|
type: "button",
|
|
2546
2575
|
"aria-label": "Play"
|
|
2547
|
-
}), this.center.innerHTML =
|
|
2576
|
+
}), 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", {
|
|
2548
2577
|
role: "slider",
|
|
2549
2578
|
"aria-label": "Seek",
|
|
2550
2579
|
"aria-valuemin": "0",
|
|
@@ -2562,7 +2591,7 @@ var On = class {
|
|
|
2562
2591
|
"aria-label": "Volume"
|
|
2563
2592
|
});
|
|
2564
2593
|
let a = t("div", "havik-vol");
|
|
2565
|
-
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML =
|
|
2594
|
+
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Q("liveDot");
|
|
2566
2595
|
let o = this.doc.createElement("span");
|
|
2567
2596
|
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";
|
|
2568
2597
|
let s = t("div", "havik-spacer");
|
|
@@ -2646,12 +2675,12 @@ var On = class {
|
|
|
2646
2675
|
}
|
|
2647
2676
|
if (e === "preplay") {
|
|
2648
2677
|
let e = this.doc.createElement("button");
|
|
2649
|
-
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML =
|
|
2678
|
+
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);
|
|
2650
2679
|
} else {
|
|
2651
2680
|
let r = this.doc.createElement("div");
|
|
2652
2681
|
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !En.has(this.lastError.code)) {
|
|
2653
2682
|
let e = this.doc.createElement("button");
|
|
2654
|
-
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${
|
|
2683
|
+
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);
|
|
2655
2684
|
}
|
|
2656
2685
|
}
|
|
2657
2686
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -2834,7 +2863,7 @@ var On = class {
|
|
|
2834
2863
|
}
|
|
2835
2864
|
}
|
|
2836
2865
|
setIcon(e, t) {
|
|
2837
|
-
e.innerHTML =
|
|
2866
|
+
e.innerHTML = Q(t);
|
|
2838
2867
|
}
|
|
2839
2868
|
destroy() {
|
|
2840
2869
|
this.hideTimer && clearTimeout(this.hideTimer), this.tapTimer && clearTimeout(this.tapTimer);
|
|
@@ -2867,25 +2896,25 @@ function Mn(e) {
|
|
|
2867
2896
|
}
|
|
2868
2897
|
//#endregion
|
|
2869
2898
|
//#region src/managed/index.ts
|
|
2870
|
-
var Nn = 6e3, Pn = 45e3,
|
|
2871
|
-
function
|
|
2899
|
+
var Nn = 6e3, Pn = 45e3, Fn = 2e3, In = 3, Ln = 2e3, Rn = 48e4;
|
|
2900
|
+
function zn(e) {
|
|
2872
2901
|
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)})`);
|
|
2873
|
-
if (e.env !== void 0) return
|
|
2902
|
+
if (e.env !== void 0) return Ke(e.env);
|
|
2874
2903
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
2875
2904
|
return e.baseUrl;
|
|
2876
2905
|
}
|
|
2877
|
-
async function
|
|
2906
|
+
async function Bn(e) {
|
|
2878
2907
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
2879
|
-
let t =
|
|
2908
|
+
let t = zn(e);
|
|
2880
2909
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
2881
2910
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
2882
|
-
let r = new
|
|
2911
|
+
let r = new Vn({
|
|
2883
2912
|
...e,
|
|
2884
2913
|
baseUrl: t
|
|
2885
2914
|
});
|
|
2886
2915
|
return await r.start(), r;
|
|
2887
2916
|
}
|
|
2888
|
-
var
|
|
2917
|
+
var Vn = class {
|
|
2889
2918
|
opts;
|
|
2890
2919
|
abort = new AbortController();
|
|
2891
2920
|
listeners = {};
|
|
@@ -2929,7 +2958,7 @@ var Bn = class {
|
|
|
2929
2958
|
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");
|
|
2930
2959
|
let e = ++this.loadGen, t = this.resolveOptions();
|
|
2931
2960
|
try {
|
|
2932
|
-
let n = await
|
|
2961
|
+
let n = await v(t);
|
|
2933
2962
|
if (await this.onResolved(n, e), e === this.loadGen && this._state === "error" && this._lastError) {
|
|
2934
2963
|
let e = this._lastError;
|
|
2935
2964
|
throw this.destroy(), e;
|
|
@@ -2956,7 +2985,7 @@ var Bn = class {
|
|
|
2956
2985
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
2957
2986
|
}
|
|
2958
2987
|
beginArmingByPolling(e) {
|
|
2959
|
-
|
|
2988
|
+
y({
|
|
2960
2989
|
...this.resolveOptions(),
|
|
2961
2990
|
signal: this.abort.signal,
|
|
2962
2991
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -2990,7 +3019,7 @@ var Bn = class {
|
|
|
2990
3019
|
}
|
|
2991
3020
|
}
|
|
2992
3021
|
}, h = () => {
|
|
2993
|
-
a || s || p() || (s = !0,
|
|
3022
|
+
a || s || p() || (s = !0, y({
|
|
2994
3023
|
...this.resolveOptions(),
|
|
2995
3024
|
signal: c.signal,
|
|
2996
3025
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -2998,7 +3027,7 @@ var Bn = class {
|
|
|
2998
3027
|
a || p() || c.signal.aborted || (a = !0, this.closeArming(), this.fail(e instanceof n ? e : new n("INTERNAL", 0, String(e))));
|
|
2999
3028
|
}));
|
|
3000
3029
|
}, g = () => {
|
|
3001
|
-
a || p() ||
|
|
3030
|
+
a || p() || v(this.resolveOptions()).then((e) => m(e)).catch((e) => {
|
|
3002
3031
|
if (!(a || p())) {
|
|
3003
3032
|
if (e instanceof n && o(e.code)) {
|
|
3004
3033
|
h();
|
|
@@ -3018,7 +3047,7 @@ var Bn = class {
|
|
|
3018
3047
|
credential: this.opts.credential,
|
|
3019
3048
|
onAlive: () => _(Pn),
|
|
3020
3049
|
onState: (e) => {
|
|
3021
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
3050
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Fn);
|
|
3022
3051
|
},
|
|
3023
3052
|
onError: () => h()
|
|
3024
3053
|
});
|
|
@@ -3041,7 +3070,7 @@ var Bn = class {
|
|
|
3041
3070
|
let n = await s(this.opts.credential);
|
|
3042
3071
|
if (this.destroyed || t !== this.loadGen) return;
|
|
3043
3072
|
this.setState("loading");
|
|
3044
|
-
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a =
|
|
3073
|
+
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = Ye(this.opts.video, (e) => {
|
|
3045
3074
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
3046
3075
|
});
|
|
3047
3076
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -3063,26 +3092,26 @@ var Bn = class {
|
|
|
3063
3092
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
3064
3093
|
let i = e.analytics?.sid;
|
|
3065
3094
|
if (!i) return;
|
|
3066
|
-
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } =
|
|
3095
|
+
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = ln(this.opts.baseUrl, a, e.analytics?.endpoint);
|
|
3067
3096
|
if (!o) {
|
|
3068
3097
|
s && setTimeout(() => {
|
|
3069
3098
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
|
|
3070
3099
|
}, 0);
|
|
3071
3100
|
return;
|
|
3072
3101
|
}
|
|
3073
|
-
let c = this.opts.video, l = new
|
|
3102
|
+
let c = this.opts.video, l = new un({
|
|
3074
3103
|
endpoint: o,
|
|
3075
3104
|
sid: i,
|
|
3076
3105
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
3077
|
-
sdkVersion:
|
|
3078
|
-
environment:
|
|
3106
|
+
sdkVersion: gn,
|
|
3107
|
+
environment: mn(c),
|
|
3079
3108
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
3080
3109
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
3081
3110
|
onBlocked: (e) => setTimeout(() => {
|
|
3082
3111
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, e));
|
|
3083
3112
|
}, 0),
|
|
3084
3113
|
sample: () => {
|
|
3085
|
-
let e = this.engine?.getStats() ??
|
|
3114
|
+
let e = this.engine?.getStats() ?? z, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
|
|
3086
3115
|
return {
|
|
3087
3116
|
...e,
|
|
3088
3117
|
bufferedMs: Math.round(t * 1e3),
|
|
@@ -3096,7 +3125,7 @@ var Bn = class {
|
|
|
3096
3125
|
let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
|
|
3097
3126
|
c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
|
|
3098
3127
|
c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
|
|
3099
|
-
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()),
|
|
3128
|
+
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), hn().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
3100
3129
|
}
|
|
3101
3130
|
currentPresentation() {
|
|
3102
3131
|
let e = this.opts.video;
|
|
@@ -3122,9 +3151,9 @@ var Bn = class {
|
|
|
3122
3151
|
emit: (e) => this.onEngineEvent(e)
|
|
3123
3152
|
}, o = this.opts.engine ?? "auto";
|
|
3124
3153
|
if (o === "native") return new K(a);
|
|
3125
|
-
if (o === "hls") return new
|
|
3126
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && W(this.opts.video) && G() || !e.drmEnabled &&
|
|
3127
|
-
if (
|
|
3154
|
+
if (o === "hls") return new Wt(a);
|
|
3155
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && W(this.opts.video) && G() || !e.drmEnabled && tt() && W(this.opts.video)) return new K(a);
|
|
3156
|
+
if (ft()) return new Wt(a);
|
|
3128
3157
|
if (W(this.opts.video)) return new K(a);
|
|
3129
3158
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
3130
3159
|
}
|
|
@@ -3177,7 +3206,7 @@ var Bn = class {
|
|
|
3177
3206
|
r = 0, i = !1;
|
|
3178
3207
|
},
|
|
3179
3208
|
onError: () => {
|
|
3180
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
3209
|
+
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= In && (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.`))));
|
|
3181
3210
|
}
|
|
3182
3211
|
});
|
|
3183
3212
|
}
|
|
@@ -3199,7 +3228,7 @@ var Bn = class {
|
|
|
3199
3228
|
scheduleRejoin(e) {
|
|
3200
3229
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
3201
3230
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
3202
|
-
}, Math.random() *
|
|
3231
|
+
}, Math.random() * Fn));
|
|
3203
3232
|
}
|
|
3204
3233
|
cancelRejoin() {
|
|
3205
3234
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -3223,7 +3252,7 @@ var Bn = class {
|
|
|
3223
3252
|
}
|
|
3224
3253
|
t.controls = !1;
|
|
3225
3254
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
3226
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
3255
|
+
r && r.insertBefore(n, t), n.appendChild(t), Z(n, this.opts.theme), this.container = n, this.controlBar = Dn({
|
|
3227
3256
|
root: n,
|
|
3228
3257
|
video: t,
|
|
3229
3258
|
player: this,
|
|
@@ -3254,7 +3283,7 @@ var Bn = class {
|
|
|
3254
3283
|
}
|
|
3255
3284
|
startStats() {
|
|
3256
3285
|
this.stopStats();
|
|
3257
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
3286
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Ln);
|
|
3258
3287
|
this.statsTimer = setInterval(() => {
|
|
3259
3288
|
if (!this.engine) return;
|
|
3260
3289
|
let e = this.engine.getStats();
|
|
@@ -3266,7 +3295,7 @@ var Bn = class {
|
|
|
3266
3295
|
}
|
|
3267
3296
|
scheduleLicenseRefresh() {
|
|
3268
3297
|
this.stopRefresh();
|
|
3269
|
-
let e = this.opts.licenseRefreshMs ??
|
|
3298
|
+
let e = this.opts.licenseRefreshMs ?? Rn;
|
|
3270
3299
|
e && this._descriptor?.drmEnabled && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
3271
3300
|
}
|
|
3272
3301
|
stopRefresh() {
|
|
@@ -3275,7 +3304,7 @@ var Bn = class {
|
|
|
3275
3304
|
async refreshLicense() {
|
|
3276
3305
|
let e = this.engine;
|
|
3277
3306
|
if (!this.destroyed && e) try {
|
|
3278
|
-
let t = await
|
|
3307
|
+
let t = await v(this.resolveOptions());
|
|
3279
3308
|
if (this.destroyed || this.engine !== e) return;
|
|
3280
3309
|
let n = t.drm?.widevine?.licenseUrl, r = t.drm?.fairplay?.licenseUrl;
|
|
3281
3310
|
(n || r) && (e.setLicenseUrls({
|
|
@@ -3311,7 +3340,7 @@ var Bn = class {
|
|
|
3311
3340
|
this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
|
|
3312
3341
|
}
|
|
3313
3342
|
getStats() {
|
|
3314
|
-
return this.engine?.getStats() ??
|
|
3343
|
+
return this.engine?.getStats() ?? z;
|
|
3315
3344
|
}
|
|
3316
3345
|
getQualityLevels() {
|
|
3317
3346
|
return this.engine?.getQualityLevels() ?? [];
|
|
@@ -3363,7 +3392,7 @@ var Bn = class {
|
|
|
3363
3392
|
let e = ++this.loadGen;
|
|
3364
3393
|
this.teardownPlayback();
|
|
3365
3394
|
try {
|
|
3366
|
-
let t = await
|
|
3395
|
+
let t = await y({
|
|
3367
3396
|
...this.resolveOptions(),
|
|
3368
3397
|
waitForLive: this.opts.waitForLive ? this.buildWaitConfig(e) : void 0
|
|
3369
3398
|
});
|
|
@@ -3421,7 +3450,7 @@ function $(e) {
|
|
|
3421
3450
|
}
|
|
3422
3451
|
//#endregion
|
|
3423
3452
|
//#region src/embed/host.ts
|
|
3424
|
-
function
|
|
3453
|
+
function Hn(e) {
|
|
3425
3454
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
3426
3455
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
3427
3456
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -3480,15 +3509,15 @@ function Vn(e) {
|
|
|
3480
3509
|
}
|
|
3481
3510
|
//#endregion
|
|
3482
3511
|
//#region src/embed/page.ts
|
|
3483
|
-
var
|
|
3484
|
-
function
|
|
3512
|
+
var Un = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
3513
|
+
function Wn(e) {
|
|
3485
3514
|
if (typeof e == "boolean") return e;
|
|
3486
3515
|
if (typeof e == "object" && e) {
|
|
3487
3516
|
let t = e.endpoint;
|
|
3488
3517
|
return typeof t == "string" ? { endpoint: t } : {};
|
|
3489
3518
|
}
|
|
3490
3519
|
}
|
|
3491
|
-
function
|
|
3520
|
+
function Gn() {
|
|
3492
3521
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
3493
3522
|
if (e) return {
|
|
3494
3523
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -3498,7 +3527,7 @@ function Wn() {
|
|
|
3498
3527
|
autoplay: e.autoplay ?? !0,
|
|
3499
3528
|
muted: e.muted ?? !0,
|
|
3500
3529
|
waitForLive: e.waitForLive ?? !0,
|
|
3501
|
-
analytics:
|
|
3530
|
+
analytics: Wn(e.analytics)
|
|
3502
3531
|
};
|
|
3503
3532
|
let t = new URLSearchParams(location.search);
|
|
3504
3533
|
return {
|
|
@@ -3511,9 +3540,9 @@ function Wn() {
|
|
|
3511
3540
|
waitForLive: !0
|
|
3512
3541
|
};
|
|
3513
3542
|
}
|
|
3514
|
-
async function
|
|
3515
|
-
let e =
|
|
3516
|
-
|
|
3543
|
+
async function Kn() {
|
|
3544
|
+
let e = Gn();
|
|
3545
|
+
Jn();
|
|
3517
3546
|
let t = document.createElement("video");
|
|
3518
3547
|
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);
|
|
3519
3548
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -3568,12 +3597,12 @@ async function Gn() {
|
|
|
3568
3597
|
code: e.code,
|
|
3569
3598
|
message: e.message
|
|
3570
3599
|
})), e.on("autoplayblocked", () => {
|
|
3571
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
3600
|
+
i({ type: "oddin:autoplayblocked" }), qn(t, e);
|
|
3572
3601
|
});
|
|
3573
3602
|
}, s = async (r) => {
|
|
3574
3603
|
a?.destroy(), a = null;
|
|
3575
3604
|
try {
|
|
3576
|
-
let n = await
|
|
3605
|
+
let n = await Bn({
|
|
3577
3606
|
video: t,
|
|
3578
3607
|
baseUrl: e.baseUrl,
|
|
3579
3608
|
matchUrn: r,
|
|
@@ -3635,7 +3664,7 @@ async function Gn() {
|
|
|
3635
3664
|
a?.retry();
|
|
3636
3665
|
break;
|
|
3637
3666
|
case "oddin:load":
|
|
3638
|
-
typeof e.matchUrn == "string" &&
|
|
3667
|
+
typeof e.matchUrn == "string" && Un.test(e.matchUrn) && s(e.matchUrn);
|
|
3639
3668
|
break;
|
|
3640
3669
|
case "oddin:destroy": c();
|
|
3641
3670
|
}
|
|
@@ -3647,18 +3676,18 @@ async function Gn() {
|
|
|
3647
3676
|
protocol: 1
|
|
3648
3677
|
});
|
|
3649
3678
|
}
|
|
3650
|
-
function
|
|
3679
|
+
function qn(e, t) {
|
|
3651
3680
|
if (document.getElementById("havik-tap")) return;
|
|
3652
3681
|
let n = document.createElement("button");
|
|
3653
3682
|
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", () => {
|
|
3654
3683
|
n.remove(), t.play();
|
|
3655
3684
|
}), document.body.appendChild(n);
|
|
3656
3685
|
}
|
|
3657
|
-
function
|
|
3686
|
+
function Jn() {
|
|
3658
3687
|
let e = document.createElement("style");
|
|
3659
3688
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
3660
3689
|
}
|
|
3661
3690
|
//#endregion
|
|
3662
|
-
export {
|
|
3691
|
+
export { _n as ODDIN_THEME, n as PlaybackError, Z as applyTheme, Ke as baseUrlForEnv, Kn as bootEmbed, Te as clearDeviceId, Bn 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, Hn as mountEmbed, de as pollToLive, y as resolveStream, T as subscribeLiveState, S as videoFullscreenActive, Ce as watchStatus };
|
|
3663
3692
|
|
|
3664
3693
|
//# sourceMappingURL=index.js.map
|