@oddin-gg/havik-player 2.26.1 → 2.27.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 +23 -4
- package/dist/index.d.ts +23 -4
- package/dist/index.js +198 -157
- package/dist/index.js.map +1 -1
- package/docs/API.md +11 -1
- package/embed/index.html +1 -1
- package/examples/vanilla.html +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1574,7 +1574,12 @@ function K(e, t) {
|
|
|
1574
1574
|
function Wt() {
|
|
1575
1575
|
return e.isSupported();
|
|
1576
1576
|
}
|
|
1577
|
-
var Gt = 3, Kt = 1e6, qt = 20, Jt = 1e4, Yt = 3, Xt = 5, Zt = 3, Qt = 1e4, $t = 3e4, en = 12e3, tn = 3e3, nn = .02, rn = 6e3, an = .5, on = 3, sn = .5, cn = 1.1, ln = .25, un = 5e3, dn = 4e3, fn = 2, pn = 5, mn = 2, hn = 2, gn = 4, _n = 4, vn = 2e3, yn = 3e4, bn = 1, xn = 2, Sn = .5, Cn = .6, wn = 2, Tn = 1.5, En = 1e4,
|
|
1577
|
+
var Gt = 3, Kt = 1e6, qt = 20, Jt = 1e4, Yt = 3, Xt = 5, Zt = 3, Qt = 1e4, $t = 3e4, en = 12e3, tn = 3e3, nn = .02, rn = 6e3, an = .5, on = 3, sn = .5, cn = 1.1, ln = .25, un = 5e3, dn = 4e3, fn = 2, pn = 5, mn = 2, hn = 2, gn = 4, _n = 4, vn = 2e3, yn = 3e4, bn = 1, xn = 2, Sn = .5, Cn = .6, wn = 2, Tn = 1.5, En = 1e4, Dn = 18e4, On = .5, kn = 2;
|
|
1578
|
+
function An(e) {
|
|
1579
|
+
let t = e.config ?? {};
|
|
1580
|
+
return t.capLevelToPlayerSize === !0 || t.capLevelOnFPSDrop === !0;
|
|
1581
|
+
}
|
|
1582
|
+
var q = 8, jn = 12e4, Mn = 6e4;
|
|
1578
1583
|
function J(e, t, n) {
|
|
1579
1584
|
if (n <= 0 || t < 0 || t >= e.length) return t;
|
|
1580
1585
|
let r = (t, n) => e[t].width === e[n].width && e[t].height === e[n].height, i = (t) => {
|
|
@@ -1587,11 +1592,11 @@ function J(e, t, n) {
|
|
|
1587
1592
|
function Y() {
|
|
1588
1593
|
return typeof self < "u" && self.devicePixelRatio > 0 ? self.devicePixelRatio : 1;
|
|
1589
1594
|
}
|
|
1590
|
-
var
|
|
1591
|
-
function
|
|
1595
|
+
var Nn = .2, Pn = 30, Fn = 2, In = 2, Ln = 2, Rn = 9, zn = .5, Bn = 64, Vn = 1e4, Hn = 8, Un = .6, Wn = .4, Gn = .4, Kn = 2, qn = 6e4, X = .5, Jn = 3.5, Yn = 300;
|
|
1596
|
+
function Xn(e) {
|
|
1592
1597
|
return (e?.part ?? e?.frag)?.stats;
|
|
1593
1598
|
}
|
|
1594
|
-
function
|
|
1599
|
+
function Zn() {
|
|
1595
1600
|
if (typeof navigator > "u") return 0;
|
|
1596
1601
|
try {
|
|
1597
1602
|
let e = navigator.connection?.rtt;
|
|
@@ -1600,20 +1605,20 @@ function qn() {
|
|
|
1600
1605
|
return 0;
|
|
1601
1606
|
}
|
|
1602
1607
|
}
|
|
1603
|
-
function
|
|
1608
|
+
function Qn(e) {
|
|
1604
1609
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
1605
1610
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
1606
1611
|
return;
|
|
1607
1612
|
}
|
|
1608
|
-
e.liveSyncDuration ??=
|
|
1609
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
1610
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
1613
|
+
e.liveSyncDuration ??= Ln;
|
|
1614
|
+
let t = Math.max(12, e.liveSyncDuration + Rn);
|
|
1615
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), $n(e, e.liveSyncDuration);
|
|
1611
1616
|
}
|
|
1612
|
-
function
|
|
1617
|
+
function $n(e, t) {
|
|
1613
1618
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
1614
1619
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
1615
1620
|
}
|
|
1616
|
-
var
|
|
1621
|
+
var er = class {
|
|
1617
1622
|
name = "hls";
|
|
1618
1623
|
hls = null;
|
|
1619
1624
|
deps;
|
|
@@ -1702,6 +1707,11 @@ var Xn = class {
|
|
|
1702
1707
|
pushedCapLevel = -1;
|
|
1703
1708
|
pushedCapReason = null;
|
|
1704
1709
|
fpsCapBitrate = null;
|
|
1710
|
+
stallCapBitrate = null;
|
|
1711
|
+
stallCapSince = 0;
|
|
1712
|
+
stallCapTickAt = 0;
|
|
1713
|
+
stallDownCaps = 0;
|
|
1714
|
+
stallCapEnabled;
|
|
1705
1715
|
fpsCapFailedHeight = null;
|
|
1706
1716
|
fpsCapManaged = !0;
|
|
1707
1717
|
fpsLastFrames = -1;
|
|
@@ -1716,7 +1726,7 @@ var Xn = class {
|
|
|
1716
1726
|
frameCounter;
|
|
1717
1727
|
detachFrames = null;
|
|
1718
1728
|
constructor(e) {
|
|
1719
|
-
this.deps = e, this.holdBackEnabled = e.adaptiveHoldBack !== !1, this.frameCounter = new ht(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
1729
|
+
this.deps = e, this.holdBackEnabled = e.adaptiveHoldBack !== !1, this.stallCapEnabled = e.stallCap !== !1, this.frameCounter = new ht(e.video), this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
1720
1730
|
}
|
|
1721
1731
|
async load() {
|
|
1722
1732
|
this.detachFrames ??= this.frameCounter.attach();
|
|
@@ -1793,7 +1803,7 @@ var Xn = class {
|
|
|
1793
1803
|
let t = e.liveSyncPosition;
|
|
1794
1804
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1795
1805
|
let { video: n } = this.deps;
|
|
1796
|
-
n.currentTime <= t +
|
|
1806
|
+
n.currentTime <= t + zn || (n.currentTime = t);
|
|
1797
1807
|
}
|
|
1798
1808
|
reanchorPartTimeline(e, t) {
|
|
1799
1809
|
let { frag: n, part: r } = t;
|
|
@@ -1869,7 +1879,7 @@ var Xn = class {
|
|
|
1869
1879
|
}), t = zt(e, f.loader);
|
|
1870
1880
|
t && (this.prefetch = e, p = h, m = g, f.fLoader = t);
|
|
1871
1881
|
}
|
|
1872
|
-
|
|
1882
|
+
Qn(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;
|
|
1873
1883
|
let _ = new e(f);
|
|
1874
1884
|
if (this.hls = _, this.armHoldBack(_, f), _.on(e.Events.FRAG_PARSED, (e, t) => this.reanchorPartTimeline(_, t)), _.on(e.Events.MANIFEST_PARSED, () => {
|
|
1875
1885
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, u && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && this.dropLevelsWidevineCannotPlay(_), this.measureLadder(_), this.applySizeCap(), this.loadSuspended = !1, t.paused && this.schedulePauseSuspend(), l({ type: "ready" });
|
|
@@ -1881,10 +1891,10 @@ var Xn = class {
|
|
|
1881
1891
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1882
1892
|
}), _.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
1883
1893
|
t?.frag?.type === "main" && (this.mainFragsSinceTick += 1, this.bwFragsLoaded += 1, this.maybeRememberBandwidth(!1));
|
|
1884
|
-
let n = t?.frag, r =
|
|
1894
|
+
let n = t?.frag, r = Xn(t), i = r?.loaded;
|
|
1885
1895
|
typeof i == "number" && (this.bytesLoaded += i), !this.reportedFirstBytes && typeof i == "number" && i > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
|
|
1886
1896
|
let a = r?.loading;
|
|
1887
|
-
a && a.end > 0 && a.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(a.end - a.start))), this.requestTimesMs.length >
|
|
1897
|
+
a && a.end > 0 && a.start > 0 && (this.requestCount += 1, this.requestTimesMs.push(Math.max(0, Math.round(a.end - a.start))), this.requestTimesMs.length > Bn && this.requestTimesMs.shift()), this.sampleHoldBack(t), this.sampleHeadroom(t);
|
|
1888
1898
|
let o = n?.url;
|
|
1889
1899
|
if (o) {
|
|
1890
1900
|
let e = ft(o);
|
|
@@ -1924,7 +1934,7 @@ var Xn = class {
|
|
|
1924
1934
|
_.on(e.Events.KEY_LOADED, () => {
|
|
1925
1935
|
u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
|
|
1926
1936
|
}), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1927
|
-
this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.adaptHoldBack(), this.reviewSizeCapHeadroom(), this.checkFrameDrops();
|
|
1937
|
+
this.checkEndStale(), this.checkStarvation(), this.updateCatchUpBand(), this.checkFutileChase(), this.adaptHoldBack(), this.reviewSizeCapHeadroom(), this.releaseStallCap(), this.checkFrameDrops();
|
|
1928
1938
|
}, tn), _.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1929
1939
|
this.renditionSwitches += 1;
|
|
1930
1940
|
let n = this.lastLevelIndex >= 0 ? _.levels[this.lastLevelIndex] : void 0, r = _.levels[t.level];
|
|
@@ -2044,7 +2054,7 @@ var Xn = class {
|
|
|
2044
2054
|
if (!this.sizeCapManaged || !this.defaultHeadroomApplies() || e.frag?.type !== "main" || typeof e.frag.level != "number" || typeof document < "u" && document.hidden) return;
|
|
2045
2055
|
let t = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag.duration;
|
|
2046
2056
|
if (typeof t != "number" || !(t > 0)) return;
|
|
2047
|
-
let n =
|
|
2057
|
+
let n = Xn(e)?.loading;
|
|
2048
2058
|
if (!n || !(n.start > 0) || !(n.end >= n.start)) return;
|
|
2049
2059
|
let r = this.hls?.levels?.[e.frag.level]?.bitrate;
|
|
2050
2060
|
if (!(typeof r == "number" && r > 0)) return;
|
|
@@ -2055,9 +2065,42 @@ var Xn = class {
|
|
|
2055
2065
|
bitrate: r
|
|
2056
2066
|
}), this.headroomSamples.length > 256 && this.headroomSamples.shift();
|
|
2057
2067
|
}
|
|
2058
|
-
onPlaybackStall() {
|
|
2059
|
-
let
|
|
2060
|
-
this.deps.video.seeking || !this.playingSince ||
|
|
2068
|
+
onPlaybackStall(e) {
|
|
2069
|
+
let t = Date.now();
|
|
2070
|
+
this.deps.video.seeking || !this.playingSince || t - this.playingSince < En || (this.lastStallAt = t, this.stepStallCapDown(t, e), this.headroomGranted && (this.headroomGranted = !1, this.applySizeCapUnlessPending()));
|
|
2071
|
+
}
|
|
2072
|
+
stallCapLevel(e) {
|
|
2073
|
+
if (this.stallCapBitrate == null) return -1;
|
|
2074
|
+
let t = -1;
|
|
2075
|
+
return e.levels.forEach((e, n) => {
|
|
2076
|
+
e.bitrate <= this.stallCapBitrate && (t = n);
|
|
2077
|
+
}), t < 0 ? 0 : t;
|
|
2078
|
+
}
|
|
2079
|
+
stepStallCapDown(e, t) {
|
|
2080
|
+
let n = this.hls;
|
|
2081
|
+
if (!n || !this.stallCapEnabled || An(n) || !n.autoLevelEnabled || typeof t == "number" && t >= On || this.isLiveEdgeWait(n, t ?? 0)) return;
|
|
2082
|
+
this.stallCapBitrate != null && (this.stallCapSince = e);
|
|
2083
|
+
let r = Math.max(n.levels[n.currentLevel]?.bitrate ?? 0, n.levels[n.loadLevel]?.bitrate ?? 0);
|
|
2084
|
+
if (!(r > 0)) return;
|
|
2085
|
+
let i = n.levels.map((e) => e.bitrate).filter((e) => e > 0 && e < r).sort((e, t) => t - e)[0];
|
|
2086
|
+
i != null && (this.stallCapBitrate != null && i >= this.stallCapBitrate || (this.stallCapBitrate = i, this.stallCapSince = e, this.stallDownCaps += 1, this.pushCap()));
|
|
2087
|
+
}
|
|
2088
|
+
isLiveEdgeWait(e, t) {
|
|
2089
|
+
let n = e.latestLevelDetails;
|
|
2090
|
+
if (!n?.live) return !1;
|
|
2091
|
+
let r = n.partTarget || n.targetduration;
|
|
2092
|
+
return !(r > 0) || !(n.edge > 0) ? !1 : n.edge - (this.deps.video.currentTime + t) < kn * r;
|
|
2093
|
+
}
|
|
2094
|
+
releaseStallCap() {
|
|
2095
|
+
let e = this.hls, t = Date.now(), n = this.stallCapTickAt;
|
|
2096
|
+
if (this.stallCapTickAt = t, !e || this.stallCapBitrate == null) return;
|
|
2097
|
+
if (this.deps.video.paused || this.loadSuspended || this.offlineHold) {
|
|
2098
|
+
n && (this.stallCapSince += t - Math.max(n, this.stallCapSince));
|
|
2099
|
+
return;
|
|
2100
|
+
}
|
|
2101
|
+
if (t - this.stallCapSince < Dn) return;
|
|
2102
|
+
let r = this.stallCapBitrate, i = e.levels.map((e) => e.bitrate).filter((e) => e > r).sort((e, t) => e - t)[0];
|
|
2103
|
+
this.stallCapBitrate = i ?? null, this.stallCapSince = t, this.pushCap();
|
|
2061
2104
|
}
|
|
2062
2105
|
reviewSizeCapHeadroom() {
|
|
2063
2106
|
let e = Date.now(), { video: t } = this.deps;
|
|
@@ -2068,12 +2111,12 @@ var Xn = class {
|
|
|
2068
2111
|
this.headroomGranted = !1, this.headroomSamples = [];
|
|
2069
2112
|
return;
|
|
2070
2113
|
}
|
|
2071
|
-
this.headroomSamples = this.headroomSamples.filter((t) => t.t >= e -
|
|
2114
|
+
this.headroomSamples = this.headroomSamples.filter((t) => t.t >= e - Vn);
|
|
2072
2115
|
let r = this.headroomEarned(n, e);
|
|
2073
|
-
r !== this.headroomGranted && (r || (this.headroomRegrantAt = e +
|
|
2116
|
+
r !== this.headroomGranted && (r || (this.headroomRegrantAt = e + Mn), this.headroomGranted = r, this.applySizeCapUnlessPending());
|
|
2074
2117
|
}
|
|
2075
2118
|
headroomEarned(e, t) {
|
|
2076
|
-
if (t - this.lastStallAt <
|
|
2119
|
+
if (t - this.lastStallAt < jn || !this.headroomGranted && t < this.headroomRegrantAt || !this.headroomGranted && this.headroomSamples.length < q) return !1;
|
|
2077
2120
|
let n = e.levels, r = this.sizeCapCoverLevel();
|
|
2078
2121
|
if (r == null) return this.headroomGranted;
|
|
2079
2122
|
let i = J(n, r, bn);
|
|
@@ -2101,7 +2144,8 @@ var Xn = class {
|
|
|
2101
2144
|
let t = [
|
|
2102
2145
|
["size", this.sizeCapLevel ?? -1],
|
|
2103
2146
|
["bitrate", this.bitrateCapLevel],
|
|
2104
|
-
["fps", this.fpsCapLevel(e)]
|
|
2147
|
+
["fps", this.fpsCapLevel(e)],
|
|
2148
|
+
["stall", this.stallCapLevel(e)]
|
|
2105
2149
|
], n = -1, r = null;
|
|
2106
2150
|
for (let [e, i] of t) i >= 0 && (n < 0 || i < n) && (n = i, r = e);
|
|
2107
2151
|
e.autoLevelCapping = n, this.pushedCapLevel = n, this.pushedCapReason = r;
|
|
@@ -2146,6 +2190,7 @@ var Xn = class {
|
|
|
2146
2190
|
liveRetargets: this.liveRetargets,
|
|
2147
2191
|
holdBackSteps: this.holdBackSteps,
|
|
2148
2192
|
fpsDownCaps: this.fpsDownCaps,
|
|
2193
|
+
stallDownCaps: this.stallDownCaps,
|
|
2149
2194
|
licenseTimeMs: this.licenseTimeMs,
|
|
2150
2195
|
upshifts: this.upshifts,
|
|
2151
2196
|
downshifts: this.downshifts,
|
|
@@ -2160,12 +2205,7 @@ var Xn = class {
|
|
|
2160
2205
|
let t = e.currentLevel >= 0 ? e.levels[e.currentLevel] : void 0;
|
|
2161
2206
|
t && (n.levelHeight = t.height);
|
|
2162
2207
|
let r = e.autoLevelCapping, i = r >= 0 ? e.levels[r] : void 0;
|
|
2163
|
-
|
|
2164
|
-
n.maxLevelHeight = i.height;
|
|
2165
|
-
let t = e.config ?? {};
|
|
2166
|
-
t.capLevelToPlayerSize !== !0 && t.capLevelOnFPSDrop !== !0 && r === this.pushedCapLevel && this.pushedCapReason && (n.capReason = this.pushedCapReason);
|
|
2167
|
-
}
|
|
2168
|
-
t?.videoCodec && (n.videoCodec = t.videoCodec), t?.audioCodec && (n.audioCodec = t.audioCodec), t && typeof t.bitrate == "number" && (n.renditionBitrateKbps = Math.round(t.bitrate / 1e3)), typeof t?.details?.live == "boolean" && (n.isLive = t.details.live, typeof e.liveSyncPosition == "number" && (n.atLiveEdge = this.deps.video.currentTime >= e.liveSyncPosition - 1.5));
|
|
2208
|
+
i && i.height > 0 && (n.maxLevelHeight = i.height, !An(e) && r === this.pushedCapLevel && this.pushedCapReason && (n.capReason = this.pushedCapReason)), t?.videoCodec && (n.videoCodec = t.videoCodec), t?.audioCodec && (n.audioCodec = t.audioCodec), t && typeof t.bitrate == "number" && (n.renditionBitrateKbps = Math.round(t.bitrate / 1e3)), typeof t?.details?.live == "boolean" && (n.isLive = t.details.live, typeof e.liveSyncPosition == "number" && (n.atLiveEdge = this.deps.video.currentTime >= e.liveSyncPosition - 1.5));
|
|
2169
2209
|
}
|
|
2170
2210
|
return n;
|
|
2171
2211
|
}
|
|
@@ -2250,7 +2290,7 @@ var Xn = class {
|
|
|
2250
2290
|
}), n < 0 ? 0 : n;
|
|
2251
2291
|
}
|
|
2252
2292
|
armFrameDropGrace() {
|
|
2253
|
-
this.fpsGraceTicks > 0 || (this.fpsGraceTicks =
|
|
2293
|
+
this.fpsGraceTicks > 0 || (this.fpsGraceTicks = In, this.fpsBadTicks = 0);
|
|
2254
2294
|
}
|
|
2255
2295
|
resetFrameDropWindow() {
|
|
2256
2296
|
this.fpsLastFrames = -1, this.fpsLastDropped = -1, this.fpsBadTicks = 0;
|
|
@@ -2262,7 +2302,7 @@ var Xn = class {
|
|
|
2262
2302
|
return;
|
|
2263
2303
|
}
|
|
2264
2304
|
let { totalFrames: n, dropped: r } = R(t), i = this.fpsLastFrames < 0, a = n - this.fpsLastFrames, o = r - this.fpsLastDropped;
|
|
2265
|
-
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a <
|
|
2305
|
+
if (this.fpsLastFrames = n, this.fpsLastDropped = r, i || a < Pn || o < 0) {
|
|
2266
2306
|
this.fpsBadTicks = 0;
|
|
2267
2307
|
return;
|
|
2268
2308
|
}
|
|
@@ -2270,11 +2310,11 @@ var Xn = class {
|
|
|
2270
2310
|
--this.fpsGraceTicks, this.fpsBadTicks = 0;
|
|
2271
2311
|
return;
|
|
2272
2312
|
}
|
|
2273
|
-
if (o <=
|
|
2313
|
+
if (o <= Nn * a) {
|
|
2274
2314
|
this.fpsBadTicks = 0;
|
|
2275
2315
|
return;
|
|
2276
2316
|
}
|
|
2277
|
-
if (this.fpsBadTicks += 1, this.fpsBadTicks <
|
|
2317
|
+
if (this.fpsBadTicks += 1, this.fpsBadTicks < Fn) return;
|
|
2278
2318
|
this.fpsBadTicks = 0;
|
|
2279
2319
|
let s = e.levels, c = s[e.currentLevel];
|
|
2280
2320
|
if (!c) return;
|
|
@@ -2323,13 +2363,13 @@ var Xn = class {
|
|
|
2323
2363
|
if (!this.holdBackEnabled || this.holdBackPriorChecked || !e || (this.holdBackPriorChecked = !0, this.holdBackApplied > 0 || this.holdBackStepCount > 0)) return;
|
|
2324
2364
|
let t = e.targetLatency;
|
|
2325
2365
|
if (this.holdBackBase < 0 && typeof t == "number" && t > 0 && (this.holdBackBase = t), this.holdBackBase < 0) return;
|
|
2326
|
-
let n =
|
|
2327
|
-
if (!(n >=
|
|
2366
|
+
let n = Zn();
|
|
2367
|
+
if (!(n >= Yn)) return;
|
|
2328
2368
|
let r = typeof t == "number" && t > 0 ? t : this.holdBackBase, i = Math.min(this.holdBackCeiling(e), this.holdBackBase + X);
|
|
2329
2369
|
i > r && (this.holdBackStepCount = 1, this.moveHoldBack(e, r, i, "connection-rtt", `connection rtt ${n} ms`));
|
|
2330
2370
|
}
|
|
2331
2371
|
holdBackCeiling(e) {
|
|
2332
|
-
let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t :
|
|
2372
|
+
let t = this.deps.adaptiveHoldBackCeiling, n = typeof t == "number" && Number.isFinite(t) ? t : Jn, r = typeof e.config.liveMaxLatencyDuration == "number" ? e.config.liveMaxLatencyDuration : e.maxLatency;
|
|
2333
2373
|
return r > 1 ? Math.min(n, r - 1) : n;
|
|
2334
2374
|
}
|
|
2335
2375
|
sampleHoldBack(e) {
|
|
@@ -2338,7 +2378,7 @@ var Xn = class {
|
|
|
2338
2378
|
if (t !== "main" && t !== "audio") return;
|
|
2339
2379
|
let n = e.part ? e.part.duration : this.detectedLowLatency ? 0 : e.frag?.duration;
|
|
2340
2380
|
if (typeof n != "number" || !(n > 0)) return;
|
|
2341
|
-
let r =
|
|
2381
|
+
let r = Xn(e)?.loading;
|
|
2342
2382
|
if (!r || !(r.start > 0) || !(r.end > 0)) return;
|
|
2343
2383
|
let i = r.first > r.start ? r.first : r.end, a = Math.max(0, i - r.start) / (n * 1e3);
|
|
2344
2384
|
this.holdBackSamples.push({
|
|
@@ -2353,20 +2393,20 @@ var Xn = class {
|
|
|
2353
2393
|
this.holdBackSlowTicks = 0, this.holdBackFastSince = 0, this.holdBackSamples = [];
|
|
2354
2394
|
return;
|
|
2355
2395
|
}
|
|
2356
|
-
let t = Date.now(), n = t -
|
|
2396
|
+
let t = Date.now(), n = t - Vn, r = this.holdBackSamples, i = 0;
|
|
2357
2397
|
for (; i < r.length && r[i].t < n;) i += 1;
|
|
2358
2398
|
i > 0 && r.splice(0, i);
|
|
2359
2399
|
let a = e.targetLatency;
|
|
2360
2400
|
if (typeof a != "number" || !(a > 0)) return;
|
|
2361
2401
|
this.holdBackBase < 0 && (this.holdBackBase = a);
|
|
2362
2402
|
let o = this.holdBackBase, s = this.holdBackCeiling(e);
|
|
2363
|
-
if (r.length <
|
|
2403
|
+
if (r.length < Hn) {
|
|
2364
2404
|
this.holdBackSlowTicks = 0;
|
|
2365
2405
|
return;
|
|
2366
2406
|
}
|
|
2367
2407
|
let c = r.map((e) => e.ratio).sort((e, t) => e - t), l = K(c, 95), u = K(c, 50), d = Math.round(l * 1e3);
|
|
2368
|
-
if (l >=
|
|
2369
|
-
if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks <
|
|
2408
|
+
if (l >= Un && u >= Wn) {
|
|
2409
|
+
if (this.holdBackFastSince = 0, this.holdBackSlowTicks += 1, this.holdBackSlowTicks < Kn) return;
|
|
2370
2410
|
this.holdBackSlowTicks = 0;
|
|
2371
2411
|
let t = Math.ceil((s - o) / X), n = Math.ceil((a - o) / X - 1e-9);
|
|
2372
2412
|
if (n > this.holdBackStepCount && (this.holdBackStepCount = n), this.holdBackStepCount >= t) return;
|
|
@@ -2376,7 +2416,7 @@ var Xn = class {
|
|
|
2376
2416
|
this.moveHoldBack(e, a, r, "slow-fetches", `part fetches slow (first byte p50 ${Math.round(u * 1e3)} / p95 ${d} ms per 1 s of media)`);
|
|
2377
2417
|
return;
|
|
2378
2418
|
}
|
|
2379
|
-
if (this.holdBackSlowTicks = 0, l >=
|
|
2419
|
+
if (this.holdBackSlowTicks = 0, l >= Gn) {
|
|
2380
2420
|
this.holdBackFastSince = 0;
|
|
2381
2421
|
return;
|
|
2382
2422
|
}
|
|
@@ -2384,7 +2424,7 @@ var Xn = class {
|
|
|
2384
2424
|
this.holdBackFastSince = t;
|
|
2385
2425
|
return;
|
|
2386
2426
|
}
|
|
2387
|
-
if (t - this.holdBackFastSince <
|
|
2427
|
+
if (t - this.holdBackFastSince < qn || (this.holdBackFastSince = t, this.holdBackStepCount === 0 || a !== this.holdBackApplied)) return;
|
|
2388
2428
|
--this.holdBackStepCount;
|
|
2389
2429
|
let f = Math.max(o, o + this.holdBackStepCount * X);
|
|
2390
2430
|
f >= a || this.moveHoldBack(e, a, f, "fast-fetches", `part fetches fast again (p95 first byte ${d} ms per 1 s of media)`);
|
|
@@ -2470,7 +2510,7 @@ var Xn = class {
|
|
|
2470
2510
|
}
|
|
2471
2511
|
}
|
|
2472
2512
|
onError(t) {
|
|
2473
|
-
if (t.details === e.ErrorDetails.BUFFER_STALLED_ERROR && this.onPlaybackStall(), t.type === e.ErrorTypes.NETWORK_ERROR && String(t.details ?? "").startsWith("frag") && (this.requestErrors += 1), !t.fatal) return;
|
|
2513
|
+
if (t.details === e.ErrorDetails.BUFFER_STALLED_ERROR && this.onPlaybackStall(t.buffer), t.type === e.ErrorTypes.NETWORK_ERROR && String(t.details ?? "").startsWith("frag") && (this.requestErrors += 1), !t.fatal) return;
|
|
2474
2514
|
let n = this.hls;
|
|
2475
2515
|
if (n) {
|
|
2476
2516
|
if (this.clearRecoveryReset(), t.type === e.ErrorTypes.KEY_SYSTEM_ERROR) {
|
|
@@ -2529,15 +2569,15 @@ var Xn = class {
|
|
|
2529
2569
|
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(Mt(t.networkDetails)) : void 0;
|
|
2530
2570
|
return new n(r === "DRM" ? a(o, l) : r === "NETWORK" && o === 0 ? "NETWORK" : o === 401 ? "UNAUTHORIZED" : o === 403 ? "FORBIDDEN" : "INTERNAL", o, `${r} error: ${s}${c ? ` (${c})` : ""}`, l ? { serverCode: l } : void 0);
|
|
2531
2571
|
}
|
|
2532
|
-
},
|
|
2572
|
+
}, tr = 15e3, nr = 6e5, rr = 3e5, ir = 100, Z = 1, ar = 1e3, or = 3e4, sr = 1e3, cr = {
|
|
2533
2573
|
inline: "PRESENTATION_INLINE",
|
|
2534
2574
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
2535
2575
|
pip: "PRESENTATION_PIP"
|
|
2536
|
-
},
|
|
2576
|
+
}, lr = {
|
|
2537
2577
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
2538
2578
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
2539
2579
|
none: "KEY_SYSTEM_NONE"
|
|
2540
|
-
},
|
|
2580
|
+
}, ur = /* @__PURE__ */ new Set([
|
|
2541
2581
|
"INVALID_URN",
|
|
2542
2582
|
"NOT_FOUND",
|
|
2543
2583
|
"GEO_DENIED",
|
|
@@ -2548,7 +2588,7 @@ var Xn = class {
|
|
|
2548
2588
|
"FORBIDDEN",
|
|
2549
2589
|
"RATE_LIMITED",
|
|
2550
2590
|
"TIMEOUT"
|
|
2551
|
-
]),
|
|
2591
|
+
]), dr = {
|
|
2552
2592
|
idle: "PLAYER_STATE_IDLE",
|
|
2553
2593
|
waiting: "PLAYER_STATE_WAITING",
|
|
2554
2594
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -2558,7 +2598,7 @@ var Xn = class {
|
|
|
2558
2598
|
ended: "PLAYER_STATE_ENDED",
|
|
2559
2599
|
error: "PLAYER_STATE_ERROR"
|
|
2560
2600
|
};
|
|
2561
|
-
function
|
|
2601
|
+
function fr(e) {
|
|
2562
2602
|
try {
|
|
2563
2603
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
2564
2604
|
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);
|
|
@@ -2566,8 +2606,8 @@ function cr(e) {
|
|
|
2566
2606
|
return;
|
|
2567
2607
|
}
|
|
2568
2608
|
}
|
|
2569
|
-
var
|
|
2570
|
-
function
|
|
2609
|
+
var pr = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase(), mr = /* @__PURE__ */ new Set(), hr = /* @__PURE__ */ new Set(), gr = /* @__PURE__ */ new Set(), _r = (e) => `this page's Content-Security-Policy blocks QoE beacons. Add ${e} to connect-src; until then none are sent.`;
|
|
2610
|
+
function vr(e) {
|
|
2571
2611
|
if (e.disposition !== "enforce" || e.effectiveDirective !== "connect-src") return;
|
|
2572
2612
|
let t;
|
|
2573
2613
|
try {
|
|
@@ -2576,19 +2616,19 @@ function mr(e) {
|
|
|
2576
2616
|
} catch {
|
|
2577
2617
|
return;
|
|
2578
2618
|
}
|
|
2579
|
-
if (
|
|
2580
|
-
|
|
2581
|
-
for (let e of
|
|
2619
|
+
if (mr.has(t) && !hr.has(t)) {
|
|
2620
|
+
hr.add(t), _(_r(new URL(t).origin));
|
|
2621
|
+
for (let e of gr) e.noteCspBlocked();
|
|
2582
2622
|
}
|
|
2583
2623
|
}
|
|
2584
|
-
function
|
|
2624
|
+
function yr(e, t) {
|
|
2585
2625
|
return _(t, e), { disabledReason: t };
|
|
2586
2626
|
}
|
|
2587
|
-
function
|
|
2588
|
-
if (n) return t && !
|
|
2627
|
+
function br(e, t, n) {
|
|
2628
|
+
if (n) return t && !pr(t, n) && _(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
|
|
2589
2629
|
if (t) return { endpoint: t };
|
|
2590
|
-
if (t !== void 0) return
|
|
2591
|
-
let r =
|
|
2630
|
+
if (t !== void 0) return yr("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).");
|
|
2631
|
+
let r = fr(e);
|
|
2592
2632
|
if (r) return { endpoint: r };
|
|
2593
2633
|
let i;
|
|
2594
2634
|
try {
|
|
@@ -2596,9 +2636,9 @@ function gr(e, t, n) {
|
|
|
2596
2636
|
} catch {
|
|
2597
2637
|
i = e;
|
|
2598
2638
|
}
|
|
2599
|
-
return
|
|
2639
|
+
return yr(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).`);
|
|
2600
2640
|
}
|
|
2601
|
-
var
|
|
2641
|
+
var xr = class {
|
|
2602
2642
|
opts;
|
|
2603
2643
|
url;
|
|
2604
2644
|
cspKey;
|
|
@@ -2680,8 +2720,8 @@ var _r = class {
|
|
|
2680
2720
|
constructor(e) {
|
|
2681
2721
|
this.opts = {
|
|
2682
2722
|
...e,
|
|
2683
|
-
heartbeatMs: e.heartbeatMs ??
|
|
2684
|
-
idleMs: e.idleMs ??
|
|
2723
|
+
heartbeatMs: e.heartbeatMs ?? tr,
|
|
2724
|
+
idleMs: e.idleMs ?? nr
|
|
2685
2725
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`;
|
|
2686
2726
|
try {
|
|
2687
2727
|
let e = new URL(this.url);
|
|
@@ -2698,11 +2738,11 @@ var _r = class {
|
|
|
2698
2738
|
sdkVersion: this.opts.sdkVersion,
|
|
2699
2739
|
...this.opts.environment
|
|
2700
2740
|
};
|
|
2701
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
2741
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), ar), 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 && mr.add(this.cspKey), document.addEventListener("securitypolicyviolation", vr), gr.add(this), this.noteCspBlocked(), this.onVisibility());
|
|
2702
2742
|
}
|
|
2703
2743
|
checkSuspension(e) {
|
|
2704
2744
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
2705
|
-
let t = Math.max(this.opts.idleMs,
|
|
2745
|
+
let t = Math.max(this.opts.idleMs, rr);
|
|
2706
2746
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
2707
2747
|
}
|
|
2708
2748
|
syncIdle(e) {
|
|
@@ -2723,14 +2763,14 @@ var _r = class {
|
|
|
2723
2763
|
} else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
|
|
2724
2764
|
this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
|
|
2725
2765
|
let a = {
|
|
2726
|
-
fromState:
|
|
2727
|
-
toState:
|
|
2728
|
-
presentation:
|
|
2766
|
+
fromState: dr[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2767
|
+
toState: dr[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
2768
|
+
presentation: cr[this.presentation]
|
|
2729
2769
|
}, o = this.causeOf(e, t, i);
|
|
2730
2770
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
2731
2771
|
}
|
|
2732
2772
|
seekInduced(e) {
|
|
2733
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
2773
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < sr;
|
|
2734
2774
|
}
|
|
2735
2775
|
causeOf(e, t, n) {
|
|
2736
2776
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -2804,7 +2844,7 @@ var _r = class {
|
|
|
2804
2844
|
let r = n ?? "";
|
|
2805
2845
|
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";
|
|
2806
2846
|
if (e === "DRM_CLIENT" || e === "DRM_DEVICE_REVOKED") return "ERROR_STAGE_DRM";
|
|
2807
|
-
if (
|
|
2847
|
+
if (ur.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
2808
2848
|
let i = t ?? "";
|
|
2809
2849
|
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";
|
|
2810
2850
|
}
|
|
@@ -2836,7 +2876,7 @@ var _r = class {
|
|
|
2836
2876
|
let l = t.droppedFrames ?? 0;
|
|
2837
2877
|
l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
|
|
2838
2878
|
let u = t.renditionSwitches ?? 0;
|
|
2839
|
-
u > this.lastSwitches && (o.renditionSwitchesDelta = u - this.lastSwitches), this.lastSwitches = u, n > this.lastHbPlayingMs && (o.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (o.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, i > this.lastHbRebufferMs && (o.rebufferMsDelta = Math.round(i - this.lastHbRebufferMs)), this.lastHbRebufferMs = i, this.rebufferCount > this.lastHbRebufferCount && (o.rebufferCountDelta = this.rebufferCount - this.lastHbRebufferCount), this.lastHbRebufferCount = this.rebufferCount, a > this.lastHbActiveMs && (o.activeMsDelta = Math.round(a - this.lastHbActiveMs)), this.lastHbActiveMs = a, typeof t.latencySeconds == "number" && (o.latencyMs = Math.round(t.latencySeconds * 1e3)), typeof t.targetLatencySeconds == "number" && (o.targetLatencyMs = Math.round(t.targetLatencySeconds * 1e3)), typeof t.bandwidthKbps == "number" && (o.bandwidthEstKbps = t.bandwidthKbps), typeof t.levelHeight == "number" && (o.renditionHeight = t.levelHeight), typeof t.renditionBitrateKbps == "number" && (o.renditionBitrateKbps = t.renditionBitrateKbps), t.atLiveEdge === !0 && (o.atLiveEdge = !0), typeof t.bufferedMs == "number" && t.bufferedMs > 0 && (o.bufferedMs = Math.round(t.bufferedMs)), o.playerState =
|
|
2879
|
+
u > this.lastSwitches && (o.renditionSwitchesDelta = u - this.lastSwitches), this.lastSwitches = u, n > this.lastHbPlayingMs && (o.playingMsDelta = Math.round(n - this.lastHbPlayingMs)), this.lastHbPlayingMs = n, r > this.lastHbHiddenMs && (o.hiddenMsDelta = Math.round(r - this.lastHbHiddenMs)), this.lastHbHiddenMs = r, i > this.lastHbRebufferMs && (o.rebufferMsDelta = Math.round(i - this.lastHbRebufferMs)), this.lastHbRebufferMs = i, this.rebufferCount > this.lastHbRebufferCount && (o.rebufferCountDelta = this.rebufferCount - this.lastHbRebufferCount), this.lastHbRebufferCount = this.rebufferCount, a > this.lastHbActiveMs && (o.activeMsDelta = Math.round(a - this.lastHbActiveMs)), this.lastHbActiveMs = a, typeof t.latencySeconds == "number" && (o.latencyMs = Math.round(t.latencySeconds * 1e3)), typeof t.targetLatencySeconds == "number" && (o.targetLatencyMs = Math.round(t.targetLatencySeconds * 1e3)), typeof t.bandwidthKbps == "number" && (o.bandwidthEstKbps = t.bandwidthKbps), typeof t.levelHeight == "number" && (o.renditionHeight = t.levelHeight), typeof t.renditionBitrateKbps == "number" && (o.renditionBitrateKbps = t.renditionBitrateKbps), t.atLiveEdge === !0 && (o.atLiveEdge = !0), typeof t.bufferedMs == "number" && t.bufferedMs > 0 && (o.bufferedMs = Math.round(t.bufferedMs)), o.playerState = dr[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
|
|
2840
2880
|
let d = this.mutedTotalMs;
|
|
2841
2881
|
this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
|
|
2842
2882
|
let f = t.upshifts ?? 0;
|
|
@@ -2858,13 +2898,13 @@ var _r = class {
|
|
|
2858
2898
|
maybeEmitMediaInfo(e) {
|
|
2859
2899
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
2860
2900
|
let t = {};
|
|
2861
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
2901
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = lr[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);
|
|
2862
2902
|
let n = JSON.stringify(t);
|
|
2863
2903
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
2864
2904
|
}
|
|
2865
2905
|
end(e, t) {
|
|
2866
2906
|
if (this.endedFlag) return;
|
|
2867
|
-
this.endedFlag = !0,
|
|
2907
|
+
this.endedFlag = !0, gr.delete(this);
|
|
2868
2908
|
let n = t ?? this.now();
|
|
2869
2909
|
this.playingSinceMs !== null && (this.playingTotalMs += n - this.playingSinceMs, this.playingSinceMs = null), this.hiddenSinceMs !== null && (this.hiddenTotalMs += n - this.hiddenSinceMs, this.hiddenSinceMs = null), this.bufferingSinceMs !== null && (this.rebufferTotalMs += n - this.bufferingSinceMs, this.bufferingSinceMs = null), this.mutedSinceMs !== null && (this.mutedTotalMs += n - this.mutedSinceMs, this.mutedSinceMs = null), this.waitingSinceMs !== null && (this.waitingTotalMs += n - this.waitingSinceMs, this.waitingSinceMs = null), this.isPlaying = !1, this.syncActive(n), this.closePresentation(n), this.firstFlushTimer &&= (clearTimeout(this.firstFlushTimer), null), this.timer &&= (clearInterval(this.timer), null), this.idleTimer &&= (clearTimeout(this.idleTimer), null), typeof window < "u" && window.removeEventListener("pagehide", this.onPagehide), typeof document < "u" && (document.removeEventListener("visibilitychange", this.onVisibility), document.removeEventListener("freeze", this.onFreeze), document.removeEventListener("resume", this.onResume));
|
|
2870
2910
|
let r = this.safeSample();
|
|
@@ -2878,7 +2918,7 @@ var _r = class {
|
|
|
2878
2918
|
let c = r?.positionMs ?? 0;
|
|
2879
2919
|
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));
|
|
2880
2920
|
let l = e !== "END_REASON_ENDED";
|
|
2881
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
2921
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= or && (i.abandonAfterStallMs = Math.max(Z, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= or && (i.abandonAfterErrorMs = Math.max(Z, 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);
|
|
2882
2922
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
2883
2923
|
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");
|
|
2884
2924
|
}
|
|
@@ -2898,13 +2938,13 @@ var _r = class {
|
|
|
2898
2938
|
};
|
|
2899
2939
|
}
|
|
2900
2940
|
noteCspBlocked() {
|
|
2901
|
-
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(
|
|
2941
|
+
this.cspBlockedNoted || this.endedFlag || !this.cspBlocked() || (this.cspBlockedNoted = !0, this.opts.onBlocked?.(_r(new URL(this.url).origin)));
|
|
2902
2942
|
}
|
|
2903
2943
|
cspBlocked() {
|
|
2904
|
-
return !!this.cspKey &&
|
|
2944
|
+
return !!this.cspKey && hr.has(this.cspKey);
|
|
2905
2945
|
}
|
|
2906
2946
|
enqueue(e) {
|
|
2907
|
-
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
2947
|
+
if (!this.cspBlocked()) for (this.pending.push(this.wrap(e)); this.pending.length > ir;) {
|
|
2908
2948
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
2909
2949
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
2910
2950
|
}
|
|
@@ -2931,7 +2971,7 @@ var _r = class {
|
|
|
2931
2971
|
};
|
|
2932
2972
|
//#endregion
|
|
2933
2973
|
//#region src/core/environment.ts
|
|
2934
|
-
function
|
|
2974
|
+
function Sr() {
|
|
2935
2975
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
2936
2976
|
let e;
|
|
2937
2977
|
try {
|
|
@@ -2956,14 +2996,14 @@ function vr() {
|
|
|
2956
2996
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
2957
2997
|
};
|
|
2958
2998
|
}
|
|
2959
|
-
function
|
|
2999
|
+
function Cr() {
|
|
2960
3000
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
2961
3001
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
2962
3002
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
2963
3003
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
2964
3004
|
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";
|
|
2965
3005
|
}
|
|
2966
|
-
function
|
|
3006
|
+
function wr() {
|
|
2967
3007
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
2968
3008
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
2969
3009
|
let t = {
|
|
@@ -2982,17 +3022,17 @@ function br() {
|
|
|
2982
3022
|
}
|
|
2983
3023
|
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;
|
|
2984
3024
|
}
|
|
2985
|
-
function
|
|
2986
|
-
let t =
|
|
2987
|
-
deviceClass:
|
|
3025
|
+
function Tr(e) {
|
|
3026
|
+
let t = Sr(), n = {
|
|
3027
|
+
deviceClass: Cr(),
|
|
2988
3028
|
integration: t.integration,
|
|
2989
|
-
...
|
|
3029
|
+
...wr()
|
|
2990
3030
|
};
|
|
2991
3031
|
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);
|
|
2992
3032
|
let r = e.getBoundingClientRect?.();
|
|
2993
3033
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
2994
3034
|
}
|
|
2995
|
-
async function
|
|
3035
|
+
async function Er() {
|
|
2996
3036
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
2997
3037
|
if (!e?.getHighEntropyValues) return {};
|
|
2998
3038
|
try {
|
|
@@ -3004,7 +3044,7 @@ async function Sr() {
|
|
|
3004
3044
|
}
|
|
3005
3045
|
//#endregion
|
|
3006
3046
|
//#region src/core/version.ts
|
|
3007
|
-
var
|
|
3047
|
+
var Dr = "2.27.0", Or = {
|
|
3008
3048
|
accent: "#E1B600",
|
|
3009
3049
|
accentText: "#1B1C23",
|
|
3010
3050
|
background: "#0e0f13",
|
|
@@ -3015,7 +3055,7 @@ var Cr = "2.26.1", wr = {
|
|
|
3015
3055
|
border: "rgba(255, 255, 255, 0.1)",
|
|
3016
3056
|
radius: "8px",
|
|
3017
3057
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
3018
|
-
},
|
|
3058
|
+
}, kr = {
|
|
3019
3059
|
accent: "--havik-accent",
|
|
3020
3060
|
accentText: "--havik-accent-text",
|
|
3021
3061
|
background: "--havik-bg",
|
|
@@ -3027,26 +3067,26 @@ var Cr = "2.26.1", wr = {
|
|
|
3027
3067
|
radius: "--havik-radius",
|
|
3028
3068
|
fontFamily: "--havik-font"
|
|
3029
3069
|
};
|
|
3030
|
-
function
|
|
3070
|
+
function Ar(e, t) {
|
|
3031
3071
|
let n = {
|
|
3032
|
-
...
|
|
3072
|
+
...Or,
|
|
3033
3073
|
...t
|
|
3034
3074
|
};
|
|
3035
|
-
for (let t of Object.keys(
|
|
3075
|
+
for (let t of Object.keys(kr)) e.style.setProperty(kr[t], n[t]);
|
|
3036
3076
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
3037
3077
|
}
|
|
3038
3078
|
//#endregion
|
|
3039
3079
|
//#region src/ui/styles.ts
|
|
3040
|
-
var
|
|
3041
|
-
function
|
|
3042
|
-
let n = e.querySelector(`style#${
|
|
3043
|
-
if (n && (!t ||
|
|
3080
|
+
var jr = "havik-player-styles", Mr = "\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", Nr = /* @__PURE__ */ new WeakMap();
|
|
3081
|
+
function Pr(e = document, t) {
|
|
3082
|
+
let n = e.querySelector(`style#${jr}`);
|
|
3083
|
+
if (n && (!t || Nr.get(n) === t)) return;
|
|
3044
3084
|
let r = e.createElement("style");
|
|
3045
|
-
r.id =
|
|
3085
|
+
r.id = jr, t && (r.nonce = t, r.setAttribute("nonce", t)), r.textContent = Mr, Nr.set(r, t), n ? n.replaceWith(r) : e.head.appendChild(r);
|
|
3046
3086
|
}
|
|
3047
3087
|
//#endregion
|
|
3048
3088
|
//#region src/ui/icons.ts
|
|
3049
|
-
var
|
|
3089
|
+
var Fr = {
|
|
3050
3090
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
3051
3091
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
3052
3092
|
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\"/>",
|
|
@@ -3060,11 +3100,11 @@ var jr = {
|
|
|
3060
3100
|
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\"/>"
|
|
3061
3101
|
};
|
|
3062
3102
|
function Q(e) {
|
|
3063
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
3103
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Fr[e]}</svg>`;
|
|
3064
3104
|
}
|
|
3065
3105
|
//#endregion
|
|
3066
3106
|
//#region src/ui/controls.ts
|
|
3067
|
-
var
|
|
3107
|
+
var Ir = 3e3, Lr = 250, Rr = /* @__PURE__ */ new Set([
|
|
3068
3108
|
"GONE",
|
|
3069
3109
|
"NOT_FOUND",
|
|
3070
3110
|
"GEO_DENIED",
|
|
@@ -3072,15 +3112,15 @@ var Mr = 3e3, Nr = 250, Pr = /* @__PURE__ */ new Set([
|
|
|
3072
3112
|
"UNAUTHORIZED",
|
|
3073
3113
|
"DRM_DEVICE_REVOKED"
|
|
3074
3114
|
]);
|
|
3075
|
-
function
|
|
3115
|
+
function zr(e) {
|
|
3076
3116
|
let t = "This match isn't available in your country";
|
|
3077
3117
|
return e ? `${t} (${e})` : t;
|
|
3078
3118
|
}
|
|
3079
|
-
var
|
|
3080
|
-
function
|
|
3081
|
-
return new
|
|
3119
|
+
var Br = "This device can't play protected video";
|
|
3120
|
+
function Vr(e) {
|
|
3121
|
+
return new Hr(e);
|
|
3082
3122
|
}
|
|
3083
|
-
var
|
|
3123
|
+
var Hr = class {
|
|
3084
3124
|
root;
|
|
3085
3125
|
video;
|
|
3086
3126
|
player;
|
|
@@ -3129,7 +3169,7 @@ var Rr = class {
|
|
|
3129
3169
|
scrubbing = !1;
|
|
3130
3170
|
offFns = [];
|
|
3131
3171
|
constructor(e) {
|
|
3132
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
3172
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? Ir, 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, this.offlineMessage = e.offlineMessage ?? "No internet connection — waiting to reconnect", Pr(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");
|
|
3133
3173
|
let t = (e, t, n) => {
|
|
3134
3174
|
let r = this.doc.createElement(e);
|
|
3135
3175
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -3215,7 +3255,7 @@ var Rr = class {
|
|
|
3215
3255
|
let t = this.surfaceWasHidden;
|
|
3216
3256
|
this.tapTimer = setTimeout(() => {
|
|
3217
3257
|
this.tapTimer = void 0, this.toggleBar(t);
|
|
3218
|
-
},
|
|
3258
|
+
}, Lr);
|
|
3219
3259
|
}
|
|
3220
3260
|
toggleBar(e) {
|
|
3221
3261
|
e ? this.poke() : this.hideIfIdle();
|
|
@@ -3242,7 +3282,7 @@ var Rr = class {
|
|
|
3242
3282
|
this.renderStatus(t);
|
|
3243
3283
|
}
|
|
3244
3284
|
statusMessageFor(e) {
|
|
3245
|
-
return e === "ended" ? this.isGone() ? this.endedMessage : this.player.endedReason === "interrupted" ? this.interruptedMessage : this.endedMessage : e === "offline" ? this.offlineMessage : e === "waiting" ? this.hasPlayed ? "Reconnecting — please stand by" : "Starting soon…" : e === "error" ? this.errorMessage === void 0 ? this.lastError?.code === "GEO_DENIED" ?
|
|
3285
|
+
return e === "ended" ? this.isGone() ? this.endedMessage : this.player.endedReason === "interrupted" ? this.interruptedMessage : this.endedMessage : e === "offline" ? this.offlineMessage : e === "waiting" ? this.hasPlayed ? "Reconnecting — please stand by" : "Starting soon…" : e === "error" ? this.errorMessage === void 0 ? this.lastError?.code === "GEO_DENIED" ? zr(this.lastError.country) : this.lastError?.code === "DRM_DEVICE_REVOKED" ? Br : this.lastError?.message ?? "Playback unavailable" : this.errorMessage : null;
|
|
3246
3286
|
}
|
|
3247
3287
|
renderStatus(e) {
|
|
3248
3288
|
let t = this.statusMessageFor(e);
|
|
@@ -3257,7 +3297,7 @@ var Rr = class {
|
|
|
3257
3297
|
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);
|
|
3258
3298
|
} else {
|
|
3259
3299
|
let r = this.doc.createElement("div");
|
|
3260
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !
|
|
3300
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !Rr.has(this.lastError.code)) {
|
|
3261
3301
|
let e = this.doc.createElement("button");
|
|
3262
3302
|
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);
|
|
3263
3303
|
}
|
|
@@ -3298,7 +3338,7 @@ var Rr = class {
|
|
|
3298
3338
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
3299
3339
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
3300
3340
|
}
|
|
3301
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
3341
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Ur(this.video.currentTime)} / ${Ur(this.video.duration)}`);
|
|
3302
3342
|
}
|
|
3303
3343
|
syncLive() {
|
|
3304
3344
|
let e = this.player.getStats(), t = e.isLive !== !1, n = this.isGone(), r = this.player.state === "ended" || n, i = !t && !this.streamEnded() && !n;
|
|
@@ -3348,17 +3388,17 @@ var Rr = class {
|
|
|
3348
3388
|
renderQualityMenu() {
|
|
3349
3389
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
3350
3390
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
3351
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
3391
|
+
for (let n of e) this.menu.append(this.menuItem(Wr(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
3352
3392
|
}
|
|
3353
3393
|
renderAudioMenu() {
|
|
3354
3394
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
3355
3395
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
3356
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
3396
|
+
for (let t of e) this.menu.append(this.menuItem(Gr(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
3357
3397
|
}
|
|
3358
3398
|
renderCcMenu() {
|
|
3359
3399
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
3360
3400
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
3361
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
3401
|
+
for (let t of e) this.menu.append(this.menuItem(Kr(t), !1, () => this.player.setTextTrack(t.id)));
|
|
3362
3402
|
}
|
|
3363
3403
|
onTracksChanged() {
|
|
3364
3404
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -3463,23 +3503,23 @@ var Rr = class {
|
|
|
3463
3503
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
3464
3504
|
}
|
|
3465
3505
|
};
|
|
3466
|
-
function
|
|
3506
|
+
function Ur(e) {
|
|
3467
3507
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
3468
3508
|
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");
|
|
3469
3509
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
3470
3510
|
}
|
|
3471
|
-
function
|
|
3511
|
+
function Wr(e) {
|
|
3472
3512
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
3473
3513
|
}
|
|
3474
|
-
function
|
|
3514
|
+
function Gr(e) {
|
|
3475
3515
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3476
3516
|
}
|
|
3477
|
-
function
|
|
3517
|
+
function Kr(e) {
|
|
3478
3518
|
return e.name || e.lang || `Track ${e.id}`;
|
|
3479
3519
|
}
|
|
3480
3520
|
//#endregion
|
|
3481
3521
|
//#region src/managed/index.ts
|
|
3482
|
-
var
|
|
3522
|
+
var qr = 6e3, Jr = 45e3, Yr = 2e3, Xr = 3, Zr = 5e3, Qr = 2e3, $r = 48e4, ei = "keySystemLicenseRequestFailed", ti = /* @__PURE__ */ new Set([
|
|
3483
3523
|
"GONE",
|
|
3484
3524
|
"NOT_FOUND",
|
|
3485
3525
|
"INVALID_URN",
|
|
@@ -3487,27 +3527,27 @@ var Ur = 6e3, Wr = 45e3, Gr = 2e3, Kr = 3, qr = 5e3, Jr = 2e3, Yr = 48e4, Xr = "
|
|
|
3487
3527
|
"GEO_DENIED",
|
|
3488
3528
|
"DRM_DEVICE_REVOKED"
|
|
3489
3529
|
]);
|
|
3490
|
-
function
|
|
3491
|
-
return !
|
|
3530
|
+
function ni(e) {
|
|
3531
|
+
return !ti.has(e);
|
|
3492
3532
|
}
|
|
3493
|
-
function
|
|
3533
|
+
function ri(e) {
|
|
3494
3534
|
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)})`);
|
|
3495
3535
|
if (e.env !== void 0) return lt(e.env);
|
|
3496
3536
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
3497
3537
|
return e.baseUrl;
|
|
3498
3538
|
}
|
|
3499
|
-
async function
|
|
3539
|
+
async function ii(e) {
|
|
3500
3540
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
3501
|
-
let t =
|
|
3541
|
+
let t = ri(e);
|
|
3502
3542
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
3503
3543
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
3504
|
-
let r = new
|
|
3544
|
+
let r = new ai({
|
|
3505
3545
|
...e,
|
|
3506
3546
|
baseUrl: t
|
|
3507
3547
|
});
|
|
3508
3548
|
return await r.start(), r;
|
|
3509
3549
|
}
|
|
3510
|
-
var
|
|
3550
|
+
var ai = class {
|
|
3511
3551
|
opts;
|
|
3512
3552
|
abort = new AbortController();
|
|
3513
3553
|
listeners = {};
|
|
@@ -3607,7 +3647,7 @@ var ti = class {
|
|
|
3607
3647
|
setTimeout(() => {
|
|
3608
3648
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
3609
3649
|
phase: i ? "unavailable" : "tooEarly",
|
|
3610
|
-
retryInMs:
|
|
3650
|
+
retryInMs: Jr,
|
|
3611
3651
|
attempt: 1,
|
|
3612
3652
|
elapsedMs: 0,
|
|
3613
3653
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -3646,13 +3686,13 @@ var ti = class {
|
|
|
3646
3686
|
!a && !p() && h();
|
|
3647
3687
|
}, e);
|
|
3648
3688
|
};
|
|
3649
|
-
_(
|
|
3689
|
+
_(qr), this.armingSub = D({
|
|
3650
3690
|
eventsBaseUrl: t,
|
|
3651
3691
|
matchUrn: this.opts.matchUrn,
|
|
3652
3692
|
credential: this.opts.credential,
|
|
3653
|
-
onAlive: () => _(
|
|
3693
|
+
onAlive: () => _(Jr),
|
|
3654
3694
|
onState: (e) => {
|
|
3655
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
3695
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * Yr);
|
|
3656
3696
|
},
|
|
3657
3697
|
onError: () => h()
|
|
3658
3698
|
});
|
|
@@ -3697,19 +3737,19 @@ var ti = class {
|
|
|
3697
3737
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
3698
3738
|
let i = e.analytics?.sid;
|
|
3699
3739
|
if (!i) return;
|
|
3700
|
-
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } =
|
|
3740
|
+
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = br(this.opts.baseUrl, a, e.analytics?.endpoint);
|
|
3701
3741
|
if (!o) {
|
|
3702
3742
|
s && setTimeout(() => {
|
|
3703
3743
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
|
|
3704
3744
|
}, 0);
|
|
3705
3745
|
return;
|
|
3706
3746
|
}
|
|
3707
|
-
let c = this.opts.video, l = new
|
|
3747
|
+
let c = this.opts.video, l = new xr({
|
|
3708
3748
|
endpoint: o,
|
|
3709
3749
|
sid: i,
|
|
3710
3750
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
3711
|
-
sdkVersion:
|
|
3712
|
-
environment:
|
|
3751
|
+
sdkVersion: Dr,
|
|
3752
|
+
environment: Tr(c),
|
|
3713
3753
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
3714
3754
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
3715
3755
|
onBlocked: (e) => setTimeout(() => {
|
|
@@ -3730,7 +3770,7 @@ var ti = class {
|
|
|
3730
3770
|
let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
|
|
3731
3771
|
c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
|
|
3732
3772
|
c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
|
|
3733
|
-
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()),
|
|
3773
|
+
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), Er().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
3734
3774
|
}
|
|
3735
3775
|
currentPresentation() {
|
|
3736
3776
|
let e = this.opts.video;
|
|
@@ -3753,6 +3793,7 @@ var ti = class {
|
|
|
3753
3793
|
sizeCapHeadroom: this.opts.sizeCapHeadroom,
|
|
3754
3794
|
adaptiveHoldBack: this.opts.adaptiveHoldBack,
|
|
3755
3795
|
adaptiveHoldBackCeiling: this.opts.adaptiveHoldBackCeiling,
|
|
3796
|
+
stallCap: this.opts.stallCap,
|
|
3756
3797
|
mediaDuringKey: this.opts.mediaDuringKey,
|
|
3757
3798
|
preloadHints: this.opts.preloadHints,
|
|
3758
3799
|
debug: this.opts.debug,
|
|
@@ -3762,9 +3803,9 @@ var ti = class {
|
|
|
3762
3803
|
freshLicenseUrl: () => this.refreshLicense()
|
|
3763
3804
|
}, o = this.opts.engine ?? "auto";
|
|
3764
3805
|
if (o === "native") return new H(a);
|
|
3765
|
-
if (o === "hls") return new
|
|
3806
|
+
if (o === "hls") return new er(a);
|
|
3766
3807
|
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && B(this.opts.video) && V() || !e.drmEnabled && Ot() && B(this.opts.video)) return new H(a);
|
|
3767
|
-
if (Wt()) return new
|
|
3808
|
+
if (Wt()) return new er(a);
|
|
3768
3809
|
if (B(this.opts.video)) return new H(a);
|
|
3769
3810
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
3770
3811
|
}
|
|
@@ -3835,7 +3876,7 @@ var ti = class {
|
|
|
3835
3876
|
a = !0, this.emit("warning", new n(r(o.status), o.status, `live-state events answered HTTP ${o.status} for ${this.opts.matchUrn}: the match is ` + (o.terminal ? "gone, so the subscription stopped" : "not in the catalog (ended and dropped, or not listed yet), so it retries every 5 min") + " — end-of-stream detection falls back to the HLS staleness watchdog."));
|
|
3836
3877
|
return;
|
|
3837
3878
|
}
|
|
3838
|
-
i += 1, i >=
|
|
3879
|
+
i += 1, i >= Xr && (a = !0, this.emit("warning", new n("NETWORK", 0, `live-state events unreachable at ${t} after ${i} 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.`)));
|
|
3839
3880
|
}
|
|
3840
3881
|
}
|
|
3841
3882
|
});
|
|
@@ -3852,7 +3893,7 @@ var ti = class {
|
|
|
3852
3893
|
}
|
|
3853
3894
|
if (this.emit("online"), this._state !== "error" || !this._lastError) return;
|
|
3854
3895
|
let t = this._lastError.code;
|
|
3855
|
-
|
|
3896
|
+
ni(t) && (t === "NETWORK" || this.failedWhileOffline) && this.retry().catch(() => void 0);
|
|
3856
3897
|
}));
|
|
3857
3898
|
}
|
|
3858
3899
|
watchReturn() {
|
|
@@ -3862,7 +3903,7 @@ var ti = class {
|
|
|
3862
3903
|
return;
|
|
3863
3904
|
}
|
|
3864
3905
|
let e = this.hiddenAtMs;
|
|
3865
|
-
this.hiddenAtMs = null, e != null && Date.now() - e >=
|
|
3906
|
+
this.hiddenAtMs = null, e != null && Date.now() - e >= Zr && this.resyncLiveState();
|
|
3866
3907
|
}, this.onReturnPageShow = (e) => {
|
|
3867
3908
|
e.persisted && this.resyncLiveState();
|
|
3868
3909
|
}, document.addEventListener("visibilitychange", this.onReturnVisible), typeof window < "u" && window.addEventListener("pageshow", this.onReturnPageShow));
|
|
@@ -3894,7 +3935,7 @@ var ti = class {
|
|
|
3894
3935
|
scheduleRejoin(e) {
|
|
3895
3936
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
3896
3937
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
3897
|
-
}, Math.random() *
|
|
3938
|
+
}, Math.random() * Yr));
|
|
3898
3939
|
}
|
|
3899
3940
|
cancelRejoin() {
|
|
3900
3941
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -3918,7 +3959,7 @@ var ti = class {
|
|
|
3918
3959
|
}
|
|
3919
3960
|
t.controls = !1;
|
|
3920
3961
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
3921
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
3962
|
+
r && r.insertBefore(n, t), n.appendChild(t), Ar(n, this.opts.theme), this.container = n, this.controlBar = Vr({
|
|
3922
3963
|
root: n,
|
|
3923
3964
|
video: t,
|
|
3924
3965
|
player: this,
|
|
@@ -3957,7 +3998,7 @@ var ti = class {
|
|
|
3957
3998
|
}
|
|
3958
3999
|
startStats() {
|
|
3959
4000
|
this.stopStats();
|
|
3960
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
4001
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? Qr);
|
|
3961
4002
|
this.statsTimer = setInterval(() => {
|
|
3962
4003
|
if (!this.engine) return;
|
|
3963
4004
|
let e = this.engine.getStats();
|
|
@@ -3968,14 +4009,14 @@ var ti = class {
|
|
|
3968
4009
|
this.statsTimer && clearInterval(this.statsTimer), this.statsTimer = void 0;
|
|
3969
4010
|
}
|
|
3970
4011
|
isStaleLicenseDenial(e) {
|
|
3971
|
-
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !==
|
|
4012
|
+
return this.staleLicenseReloaded || this.opts.hlsConfig?.licenseXhrSetup || this._state === "ended" || this._state === "error" || e.detail !== ei || e.error.httpStatus !== 403 || e.error.code !== "FORBIDDEN" || e.error.serverCode === "license_refused" ? !1 : W(this._descriptor?.drm?.widevine?.licenseUrl);
|
|
3972
4013
|
}
|
|
3973
4014
|
scheduleLicenseRefresh() {
|
|
3974
4015
|
if (this.stopRefresh(), !this._descriptor?.drmEnabled) return;
|
|
3975
4016
|
typeof document < "u" && this.engine?.name === "hls" && (this.onRefocus = () => {
|
|
3976
4017
|
document.visibilityState !== "visible" || this.destroyed || W(this._descriptor?.drm?.widevine?.licenseUrl) && this.refreshLicense();
|
|
3977
4018
|
}, document.addEventListener("visibilitychange", this.onRefocus));
|
|
3978
|
-
let e = this.opts.licenseRefreshMs ??
|
|
4019
|
+
let e = this.opts.licenseRefreshMs ?? $r;
|
|
3979
4020
|
e && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
3980
4021
|
}
|
|
3981
4022
|
stopRefresh() {
|
|
@@ -4145,7 +4186,7 @@ function $(e) {
|
|
|
4145
4186
|
}
|
|
4146
4187
|
//#endregion
|
|
4147
4188
|
//#region src/embed/host.ts
|
|
4148
|
-
function
|
|
4189
|
+
function oi(e) {
|
|
4149
4190
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
4150
4191
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
4151
4192
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -4204,15 +4245,15 @@ function ni(e) {
|
|
|
4204
4245
|
}
|
|
4205
4246
|
//#endregion
|
|
4206
4247
|
//#region src/embed/page.ts
|
|
4207
|
-
var
|
|
4208
|
-
function
|
|
4248
|
+
var si = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
4249
|
+
function ci(e) {
|
|
4209
4250
|
if (typeof e == "boolean") return e;
|
|
4210
4251
|
if (typeof e == "object" && e) {
|
|
4211
4252
|
let t = e.endpoint;
|
|
4212
4253
|
return typeof t == "string" ? { endpoint: t } : {};
|
|
4213
4254
|
}
|
|
4214
4255
|
}
|
|
4215
|
-
function
|
|
4256
|
+
function li() {
|
|
4216
4257
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
4217
4258
|
if (e) return {
|
|
4218
4259
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -4222,7 +4263,7 @@ function ai() {
|
|
|
4222
4263
|
autoplay: e.autoplay ?? !0,
|
|
4223
4264
|
muted: e.muted ?? !0,
|
|
4224
4265
|
waitForLive: e.waitForLive ?? !0,
|
|
4225
|
-
analytics:
|
|
4266
|
+
analytics: ci(e.analytics)
|
|
4226
4267
|
};
|
|
4227
4268
|
let t = new URLSearchParams(location.search);
|
|
4228
4269
|
return {
|
|
@@ -4235,9 +4276,9 @@ function ai() {
|
|
|
4235
4276
|
waitForLive: !0
|
|
4236
4277
|
};
|
|
4237
4278
|
}
|
|
4238
|
-
async function
|
|
4239
|
-
let e =
|
|
4240
|
-
|
|
4279
|
+
async function ui() {
|
|
4280
|
+
let e = li();
|
|
4281
|
+
fi();
|
|
4241
4282
|
let t = document.createElement("video");
|
|
4242
4283
|
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);
|
|
4243
4284
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -4293,12 +4334,12 @@ async function oi() {
|
|
|
4293
4334
|
message: e.message,
|
|
4294
4335
|
...e.country === void 0 ? {} : { country: e.country }
|
|
4295
4336
|
})), e.on("autoplayblocked", () => {
|
|
4296
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
4337
|
+
i({ type: "oddin:autoplayblocked" }), di(t, e);
|
|
4297
4338
|
});
|
|
4298
4339
|
}, s = async (r) => {
|
|
4299
4340
|
a?.destroy(), a = null;
|
|
4300
4341
|
try {
|
|
4301
|
-
let n = await
|
|
4342
|
+
let n = await ii({
|
|
4302
4343
|
video: t,
|
|
4303
4344
|
baseUrl: e.baseUrl,
|
|
4304
4345
|
matchUrn: r,
|
|
@@ -4361,7 +4402,7 @@ async function oi() {
|
|
|
4361
4402
|
a?.retry();
|
|
4362
4403
|
break;
|
|
4363
4404
|
case "oddin:load":
|
|
4364
|
-
typeof e.matchUrn == "string" &&
|
|
4405
|
+
typeof e.matchUrn == "string" && si.test(e.matchUrn) && s(e.matchUrn);
|
|
4365
4406
|
break;
|
|
4366
4407
|
case "oddin:destroy": c();
|
|
4367
4408
|
}
|
|
@@ -4373,18 +4414,18 @@ async function oi() {
|
|
|
4373
4414
|
protocol: 1
|
|
4374
4415
|
});
|
|
4375
4416
|
}
|
|
4376
|
-
function
|
|
4417
|
+
function di(e, t) {
|
|
4377
4418
|
if (document.getElementById("havik-tap")) return;
|
|
4378
4419
|
let n = document.createElement("button");
|
|
4379
4420
|
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", () => {
|
|
4380
4421
|
n.remove(), t.play();
|
|
4381
4422
|
}), document.body.appendChild(n);
|
|
4382
4423
|
}
|
|
4383
|
-
function
|
|
4424
|
+
function fi() {
|
|
4384
4425
|
let e = document.createElement("style");
|
|
4385
4426
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
4386
4427
|
}
|
|
4387
4428
|
//#endregion
|
|
4388
|
-
export { E as LiveStateHttpError,
|
|
4429
|
+
export { E as LiveStateHttpError, Or as ODDIN_THEME, n as PlaybackError, Ar as applyTheme, lt as baseUrlForEnv, ui as bootEmbed, ke as clearDeviceId, He as clearRememberedBandwidth, ii as createPlayer, O as deriveEventsBaseUrl, at as detectDrmSupport, w as enterVideoFullscreen, T as exitVideoFullscreen, ve as fetchCatalog, be as fetchTournament, Se as flattenMatches, C as fullscreenSupported, Oe as getDeviceId, st as isLowLatencyManifest, $ as isOddinMessage, je as licenseRequestHeaders, oi as mountEmbed, fe as pollToLive, y as resolveStream, D as subscribeLiveState, S as videoFullscreenActive, we as watchStatus };
|
|
4389
4430
|
|
|
4390
4431
|
//# sourceMappingURL=index.js.map
|