@oddin-gg/havik-player 2.21.0 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +134 -119
- package/dist/index.js.map +1 -1
- package/docs/API.md +11 -3
- 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 = 9, yn = .5, bn = 64;
|
|
1498
|
+
function xn(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 ??= _n;
|
|
1504
|
+
let t = Math.max(12, e.liveSyncDuration + vn);
|
|
1505
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Sn(e, e.liveSyncDuration);
|
|
1496
1506
|
}
|
|
1497
|
-
function
|
|
1507
|
+
function Sn(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 Cn = class {
|
|
1502
1512
|
name = "hls";
|
|
1503
1513
|
hls = null;
|
|
1504
1514
|
deps;
|
|
@@ -1650,7 +1660,7 @@ var bn = class {
|
|
|
1650
1660
|
let t = e.liveSyncPosition;
|
|
1651
1661
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1652
1662
|
let { video: n } = this.deps;
|
|
1653
|
-
n.currentTime <= t +
|
|
1663
|
+
n.currentTime <= t + yn || (n.currentTime = t);
|
|
1654
1664
|
}
|
|
1655
1665
|
reanchorPartTimeline(e, t) {
|
|
1656
1666
|
let { frag: n, part: r } = t;
|
|
@@ -1724,7 +1734,7 @@ var bn = class {
|
|
|
1724
1734
|
}), t = Mt(e);
|
|
1725
1735
|
t && (this.prefetch = e, f.fLoader = t);
|
|
1726
1736
|
}
|
|
1727
|
-
|
|
1737
|
+
xn(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
1738
|
let p = new e(f);
|
|
1729
1739
|
if (this.hls = p, p.on(e.Events.FRAG_PARSED, (e, t) => this.reanchorPartTimeline(p, t)), p.on(e.Events.MANIFEST_PARSED, () => {
|
|
1730
1740
|
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 +1749,7 @@ var bn = class {
|
|
|
1739
1749
|
let n = t?.frag?.stats, r = n?.loaded;
|
|
1740
1750
|
typeof r == "number" && (this.bytesLoaded += r), !this.reportedFirstBytes && typeof r == "number" && r > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
|
|
1741
1751
|
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 >
|
|
1752
|
+
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 > bn && this.requestTimesMs.shift());
|
|
1743
1753
|
let a = t?.frag?.url;
|
|
1744
1754
|
if (a) {
|
|
1745
1755
|
let e = ot(a);
|
|
@@ -1812,8 +1822,12 @@ var bn = class {
|
|
|
1812
1822
|
if (!e || e.levels.length === 0) return null;
|
|
1813
1823
|
let { video: n } = this.deps, r = n.getBoundingClientRect(), i = r.width, a = r.height;
|
|
1814
1824
|
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
|
-
|
|
1825
|
+
let o = e.config ?? {}, s = typeof self < "u" && self.devicePixelRatio > 0 ? self.devicePixelRatio : 1, c = o.ignoreDevicePixelRatio ? 1 : s;
|
|
1826
|
+
c = Math.min(c, o.maxDevicePixelRatio ?? Infinity);
|
|
1827
|
+
let l = t.getMaxLevelByMediaSize(e.levels, i * c, a * c), u = this.deps.sizeCapHeadroom;
|
|
1828
|
+
if (u == null && s >= fn) return l;
|
|
1829
|
+
let d = u ?? dn, f = Number.isNaN(d) ? dn : d === Infinity ? e.levels.length : Math.max(0, Math.floor(d));
|
|
1830
|
+
return pn(e.levels, l, f);
|
|
1817
1831
|
}
|
|
1818
1832
|
onMediaResize() {
|
|
1819
1833
|
if (!this.sizeCapManaged) return;
|
|
@@ -2023,15 +2037,15 @@ var bn = class {
|
|
|
2023
2037
|
return;
|
|
2024
2038
|
}
|
|
2025
2039
|
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 <
|
|
2040
|
+
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < hn || o < 0) {
|
|
2027
2041
|
this.fpsBadTicks = 0;
|
|
2028
2042
|
return;
|
|
2029
2043
|
}
|
|
2030
|
-
if (o <=
|
|
2044
|
+
if (o <= mn * a) {
|
|
2031
2045
|
this.fpsBadTicks = 0;
|
|
2032
2046
|
return;
|
|
2033
2047
|
}
|
|
2034
|
-
if (this.fpsBadTicks += 1, this.fpsBadTicks <
|
|
2048
|
+
if (this.fpsBadTicks += 1, this.fpsBadTicks < gn) return;
|
|
2035
2049
|
this.fpsBadTicks = 0;
|
|
2036
2050
|
let s = e.levels, c = s[e.currentLevel];
|
|
2037
2051
|
if (!c) return;
|
|
@@ -2189,19 +2203,19 @@ var bn = class {
|
|
|
2189
2203
|
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
2204
|
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
2205
|
}
|
|
2192
|
-
},
|
|
2206
|
+
}, wn = 15e3, Tn = 6e5, En = 3e5, Dn = 100, q = 1, On = 1e3, kn = 3e4, An = 1e3, jn = {
|
|
2193
2207
|
inline: "PRESENTATION_INLINE",
|
|
2194
2208
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
2195
2209
|
pip: "PRESENTATION_PIP"
|
|
2196
|
-
},
|
|
2210
|
+
}, Mn = {
|
|
2197
2211
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
2198
2212
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
2199
2213
|
none: "KEY_SYSTEM_NONE"
|
|
2200
2214
|
};
|
|
2201
|
-
function
|
|
2215
|
+
function Nn(e, t) {
|
|
2202
2216
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
2203
2217
|
}
|
|
2204
|
-
var
|
|
2218
|
+
var Pn = /* @__PURE__ */ new Set([
|
|
2205
2219
|
"INVALID_URN",
|
|
2206
2220
|
"NOT_FOUND",
|
|
2207
2221
|
"GEO_DENIED",
|
|
@@ -2222,7 +2236,7 @@ var jn = /* @__PURE__ */ new Set([
|
|
|
2222
2236
|
ended: "PLAYER_STATE_ENDED",
|
|
2223
2237
|
error: "PLAYER_STATE_ERROR"
|
|
2224
2238
|
};
|
|
2225
|
-
function
|
|
2239
|
+
function Fn(e) {
|
|
2226
2240
|
try {
|
|
2227
2241
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
2228
2242
|
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 +2244,8 @@ function Mn(e) {
|
|
|
2230
2244
|
return;
|
|
2231
2245
|
}
|
|
2232
2246
|
}
|
|
2233
|
-
var
|
|
2234
|
-
function
|
|
2247
|
+
var In = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), Ln = /* @__PURE__ */ new Set(), Y = /* @__PURE__ */ new Set(), X = /* @__PURE__ */ new Set(), Rn = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
|
|
2248
|
+
function zn(e) {
|
|
2235
2249
|
if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
|
|
2236
2250
|
let t;
|
|
2237
2251
|
try {
|
|
@@ -2240,19 +2254,19 @@ function In(e) {
|
|
|
2240
2254
|
} catch {
|
|
2241
2255
|
return;
|
|
2242
2256
|
}
|
|
2243
|
-
if (
|
|
2244
|
-
Y.add(t), _(
|
|
2257
|
+
if (Ln.has(t) && !Y.has(t)) {
|
|
2258
|
+
Y.add(t), _(Rn(new URL(t).origin));
|
|
2245
2259
|
for (let e of X) e.noteCspBlocked();
|
|
2246
2260
|
}
|
|
2247
2261
|
}
|
|
2248
|
-
function
|
|
2262
|
+
function Z(e, t) {
|
|
2249
2263
|
return _(t, e), { disabledReason: t };
|
|
2250
2264
|
}
|
|
2251
|
-
function
|
|
2252
|
-
if (n) return t && !
|
|
2265
|
+
function Bn(e, t, n) {
|
|
2266
|
+
if (n) return t && !In(t, n) && _(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
|
|
2253
2267
|
if (t) return { endpoint: t };
|
|
2254
|
-
if (t !== void 0) return
|
|
2255
|
-
let r =
|
|
2268
|
+
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).");
|
|
2269
|
+
let r = Fn(e);
|
|
2256
2270
|
if (r) return { endpoint: r };
|
|
2257
2271
|
let i;
|
|
2258
2272
|
try {
|
|
@@ -2260,9 +2274,9 @@ function Rn(e, t, n) {
|
|
|
2260
2274
|
} catch {
|
|
2261
2275
|
i = e;
|
|
2262
2276
|
}
|
|
2263
|
-
return
|
|
2277
|
+
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
2278
|
}
|
|
2265
|
-
var
|
|
2279
|
+
var Vn = class {
|
|
2266
2280
|
opts;
|
|
2267
2281
|
url;
|
|
2268
2282
|
cspKey;
|
|
@@ -2344,8 +2358,8 @@ var zn = class {
|
|
|
2344
2358
|
constructor(e) {
|
|
2345
2359
|
this.opts = {
|
|
2346
2360
|
...e,
|
|
2347
|
-
heartbeatMs: e.heartbeatMs ??
|
|
2348
|
-
idleMs: e.idleMs ??
|
|
2361
|
+
heartbeatMs: e.heartbeatMs ?? wn,
|
|
2362
|
+
idleMs: e.idleMs ?? Tn
|
|
2349
2363
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
|
|
2350
2364
|
try {
|
|
2351
2365
|
let e = new URL(this.url);
|
|
@@ -2362,11 +2376,11 @@ var zn = class {
|
|
|
2362
2376
|
sdkVersion: this.opts.sdkVersion,
|
|
2363
2377
|
...this.opts.environment
|
|
2364
2378
|
};
|
|
2365
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
2379
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), On), this.lastTickMs = this.now(), this.timer = setInterval(() => this.heartbeat(), this.opts.heartbeatMs), typeof window < "u" && window.addEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.addEventListener("visibilitychange", this.onVisibility), document.addEventListener("freeze", this.onFreeze), document.addEventListener("resume", this.onResume), this.cspKey && Ln.add(this.cspKey), document.addEventListener("securitypolicyviolation", zn), X.add(this), this.noteCspBlocked(), this.onVisibility());
|
|
2366
2380
|
}
|
|
2367
2381
|
checkSuspension(e) {
|
|
2368
2382
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
2369
|
-
let t = Math.max(this.opts.idleMs,
|
|
2383
|
+
let t = Math.max(this.opts.idleMs, En);
|
|
2370
2384
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
2371
2385
|
}
|
|
2372
2386
|
syncIdle(e) {
|
|
@@ -2389,12 +2403,12 @@ var zn = class {
|
|
|
2389
2403
|
let a = {
|
|
2390
2404
|
fromState: J[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2391
2405
|
toState: J[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2392
|
-
presentation:
|
|
2406
|
+
presentation: jn[this.presentation]
|
|
2393
2407
|
}, o = this.causeOf(e, t, i);
|
|
2394
2408
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
2395
2409
|
}
|
|
2396
2410
|
seekInduced(e) {
|
|
2397
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
2411
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < An;
|
|
2398
2412
|
}
|
|
2399
2413
|
causeOf(e, t, n) {
|
|
2400
2414
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -2468,7 +2482,7 @@ var zn = class {
|
|
|
2468
2482
|
let r = n ?? "";
|
|
2469
2483
|
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
2484
|
if (e === "DRM_CLIENT" || e === "DRM_DEVICE_REVOKED") return "ERROR_STAGE_DRM";
|
|
2471
|
-
if (
|
|
2485
|
+
if (Pn.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
2472
2486
|
let i = t ?? "";
|
|
2473
2487
|
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
2488
|
}
|
|
@@ -2515,14 +2529,14 @@ var zn = class {
|
|
|
2515
2529
|
if (this.lastRequestCount = g, _ > 0) {
|
|
2516
2530
|
o.requestCountDelta = _;
|
|
2517
2531
|
let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
|
|
2518
|
-
n.length > 0 && (o.requestTimeP50Ms =
|
|
2532
|
+
n.length > 0 && (o.requestTimeP50Ms = Nn(n, 50), o.requestTimeP95Ms = Nn(n, 95));
|
|
2519
2533
|
}
|
|
2520
2534
|
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
2535
|
}
|
|
2522
2536
|
maybeEmitMediaInfo(e) {
|
|
2523
2537
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
2524
2538
|
let t = {};
|
|
2525
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
2539
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = Mn[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
2540
|
let n = JSON.stringify(t);
|
|
2527
2541
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
2528
2542
|
}
|
|
@@ -2542,7 +2556,7 @@ var zn = class {
|
|
|
2542
2556
|
let c = r?.positionMs ?? 0;
|
|
2543
2557
|
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
2558
|
let l = e !== "END_REASON_ENDED";
|
|
2545
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
2559
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= kn && (i.abandonAfterStallMs = Math.max(q, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= kn && (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
2560
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
2547
2561
|
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
2562
|
}
|
|
@@ -2562,13 +2576,13 @@ var zn = class {
|
|
|
2562
2576
|
};
|
|
2563
2577
|
}
|
|
2564
2578
|
noteCspBlocked() {
|
|
2565
|
-
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(
|
|
2579
|
+
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(Rn(new URL(this.url).origin)));
|
|
2566
2580
|
}
|
|
2567
2581
|
cspBlocked() {
|
|
2568
2582
|
return !!this.cspKey && Y.has(this.cspKey);
|
|
2569
2583
|
}
|
|
2570
2584
|
enqueue(e) {
|
|
2571
|
-
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
2585
|
+
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > Dn;) {
|
|
2572
2586
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
2573
2587
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
2574
2588
|
}
|
|
@@ -2595,7 +2609,7 @@ var zn = class {
|
|
|
2595
2609
|
};
|
|
2596
2610
|
//#endregion
|
|
2597
2611
|
//#region src/core/environment.ts
|
|
2598
|
-
function
|
|
2612
|
+
function Hn() {
|
|
2599
2613
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
2600
2614
|
let e;
|
|
2601
2615
|
try {
|
|
@@ -2620,14 +2634,14 @@ function Bn() {
|
|
|
2620
2634
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
2621
2635
|
};
|
|
2622
2636
|
}
|
|
2623
|
-
function
|
|
2637
|
+
function Un() {
|
|
2624
2638
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
2625
2639
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
2626
2640
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
2627
2641
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
2628
2642
|
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
2643
|
}
|
|
2630
|
-
function
|
|
2644
|
+
function Wn() {
|
|
2631
2645
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
2632
2646
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
2633
2647
|
let t = {
|
|
@@ -2646,17 +2660,17 @@ function Hn() {
|
|
|
2646
2660
|
}
|
|
2647
2661
|
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
2662
|
}
|
|
2649
|
-
function
|
|
2650
|
-
let t =
|
|
2651
|
-
deviceClass:
|
|
2663
|
+
function Gn(e) {
|
|
2664
|
+
let t = Hn(), n = {
|
|
2665
|
+
deviceClass: Un(),
|
|
2652
2666
|
integration: t.integration,
|
|
2653
|
-
...
|
|
2667
|
+
...Wn()
|
|
2654
2668
|
};
|
|
2655
2669
|
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
2670
|
let r = e.getBoundingClientRect?.();
|
|
2657
2671
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
2658
2672
|
}
|
|
2659
|
-
async function
|
|
2673
|
+
async function Kn() {
|
|
2660
2674
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
2661
2675
|
if (!e?.getHighEntropyValues) return {};
|
|
2662
2676
|
try {
|
|
@@ -2668,7 +2682,7 @@ async function Wn() {
|
|
|
2668
2682
|
}
|
|
2669
2683
|
//#endregion
|
|
2670
2684
|
//#region src/core/version.ts
|
|
2671
|
-
var
|
|
2685
|
+
var qn = "2.22.0", Jn = {
|
|
2672
2686
|
accent: "#E1B600",
|
|
2673
2687
|
accentText: "#1B1C23",
|
|
2674
2688
|
background: "#0e0f13",
|
|
@@ -2679,7 +2693,7 @@ var Gn = "2.21.0", Kn = {
|
|
|
2679
2693
|
border: "rgba(255, 255, 255, 0.1)",
|
|
2680
2694
|
radius: "8px",
|
|
2681
2695
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
2682
|
-
},
|
|
2696
|
+
}, Yn = {
|
|
2683
2697
|
accent: "--havik-accent",
|
|
2684
2698
|
accentText: "--havik-accent-text",
|
|
2685
2699
|
background: "--havik-bg",
|
|
@@ -2691,26 +2705,26 @@ var Gn = "2.21.0", Kn = {
|
|
|
2691
2705
|
radius: "--havik-radius",
|
|
2692
2706
|
fontFamily: "--havik-font"
|
|
2693
2707
|
};
|
|
2694
|
-
function
|
|
2708
|
+
function Xn(e, t) {
|
|
2695
2709
|
let n = {
|
|
2696
|
-
...
|
|
2710
|
+
...Jn,
|
|
2697
2711
|
...t
|
|
2698
2712
|
};
|
|
2699
|
-
for (let t of Object.keys(
|
|
2713
|
+
for (let t of Object.keys(Yn)) e.style.setProperty(Yn[t], n[t]);
|
|
2700
2714
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
2701
2715
|
}
|
|
2702
2716
|
//#endregion
|
|
2703
2717
|
//#region src/ui/styles.ts
|
|
2704
|
-
var
|
|
2705
|
-
function
|
|
2706
|
-
let n = e.querySelector(`style#${
|
|
2707
|
-
if (n && (!t ||
|
|
2718
|
+
var Zn = "havik-player-styles", Qn = "\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", $n = /* @__PURE__ */ new WeakMap();
|
|
2719
|
+
function er(e = document, t) {
|
|
2720
|
+
let n = e.querySelector(`style#${Zn}`);
|
|
2721
|
+
if (n && (!t || $n.get(n) === t)) return;
|
|
2708
2722
|
let r = e.createElement("style");
|
|
2709
|
-
r.id =
|
|
2723
|
+
r.id = Zn, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = Qn, $n.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
|
|
2710
2724
|
}
|
|
2711
2725
|
//#endregion
|
|
2712
2726
|
//#region src/ui/icons.ts
|
|
2713
|
-
var
|
|
2727
|
+
var tr = {
|
|
2714
2728
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
2715
2729
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
2716
2730
|
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 +2738,11 @@ var Qn = {
|
|
|
2724
2738
|
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
2739
|
};
|
|
2726
2740
|
function Q(e) {
|
|
2727
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
2741
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${tr[e]}</svg>`;
|
|
2728
2742
|
}
|
|
2729
2743
|
//#endregion
|
|
2730
2744
|
//#region src/ui/controls.ts
|
|
2731
|
-
var
|
|
2745
|
+
var nr = 3e3, rr = 250, ir = /* @__PURE__ */ new Set([
|
|
2732
2746
|
"GONE",
|
|
2733
2747
|
"NOT_FOUND",
|
|
2734
2748
|
"GEO_DENIED",
|
|
@@ -2736,15 +2750,15 @@ var $n = 3e3, er = 250, tr = /* @__PURE__ */ new Set([
|
|
|
2736
2750
|
"UNAUTHORIZED",
|
|
2737
2751
|
"DRM_DEVICE_REVOKED"
|
|
2738
2752
|
]);
|
|
2739
|
-
function
|
|
2753
|
+
function ar(e) {
|
|
2740
2754
|
let t = "This match isn't available in your country";
|
|
2741
2755
|
return e ? `${t} (${e})` : t;
|
|
2742
2756
|
}
|
|
2743
|
-
var
|
|
2744
|
-
function
|
|
2745
|
-
return new
|
|
2757
|
+
var or = "This device can't play protected video";
|
|
2758
|
+
function sr(e) {
|
|
2759
|
+
return new cr(e);
|
|
2746
2760
|
}
|
|
2747
|
-
var
|
|
2761
|
+
var cr = class {
|
|
2748
2762
|
root;
|
|
2749
2763
|
video;
|
|
2750
2764
|
player;
|
|
@@ -2792,7 +2806,7 @@ var ar = class {
|
|
|
2792
2806
|
scrubbing = !1;
|
|
2793
2807
|
offFns = [];
|
|
2794
2808
|
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 ??
|
|
2809
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? nr, 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, er(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
2810
|
let t = (e, t, n) => {
|
|
2797
2811
|
let r = this.doc.createElement(e);
|
|
2798
2812
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -2878,7 +2892,7 @@ var ar = class {
|
|
|
2878
2892
|
let t = this.surfaceWasHidden;
|
|
2879
2893
|
this.tapTimer = setTimeout(() => {
|
|
2880
2894
|
this.tapTimer = void 0, this.toggleBar(t);
|
|
2881
|
-
},
|
|
2895
|
+
}, rr);
|
|
2882
2896
|
}
|
|
2883
2897
|
toggleBar(e) {
|
|
2884
2898
|
e ? this.poke() : this.hideIfIdle();
|
|
@@ -2898,7 +2912,7 @@ var ar = class {
|
|
|
2898
2912
|
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
2913
|
}
|
|
2900
2914
|
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" ?
|
|
2915
|
+
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" ? ar(this.lastError.country) : this.lastError?.code === "DRM_DEVICE_REVOKED" ? or : this.lastError?.message ?? "Playback unavailable" : this.errorMessage : null;
|
|
2902
2916
|
}
|
|
2903
2917
|
renderStatus(e) {
|
|
2904
2918
|
let t = this.statusMessageFor(e);
|
|
@@ -2913,7 +2927,7 @@ var ar = class {
|
|
|
2913
2927
|
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
2928
|
} else {
|
|
2915
2929
|
let r = this.doc.createElement("div");
|
|
2916
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
2930
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !ir.has(this.lastError.code)) {
|
|
2917
2931
|
let e = this.doc.createElement("button");
|
|
2918
2932
|
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
2933
|
}
|
|
@@ -2954,7 +2968,7 @@ var ar = class {
|
|
|
2954
2968
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
2955
2969
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
2956
2970
|
}
|
|
2957
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
2971
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${lr(this.video.currentTime)} / ${lr(this.video.duration)}`);
|
|
2958
2972
|
}
|
|
2959
2973
|
syncLive() {
|
|
2960
2974
|
let e = this.player.getStats(), t = e.isLive !== !1, n = this.player.state === "ended", r = !t && !this.streamEnded();
|
|
@@ -3004,17 +3018,17 @@ var ar = class {
|
|
|
3004
3018
|
renderQualityMenu() {
|
|
3005
3019
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
3006
3020
|
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(
|
|
3021
|
+
for (let n of e) this.menu.append(this.menuItem(ur(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
3008
3022
|
}
|
|
3009
3023
|
renderAudioMenu() {
|
|
3010
3024
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
3011
3025
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
3012
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
3026
|
+
for (let t of e) this.menu.append(this.menuItem(dr(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
3013
3027
|
}
|
|
3014
3028
|
renderCcMenu() {
|
|
3015
3029
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
3016
3030
|
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(
|
|
3031
|
+
for (let t of e) this.menu.append(this.menuItem(fr(t), !1, () => this.player.setTextTrack(t.id)));
|
|
3018
3032
|
}
|
|
3019
3033
|
onTracksChanged() {
|
|
3020
3034
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -3119,41 +3133,41 @@ var ar = class {
|
|
|
3119
3133
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
3120
3134
|
}
|
|
3121
3135
|
};
|
|
3122
|
-
function
|
|
3136
|
+
function lr(e) {
|
|
3123
3137
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
3124
3138
|
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
3139
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
3126
3140
|
}
|
|
3127
|
-
function
|
|
3141
|
+
function ur(e) {
|
|
3128
3142
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
3129
3143
|
}
|
|
3130
|
-
function
|
|
3144
|
+
function dr(e) {
|
|
3131
3145
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3132
3146
|
}
|
|
3133
|
-
function
|
|
3147
|
+
function fr(e) {
|
|
3134
3148
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3135
3149
|
}
|
|
3136
3150
|
//#endregion
|
|
3137
3151
|
//#region src/managed/index.ts
|
|
3138
|
-
var
|
|
3139
|
-
function
|
|
3152
|
+
var pr = 6e3, mr = 45e3, hr = 2e3, gr = 3, _r = 5e3, vr = 2e3, yr = 48e4, br = "keySystemLicenseRequestFailed";
|
|
3153
|
+
function xr(e) {
|
|
3140
3154
|
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
3155
|
if (e.env !== void 0) return at(e.env);
|
|
3142
3156
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
3143
3157
|
return e.baseUrl;
|
|
3144
3158
|
}
|
|
3145
|
-
async function
|
|
3159
|
+
async function Sr(e) {
|
|
3146
3160
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
3147
|
-
let t =
|
|
3161
|
+
let t = xr(e);
|
|
3148
3162
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
3149
3163
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
3150
|
-
let r = new
|
|
3164
|
+
let r = new Cr({
|
|
3151
3165
|
...e,
|
|
3152
3166
|
baseUrl: t
|
|
3153
3167
|
});
|
|
3154
3168
|
return await r.start(), r;
|
|
3155
3169
|
}
|
|
3156
|
-
var
|
|
3170
|
+
var Cr = class {
|
|
3157
3171
|
opts;
|
|
3158
3172
|
abort = new AbortController();
|
|
3159
3173
|
listeners = {};
|
|
@@ -3248,7 +3262,7 @@ var br = class {
|
|
|
3248
3262
|
setTimeout(() => {
|
|
3249
3263
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
3250
3264
|
phase: i ? "unavailable" : "tooEarly",
|
|
3251
|
-
retryInMs:
|
|
3265
|
+
retryInMs: mr,
|
|
3252
3266
|
attempt: 1,
|
|
3253
3267
|
elapsedMs: 0,
|
|
3254
3268
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -3287,13 +3301,13 @@ var br = class {
|
|
|
3287
3301
|
!a && !p() && h();
|
|
3288
3302
|
}, e);
|
|
3289
3303
|
};
|
|
3290
|
-
_(
|
|
3304
|
+
_(pr), this.armingSub = E({
|
|
3291
3305
|
eventsBaseUrl: t,
|
|
3292
3306
|
matchUrn: this.opts.matchUrn,
|
|
3293
3307
|
credential: this.opts.credential,
|
|
3294
|
-
onAlive: () => _(
|
|
3308
|
+
onAlive: () => _(mr),
|
|
3295
3309
|
onState: (e) => {
|
|
3296
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
3310
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * hr);
|
|
3297
3311
|
},
|
|
3298
3312
|
onError: () => h()
|
|
3299
3313
|
});
|
|
@@ -3338,19 +3352,19 @@ var br = class {
|
|
|
3338
3352
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
3339
3353
|
let i = e.analytics?.sid;
|
|
3340
3354
|
if (!i) return;
|
|
3341
|
-
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } =
|
|
3355
|
+
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = Bn(this.opts.baseUrl, a, e.analytics?.endpoint);
|
|
3342
3356
|
if (!o) {
|
|
3343
3357
|
s && setTimeout(() => {
|
|
3344
3358
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
|
|
3345
3359
|
}, 0);
|
|
3346
3360
|
return;
|
|
3347
3361
|
}
|
|
3348
|
-
let c = this.opts.video, l = new
|
|
3362
|
+
let c = this.opts.video, l = new Vn({
|
|
3349
3363
|
endpoint: o,
|
|
3350
3364
|
sid: i,
|
|
3351
3365
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
3352
|
-
sdkVersion:
|
|
3353
|
-
environment:
|
|
3366
|
+
sdkVersion: qn,
|
|
3367
|
+
environment: Gn(c),
|
|
3354
3368
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
3355
3369
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
3356
3370
|
onBlocked: (e) => setTimeout(() => {
|
|
@@ -3371,7 +3385,7 @@ var br = class {
|
|
|
3371
3385
|
let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
|
|
3372
3386
|
c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
|
|
3373
3387
|
c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
|
|
3374
|
-
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()),
|
|
3388
|
+
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), Kn().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
3375
3389
|
}
|
|
3376
3390
|
currentPresentation() {
|
|
3377
3391
|
let e = this.opts.video;
|
|
@@ -3391,6 +3405,7 @@ var br = class {
|
|
|
3391
3405
|
lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
|
|
3392
3406
|
snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
|
|
3393
3407
|
rememberBandwidth: this.opts.rememberBandwidth,
|
|
3408
|
+
sizeCapHeadroom: this.opts.sizeCapHeadroom,
|
|
3394
3409
|
mediaDuringKey: this.opts.mediaDuringKey,
|
|
3395
3410
|
debug: this.opts.debug,
|
|
3396
3411
|
deferLoad: r,
|
|
@@ -3399,9 +3414,9 @@ var br = class {
|
|
|
3399
3414
|
freshLicenseUrl: () => this.refreshLicense()
|
|
3400
3415
|
}, o = this.opts.engine ?? "auto";
|
|
3401
3416
|
if (o === "native") return new W(a);
|
|
3402
|
-
if (o === "hls") return new
|
|
3417
|
+
if (o === "hls") return new Cn(a);
|
|
3403
3418
|
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
|
|
3419
|
+
if (It()) return new Cn(a);
|
|
3405
3420
|
if (H(this.opts.video)) return new W(a);
|
|
3406
3421
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
3407
3422
|
}
|
|
@@ -3464,7 +3479,7 @@ var br = class {
|
|
|
3464
3479
|
r = 0, i = !1;
|
|
3465
3480
|
},
|
|
3466
3481
|
onError: () => {
|
|
3467
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
3482
|
+
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= gr && (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
3483
|
}
|
|
3469
3484
|
});
|
|
3470
3485
|
}
|
|
@@ -3478,7 +3493,7 @@ var br = class {
|
|
|
3478
3493
|
return;
|
|
3479
3494
|
}
|
|
3480
3495
|
let e = this.hiddenAtMs;
|
|
3481
|
-
this.hiddenAtMs = null, e != null && Date.now() - e >=
|
|
3496
|
+
this.hiddenAtMs = null, e != null && Date.now() - e >= _r && this.resyncLiveState();
|
|
3482
3497
|
}, this.onReturnPageShow = (e) => {
|
|
3483
3498
|
e.persisted && this.resyncLiveState();
|
|
3484
3499
|
}, document.addEventListener("visibilitychange", this.onReturnVisible), typeof window < "u" && window.addEventListener("pageshow", this.onReturnPageShow));
|
|
@@ -3510,7 +3525,7 @@ var br = class {
|
|
|
3510
3525
|
scheduleRejoin(e) {
|
|
3511
3526
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
3512
3527
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
3513
|
-
}, Math.random() *
|
|
3528
|
+
}, Math.random() * hr));
|
|
3514
3529
|
}
|
|
3515
3530
|
cancelRejoin() {
|
|
3516
3531
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -3534,7 +3549,7 @@ var br = class {
|
|
|
3534
3549
|
}
|
|
3535
3550
|
t.controls = !1;
|
|
3536
3551
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
3537
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
3552
|
+
r && r.insertBefore(n, t), n.appendChild(t), Xn(n, this.opts.theme), this.container = n, this.controlBar = sr({
|
|
3538
3553
|
root: n,
|
|
3539
3554
|
video: t,
|
|
3540
3555
|
player: this,
|
|
@@ -3572,7 +3587,7 @@ var br = class {
|
|
|
3572
3587
|
}
|
|
3573
3588
|
startStats() {
|
|
3574
3589
|
this.stopStats();
|
|
3575
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
3590
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? vr);
|
|
3576
3591
|
this.statsTimer = setInterval(() => {
|
|
3577
3592
|
if (!this.engine) return;
|
|
3578
3593
|
let e = this.engine.getStats();
|
|
@@ -3583,14 +3598,14 @@ var br = class {
|
|
|
3583
3598
|
this.statsTimer && clearInterval(this.statsTimer), this.statsTimer = void 0;
|
|
3584
3599
|
}
|
|
3585
3600
|
isStaleLicenseDenial(e) {
|
|
3586
|
-
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !==
|
|
3601
|
+
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== br || e.error.httpStatus !== 403 || e.error.code !== "FORBIDDEN" || e.error.serverCode === "license_refused" ? !1 : K(this._descriptor?.drm?.widevine?.licenseUrl);
|
|
3587
3602
|
}
|
|
3588
3603
|
scheduleLicenseRefresh() {
|
|
3589
3604
|
if (this.stopRefresh(), !this._descriptor?.drmEnabled) return;
|
|
3590
3605
|
typeof document < "u" && this.engine?.name === "hls" && (this.onRefocus = () => {
|
|
3591
3606
|
document.visibilityState !== "visible" || this.destroyed || K(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
|
|
3592
3607
|
}, document.addEventListener("visibilitychange", this.onRefocus));
|
|
3593
|
-
let e = this.opts.licenseRefreshMs ??
|
|
3608
|
+
let e = this.opts.licenseRefreshMs ?? yr;
|
|
3594
3609
|
e && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
3595
3610
|
}
|
|
3596
3611
|
stopRefresh() {
|
|
@@ -3760,7 +3775,7 @@ function $(e) {
|
|
|
3760
3775
|
}
|
|
3761
3776
|
//#endregion
|
|
3762
3777
|
//#region src/embed/host.ts
|
|
3763
|
-
function
|
|
3778
|
+
function wr(e) {
|
|
3764
3779
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
3765
3780
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
3766
3781
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -3819,15 +3834,15 @@ function xr(e) {
|
|
|
3819
3834
|
}
|
|
3820
3835
|
//#endregion
|
|
3821
3836
|
//#region src/embed/page.ts
|
|
3822
|
-
var
|
|
3823
|
-
function
|
|
3837
|
+
var Tr = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
3838
|
+
function Er(e) {
|
|
3824
3839
|
if (typeof e == "boolean") return e;
|
|
3825
3840
|
if (typeof e == "object" && e) {
|
|
3826
3841
|
let t = e.endpoint;
|
|
3827
3842
|
return typeof t == "string" ? { endpoint: t } : {};
|
|
3828
3843
|
}
|
|
3829
3844
|
}
|
|
3830
|
-
function
|
|
3845
|
+
function Dr() {
|
|
3831
3846
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
3832
3847
|
if (e) return {
|
|
3833
3848
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -3837,7 +3852,7 @@ function wr() {
|
|
|
3837
3852
|
autoplay: e.autoplay ?? !0,
|
|
3838
3853
|
muted: e.muted ?? !0,
|
|
3839
3854
|
waitForLive: e.waitForLive ?? !0,
|
|
3840
|
-
analytics:
|
|
3855
|
+
analytics: Er(e.analytics)
|
|
3841
3856
|
};
|
|
3842
3857
|
let t = new URLSearchParams(location.search);
|
|
3843
3858
|
return {
|
|
@@ -3850,9 +3865,9 @@ function wr() {
|
|
|
3850
3865
|
waitForLive: !0
|
|
3851
3866
|
};
|
|
3852
3867
|
}
|
|
3853
|
-
async function
|
|
3854
|
-
let e =
|
|
3855
|
-
|
|
3868
|
+
async function Or() {
|
|
3869
|
+
let e = Dr();
|
|
3870
|
+
Ar();
|
|
3856
3871
|
let t = document.createElement("video");
|
|
3857
3872
|
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
3873
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -3908,12 +3923,12 @@ async function Tr() {
|
|
|
3908
3923
|
message: e.message,
|
|
3909
3924
|
...e.country === void 0 ? {} : { country: e.country }
|
|
3910
3925
|
})), e.on("autoplayblocked", () => {
|
|
3911
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
3926
|
+
i({ type: "oddin:autoplayblocked" }), kr(t, e);
|
|
3912
3927
|
});
|
|
3913
3928
|
}, s = async (r) => {
|
|
3914
3929
|
a?.destroy(), a = null;
|
|
3915
3930
|
try {
|
|
3916
|
-
let n = await
|
|
3931
|
+
let n = await Sr({
|
|
3917
3932
|
video: t,
|
|
3918
3933
|
baseUrl: e.baseUrl,
|
|
3919
3934
|
matchUrn: r,
|
|
@@ -3976,7 +3991,7 @@ async function Tr() {
|
|
|
3976
3991
|
a?.retry();
|
|
3977
3992
|
break;
|
|
3978
3993
|
case "oddin:load":
|
|
3979
|
-
typeof e.matchUrn == "string" &&
|
|
3994
|
+
typeof e.matchUrn == "string" && Tr.test(e.matchUrn) && s(e.matchUrn);
|
|
3980
3995
|
break;
|
|
3981
3996
|
case "oddin:destroy": c();
|
|
3982
3997
|
}
|
|
@@ -3988,18 +4003,18 @@ async function Tr() {
|
|
|
3988
4003
|
protocol: 1
|
|
3989
4004
|
});
|
|
3990
4005
|
}
|
|
3991
|
-
function
|
|
4006
|
+
function kr(e, t) {
|
|
3992
4007
|
if (document.getElementById("havik-tap")) return;
|
|
3993
4008
|
let n = document.createElement("button");
|
|
3994
4009
|
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
4010
|
n.remove(), t.play();
|
|
3996
4011
|
}), document.body.appendChild(n);
|
|
3997
4012
|
}
|
|
3998
|
-
function
|
|
4013
|
+
function Ar() {
|
|
3999
4014
|
let e = document.createElement("style");
|
|
4000
4015
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
4001
4016
|
}
|
|
4002
4017
|
//#endregion
|
|
4003
|
-
export {
|
|
4018
|
+
export { Jn as ODDIN_THEME, n as PlaybackError, Xn as applyTheme, at as baseUrlForEnv, Or as bootEmbed, Ee as clearDeviceId, Re as clearRememberedBandwidth, Sr 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, wr as mountEmbed, fe as pollToLive, y as resolveStream, E as subscribeLiveState, S as videoFullscreenActive, we as watchStatus };
|
|
4004
4019
|
|
|
4005
4020
|
//# sourceMappingURL=index.js.map
|