@oddin-gg/havik-player 2.11.1 → 2.12.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/README.md +26 -7
- package/dist/havik-player.global.js +18 -18
- package/dist/havik-player.global.js.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -15
- package/dist/index.d.ts +33 -15
- package/dist/index.js +356 -335
- package/dist/index.js.map +1 -1
- package/docs/API.md +48 -43
- package/embed/index.html +1 -1
- package/examples/vanilla.html +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -110,42 +110,48 @@ function m(e) {
|
|
|
110
110
|
return e instanceof Error ? e.message : String(e);
|
|
111
111
|
}
|
|
112
112
|
//#endregion
|
|
113
|
+
//#region src/core/warnOnce.ts
|
|
114
|
+
var h = /* @__PURE__ */ new Set();
|
|
115
|
+
function g(e, t = e) {
|
|
116
|
+
h.has(t) || (h.add(t), console.warn(`havik-player: ${e}`));
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
113
119
|
//#region src/core/waitForLive.ts
|
|
114
|
-
var
|
|
120
|
+
var _ = 1e3, ee = 3e4, te = 6e5, ne = 3e5, re = 1e3, ie = {
|
|
115
121
|
TOO_EARLY: "tooEarly",
|
|
116
122
|
UNAVAILABLE: "unavailable",
|
|
117
123
|
RATE_LIMITED: "rateLimited",
|
|
118
124
|
NETWORK: "network"
|
|
119
125
|
};
|
|
120
|
-
function
|
|
121
|
-
let t = e === !0 || e === !1 ? {} : e, n = Math.max(
|
|
126
|
+
function ae(e) {
|
|
127
|
+
let t = e === !0 || e === !1 ? {} : e, n = Math.max(re, t.floorMs ?? _), r = Math.max(n, t.ceilMs ?? ee), i = Math.max(0, t.imminentMs ?? te), a = Math.max(r, t.sanityFloorMs ?? ne);
|
|
122
128
|
return {
|
|
123
129
|
timeoutMs: t.timeoutMs,
|
|
124
130
|
floorMs: n,
|
|
125
131
|
ceilMs: r,
|
|
126
132
|
imminentMs: i,
|
|
127
133
|
sanityFloorMs: a,
|
|
128
|
-
kickoffMs:
|
|
134
|
+
kickoffMs: oe(t.kickoffAt),
|
|
129
135
|
jitter: t.jitter ?? !0,
|
|
130
136
|
onState: t.onState
|
|
131
137
|
};
|
|
132
138
|
}
|
|
133
|
-
function
|
|
139
|
+
function oe(e) {
|
|
134
140
|
if (e == null) return;
|
|
135
141
|
if (typeof e == "number") return Number.isFinite(e) ? e : void 0;
|
|
136
142
|
let t = Date.parse(e);
|
|
137
143
|
return Number.isFinite(t) ? t : void 0;
|
|
138
144
|
}
|
|
139
|
-
function
|
|
145
|
+
function se(e, t, n) {
|
|
140
146
|
return Math.min(n, Math.max(t, e));
|
|
141
147
|
}
|
|
142
|
-
function
|
|
148
|
+
function ce(e) {
|
|
143
149
|
return Math.round(e * (1 + .15 * Math.random()));
|
|
144
150
|
}
|
|
145
|
-
function
|
|
151
|
+
function le(e, t, n, r) {
|
|
146
152
|
let i = r ?? n.kickoffMs, a = i == null ? void 0 : Math.max(0, i - t), o = Math.max(n.floorMs, e ?? 0);
|
|
147
153
|
if (a == null || a <= n.imminentMs) return {
|
|
148
|
-
delay:
|
|
154
|
+
delay: se(e ?? n.floorMs, o, n.ceilMs),
|
|
149
155
|
ttkMs: a
|
|
150
156
|
};
|
|
151
157
|
let s = Math.min(Math.floor(a / 10), n.sanityFloorMs, a);
|
|
@@ -154,7 +160,7 @@ function se(e, t, n, r) {
|
|
|
154
160
|
ttkMs: a
|
|
155
161
|
};
|
|
156
162
|
}
|
|
157
|
-
function
|
|
163
|
+
function ue(e, t) {
|
|
158
164
|
return new Promise((r, i) => {
|
|
159
165
|
if (t?.aborted) {
|
|
160
166
|
i(new n("ABORTED", 0, "wait-for-live aborted"));
|
|
@@ -168,8 +174,8 @@ function ce(e, t) {
|
|
|
168
174
|
t?.addEventListener("abort", a, { once: !0 });
|
|
169
175
|
});
|
|
170
176
|
}
|
|
171
|
-
async function
|
|
172
|
-
let i =
|
|
177
|
+
async function de(e, t, r) {
|
|
178
|
+
let i = ae(t), a = Date.now(), s = i.timeoutMs == null ? Infinity : a + i.timeoutMs, c = 0, l;
|
|
173
179
|
for (;;) {
|
|
174
180
|
if (r?.aborted) throw new n("ABORTED", 0, "wait-for-live aborted");
|
|
175
181
|
try {
|
|
@@ -177,38 +183,38 @@ async function v(e, t, r) {
|
|
|
177
183
|
} catch (e) {
|
|
178
184
|
if (!(e instanceof n) || !o(e.code)) throw e;
|
|
179
185
|
c += 1, e.liveStartsAtMs != null && Number.isFinite(e.liveStartsAtMs) && (l = e.liveStartsAtMs);
|
|
180
|
-
let t = Date.now(), u =
|
|
181
|
-
if (i.jitter && (f =
|
|
186
|
+
let t = Date.now(), u = le(e.retryAfterMs, t, i, l), d = u.ttkMs, f = u.delay;
|
|
187
|
+
if (i.jitter && (f = ce(f)), t + f > s) throw new n("TIMEOUT", e.httpStatus, `timed out after ${i.timeoutMs}ms waiting for the stream to go live`, {
|
|
182
188
|
retryAfterMs: e.retryAfterMs,
|
|
183
189
|
cause: e
|
|
184
190
|
});
|
|
185
191
|
i.onState?.({
|
|
186
|
-
phase:
|
|
192
|
+
phase: ie[e.code] ?? "unavailable",
|
|
187
193
|
retryInMs: f,
|
|
188
194
|
attempt: c,
|
|
189
195
|
elapsedMs: t - a,
|
|
190
196
|
ttkMs: d
|
|
191
|
-
}), await
|
|
197
|
+
}), await ue(f, r);
|
|
192
198
|
}
|
|
193
199
|
}
|
|
194
200
|
}
|
|
195
201
|
//#endregion
|
|
196
202
|
//#region src/core/resolve.ts
|
|
197
|
-
async function
|
|
203
|
+
async function v(e) {
|
|
198
204
|
if (!e.matchUrn || typeof e.matchUrn != "string") throw new n("INVALID_URN", 0, "resolveStream: a non-empty matchUrn is required");
|
|
199
205
|
let t = await p(d(e.baseUrl, `/v1/playback/${encodeURIComponent(e.matchUrn)}`), {
|
|
200
206
|
credential: e.credential,
|
|
201
207
|
signal: e.signal,
|
|
202
208
|
apiHeaders: e.apiHeaders
|
|
203
209
|
});
|
|
204
|
-
if (!t.ok) throw await
|
|
205
|
-
return
|
|
210
|
+
if (!t.ok) throw await fe(t);
|
|
211
|
+
return he(await t.json(), e.matchUrn);
|
|
206
212
|
}
|
|
207
|
-
function
|
|
208
|
-
let t = () =>
|
|
209
|
-
return e.waitForLive ?
|
|
213
|
+
function y(e) {
|
|
214
|
+
let t = () => v(e);
|
|
215
|
+
return e.waitForLive ? de(t, e.waitForLive, e.signal) : t();
|
|
210
216
|
}
|
|
211
|
-
async function
|
|
217
|
+
async function fe(e) {
|
|
212
218
|
let t = f(e.headers.get("retry-after")), i = e.headers.get("x-request-id") ?? e.headers.get("x-amzn-requestid") ?? void 0, a = e.statusText || `HTTP ${e.status}`, o, s;
|
|
213
219
|
try {
|
|
214
220
|
let t = await e.json();
|
|
@@ -224,7 +230,7 @@ async function le(e) {
|
|
|
224
230
|
liveStartsAtMs: s
|
|
225
231
|
});
|
|
226
232
|
}
|
|
227
|
-
var
|
|
233
|
+
var pe = /* @__PURE__ */ new Set([
|
|
228
234
|
"matchUrn",
|
|
229
235
|
"protocol",
|
|
230
236
|
"drmEnabled",
|
|
@@ -235,7 +241,7 @@ var ue = /* @__PURE__ */ new Set([
|
|
|
235
241
|
"expiresAt",
|
|
236
242
|
"analytics"
|
|
237
243
|
]);
|
|
238
|
-
function
|
|
244
|
+
function b(e, t) {
|
|
239
245
|
let r;
|
|
240
246
|
try {
|
|
241
247
|
r = new URL(t);
|
|
@@ -245,57 +251,71 @@ function x(e, t) {
|
|
|
245
251
|
if (r.protocol !== "https:" && r.protocol !== "http:") throw new n("INTERNAL", 0, `playback ${e} has a disallowed scheme: ${r.protocol}`);
|
|
246
252
|
return t;
|
|
247
253
|
}
|
|
248
|
-
function
|
|
254
|
+
function me(e) {
|
|
255
|
+
if (e !== void 0) {
|
|
256
|
+
if (typeof e == "string" && !e.endsWith("/")) try {
|
|
257
|
+
let t = new URL(e);
|
|
258
|
+
if (t.protocol === "https:" && t.href === `${t.origin}/`) return t.origin;
|
|
259
|
+
} catch {}
|
|
260
|
+
g(`server analytics.endpoint ${JSON.stringify(e)} ignored: not a bare https origin.`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function he(e, t) {
|
|
249
264
|
if (!e.manifestUrl) throw new n("INTERNAL", 0, "playback response is missing manifestUrl");
|
|
250
265
|
let r = e.drmEnabled ?? !!e.drm, i = {
|
|
251
266
|
matchUrn: e.matchUrn ?? t,
|
|
252
267
|
protocol: "hls",
|
|
253
268
|
drmEnabled: r,
|
|
254
|
-
manifestUrl:
|
|
269
|
+
manifestUrl: b("manifestUrl", e.manifestUrl),
|
|
255
270
|
serverTime: e.serverTime ?? ""
|
|
256
271
|
};
|
|
257
|
-
if (e.liveStartsAt && (i.liveStartsAt = e.liveStartsAt), typeof e.analytics?.sid == "string" && e.analytics.sid
|
|
272
|
+
if (e.liveStartsAt && (i.liveStartsAt = e.liveStartsAt), typeof e.analytics?.sid == "string" && e.analytics.sid) {
|
|
273
|
+
i.analytics = { sid: e.analytics.sid };
|
|
274
|
+
let t = me(e.analytics.endpoint);
|
|
275
|
+
t && (i.analytics.endpoint = t);
|
|
276
|
+
}
|
|
277
|
+
if (r && e.drm) {
|
|
258
278
|
let t = {};
|
|
259
|
-
e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl:
|
|
260
|
-
licenseUrl:
|
|
261
|
-
certificateUrl:
|
|
279
|
+
e.drm.widevine?.licenseUrl && (t.widevine = { licenseUrl: b("widevine licenseUrl", e.drm.widevine.licenseUrl) }), e.drm.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && (t.fairplay = {
|
|
280
|
+
licenseUrl: b("fairplay licenseUrl", e.drm.fairplay.licenseUrl),
|
|
281
|
+
certificateUrl: b("fairplay certificateUrl", e.drm.fairplay.certificateUrl)
|
|
262
282
|
}), (t.widevine || t.fairplay) && (i.drm = t);
|
|
263
283
|
}
|
|
264
284
|
let a = {};
|
|
265
|
-
for (let [t, n] of Object.entries(e))
|
|
285
|
+
for (let [t, n] of Object.entries(e)) pe.has(t) || (a[t] = n);
|
|
266
286
|
return Object.keys(a).length > 0 && (i.extensions = a), i;
|
|
267
287
|
}
|
|
268
288
|
//#endregion
|
|
269
289
|
//#region src/core/fullscreen.ts
|
|
270
|
-
function
|
|
290
|
+
function ge(e) {
|
|
271
291
|
return e.ownerDocument ?? document;
|
|
272
292
|
}
|
|
273
|
-
function
|
|
293
|
+
function _e(e) {
|
|
274
294
|
return e.fullscreenElement ?? e.webkitFullscreenElement ?? null;
|
|
275
295
|
}
|
|
276
|
-
function
|
|
277
|
-
let n =
|
|
296
|
+
function x(e, t) {
|
|
297
|
+
let n = _e(ge(e));
|
|
278
298
|
return n != null && (n === e || t != null && n === t) || e.webkitDisplayingFullscreen === !0;
|
|
279
299
|
}
|
|
280
|
-
async function
|
|
300
|
+
async function S(e, t) {
|
|
281
301
|
let n = t ?? e;
|
|
282
302
|
if (typeof n.requestFullscreen == "function") return await n.requestFullscreen(), !0;
|
|
283
303
|
if (typeof n.webkitRequestFullscreen == "function") return n.webkitRequestFullscreen(), !0;
|
|
284
304
|
let r = e;
|
|
285
305
|
return r.webkitSupportsFullscreen && typeof r.webkitEnterFullscreen == "function" ? (r.webkitEnterFullscreen(), !0) : !1;
|
|
286
306
|
}
|
|
287
|
-
async function
|
|
307
|
+
async function C(e, t) {
|
|
288
308
|
let n = e;
|
|
289
309
|
if (n.webkitDisplayingFullscreen) {
|
|
290
310
|
n.webkitExitFullscreen?.();
|
|
291
311
|
return;
|
|
292
312
|
}
|
|
293
|
-
let r =
|
|
313
|
+
let r = ge(e), i = _e(r);
|
|
294
314
|
i != null && (i === e || t != null && i === t) && (typeof r.exitFullscreen == "function" ? await r.exitFullscreen() : r.webkitExitFullscreen?.());
|
|
295
315
|
}
|
|
296
316
|
//#endregion
|
|
297
317
|
//#region src/core/catalog.ts
|
|
298
|
-
async function
|
|
318
|
+
async function ve(e) {
|
|
299
319
|
let t = new URLSearchParams();
|
|
300
320
|
e.status && t.set("status", Array.isArray(e.status) ? e.status.join(",") : e.status), e.sport && t.set("sport", e.sport);
|
|
301
321
|
let i = t.toString(), a = d(e.baseUrl, "/v1/catalog" + (i ? `?${i}` : "")), o = new Headers();
|
|
@@ -313,12 +333,12 @@ async function fe(e) {
|
|
|
313
333
|
};
|
|
314
334
|
if (!s.ok) throw new n(r(s.status), s.status, `catalog request failed (HTTP ${s.status})`);
|
|
315
335
|
return {
|
|
316
|
-
tournaments:
|
|
336
|
+
tournaments: ye(await s.json()),
|
|
317
337
|
etag: s.headers.get("etag") ?? void 0,
|
|
318
338
|
notModified: !1
|
|
319
339
|
};
|
|
320
340
|
}
|
|
321
|
-
function
|
|
341
|
+
function ye(e) {
|
|
322
342
|
return (e.tournaments ?? []).map((e) => {
|
|
323
343
|
let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
|
|
324
344
|
return {
|
|
@@ -340,7 +360,7 @@ function pe(e) {
|
|
|
340
360
|
};
|
|
341
361
|
});
|
|
342
362
|
}
|
|
343
|
-
async function
|
|
363
|
+
async function be(e) {
|
|
344
364
|
let t = d(e.baseUrl, `/v1/tournaments/${encodeURIComponent(e.urn)}`), i = new Headers();
|
|
345
365
|
e.etag && i.set("If-None-Match", e.etag);
|
|
346
366
|
let a = await p(t, {
|
|
@@ -360,13 +380,13 @@ async function me(e) {
|
|
|
360
380
|
};
|
|
361
381
|
if (!a.ok) throw new n(r(a.status), a.status, `tournament request failed (HTTP ${a.status})`);
|
|
362
382
|
return {
|
|
363
|
-
tournament:
|
|
383
|
+
tournament: xe(await a.json()),
|
|
364
384
|
etag: a.headers.get("etag") ?? void 0,
|
|
365
385
|
notModified: !1,
|
|
366
386
|
notFound: !1
|
|
367
387
|
};
|
|
368
388
|
}
|
|
369
|
-
function
|
|
389
|
+
function xe(e) {
|
|
370
390
|
let t = e.urn ?? "", n = e.name ?? "", r = e.sport ?? "";
|
|
371
391
|
return {
|
|
372
392
|
urn: t,
|
|
@@ -386,12 +406,12 @@ function he(e) {
|
|
|
386
406
|
}))
|
|
387
407
|
};
|
|
388
408
|
}
|
|
389
|
-
function
|
|
409
|
+
function Se(e) {
|
|
390
410
|
return e.tournaments.flatMap((e) => e.matches);
|
|
391
411
|
}
|
|
392
412
|
//#endregion
|
|
393
413
|
//#region src/core/poll.ts
|
|
394
|
-
function
|
|
414
|
+
function Ce(e) {
|
|
395
415
|
let t = Math.max(2e3, e.intervalMs ?? 1e4), i = new AbortController(), a, o, s, u = !1, f = () => {
|
|
396
416
|
u || (a = setTimeout(m, t));
|
|
397
417
|
}, m = async () => {
|
|
@@ -433,9 +453,9 @@ function _e(e) {
|
|
|
433
453
|
}
|
|
434
454
|
//#endregion
|
|
435
455
|
//#region src/core/events.ts
|
|
436
|
-
var
|
|
437
|
-
function
|
|
438
|
-
let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = e.idleTimeoutMs ??
|
|
456
|
+
var we = 45e3;
|
|
457
|
+
function w(e) {
|
|
458
|
+
let t = Math.max(250, e.minBackoffMs ?? 1e3), n = Math.max(t, e.maxBackoffMs ?? 15e3), r = e.idleTimeoutMs ?? we, i = Number.isFinite(r) && r > 0 ? r : 0, a = new AbortController(), o = !1, c = (e) => new Promise((t) => {
|
|
439
459
|
if (a.signal.aborted) return t();
|
|
440
460
|
let n = setTimeout(t, e);
|
|
441
461
|
a.signal.addEventListener("abort", () => {
|
|
@@ -516,7 +536,7 @@ function D(e) {
|
|
|
516
536
|
o || (o = !0, a.abort());
|
|
517
537
|
} };
|
|
518
538
|
}
|
|
519
|
-
function
|
|
539
|
+
function T(e) {
|
|
520
540
|
try {
|
|
521
541
|
let t = new URL(e);
|
|
522
542
|
return t.hostname = `events.${t.hostname}`, t.pathname = "", t.search = "", t.origin;
|
|
@@ -526,27 +546,27 @@ function O(e) {
|
|
|
526
546
|
}
|
|
527
547
|
//#endregion
|
|
528
548
|
//#region src/core/drm/deviceId.ts
|
|
529
|
-
var
|
|
530
|
-
function
|
|
531
|
-
if (
|
|
549
|
+
var E = "havik.player.deviceId", D;
|
|
550
|
+
function O() {
|
|
551
|
+
if (D) return D;
|
|
532
552
|
try {
|
|
533
|
-
let e = globalThis.localStorage?.getItem(
|
|
534
|
-
if (e) return
|
|
553
|
+
let e = globalThis.localStorage?.getItem(E);
|
|
554
|
+
if (e) return D = e, e;
|
|
535
555
|
} catch {}
|
|
536
|
-
let e =
|
|
537
|
-
|
|
556
|
+
let e = Ee();
|
|
557
|
+
D = e;
|
|
538
558
|
try {
|
|
539
|
-
globalThis.localStorage?.setItem(
|
|
559
|
+
globalThis.localStorage?.setItem(E, e);
|
|
540
560
|
} catch {}
|
|
541
561
|
return e;
|
|
542
562
|
}
|
|
543
|
-
function
|
|
544
|
-
|
|
563
|
+
function Te() {
|
|
564
|
+
D = void 0;
|
|
545
565
|
try {
|
|
546
|
-
globalThis.localStorage?.removeItem(
|
|
566
|
+
globalThis.localStorage?.removeItem(E);
|
|
547
567
|
} catch {}
|
|
548
568
|
}
|
|
549
|
-
function
|
|
569
|
+
function Ee() {
|
|
550
570
|
let e = globalThis.crypto;
|
|
551
571
|
if (e && typeof e.randomUUID == "function") return e.randomUUID();
|
|
552
572
|
let t = /* @__PURE__ */ new Uint8Array(16);
|
|
@@ -558,21 +578,21 @@ function be() {
|
|
|
558
578
|
}
|
|
559
579
|
//#endregion
|
|
560
580
|
//#region src/core/drm/headers.ts
|
|
561
|
-
function
|
|
581
|
+
function De(e, t, n = {}) {
|
|
562
582
|
let r = {
|
|
563
583
|
"x-api-key": t.apiKey,
|
|
564
584
|
"X-Match-Urn": e.matchUrn,
|
|
565
|
-
"X-Device-Id": n.deviceId ??
|
|
585
|
+
"X-Device-Id": n.deviceId ?? O(),
|
|
566
586
|
"Content-Type": "application/octet-stream"
|
|
567
587
|
};
|
|
568
588
|
return n.userId && (r["X-User-Id"] = n.userId), r;
|
|
569
589
|
}
|
|
570
590
|
//#endregion
|
|
571
591
|
//#region src/core/drm/cdm.ts
|
|
572
|
-
var
|
|
573
|
-
function
|
|
574
|
-
let n =
|
|
575
|
-
n || (n = /* @__PURE__ */ new Map(),
|
|
592
|
+
var k = /* @__PURE__ */ new WeakMap();
|
|
593
|
+
function Oe(e, t) {
|
|
594
|
+
let n = k.get(e);
|
|
595
|
+
n || (n = /* @__PURE__ */ new Map(), k.set(e, n));
|
|
576
596
|
let r = n.get(t.keySystem);
|
|
577
597
|
if (r) return r;
|
|
578
598
|
let i = t.createMediaKeys().catch((e) => {
|
|
@@ -580,22 +600,22 @@ function Se(e, t) {
|
|
|
580
600
|
});
|
|
581
601
|
return n.set(t.keySystem, i), i;
|
|
582
602
|
}
|
|
583
|
-
function
|
|
603
|
+
function A() {
|
|
584
604
|
return typeof navigator < "u" && typeof navigator.requestMediaKeySystemAccess == "function";
|
|
585
605
|
}
|
|
586
|
-
var
|
|
587
|
-
function
|
|
606
|
+
var j = ["SW_SECURE_DECODE", "SW_SECURE_CRYPTO"];
|
|
607
|
+
function ke(e) {
|
|
588
608
|
return e.startsWith("com.widevine");
|
|
589
609
|
}
|
|
590
|
-
function
|
|
591
|
-
if (!
|
|
610
|
+
function M(e, t) {
|
|
611
|
+
if (!ke(e)) return t;
|
|
592
612
|
let n = (e, t) => {
|
|
593
613
|
let n = e.videoCapabilities;
|
|
594
614
|
return !n?.length || !n.some((e) => e.robustness) ? !1 : n.every((e) => {
|
|
595
|
-
let n =
|
|
596
|
-
return n === -1 ||
|
|
615
|
+
let n = j.indexOf(e.robustness);
|
|
616
|
+
return n === -1 || j.indexOf(t) > n;
|
|
597
617
|
});
|
|
598
|
-
}, r =
|
|
618
|
+
}, r = j.flatMap((e) => t.filter((t) => n(t, e)).map((t) => ({
|
|
599
619
|
...t,
|
|
600
620
|
videoCapabilities: t.videoCapabilities?.map((t) => ({
|
|
601
621
|
...t,
|
|
@@ -604,53 +624,53 @@ function F(e, t) {
|
|
|
604
624
|
})));
|
|
605
625
|
return [...t, ...r];
|
|
606
626
|
}
|
|
607
|
-
function
|
|
608
|
-
return (t, n) =>
|
|
627
|
+
function N(e) {
|
|
628
|
+
return (t, n) => A() ? navigator.requestMediaKeySystemAccess(t, M(t, n)).then((t) => ({
|
|
609
629
|
keySystem: t.keySystem,
|
|
610
630
|
getConfiguration: () => t.getConfiguration(),
|
|
611
|
-
createMediaKeys: () =>
|
|
631
|
+
createMediaKeys: () => Oe(e, t)
|
|
612
632
|
})) : Promise.reject(/* @__PURE__ */ Error("navigator.requestMediaKeySystemAccess is unavailable — EME needs a secure context (https, or localhost)"));
|
|
613
633
|
}
|
|
614
|
-
var
|
|
634
|
+
var P = {
|
|
615
635
|
video: "SW_SECURE_DECODE",
|
|
616
636
|
audio: "SW_SECURE_CRYPTO",
|
|
617
637
|
scheme: "cbcs"
|
|
618
638
|
};
|
|
619
|
-
function
|
|
620
|
-
if (!
|
|
639
|
+
function Ae(e) {
|
|
640
|
+
if (!A()) return;
|
|
621
641
|
let t = (e, t) => ({
|
|
622
642
|
contentType: e,
|
|
623
643
|
robustness: t,
|
|
624
|
-
encryptionScheme:
|
|
644
|
+
encryptionScheme: P.scheme
|
|
625
645
|
});
|
|
626
|
-
|
|
646
|
+
N(e)("com.widevine.alpha", [{
|
|
627
647
|
initDataTypes: ["cenc"],
|
|
628
648
|
distinctiveIdentifier: "optional",
|
|
629
649
|
persistentState: "optional",
|
|
630
650
|
sessionTypes: ["temporary"],
|
|
631
|
-
audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"",
|
|
632
|
-
videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"",
|
|
651
|
+
audioCapabilities: [t("audio/mp4; codecs=\"mp4a.40.2\"", P.audio)],
|
|
652
|
+
videoCapabilities: [t("video/mp4; codecs=\"avc1.42e01e\"", P.video)]
|
|
633
653
|
}]).then((e) => e.createMediaKeys()).catch(() => {});
|
|
634
654
|
}
|
|
635
|
-
function
|
|
636
|
-
let t =
|
|
655
|
+
function F(e) {
|
|
656
|
+
let t = I(e);
|
|
637
657
|
if (/^avc[13]/.test(t)) return "avc";
|
|
638
658
|
if (/^(hvc1|hev1)/.test(t)) return "hevc";
|
|
639
659
|
if (/^(dvh1|dvhe)/.test(t)) return "dv";
|
|
640
660
|
if (t.startsWith("av01")) return "av1";
|
|
641
661
|
if (/^vp0?9/.test(t)) return "vp9";
|
|
642
662
|
}
|
|
643
|
-
function
|
|
663
|
+
function I(e) {
|
|
644
664
|
return (e ?? "").trim().toLowerCase();
|
|
645
665
|
}
|
|
646
|
-
var
|
|
666
|
+
var je = {
|
|
647
667
|
hevc: "hvc1.1.6.L93.90",
|
|
648
668
|
dv: "dvh1.05.06",
|
|
649
669
|
av1: "av01.0.05M.08",
|
|
650
670
|
vp9: "vp09.00.10.08"
|
|
651
|
-
},
|
|
652
|
-
function
|
|
653
|
-
let t =
|
|
671
|
+
}, Me = /* @__PURE__ */ new Map(), L = /* @__PURE__ */ new Map();
|
|
672
|
+
function Ne(e) {
|
|
673
|
+
let t = I(e), n = Me.get(t);
|
|
654
674
|
if (n) return n;
|
|
655
675
|
let r = {
|
|
656
676
|
initDataTypes: ["cenc"],
|
|
@@ -659,32 +679,32 @@ function Oe(e) {
|
|
|
659
679
|
sessionTypes: ["temporary"],
|
|
660
680
|
videoCapabilities: [{
|
|
661
681
|
contentType: `video/mp4; codecs="${e.trim()}"`,
|
|
662
|
-
robustness:
|
|
663
|
-
encryptionScheme:
|
|
682
|
+
robustness: P.video,
|
|
683
|
+
encryptionScheme: P.scheme
|
|
664
684
|
}]
|
|
665
685
|
}, i = (async () => {
|
|
666
686
|
try {
|
|
667
|
-
return await navigator.requestMediaKeySystemAccess("com.widevine.alpha",
|
|
687
|
+
return await navigator.requestMediaKeySystemAccess("com.widevine.alpha", M("com.widevine.alpha", [r])), !0;
|
|
668
688
|
} catch {
|
|
669
689
|
return !1;
|
|
670
690
|
}
|
|
671
|
-
})().then((e) => (
|
|
672
|
-
return
|
|
691
|
+
})().then((e) => (L.set(t, e), e));
|
|
692
|
+
return Me.set(t, i), i;
|
|
673
693
|
}
|
|
674
|
-
function
|
|
675
|
-
if (
|
|
694
|
+
function Pe() {
|
|
695
|
+
if (A()) for (let e of Object.values(je)) Ne(e);
|
|
676
696
|
}
|
|
677
|
-
function
|
|
678
|
-
let t =
|
|
679
|
-
if (t) return t === "avc" ? !0 :
|
|
697
|
+
function Fe(e) {
|
|
698
|
+
let t = F(e);
|
|
699
|
+
if (t) return t === "avc" ? !0 : L.get(I(e)) ?? L.get(I(je[t]));
|
|
680
700
|
}
|
|
681
701
|
//#endregion
|
|
682
702
|
//#region src/core/drm/support.ts
|
|
683
|
-
var
|
|
703
|
+
var Ie = 5e3, R = "video/mp4; codecs=\"avc1.42E01E\"", z = "audio/mp4; codecs=\"mp4a.40.2\"", Le = {
|
|
684
704
|
widevine: ["com.widevine.alpha"],
|
|
685
705
|
fairplay: ["com.apple.fps"]
|
|
686
706
|
};
|
|
687
|
-
function
|
|
707
|
+
function Re(e) {
|
|
688
708
|
return e === "fairplay" ? [{
|
|
689
709
|
initDataTypes: [
|
|
690
710
|
"sinf",
|
|
@@ -692,30 +712,30 @@ function Pe(e) {
|
|
|
692
712
|
"cenc"
|
|
693
713
|
],
|
|
694
714
|
videoCapabilities: [{
|
|
695
|
-
contentType:
|
|
715
|
+
contentType: R,
|
|
696
716
|
robustness: "",
|
|
697
717
|
encryptionScheme: "cbcs"
|
|
698
718
|
}],
|
|
699
719
|
audioCapabilities: [{
|
|
700
|
-
contentType:
|
|
720
|
+
contentType: z,
|
|
701
721
|
robustness: "",
|
|
702
722
|
encryptionScheme: "cbcs"
|
|
703
723
|
}]
|
|
704
|
-
}] :
|
|
724
|
+
}] : M("com.widevine.alpha", [{
|
|
705
725
|
initDataTypes: ["cenc"],
|
|
706
726
|
videoCapabilities: [{
|
|
707
|
-
contentType:
|
|
708
|
-
robustness:
|
|
709
|
-
encryptionScheme:
|
|
727
|
+
contentType: R,
|
|
728
|
+
robustness: P.video,
|
|
729
|
+
encryptionScheme: P.scheme
|
|
710
730
|
}],
|
|
711
731
|
audioCapabilities: [{
|
|
712
|
-
contentType:
|
|
713
|
-
robustness:
|
|
714
|
-
encryptionScheme:
|
|
732
|
+
contentType: z,
|
|
733
|
+
robustness: P.audio,
|
|
734
|
+
encryptionScheme: P.scheme
|
|
715
735
|
}]
|
|
716
736
|
}]);
|
|
717
737
|
}
|
|
718
|
-
function
|
|
738
|
+
function B(e, t) {
|
|
719
739
|
return new Promise((n, r) => {
|
|
720
740
|
let i = setTimeout(() => r(/* @__PURE__ */ Error("probe-timeout")), t);
|
|
721
741
|
e.then((e) => {
|
|
@@ -725,8 +745,8 @@ function V(e, t) {
|
|
|
725
745
|
});
|
|
726
746
|
});
|
|
727
747
|
}
|
|
728
|
-
async function
|
|
729
|
-
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ??
|
|
748
|
+
async function ze(e = {}) {
|
|
749
|
+
let t = e.systems ?? ["widevine", "fairplay"], n = e.timeoutMs ?? Ie, r = {};
|
|
730
750
|
if (typeof window < "u" && window.isSecureContext === !1) return {
|
|
731
751
|
verdict: "insecure-context",
|
|
732
752
|
detail: r
|
|
@@ -738,7 +758,7 @@ async function Fe(e = {}) {
|
|
|
738
758
|
};
|
|
739
759
|
let a = !1, o = !1, s = Date.now() + n, c = () => Math.max(1, s - Date.now());
|
|
740
760
|
for (let e of t) {
|
|
741
|
-
let t =
|
|
761
|
+
let t = Le[e];
|
|
742
762
|
if (!t) {
|
|
743
763
|
r[e] = "unknown system";
|
|
744
764
|
continue;
|
|
@@ -749,7 +769,7 @@ async function Fe(e = {}) {
|
|
|
749
769
|
break;
|
|
750
770
|
}
|
|
751
771
|
try {
|
|
752
|
-
return await
|
|
772
|
+
return await B((await B(i(n, Re(e)), c())).createMediaKeys(), c()), r[e] = `ok (${n})`, {
|
|
753
773
|
verdict: "supported",
|
|
754
774
|
system: e,
|
|
755
775
|
detail: r
|
|
@@ -773,49 +793,49 @@ async function Fe(e = {}) {
|
|
|
773
793
|
}
|
|
774
794
|
//#endregion
|
|
775
795
|
//#region src/core/manifest.ts
|
|
776
|
-
var
|
|
777
|
-
function
|
|
778
|
-
return
|
|
796
|
+
var Be = /^#EXT-X-(PART-INF|PART|PRELOAD-HINT)[:\s]/m;
|
|
797
|
+
function Ve(e) {
|
|
798
|
+
return Be.test(e);
|
|
779
799
|
}
|
|
780
800
|
//#endregion
|
|
781
801
|
//#region src/core/env.ts
|
|
782
|
-
var
|
|
802
|
+
var V = {
|
|
783
803
|
integration: "https://feed-dev.oddin-video.gg",
|
|
784
804
|
production: "https://feed.oddin-video.gg"
|
|
785
805
|
};
|
|
786
|
-
function
|
|
787
|
-
let t = Object.prototype.hasOwnProperty.call(
|
|
806
|
+
function H(e) {
|
|
807
|
+
let t = Object.prototype.hasOwnProperty.call(V, e) ? V[e] : void 0;
|
|
788
808
|
if (!t) throw new n("INTERNAL", 0, `unknown env ${JSON.stringify(e)} — expected 'integration' or 'production'`);
|
|
789
809
|
return t;
|
|
790
810
|
}
|
|
791
811
|
//#endregion
|
|
792
812
|
//#region src/core/stats.ts
|
|
793
|
-
var
|
|
794
|
-
function
|
|
813
|
+
var U = { droppedFrames: 0 };
|
|
814
|
+
function W(e) {
|
|
795
815
|
try {
|
|
796
816
|
return new URL(e).host;
|
|
797
817
|
} catch {
|
|
798
818
|
return "";
|
|
799
819
|
}
|
|
800
820
|
}
|
|
801
|
-
var
|
|
802
|
-
function
|
|
821
|
+
var He = /\.(m3u8|ts|m4s|mp4|cmfv|cmfa)(\?|$)/i;
|
|
822
|
+
function Ue(e) {
|
|
803
823
|
if (typeof performance > "u" || typeof performance.getEntriesByType != "function") return "";
|
|
804
824
|
let t = "", n = -1, r = performance.getEntriesByType("resource");
|
|
805
|
-
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" ||
|
|
806
|
-
let e =
|
|
825
|
+
for (let i of r) if (!(i.startTime < e) && (i.initiatorType === "video" || i.initiatorType === "audio" || He.test(i.name)) && i.startTime >= n) {
|
|
826
|
+
let e = W(i.name);
|
|
807
827
|
e && (t = e, n = i.startTime);
|
|
808
828
|
}
|
|
809
829
|
return t;
|
|
810
830
|
}
|
|
811
|
-
function
|
|
831
|
+
function G(e) {
|
|
812
832
|
let t = e.getVideoPlaybackQuality?.();
|
|
813
833
|
return {
|
|
814
834
|
dropped: t?.droppedVideoFrames ?? 0,
|
|
815
835
|
totalFrames: t?.totalVideoFrames ?? 0
|
|
816
836
|
};
|
|
817
837
|
}
|
|
818
|
-
function
|
|
838
|
+
function We(e, t) {
|
|
819
839
|
let n = [
|
|
820
840
|
["playing", () => t("playing")],
|
|
821
841
|
["waiting", () => t("buffering")],
|
|
@@ -832,7 +852,7 @@ function Be(e, t) {
|
|
|
832
852
|
}
|
|
833
853
|
//#endregion
|
|
834
854
|
//#region src/core/engine/native.ts
|
|
835
|
-
function
|
|
855
|
+
function Ge(e) {
|
|
836
856
|
try {
|
|
837
857
|
let t = new TextDecoder("utf-8").decode(new Uint8Array(e));
|
|
838
858
|
return /^skd:\/\/[0-9a-fA-F-]{36}:([0-9a-fA-F]{32})$/.exec(t)?.[1];
|
|
@@ -840,15 +860,15 @@ function Ve(e) {
|
|
|
840
860
|
return;
|
|
841
861
|
}
|
|
842
862
|
}
|
|
843
|
-
function
|
|
863
|
+
function K(e) {
|
|
844
864
|
return !!(e ?? (typeof document < "u" ? document.createElement("video") : void 0))?.canPlayType("application/vnd.apple.mpegurl");
|
|
845
865
|
}
|
|
846
|
-
function
|
|
866
|
+
function q() {
|
|
847
867
|
if (typeof window > "u") return !1;
|
|
848
868
|
let e = "WebKitMediaKeys" in window || typeof HTMLMediaElement < "u" && "webkitSetMediaKeys" in HTMLMediaElement.prototype, t = typeof navigator < "u" && /Apple/i.test(navigator.vendor ?? "");
|
|
849
869
|
return e || t;
|
|
850
870
|
}
|
|
851
|
-
var
|
|
871
|
+
var J = class {
|
|
852
872
|
name = "native";
|
|
853
873
|
deps;
|
|
854
874
|
onLoaded;
|
|
@@ -884,7 +904,7 @@ var Y = class {
|
|
|
884
904
|
type: "error",
|
|
885
905
|
error: new n("INTERNAL", 0, "native HLS playback error"),
|
|
886
906
|
fatal: !0
|
|
887
|
-
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src =
|
|
907
|
+
}), this.onLoaded && e.addEventListener("loadedmetadata", this.onLoaded, { once: !0 }), e.addEventListener("error", this.onError), e.src = Ke(t.manifestUrl, t.analytics?.sid), e.load();
|
|
888
908
|
}
|
|
889
909
|
startLoad() {
|
|
890
910
|
this.loadStarted || (this.loadStarted = !0, this.restorePreload());
|
|
@@ -906,7 +926,7 @@ var Y = class {
|
|
|
906
926
|
});
|
|
907
927
|
this.onEncrypted = (n) => {
|
|
908
928
|
let i = n;
|
|
909
|
-
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV =
|
|
929
|
+
i.initData && !this.fairplayArmed && (this.fairplayArmed = !0, this.fairplayKeyIV = Ge(i.initData), (async () => {
|
|
910
930
|
try {
|
|
911
931
|
let n = await (await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
|
912
932
|
initDataTypes: [i.initDataType],
|
|
@@ -1001,11 +1021,11 @@ var Y = class {
|
|
|
1001
1021
|
e.seekable.length > 0 && (e.currentTime = e.seekable.end(e.seekable.length - 1));
|
|
1002
1022
|
}
|
|
1003
1023
|
getStats() {
|
|
1004
|
-
let e = this.deps.video, t =
|
|
1024
|
+
let e = this.deps.video, t = G(e), n = {
|
|
1005
1025
|
droppedFrames: t.dropped,
|
|
1006
1026
|
decodedFrames: t.totalFrames
|
|
1007
1027
|
};
|
|
1008
|
-
return this.cdnHost ||=
|
|
1028
|
+
return this.cdnHost ||= Ue(this.builtAt), this.cdnHost && (n.cdnHost = this.cdnHost), this.deps.descriptor.drmEnabled && (n.keySystem = "fairplay"), e.duration === Infinity ? (n.isLive = !0, e.seekable.length > 0 && (n.atLiveEdge = e.currentTime >= e.seekable.end(e.seekable.length - 1) - 2)) : Number.isFinite(e.duration) && e.duration > 0 && (n.isLive = !1), n;
|
|
1009
1029
|
}
|
|
1010
1030
|
stop() {
|
|
1011
1031
|
try {
|
|
@@ -1024,13 +1044,13 @@ var Y = class {
|
|
|
1024
1044
|
} catch {}
|
|
1025
1045
|
}
|
|
1026
1046
|
};
|
|
1027
|
-
function
|
|
1047
|
+
function Ke(e, t) {
|
|
1028
1048
|
return t ? `${e}${e.includes("?") ? "&" : "?"}CMCD=${encodeURIComponent(`sid="${t}"`)}` : e;
|
|
1029
1049
|
}
|
|
1030
1050
|
//#endregion
|
|
1031
1051
|
//#region src/core/engine/prefetch.ts
|
|
1032
|
-
var
|
|
1033
|
-
function
|
|
1052
|
+
var qe = 15e3, Je = 5e3, Ye = 6;
|
|
1053
|
+
function Xe(e) {
|
|
1034
1054
|
try {
|
|
1035
1055
|
let t = new URL(e);
|
|
1036
1056
|
return t.searchParams.delete("CMCD"), t.toString();
|
|
@@ -1038,7 +1058,7 @@ function Ke(e) {
|
|
|
1038
1058
|
return e;
|
|
1039
1059
|
}
|
|
1040
1060
|
}
|
|
1041
|
-
var
|
|
1061
|
+
var Ze = class {
|
|
1042
1062
|
cmcd;
|
|
1043
1063
|
entries = /* @__PURE__ */ new Map();
|
|
1044
1064
|
keyed = /* @__PURE__ */ new Set();
|
|
@@ -1061,10 +1081,10 @@ var qe = class {
|
|
|
1061
1081
|
}
|
|
1062
1082
|
prefetch(e, t, n) {
|
|
1063
1083
|
if (!this.isActive(t)) return;
|
|
1064
|
-
let r =
|
|
1084
|
+
let r = Xe(e);
|
|
1065
1085
|
if (this.entries.has(r)) return;
|
|
1066
1086
|
let i = this.perTrack.get(t) ?? 0;
|
|
1067
|
-
if (i >=
|
|
1087
|
+
if (i >= Ye) return;
|
|
1068
1088
|
this.perTrack.set(t, i + 1);
|
|
1069
1089
|
let a = new AbortController(), o = {
|
|
1070
1090
|
started: performance.now(),
|
|
@@ -1078,10 +1098,10 @@ var qe = class {
|
|
|
1078
1098
|
signal: a.signal
|
|
1079
1099
|
}).then(async (e) => (o.first = performance.now(), e.ok ? e.arrayBuffer() : null)).catch(() => null), this.entries.set(r, o), this.stats.started += 1, setTimeout(() => {
|
|
1080
1100
|
this.entries.get(r) === o && (this.entries.delete(r), a.abort(), this.stats.expired += 1);
|
|
1081
|
-
},
|
|
1101
|
+
}, qe);
|
|
1082
1102
|
}
|
|
1083
1103
|
take(e) {
|
|
1084
|
-
let t =
|
|
1104
|
+
let t = Xe(e), n = this.entries.get(t);
|
|
1085
1105
|
return n && this.entries.delete(t), n;
|
|
1086
1106
|
}
|
|
1087
1107
|
destroy() {
|
|
@@ -1101,13 +1121,13 @@ var qe = class {
|
|
|
1101
1121
|
}
|
|
1102
1122
|
}
|
|
1103
1123
|
};
|
|
1104
|
-
function
|
|
1124
|
+
function Qe(t) {
|
|
1105
1125
|
let n = e.DefaultConfig?.loader;
|
|
1106
1126
|
if (typeof n != "function") return;
|
|
1107
1127
|
class r extends n {
|
|
1108
1128
|
served = !1;
|
|
1109
1129
|
cancelled = !1;
|
|
1110
|
-
stats =
|
|
1130
|
+
stats = $e();
|
|
1111
1131
|
load(e, n, r) {
|
|
1112
1132
|
let i = e.rangeEnd ? void 0 : t.take(e.url);
|
|
1113
1133
|
if (!i) {
|
|
@@ -1115,7 +1135,7 @@ function Je(t) {
|
|
|
1115
1135
|
return;
|
|
1116
1136
|
}
|
|
1117
1137
|
this.served = !0;
|
|
1118
|
-
let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs ||
|
|
1138
|
+
let a = performance.now(), o = n?.loadPolicy?.maxTimeToFirstByteMs || Je, s = setTimeout(() => {
|
|
1119
1139
|
!this.cancelled && this.served && (i.abort.abort(), t.stats.failed += 1, this.served = !1, super.load(e, n, r));
|
|
1120
1140
|
}, o);
|
|
1121
1141
|
i.bytes.then((o) => {
|
|
@@ -1142,7 +1162,7 @@ function Je(t) {
|
|
|
1142
1162
|
}
|
|
1143
1163
|
return r;
|
|
1144
1164
|
}
|
|
1145
|
-
function
|
|
1165
|
+
function $e() {
|
|
1146
1166
|
return {
|
|
1147
1167
|
aborted: !1,
|
|
1148
1168
|
loaded: 0,
|
|
@@ -1166,10 +1186,10 @@ function Ye() {
|
|
|
1166
1186
|
}
|
|
1167
1187
|
};
|
|
1168
1188
|
}
|
|
1169
|
-
function
|
|
1189
|
+
function et(e) {
|
|
1170
1190
|
return e === "audio" ? "audio" : "main";
|
|
1171
1191
|
}
|
|
1172
|
-
function
|
|
1192
|
+
function tt(e, t) {
|
|
1173
1193
|
let n = [];
|
|
1174
1194
|
t.initSegment?.url && !t.initSegment.data && n.push({
|
|
1175
1195
|
url: t.initSegment.url,
|
|
@@ -1188,24 +1208,24 @@ function Ze(e, t) {
|
|
|
1188
1208
|
}
|
|
1189
1209
|
//#endregion
|
|
1190
1210
|
//#region src/core/engine/hls.ts
|
|
1191
|
-
function
|
|
1211
|
+
function nt() {
|
|
1192
1212
|
return e.isSupported();
|
|
1193
1213
|
}
|
|
1194
|
-
var
|
|
1195
|
-
function
|
|
1214
|
+
var rt = 3, it = 5, at = 3, ot = 3e4, st = 12e3, ct = 3e3, lt = 6e3, ut = 5e3, dt = 4e3, ft = 2, pt = 5, mt = 2, ht = 2, gt = 4, _t = 4, vt = 2e3, yt = 3e4, bt = 2, xt = 9, St = .5, Ct = 64;
|
|
1215
|
+
function wt(e) {
|
|
1196
1216
|
if (e.liveSyncDurationCount != null || e.liveMaxLatencyDurationCount != null) {
|
|
1197
1217
|
delete e.liveSyncDuration, delete e.liveMaxLatencyDuration;
|
|
1198
1218
|
return;
|
|
1199
1219
|
}
|
|
1200
|
-
e.liveSyncDuration ??=
|
|
1201
|
-
let t = Math.max(12, e.liveSyncDuration +
|
|
1202
|
-
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t),
|
|
1220
|
+
e.liveSyncDuration ??= bt;
|
|
1221
|
+
let t = Math.max(12, e.liveSyncDuration + xt);
|
|
1222
|
+
(e.liveMaxLatencyDuration == null || e.liveMaxLatencyDuration <= e.liveSyncDuration) && (e.liveMaxLatencyDuration = t), Tt(e, e.liveSyncDuration);
|
|
1203
1223
|
}
|
|
1204
|
-
function
|
|
1224
|
+
function Tt(e, t) {
|
|
1205
1225
|
let n = (e, t, n) => Math.min(n, Math.max(t, e));
|
|
1206
1226
|
e.maxStarvationDelay ??= n(t / 2, .5, 4), e.maxLoadingDelay ??= n(t, 1, 4), e.abrEwmaFastLive ??= n(t / 2, 1, 3);
|
|
1207
1227
|
}
|
|
1208
|
-
var
|
|
1228
|
+
var Et = class {
|
|
1209
1229
|
name = "hls";
|
|
1210
1230
|
hls = null;
|
|
1211
1231
|
deps;
|
|
@@ -1273,7 +1293,7 @@ var St = class {
|
|
|
1273
1293
|
this.deps = e, this.licenseUrl = e.descriptor.drm?.widevine?.licenseUrl, this.loadStarted = e.deferLoad !== !0;
|
|
1274
1294
|
}
|
|
1275
1295
|
async load() {
|
|
1276
|
-
let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a =
|
|
1296
|
+
let { descriptor: e, snapToLiveOnRefocus: t, video: r, emit: i } = this.deps, a = K(r) && q(), o = !!e.drm?.widevine?.licenseUrl && !a;
|
|
1277
1297
|
if (e.drmEnabled && !o) {
|
|
1278
1298
|
i({
|
|
1279
1299
|
type: "error",
|
|
@@ -1282,7 +1302,7 @@ var St = class {
|
|
|
1282
1302
|
});
|
|
1283
1303
|
return;
|
|
1284
1304
|
}
|
|
1285
|
-
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (
|
|
1305
|
+
e.drmEnabled && o && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && (Ae(r), Pe()), this.startHls(), t !== !1 && typeof document < "u" && (this.onVisibility = () => {
|
|
1286
1306
|
let e = this.hls;
|
|
1287
1307
|
if (document.visibilityState !== "visible" || !e) return;
|
|
1288
1308
|
let t = e.liveSyncPosition;
|
|
@@ -1305,7 +1325,7 @@ var St = class {
|
|
|
1305
1325
|
}
|
|
1306
1326
|
this.loadSuspended = !0;
|
|
1307
1327
|
}
|
|
1308
|
-
},
|
|
1328
|
+
}, ut));
|
|
1309
1329
|
}
|
|
1310
1330
|
resumeLoading() {
|
|
1311
1331
|
if (this.pauseSuspendTimer &&= (clearTimeout(this.pauseSuspendTimer), null), this.loadSuspended && (this.loadSuspended = !1, !this.stopped && this.hls)) {
|
|
@@ -1337,7 +1357,7 @@ var St = class {
|
|
|
1337
1357
|
let t = e.liveSyncPosition;
|
|
1338
1358
|
if (typeof t != "number" || !Number.isFinite(t)) return;
|
|
1339
1359
|
let { video: n } = this.deps;
|
|
1340
|
-
n.currentTime <= t +
|
|
1360
|
+
n.currentTime <= t + St || (n.currentTime = t);
|
|
1341
1361
|
}
|
|
1342
1362
|
startHls() {
|
|
1343
1363
|
let { video: t, descriptor: n, credential: r, deviceId: i, userId: a, lowLatency: o, debug: s, hlsConfig: c, emit: l } = this.deps;
|
|
@@ -1356,12 +1376,12 @@ var St = class {
|
|
|
1356
1376
|
emeEnabled: !0,
|
|
1357
1377
|
drmSystems: { ...this.licenseUrl ? { "com.widevine.alpha": { licenseUrl: this.licenseUrl } } : {} },
|
|
1358
1378
|
drmSystemOptions: {
|
|
1359
|
-
videoRobustness:
|
|
1360
|
-
audioRobustness:
|
|
1361
|
-
videoEncryptionScheme:
|
|
1362
|
-
audioEncryptionScheme:
|
|
1379
|
+
videoRobustness: P.video,
|
|
1380
|
+
audioRobustness: P.audio,
|
|
1381
|
+
videoEncryptionScheme: P.scheme,
|
|
1382
|
+
audioEncryptionScheme: P.scheme
|
|
1363
1383
|
},
|
|
1364
|
-
...
|
|
1384
|
+
...A() ? { requestMediaKeySystemAccessFunc: N(t) } : {},
|
|
1365
1385
|
licenseXhrSetup: (e, t) => {
|
|
1366
1386
|
e.open("POST", this.licenseUrl ?? t, !0), e.setRequestHeader("x-api-key", r.apiKey), e.setRequestHeader("X-Match-Urn", n.matchUrn), e.setRequestHeader("X-Device-Id", i), a && e.setRequestHeader("X-User-Id", a), this.licenseRequested = !0;
|
|
1367
1387
|
let o = performance.now();
|
|
@@ -1378,20 +1398,20 @@ var St = class {
|
|
|
1378
1398
|
...c
|
|
1379
1399
|
};
|
|
1380
1400
|
if (this.prefetch?.destroy(), this.prefetch = null, u && this.deps.mediaDuringKey !== !1 && !d.fLoader) {
|
|
1381
|
-
let e = new
|
|
1401
|
+
let e = new Ze({
|
|
1382
1402
|
sessionId: n.analytics?.sid,
|
|
1383
1403
|
contentId: n.matchUrn
|
|
1384
|
-
}), t =
|
|
1404
|
+
}), t = Qe(e);
|
|
1385
1405
|
t && (this.prefetch = e, d.fLoader = t);
|
|
1386
1406
|
}
|
|
1387
|
-
|
|
1407
|
+
wt(d), this.sizeCapManaged = d.capLevelToPlayerSize !== !0, this.loadStarted = d.autoStartLoad !== !1;
|
|
1388
1408
|
let f = new e(d);
|
|
1389
1409
|
if (this.hls = f, f.on(e.Events.MANIFEST_PARSED, () => {
|
|
1390
1410
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, u && !this.deps.hlsConfig?.requestMediaKeySystemAccessFunc && this.dropLevelsWidevineCannotPlay(f), this.measureLadder(f), this.applySizeCap(), this.loadSuspended = !1, t.paused && this.schedulePauseSuspend(), l({ type: "ready" });
|
|
1391
1411
|
}), f.on(e.Events.FRAG_BUFFERED, (e, t) => {
|
|
1392
1412
|
t?.frag?.type === "main" && (this.kickKind !== "dead" && this.clearKick(), (this.mediaRecoveries > 0 || this.networkRecoveries > 0 || this.licenseRecoveries > 0 || this.starvationKicks > 0 || this.starvationRebuilds > 0) && !this.recoveryResetTimer && (this.recoveryResetTimer = setTimeout(() => {
|
|
1393
1413
|
this.mediaRecoveries = 0, this.networkRecoveries = 0, this.licenseRecoveries = 0, this.starvationKicks = 0, this.starvationRebuilds = 0, this.recoveryResetTimer = null;
|
|
1394
|
-
},
|
|
1414
|
+
}, ot)));
|
|
1395
1415
|
}), f.on(e.Events.FRAG_LOADING, (e, t) => {
|
|
1396
1416
|
t?.frag?.type === "main" && (this.lastFragLoadingMs = Date.now());
|
|
1397
1417
|
}), f.on(e.Events.FRAG_LOADED, (e, t) => {
|
|
@@ -1399,10 +1419,10 @@ var St = class {
|
|
|
1399
1419
|
let n = t?.frag?.stats, r = n?.loaded;
|
|
1400
1420
|
typeof r == "number" && (this.bytesLoaded += r), !this.reportedFirstBytes && typeof r == "number" && r > 0 && (this.reportedFirstBytes = !0, l({ type: "firstBytes" }));
|
|
1401
1421
|
let i = n?.loading;
|
|
1402
|
-
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 >
|
|
1422
|
+
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 > Ct && this.requestTimesMs.shift());
|
|
1403
1423
|
let a = t?.frag?.url;
|
|
1404
1424
|
if (a) {
|
|
1405
|
-
let e =
|
|
1425
|
+
let e = W(a);
|
|
1406
1426
|
e && (this.cdnHost = e);
|
|
1407
1427
|
}
|
|
1408
1428
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => {
|
|
@@ -1416,15 +1436,15 @@ var St = class {
|
|
|
1416
1436
|
}), f.on(e.Events.LEVEL_LOADED, (e, t) => this.trackEnd(t)), this.prefetch) {
|
|
1417
1437
|
let t = this.prefetch;
|
|
1418
1438
|
f.on(e.Events.KEY_LOADING, (e, n) => {
|
|
1419
|
-
let r = n?.frag, i =
|
|
1420
|
-
if (r && t.isActive(i)) for (let e of
|
|
1421
|
-
}), f.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(
|
|
1439
|
+
let r = n?.frag, i = et(r?.type);
|
|
1440
|
+
if (r && t.isActive(i)) for (let e of tt(f, r)) t.prefetch(e.url, i, e.kind);
|
|
1441
|
+
}), f.on(e.Events.KEY_LOADED, (e, n) => t.keyUsable(et(n?.frag?.type)));
|
|
1422
1442
|
}
|
|
1423
1443
|
f.on(e.Events.KEY_LOADED, () => {
|
|
1424
1444
|
u && !this.reportedDrmReady && (this.reportedDrmReady = !0, l({ type: "drmReady" }));
|
|
1425
1445
|
}), this.endWatchdog && clearInterval(this.endWatchdog), this.endWatchdog = setInterval(() => {
|
|
1426
1446
|
this.checkEndStale(), this.checkStarvation();
|
|
1427
|
-
},
|
|
1447
|
+
}, ct), f.on(e.Events.LEVEL_SWITCHED, (e, t) => {
|
|
1428
1448
|
this.renditionSwitches += 1;
|
|
1429
1449
|
let n = this.lastLevelIndex >= 0 ? f.levels[this.lastLevelIndex] : void 0, r = f.levels[t.level];
|
|
1430
1450
|
n && r && r.bitrate !== n.bitrate && (r.bitrate > n.bitrate ? this.upshifts += 1 : this.downshifts += 1), this.lastLevelIndex = t.level, l({
|
|
@@ -1488,7 +1508,7 @@ var St = class {
|
|
|
1488
1508
|
return;
|
|
1489
1509
|
}
|
|
1490
1510
|
this.capTimer && clearTimeout(this.capTimer);
|
|
1491
|
-
let t = e > this.sizeCapLevel ?
|
|
1511
|
+
let t = e > this.sizeCapLevel ? vt : yt;
|
|
1492
1512
|
this.capTimer = setTimeout(() => {
|
|
1493
1513
|
this.capTimer = null, this.computeSizeCapTarget() === e ? this.applySizeCap() : this.onMediaResize();
|
|
1494
1514
|
}, t);
|
|
@@ -1498,9 +1518,9 @@ var St = class {
|
|
|
1498
1518
|
this.ladderHeights = t.length ? [...new Set(t)].sort((e, t) => e - t) : void 0, this.ladderTopBitrateKbps = e.levels.length ? Math.round(Math.max(...e.levels.map((e) => e.bitrate)) / 1e3) : 0;
|
|
1499
1519
|
}
|
|
1500
1520
|
dropLevelsWidevineCannotPlay(e) {
|
|
1501
|
-
this.removeLevelsWhere(e, (e) =>
|
|
1502
|
-
let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e &&
|
|
1503
|
-
for (let n of t)
|
|
1521
|
+
this.removeLevelsWhere(e, (e) => Fe(e) !== !0);
|
|
1522
|
+
let t = new Set(e.levels.map((e) => e.videoCodec).filter((e) => !!e && F(e) !== "avc" && !!F(e)));
|
|
1523
|
+
for (let n of t) Ne(n).then((t) => {
|
|
1504
1524
|
t || this.hls !== e || this.removeLevelsWhere(e, (e) => e === n) && (this.measureLadder(e), this.applySizeCap());
|
|
1505
1525
|
});
|
|
1506
1526
|
}
|
|
@@ -1508,10 +1528,10 @@ var St = class {
|
|
|
1508
1528
|
let n = e.levels ?? [], r = [], i = /* @__PURE__ */ new Set();
|
|
1509
1529
|
if (n.forEach((e, n) => {
|
|
1510
1530
|
let a = e.videoCodec;
|
|
1511
|
-
a &&
|
|
1531
|
+
a && F(a) && t(a) && (r.push(n), i.add(a));
|
|
1512
1532
|
}), !r.length) return !1;
|
|
1513
1533
|
let a = [...i].join(", ");
|
|
1514
|
-
if (!n.some((e, t) => r.includes(t) ? !1 : !
|
|
1534
|
+
if (!n.some((e, t) => r.includes(t) ? !1 : !F(e.videoCodec) || Fe(e.videoCodec) === !0)) return console.warn(`havik-player: every rendition is ${a}, which Widevine may not play on this browser; keeping them`), !1;
|
|
1515
1535
|
for (let t = r.length - 1; t >= 0; --t) e.removeLevel(r[t]);
|
|
1516
1536
|
return console.info(`havik-player: skipped ${r.length} rendition(s) Widevine cannot play on this browser (${a})`), !0;
|
|
1517
1537
|
}
|
|
@@ -1557,7 +1577,7 @@ var St = class {
|
|
|
1557
1577
|
e.widevine && (this.licenseUrl = e.widevine);
|
|
1558
1578
|
}
|
|
1559
1579
|
getStats() {
|
|
1560
|
-
let e = this.hls, t =
|
|
1580
|
+
let e = this.hls, t = G(this.deps.video), n = {
|
|
1561
1581
|
droppedFrames: t.dropped,
|
|
1562
1582
|
decodedFrames: t.totalFrames,
|
|
1563
1583
|
lowLatency: this.detectedLowLatency,
|
|
@@ -1603,7 +1623,7 @@ var St = class {
|
|
|
1603
1623
|
return;
|
|
1604
1624
|
}
|
|
1605
1625
|
let e = Date.now() - this.lastAdvanceMs;
|
|
1606
|
-
!this.chaseSuspended && e >
|
|
1626
|
+
!this.chaseSuspended && e > lt && this.suspendChasing(), e > st && this.emitEnded("stalled");
|
|
1607
1627
|
}
|
|
1608
1628
|
resetStarvationWindow() {
|
|
1609
1629
|
this.starvedTicks = 0, this.deadTicks = 0, this.mainFragsSinceTick = 0, this.recentMainFrags = [];
|
|
@@ -1618,7 +1638,7 @@ var St = class {
|
|
|
1618
1638
|
this.resetStarvationWindow();
|
|
1619
1639
|
return;
|
|
1620
1640
|
}
|
|
1621
|
-
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs <
|
|
1641
|
+
let n = Date.now(), r = this.lastAdvanceMs !== 0 && n - this.lastAdvanceMs < lt, i = this.lastFragLoadingMs !== 0 && n - this.lastFragLoadingMs > dt, a = t.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !t.paused, { totalFrames: o, dropped: s } = G(t), c = o - s, l = c !== this.starvedFrames;
|
|
1622
1642
|
if (this.starvedFrames = c, !a || l) {
|
|
1623
1643
|
(t.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA || l) && this.clearKick(), this.resetStarvationWindow();
|
|
1624
1644
|
return;
|
|
@@ -1627,12 +1647,12 @@ var St = class {
|
|
|
1627
1647
|
this.resetStarvationWindow();
|
|
1628
1648
|
return;
|
|
1629
1649
|
}
|
|
1630
|
-
if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length >
|
|
1650
|
+
if (this.kickPending && (this.kickKind === "dead" || i) && (this.kickTicks += 1), this.starvedTicks = i ? this.starvedTicks + 1 : 0, this.deadTicks += 1, this.recentMainFrags.push(this.mainFragsSinceTick), this.mainFragsSinceTick = 0, this.recentMainFrags.length > gt && this.recentMainFrags.shift(), this.clearRecoveryReset(), this.kickPending && this.kickTicks >= mt && (this.clearKick(), this.starvationRebuilds < ht)) {
|
|
1631
1651
|
this.starvationRebuilds += 1, this.resetStarvationWindow(), this.clearRecoveryReset(), console.warn("havik-player: restarting the load did not resume video (the wedge is in hls.js state that only a rebuild clears) — rebuilding the player"), this.rebuildInstance("starvation rebuild");
|
|
1632
1652
|
return;
|
|
1633
1653
|
}
|
|
1634
|
-
let u = i && this.starvedTicks >=
|
|
1635
|
-
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >=
|
|
1654
|
+
let u = i && this.starvedTicks >= ft, d = !i && this.deadTicks >= gt && this.recentMainFrags.reduce((e, t) => e + t, 0) >= _t;
|
|
1655
|
+
if ((u || d) && (this.resetStarvationWindow(), !(this.starvationKicks >= pt))) {
|
|
1636
1656
|
this.starvationKicks += 1, this.kickPending = !0, this.kickTicks = 0, this.kickKind = d ? "dead" : "quiet", this.clearRecoveryReset(), console.warn(d ? "havik-player: video starved while hls.js keeps loading media it never plays (dead pipeline at the live edge) — restarting the load" : "havik-player: video starved while the live playlist advances (wedged hls.js fragment pipeline) — restarting the load");
|
|
1637
1657
|
try {
|
|
1638
1658
|
e.stopLoad(), e.startLoad(-1);
|
|
@@ -1681,7 +1701,7 @@ var St = class {
|
|
|
1681
1701
|
scheduleLicenseRetry(t) {
|
|
1682
1702
|
if (t.details !== e.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED && t.details !== e.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED) return !1;
|
|
1683
1703
|
let n = t.response?.code ?? 0;
|
|
1684
|
-
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >=
|
|
1704
|
+
if (!(n === 0 || n === 408 || n === 429 || n >= 500) || this.licenseRecoveries >= at) return !1;
|
|
1685
1705
|
this.licenseRecoveries += 1;
|
|
1686
1706
|
let r = Math.min(8e3, 500 * 2 ** (this.licenseRecoveries - 1));
|
|
1687
1707
|
return this.licenseRetryTimer = setTimeout(() => {
|
|
@@ -1713,7 +1733,7 @@ var St = class {
|
|
|
1713
1733
|
return;
|
|
1714
1734
|
}
|
|
1715
1735
|
if (t.type === e.ErrorTypes.NETWORK_ERROR) {
|
|
1716
|
-
if (this.networkRecoveries <
|
|
1736
|
+
if (this.networkRecoveries < it) {
|
|
1717
1737
|
this.networkRecoveries += 1;
|
|
1718
1738
|
let e = Math.min(8e3, 1e3 * 2 ** (this.networkRecoveries - 1));
|
|
1719
1739
|
this.networkRetryTimer = setTimeout(() => {
|
|
@@ -1730,7 +1750,7 @@ var St = class {
|
|
|
1730
1750
|
return;
|
|
1731
1751
|
}
|
|
1732
1752
|
if (t.type === e.ErrorTypes.MEDIA_ERROR) {
|
|
1733
|
-
if (this.mediaRecoveries <
|
|
1753
|
+
if (this.mediaRecoveries < rt) {
|
|
1734
1754
|
this.mediaRecoveries += 1, n.recoverMediaError();
|
|
1735
1755
|
return;
|
|
1736
1756
|
}
|
|
@@ -1754,19 +1774,19 @@ var St = class {
|
|
|
1754
1774
|
let r = e.response?.code ?? 0, a = e.details ?? e.type, o = e.reason ?? e.error?.message ?? "";
|
|
1755
1775
|
return new n(t === "DRM" ? i(r) : r === 401 ? "UNAUTHORIZED" : r === 403 ? "FORBIDDEN" : "INTERNAL", r, `${t} error: ${a}${o ? ` (${o})` : ""}`);
|
|
1756
1776
|
}
|
|
1757
|
-
},
|
|
1777
|
+
}, Dt = 15e3, Ot = 6e5, kt = 3e5, At = 100, Y = 1, jt = 1e3, Mt = 3e4, Nt = 1e3, Pt = {
|
|
1758
1778
|
inline: "PRESENTATION_INLINE",
|
|
1759
1779
|
fullscreen: "PRESENTATION_FULLSCREEN",
|
|
1760
1780
|
pip: "PRESENTATION_PIP"
|
|
1761
|
-
},
|
|
1781
|
+
}, Ft = {
|
|
1762
1782
|
widevine: "KEY_SYSTEM_WIDEVINE",
|
|
1763
1783
|
fairplay: "KEY_SYSTEM_FAIRPLAY",
|
|
1764
1784
|
none: "KEY_SYSTEM_NONE"
|
|
1765
1785
|
};
|
|
1766
|
-
function
|
|
1786
|
+
function It(e, t) {
|
|
1767
1787
|
return e.length === 0 ? 0 : e[Math.min(e.length, Math.max(1, Math.ceil(t / 100 * e.length))) - 1] ?? 0;
|
|
1768
1788
|
}
|
|
1769
|
-
var
|
|
1789
|
+
var Lt = /* @__PURE__ */ new Set([
|
|
1770
1790
|
"INVALID_URN",
|
|
1771
1791
|
"NOT_FOUND",
|
|
1772
1792
|
"GONE",
|
|
@@ -1776,7 +1796,7 @@ var Nt = /* @__PURE__ */ new Set([
|
|
|
1776
1796
|
"FORBIDDEN",
|
|
1777
1797
|
"RATE_LIMITED",
|
|
1778
1798
|
"TIMEOUT"
|
|
1779
|
-
]),
|
|
1799
|
+
]), X = {
|
|
1780
1800
|
idle: "PLAYER_STATE_IDLE",
|
|
1781
1801
|
waiting: "PLAYER_STATE_WAITING",
|
|
1782
1802
|
loading: "PLAYER_STATE_LOADING",
|
|
@@ -1786,7 +1806,7 @@ var Nt = /* @__PURE__ */ new Set([
|
|
|
1786
1806
|
ended: "PLAYER_STATE_ENDED",
|
|
1787
1807
|
error: "PLAYER_STATE_ERROR"
|
|
1788
1808
|
};
|
|
1789
|
-
function
|
|
1809
|
+
function Rt(e) {
|
|
1790
1810
|
try {
|
|
1791
1811
|
let t = new URL(e), [n, ...r] = t.hostname.split(".");
|
|
1792
1812
|
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);
|
|
@@ -1794,24 +1814,25 @@ function Pt(e) {
|
|
|
1794
1814
|
return;
|
|
1795
1815
|
}
|
|
1796
1816
|
}
|
|
1797
|
-
var
|
|
1798
|
-
function
|
|
1799
|
-
return
|
|
1817
|
+
var zt = (e, t) => e.replace(/\/$/, "").toLowerCase() === t.replace(/\/$/, "").toLowerCase();
|
|
1818
|
+
function Bt(e, t) {
|
|
1819
|
+
return g(t, e), { disabledReason: t };
|
|
1800
1820
|
}
|
|
1801
|
-
function
|
|
1821
|
+
function Vt(e, t, n) {
|
|
1822
|
+
if (n) return t && !zt(t, n) && g(`analytics.endpoint "${t}" ignored; the server named "${n}".`), { endpoint: n };
|
|
1802
1823
|
if (t) return { endpoint: t };
|
|
1803
|
-
if (t !== void 0) return
|
|
1804
|
-
let
|
|
1805
|
-
if (
|
|
1806
|
-
let
|
|
1824
|
+
if (t !== void 0) return Bt("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).");
|
|
1825
|
+
let r = Rt(e);
|
|
1826
|
+
if (r) return { endpoint: r };
|
|
1827
|
+
let i;
|
|
1807
1828
|
try {
|
|
1808
|
-
|
|
1829
|
+
i = new URL(e).hostname || e;
|
|
1809
1830
|
} catch {
|
|
1810
|
-
|
|
1831
|
+
i = e;
|
|
1811
1832
|
}
|
|
1812
|
-
return
|
|
1833
|
+
return Bt(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).`);
|
|
1813
1834
|
}
|
|
1814
|
-
var
|
|
1835
|
+
var Ht = class {
|
|
1815
1836
|
opts;
|
|
1816
1837
|
url;
|
|
1817
1838
|
now;
|
|
@@ -1891,8 +1912,8 @@ var Rt = class {
|
|
|
1891
1912
|
constructor(e) {
|
|
1892
1913
|
this.opts = {
|
|
1893
1914
|
...e,
|
|
1894
|
-
heartbeatMs: e.heartbeatMs ??
|
|
1895
|
-
idleMs: e.idleMs ??
|
|
1915
|
+
heartbeatMs: e.heartbeatMs ?? Dt,
|
|
1916
|
+
idleMs: e.idleMs ?? Ot
|
|
1896
1917
|
}, this.url = `${e.endpoint.replace(/\/$/, "")}/v1/beacons`, this.now = e.now ?? (() => Date.now()), this.bornMs = this.now(), this.presentationSinceMs = this.bornMs, this.startupAnchorMs = this.bornMs;
|
|
1897
1918
|
}
|
|
1898
1919
|
start() {
|
|
@@ -1902,11 +1923,11 @@ var Rt = class {
|
|
|
1902
1923
|
sdkVersion: this.opts.sdkVersion,
|
|
1903
1924
|
...this.opts.environment
|
|
1904
1925
|
};
|
|
1905
|
-
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(),
|
|
1926
|
+
this.pendingStart = e, this.enqueue({ sessionStart: e }), this.firstFlushTimer = setTimeout(() => this.flush(), jt), 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.onVisibility());
|
|
1906
1927
|
}
|
|
1907
1928
|
checkSuspension(e) {
|
|
1908
1929
|
if (this.endedFlag || !this.opts.idleMs) return !1;
|
|
1909
|
-
let t = Math.max(this.opts.idleMs,
|
|
1930
|
+
let t = Math.max(this.opts.idleMs, kt);
|
|
1910
1931
|
return this.lastTickMs > 0 && e - this.lastTickMs >= t ? (this.endIdle(this.lastTickMs), !0) : (this.lastTickMs = e, !1);
|
|
1911
1932
|
}
|
|
1912
1933
|
syncIdle(e) {
|
|
@@ -1920,21 +1941,21 @@ var Rt = class {
|
|
|
1920
1941
|
noteStateChange(e, t, n, r) {
|
|
1921
1942
|
if (this.endedFlag || e === t) return;
|
|
1922
1943
|
let i = this.now();
|
|
1923
|
-
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(
|
|
1944
|
+
if (t === "playing" ? (this.playingSinceMs === null && (this.playingSinceMs = i), this.startupTimeMs === 0 && (this.startupTimeMs = Math.max(Y, i - this.startupAnchorMs)), this.firstAudioMs === 0 && !this.isMuted && (this.firstAudioMs = Math.max(Y, i - this.startupAnchorMs)), this.isMuted && this.mutedSinceMs === null && (this.mutedSinceMs = i)) : this.playingSinceMs !== null && (this.playingTotalMs += i - this.playingSinceMs, this.playingSinceMs = null, this.mutedSinceMs !== null && (this.mutedTotalMs += i - this.mutedSinceMs, this.mutedSinceMs = null)), this.isPlaying = t === "playing", this.syncActive(), t === "waiting" ? this.waitingSinceMs = i : this.waitingSinceMs !== null && (this.waitingTotalMs += i - this.waitingSinceMs, this.waitingSinceMs = null), t === "buffering" && e === "playing") {
|
|
1924
1945
|
this.stallIsSeekInduced = this.seekInduced(i);
|
|
1925
1946
|
let e = !this.isHidden && !this.stallIsSeekInduced;
|
|
1926
|
-
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(
|
|
1947
|
+
e && (this.rebufferCount += 1), this.isBuffering = !0, this.lastStallMs = i, e && this.timeToFirstStallMs === 0 && (this.timeToFirstStallMs = Math.max(Y, Math.round(this.playingTotalMs)));
|
|
1927
1948
|
} else e === "buffering" && (this.isBuffering = !1, this.stallIsSeekInduced = !1);
|
|
1928
1949
|
this.syncBuffering(), t === "paused" && (this.pauseCount += 1), this.syncIdle(t);
|
|
1929
1950
|
let a = {
|
|
1930
|
-
fromState:
|
|
1931
|
-
toState:
|
|
1932
|
-
presentation:
|
|
1951
|
+
fromState: X[e] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1952
|
+
toState: X[t] ?? "PLAYER_STATE_UNSPECIFIED",
|
|
1953
|
+
presentation: Pt[this.presentation]
|
|
1933
1954
|
}, o = this.causeOf(e, t, i);
|
|
1934
1955
|
o && (a.cause = o), n > 0 && (a.positionMs = Math.round(n)), r && (a.renditionHeight = r), this.enqueue({ stateChange: a });
|
|
1935
1956
|
}
|
|
1936
1957
|
seekInduced(e) {
|
|
1937
|
-
return this.lastSeekMs >= 0 && e - this.lastSeekMs <
|
|
1958
|
+
return this.lastSeekMs >= 0 && e - this.lastSeekMs < Nt;
|
|
1938
1959
|
}
|
|
1939
1960
|
causeOf(e, t, n) {
|
|
1940
1961
|
if (t === "error") return "TRANSITION_CAUSE_ERROR";
|
|
@@ -1971,25 +1992,25 @@ var Rt = class {
|
|
|
1971
1992
|
}
|
|
1972
1993
|
this.muteChanges += 1;
|
|
1973
1994
|
let r = this.now();
|
|
1974
|
-
n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(
|
|
1995
|
+
n ? this.isPlaying && this.mutedSinceMs === null && (this.mutedSinceMs = r) : (this.mutedSinceMs !== null && (this.mutedTotalMs += r - this.mutedSinceMs, this.mutedSinceMs = null), this.firstAudioMs === 0 && this.isPlaying && (this.firstAudioMs = Math.max(Y, r - this.startupAnchorMs))), this.isMuted = n, this.syncActive();
|
|
1975
1996
|
}
|
|
1976
1997
|
notePresentation(e) {
|
|
1977
1998
|
this.endedFlag || e === this.presentation || (this.closePresentation(), this.presentation = e);
|
|
1978
1999
|
}
|
|
1979
2000
|
notePlayIntent() {
|
|
1980
|
-
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs =
|
|
2001
|
+
this.endedFlag || this.startupTimeMs > 0 || (this.startupAnchorMs = this.now(), this.manifestLoadMs > 0 && (this.manifestLoadMs = Y), this.firstPlaylistMs > 0 && (this.firstPlaylistMs = Y), this.firstFragLoadMs > 0 && (this.firstFragLoadMs = Y), this.drmSetupMs > 0 && (this.drmSetupMs = Y));
|
|
1981
2002
|
}
|
|
1982
2003
|
noteReady() {
|
|
1983
|
-
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(
|
|
2004
|
+
this.manifestLoadMs === 0 && (this.manifestLoadMs = Math.max(Y, this.now() - this.startupAnchorMs));
|
|
1984
2005
|
}
|
|
1985
2006
|
noteFirstPlaylist() {
|
|
1986
|
-
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(
|
|
2007
|
+
this.firstPlaylistMs === 0 && (this.firstPlaylistMs = Math.max(Y, this.now() - this.startupAnchorMs));
|
|
1987
2008
|
}
|
|
1988
2009
|
noteDrmReady() {
|
|
1989
|
-
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(
|
|
2010
|
+
this.drmSetupMs === 0 && (this.drmSetupMs = Math.max(Y, this.now() - this.startupAnchorMs));
|
|
1990
2011
|
}
|
|
1991
2012
|
noteFirstBytes() {
|
|
1992
|
-
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(
|
|
2013
|
+
this.sawFirstBytes = !0, this.firstFragLoadMs === 0 && (this.firstFragLoadMs = Math.max(Y, this.now() - this.startupAnchorMs));
|
|
1993
2014
|
}
|
|
1994
2015
|
noteSeek() {
|
|
1995
2016
|
this.endedFlag || (this.seekCount += 1, this.lastSeekMs = this.now());
|
|
@@ -2008,7 +2029,7 @@ var Rt = class {
|
|
|
2008
2029
|
let r = n ?? "";
|
|
2009
2030
|
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";
|
|
2010
2031
|
if (e === "DRM_CLIENT") return "ERROR_STAGE_DRM";
|
|
2011
|
-
if (
|
|
2032
|
+
if (Lt.has(e)) return "ERROR_STAGE_RESOLVE";
|
|
2012
2033
|
let i = t ?? "";
|
|
2013
2034
|
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";
|
|
2014
2035
|
}
|
|
@@ -2040,7 +2061,7 @@ var Rt = class {
|
|
|
2040
2061
|
let l = t.droppedFrames ?? 0;
|
|
2041
2062
|
l > this.lastDropped && (o.droppedFramesDelta = l - this.lastDropped), this.lastDropped = l;
|
|
2042
2063
|
let u = t.renditionSwitches ?? 0;
|
|
2043
|
-
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 =
|
|
2064
|
+
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 = X[t.state] ?? "PLAYER_STATE_UNSPECIFIED";
|
|
2044
2065
|
let d = this.mutedTotalMs;
|
|
2045
2066
|
this.mutedSinceMs !== null && (d += e - this.mutedSinceMs), d > this.lastHbMutedMs && (o.mutedMsDelta = Math.round(d - this.lastHbMutedMs)), this.lastHbMutedMs = d;
|
|
2046
2067
|
let f = t.upshifts ?? 0;
|
|
@@ -2055,14 +2076,14 @@ var Rt = class {
|
|
|
2055
2076
|
if (this.lastRequestCount = g, _ > 0) {
|
|
2056
2077
|
o.requestCountDelta = _;
|
|
2057
2078
|
let e = t.requestTimesMs ?? [], n = e.slice(Math.max(0, e.length - _)).sort((e, t) => e - t);
|
|
2058
|
-
n.length > 0 && (o.requestTimeP50Ms =
|
|
2079
|
+
n.length > 0 && (o.requestTimeP50Ms = It(n, 50), o.requestTimeP95Ms = It(n, 95));
|
|
2059
2080
|
}
|
|
2060
2081
|
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();
|
|
2061
2082
|
}
|
|
2062
2083
|
maybeEmitMediaInfo(e) {
|
|
2063
2084
|
if (!(e.videoCodec ?? e.keySystem ?? e.ladderHeights)) return;
|
|
2064
2085
|
let t = {};
|
|
2065
|
-
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem =
|
|
2086
|
+
e.videoCodec && (t.videoCodec = e.videoCodec), e.audioCodec && (t.audioCodec = e.audioCodec), e.keySystem && (t.keySystem = Ft[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);
|
|
2066
2087
|
let n = JSON.stringify(t);
|
|
2067
2088
|
n !== this.mediaInfoSignature && (this.mediaInfoSignature = n, this.enqueue({ mediaInfo: t }));
|
|
2068
2089
|
}
|
|
@@ -2082,7 +2103,7 @@ var Rt = class {
|
|
|
2082
2103
|
let c = r?.positionMs ?? 0;
|
|
2083
2104
|
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));
|
|
2084
2105
|
let l = e !== "END_REASON_ENDED";
|
|
2085
|
-
l && this.lastStallMs > 0 && n - this.lastStallMs <=
|
|
2106
|
+
l && this.lastStallMs > 0 && n - this.lastStallMs <= Mt && (i.abandonAfterStallMs = Math.max(Y, Math.round(n - this.lastStallMs))), l && this.lastErrorMs > 0 && n - this.lastErrorMs <= Mt && (i.abandonAfterErrorMs = Math.max(Y, 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);
|
|
2086
2107
|
let u = r?.decodedFrames ?? this.lastDecoded;
|
|
2087
2108
|
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");
|
|
2088
2109
|
}
|
|
@@ -2102,7 +2123,7 @@ var Rt = class {
|
|
|
2102
2123
|
};
|
|
2103
2124
|
}
|
|
2104
2125
|
enqueue(e) {
|
|
2105
|
-
for (this.pending.push(this.wrap(e)); this.pending.length >
|
|
2126
|
+
for (this.pending.push(this.wrap(e)); this.pending.length > At;) {
|
|
2106
2127
|
let e = this.pending.findIndex((e) => e.heartbeat || e.stateChange);
|
|
2107
2128
|
this.pending.splice(e >= 0 ? e : 0, 1);
|
|
2108
2129
|
}
|
|
@@ -2125,7 +2146,7 @@ var Rt = class {
|
|
|
2125
2146
|
};
|
|
2126
2147
|
//#endregion
|
|
2127
2148
|
//#region src/core/environment.ts
|
|
2128
|
-
function
|
|
2149
|
+
function Ut() {
|
|
2129
2150
|
if (typeof window > "u") return { integration: "INTEGRATION_KIND_SDK" };
|
|
2130
2151
|
let e;
|
|
2131
2152
|
try {
|
|
@@ -2150,14 +2171,14 @@ function zt() {
|
|
|
2150
2171
|
integration: "INTEGRATION_KIND_IFRAME"
|
|
2151
2172
|
};
|
|
2152
2173
|
}
|
|
2153
|
-
function
|
|
2174
|
+
function Wt() {
|
|
2154
2175
|
if (typeof navigator > "u") return "DEVICE_CLASS_OTHER";
|
|
2155
2176
|
let e = navigator.userAgentData, t = e?.platform ?? "";
|
|
2156
2177
|
if (/tv|tizen|webos/i.test(t)) return "DEVICE_CLASS_TV";
|
|
2157
2178
|
let n = typeof screen < "u" ? Math.min(screen.width, screen.height) : 0;
|
|
2158
2179
|
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";
|
|
2159
2180
|
}
|
|
2160
|
-
function
|
|
2181
|
+
function Gt() {
|
|
2161
2182
|
let e = typeof navigator < "u" ? navigator.connection : void 0;
|
|
2162
2183
|
if (!e) return { connectionType: "CONNECTION_TYPE_UNKNOWN" };
|
|
2163
2184
|
let t = {
|
|
@@ -2176,17 +2197,17 @@ function Vt() {
|
|
|
2176
2197
|
}
|
|
2177
2198
|
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;
|
|
2178
2199
|
}
|
|
2179
|
-
function
|
|
2180
|
-
let t =
|
|
2181
|
-
deviceClass:
|
|
2200
|
+
function Kt(e) {
|
|
2201
|
+
let t = Ut(), n = {
|
|
2202
|
+
deviceClass: Wt(),
|
|
2182
2203
|
integration: t.integration,
|
|
2183
|
-
...
|
|
2204
|
+
...Gt()
|
|
2184
2205
|
};
|
|
2185
2206
|
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);
|
|
2186
2207
|
let r = e.getBoundingClientRect?.();
|
|
2187
2208
|
return r && r.width > 0 && (n.viewportWidth = Math.round(r.width), n.viewportHeight = Math.round(r.height)), n;
|
|
2188
2209
|
}
|
|
2189
|
-
async function
|
|
2210
|
+
async function qt() {
|
|
2190
2211
|
let e = typeof navigator < "u" ? navigator.userAgentData : void 0;
|
|
2191
2212
|
if (!e?.getHighEntropyValues) return {};
|
|
2192
2213
|
try {
|
|
@@ -2198,7 +2219,7 @@ async function Ut() {
|
|
|
2198
2219
|
}
|
|
2199
2220
|
//#endregion
|
|
2200
2221
|
//#region src/core/version.ts
|
|
2201
|
-
var
|
|
2222
|
+
var Jt = "2.12.0", Yt = {
|
|
2202
2223
|
accent: "#E1B600",
|
|
2203
2224
|
accentText: "#1B1C23",
|
|
2204
2225
|
background: "#0e0f13",
|
|
@@ -2209,7 +2230,7 @@ var Wt = "2.11.1", Gt = {
|
|
|
2209
2230
|
border: "rgba(255, 255, 255, 0.1)",
|
|
2210
2231
|
radius: "8px",
|
|
2211
2232
|
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
2212
|
-
},
|
|
2233
|
+
}, Xt = {
|
|
2213
2234
|
accent: "--havik-accent",
|
|
2214
2235
|
accentText: "--havik-accent-text",
|
|
2215
2236
|
background: "--havik-bg",
|
|
@@ -2221,25 +2242,25 @@ var Wt = "2.11.1", Gt = {
|
|
|
2221
2242
|
radius: "--havik-radius",
|
|
2222
2243
|
fontFamily: "--havik-font"
|
|
2223
2244
|
};
|
|
2224
|
-
function
|
|
2245
|
+
function Zt(e, t) {
|
|
2225
2246
|
let n = {
|
|
2226
|
-
...
|
|
2247
|
+
...Yt,
|
|
2227
2248
|
...t
|
|
2228
2249
|
};
|
|
2229
|
-
for (let t of Object.keys(
|
|
2250
|
+
for (let t of Object.keys(Xt)) e.style.setProperty(Xt[t], n[t]);
|
|
2230
2251
|
n.logoUrl && e.style.setProperty("--havik-logo", `url("${n.logoUrl}")`);
|
|
2231
2252
|
}
|
|
2232
2253
|
//#endregion
|
|
2233
2254
|
//#region src/ui/styles.ts
|
|
2234
|
-
var
|
|
2235
|
-
function
|
|
2236
|
-
if (e.getElementById(
|
|
2255
|
+
var Qt = "havik-player-styles", $t = "\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.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";
|
|
2256
|
+
function en(e = document) {
|
|
2257
|
+
if (e.getElementById(Qt)) return;
|
|
2237
2258
|
let t = e.createElement("style");
|
|
2238
|
-
t.id =
|
|
2259
|
+
t.id = Qt, t.textContent = $t, e.head.appendChild(t);
|
|
2239
2260
|
}
|
|
2240
2261
|
//#endregion
|
|
2241
2262
|
//#region src/ui/icons.ts
|
|
2242
|
-
var
|
|
2263
|
+
var tn = {
|
|
2243
2264
|
play: "<path d=\"M8 5v14l11-7z\"/>",
|
|
2244
2265
|
pause: "<path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/>",
|
|
2245
2266
|
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\"/>",
|
|
@@ -2252,21 +2273,21 @@ var Zt = {
|
|
|
2252
2273
|
liveDot: "<circle cx=\"12\" cy=\"12\" r=\"6\"/>",
|
|
2253
2274
|
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\"/>"
|
|
2254
2275
|
};
|
|
2255
|
-
function
|
|
2256
|
-
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${
|
|
2276
|
+
function Z(e) {
|
|
2277
|
+
return `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${tn[e]}</svg>`;
|
|
2257
2278
|
}
|
|
2258
2279
|
//#endregion
|
|
2259
2280
|
//#region src/ui/controls.ts
|
|
2260
|
-
var
|
|
2281
|
+
var nn = 3e3, rn = /* @__PURE__ */ new Set([
|
|
2261
2282
|
"GONE",
|
|
2262
2283
|
"NOT_FOUND",
|
|
2263
2284
|
"INVALID_URN",
|
|
2264
2285
|
"UNAUTHORIZED"
|
|
2265
2286
|
]);
|
|
2266
|
-
function
|
|
2267
|
-
return new
|
|
2287
|
+
function an(e) {
|
|
2288
|
+
return new on(e);
|
|
2268
2289
|
}
|
|
2269
|
-
var
|
|
2290
|
+
var on = class {
|
|
2270
2291
|
root;
|
|
2271
2292
|
video;
|
|
2272
2293
|
player;
|
|
@@ -2308,7 +2329,7 @@ var tn = class {
|
|
|
2308
2329
|
scrubbing = !1;
|
|
2309
2330
|
offFns = [];
|
|
2310
2331
|
constructor(e) {
|
|
2311
|
-
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ??
|
|
2332
|
+
this.root = e.root, this.video = e.video, this.player = e.player, this.doc = e.root.ownerDocument ?? document, this.autoHideMs = e.autoHideMs ?? nn, this.logoUrl = e.logoUrl, this.statusOverlays = e.statusOverlays !== !1, this.endedMessage = e.endedMessage ?? "This stream has ended", this.interruptedMessage = e.interruptedMessage ?? "Reconnecting — please stand by", this.errorMessage = e.errorMessage, en(this.doc), 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");
|
|
2312
2333
|
let t = (e, t, n) => {
|
|
2313
2334
|
let r = this.doc.createElement(e);
|
|
2314
2335
|
if (r.className = t, n) for (let [e, t] of Object.entries(n)) r.setAttribute(e, t);
|
|
@@ -2319,12 +2340,12 @@ var tn = class {
|
|
|
2319
2340
|
"aria-label": r,
|
|
2320
2341
|
title: r
|
|
2321
2342
|
});
|
|
2322
|
-
return i.innerHTML =
|
|
2343
|
+
return i.innerHTML = Z(n), i;
|
|
2323
2344
|
};
|
|
2324
2345
|
this.overlay = t("div", "havik-overlay"), this.center = t("button", "havik-center", {
|
|
2325
2346
|
type: "button",
|
|
2326
2347
|
"aria-label": "Play"
|
|
2327
|
-
}), this.center.innerHTML =
|
|
2348
|
+
}), this.center.innerHTML = Z("play"), this.spinner = t("div", "havik-spinner"), this.spinner.style.display = "none", this.overlay.append(this.center, this.spinner), this.gradient = t("div", "havik-gradient"), this.bar = t("div", "havik-bar"), this.seek = t("div", "havik-seek", {
|
|
2328
2349
|
role: "slider",
|
|
2329
2350
|
"aria-label": "Seek",
|
|
2330
2351
|
"aria-valuemin": "0",
|
|
@@ -2342,7 +2363,7 @@ var tn = class {
|
|
|
2342
2363
|
"aria-label": "Volume"
|
|
2343
2364
|
});
|
|
2344
2365
|
let a = t("div", "havik-vol");
|
|
2345
|
-
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML =
|
|
2366
|
+
a.append(this.muteBtn, this.volSlider), this.live = t("div", "havik-live"), this.live.innerHTML = Z("liveDot");
|
|
2346
2367
|
let o = this.doc.createElement("span");
|
|
2347
2368
|
o.textContent = "LIVE", this.liveGo = t("button", "havik-live__go", { type: "button" }), this.liveGo.textContent = "Go live", this.live.append(o, this.liveGo), this.time = t("div", "havik-time"), this.time.textContent = "0:00", this.time.style.display = "none";
|
|
2348
2369
|
let s = t("div", "havik-spacer");
|
|
@@ -2396,12 +2417,12 @@ var tn = class {
|
|
|
2396
2417
|
}
|
|
2397
2418
|
if (e === "preplay") {
|
|
2398
2419
|
let e = this.doc.createElement("button");
|
|
2399
|
-
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML =
|
|
2420
|
+
e.type = "button", e.className = "havik-status__btn havik-status__btn--play", e.setAttribute("aria-label", "Play"), e.innerHTML = Z("play"), e.addEventListener("click", () => void this.player.play()), n.append(e);
|
|
2400
2421
|
} else {
|
|
2401
2422
|
let r = this.doc.createElement("div");
|
|
2402
|
-
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError &&
|
|
2423
|
+
if (r.className = "havik-status__msg", r.textContent = t ?? "", n.append(r), e === "error" && this.lastError && !rn.has(this.lastError.code)) {
|
|
2403
2424
|
let e = this.doc.createElement("button");
|
|
2404
|
-
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${
|
|
2425
|
+
e.type = "button", e.className = "havik-status__btn", e.innerHTML = `${Z("retry")}<span>Retry</span>`, e.addEventListener("click", () => void this.player.retry()), n.append(e);
|
|
2405
2426
|
}
|
|
2406
2427
|
}
|
|
2407
2428
|
this.root.append(n), this.statusBox = n, this.show();
|
|
@@ -2440,7 +2461,7 @@ var tn = class {
|
|
|
2440
2461
|
let n = r.end(r.length - 1), i = Math.min(1, Math.max(0, (n - e.start) / t));
|
|
2441
2462
|
this.seekBuffered.style.width = `${(i * 100).toFixed(2)}%`;
|
|
2442
2463
|
}
|
|
2443
|
-
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${
|
|
2464
|
+
!this.player.getStats().isLive && Number.isFinite(this.video.duration) && (this.time.textContent = `${Q(this.video.currentTime)} / ${Q(this.video.duration)}`);
|
|
2444
2465
|
}
|
|
2445
2466
|
syncLive() {
|
|
2446
2467
|
let e = this.player.getStats(), t = e.isLive !== !1;
|
|
@@ -2490,17 +2511,17 @@ var tn = class {
|
|
|
2490
2511
|
renderQualityMenu() {
|
|
2491
2512
|
let e = this.player.getQualityLevels(), t = this.player.getCurrentQuality(), n = this.doc.createElement("div");
|
|
2492
2513
|
n.className = "havik-menu__title", n.textContent = "Quality", this.menu.replaceChildren(n, this.menuItem("Auto", t === -1, () => this.player.setQuality("auto")));
|
|
2493
|
-
for (let n of e) this.menu.append(this.menuItem(
|
|
2514
|
+
for (let n of e) this.menu.append(this.menuItem(sn(n), t === n.index, () => this.player.setQuality(n.index)));
|
|
2494
2515
|
}
|
|
2495
2516
|
renderAudioMenu() {
|
|
2496
2517
|
let e = this.player.getAudioTracks(), t = this.doc.createElement("div");
|
|
2497
2518
|
t.className = "havik-menu__title", t.textContent = "Audio", this.menu.replaceChildren(t);
|
|
2498
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2519
|
+
for (let t of e) this.menu.append(this.menuItem(cn(t), t.default, () => this.player.setAudioTrack(t.id)));
|
|
2499
2520
|
}
|
|
2500
2521
|
renderCcMenu() {
|
|
2501
2522
|
let e = this.player.getTextTracks(), t = this.doc.createElement("div");
|
|
2502
2523
|
t.className = "havik-menu__title", t.textContent = "Subtitles", this.menu.replaceChildren(t, this.menuItem("Off", !1, () => this.player.setTextTrack(-1)));
|
|
2503
|
-
for (let t of e) this.menu.append(this.menuItem(
|
|
2524
|
+
for (let t of e) this.menu.append(this.menuItem(ln(t), !1, () => this.player.setTextTrack(t.id)));
|
|
2504
2525
|
}
|
|
2505
2526
|
onTracksChanged() {
|
|
2506
2527
|
this.openMenu && this.renderMenu(this.openMenu);
|
|
@@ -2520,11 +2541,11 @@ var tn = class {
|
|
|
2520
2541
|
}
|
|
2521
2542
|
async toggleFullscreen() {
|
|
2522
2543
|
try {
|
|
2523
|
-
|
|
2544
|
+
x(this.video, this.root) ? await C(this.video, this.root) : await S(this.video, this.root);
|
|
2524
2545
|
} catch {}
|
|
2525
2546
|
}
|
|
2526
2547
|
syncFullscreen() {
|
|
2527
|
-
let e =
|
|
2548
|
+
let e = x(this.video, this.root);
|
|
2528
2549
|
this.setIcon(this.fsBtn, e ? "fullscreenExit" : "fullscreen"), this.fsBtn.setAttribute("aria-label", e ? "Exit fullscreen" : "Fullscreen");
|
|
2529
2550
|
}
|
|
2530
2551
|
poke() {
|
|
@@ -2583,7 +2604,7 @@ var tn = class {
|
|
|
2583
2604
|
}
|
|
2584
2605
|
}
|
|
2585
2606
|
setIcon(e, t) {
|
|
2586
|
-
e.innerHTML =
|
|
2607
|
+
e.innerHTML = Z(t);
|
|
2587
2608
|
}
|
|
2588
2609
|
destroy() {
|
|
2589
2610
|
this.hideTimer && clearTimeout(this.hideTimer);
|
|
@@ -2600,41 +2621,41 @@ var tn = class {
|
|
|
2600
2621
|
this.root.classList.remove("havik-player", "havik-hide", "havik-has-status");
|
|
2601
2622
|
}
|
|
2602
2623
|
};
|
|
2603
|
-
function
|
|
2624
|
+
function Q(e) {
|
|
2604
2625
|
(!Number.isFinite(e) || e < 0) && (e = 0);
|
|
2605
2626
|
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");
|
|
2606
2627
|
return r > 0 ? `${r}:${i}:${a}` : `${i}:${a}`;
|
|
2607
2628
|
}
|
|
2608
|
-
function
|
|
2629
|
+
function sn(e) {
|
|
2609
2630
|
return e.height ? `${e.height}p` : `${Math.round(e.bitrate / 1e3)} kbps`;
|
|
2610
2631
|
}
|
|
2611
|
-
function
|
|
2632
|
+
function cn(e) {
|
|
2612
2633
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2613
2634
|
}
|
|
2614
|
-
function
|
|
2635
|
+
function ln(e) {
|
|
2615
2636
|
return e.name || e.lang || `Track ${e.id}`;
|
|
2616
2637
|
}
|
|
2617
2638
|
//#endregion
|
|
2618
2639
|
//#region src/managed/index.ts
|
|
2619
|
-
var
|
|
2620
|
-
function
|
|
2640
|
+
var un = 6e3, dn = 45e3, fn = 2e3, pn = 3, mn = 2e3, hn = 48e4;
|
|
2641
|
+
function gn(e) {
|
|
2621
2642
|
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)})`);
|
|
2622
|
-
if (e.env !== void 0) return
|
|
2643
|
+
if (e.env !== void 0) return H(e.env);
|
|
2623
2644
|
if (!e.baseUrl) throw new n("INTERNAL", 0, "createPlayer: env or baseUrl is required (env: 'integration' | 'production')");
|
|
2624
2645
|
return e.baseUrl;
|
|
2625
2646
|
}
|
|
2626
|
-
async function
|
|
2647
|
+
async function _n(e) {
|
|
2627
2648
|
if (!e.video || typeof e.video.play != "function") throw new n("INTERNAL", 0, "createPlayer: opts.video must be an HTMLVideoElement");
|
|
2628
|
-
let t =
|
|
2649
|
+
let t = gn(e);
|
|
2629
2650
|
if (!e.matchUrn) throw new n("INVALID_URN", 0, "createPlayer: matchUrn is required");
|
|
2630
2651
|
if (!e.credential) throw new n("INTERNAL", 0, "createPlayer: credential is required");
|
|
2631
|
-
let r = new
|
|
2652
|
+
let r = new vn({
|
|
2632
2653
|
...e,
|
|
2633
2654
|
baseUrl: t
|
|
2634
2655
|
});
|
|
2635
2656
|
return await r.start(), r;
|
|
2636
2657
|
}
|
|
2637
|
-
var
|
|
2658
|
+
var vn = class {
|
|
2638
2659
|
opts;
|
|
2639
2660
|
abort = new AbortController();
|
|
2640
2661
|
listeners = {};
|
|
@@ -2678,7 +2699,7 @@ var hn = class {
|
|
|
2678
2699
|
this.opts.muted && (this.opts.video.muted = !0), this.opts.poster && (this.opts.video.poster = this.opts.poster), this.mountControls(), this.attachPipListeners(), this.setState("loading");
|
|
2679
2700
|
let e = ++this.loadGen, t = this.resolveOptions();
|
|
2680
2701
|
try {
|
|
2681
|
-
let n = await
|
|
2702
|
+
let n = await v(t);
|
|
2682
2703
|
if (await this.onResolved(n, e), e === this.loadGen && this._state === "error" && this._lastError) {
|
|
2683
2704
|
let e = this._lastError;
|
|
2684
2705
|
throw this.destroy(), e;
|
|
@@ -2701,11 +2722,11 @@ var hn = class {
|
|
|
2701
2722
|
};
|
|
2702
2723
|
}
|
|
2703
2724
|
beginArming(e, t, n = !1) {
|
|
2704
|
-
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ??
|
|
2725
|
+
let r = this.opts.liveStateEvents === !1 ? void 0 : this.opts.eventsBaseUrl ?? T(this.opts.baseUrl);
|
|
2705
2726
|
r ? this.armWithSse(e, r, t, n) : this.beginArmingByPolling(e);
|
|
2706
2727
|
}
|
|
2707
2728
|
beginArmingByPolling(e) {
|
|
2708
|
-
|
|
2729
|
+
y({
|
|
2709
2730
|
...this.resolveOptions(),
|
|
2710
2731
|
signal: this.abort.signal,
|
|
2711
2732
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -2722,7 +2743,7 @@ var hn = class {
|
|
|
2722
2743
|
setTimeout(() => {
|
|
2723
2744
|
a || this.destroyed || e !== this.loadGen || this.emit("waiting", {
|
|
2724
2745
|
phase: i ? "unavailable" : "tooEarly",
|
|
2725
|
-
retryInMs:
|
|
2746
|
+
retryInMs: dn,
|
|
2726
2747
|
attempt: 1,
|
|
2727
2748
|
elapsedMs: 0,
|
|
2728
2749
|
...!i && f !== void 0 && f > Date.now() ? { ttkMs: f - Date.now() } : {}
|
|
@@ -2739,7 +2760,7 @@ var hn = class {
|
|
|
2739
2760
|
}
|
|
2740
2761
|
}
|
|
2741
2762
|
}, h = () => {
|
|
2742
|
-
a || s || p() || (s = !0,
|
|
2763
|
+
a || s || p() || (s = !0, y({
|
|
2743
2764
|
...this.resolveOptions(),
|
|
2744
2765
|
signal: c.signal,
|
|
2745
2766
|
waitForLive: this.buildWaitConfig(e)
|
|
@@ -2747,7 +2768,7 @@ var hn = class {
|
|
|
2747
2768
|
a || p() || c.signal.aborted || (a = !0, this.closeArming(), this.fail(e instanceof n ? e : new n("INTERNAL", 0, String(e))));
|
|
2748
2769
|
}));
|
|
2749
2770
|
}, g = () => {
|
|
2750
|
-
a || p() ||
|
|
2771
|
+
a || p() || v(this.resolveOptions()).then((e) => m(e)).catch((e) => {
|
|
2751
2772
|
if (!(a || p())) {
|
|
2752
2773
|
if (e instanceof n && o(e.code)) {
|
|
2753
2774
|
h();
|
|
@@ -2761,13 +2782,13 @@ var hn = class {
|
|
|
2761
2782
|
!a && !p() && h();
|
|
2762
2783
|
}, e);
|
|
2763
2784
|
};
|
|
2764
|
-
_(
|
|
2785
|
+
_(un), this.armingSub = w({
|
|
2765
2786
|
eventsBaseUrl: t,
|
|
2766
2787
|
matchUrn: this.opts.matchUrn,
|
|
2767
2788
|
credential: this.opts.credential,
|
|
2768
|
-
onAlive: () => _(
|
|
2789
|
+
onAlive: () => _(dn),
|
|
2769
2790
|
onState: (e) => {
|
|
2770
|
-
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() *
|
|
2791
|
+
a || p() || (e.state === "live" || e.state === "gone") && setTimeout(g, Math.random() * fn);
|
|
2771
2792
|
},
|
|
2772
2793
|
onError: () => h()
|
|
2773
2794
|
});
|
|
@@ -2790,7 +2811,7 @@ var hn = class {
|
|
|
2790
2811
|
let n = await s(this.opts.credential);
|
|
2791
2812
|
if (this.destroyed || t !== this.loadGen) return;
|
|
2792
2813
|
this.setState("loading");
|
|
2793
|
-
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a =
|
|
2814
|
+
let r = this.opts.autoplay === !1 && !this.playRequested, i = this.createEngine(e, n, r), a = We(this.opts.video, (e) => {
|
|
2794
2815
|
this._state !== "ended" && this._state !== "error" && this.setState(e);
|
|
2795
2816
|
});
|
|
2796
2817
|
if (await i.load(), this.destroyed || t !== this.loadGen) {
|
|
@@ -2812,23 +2833,23 @@ var hn = class {
|
|
|
2812
2833
|
if (this.analyticsSession?.noteDestroyed(), this.analyticsSession = null, this.detachMediaListeners?.(), this.opts.analytics === !1) return;
|
|
2813
2834
|
let i = e.analytics?.sid;
|
|
2814
2835
|
if (!i) return;
|
|
2815
|
-
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } =
|
|
2836
|
+
let a = typeof this.opts.analytics == "object" ? this.opts.analytics.endpoint : void 0, { endpoint: o, disabledReason: s } = Vt(this.opts.baseUrl, a, e.analytics?.endpoint);
|
|
2816
2837
|
if (!o) {
|
|
2817
2838
|
s && setTimeout(() => {
|
|
2818
2839
|
this.destroyed || r !== this.loadGen || this.emit("warning", new n("INTERNAL", 0, s));
|
|
2819
2840
|
}, 0);
|
|
2820
2841
|
return;
|
|
2821
2842
|
}
|
|
2822
|
-
let c = this.opts.video, l = new
|
|
2843
|
+
let c = this.opts.video, l = new Ht({
|
|
2823
2844
|
endpoint: o,
|
|
2824
2845
|
sid: i,
|
|
2825
2846
|
player: t.name === "native" ? "PLAYER_SAFARI_NATIVE" : "PLAYER_HLSJS",
|
|
2826
|
-
sdkVersion:
|
|
2827
|
-
environment:
|
|
2847
|
+
sdkVersion: Jt,
|
|
2848
|
+
environment: Kt(c),
|
|
2828
2849
|
idleMs: typeof this.opts.analytics == "object" ? this.opts.analytics.idleMs : void 0,
|
|
2829
2850
|
onIdle: () => this.onAnalyticsIdle(t),
|
|
2830
2851
|
sample: () => {
|
|
2831
|
-
let e = this.engine?.getStats() ??
|
|
2852
|
+
let e = this.engine?.getStats() ?? U, t = c.buffered.length ? Math.max(0, c.buffered.end(c.buffered.length - 1) - c.currentTime) : 0;
|
|
2832
2853
|
return {
|
|
2833
2854
|
...e,
|
|
2834
2855
|
bufferedMs: Math.round(t * 1e3),
|
|
@@ -2842,7 +2863,7 @@ var hn = class {
|
|
|
2842
2863
|
let u = () => l.noteSeek(), d = () => l.noteVolume(c.muted, c.volume);
|
|
2843
2864
|
c.addEventListener("seeking", u), c.addEventListener("volumechange", d), this.detachMediaListeners = () => {
|
|
2844
2865
|
c.removeEventListener("seeking", u), c.removeEventListener("volumechange", d);
|
|
2845
|
-
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()),
|
|
2866
|
+
}, l.start(), l.seedVolume(c.muted, c.volume), l.notePresentation(this.currentPresentation()), qt().then((e) => l.noteEnvironment(e)), this.opts.autoplay === !1 && l.noteAutoplay("AUTOPLAY_RESULT_NOT_ATTEMPTED");
|
|
2846
2867
|
}
|
|
2847
2868
|
currentPresentation() {
|
|
2848
2869
|
let e = this.opts.video;
|
|
@@ -2857,7 +2878,7 @@ var hn = class {
|
|
|
2857
2878
|
video: this.opts.video,
|
|
2858
2879
|
descriptor: e,
|
|
2859
2880
|
credential: t,
|
|
2860
|
-
deviceId:
|
|
2881
|
+
deviceId: O(),
|
|
2861
2882
|
userId: this.opts.userId,
|
|
2862
2883
|
lowLatency: this.opts.lowLatency === void 0 || this.opts.lowLatency === "auto" || this.opts.lowLatency,
|
|
2863
2884
|
snapToLiveOnRefocus: this.opts.snapToLiveOnRefocus,
|
|
@@ -2867,11 +2888,11 @@ var hn = class {
|
|
|
2867
2888
|
hlsConfig: i,
|
|
2868
2889
|
emit: (e) => this.onEngineEvent(e)
|
|
2869
2890
|
}, o = this.opts.engine ?? "auto";
|
|
2870
|
-
if (o === "native") return new
|
|
2871
|
-
if (o === "hls") return new
|
|
2872
|
-
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl &&
|
|
2873
|
-
if (
|
|
2874
|
-
if (
|
|
2891
|
+
if (o === "native") return new J(a);
|
|
2892
|
+
if (o === "hls") return new Et(a);
|
|
2893
|
+
if (e.drmEnabled && e.drm?.fairplay?.licenseUrl && e.drm.fairplay.certificateUrl && K(this.opts.video) && q()) return new J(a);
|
|
2894
|
+
if (nt()) return new Et(a);
|
|
2895
|
+
if (K(this.opts.video)) return new J(a);
|
|
2875
2896
|
throw new n("INTERNAL", 0, "no supported HLS playback engine in this browser");
|
|
2876
2897
|
}
|
|
2877
2898
|
onEngineEvent(e) {
|
|
@@ -2908,11 +2929,11 @@ var hn = class {
|
|
|
2908
2929
|
}
|
|
2909
2930
|
startLiveState(e) {
|
|
2910
2931
|
if (this.opts.liveStateEvents === !1) return;
|
|
2911
|
-
let t = this.opts.eventsBaseUrl ??
|
|
2932
|
+
let t = this.opts.eventsBaseUrl ?? T(this.opts.baseUrl);
|
|
2912
2933
|
if (!t) return;
|
|
2913
2934
|
this.closeLiveState();
|
|
2914
2935
|
let r = 0, i = !1;
|
|
2915
|
-
this.liveStateSub =
|
|
2936
|
+
this.liveStateSub = w({
|
|
2916
2937
|
eventsBaseUrl: t,
|
|
2917
2938
|
matchUrn: this.opts.matchUrn,
|
|
2918
2939
|
credential: this.opts.credential,
|
|
@@ -2923,7 +2944,7 @@ var hn = class {
|
|
|
2923
2944
|
r = 0, i = !1;
|
|
2924
2945
|
},
|
|
2925
2946
|
onError: () => {
|
|
2926
|
-
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >=
|
|
2947
|
+
this.destroyed || e !== this.loadGen || i || this.endedHandled || (r += 1, r >= pn && (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.`))));
|
|
2927
2948
|
}
|
|
2928
2949
|
});
|
|
2929
2950
|
}
|
|
@@ -2945,7 +2966,7 @@ var hn = class {
|
|
|
2945
2966
|
scheduleRejoin(e) {
|
|
2946
2967
|
this.rejoinEnabled() && !this.rejoinTimer && (this.rejoinTimer = setTimeout(() => {
|
|
2947
2968
|
this.rejoinTimer = null, !(this.destroyed || e !== this.loadGen || this._state !== "ended") && this.rejoin();
|
|
2948
|
-
}, Math.random() *
|
|
2969
|
+
}, Math.random() * fn));
|
|
2949
2970
|
}
|
|
2950
2971
|
cancelRejoin() {
|
|
2951
2972
|
this.rejoinTimer &&= (clearTimeout(this.rejoinTimer), null);
|
|
@@ -2969,7 +2990,7 @@ var hn = class {
|
|
|
2969
2990
|
}
|
|
2970
2991
|
t.controls = !1;
|
|
2971
2992
|
let n = (t.ownerDocument ?? document).createElement("div"), r = t.parentNode;
|
|
2972
|
-
r && r.insertBefore(n, t), n.appendChild(t),
|
|
2993
|
+
r && r.insertBefore(n, t), n.appendChild(t), Zt(n, this.opts.theme), this.container = n, this.controlBar = an({
|
|
2973
2994
|
root: n,
|
|
2974
2995
|
video: t,
|
|
2975
2996
|
player: this,
|
|
@@ -2999,7 +3020,7 @@ var hn = class {
|
|
|
2999
3020
|
}
|
|
3000
3021
|
startStats() {
|
|
3001
3022
|
this.stopStats();
|
|
3002
|
-
let e = Math.max(500, this.opts.statsIntervalMs ??
|
|
3023
|
+
let e = Math.max(500, this.opts.statsIntervalMs ?? mn);
|
|
3003
3024
|
this.statsTimer = setInterval(() => {
|
|
3004
3025
|
if (!this.engine) return;
|
|
3005
3026
|
let e = this.engine.getStats();
|
|
@@ -3011,7 +3032,7 @@ var hn = class {
|
|
|
3011
3032
|
}
|
|
3012
3033
|
scheduleLicenseRefresh() {
|
|
3013
3034
|
this.stopRefresh();
|
|
3014
|
-
let e = this.opts.licenseRefreshMs ??
|
|
3035
|
+
let e = this.opts.licenseRefreshMs ?? hn;
|
|
3015
3036
|
e && this._descriptor?.drmEnabled && (this.refreshTimer = setInterval(() => void this.refreshLicense(), e));
|
|
3016
3037
|
}
|
|
3017
3038
|
stopRefresh() {
|
|
@@ -3020,7 +3041,7 @@ var hn = class {
|
|
|
3020
3041
|
async refreshLicense() {
|
|
3021
3042
|
let e = this.engine;
|
|
3022
3043
|
if (!this.destroyed && e) try {
|
|
3023
|
-
let t = await
|
|
3044
|
+
let t = await v(this.resolveOptions());
|
|
3024
3045
|
if (this.destroyed || this.engine !== e) return;
|
|
3025
3046
|
let n = t.drm?.widevine?.licenseUrl, r = t.drm?.fairplay?.licenseUrl;
|
|
3026
3047
|
(n || r) && (e.setLicenseUrls({
|
|
@@ -3056,7 +3077,7 @@ var hn = class {
|
|
|
3056
3077
|
this.destroyed || (this.opts.video.volume = Math.min(1, Math.max(0, e)));
|
|
3057
3078
|
}
|
|
3058
3079
|
getStats() {
|
|
3059
|
-
return this.engine?.getStats() ??
|
|
3080
|
+
return this.engine?.getStats() ?? U;
|
|
3060
3081
|
}
|
|
3061
3082
|
getQualityLevels() {
|
|
3062
3083
|
return this.engine?.getQualityLevels() ?? [];
|
|
@@ -3095,10 +3116,10 @@ var hn = class {
|
|
|
3095
3116
|
e.pictureInPictureElement === this.opts.video && typeof e.exitPictureInPicture == "function" && await e.exitPictureInPicture();
|
|
3096
3117
|
}
|
|
3097
3118
|
async enterFullscreen() {
|
|
3098
|
-
return !this.destroyed &&
|
|
3119
|
+
return !this.destroyed && S(this.opts.video, this.container ?? void 0);
|
|
3099
3120
|
}
|
|
3100
3121
|
async exitFullscreen() {
|
|
3101
|
-
await
|
|
3122
|
+
await C(this.opts.video, this.container ?? void 0);
|
|
3102
3123
|
}
|
|
3103
3124
|
retry() {
|
|
3104
3125
|
return this.reload();
|
|
@@ -3108,7 +3129,7 @@ var hn = class {
|
|
|
3108
3129
|
let e = ++this.loadGen;
|
|
3109
3130
|
this.teardownPlayback();
|
|
3110
3131
|
try {
|
|
3111
|
-
let t = await
|
|
3132
|
+
let t = await y({
|
|
3112
3133
|
...this.resolveOptions(),
|
|
3113
3134
|
waitForLive: this.opts.waitForLive ? this.buildWaitConfig(e) : void 0
|
|
3114
3135
|
});
|
|
@@ -3166,7 +3187,7 @@ function $(e) {
|
|
|
3166
3187
|
}
|
|
3167
3188
|
//#endregion
|
|
3168
3189
|
//#region src/embed/host.ts
|
|
3169
|
-
function
|
|
3190
|
+
function yn(e) {
|
|
3170
3191
|
if (!e.container || typeof e.container.appendChild != "function") throw Error("mountEmbed: opts.container must be a DOM element");
|
|
3171
3192
|
if (!e.src) throw Error("mountEmbed: opts.src is required");
|
|
3172
3193
|
if (!e.baseUrl || !e.matchUrn) throw Error("mountEmbed: opts.baseUrl and opts.matchUrn are required");
|
|
@@ -3225,15 +3246,15 @@ function gn(e) {
|
|
|
3225
3246
|
}
|
|
3226
3247
|
//#endregion
|
|
3227
3248
|
//#region src/embed/page.ts
|
|
3228
|
-
var
|
|
3229
|
-
function
|
|
3249
|
+
var bn = /^[A-Za-z0-9:_.-]{1,128}$/;
|
|
3250
|
+
function xn(e) {
|
|
3230
3251
|
if (typeof e == "boolean") return e;
|
|
3231
3252
|
if (typeof e == "object" && e) {
|
|
3232
3253
|
let t = e.endpoint;
|
|
3233
3254
|
return typeof t == "string" ? { endpoint: t } : {};
|
|
3234
3255
|
}
|
|
3235
3256
|
}
|
|
3236
|
-
function
|
|
3257
|
+
function Sn() {
|
|
3237
3258
|
let e = window.HAVIK_EMBED_CONFIG;
|
|
3238
3259
|
if (e) return {
|
|
3239
3260
|
baseUrl: e.baseUrl ?? "",
|
|
@@ -3243,7 +3264,7 @@ function yn() {
|
|
|
3243
3264
|
autoplay: e.autoplay ?? !0,
|
|
3244
3265
|
muted: e.muted ?? !0,
|
|
3245
3266
|
waitForLive: e.waitForLive ?? !0,
|
|
3246
|
-
analytics:
|
|
3267
|
+
analytics: xn(e.analytics)
|
|
3247
3268
|
};
|
|
3248
3269
|
let t = new URLSearchParams(location.search);
|
|
3249
3270
|
return {
|
|
@@ -3256,9 +3277,9 @@ function yn() {
|
|
|
3256
3277
|
waitForLive: !0
|
|
3257
3278
|
};
|
|
3258
3279
|
}
|
|
3259
|
-
async function
|
|
3260
|
-
let e =
|
|
3261
|
-
|
|
3280
|
+
async function Cn() {
|
|
3281
|
+
let e = Sn();
|
|
3282
|
+
Tn();
|
|
3262
3283
|
let t = document.createElement("video");
|
|
3263
3284
|
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);
|
|
3264
3285
|
let r = e.parentOrigin && e.parentOrigin !== "null" ? e.parentOrigin : null;
|
|
@@ -3313,12 +3334,12 @@ async function bn() {
|
|
|
3313
3334
|
code: e.code,
|
|
3314
3335
|
message: e.message
|
|
3315
3336
|
})), e.on("autoplayblocked", () => {
|
|
3316
|
-
i({ type: "oddin:autoplayblocked" }),
|
|
3337
|
+
i({ type: "oddin:autoplayblocked" }), wn(t, e);
|
|
3317
3338
|
});
|
|
3318
3339
|
}, s = async (r) => {
|
|
3319
3340
|
a?.destroy(), a = null;
|
|
3320
3341
|
try {
|
|
3321
|
-
let n = await
|
|
3342
|
+
let n = await _n({
|
|
3322
3343
|
video: t,
|
|
3323
3344
|
baseUrl: e.baseUrl,
|
|
3324
3345
|
matchUrn: r,
|
|
@@ -3380,7 +3401,7 @@ async function bn() {
|
|
|
3380
3401
|
a?.retry();
|
|
3381
3402
|
break;
|
|
3382
3403
|
case "oddin:load":
|
|
3383
|
-
typeof e.matchUrn == "string" &&
|
|
3404
|
+
typeof e.matchUrn == "string" && bn.test(e.matchUrn) && s(e.matchUrn);
|
|
3384
3405
|
break;
|
|
3385
3406
|
case "oddin:destroy": c();
|
|
3386
3407
|
}
|
|
@@ -3392,18 +3413,18 @@ async function bn() {
|
|
|
3392
3413
|
protocol: 1
|
|
3393
3414
|
});
|
|
3394
3415
|
}
|
|
3395
|
-
function
|
|
3416
|
+
function wn(e, t) {
|
|
3396
3417
|
if (document.getElementById("havik-tap")) return;
|
|
3397
3418
|
let n = document.createElement("button");
|
|
3398
3419
|
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", () => {
|
|
3399
3420
|
n.remove(), t.play();
|
|
3400
3421
|
}), document.body.appendChild(n);
|
|
3401
3422
|
}
|
|
3402
|
-
function
|
|
3423
|
+
function Tn() {
|
|
3403
3424
|
let e = document.createElement("style");
|
|
3404
3425
|
e.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}", document.head.appendChild(e);
|
|
3405
3426
|
}
|
|
3406
3427
|
//#endregion
|
|
3407
|
-
export {
|
|
3428
|
+
export { Yt as ODDIN_THEME, n as PlaybackError, Zt as applyTheme, H as baseUrlForEnv, Cn as bootEmbed, Te as clearDeviceId, _n as createPlayer, T as deriveEventsBaseUrl, ze as detectDrmSupport, S as enterVideoFullscreen, C as exitVideoFullscreen, ve as fetchCatalog, be as fetchTournament, Se as flattenMatches, O as getDeviceId, Ve as isLowLatencyManifest, $ as isOddinMessage, De as licenseRequestHeaders, yn as mountEmbed, de as pollToLive, y as resolveStream, w as subscribeLiveState, x as videoFullscreenActive, Ce as watchStatus };
|
|
3408
3429
|
|
|
3409
3430
|
//# sourceMappingURL=index.js.map
|