@oddin-gg/havik-player 2.21.0 → 2.22.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/havik-player.global.js +2 -2
- package/dist/havik-player.global.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +144 -121
- package/dist/index.js.map +1 -1
- package/docs/API.md +14 -4
- package/embed/index.html +1 -1
- package/examples/vanilla.html +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1484,21 +1484,31 @@ function Ft(e, t) {
|
|
|
1484
1484
|
function It() {
|
|
1485
1485
|
return e.isSupported();
|
|
1486
1486
|
}
|
|
1487
|
-
var Lt = 1e6, Rt = 20, zt = 1e4, Bt = 3, Vt = 5, Ht = 3, Ut = 1e4, Wt = 3e4, Gt = 12e3, Kt = 3e3, qt = .02, Jt = 6e3, Yt = .5, Xt = 3, Zt = .5, Qt = 1.1, $t = .25, en = 5e3, tn = 4e3, nn = 2, rn = 5, an = 2, on = 2, sn = 4, cn = 4, ln = 2e3, un = 3e4, dn =
|
|
1488
|
-
function
|
|
1487
|
+
var Lt = 1e6, Rt = 20, zt = 1e4, Bt = 3, Vt = 5, Ht = 3, Ut = 1e4, Wt = 3e4, Gt = 12e3, Kt = 3e3, qt = .02, Jt = 6e3, Yt = .5, Xt = 3, Zt = .5, Qt = 1.1, $t = .25, en = 5e3, tn = 4e3, nn = 2, rn = 5, an = 2, on = 2, sn = 4, cn = 4, ln = 2e3, un = 3e4, dn = 1, fn = 2;
|
|
1488
|
+
function pn(e, t, n) {
|
|
1489
|
+
if (n <= 0 || t < 0 || t >= e.length) return t;
|
|
1490
|
+
let r = (t, n) => e[t].width === e[n].width && e[t].height === e[n].height, i = (t) => {
|
|
1491
|
+
for (; t + 1 < e.length && r(t + 1, t);) t++;
|
|
1492
|
+
return t;
|
|
1493
|
+
}, a = i(t);
|
|
1494
|
+
for (let t = 0; t < n && a + 1 < e.length; t++) a = i(a + 1);
|
|
1495
|
+
return a;
|
|
1496
|
+
}
|
|
1497
|
+
var mn = .2, hn = 30, gn = 2, _n = 2, vn = 2, yn = 9, bn = .5, xn = 64;
|
|
1498
|
+
function Sn(e) {
|
|
1489
1499
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
1490
1500
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
1491
1501
|
return;
|
|
1492
1502
|
}
|
|
1493
|
-
e.liveSyncDuration ??=
|
|
1494
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
1495
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
1503
|
+
e.liveSyncDuration ??= vn;
|
|
1504
|
+
let t = Math.max(12, e.liveSyncDuration + yn);
|
|
1505
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Cn(e, e.liveSyncDuration);
|
|
1496
1506
|
}
|
|
1497
|
-
function
|
|
1507
|
+
function Cn(e, t) {
|
|
1498
1508
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
1499
1509
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
1500
1510
|
}
|
|
1501
|
-
var
|
|
1511
|
+
var wn = class {
|
|
1502
1512
|
name = "hls";
|
|
1503
1513
|
hls = null;
|
|
1504
1514
|
deps;
|
|
@@ -1574,6 +1584,7 @@ var bn = class {
|
|
|
1574
1584
|
fpsLastFrames = -1;
|
|
1575
1585
|
fpsLastDropped = -1;
|
|
1576
1586
|
fpsBadTicks = 0;
|
|
1587
|
+
fpsGraceTicks = 0;
|
|
1577
1588
|
fpsDownCaps = 0;
|
|
1578
1589
|
sizeCapManaged = !0;
|
|
1579
1590
|
dprMedia = null;
|
|
@@ -1650,7 +1661,7 @@ var bn = class {
|
|
|
1650
1661
|
let t = e.liveSyncPosition;
|
|
1651
1662
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1652
1663
|
let { video: n } = this.deps;
|
|
1653
|
-
n.currentTime <= t +
|
|
1664
|
+
n.currentTime <= t + bn || (n.currentTime = t);
|
|
1654
1665
|
}
|
|
1655
1666
|
reanchorPartTimeline(e, t) {
|
|
1656
1667
|
let { frag: n, part: r } = t;
|
|
@@ -1724,7 +1735,7 @@ var bn = class {
|
|
|
1724
1735
|
}), t = Mt(e);
|
|
1725
1736
|
t && (this.prefetch = e, f.fLoader = t);
|
|
1726
1737
|
}
|
|
1727
|
-
|
|
1738
|
+
Sn(f), this.catchUpRate = typeof f.maxLiveSyncPlaybackRate == "number" ? f.maxLiveSyncPlaybackRate : 1, this.catchUpEngaged = !1, this.catchUpRate > 1 && (f.maxLiveSyncPlaybackRate = 1), this.sizeCapManaged = f.capLevelToPlayerSize !== !0, this.fpsCapManaged = !(c && "capLevelOnFPSDrop" in c), this.loadStarted = f.autoStartLoad !== !1;
|
|
1728
1739
|
let p = new e(f);
|
|
1729
1740
|
if (this.hls = p, p.on(e.Events.FRAG_PARSED, (e, t) => this.reanchorPartTimeline(p, t)), p.on(e.Events.MANIFEST_PARSED, () => {
|
|
1730
1741
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, u && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && this.dropLevelsWidevineCannotPlay(p), this.measureLadder(p), this.applySizeCap(), this.loadSuspended = !1, t.paused && this.schedulePauseSuspend(), l({ type: "ready" });
|
|
@@ -1739,7 +1750,7 @@ var bn = class {
|
|
|
1739
1750
|
let n = t?.frag?.stats, r = n?.loaded;
|
|
1740
1751
|
typeof r == "number" && (this.bytesLoaded += r), !this.reportedFirstBytes && typeof r == "number" && r > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
|
|
1741
1752
|
let i = n?.loading;
|
|
1742
|
-
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 >
|
|
1753
|
+
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 > xn && this.requestTimesMs.shift());
|
|
1743
1754
|
let a = t?.frag?.url;
|
|
1744
1755
|
if (a) {
|
|
1745
1756
|
let e = ot(a);
|
|
@@ -1767,7 +1778,7 @@ var bn = class {
|
|
|
1767
1778
|
}, Kt), p.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1768
1779
|
this.renditionSwitches += 1;
|
|
1769
1780
|
let n = this.lastLevelIndex >= 0 ? p.levels[this.lastLevelIndex] : void 0, r = p.levels[t.level];
|
|
1770
|
-
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
|
|
1781
|
+
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, this.armFrameDropGrace(), l({
|
|
1771
1782
|
type: "qualitychange",
|
|
1772
1783
|
index: t.level
|
|
1773
1784
|
});
|
|
@@ -1812,8 +1823,12 @@ var bn = class {
|
|
|
1812
1823
|
if (!e || e.levels.length === 0) return null;
|
|
1813
1824
|
let { video: n } = this.deps, r = n.getBoundingClientRect(), i = r.width, a = r.height;
|
|
1814
1825
|
if (!i && !a && (i = n.width || 0, a = n.height || 0), !(i > 0) || !(a > 0)) return null;
|
|
1815
|
-
let o = e.config ?? {}, s = 1;
|
|
1816
|
-
|
|
1826
|
+
let o = e.config ?? {}, s = typeof self < "u" && self.devicePixelRatio > 0 ? self.devicePixelRatio : 1, c = o.ignoreDevicePixelRatio ? 1 : s;
|
|
1827
|
+
c = Math.min(c, o.maxDevicePixelRatio ?? Infinity);
|
|
1828
|
+
let l = t.getMaxLevelByMediaSize(e.levels, i * c, a * c), u = this.deps.sizeCapHeadroom;
|
|
1829
|
+
if (u == null && s >= fn) return l;
|
|
1830
|
+
let d = u ?? dn, f = Number.isNaN(d) ? dn : d === Infinity ? e.levels.length : Math.max(0, Math.floor(d));
|
|
1831
|
+
return pn(e.levels, l, f);
|
|
1817
1832
|
}
|
|
1818
1833
|
onMediaResize() {
|
|
1819
1834
|
if (!this.sizeCapManaged) return;
|
|
@@ -2013,6 +2028,9 @@ var bn = class {
|
|
|
2013
2028
|
e.bitrate <= this.fpsCapBitrate && i && (n = r);
|
|
2014
2029
|
}), n < 0 ? 0 : n;
|
|
2015
2030
|
}
|
|
2031
|
+
armFrameDropGrace() {
|
|
2032
|
+
this.fpsGraceTicks > 0 || (this.fpsGraceTicks = _n, this.fpsBadTicks = 0);
|
|
2033
|
+
}
|
|
2016
2034
|
resetFrameDropWindow() {
|
|
2017
2035
|
this.fpsLastFrames = -1, this.fpsLastDropped = -1, this.fpsBadTicks = 0;
|
|
2018
2036
|
}
|
|
@@ -2023,15 +2041,19 @@ var bn = class {
|
|
|
2023
2041
|
return;
|
|
2024
2042
|
}
|
|
2025
2043
|
let { totalFrames: n, dropped: r } = B(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
|
|
2026
|
-
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a <
|
|
2044
|
+
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < hn || o < 0) {
|
|
2027
2045
|
this.fpsBadTicks = 0;
|
|
2028
2046
|
return;
|
|
2029
2047
|
}
|
|
2030
|
-
if (
|
|
2048
|
+
if (this.fpsGraceTicks > 0) {
|
|
2049
|
+
--this.fpsGraceTicks, this.fpsBadTicks = 0;
|
|
2050
|
+
return;
|
|
2051
|
+
}
|
|
2052
|
+
if (o <= mn * a) {
|
|
2031
2053
|
this.fpsBadTicks = 0;
|
|
2032
2054
|
return;
|
|
2033
2055
|
}
|
|
2034
|
-
if (this.fpsBadTicks += 1, this.fpsBadTicks <
|
|
2056
|
+
if (this.fpsBadTicks += 1, this.fpsBadTicks < gn) return;
|
|
2035
2057
|
this.fpsBadTicks = 0;
|
|
2036
2058
|
let s = e.levels, c = s[e.currentLevel];
|
|
2037
2059
|
if (!c) return;
|
|
@@ -2130,7 +2152,7 @@ var bn = class {
|
|
|
2130
2152
|
} catch (t) {
|
|
2131
2153
|
console.warn(`havik-player: hls.js destroy() threw during ${e}`, t);
|
|
2132
2154
|
}
|
|
2133
|
-
this.hls = null, this.startHls();
|
|
2155
|
+
this.hls = null, this.startHls(), this.armFrameDropGrace();
|
|
2134
2156
|
}
|
|
2135
2157
|
}
|
|
2136
2158
|
onError(t) {
|
|
@@ -2189,19 +2211,19 @@ var bn = class {
|
|
|
2189
2211
|
let o = t.response?.code ?? 0, s = t.details ?? t.type, c = t.reason ?? t.error?.message ?? "", l = r === "DRM" && o === 403 && t.details === e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED ? i(Et(t.networkDetails)) : void 0;
|
|
2190
2212
|
return new n(r === "DRM" ? a(o, l) : o === 401 ? "UNAUTHORIZED" : o === 403 ? "FORBIDDEN" : "INTERNAL", o, `${r} error: ${s}${c ? ` (${c})` : ""}`, l ? { serverCode: l } : void 0);
|
|
2191
2213
|
}
|
|
2192
|
-
},
|
|
2214
|
+
}, Tn = 15e3, En = 6e5, Dn = 3e5, On = 100, q = 1, kn = 1e3, An = 3e4, jn = 1e3, Mn = {
|
|
2193
2215
|
inline: "PRESENTATION_INLINE",
|
|
2194
2216
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
2195
2217
|
pip: "PRESENTATION_PIP"
|
|
2196
|
-
},
|
|
2218
|
+
}, Nn = {
|
|
2197
2219
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
2198
2220
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
2199
2221
|
none: "KEY_SYSTEM_NONE"
|
|
2200
2222
|
};
|
|
2201
|
-
function
|
|
2223
|
+
function Pn(e, t) {
|
|
2202
2224
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
2203
2225
|
}
|
|
2204
|
-
var
|
|
2226
|
+
var Fn = /* @__PURE__ */ new Set([
|
|
2205
2227
|
"INVALID_URN",
|
|
2206
2228
|
"NOT_FOUND",
|
|
2207
2229
|
"GEO_DENIED",
|
|
@@ -2222,7 +2244,7 @@ var jn = /* @__PURE__ */ new Set([
|
|
|
2222
2244
|
ended: "PLAYER_STATE_ENDED",
|
|
2223
2245
|
error: "PLAYER_STATE_ERROR"
|
|
2224
2246
|
};
|
|
2225
|
-
function
|
|
2247
|
+
function In(e) {
|
|
2226
2248
|
try {
|
|
2227
2249
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
2228
2250
|
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);
|
|
@@ -2230,8 +2252,8 @@ function Mn(e) {
|
|
|
2230
2252
|
return;
|
|
2231
2253
|
}
|
|
2232
2254
|
}
|
|
2233
|
-
var
|
|
2234
|
-
function
|
|
2255
|
+
var Ln = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), Rn = /* @__PURE__ */ new Set(), Y = /* @__PURE__ */ new Set(), X = /* @__PURE__ */ new Set(), zn = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
|
|
2256
|
+
function Bn(e) {
|
|
2235
2257
|
if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
|
|
2236
2258
|
let t;
|
|
2237
2259
|
try {
|
|
@@ -2240,19 +2262,19 @@ function In(e) {
|
|
|
2240
2262
|
} catch {
|
|
2241
2263
|
return;
|
|
2242
2264
|
}
|
|
2243
|
-
if (
|
|
2244
|
-
Y.add(t), _(
|
|
2265
|
+
if (Rn.has(t) && !Y.has(t)) {
|
|
2266
|
+
Y.add(t), _(zn(new URL(t).origin));
|
|
2245
2267
|
for (let e of X) e.noteCspBlocked();
|
|
2246
2268
|
}
|
|
2247
2269
|
}
|
|
2248
|
-
function
|
|
2270
|
+
function Z(e, t) {
|
|
2249
2271
|
return _(t, e), { disabledReason: t };
|
|
2250
2272
|
}
|
|
2251
|
-
function
|
|
2252
|
-
if (n) return t && !
|
|
2273
|
+
function Vn(e, t, n) {
|
|
2274
|
+
if (n) return t && !Ln(t, n) && _(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
|
|
2253
2275
|
if (t) return { endpoint: t };
|
|
2254
|
-
if (t !== void 0) return
|
|
2255
|
-
let r =
|
|
2276
|
+
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).");
|
|
2277
|
+
let r = In(e);
|
|
2256
2278
|
if (r) return { endpoint: r };
|
|
2257
2279
|
let i;
|
|
2258
2280
|
try {
|
|
@@ -2260,9 +2282,9 @@ function Rn(e, t, n) {
|
|
|
2260
2282
|
} catch {
|
|
2261
2283
|
i = e;
|
|
2262
2284
|
}
|
|
2263
|
-
return
|
|
2285
|
+
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).`);
|
|
2264
2286
|
}
|
|
2265
|
-
var
|
|
2287
|
+
var Hn = class {
|
|
2266
2288
|
opts;
|
|
2267
2289
|
url;
|
|
2268
2290
|
cspKey;
|
|
@@ -2344,8 +2366,8 @@ var zn = class {
|
|
|
2344
2366
|
constructor(e) {
|
|
2345
2367
|
this.opts = {
|
|
2346
2368
|
...e,
|
|
2347
|
-
heartbeatMs: e.heartbeatMs ??
|
|
2348
|
-
idleMs: e.idleMs ??
|
|
2369
|
+
heartbeatMs: e.heartbeatMs ?? Tn,
|
|
2370
|
+
idleMs: e.idleMs ?? En
|
|
2349
2371
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
|
|
2350
2372
|
try {
|
|
2351
2373
|
let e = new URL(this.url);
|
|
@@ -2362,11 +2384,11 @@ var zn = class {
|
|
|
2362
2384
|
sdkVersion: this.opts.sdkVersion,
|
|
2363
2385
|
...this.opts.environment
|
|
2364
2386
|
};
|
|
2365
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
2387
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), kn), 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 && Rn.add(this.cspKey), document.addEventListener("securitypolicyviolation", Bn), X.add(this), this.noteCspBlocked(), this.onVisibility());
|
|
2366
2388
|
}
|
|
2367
2389
|
checkSuspension(e) {
|
|
2368
2390
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
2369
|
-
let t = Math.max(this.opts.idleMs,
|
|
2391
|
+
let t = Math.max(this.opts.idleMs, Dn);
|
|
2370
2392
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
2371
2393
|
}
|
|
2372
2394
|
syncIdle(e) {
|
|
@@ -2389,12 +2411,12 @@ var zn = class {
|
|
|
2389
2411
|
let a = {
|
|
2390
2412
|
fromState: J[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2391
2413
|
toState: J[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2392
|
-
presentation:
|
|
2414
|
+
presentation: Mn[this.presentation]
|
|
2393
2415
|
}, o = this.causeOf(e, t, i);
|
|
2394
2416
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
2395
2417
|
}
|
|
2396
2418
|
seekInduced(e) {
|
|
2397
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
2419
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < jn;
|
|
2398
2420
|
}
|
|
2399
2421
|
causeOf(e, t, n) {
|
|
2400
2422
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -2468,7 +2490,7 @@ var zn = class {
|
|
|
2468
2490
|
let r = n ?? "";
|
|
2469
2491
|
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";
|
|
2470
2492
|
if (e === "DRM_CLIENT" || e === "DRM_DEVICE_REVOKED") return "ERROR_STAGE_DRM";
|
|
2471
|
-
if (
|
|
2493
|
+
if (Fn.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
2472
2494
|
let i = t ?? "";
|
|
2473
2495
|
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";
|
|
2474
2496
|
}
|
|
@@ -2515,14 +2537,14 @@ var zn = class {
|
|
|
2515
2537
|
if (this.lastRequestCount = g, _ > 0) {
|
|
2516
2538
|
o.requestCountDelta = _;
|
|
2517
2539
|
let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
|
|
2518
|
-
n.length > 0 && (o.requestTimeP50Ms =
|
|
2540
|
+
n.length > 0 && (o.requestTimeP50Ms = Pn(n, 50), o.requestTimeP95Ms = Pn(n, 95));
|
|
2519
2541
|
}
|
|
2520
2542
|
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();
|
|
2521
2543
|
}
|
|
2522
2544
|
maybeEmitMediaInfo(e) {
|
|
2523
2545
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
2524
2546
|
let t = {};
|
|
2525
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
2547
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = Nn[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);
|
|
2526
2548
|
let n = JSON.stringify(t);
|
|
2527
2549
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
2528
2550
|
}
|
|
@@ -2542,7 +2564,7 @@ var zn = class {
|
|
|
2542
2564
|
let c = r?.positionMs ?? 0;
|
|
2543
2565
|
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));
|
|
2544
2566
|
let l = e !== "END_REASON_ENDED";
|
|
2545
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
2567
|
+
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);
|
|
2546
2568
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
2547
2569
|
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");
|
|
2548
2570
|
}
|
|
@@ -2562,13 +2584,13 @@ var zn = class {
|
|
|
2562
2584
|
};
|
|
2563
2585
|
}
|
|
2564
2586
|
noteCspBlocked() {
|
|
2565
|
-
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(
|
|
2587
|
+
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(zn(new URL(this.url).origin)));
|
|
2566
2588
|
}
|
|
2567
2589
|
cspBlocked() {
|
|
2568
2590
|
return !!this.cspKey && Y.has(this.cspKey);
|
|
2569
2591
|
}
|
|
2570
2592
|
enqueue(e) {
|
|
2571
|
-
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
2593
|
+
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > On;) {
|
|
2572
2594
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
2573
2595
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
2574
2596
|
}
|
|
@@ -2595,7 +2617,7 @@ var zn = class {
|
|
|
2595
2617
|
};
|
|
2596
2618
|
//#endregion
|
|
2597
2619
|
//#region src/core/environment.ts
|
|
2598
|
-
function
|
|
2620
|
+
function Un() {
|
|
2599
2621
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
2600
2622
|
let e;
|
|
2601
2623
|
try {
|
|
@@ -2620,14 +2642,14 @@ function Bn() {
|
|
|
2620
2642
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
2621
2643
|
};
|
|
2622
2644
|
}
|
|
2623
|
-
function
|
|
2645
|
+
function Wn() {
|
|
2624
2646
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
2625
2647
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
2626
2648
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
2627
2649
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
2628
2650
|
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";
|
|
2629
2651
|
}
|
|
2630
|
-
function
|
|
2652
|
+
function Gn() {
|
|
2631
2653
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
2632
2654
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
2633
2655
|
let t = {
|
|
@@ -2646,17 +2668,17 @@ function Hn() {
|
|
|
2646
2668
|
}
|
|
2647
2669
|
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;
|
|
2648
2670
|
}
|
|
2649
|
-
function
|
|
2650
|
-
let t =
|
|
2651
|
-
deviceClass:
|
|
2671
|
+
function Kn(e) {
|
|
2672
|
+
let t = Un(), n = {
|
|
2673
|
+
deviceClass: Wn(),
|
|
2652
2674
|
integration: t.integration,
|
|
2653
|
-
...
|
|
2675
|
+
...Gn()
|
|
2654
2676
|
};
|
|
2655
2677
|
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);
|
|
2656
2678
|
let r = e.getBoundingClientRect?.();
|
|
2657
2679
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
2658
2680
|
}
|
|
2659
|
-
async function
|
|
2681
|
+
async function qn() {
|
|
2660
2682
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
2661
2683
|
if (!e?.getHighEntropyValues) return {};
|
|
2662
2684
|
try {
|
|
@@ -2668,7 +2690,7 @@ async function Wn() {
|
|
|
2668
2690
|
}
|
|
2669
2691
|
//#endregion
|
|
2670
2692
|
//#region src/core/version.ts
|
|
2671
|
-
var
|
|
2693
|
+
var Jn = "2.22.1", Yn = {
|
|
2672
2694
|
accent: "#E1B600",
|
|
2673
2695
|
accentText: "#1B1C23",
|
|
2674
2696
|
background: "#0e0f13",
|
|
@@ -2679,7 +2701,7 @@ var Gn = "2.21.0", Kn = {
|
|
|
2679
2701
|
border: "rgba(255, 255, 255, 0.1)",
|
|
2680
2702
|
radius: "8px",
|
|
2681
2703
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
2682
|
-
},
|
|
2704
|
+
}, Xn = {
|
|
2683
2705
|
accent: "--havik-accent",
|
|
2684
2706
|
accentText: "--havik-accent-text",
|
|
2685
2707
|
background: "--havik-bg",
|
|
@@ -2691,26 +2713,26 @@ var Gn = "2.21.0", Kn = {
|
|
|
2691
2713
|
radius: "--havik-radius",
|
|
2692
2714
|
fontFamily: "--havik-font"
|
|
2693
2715
|
};
|
|
2694
|
-
function
|
|
2716
|
+
function Zn(e, t) {
|
|
2695
2717
|
let n = {
|
|
2696
|
-
...
|
|
2718
|
+
...Yn,
|
|
2697
2719
|
...t
|
|
2698
2720
|
};
|
|
2699
|
-
for (let t of Object.keys(
|
|
2721
|
+
for (let t of Object.keys(Xn)) e.style.setProperty(Xn[t], n[t]);
|
|
2700
2722
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
2701
2723
|
}
|
|
2702
2724
|
//#endregion
|
|
2703
2725
|
//#region src/ui/styles.ts
|
|
2704
|
-
var
|
|
2705
|
-
function
|
|
2706
|
-
let n = e.querySelector(`style#${
|
|
2707
|
-
if (n && (!t ||
|
|
2726
|
+
var Qn = "havik-player-styles", $n = "\n.havik-player{position:relative;display:block;width:100%;background:var(--havik-bg,#0e0f13);\n color:var(--havik-text,#fff);font-family:var(--havik-font,system-ui,sans-serif);\n overflow:hidden;line-height:1.4;-webkit-tap-highlight-color:transparent}\n.havik-player video{display:block;width:100%;height:auto;aspect-ratio:16/9;\n object-fit:contain;background:#000;outline:none}\n.havik-player:focus{outline:none}\n.havik-player *{box-sizing:border-box}\n\n.havik-player:fullscreen,.havik-player:-webkit-full-screen{display:flex;align-items:center;\n justify-content:center;width:100vw;height:100vh;aspect-ratio:auto}\n.havik-player:fullscreen video,.havik-player:-webkit-full-screen video{width:100%;height:100%;\n aspect-ratio:auto;object-fit:contain}\n\n.havik-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer;\n touch-action:manipulation}\n.havik-gradient{position:absolute;left:0;right:0;bottom:0;height:120px;pointer-events:none;\n background:linear-gradient(to top,rgba(0,0,0,.78),transparent);\n opacity:1;transition:opacity .25s}\n.havik-player.havik-hide .havik-gradient,\n.havik-player.havik-hide .havik-bar{opacity:0;pointer-events:none}\n.havik-player.havik-hide{cursor:none}\n\n.havik-center{width:74px;height:74px;border-radius:50%;border:0;cursor:pointer;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);\n display:flex;align-items:center;justify-content:center;\n box-shadow:0 6px 24px rgba(0,0,0,.45);transition:transform .15s,opacity .15s}\n.havik-center:hover{transform:scale(1.06)}\n.havik-center svg{width:38px;height:38px;margin-left:2px}\n.havik-center.havik-gone{opacity:0;pointer-events:none;transform:scale(.8)}\n\n/* Absolutely centred, NOT a flex sibling of .havik-center: the hidden center\n button (.havik-gone) still occupies its 74px in the row, which pushed an\n in-flow spinner 37px right of centre. */\n.havik-spinner{position:absolute;inset:0;margin:auto;width:56px;height:56px;border-radius:50%;\n border:4px solid rgba(255,255,255,.2);border-top-color:var(--havik-accent,#E1B600);\n animation:havik-spin .8s linear infinite}\n@keyframes havik-spin{to{transform:rotate(360deg)}}\n\n/* Status card — branded full-bleed overlay for the stopped/pre-play states\n (ended / fatal error / pre-play / armed-waiting). */\n.havik-status{position:absolute;inset:0;display:flex;flex-direction:column;gap:16px;\n align-items:center;justify-content:center;background:rgba(14,15,19,.82);text-align:center;padding:24px}\n.havik-status__logo{width:128px;height:46px;background:var(--havik-logo) center/contain no-repeat;opacity:.95}\n.havik-status__msg{color:var(--havik-text,#fff);font-size:15px;font-weight:600;max-width:480px}\n.havik-status__btn{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;\n padding:10px 18px;border-radius:var(--havik-radius,8px);font-weight:700;font-size:14px;\n background:var(--havik-accent,#E1B600);color:var(--havik-accent-text,#1B1C23);transition:transform .15s}\n.havik-status__btn:hover{transform:scale(1.04)}\n.havik-status__btn svg{width:18px;height:18px}\n/* Pre-play: lighter scrim so the poster shows through, and a round play CTA. */\n.havik-status--preplay{background:rgba(14,15,19,.4)}\n.havik-status--preplay .havik-status__btn--play{width:74px;height:74px;border-radius:50%;padding:0;\n justify-content:center;box-shadow:0 6px 24px rgba(0,0,0,.45)}\n.havik-status--preplay .havik-status__btn--play svg{width:38px;height:38px;margin-left:3px}\n\n.havik-watermark{position:absolute;top:12px;right:14px;height:22px;opacity:.85;pointer-events:none;\n content:'';background:var(--havik-logo) center/contain no-repeat;width:90px}\n/* A status card carries its own logo — the corner watermark would duplicate it. */\n.havik-player.havik-has-status .havik-watermark{display:none}\n\n.havik-bar{position:absolute;left:0;right:0;bottom:0;padding:0 12px 8px;\n opacity:1;transition:opacity .25s;z-index:2}\n.havik-seek{position:relative;height:16px;display:flex;align-items:center;cursor:pointer;margin-bottom:2px}\n.havik-seek__track{position:relative;width:100%;height:4px;border-radius:3px;background:rgba(255,255,255,.25)}\n.havik-seek__buffered{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:rgba(255,255,255,.4)}\n.havik-seek__played{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-seek__thumb{position:absolute;top:50%;width:13px;height:13px;border-radius:50%;\n background:var(--havik-accent,#E1B600);transform:translate(-50%,-50%) scale(0);transition:transform .1s}\n.havik-seek:hover .havik-seek__thumb{transform:translate(-50%,-50%) scale(1)}\n\n.havik-controls{display:flex;align-items:center;gap:6px;height:40px}\n.havik-spacer{flex:1}\n.havik-btn{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;border-radius:var(--havik-radius,8px);\n padding:0;transition:background .12s,color .12s}\n.havik-btn:hover{background:rgba(255,255,255,.12)}\n.havik-btn:focus-visible{outline:2px solid var(--havik-accent,#E1B600);outline-offset:1px}\n.havik-btn svg{width:22px;height:22px}\n\n/* The volume level is filled in accent up to the thumb, like the seek bar's\n played span — a native range input paints no \"elapsed\" side, which left the\n level readable only from the dot's position. --havik-vol (0..1) is set by\n syncVolume(); the track width and thumb size live here as variables because\n the WebKit fill has to compute the thumb centre from both. */\n.havik-vol{display:flex;align-items:center}\n.havik-vol__slider{--havik-vol-w:70px;--havik-vol-thumb:12px;--havik-vol:1;\n --havik-vol-pos:calc(var(--havik-vol-thumb) / 2 + var(--havik-vol) * (var(--havik-vol-w) - var(--havik-vol-thumb)));\n width:0;opacity:0;transition:width .18s,opacity .18s;height:4px;cursor:pointer;\n appearance:none;-webkit-appearance:none;background:transparent;border-radius:3px;margin:0 4px}\n.havik-vol:hover .havik-vol__slider,.havik-vol:focus-within .havik-vol__slider{width:var(--havik-vol-w);opacity:1}\n/* WebKit/Blink have no progress pseudo-element: paint the fill as a hard-stop\n gradient that ends at the thumb centre. */\n.havik-vol__slider::-webkit-slider-runnable-track{height:4px;border-radius:3px;\n background:linear-gradient(to right,var(--havik-accent,#E1B600) var(--havik-vol-pos),\n rgba(255,255,255,.3) var(--havik-vol-pos))}\n/* Firefox fills natively, and tracks the thumb exactly. */\n.havik-vol__slider::-moz-range-track{height:4px;border-radius:3px;background:rgba(255,255,255,.3)}\n.havik-vol__slider::-moz-range-progress{height:4px;border-radius:3px;background:var(--havik-accent,#E1B600)}\n.havik-vol__slider::-webkit-slider-thumb{-webkit-appearance:none;width:var(--havik-vol-thumb);\n height:var(--havik-vol-thumb);border-radius:50%;background:var(--havik-accent,#E1B600);\n margin-top:calc((4px - var(--havik-vol-thumb)) / 2)}\n.havik-vol__slider::-moz-range-thumb{width:var(--havik-vol-thumb);height:var(--havik-vol-thumb);\n border:0;border-radius:50%;background:var(--havik-accent,#E1B600)}\n\n.havik-time{font-size:12px;color:var(--havik-text-muted,#9aa0ad);\n font-variant-numeric:tabular-nums;padding:0 6px;white-space:nowrap}\n.havik-live{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;\n letter-spacing:.4px;padding:0 8px;color:var(--havik-text,#fff)}\n.havik-live svg{width:9px;height:9px;color:var(--havik-text-muted,#9aa0ad)}\n.havik-live.is-live svg{color:var(--havik-accent,#E1B600)}\n.havik-live__go{margin-left:2px;border:0;cursor:pointer;background:transparent;color:var(--havik-text-muted,#9aa0ad);\n font:inherit;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 6px;border-radius:6px}\n.havik-live.is-live .havik-live__go{display:none}\n.havik-live__go:hover{color:var(--havik-accent,#E1B600)}\n\n.havik-menu{position:absolute;bottom:54px;right:12px;min-width:170px;max-height:230px;overflow:auto;\n background:var(--havik-surface,#1B1C23);border:1px solid var(--havik-border,rgba(255,255,255,.1));\n border-radius:var(--havik-radius,8px);box-shadow:0 10px 30px rgba(0,0,0,.5);padding:6px;z-index:3}\n.havik-menu[hidden]{display:none}\n.havik-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;\n color:var(--havik-text-muted,#9aa0ad);padding:6px 8px 4px}\n.havik-menu__item{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;\n border:0;background:transparent;color:var(--havik-text,#fff);cursor:pointer;font:inherit;font-size:13px;\n text-align:left;padding:7px 8px;border-radius:6px}\n.havik-menu__item:hover{background:var(--havik-surface-muted,#2a2c36)}\n.havik-menu__item[aria-checked=\"true\"]{color:var(--havik-accent,#E1B600);font-weight:600}\n.havik-menu__item[aria-checked=\"true\"]::after{content:'✓'}\n", er = /* @__PURE__ */ new WeakMap();
|
|
2727
|
+
function tr(e = document, t) {
|
|
2728
|
+
let n = e.querySelector(`style#${Qn}`);
|
|
2729
|
+
if (n && (!t || er.get(n) === t)) return;
|
|
2708
2730
|
let r = e.createElement("style");
|
|
2709
|
-
r.id =
|
|
2731
|
+
r.id = Qn, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = $n, er.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
|
|
2710
2732
|
}
|
|
2711
2733
|
//#endregion
|
|
2712
2734
|
//#region src/ui/icons.ts
|
|
2713
|
-
var
|
|
2735
|
+
var nr = {
|
|
2714
2736
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
2715
2737
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
2716
2738
|
volumeHigh: "<path d=\"M3 10v4h4l5 5V5L7 10H3zm13.5 2a4.5 4.5 0 0 0-2.5-4v8a4.5 4.5 0 0 0 2.5-4zm-2.5-9v2.06A7 7 0 0 1 14 19v2a9 9 0 0 0 0-18z\"/>",
|
|
@@ -2724,11 +2746,11 @@ var Qn = {
|
|
|
2724
2746
|
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\"/>"
|
|
2725
2747
|
};
|
|
2726
2748
|
function Q(e) {
|
|
2727
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
2749
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${nr[e]}</svg>`;
|
|
2728
2750
|
}
|
|
2729
2751
|
//#endregion
|
|
2730
2752
|
//#region src/ui/controls.ts
|
|
2731
|
-
var
|
|
2753
|
+
var rr = 3e3, ir = 250, ar = /* @__PURE__ */ new Set([
|
|
2732
2754
|
"GONE",
|
|
2733
2755
|
"NOT_FOUND",
|
|
2734
2756
|
"GEO_DENIED",
|
|
@@ -2736,15 +2758,15 @@ var $n = 3e3, er = 250, tr = /* @__PURE__ */ new Set([
|
|
|
2736
2758
|
"UNAUTHORIZED",
|
|
2737
2759
|
"DRM_DEVICE_REVOKED"
|
|
2738
2760
|
]);
|
|
2739
|
-
function
|
|
2761
|
+
function or(e) {
|
|
2740
2762
|
let t = "This match isn't available in your country";
|
|
2741
2763
|
return e ? `${t} (${e})` : t;
|
|
2742
2764
|
}
|
|
2743
|
-
var
|
|
2744
|
-
function
|
|
2745
|
-
return new
|
|
2765
|
+
var sr = "This device can't play protected video";
|
|
2766
|
+
function cr(e) {
|
|
2767
|
+
return new lr(e);
|
|
2746
2768
|
}
|
|
2747
|
-
var
|
|
2769
|
+
var lr = class {
|
|
2748
2770
|
root;
|
|
2749
2771
|
video;
|
|
2750
2772
|
player;
|
|
@@ -2792,7 +2814,7 @@ var ar = class {
|
|
|
2792
2814
|
scrubbing = !1;
|
|
2793
2815
|
offFns = [];
|
|
2794
2816
|
constructor(e) {
|
|
2795
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
2817
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? rr, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.streamEnded = e.streamEnded ?? (() => !1), this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, tr(this.doc, e.cspNonce), this.root.classList.add("havik-player"), this.root.hasAttribute("tabindex") || (this.root.tabIndex = 0), this.root.setAttribute("role", "region"), this.root.setAttribute("aria-label", "Video player");
|
|
2796
2818
|
let t = (e, t, n) => {
|
|
2797
2819
|
let r = this.doc.createElement(e);
|
|
2798
2820
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -2878,7 +2900,7 @@ var ar = class {
|
|
|
2878
2900
|
let t = this.surfaceWasHidden;
|
|
2879
2901
|
this.tapTimer = setTimeout(() => {
|
|
2880
2902
|
this.tapTimer = void 0, this.toggleBar(t);
|
|
2881
|
-
},
|
|
2903
|
+
}, ir);
|
|
2882
2904
|
}
|
|
2883
2905
|
toggleBar(e) {
|
|
2884
2906
|
e ? this.poke() : this.hideIfIdle();
|
|
@@ -2898,7 +2920,7 @@ var ar = class {
|
|
|
2898
2920
|
this.statusOverlays && (e === "ended" ? t = "ended" : e === "error" ? t = "error" : e === "waiting" ? t = "waiting" : !this.hasPlayed && (e === "idle" || e === "paused") && (t = "preplay")), this.renderStatus(t);
|
|
2899
2921
|
}
|
|
2900
2922
|
statusMessageFor(e) {
|
|
2901
|
-
return e === "ended" ? this.player.endedReason === "interrupted" ? this.interruptedMessage : this.endedMessage : e === "waiting" ? this.hasPlayed ? "Reconnecting — please stand by" : "Starting soon…" : e === "error" ? this.errorMessage === void 0 ? this.lastError?.code === "GEO_DENIED" ?
|
|
2923
|
+
return e === "ended" ? this.player.endedReason === "interrupted" ? this.interruptedMessage : this.endedMessage : e === "waiting" ? this.hasPlayed ? "Reconnecting — please stand by" : "Starting soon…" : e === "error" ? this.errorMessage === void 0 ? this.lastError?.code === "GEO_DENIED" ? or(this.lastError.country) : this.lastError?.code === "DRM_DEVICE_REVOKED" ? sr : this.lastError?.message ?? "Playback unavailable" : this.errorMessage : null;
|
|
2902
2924
|
}
|
|
2903
2925
|
renderStatus(e) {
|
|
2904
2926
|
let t = this.statusMessageFor(e);
|
|
@@ -2913,7 +2935,7 @@ var ar = class {
|
|
|
2913
2935
|
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);
|
|
2914
2936
|
} else {
|
|
2915
2937
|
let r = this.doc.createElement("div");
|
|
2916
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
2938
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !ar.has(this.lastError.code)) {
|
|
2917
2939
|
let e = this.doc.createElement("button");
|
|
2918
2940
|
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);
|
|
2919
2941
|
}
|
|
@@ -2954,7 +2976,7 @@ var ar = class {
|
|
|
2954
2976
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
2955
2977
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
2956
2978
|
}
|
|
2957
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
2979
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${ur(this.video.currentTime)} / ${ur(this.video.duration)}`);
|
|
2958
2980
|
}
|
|
2959
2981
|
syncLive() {
|
|
2960
2982
|
let e = this.player.getStats(), t = e.isLive !== !1, n = this.player.state === "ended", r = !t && !this.streamEnded();
|
|
@@ -3004,17 +3026,17 @@ var ar = class {
|
|
|
3004
3026
|
renderQualityMenu() {
|
|
3005
3027
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
3006
3028
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
3007
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
3029
|
+
for (let n of e) this.menu.append(this.menuItem(dr(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
3008
3030
|
}
|
|
3009
3031
|
renderAudioMenu() {
|
|
3010
3032
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
3011
3033
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
3012
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
3034
|
+
for (let t of e) this.menu.append(this.menuItem(fr(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
3013
3035
|
}
|
|
3014
3036
|
renderCcMenu() {
|
|
3015
3037
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
3016
3038
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
3017
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
3039
|
+
for (let t of e) this.menu.append(this.menuItem(pr(t), !1, () => this.player.setTextTrack(t.id)));
|
|
3018
3040
|
}
|
|
3019
3041
|
onTracksChanged() {
|
|
3020
3042
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -3119,41 +3141,41 @@ var ar = class {
|
|
|
3119
3141
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
3120
3142
|
}
|
|
3121
3143
|
};
|
|
3122
|
-
function
|
|
3144
|
+
function ur(e) {
|
|
3123
3145
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
3124
3146
|
let t = Math.floor(e % 60), n = Math.floor(e / 60 % 60), r = Math.floor(e / 3600), i = r > 0 ? String(n).padStart(2, "0") : String(n), a = String(t).padStart(2, "0");
|
|
3125
3147
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
3126
3148
|
}
|
|
3127
|
-
function
|
|
3149
|
+
function dr(e) {
|
|
3128
3150
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
3129
3151
|
}
|
|
3130
|
-
function
|
|
3152
|
+
function fr(e) {
|
|
3131
3153
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3132
3154
|
}
|
|
3133
|
-
function
|
|
3155
|
+
function pr(e) {
|
|
3134
3156
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3135
3157
|
}
|
|
3136
3158
|
//#endregion
|
|
3137
3159
|
//#region src/managed/index.ts
|
|
3138
|
-
var
|
|
3139
|
-
function
|
|
3160
|
+
var mr = 6e3, hr = 45e3, gr = 2e3, _r = 3, vr = 5e3, yr = 2e3, br = 48e4, xr = "keySystemLicenseRequestFailed";
|
|
3161
|
+
function Sr(e) {
|
|
3140
3162
|
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)})`);
|
|
3141
3163
|
if (e.env !== void 0) return at(e.env);
|
|
3142
3164
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
3143
3165
|
return e.baseUrl;
|
|
3144
3166
|
}
|
|
3145
|
-
async function
|
|
3167
|
+
async function Cr(e) {
|
|
3146
3168
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
3147
|
-
let t =
|
|
3169
|
+
let t = Sr(e);
|
|
3148
3170
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
3149
3171
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
3150
|
-
let r = new
|
|
3172
|
+
let r = new wr({
|
|
3151
3173
|
...e,
|
|
3152
3174
|
baseUrl: t
|
|
3153
3175
|
});
|
|
3154
3176
|
return await r.start(), r;
|
|
3155
3177
|
}
|
|
3156
|
-
var
|
|
3178
|
+
var wr = class {
|
|
3157
3179
|
opts;
|
|
3158
3180
|
abort = new AbortController();
|
|
3159
3181
|
listeners = {};
|
|
@@ -3248,7 +3270,7 @@ var br = class {
|
|
|
3248
3270
|
setTimeout(() => {
|
|
3249
3271
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
3250
3272
|
phase: i ? "unavailable" : "tooEarly",
|
|
3251
|
-
retryInMs:
|
|
3273
|
+
retryInMs: hr,
|
|
3252
3274
|
attempt: 1,
|
|
3253
3275
|
elapsedMs: 0,
|
|
3254
3276
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -3287,13 +3309,13 @@ var br = class {
|
|
|
3287
3309
|
!a && !p() && h();
|
|
3288
3310
|
}, e);
|
|
3289
3311
|
};
|
|
3290
|
-
_(
|
|
3312
|
+
_(mr), this.armingSub = E({
|
|
3291
3313
|
eventsBaseUrl: t,
|
|
3292
3314
|
matchUrn: this.opts.matchUrn,
|
|
3293
3315
|
credential: this.opts.credential,
|
|
3294
|
-
onAlive: () => _(
|
|
3316
|
+
onAlive: () => _(hr),
|
|
3295
3317
|
onState: (e) => {
|
|
3296
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
3318
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * gr);
|
|
3297
3319
|
},
|
|
3298
3320
|
onError: () => h()
|
|
3299
3321
|
});
|
|
@@ -3338,19 +3360,19 @@ var br = class {
|
|
|
3338
3360
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
3339
3361
|
let i = e.analytics?.sid;
|
|
3340
3362
|
if (!i) return;
|
|
3341
|
-
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } =
|
|
3363
|
+
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = Vn(this.opts.baseUrl, a, e.analytics?.endpoint);
|
|
3342
3364
|
if (!o) {
|
|
3343
3365
|
s && setTimeout(() => {
|
|
3344
3366
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
|
|
3345
3367
|
}, 0);
|
|
3346
3368
|
return;
|
|
3347
3369
|
}
|
|
3348
|
-
let c = this.opts.video, l = new
|
|
3370
|
+
let c = this.opts.video, l = new Hn({
|
|
3349
3371
|
endpoint: o,
|
|
3350
3372
|
sid: i,
|
|
3351
3373
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
3352
|
-
sdkVersion:
|
|
3353
|
-
environment:
|
|
3374
|
+
sdkVersion: Jn,
|
|
3375
|
+
environment: Kn(c),
|
|
3354
3376
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
3355
3377
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
3356
3378
|
onBlocked: (e) => setTimeout(() => {
|
|
@@ -3371,7 +3393,7 @@ var br = class {
|
|
|
3371
3393
|
let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
|
|
3372
3394
|
c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
|
|
3373
3395
|
c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
|
|
3374
|
-
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()),
|
|
3396
|
+
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), qn().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
3375
3397
|
}
|
|
3376
3398
|
currentPresentation() {
|
|
3377
3399
|
let e = this.opts.video;
|
|
@@ -3391,6 +3413,7 @@ var br = class {
|
|
|
3391
3413
|
lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
|
|
3392
3414
|
snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
|
|
3393
3415
|
rememberBandwidth: this.opts.rememberBandwidth,
|
|
3416
|
+
sizeCapHeadroom: this.opts.sizeCapHeadroom,
|
|
3394
3417
|
mediaDuringKey: this.opts.mediaDuringKey,
|
|
3395
3418
|
debug: this.opts.debug,
|
|
3396
3419
|
deferLoad: r,
|
|
@@ -3399,9 +3422,9 @@ var br = class {
|
|
|
3399
3422
|
freshLicenseUrl: () => this.refreshLicense()
|
|
3400
3423
|
}, o = this.opts.engine ?? "auto";
|
|
3401
3424
|
if (o === "native") return new W(a);
|
|
3402
|
-
if (o === "hls") return new
|
|
3425
|
+
if (o === "hls") return new wn(a);
|
|
3403
3426
|
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && H(this.opts.video) && U() || !e.drmEnabled && St() && H(this.opts.video)) return new W(a);
|
|
3404
|
-
if (It()) return new
|
|
3427
|
+
if (It()) return new wn(a);
|
|
3405
3428
|
if (H(this.opts.video)) return new W(a);
|
|
3406
3429
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
3407
3430
|
}
|
|
@@ -3464,7 +3487,7 @@ var br = class {
|
|
|
3464
3487
|
r = 0, i = !1;
|
|
3465
3488
|
},
|
|
3466
3489
|
onError: () => {
|
|
3467
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
3490
|
+
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= _r && (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.`))));
|
|
3468
3491
|
}
|
|
3469
3492
|
});
|
|
3470
3493
|
}
|
|
@@ -3478,7 +3501,7 @@ var br = class {
|
|
|
3478
3501
|
return;
|
|
3479
3502
|
}
|
|
3480
3503
|
let e = this.hiddenAtMs;
|
|
3481
|
-
this.hiddenAtMs = null, e != null && Date.now() - e >=
|
|
3504
|
+
this.hiddenAtMs = null, e != null && Date.now() - e >= vr && this.resyncLiveState();
|
|
3482
3505
|
}, this.onReturnPageShow = (e) => {
|
|
3483
3506
|
e.persisted && this.resyncLiveState();
|
|
3484
3507
|
}, document.addEventListener("visibilitychange", this.onReturnVisible), typeof window < "u" && window.addEventListener("pageshow", this.onReturnPageShow));
|
|
@@ -3510,7 +3533,7 @@ var br = class {
|
|
|
3510
3533
|
scheduleRejoin(e) {
|
|
3511
3534
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
3512
3535
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
3513
|
-
}, Math.random() *
|
|
3536
|
+
}, Math.random() * gr));
|
|
3514
3537
|
}
|
|
3515
3538
|
cancelRejoin() {
|
|
3516
3539
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -3534,7 +3557,7 @@ var br = class {
|
|
|
3534
3557
|
}
|
|
3535
3558
|
t.controls = !1;
|
|
3536
3559
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
3537
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
3560
|
+
r && r.insertBefore(n, t), n.appendChild(t), Zn(n, this.opts.theme), this.container = n, this.controlBar = cr({
|
|
3538
3561
|
root: n,
|
|
3539
3562
|
video: t,
|
|
3540
3563
|
player: this,
|
|
@@ -3572,7 +3595,7 @@ var br = class {
|
|
|
3572
3595
|
}
|
|
3573
3596
|
startStats() {
|
|
3574
3597
|
this.stopStats();
|
|
3575
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
3598
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? yr);
|
|
3576
3599
|
this.statsTimer = setInterval(() => {
|
|
3577
3600
|
if (!this.engine) return;
|
|
3578
3601
|
let e = this.engine.getStats();
|
|
@@ -3583,14 +3606,14 @@ var br = class {
|
|
|
3583
3606
|
this.statsTimer && clearInterval(this.statsTimer), this.statsTimer = void 0;
|
|
3584
3607
|
}
|
|
3585
3608
|
isStaleLicenseDenial(e) {
|
|
3586
|
-
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !==
|
|
3609
|
+
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== xr || e.error.httpStatus !== 403 || e.error.code !== "FORBIDDEN" || e.error.serverCode === "license_refused" ? !1 : K(this._descriptor?.drm?.widevine?.licenseUrl);
|
|
3587
3610
|
}
|
|
3588
3611
|
scheduleLicenseRefresh() {
|
|
3589
3612
|
if (this.stopRefresh(), !this._descriptor?.drmEnabled) return;
|
|
3590
3613
|
typeof document < "u" && this.engine?.name === "hls" && (this.onRefocus = () => {
|
|
3591
3614
|
document.visibilityState !== "visible" || this.destroyed || K(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
|
|
3592
3615
|
}, document.addEventListener("visibilitychange", this.onRefocus));
|
|
3593
|
-
let e = this.opts.licenseRefreshMs ??
|
|
3616
|
+
let e = this.opts.licenseRefreshMs ?? br;
|
|
3594
3617
|
e && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
3595
3618
|
}
|
|
3596
3619
|
stopRefresh() {
|
|
@@ -3760,7 +3783,7 @@ function $(e) {
|
|
|
3760
3783
|
}
|
|
3761
3784
|
//#endregion
|
|
3762
3785
|
//#region src/embed/host.ts
|
|
3763
|
-
function
|
|
3786
|
+
function Tr(e) {
|
|
3764
3787
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
3765
3788
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
3766
3789
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -3819,15 +3842,15 @@ function xr(e) {
|
|
|
3819
3842
|
}
|
|
3820
3843
|
//#endregion
|
|
3821
3844
|
//#region src/embed/page.ts
|
|
3822
|
-
var
|
|
3823
|
-
function
|
|
3845
|
+
var Er = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
3846
|
+
function Dr(e) {
|
|
3824
3847
|
if (typeof e == "boolean") return e;
|
|
3825
3848
|
if (typeof e == "object" && e) {
|
|
3826
3849
|
let t = e.endpoint;
|
|
3827
3850
|
return typeof t == "string" ? { endpoint: t } : {};
|
|
3828
3851
|
}
|
|
3829
3852
|
}
|
|
3830
|
-
function
|
|
3853
|
+
function Or() {
|
|
3831
3854
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
3832
3855
|
if (e) return {
|
|
3833
3856
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -3837,7 +3860,7 @@ function wr() {
|
|
|
3837
3860
|
autoplay: e.autoplay ?? !0,
|
|
3838
3861
|
muted: e.muted ?? !0,
|
|
3839
3862
|
waitForLive: e.waitForLive ?? !0,
|
|
3840
|
-
analytics:
|
|
3863
|
+
analytics: Dr(e.analytics)
|
|
3841
3864
|
};
|
|
3842
3865
|
let t = new URLSearchParams(location.search);
|
|
3843
3866
|
return {
|
|
@@ -3850,9 +3873,9 @@ function wr() {
|
|
|
3850
3873
|
waitForLive: !0
|
|
3851
3874
|
};
|
|
3852
3875
|
}
|
|
3853
|
-
async function
|
|
3854
|
-
let e =
|
|
3855
|
-
|
|
3876
|
+
async function kr() {
|
|
3877
|
+
let e = Or();
|
|
3878
|
+
jr();
|
|
3856
3879
|
let t = document.createElement("video");
|
|
3857
3880
|
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);
|
|
3858
3881
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -3908,12 +3931,12 @@ async function Tr() {
|
|
|
3908
3931
|
message: e.message,
|
|
3909
3932
|
...e.country === void 0 ? {} : { country: e.country }
|
|
3910
3933
|
})), e.on("autoplayblocked", () => {
|
|
3911
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
3934
|
+
i({ type: "oddin:autoplayblocked" }), Ar(t, e);
|
|
3912
3935
|
});
|
|
3913
3936
|
}, s = async (r) => {
|
|
3914
3937
|
a?.destroy(), a = null;
|
|
3915
3938
|
try {
|
|
3916
|
-
let n = await
|
|
3939
|
+
let n = await Cr({
|
|
3917
3940
|
video: t,
|
|
3918
3941
|
baseUrl: e.baseUrl,
|
|
3919
3942
|
matchUrn: r,
|
|
@@ -3976,7 +3999,7 @@ async function Tr() {
|
|
|
3976
3999
|
a?.retry();
|
|
3977
4000
|
break;
|
|
3978
4001
|
case "oddin:load":
|
|
3979
|
-
typeof e.matchUrn == "string" &&
|
|
4002
|
+
typeof e.matchUrn == "string" && Er.test(e.matchUrn) && s(e.matchUrn);
|
|
3980
4003
|
break;
|
|
3981
4004
|
case "oddin:destroy": c();
|
|
3982
4005
|
}
|
|
@@ -3988,18 +4011,18 @@ async function Tr() {
|
|
|
3988
4011
|
protocol: 1
|
|
3989
4012
|
});
|
|
3990
4013
|
}
|
|
3991
|
-
function
|
|
4014
|
+
function Ar(e, t) {
|
|
3992
4015
|
if (document.getElementById("havik-tap")) return;
|
|
3993
4016
|
let n = document.createElement("button");
|
|
3994
4017
|
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", () => {
|
|
3995
4018
|
n.remove(), t.play();
|
|
3996
4019
|
}), document.body.appendChild(n);
|
|
3997
4020
|
}
|
|
3998
|
-
function
|
|
4021
|
+
function jr() {
|
|
3999
4022
|
let e = document.createElement("style");
|
|
4000
4023
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
4001
4024
|
}
|
|
4002
4025
|
//#endregion
|
|
4003
|
-
export {
|
|
4026
|
+
export { Yn as ODDIN_THEME, n as PlaybackError, Zn as applyTheme, at as baseUrlForEnv, kr as bootEmbed, Ee as clearDeviceId, Re as clearRememberedBandwidth, Cr as createPlayer, D as deriveEventsBaseUrl, tt as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ve as fetchCatalog, be as fetchTournament, Se as flattenMatches, C as fullscreenSupported, A as getDeviceId, rt as isLowLatencyManifest, $ as isOddinMessage, Oe as licenseRequestHeaders, Tr as mountEmbed, fe as pollToLive, y as resolveStream, E as subscribeLiveState, S as videoFullscreenActive, we as watchStatus };
|
|
4004
4027
|
|
|
4005
4028
|
//# sourceMappingURL=index.js.map
|