itube-modern-player 0.8.0 → 0.8.2
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 +20 -3
- package/dist/core.cjs +3 -3
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +362 -332
- package/dist/core.js.map +1 -1
- package/dist/gesture-BLWiPHlW.cjs +2 -0
- package/dist/gesture-BLWiPHlW.cjs.map +1 -0
- package/dist/gesture-BYJrYanO.js +11 -0
- package/dist/gesture-BYJrYanO.js.map +1 -0
- package/dist/gesture.d.ts +18 -0
- package/dist/itube-modern-player.iife.js +3 -3
- package/dist/itube-modern-player.iife.js.map +1 -1
- package/dist/lazy.cjs +1 -1
- package/dist/lazy.cjs.map +1 -1
- package/dist/lazy.js +81 -44
- package/dist/lazy.js.map +1 -1
- package/dist/player.d.ts +10 -0
- package/dist/types.d.ts +20 -3
- package/dist/vue.cjs +1 -1
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +101 -72
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
package/dist/core.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { posterSrc as q } from "./placeholder.js";
|
|
2
|
-
import { d as
|
|
2
|
+
import { d as G } from "./labels-CCjOCBKU.js";
|
|
3
3
|
function a(r, t, e) {
|
|
4
4
|
const i = document.createElement(r);
|
|
5
5
|
if (t && (i.className = t), e)
|
|
6
6
|
for (const [s, n] of Object.entries(e)) i.setAttribute(s, n);
|
|
7
7
|
return i;
|
|
8
8
|
}
|
|
9
|
-
function
|
|
9
|
+
function L(r, t) {
|
|
10
10
|
if (r.textContent = "", typeof t == "object") {
|
|
11
11
|
"url" in t ? r.append(a("img", "imp-icon-img", { src: t.url, alt: "" })) : r.innerHTML = t.svg;
|
|
12
12
|
return;
|
|
@@ -19,22 +19,22 @@ function T(r, t = "") {
|
|
|
19
19
|
}
|
|
20
20
|
function b(r, t, e) {
|
|
21
21
|
const i = a("button", `imp-btn ${r}`, { type: "button", "aria-label": t, title: t });
|
|
22
|
-
return
|
|
22
|
+
return L(i, e), i;
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function X(r, t) {
|
|
25
25
|
const e = a("div", `${t}__meta`);
|
|
26
26
|
return r.forEach((i, s) => {
|
|
27
27
|
s > 0 && e.append(document.createTextNode(" "));
|
|
28
|
-
const n = typeof i == "string" ? i : i.text,
|
|
29
|
-
if (
|
|
28
|
+
const n = typeof i == "string" ? i : i.text, o = typeof i == "string" ? void 0 : i.icon, l = a("span", `${t}__meta-chunk`);
|
|
29
|
+
if (o) {
|
|
30
30
|
const h = a("span", `${t}__meta-icon`);
|
|
31
|
-
|
|
31
|
+
L(h, o), l.append(h);
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
l.append(document.createTextNode(n)), e.append(l);
|
|
34
34
|
}), e;
|
|
35
35
|
}
|
|
36
36
|
function I(r, t, e) {
|
|
37
|
-
|
|
37
|
+
L(r, t), e !== void 0 && (r.setAttribute("aria-label", e), r.setAttribute("title", e));
|
|
38
38
|
}
|
|
39
39
|
function x(r, t, e) {
|
|
40
40
|
return Math.min(e, Math.max(t, r));
|
|
@@ -44,22 +44,22 @@ function _(r) {
|
|
|
44
44
|
const t = Math.floor(r % 60), e = Math.floor(r / 60 % 60), i = Math.floor(r / 3600), s = i > 0 ? String(e).padStart(2, "0") : String(e), n = String(t).padStart(2, "0");
|
|
45
45
|
return i > 0 ? `${i}:${s}:${n}` : `${s}:${n}`;
|
|
46
46
|
}
|
|
47
|
-
function
|
|
47
|
+
function H(r) {
|
|
48
48
|
const t = r.trim().match(/^(?:(\d+):)?(\d{1,2}):(\d{2})(?:[.,](\d{1,3}))?$/);
|
|
49
49
|
if (!t) return null;
|
|
50
50
|
const e = t[1] ? Number(t[1]) : 0, i = Number(t[2]), s = Number(t[3]), n = t[4] ? Number(t[4].padEnd(3, "0")) : 0;
|
|
51
51
|
return e * 3600 + i * 60 + s + n / 1e3;
|
|
52
52
|
}
|
|
53
|
-
function
|
|
53
|
+
function J(r) {
|
|
54
54
|
const t = [], e = r.replace(/\r\n?/g, `
|
|
55
55
|
`).split(/\n\n+/);
|
|
56
56
|
for (const i of e) {
|
|
57
57
|
const s = i.split(`
|
|
58
|
-
`).filter((
|
|
58
|
+
`).filter((f) => f.trim() !== "");
|
|
59
59
|
if (s.length === 0) continue;
|
|
60
|
-
let n = s.findIndex((
|
|
60
|
+
let n = s.findIndex((f) => f.includes("-->"));
|
|
61
61
|
if (n === -1) continue;
|
|
62
|
-
const [
|
|
62
|
+
const [o, l] = s[n].split("-->"), h = H(o), c = H((l ?? "").split(" ")[1] ?? l ?? "") ?? H(l ?? "");
|
|
63
63
|
if (h === null || c === null) continue;
|
|
64
64
|
const u = s.slice(n + 1).join(`
|
|
65
65
|
`).trim();
|
|
@@ -67,14 +67,14 @@ function X(r) {
|
|
|
67
67
|
}
|
|
68
68
|
return t;
|
|
69
69
|
}
|
|
70
|
-
function
|
|
70
|
+
function nt(r, t) {
|
|
71
71
|
try {
|
|
72
72
|
return new URL(r, new URL(t, window.location.href)).toString();
|
|
73
73
|
} catch {
|
|
74
74
|
return r;
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
class
|
|
77
|
+
class rt {
|
|
78
78
|
constructor() {
|
|
79
79
|
this.listeners = /* @__PURE__ */ new Map();
|
|
80
80
|
}
|
|
@@ -106,7 +106,7 @@ class nt {
|
|
|
106
106
|
this.listeners.clear();
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
const g = (r, t = "0 0 24 24") => `<svg viewBox="${t}" fill="currentColor" aria-hidden="true" focusable="false">${r}</svg>`,
|
|
109
|
+
const g = (r, t = "0 0 24 24") => `<svg viewBox="${t}" fill="currentColor" aria-hidden="true" focusable="false">${r}</svg>`, ot = {
|
|
110
110
|
play: g('<path d="M8 5.14v13.72c0 .8.87 1.3 1.56.88l10.54-6.86a1.05 1.05 0 0 0 0-1.76L9.56 4.26C8.87 3.84 8 4.34 8 5.14Z"/>'),
|
|
111
111
|
pause: g('<rect x="6" y="5" width="4" height="14" rx="1"/><rect x="14" y="5" width="4" height="14" rx="1"/>'),
|
|
112
112
|
replay: g('<path d="M12 5V2.5L7.5 6 12 9.5V7a5 5 0 1 1-5 5H5a7 7 0 1 0 7-7Z"/>'),
|
|
@@ -141,79 +141,79 @@ const g = (r, t = "0 0 24 24") => `<svg viewBox="${t}" fill="currentColor" aria-
|
|
|
141
141
|
user: g('<path d="M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm0 2c-3.6 0-8 1.8-8 4.4V21h16v-2.6c0-2.6-4.4-4.4-8-4.4Z"/>'),
|
|
142
142
|
// Generic "channel" glyph (play badge) for preview meta when a channel is set.
|
|
143
143
|
channel: g('<path d="M3 5h18a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1Zm7 3.5v7l6-3.5-6-3.5Z"/>')
|
|
144
|
-
},
|
|
144
|
+
}, V = { en: G };
|
|
145
145
|
function qt(r, t) {
|
|
146
|
-
|
|
146
|
+
V[r] = t;
|
|
147
147
|
}
|
|
148
|
-
function
|
|
148
|
+
function Vt(r) {
|
|
149
149
|
for (const [t, e] of Object.entries(r))
|
|
150
|
-
e && (
|
|
150
|
+
e && (V[t] = e);
|
|
151
151
|
}
|
|
152
|
-
function
|
|
153
|
-
return r &&
|
|
152
|
+
function at(r) {
|
|
153
|
+
return r && V[r] || G;
|
|
154
154
|
}
|
|
155
|
-
function
|
|
156
|
-
return Object.keys(
|
|
155
|
+
function Ot() {
|
|
156
|
+
return Object.keys(V);
|
|
157
157
|
}
|
|
158
158
|
function lt(r) {
|
|
159
159
|
const t = [0.06, 0.24, 0.4, 0.24, 0.06], e = r.length;
|
|
160
160
|
return r.map(
|
|
161
|
-
(i, s) => t.reduce((n,
|
|
162
|
-
const h = Math.min(e - 1, Math.max(0, s +
|
|
163
|
-
return n +
|
|
161
|
+
(i, s) => t.reduce((n, o, l) => {
|
|
162
|
+
const h = Math.min(e - 1, Math.max(0, s + l - 2));
|
|
163
|
+
return n + o * r[h];
|
|
164
164
|
}, 0)
|
|
165
165
|
);
|
|
166
166
|
}
|
|
167
|
-
function
|
|
167
|
+
function ht(r, t) {
|
|
168
168
|
if (r.length === 0) return 0;
|
|
169
169
|
const e = Math.min(r.length - 1, Math.max(0, Math.round((r.length - 1) * t)));
|
|
170
170
|
return r[e];
|
|
171
171
|
}
|
|
172
|
-
function
|
|
172
|
+
function Y(r, t) {
|
|
173
173
|
if (r.length === 0 || r.every((n) => n <= 0)) return [];
|
|
174
|
-
const e = lt(r), i = t === "retention" ?
|
|
174
|
+
const e = lt(r), i = t === "retention" ? ht([...e].sort((n, o) => n - o), 0.95) : Math.max(...e);
|
|
175
175
|
if (i <= 0) return [];
|
|
176
176
|
const s = 0.08;
|
|
177
177
|
return e.map((n) => s + (1 - s) * Math.min(1, Math.max(0, n / i)));
|
|
178
178
|
}
|
|
179
|
-
function
|
|
179
|
+
function ct(r, t, e = 100) {
|
|
180
180
|
if (r.length === 0 || !Number.isFinite(t) || t <= 0) return [];
|
|
181
181
|
const i = new Array(e).fill(0);
|
|
182
182
|
let s = !1;
|
|
183
183
|
for (const n of r) {
|
|
184
184
|
if (!Number.isFinite(n.time) || n.time < 0 || n.time > t) continue;
|
|
185
|
-
const
|
|
186
|
-
|
|
185
|
+
const o = Math.max(0, n.value);
|
|
186
|
+
o !== 0 && (i[Math.min(e - 1, Math.floor(n.time / t * e))] += o, s = !0);
|
|
187
187
|
}
|
|
188
|
-
return s ?
|
|
188
|
+
return s ? Y(i, "peaks") : [];
|
|
189
189
|
}
|
|
190
|
-
function
|
|
190
|
+
function dt(r, t = "peaks", e = 200) {
|
|
191
191
|
let i = r.map((s) => Number.isFinite(s) ? Math.max(0, s) : 0);
|
|
192
192
|
if (i.length > e) {
|
|
193
193
|
const s = new Array(e).fill(0), n = new Array(e).fill(0);
|
|
194
|
-
for (let
|
|
195
|
-
const
|
|
196
|
-
s[
|
|
194
|
+
for (let o = 0; o < i.length; o++) {
|
|
195
|
+
const l = Math.min(e - 1, Math.floor(o / i.length * e));
|
|
196
|
+
s[l] += i[o], n[l]++;
|
|
197
197
|
}
|
|
198
|
-
i = s.map((
|
|
198
|
+
i = s.map((o, l) => n[l] > 0 ? o / n[l] : 0);
|
|
199
199
|
}
|
|
200
|
-
return
|
|
200
|
+
return Y(i, t);
|
|
201
201
|
}
|
|
202
|
-
function
|
|
202
|
+
function ut(r, t = 1, e = 1e3, i = 100) {
|
|
203
203
|
const s = r.length;
|
|
204
204
|
if (s === 0) return "";
|
|
205
|
-
const n = e / (s - 1 || 1),
|
|
206
|
-
const
|
|
207
|
-
return [
|
|
208
|
-
}, [, h] =
|
|
205
|
+
const n = e / (s - 1 || 1), o = Math.max(0, t) / 6, l = (u) => {
|
|
206
|
+
const f = Math.min(s - 1, Math.max(0, u));
|
|
207
|
+
return [f * n, i - r[f] * i];
|
|
208
|
+
}, [, h] = l(0);
|
|
209
209
|
let c = `M 0 ${i} L 0 ${h.toFixed(1)}`;
|
|
210
210
|
for (let u = 0; u < s - 1; u++) {
|
|
211
|
-
const [
|
|
212
|
-
c += ` C ${A.toFixed(1)} ${
|
|
211
|
+
const [f, p] = l(u - 1), [m, v] = l(u), [y, d] = l(u + 1), [k, C] = l(u + 2), A = m + (y - f) * o, O = Math.min(i, Math.max(0, v + (d - p) * o)), P = y - (k - m) * o, R = Math.min(i, Math.max(0, d - (C - v) * o));
|
|
212
|
+
c += ` C ${A.toFixed(1)} ${O.toFixed(1)} ${P.toFixed(1)} ${R.toFixed(1)} ${y.toFixed(1)} ${d.toFixed(1)}`;
|
|
213
213
|
}
|
|
214
214
|
return c += ` L ${e} ${i} Z`, c;
|
|
215
215
|
}
|
|
216
|
-
async function
|
|
216
|
+
async function pt(r, t) {
|
|
217
217
|
if (r.src)
|
|
218
218
|
return {
|
|
219
219
|
roll: r.roll,
|
|
@@ -223,82 +223,82 @@ async function ut(r, t) {
|
|
|
223
223
|
tracking: {}
|
|
224
224
|
};
|
|
225
225
|
if (!r.vastTag) throw new Error('Ad roll has neither "vastTag" nor "src"');
|
|
226
|
-
return
|
|
226
|
+
return tt(r, r.vastTag, t, 0, { impressions: [], tracking: {} });
|
|
227
227
|
}
|
|
228
|
-
async function
|
|
228
|
+
async function tt(r, t, e, i, s) {
|
|
229
229
|
if (i > e.maxWrapperDepth) throw new Error("VAST wrapper depth limit exceeded");
|
|
230
|
-
const n = new AbortController(),
|
|
231
|
-
let
|
|
230
|
+
const n = new AbortController(), o = setTimeout(() => n.abort(), e.requestTimeout);
|
|
231
|
+
let l;
|
|
232
232
|
try {
|
|
233
|
-
const
|
|
234
|
-
if (!
|
|
235
|
-
|
|
233
|
+
const v = await fetch(t, { signal: n.signal, credentials: "omit" });
|
|
234
|
+
if (!v.ok) throw new Error(`VAST request failed (${v.status})`);
|
|
235
|
+
l = await v.text();
|
|
236
236
|
} finally {
|
|
237
|
-
clearTimeout(
|
|
237
|
+
clearTimeout(o);
|
|
238
238
|
}
|
|
239
|
-
const h = new DOMParser().parseFromString(
|
|
239
|
+
const h = new DOMParser().parseFromString(l, "text/xml");
|
|
240
240
|
if (h.querySelector("parsererror")) throw new Error("VAST response is not valid XML");
|
|
241
241
|
const c = h.querySelector("VAST > Ad");
|
|
242
242
|
if (!c) throw new Error("VAST response contains no ads");
|
|
243
|
-
|
|
243
|
+
mt(c, s);
|
|
244
244
|
const u = c.querySelector(":scope > Wrapper");
|
|
245
245
|
if (u) {
|
|
246
|
-
const
|
|
247
|
-
if (!
|
|
248
|
-
return
|
|
246
|
+
const v = S(u.querySelector("VASTAdTagURI"));
|
|
247
|
+
if (!v) throw new Error("VAST wrapper without VASTAdTagURI");
|
|
248
|
+
return tt(r, v, e, i + 1, s);
|
|
249
249
|
}
|
|
250
|
-
const
|
|
251
|
-
if (!
|
|
252
|
-
const p =
|
|
250
|
+
const f = c.querySelector(":scope > InLine");
|
|
251
|
+
if (!f) throw new Error("VAST ad has neither InLine nor Wrapper");
|
|
252
|
+
const p = f.querySelector("Creatives > Creative > Linear");
|
|
253
253
|
if (!p) throw new Error("VAST ad has no Linear creative");
|
|
254
|
-
const m =
|
|
254
|
+
const m = ft(p);
|
|
255
255
|
if (!m) throw new Error("VAST ad has no playable MediaFile");
|
|
256
256
|
return {
|
|
257
257
|
roll: r.roll,
|
|
258
258
|
mediaUrl: m.url,
|
|
259
259
|
mediaType: m.type,
|
|
260
|
-
clickThrough:
|
|
261
|
-
duration:
|
|
260
|
+
clickThrough: S(p.querySelector("VideoClicks > ClickThrough")) ?? r.clickUrl,
|
|
261
|
+
duration: D(S(p.querySelector(":scope > Duration"))),
|
|
262
262
|
skipOffset: vt(
|
|
263
263
|
p.getAttribute("skipoffset"),
|
|
264
|
-
|
|
264
|
+
D(S(p.querySelector(":scope > Duration")))
|
|
265
265
|
),
|
|
266
266
|
impressions: s.impressions,
|
|
267
267
|
tracking: s.tracking,
|
|
268
|
-
adTitle:
|
|
268
|
+
adTitle: S(f.querySelector(":scope > AdTitle")) ?? void 0
|
|
269
269
|
};
|
|
270
270
|
}
|
|
271
|
-
function
|
|
271
|
+
function mt(r, t) {
|
|
272
272
|
var e, i;
|
|
273
273
|
for (const s of r.querySelectorAll("Impression")) {
|
|
274
|
-
const n =
|
|
274
|
+
const n = S(s);
|
|
275
275
|
n && t.impressions.push(n);
|
|
276
276
|
}
|
|
277
277
|
for (const s of r.querySelectorAll("Linear > TrackingEvents > Tracking")) {
|
|
278
|
-
const n = s.getAttribute("event"),
|
|
279
|
-
!n || !
|
|
278
|
+
const n = s.getAttribute("event"), o = S(s);
|
|
279
|
+
!n || !o || ["start", "firstQuartile", "midpoint", "thirdQuartile", "complete", "skip", "pause", "resume"].includes(n) && ((e = t.tracking)[n] ?? (e[n] = [])).push(o);
|
|
280
280
|
}
|
|
281
281
|
for (const s of r.querySelectorAll("Linear > VideoClicks > ClickTracking")) {
|
|
282
|
-
const n =
|
|
282
|
+
const n = S(s);
|
|
283
283
|
n && ((i = t.tracking).click ?? (i.click = [])).push(n);
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
function
|
|
287
|
-
const e = [...r.querySelectorAll("MediaFiles > MediaFile")].map((
|
|
288
|
-
url:
|
|
289
|
-
type:
|
|
290
|
-
delivery:
|
|
291
|
-
bitrate: Number(
|
|
292
|
-
apiFramework:
|
|
293
|
-
})).filter((
|
|
294
|
-
(
|
|
286
|
+
function ft(r) {
|
|
287
|
+
const e = [...r.querySelectorAll("MediaFiles > MediaFile")].map((o) => ({
|
|
288
|
+
url: S(o) ?? "",
|
|
289
|
+
type: o.getAttribute("type") ?? void 0,
|
|
290
|
+
delivery: o.getAttribute("delivery") ?? "",
|
|
291
|
+
bitrate: Number(o.getAttribute("bitrate") ?? 0),
|
|
292
|
+
apiFramework: o.getAttribute("apiFramework") ?? ""
|
|
293
|
+
})).filter((o) => o.url && o.apiFramework.toUpperCase() !== "VPAID").filter(
|
|
294
|
+
(o) => !o.type || /(video\/(mp4|webm|ogg)|application\/(x-mpegurl|vnd\.apple\.mpegurl))/i.test(o.type)
|
|
295
295
|
);
|
|
296
296
|
if (e.length === 0) return null;
|
|
297
|
-
e.sort((
|
|
298
|
-
const i = e.filter((
|
|
297
|
+
e.sort((o, l) => o.bitrate - l.bitrate);
|
|
298
|
+
const i = e.filter((o) => o.delivery !== "streaming"), s = i.length > 0 ? i : e, n = s[Math.floor(s.length / 2)];
|
|
299
299
|
return { url: n.url, type: n.type };
|
|
300
300
|
}
|
|
301
|
-
function
|
|
301
|
+
function D(r) {
|
|
302
302
|
if (!r) return;
|
|
303
303
|
const t = r.trim().match(/^(?:(\d+):)?(\d{1,2}):(\d{2})(?:\.(\d{1,3}))?$/);
|
|
304
304
|
if (t)
|
|
@@ -307,9 +307,9 @@ function Z(r) {
|
|
|
307
307
|
function vt(r, t) {
|
|
308
308
|
if (!r) return;
|
|
309
309
|
const e = r.trim().match(/^(\d+(?:\.\d+)?)%$/);
|
|
310
|
-
return e ? t !== void 0 ? Number(e[1]) / 100 * t : void 0 :
|
|
310
|
+
return e ? t !== void 0 ? Number(e[1]) / 100 * t : void 0 : D(r);
|
|
311
311
|
}
|
|
312
|
-
function
|
|
312
|
+
function F(r) {
|
|
313
313
|
if (r)
|
|
314
314
|
for (const t of r)
|
|
315
315
|
try {
|
|
@@ -317,10 +317,10 @@ function $(r) {
|
|
|
317
317
|
} catch {
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
|
-
function
|
|
320
|
+
function S(r) {
|
|
321
321
|
return r?.textContent?.trim().replace(/^<!\[CDATA\[|\]\]>$/g, "").trim() || null;
|
|
322
322
|
}
|
|
323
|
-
class
|
|
323
|
+
class gt {
|
|
324
324
|
constructor(t, e) {
|
|
325
325
|
this.host = t, this.playedRolls = /* @__PURE__ */ new Set(), this.sourcesSeen = 0, this.activeBreak = null, this.layer = null, this.adVideo = null, this.destroyed = !1, this.opts = {
|
|
326
326
|
skipDelay: 5,
|
|
@@ -387,11 +387,11 @@ class ft {
|
|
|
387
387
|
for (const n of t) {
|
|
388
388
|
this.playedRolls.add(n);
|
|
389
389
|
try {
|
|
390
|
-
const
|
|
391
|
-
await this.playAd(
|
|
392
|
-
} catch (
|
|
393
|
-
const
|
|
394
|
-
this.host.emitter.emit("aderror", { roll: n, error:
|
|
390
|
+
const o = await pt(n, this.opts);
|
|
391
|
+
await this.playAd(o);
|
|
392
|
+
} catch (o) {
|
|
393
|
+
const l = o instanceof Error ? o : new Error(String(o));
|
|
394
|
+
this.host.emitter.emit("aderror", { roll: n, error: l });
|
|
395
395
|
}
|
|
396
396
|
if (this.destroyed) return;
|
|
397
397
|
}
|
|
@@ -404,22 +404,22 @@ class ft {
|
|
|
404
404
|
}
|
|
405
405
|
playAd(t) {
|
|
406
406
|
return new Promise((e) => {
|
|
407
|
-
const { labels: i } = this.host, s = a("div", "imp-ad"), n = this.ensureAdVideo(),
|
|
407
|
+
const { labels: i } = this.host, s = a("div", "imp-ad"), n = this.ensureAdVideo(), o = new AbortController(), l = o.signal;
|
|
408
408
|
n.src = t.mediaUrl, n.muted = this.host.contentVideo.muted, n.volume = this.host.contentVideo.volume;
|
|
409
409
|
const h = a("div", "imp-spinner imp-ad__spinner"), c = a("div", "imp-ad__hud"), u = a("span", "imp-ad__badge");
|
|
410
410
|
u.textContent = t.adTitle ? `${i.adLabel} · ${t.adTitle}` : i.adLabel;
|
|
411
|
-
const
|
|
412
|
-
c.append(u,
|
|
411
|
+
const f = a("span", "imp-ad__countdown");
|
|
412
|
+
c.append(u, f);
|
|
413
413
|
const p = a("div", "imp-ad__actions");
|
|
414
414
|
let m = null;
|
|
415
415
|
t.clickThrough && (m = a("button", "imp-ad__visit", { type: "button" }), m.textContent = i.visitAdvertiser, p.append(m));
|
|
416
|
-
const
|
|
417
|
-
|
|
416
|
+
const v = a("button", "imp-ad__skip", { type: "button" });
|
|
417
|
+
v.hidden = !0, p.append(v), s.append(n, h, c, p), this.host.container.append(s), this.layer = s;
|
|
418
418
|
const y = t.skipOffset ?? this.opts.skipDelay, d = /* @__PURE__ */ new Set(), k = (w) => {
|
|
419
|
-
d.has(w) || (d.add(w),
|
|
419
|
+
d.has(w) || (d.add(w), F(t.tracking[w]));
|
|
420
420
|
};
|
|
421
421
|
let C = Date.now(), A = -1;
|
|
422
|
-
const
|
|
422
|
+
const O = setInterval(() => {
|
|
423
423
|
if (n.paused) {
|
|
424
424
|
C = Date.now();
|
|
425
425
|
return;
|
|
@@ -433,40 +433,40 @@ class ft {
|
|
|
433
433
|
error: new Error(`Ad media stalled for ${this.opts.mediaTimeout} ms — skipping`)
|
|
434
434
|
}), P());
|
|
435
435
|
}, 500), P = () => {
|
|
436
|
-
clearInterval(
|
|
436
|
+
clearInterval(O), o.abort(), n.pause(), n.removeAttribute("src"), n.load(), s.remove(), this.layer = null, e();
|
|
437
437
|
}, R = (w) => {
|
|
438
438
|
w ? (k("skip"), this.host.emitter.emit("adskip", { ad: t })) : k("complete"), this.host.emitter.emit("adend", { ad: t }), P();
|
|
439
439
|
};
|
|
440
440
|
n.addEventListener("playing", () => {
|
|
441
|
-
|
|
442
|
-
}, { once: !0, signal:
|
|
441
|
+
F(t.impressions), k("start"), this.host.emitter.emit("adstart", { ad: t });
|
|
442
|
+
}, { once: !0, signal: l }), n.addEventListener("playing", () => {
|
|
443
443
|
h.hidden = !0;
|
|
444
|
-
}, { signal:
|
|
444
|
+
}, { signal: l }), n.addEventListener("waiting", () => {
|
|
445
445
|
h.hidden = !1;
|
|
446
|
-
}, { signal:
|
|
446
|
+
}, { signal: l }), n.addEventListener("timeupdate", () => {
|
|
447
447
|
const w = n.currentTime, B = n.duration;
|
|
448
|
-
if (Number.isFinite(B) && B > 0 && (
|
|
449
|
-
const
|
|
450
|
-
|
|
448
|
+
if (Number.isFinite(B) && B > 0 && (f.textContent = _(Math.max(0, B - w)), w / B >= 0.25 && k("firstQuartile"), w / B >= 0.5 && k("midpoint"), w / B >= 0.75 && k("thirdQuartile")), y >= 0) {
|
|
449
|
+
const U = Math.ceil(y - w);
|
|
450
|
+
U > 0 ? (v.hidden = !1, v.disabled = !0, v.textContent = `${i.skipAdIn} ${U}`) : (v.hidden = !1, v.disabled = !1, v.textContent = i.skipAd);
|
|
451
451
|
}
|
|
452
|
-
}, { signal:
|
|
452
|
+
}, { signal: l }), n.addEventListener("ended", () => R(!1), { signal: l }), n.addEventListener("error", () => {
|
|
453
453
|
this.host.emitter.emit("aderror", {
|
|
454
454
|
roll: { roll: t.roll },
|
|
455
455
|
error: new Error("Ad media failed to play")
|
|
456
456
|
}), P();
|
|
457
|
-
}, { signal:
|
|
458
|
-
const
|
|
457
|
+
}, { signal: l }), v.addEventListener("click", () => R(!0));
|
|
458
|
+
const z = () => {
|
|
459
459
|
t.clickThrough && (k("click"), this.host.emitter.emit("adclick", { ad: t }), window.open(t.clickThrough, "_blank", "noopener"), n.pause());
|
|
460
460
|
};
|
|
461
|
-
n.addEventListener("click",
|
|
462
|
-
let
|
|
461
|
+
n.addEventListener("click", z, { signal: l }), m?.addEventListener("click", z);
|
|
462
|
+
let Q = !1, N = !1;
|
|
463
463
|
n.addEventListener("playing", () => {
|
|
464
|
-
|
|
465
|
-
}, { once: !0, signal:
|
|
466
|
-
n.ended || !s.isConnected || (s.classList.add("imp-ad--paused"),
|
|
467
|
-
}, { signal:
|
|
468
|
-
s.classList.remove("imp-ad--paused"), N && (N = !1,
|
|
469
|
-
}, { signal:
|
|
464
|
+
Q = !0;
|
|
465
|
+
}, { once: !0, signal: l }), n.addEventListener("pause", () => {
|
|
466
|
+
n.ended || !s.isConnected || (s.classList.add("imp-ad--paused"), Q && !N && (N = !0, F(t.tracking.pause), this.host.emitter.emit("adpause", { ad: t })));
|
|
467
|
+
}, { signal: l }), n.addEventListener("play", () => {
|
|
468
|
+
s.classList.remove("imp-ad--paused"), N && (N = !1, F(t.tracking.resume), this.host.emitter.emit("adresume", { ad: t }));
|
|
469
|
+
}, { signal: l }), s.addEventListener("click", (w) => {
|
|
470
470
|
(w.target === s || s.classList.contains("imp-ad--paused")) && n.paused && n.play().catch(() => {
|
|
471
471
|
});
|
|
472
472
|
}), n.play().catch(() => {
|
|
@@ -482,32 +482,32 @@ class ft {
|
|
|
482
482
|
this.destroyed = !0, this.adVideo?.pause(), this.layer?.remove(), this.layer = null, this.adVideo = null;
|
|
483
483
|
}
|
|
484
484
|
}
|
|
485
|
-
function
|
|
485
|
+
function j(r, t) {
|
|
486
486
|
const e = [...r].sort((s, n) => s.start - n.start), i = [];
|
|
487
487
|
for (let s = 0; s < e.length; s++) {
|
|
488
488
|
const n = Math.max(0, e[s].start);
|
|
489
489
|
if (Number.isFinite(t) && n >= t) continue;
|
|
490
|
-
let
|
|
491
|
-
Number.isFinite(t) && (
|
|
490
|
+
let o = e[s].end ?? e[s + 1]?.start ?? t;
|
|
491
|
+
Number.isFinite(t) && (o = Math.min(o, t)), !(!Number.isFinite(o) || o <= n) && i.push({ start: n, end: o, title: e[s].title });
|
|
492
492
|
}
|
|
493
493
|
return i;
|
|
494
494
|
}
|
|
495
|
-
async function
|
|
495
|
+
async function yt(r) {
|
|
496
496
|
const t = await fetch(r);
|
|
497
497
|
if (!t.ok) throw new Error(`Failed to load chapters VTT (${t.status})`);
|
|
498
498
|
const e = await t.text();
|
|
499
|
-
return
|
|
499
|
+
return J(e).map((i) => ({ start: i.start, end: i.end, title: i.text }));
|
|
500
500
|
}
|
|
501
|
-
function
|
|
501
|
+
function et(r, t) {
|
|
502
502
|
for (const e of r)
|
|
503
503
|
if (t >= e.start && t < e.end) return e;
|
|
504
504
|
return null;
|
|
505
505
|
}
|
|
506
|
-
function
|
|
506
|
+
function bt(r, t) {
|
|
507
507
|
return t ? /application\/(x-mpegurl|vnd\.apple\.mpegurl)/i.test(t) : /\.m3u8(\?|#|$)/i.test(r);
|
|
508
508
|
}
|
|
509
509
|
let E;
|
|
510
|
-
async function
|
|
510
|
+
async function kt() {
|
|
511
511
|
if (E !== void 0) return E;
|
|
512
512
|
const r = globalThis.Hls;
|
|
513
513
|
if (r)
|
|
@@ -518,14 +518,14 @@ async function bt() {
|
|
|
518
518
|
return null;
|
|
519
519
|
}
|
|
520
520
|
}
|
|
521
|
-
async function
|
|
522
|
-
if (
|
|
523
|
-
const s = r.canPlayType("application/vnd.apple.mpegurl"), n = s ? null : await
|
|
524
|
-
return n && n.isSupported() ?
|
|
521
|
+
async function wt(r, t, e, i) {
|
|
522
|
+
if (bt(t, e)) {
|
|
523
|
+
const s = r.canPlayType("application/vnd.apple.mpegurl"), n = s ? null : await kt();
|
|
524
|
+
return n && n.isSupported() ? xt(n, r, t, i) : s ? (r.src = t, Z(r)) : (i.onError("HLS is not supported in this browser and hls.js could not be loaded."), Z(r));
|
|
525
525
|
}
|
|
526
|
-
return r.src = t,
|
|
526
|
+
return r.src = t, Z(r);
|
|
527
527
|
}
|
|
528
|
-
function
|
|
528
|
+
function Z(r) {
|
|
529
529
|
return {
|
|
530
530
|
kind: "native",
|
|
531
531
|
levels: [],
|
|
@@ -537,7 +537,7 @@ function H(r) {
|
|
|
537
537
|
}
|
|
538
538
|
};
|
|
539
539
|
}
|
|
540
|
-
function
|
|
540
|
+
function xt(r, t, e, i) {
|
|
541
541
|
const s = new r({ enableWorker: !0 }), n = {
|
|
542
542
|
kind: "hls",
|
|
543
543
|
levels: [],
|
|
@@ -555,20 +555,20 @@ function wt(r, t, e, i) {
|
|
|
555
555
|
label: c.height ? `${c.height}p` : `${Math.round(c.bitrate / 1e3)} kbps`
|
|
556
556
|
})).reverse(), i.onLevels(n.levels);
|
|
557
557
|
}), s.on(r.Events.LEVEL_SWITCHED, (c, u) => {
|
|
558
|
-
const
|
|
559
|
-
|
|
558
|
+
const f = s.levels[u.level];
|
|
559
|
+
f && i.onLevelSwitch(f.height ? `${f.height}p` : `${Math.round(f.bitrate / 1e3)} kbps`);
|
|
560
560
|
});
|
|
561
|
-
let
|
|
561
|
+
let o = 0, l = 0, h = !1;
|
|
562
562
|
return s.on(r.Events.FRAG_BUFFERED, () => {
|
|
563
|
-
|
|
563
|
+
l = 0;
|
|
564
564
|
}), s.on(r.Events.ERROR, (c, u) => {
|
|
565
565
|
if (u.fatal)
|
|
566
566
|
switch (u.type) {
|
|
567
567
|
case r.ErrorTypes.NETWORK_ERROR:
|
|
568
|
-
|
|
568
|
+
l < 3 ? (l++, s.startLoad()) : (i.onError(`HLS network error: ${u.details}`, u), s.destroy());
|
|
569
569
|
break;
|
|
570
570
|
case r.ErrorTypes.MEDIA_ERROR:
|
|
571
|
-
|
|
571
|
+
o < 3 ? (o++, s.recoverMediaError()) : (i.onError(`HLS media error: ${u.details}`, u), s.destroy());
|
|
572
572
|
break;
|
|
573
573
|
default:
|
|
574
574
|
if (h)
|
|
@@ -584,7 +584,7 @@ function wt(r, t, e, i) {
|
|
|
584
584
|
}
|
|
585
585
|
}), s.loadSource(e), s.attachMedia(t), n;
|
|
586
586
|
}
|
|
587
|
-
class
|
|
587
|
+
class W {
|
|
588
588
|
constructor(t) {
|
|
589
589
|
this.cues = t;
|
|
590
590
|
}
|
|
@@ -592,17 +592,17 @@ class G {
|
|
|
592
592
|
const e = await fetch(t);
|
|
593
593
|
if (!e.ok) throw new Error(`Failed to load thumbnails VTT (${e.status})`);
|
|
594
594
|
const i = await e.text(), s = [];
|
|
595
|
-
for (const n of
|
|
596
|
-
const [
|
|
597
|
-
if (!
|
|
595
|
+
for (const n of J(i)) {
|
|
596
|
+
const [o, l] = n.text.trim().split("#");
|
|
597
|
+
if (!o) continue;
|
|
598
598
|
const h = {
|
|
599
599
|
start: n.start,
|
|
600
600
|
end: n.end,
|
|
601
|
-
src:
|
|
602
|
-
}, c =
|
|
601
|
+
src: nt(o, t)
|
|
602
|
+
}, c = l?.match(/xywh=(\d+),(\d+),(\d+),(\d+)/);
|
|
603
603
|
c && (h.xywh = { x: Number(c[1]), y: Number(c[2]), w: Number(c[3]), h: Number(c[4]) }), s.push(h);
|
|
604
604
|
}
|
|
605
|
-
return s.sort((n,
|
|
605
|
+
return s.sort((n, o) => n.start - o.start), new W(s);
|
|
606
606
|
}
|
|
607
607
|
cueAt(t) {
|
|
608
608
|
let e = 0, i = this.cues.length - 1;
|
|
@@ -615,7 +615,7 @@ class G {
|
|
|
615
615
|
return null;
|
|
616
616
|
}
|
|
617
617
|
}
|
|
618
|
-
const
|
|
618
|
+
const _t = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg>', St = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 6-6 6 6 6"/></svg>';
|
|
619
619
|
class M {
|
|
620
620
|
constructor(t) {
|
|
621
621
|
this.anchor = t, this.outsideListener = null, this.escListener = null, this.root = a("div", "imp-menu"), this.root.hidden = !0, this.backdrop = a("div", "imp-menu__backdrop"), this.backdrop.hidden = !0, this.backdrop.addEventListener("pointerdown", (e) => {
|
|
@@ -651,10 +651,10 @@ class M {
|
|
|
651
651
|
}
|
|
652
652
|
const s = a("button", "imp-menu__item imp-menu__row", { type: "button" }), n = a("span", "imp-menu__label");
|
|
653
653
|
n.textContent = i.label;
|
|
654
|
-
const
|
|
655
|
-
|
|
656
|
-
const
|
|
657
|
-
|
|
654
|
+
const o = a("span", "imp-menu__value");
|
|
655
|
+
o.textContent = i.value ?? "";
|
|
656
|
+
const l = a("span", "imp-menu__chevron");
|
|
657
|
+
l.innerHTML = _t, s.append(n, o, l), s.addEventListener("click", () => this.renderSettingsDetail(t, i)), e.append(s);
|
|
658
658
|
}
|
|
659
659
|
this.root.append(e);
|
|
660
660
|
}
|
|
@@ -668,15 +668,15 @@ class M {
|
|
|
668
668
|
s.textContent = t.label;
|
|
669
669
|
const n = a("span", "imp-switch");
|
|
670
670
|
return n.append(a("span", "imp-switch__knob")), i.classList.toggle("imp-menu__toggle--on", e.value), i.append(s, n), i.addEventListener("click", () => {
|
|
671
|
-
const
|
|
672
|
-
i.setAttribute("aria-checked", String(
|
|
671
|
+
const o = i.getAttribute("aria-checked") !== "true";
|
|
672
|
+
i.setAttribute("aria-checked", String(o)), i.classList.toggle("imp-menu__toggle--on", o), e.onChange(o);
|
|
673
673
|
}), i;
|
|
674
674
|
}
|
|
675
675
|
renderSettingsDetail(t, e) {
|
|
676
676
|
if (!e.section) return;
|
|
677
677
|
this.root.textContent = "";
|
|
678
678
|
const i = a("button", "imp-menu__item imp-menu__back", { type: "button" }), s = a("span", "imp-menu__chevron");
|
|
679
|
-
s.innerHTML =
|
|
679
|
+
s.innerHTML = St;
|
|
680
680
|
const n = a("span", "imp-menu__label");
|
|
681
681
|
n.textContent = e.label, i.append(s, n), i.addEventListener("click", () => this.renderSettingsRoot(t)), this.root.append(i), this.root.append(this.renderSection(e.section())), this.root.scrollTop = 0;
|
|
682
682
|
}
|
|
@@ -690,8 +690,8 @@ class M {
|
|
|
690
690
|
for (const i of t.items) {
|
|
691
691
|
const s = a("button", "imp-menu__item", { type: "button", role: "menuitemradio" });
|
|
692
692
|
if (s.setAttribute("aria-checked", String(i.active)), i.active && s.classList.add("imp-menu__item--active"), i.icon) {
|
|
693
|
-
const
|
|
694
|
-
|
|
693
|
+
const o = a("span", "imp-menu__icon");
|
|
694
|
+
L(o, i.icon), s.append(o);
|
|
695
695
|
}
|
|
696
696
|
const n = a("span", "imp-menu__label");
|
|
697
697
|
n.textContent = i.label, s.append(n), s.addEventListener("click", () => {
|
|
@@ -729,7 +729,7 @@ class Lt {
|
|
|
729
729
|
this.heatmap.hidden = !0, this.heatmap.textContent = "";
|
|
730
730
|
return;
|
|
731
731
|
}
|
|
732
|
-
this.heatmap.innerHTML = `<svg viewBox="0 0 1000 100" preserveAspectRatio="none" aria-hidden="true"><path d="${
|
|
732
|
+
this.heatmap.innerHTML = `<svg viewBox="0 0 1000 100" preserveAspectRatio="none" aria-hidden="true"><path d="${ut(t, e)}"/></svg>`, this.heatmap.hidden = !1;
|
|
733
733
|
}
|
|
734
734
|
setDuration(t) {
|
|
735
735
|
this.duration = Number.isFinite(t) ? t : 0, this.root.classList.toggle("imp-progress--live", !Number.isFinite(t)), this.chapters.length === 0 && this.setChapters([]);
|
|
@@ -742,10 +742,10 @@ class Lt {
|
|
|
742
742
|
n.start > s && i.push({ start: s, end: n.start, title: "" }), i.push(n), s = n.end;
|
|
743
743
|
this.duration > 0 && s < this.duration && i.push({ start: s, end: this.duration, title: "" });
|
|
744
744
|
for (const n of i) {
|
|
745
|
-
const
|
|
746
|
-
|
|
747
|
-
const
|
|
748
|
-
|
|
745
|
+
const o = a("div", "imp-progress__segment");
|
|
746
|
+
o.style.flexGrow = String(Math.max(n.end - n.start, 0.01));
|
|
747
|
+
const l = a("div", "imp-progress__fill");
|
|
748
|
+
o.append(l), this.track.append(o), this.segments.push({ chapter: n, root: o, fill: l });
|
|
749
749
|
}
|
|
750
750
|
}
|
|
751
751
|
setThumbnails(t) {
|
|
@@ -759,8 +759,8 @@ class Lt {
|
|
|
759
759
|
}
|
|
760
760
|
render(t) {
|
|
761
761
|
for (const { chapter: i, fill: s } of this.segments) {
|
|
762
|
-
const n = i.end - i.start,
|
|
763
|
-
s.style.transform = `scaleX(${
|
|
762
|
+
const n = i.end - i.start, o = n > 0 ? x((t - i.start) / n, 0, 1) : 0;
|
|
763
|
+
s.style.transform = `scaleX(${o})`;
|
|
764
764
|
}
|
|
765
765
|
const e = this.duration > 0 ? x(t / this.duration, 0, 1) : 0;
|
|
766
766
|
this.handle.style.left = `${e * 100}%`;
|
|
@@ -783,18 +783,18 @@ class Lt {
|
|
|
783
783
|
showTooltip(t) {
|
|
784
784
|
const e = this.timeFromEvent(t);
|
|
785
785
|
this.tooltipTime.textContent = _(e);
|
|
786
|
-
const i =
|
|
786
|
+
const i = et(this.chapters, e), s = !!i?.title;
|
|
787
787
|
this.tooltipChapter.textContent = i?.title ?? "", this.tooltipChapter.hidden = !s, this.tooltipCaption.classList.toggle("imp-progress__caption--time-only", !s);
|
|
788
788
|
const n = this.thumbnails?.cueAt(e) ?? null;
|
|
789
789
|
this.tooltip.classList.toggle("imp-progress__tooltip--thumb", !!n), n ? (this.tooltipThumb.hidden = !1, this.tooltipThumb.style.backgroundImage = `url("${n.src}")`, n.xywh ? (this.tooltipThumb.style.width = `${n.xywh.w}px`, this.tooltipThumb.style.height = `${n.xywh.h}px`, this.tooltipThumb.style.backgroundPosition = `-${n.xywh.x}px -${n.xywh.y}px`, this.tooltipThumb.style.backgroundSize = "auto") : (this.tooltipThumb.style.width = "160px", this.tooltipThumb.style.height = "90px", this.tooltipThumb.style.backgroundPosition = "center", this.tooltipThumb.style.backgroundSize = "cover")) : this.tooltipThumb.hidden = !0, this.tooltip.classList.add("imp-progress__tooltip--visible");
|
|
790
|
-
const
|
|
791
|
-
this.tooltip.style.left = `${x(
|
|
790
|
+
const o = this.root.getBoundingClientRect(), l = x(t.clientX - o.left, 0, o.width), h = this.tooltip.offsetWidth / 2;
|
|
791
|
+
this.tooltip.style.left = `${x(l, h, Math.max(h, o.width - h))}px`;
|
|
792
792
|
}
|
|
793
793
|
hideTooltip() {
|
|
794
794
|
this.tooltip.classList.remove("imp-progress__tooltip--visible");
|
|
795
795
|
}
|
|
796
796
|
}
|
|
797
|
-
class
|
|
797
|
+
class Tt {
|
|
798
798
|
constructor(t) {
|
|
799
799
|
this.player = t, this.rightItems = /* @__PURE__ */ new Map(), this.subtitlesBtn = null, this.settingsBtn = null, this.settingsMenu = null, this.subtitlesMenu = null, this.moreMenu = null, this.moreWrap = null, this.qualityBtn = null, this.qualityMenu = null, this.gearBtn = null, this.gearMenu = null, this.gear = { speed: !1, quality: !1, subtitles: !1 }, this.nextPreviewEl = null, this.nextPreviewOpts = null, this.scenesBtn = null, this.sceneTypeBtn = null, this.sceneTypeMenu = null, this.likeBtn = null, this.dislikeBtn = null, this.likeCountEl = null, this.dislikeCountEl = null, this.prevBtn = null, this.nextBtn = null, this.seekBackBtn = null, this.seekFwdBtn = null, this.centerPlayBtn = null, this.centerPrevBtn = null, this.centerNextBtn = null, this.collapsibles = [], this.overflowed = /* @__PURE__ */ new Set(), this.resizeObserver = null, this.reflowScheduled = !1, this.actionItems = [], this.wasPlayingBeforeScrub = !1, this.disposers = [], this.onWindowResize = null;
|
|
800
800
|
const { labels: e, icons: i } = t, s = t.controlsOptions;
|
|
@@ -804,17 +804,17 @@ class St {
|
|
|
804
804
|
t.scrubbing = !0, this.wasPlayingBeforeScrub = !t.paused, t.pause();
|
|
805
805
|
},
|
|
806
806
|
onScrubEnd: () => {
|
|
807
|
-
t.scrubbing = !1, this.wasPlayingBeforeScrub
|
|
807
|
+
t.scrubbing = !1, this.wasPlayingBeforeScrub ? t.play(!0) : t.started || t.play();
|
|
808
808
|
}
|
|
809
809
|
}, t.labels.seek), s.progress && this.root.append(this.progress.root);
|
|
810
810
|
const n = a("div", "imp-controls__row");
|
|
811
811
|
this.row = n, this.root.append(n);
|
|
812
|
-
const
|
|
813
|
-
this.rightGroup =
|
|
812
|
+
const o = a("div", "imp-controls__group"), l = a("div", "imp-controls__group");
|
|
813
|
+
this.rightGroup = l;
|
|
814
814
|
const h = a("div", "imp-controls__spacer");
|
|
815
|
-
this.chapterLabel = a("div", "imp-controls__chapter"), n.append(
|
|
816
|
-
const c = typeof s.seekButtons == "object" ? s.seekButtons : {}, u = c.back ?? t.seekStep,
|
|
817
|
-
if (this.seekLabelFn = c.label, s.playlist && t.hasPlaylist && !s.hidePrev && (this.prevBtn = b("imp-btn--prev", e.previous, i.previous), this.prevBtn.addEventListener("click", () => t.previous()),
|
|
815
|
+
this.chapterLabel = a("div", "imp-controls__chapter"), n.append(o, h, l), h.append(this.chapterLabel);
|
|
816
|
+
const c = typeof s.seekButtons == "object" ? s.seekButtons : {}, u = c.back ?? t.seekStep, f = c.forward ?? t.seekStep;
|
|
817
|
+
if (this.seekLabelFn = c.label, s.playlist && t.hasPlaylist && !s.hidePrev && (this.prevBtn = b("imp-btn--prev", e.previous, i.previous), this.prevBtn.addEventListener("click", () => t.previous()), o.append(this.prevBtn)), s.seekButtons && (this.seekBackBtn = b("imp-btn--seek-back", `${e.seekBack} ${u}s`, i.seekBack), this.addStepBadge(this.seekBackBtn, u, "back"), this.seekBackBtn.addEventListener("click", () => t.skip(-u)), o.append(this.seekBackBtn)), s.play && (this.playBtn = b("imp-btn--play", e.play, i.play), this.playBtn.addEventListener("click", () => t.togglePlay()), o.append(this.playBtn)), s.seekButtons && (this.seekFwdBtn = b("imp-btn--seek-forward", `${e.seekForward} ${f}s`, i.seekForward), this.addStepBadge(this.seekFwdBtn, f, "forward"), this.seekFwdBtn.addEventListener("click", () => t.skip(f)), o.append(this.seekFwdBtn)), s.playlist && t.hasPlaylist && !s.hideNext && (this.nextBtn = b("imp-btn--next", e.next, i.next), this.nextBtn.addEventListener("click", () => t.next()), o.append(this.nextBtn)), s.volume) {
|
|
818
818
|
const d = a("div", "imp-volume");
|
|
819
819
|
this.muteBtn = b("imp-btn--mute", e.mute, i.volumeHigh), this.muteBtn.addEventListener("click", () => t.toggleMute()), this.volumeSlider = a("input", "imp-volume__slider", {
|
|
820
820
|
type: "range",
|
|
@@ -824,9 +824,9 @@ class St {
|
|
|
824
824
|
"aria-label": e.volume
|
|
825
825
|
}), this.volumeSlider.addEventListener("input", () => {
|
|
826
826
|
t.setVolume(Number(this.volumeSlider.value));
|
|
827
|
-
}), d.append(this.muteBtn, this.volumeSlider),
|
|
827
|
+
}), d.append(this.muteBtn, this.volumeSlider), o.append(d);
|
|
828
828
|
}
|
|
829
|
-
s.time && (this.timeLabel = a("div", "imp-controls__time"), this.timeCurrent = a("span", "imp-controls__time-current"), this.timeTotal = a("span", "imp-controls__time-total"), this.timeLabel.append(this.timeCurrent, this.timeTotal), this.liveBadge = a("span", "imp-controls__live"), this.liveBadge.textContent = e.live, this.liveBadge.hidden = !0,
|
|
829
|
+
s.time && (this.timeLabel = a("div", "imp-controls__time"), this.timeCurrent = a("span", "imp-controls__time-current"), this.timeTotal = a("span", "imp-controls__time-total"), this.timeLabel.append(this.timeCurrent, this.timeTotal), this.liveBadge = a("span", "imp-controls__live"), this.liveBadge.textContent = e.live, this.liveBadge.hidden = !0, o.append(this.timeLabel, this.liveBadge)), this.buildLikeDislike();
|
|
830
830
|
for (const d of (t.actionsOptions.custom ?? []).filter((k) => k.placement === "bar")) {
|
|
831
831
|
const k = b(`imp-btn--custom imp-btn--custom-${d.id}`, d.title, d.icon ?? i.more);
|
|
832
832
|
k.addEventListener("click", () => t.emit("customaction", { id: d.id })), this.rightItems.set(`custom:${d.id}`, k), this.registerCollapsible({
|
|
@@ -837,8 +837,8 @@ class St {
|
|
|
837
837
|
section: () => this.simpleSection(`custom:${d.id}`, d.title, d.icon ?? i.more, () => t.emit("customaction", { id: d.id }))
|
|
838
838
|
});
|
|
839
839
|
}
|
|
840
|
-
const p = (d) => d === !1 ? "off" : d === "bar" ? "bar" : "gear", m = p(s.subtitles),
|
|
841
|
-
if (this.gear = { speed: y === "gear", quality:
|
|
840
|
+
const p = (d) => d === !1 ? "off" : d === "bar" ? "bar" : "gear", m = p(s.subtitles), v = p(s.quality), y = p(s.speed);
|
|
841
|
+
if (this.gear = { speed: y === "gear", quality: v === "gear", subtitles: m === "gear" }, m === "bar") {
|
|
842
842
|
this.subtitlesBtn = b("imp-btn--subtitles", e.subtitles, i.subtitles), this.subtitlesMenu = new M(this.subtitlesBtn);
|
|
843
843
|
const d = a("div", "imp-controls__menu-anchor");
|
|
844
844
|
d.append(this.subtitlesBtn, this.subtitlesMenu.root), this.subtitlesBtn.addEventListener("click", () => this.toggleSubtitlesMenu()), this.rightItems.set("subtitles", d), this.registerCollapsible({
|
|
@@ -849,7 +849,7 @@ class St {
|
|
|
849
849
|
section: () => this.subtitlesSection()
|
|
850
850
|
});
|
|
851
851
|
}
|
|
852
|
-
if (
|
|
852
|
+
if (v === "bar") {
|
|
853
853
|
this.qualityBtn = b("imp-btn--quality", e.quality, i.settings), this.qualityMenu = new M(this.qualityBtn);
|
|
854
854
|
const d = a("div", "imp-controls__menu-anchor");
|
|
855
855
|
d.append(this.qualityBtn, this.qualityMenu.root), this.qualityBtn.addEventListener("click", () => this.toggleQualityMenu()), this.rightItems.set("quality", d), this.registerCollapsible({
|
|
@@ -883,7 +883,7 @@ class St {
|
|
|
883
883
|
d.append(this.sceneTypeBtn, this.sceneTypeMenu.root), this.sceneTypeBtn.addEventListener("click", () => this.toggleSceneTypeMenu()), this.rightItems.set("sceneTypes", d), this.refreshSceneTypeButton(), this.registerCollapsible({
|
|
884
884
|
key: "sceneTypes",
|
|
885
885
|
el: d,
|
|
886
|
-
priority:
|
|
886
|
+
priority: 68,
|
|
887
887
|
available: () => t.sceneTypes.length > 0,
|
|
888
888
|
section: () => this.sceneTypeSection()
|
|
889
889
|
});
|
|
@@ -937,7 +937,7 @@ class St {
|
|
|
937
937
|
el: d,
|
|
938
938
|
priority: 82,
|
|
939
939
|
available: () => Number.isFinite(t.duration) && t.duration > 0,
|
|
940
|
-
section: () => this.simpleSection("seekFwd", `${e.seekForward} ${
|
|
940
|
+
section: () => this.simpleSection("seekFwd", `${e.seekForward} ${f}s`, i.seekForward, () => t.skip(f))
|
|
941
941
|
});
|
|
942
942
|
}
|
|
943
943
|
if (this.center = a("div", "imp-center-controls"), s.playlist && t.hasPlaylist && (this.centerPrevBtn = this.makeCenterButton("prev", e.previous, i.previous), this.centerPrevBtn.addEventListener("click", () => t.previous()), this.center.append(this.centerPrevBtn)), s.seekButtons) {
|
|
@@ -945,8 +945,8 @@ class St {
|
|
|
945
945
|
this.addStepBadge(d, u, "back"), d.addEventListener("click", () => t.skip(-u)), this.center.append(d);
|
|
946
946
|
}
|
|
947
947
|
if (s.play && (this.centerPlayBtn = this.makeCenterButton("play", e.play, i.play), this.centerPlayBtn.addEventListener("click", () => t.togglePlay()), this.center.append(this.centerPlayBtn)), s.seekButtons) {
|
|
948
|
-
const d = this.makeCenterButton("seek-forward", `${e.seekForward} ${
|
|
949
|
-
this.addStepBadge(d,
|
|
948
|
+
const d = this.makeCenterButton("seek-forward", `${e.seekForward} ${f}s`, i.seekForward);
|
|
949
|
+
this.addStepBadge(d, f, "forward"), d.addEventListener("click", () => t.skip(f)), this.center.append(d);
|
|
950
950
|
}
|
|
951
951
|
if (s.playlist && t.hasPlaylist && (this.centerNextBtn = this.makeCenterButton("next", e.next, i.next), this.centerNextBtn.addEventListener("click", () => t.next()), this.center.append(this.centerNextBtn)), this.center.style.display = "none", this.setupNextPreview(), this.gear.speed || this.gear.quality || this.gear.subtitles) {
|
|
952
952
|
this.gearBtn = b("imp-btn--settings", e.settings, i.settings), this.gearMenu = new M(this.gearBtn);
|
|
@@ -959,7 +959,7 @@ class St {
|
|
|
959
959
|
section: () => this.gearSections()
|
|
960
960
|
});
|
|
961
961
|
}
|
|
962
|
-
this.layoutRightCluster(
|
|
962
|
+
this.layoutRightCluster(l), this.buildMoreDropdown(l), this.bind(), this.syncVolume(), this.syncPlayState(), this.setLikeState(t.actionsOptions.likeState ?? null), typeof ResizeObserver < "u" && (this.resizeObserver = new ResizeObserver(() => this.scheduleReflow()), this.resizeObserver.observe(t.container)), this.onWindowResize = () => this.scheduleReflow(), window.addEventListener("resize", this.onWindowResize);
|
|
963
963
|
}
|
|
964
964
|
registerCollapsible(t) {
|
|
965
965
|
this.collapsibles.push(t);
|
|
@@ -975,19 +975,19 @@ class St {
|
|
|
975
975
|
if (i.length > 0) {
|
|
976
976
|
const n = /* @__PURE__ */ new Set();
|
|
977
977
|
s = [];
|
|
978
|
-
for (const
|
|
979
|
-
this.rightItems.has(
|
|
980
|
-
for (const
|
|
978
|
+
for (const o of i)
|
|
979
|
+
this.rightItems.has(o) && !n.has(o) && (s.push(o), n.add(o));
|
|
980
|
+
for (const o of e) n.has(o) || s.push(o);
|
|
981
981
|
}
|
|
982
982
|
for (const n of s) {
|
|
983
|
-
const
|
|
984
|
-
|
|
983
|
+
const o = this.rightItems.get(n);
|
|
984
|
+
o && t.append(o);
|
|
985
985
|
}
|
|
986
986
|
}
|
|
987
987
|
/** Center-cluster button — deliberately NOT `.imp-btn` (own sizing/look). */
|
|
988
988
|
makeCenterButton(t, e, i) {
|
|
989
989
|
const s = a("button", `imp-center-btn imp-center-btn--${t}`, { type: "button", "aria-label": e, title: e });
|
|
990
|
-
return
|
|
990
|
+
return L(s, i), s;
|
|
991
991
|
}
|
|
992
992
|
/** Caption under the seek arrow. Default "−15s"/"+15s"; overridable via `controls.seekButtons.label`. */
|
|
993
993
|
addStepBadge(t, e, i) {
|
|
@@ -1030,7 +1030,7 @@ class St {
|
|
|
1030
1030
|
if (t.textContent = "", !e) return;
|
|
1031
1031
|
if (e.icon) {
|
|
1032
1032
|
const s = a("span", "imp-scene-type__icon");
|
|
1033
|
-
|
|
1033
|
+
L(s, e.icon), t.append(s);
|
|
1034
1034
|
}
|
|
1035
1035
|
const i = a("span", "imp-scene-type__label");
|
|
1036
1036
|
i.textContent = e.title, t.append(i), t.setAttribute("aria-label", `${this.player.labels.sceneTypes}: ${e.title}`), t.title = e.title;
|
|
@@ -1086,12 +1086,12 @@ class St {
|
|
|
1086
1086
|
e.textContent = "";
|
|
1087
1087
|
const n = a("div", "imp-next-preview__kicker");
|
|
1088
1088
|
n.textContent = this.player.labels.next, e.append(n);
|
|
1089
|
-
const
|
|
1090
|
-
if (i.thumbnail &&
|
|
1091
|
-
const m = a("div", "imp-next-preview__thumb"),
|
|
1092
|
-
if (
|
|
1089
|
+
const o = q(s.poster);
|
|
1090
|
+
if (i.thumbnail && o) {
|
|
1091
|
+
const m = a("div", "imp-next-preview__thumb"), v = T(o);
|
|
1092
|
+
if (v.addEventListener("error", () => {
|
|
1093
1093
|
this.player.markSourceDead(s), this.nextPreviewEl && !this.nextPreviewEl.hidden && this.showNextPreview(t);
|
|
1094
|
-
}, { once: !0 }), m.append(
|
|
1094
|
+
}, { once: !0 }), m.append(v), i.duration && s.duration) {
|
|
1095
1095
|
const y = a("span", "imp-next-preview__duration");
|
|
1096
1096
|
y.textContent = _(s.duration), m.append(y);
|
|
1097
1097
|
}
|
|
@@ -1101,9 +1101,9 @@ class St {
|
|
|
1101
1101
|
const m = a("div", "imp-next-preview__title");
|
|
1102
1102
|
m.textContent = s.title, e.append(m);
|
|
1103
1103
|
}
|
|
1104
|
-
i.meta && s.previewMeta?.length && e.append(
|
|
1105
|
-
const
|
|
1106
|
-
e.style.left = `${p}px`, e.style.bottom = `${
|
|
1104
|
+
i.meta && s.previewMeta?.length && e.append(X(s.previewMeta, "imp-next-preview")), e.hidden = !1;
|
|
1105
|
+
const l = this.player.container.getBoundingClientRect(), h = t.getBoundingClientRect(), c = 8, u = e.offsetWidth, f = h.left - l.left + h.width / 2 - u / 2, p = Math.max(c, Math.min(f, l.width - u - c));
|
|
1106
|
+
e.style.left = `${p}px`, e.style.bottom = `${l.height - (h.top - l.top) + 10}px`;
|
|
1107
1107
|
}
|
|
1108
1108
|
hideNextPreview() {
|
|
1109
1109
|
this.nextPreviewEl && (this.nextPreviewEl.hidden = !0);
|
|
@@ -1158,21 +1158,21 @@ class St {
|
|
|
1158
1158
|
i.addTo && this.actionItems.push({ value: "addTo", label: s.addTo, icon: n.addTo, run: () => e.emit("action", { id: "addTo" }) }), i.share && this.actionItems.push({ value: "share", label: s.share, icon: n.share, run: () => void e.share() }), i.report && this.actionItems.push({ value: "report", label: s.report, icon: n.report, run: () => e.emit("action", { id: "report" }) });
|
|
1159
1159
|
for (const h of (i.custom ?? []).filter((c) => c.placement !== "bar"))
|
|
1160
1160
|
this.actionItems.push({ value: `custom:${h.id}`, label: h.title, icon: h.icon, run: () => e.emit("customaction", { id: h.id }) });
|
|
1161
|
-
const
|
|
1162
|
-
this.moreMenu = new M(
|
|
1163
|
-
const
|
|
1164
|
-
|
|
1161
|
+
const o = b("imp-btn--more", s.more, n.more);
|
|
1162
|
+
this.moreMenu = new M(o);
|
|
1163
|
+
const l = a("div", "imp-controls__menu-anchor imp-controls__more");
|
|
1164
|
+
l.append(o, this.moreMenu.root), o.addEventListener("click", () => {
|
|
1165
1165
|
this.closeMenus(this.moreMenu), this.moreMenu?.toggle(this.buildMoreSections());
|
|
1166
|
-
}), t.append(
|
|
1166
|
+
}), t.append(l), this.moreWrap = l;
|
|
1167
1167
|
}
|
|
1168
1168
|
/** ⋯ menu = overflowed controls (in display order) + consumer actions. */
|
|
1169
1169
|
buildMoreSections() {
|
|
1170
|
-
const t = [], e = /* @__PURE__ */ new Map(), i = [], s = ["prev", "next", "seekBack", "seekFwd", "like", "dislike", "scenes", "sceneTypes", "pip", "list", "subtitles", "speed", "quality", "gear"], n = (
|
|
1171
|
-
const h = s.indexOf(
|
|
1170
|
+
const t = [], e = /* @__PURE__ */ new Map(), i = [], s = ["prev", "next", "seekBack", "seekFwd", "like", "dislike", "scenes", "sceneTypes", "pip", "list", "subtitles", "speed", "quality", "gear"], n = (l) => {
|
|
1171
|
+
const h = s.indexOf(l);
|
|
1172
1172
|
return h === -1 ? s.length : h;
|
|
1173
|
-
},
|
|
1174
|
-
for (const
|
|
1175
|
-
const h =
|
|
1173
|
+
}, o = this.collapsibles.filter((l) => this.overflowed.has(l.key) && l.available()).sort((l, h) => n(l.key) - n(h.key));
|
|
1174
|
+
for (const l of o) {
|
|
1175
|
+
const h = l.section();
|
|
1176
1176
|
if (h)
|
|
1177
1177
|
for (const c of Array.isArray(h) ? h : [h])
|
|
1178
1178
|
if (!c.title && c.items.length === 1) {
|
|
@@ -1181,12 +1181,12 @@ class St {
|
|
|
1181
1181
|
} else
|
|
1182
1182
|
t.push(c);
|
|
1183
1183
|
}
|
|
1184
|
-
if (i.length > 0 && t.unshift({ title: "", items: i, onSelect: (
|
|
1185
|
-
const
|
|
1184
|
+
if (i.length > 0 && t.unshift({ title: "", items: i, onSelect: (l) => e.get(l)?.() }), this.actionItems.length > 0) {
|
|
1185
|
+
const l = new Map(this.actionItems.map((h) => [h.value, h.run]));
|
|
1186
1186
|
t.push({
|
|
1187
1187
|
title: "",
|
|
1188
1188
|
items: this.actionItems.map(({ value: h, label: c, icon: u }) => ({ value: h, label: c, icon: u, active: !1 })),
|
|
1189
|
-
onSelect: (h) =>
|
|
1189
|
+
onSelect: (h) => l.get(h)?.()
|
|
1190
1190
|
});
|
|
1191
1191
|
}
|
|
1192
1192
|
return t;
|
|
@@ -1239,28 +1239,28 @@ class St {
|
|
|
1239
1239
|
* the ⋯ menu can offer them. Unavailable controls are hidden outright.
|
|
1240
1240
|
*/
|
|
1241
1241
|
reflow() {
|
|
1242
|
-
const t = window.innerWidth <= 767,
|
|
1243
|
-
this.center.style.display =
|
|
1244
|
-
const
|
|
1242
|
+
const t = window.innerWidth <= 767, e = t && this.player.controlsOptions.mobileLayout === "center", s = this.player.controlsOptions.seekPlacement !== "bar" || t;
|
|
1243
|
+
this.center.style.display = s ? "flex" : "none", this.centerPrevBtn && (this.centerPrevBtn.style.display = e ? "" : "none"), this.centerNextBtn && (this.centerNextBtn.style.display = e ? "" : "none"), this.playBtn && (this.playBtn.style.display = e ? "none" : "");
|
|
1244
|
+
const n = (h) => h === "seekBack" || h === "seekFwd" ? s : h === "prev" || h === "next" ? e : !1;
|
|
1245
1245
|
this.overflowed.clear();
|
|
1246
|
-
for (const
|
|
1247
|
-
if (
|
|
1248
|
-
|
|
1246
|
+
for (const h of this.collapsibles) {
|
|
1247
|
+
if (n(h.key)) {
|
|
1248
|
+
h.el.style.display = "none";
|
|
1249
1249
|
continue;
|
|
1250
1250
|
}
|
|
1251
|
-
const
|
|
1252
|
-
|
|
1251
|
+
const c = h.available();
|
|
1252
|
+
h.el.style.display = c ? "" : "none", h.el.classList.remove("imp-collapsed");
|
|
1253
1253
|
}
|
|
1254
|
-
const
|
|
1255
|
-
let l =
|
|
1254
|
+
const o = this.collapsibles.filter((h) => h.available() && !n(h.key)).sort((h, c) => h.priority - c.priority);
|
|
1255
|
+
let l = o.length;
|
|
1256
1256
|
for (; l-- > 0 && this.overflowsRow(); ) {
|
|
1257
|
-
const
|
|
1258
|
-
if (!
|
|
1259
|
-
|
|
1257
|
+
const h = o.find((c) => !this.overflowed.has(c.key));
|
|
1258
|
+
if (!h) break;
|
|
1259
|
+
h.el.style.display = "none", h.el.classList.add("imp-collapsed"), this.overflowed.add(h.key);
|
|
1260
1260
|
}
|
|
1261
1261
|
if (this.moreWrap) {
|
|
1262
|
-
const
|
|
1263
|
-
this.moreWrap.style.display =
|
|
1262
|
+
const h = this.actionItems.length > 0 || this.overflowed.size > 0;
|
|
1263
|
+
this.moreWrap.style.display = h ? "" : "none";
|
|
1264
1264
|
}
|
|
1265
1265
|
}
|
|
1266
1266
|
overflowsRow() {
|
|
@@ -1330,7 +1330,7 @@ class St {
|
|
|
1330
1330
|
this.disposers = [], this.resizeObserver?.disconnect(), this.onWindowResize && window.removeEventListener("resize", this.onWindowResize), this.gearMenu?.destroy(), this.sceneTypeMenu?.destroy(), this.settingsMenu?.destroy(), this.subtitlesMenu?.destroy(), this.qualityMenu?.destroy(), this.moreMenu?.destroy(), this.nextPreviewEl?.remove(), this.root.remove();
|
|
1331
1331
|
}
|
|
1332
1332
|
}
|
|
1333
|
-
class
|
|
1333
|
+
class Bt {
|
|
1334
1334
|
constructor(t) {
|
|
1335
1335
|
this.root = a("div", "imp-poster"), this.image = a("div", "imp-poster__image"), this.image.hidden = !0, this.img = T(""), this.image.append(this.img);
|
|
1336
1336
|
const e = b("imp-poster__play", t.labels.play, t.icons.bigPlay);
|
|
@@ -1353,7 +1353,7 @@ class Tt {
|
|
|
1353
1353
|
this.root.hidden = !0;
|
|
1354
1354
|
}
|
|
1355
1355
|
}
|
|
1356
|
-
class
|
|
1356
|
+
class Et {
|
|
1357
1357
|
constructor(t) {
|
|
1358
1358
|
this.labels = t, this.channelUrl = null, this.custom = null, this.visible = { title: !0, description: !0, sponsor: !0 }, this.root = a("div", "imp-pause-screen"), this.root.hidden = !0, this.defaultContent = a("div", "imp-pause-screen__default"), this.channel = a("button", "imp-channel", { type: "button" }), this.channel.hidden = !0, this.channelAvatar = a("div", "imp-channel__avatar"), this.channelName = a("div", "imp-channel__name"), this.channel.append(this.channelName, this.channelAvatar), this.channel.addEventListener("click", () => {
|
|
1359
1359
|
this.channelUrl && window.open(this.channelUrl, "_blank", "noopener");
|
|
@@ -1390,7 +1390,7 @@ class Bt {
|
|
|
1390
1390
|
this.root.hidden = !0;
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
1393
|
-
class
|
|
1393
|
+
class Mt {
|
|
1394
1394
|
constructor(t) {
|
|
1395
1395
|
this.player = t, this.clickBehavior = "player", this.root = a("div", "imp-related"), this.root.hidden = !0, this.heading = a("div", "imp-related__title"), this.grid = a("div", "imp-related__grid");
|
|
1396
1396
|
const e = b("imp-related__close", t.labels.close, t.icons.close);
|
|
@@ -1439,7 +1439,7 @@ class Et {
|
|
|
1439
1439
|
this.root.hidden = !0;
|
|
1440
1440
|
}
|
|
1441
1441
|
}
|
|
1442
|
-
class
|
|
1442
|
+
class Ct {
|
|
1443
1443
|
constructor(t) {
|
|
1444
1444
|
this.player = t, this.root = a("div", "imp-upnext"), this.root.hidden = !0;
|
|
1445
1445
|
}
|
|
@@ -1458,29 +1458,29 @@ class Mt {
|
|
|
1458
1458
|
s.textContent = e.nextVideo, i.append(s);
|
|
1459
1459
|
const n = q(t.poster);
|
|
1460
1460
|
if (n) {
|
|
1461
|
-
const
|
|
1461
|
+
const l = a("button", "imp-upnext__thumb", { type: "button", "aria-label": e.playNext }), h = T(n);
|
|
1462
1462
|
if (h.addEventListener("error", () => {
|
|
1463
1463
|
this.player.markSourceDead(t), this.root.hidden || this.show();
|
|
1464
|
-
}, { once: !0 }),
|
|
1464
|
+
}, { once: !0 }), l.append(h), t.duration) {
|
|
1465
1465
|
const u = a("span", "imp-upnext__duration");
|
|
1466
|
-
u.textContent = _(t.duration),
|
|
1466
|
+
u.textContent = _(t.duration), l.append(u);
|
|
1467
1467
|
}
|
|
1468
1468
|
const c = a("span", "imp-upnext__thumb-play");
|
|
1469
|
-
|
|
1469
|
+
L(c, this.player.icons.bigPlay), l.append(c), l.addEventListener("click", () => this.player.next()), i.append(l);
|
|
1470
1470
|
}
|
|
1471
1471
|
if (t.title) {
|
|
1472
|
-
const
|
|
1473
|
-
|
|
1472
|
+
const l = a("div", "imp-upnext__title");
|
|
1473
|
+
l.textContent = t.title, i.append(l);
|
|
1474
1474
|
}
|
|
1475
|
-
t.previewMeta?.length && i.append(
|
|
1476
|
-
const
|
|
1477
|
-
|
|
1475
|
+
t.previewMeta?.length && i.append(X(t.previewMeta, "imp-upnext"));
|
|
1476
|
+
const o = a("button", "imp-upnext__btn", { type: "button" });
|
|
1477
|
+
o.textContent = e.playNext, o.addEventListener("click", () => this.player.next()), i.append(o), this.root.append(i), this.root.hidden = !1;
|
|
1478
1478
|
}
|
|
1479
1479
|
hide() {
|
|
1480
1480
|
this.root.hidden = !0;
|
|
1481
1481
|
}
|
|
1482
1482
|
}
|
|
1483
|
-
class
|
|
1483
|
+
class Pt {
|
|
1484
1484
|
constructor(t, e = "sidebar", i) {
|
|
1485
1485
|
this.player = t, this.root = a("div", `imp-playlist imp-playlist--${e}`), this.root.hidden = !0;
|
|
1486
1486
|
const s = a("div", "imp-playlist__header"), n = a("div", "imp-playlist__heading");
|
|
@@ -1491,14 +1491,14 @@ class Ct {
|
|
|
1491
1491
|
c.textContent = i, n.append(h, c);
|
|
1492
1492
|
} else
|
|
1493
1493
|
n.textContent = t.labels.playlist;
|
|
1494
|
-
const
|
|
1494
|
+
const o = a("div", "imp-playlist__tools");
|
|
1495
1495
|
this.shuffleBtn = b("imp-playlist__shuffle", t.labels.shuffle, t.icons.shuffle), this.shuffleBtn.addEventListener("click", () => {
|
|
1496
1496
|
t.setShuffle(!t.shuffle), this.syncModes();
|
|
1497
1497
|
}), this.repeatBtn = b("imp-playlist__repeat", t.labels.repeat, t.icons.repeat), this.repeatBtn.addEventListener("click", () => {
|
|
1498
1498
|
t.setRepeat(!t.repeat), this.syncModes();
|
|
1499
1499
|
});
|
|
1500
|
-
const
|
|
1501
|
-
|
|
1500
|
+
const l = b("imp-playlist__close", t.labels.close, t.icons.close);
|
|
1501
|
+
l.addEventListener("click", () => this.hide()), o.append(this.shuffleBtn, this.repeatBtn, l), s.append(n, o), this.list = a("div", "imp-playlist__list"), this.root.append(s, this.list), this.rebuild(), this.syncModes();
|
|
1502
1502
|
}
|
|
1503
1503
|
syncModes() {
|
|
1504
1504
|
this.shuffleBtn.classList.toggle("imp-btn--active", this.player.shuffle), this.repeatBtn.classList.toggle("imp-btn--active", this.player.repeat);
|
|
@@ -1509,12 +1509,12 @@ class Ct {
|
|
|
1509
1509
|
e === this.player.index && i.classList.add("imp-playlist__item--active");
|
|
1510
1510
|
const s = a("div", "imp-playlist__thumb"), n = q(t.poster);
|
|
1511
1511
|
n && s.append(T(n));
|
|
1512
|
-
const
|
|
1513
|
-
if (
|
|
1512
|
+
const o = a("div", "imp-playlist__meta"), l = a("div", "imp-playlist__title");
|
|
1513
|
+
if (l.textContent = t.title ?? `#${e + 1}`, o.append(l), t.duration) {
|
|
1514
1514
|
const h = a("div", "imp-playlist__duration");
|
|
1515
|
-
h.textContent = _(t.duration),
|
|
1515
|
+
h.textContent = _(t.duration), o.append(h);
|
|
1516
1516
|
}
|
|
1517
|
-
i.append(s,
|
|
1517
|
+
i.append(s, o), i.addEventListener("click", () => {
|
|
1518
1518
|
this.player.playItem(e), window.innerWidth <= 767 && this.hide();
|
|
1519
1519
|
}), this.list.append(i);
|
|
1520
1520
|
});
|
|
@@ -1532,7 +1532,7 @@ class Ct {
|
|
|
1532
1532
|
this.visible ? this.hide() : this.show();
|
|
1533
1533
|
}
|
|
1534
1534
|
}
|
|
1535
|
-
class
|
|
1535
|
+
class At {
|
|
1536
1536
|
constructor(t, e = "bottom") {
|
|
1537
1537
|
this.player = t, this.items = [], this.root = a("div", `imp-playlist imp-scenes imp-playlist--${e}`), this.root.hidden = !0;
|
|
1538
1538
|
const i = a("div", "imp-playlist__header"), s = a("span");
|
|
@@ -1550,10 +1550,10 @@ class Pt {
|
|
|
1550
1550
|
const c = a("div", "imp-scenes__sprite");
|
|
1551
1551
|
c.style.width = `${n.xywh.w}px`, c.style.height = `${n.xywh.h}px`, c.style.backgroundImage = `url("${n.src}")`, c.style.backgroundPosition = `-${n.xywh.x}px -${n.xywh.y}px`, c.style.setProperty("--imp-sprite-w", String(n.xywh.w)), s.append(c);
|
|
1552
1552
|
} else n && s.append(T(n.src));
|
|
1553
|
-
const
|
|
1554
|
-
|
|
1553
|
+
const o = a("div", "imp-playlist__meta"), l = a("div", "imp-playlist__title");
|
|
1554
|
+
l.textContent = e.title || _(e.start);
|
|
1555
1555
|
const h = a("div", "imp-playlist__duration");
|
|
1556
|
-
h.textContent = _(e.start),
|
|
1556
|
+
h.textContent = _(e.start), o.append(l, h), i.append(s, o), i.addEventListener("click", () => {
|
|
1557
1557
|
this.player.seek(e.start), this.player.play(), window.innerWidth <= 767 && this.hide();
|
|
1558
1558
|
}), this.list.append(i), this.items.push(i);
|
|
1559
1559
|
}
|
|
@@ -1578,21 +1578,24 @@ class Pt {
|
|
|
1578
1578
|
this.visible ? this.hide() : this.show();
|
|
1579
1579
|
}
|
|
1580
1580
|
}
|
|
1581
|
-
let
|
|
1582
|
-
function
|
|
1581
|
+
let it = 0;
|
|
1582
|
+
function st(r) {
|
|
1583
1583
|
const t = r.reason;
|
|
1584
1584
|
t?.name === "AbortError" && /interrupted by a (new load request|call to pause)/i.test(t.message ?? "") && r.preventDefault();
|
|
1585
1585
|
}
|
|
1586
|
-
function At() {
|
|
1587
|
-
typeof window < "u" && ++et === 1 && window.addEventListener("unhandledrejection", it);
|
|
1588
|
-
}
|
|
1589
1586
|
function Rt() {
|
|
1590
|
-
typeof window < "u" &&
|
|
1587
|
+
typeof window < "u" && ++it === 1 && window.addEventListener("unhandledrejection", st);
|
|
1591
1588
|
}
|
|
1592
|
-
function
|
|
1589
|
+
function Nt() {
|
|
1590
|
+
typeof window < "u" && --it === 0 && window.removeEventListener("unhandledrejection", st);
|
|
1591
|
+
}
|
|
1592
|
+
function $(r) {
|
|
1593
|
+
console.debug("[itube-player] play() rejected:", r);
|
|
1594
|
+
}
|
|
1595
|
+
function K(r) {
|
|
1593
1596
|
return r ? typeof r == "string" ? [{ src: r, label: "Subtitles" }] : Array.isArray(r) ? r : [r] : [];
|
|
1594
1597
|
}
|
|
1595
|
-
const
|
|
1598
|
+
const It = {
|
|
1596
1599
|
play: !0,
|
|
1597
1600
|
progress: !0,
|
|
1598
1601
|
time: !0,
|
|
@@ -1611,6 +1614,8 @@ const Nt = {
|
|
|
1611
1614
|
seekButtons: !0,
|
|
1612
1615
|
// Prev/seek/play/next as a centered overlay on every viewport.
|
|
1613
1616
|
seekPlacement: "overlay",
|
|
1617
|
+
// Mobile: only ±N seek over the video; play/next live in the bottom bar.
|
|
1618
|
+
mobileLayout: "bar",
|
|
1614
1619
|
order: [],
|
|
1615
1620
|
// empty → built-in right-cluster order
|
|
1616
1621
|
playlist: !0,
|
|
@@ -1621,26 +1626,26 @@ const Nt = {
|
|
|
1621
1626
|
hideDelay: 2500,
|
|
1622
1627
|
revealBeforePlay: !0
|
|
1623
1628
|
};
|
|
1624
|
-
class
|
|
1629
|
+
class Ht {
|
|
1625
1630
|
constructor(t, e = {}) {
|
|
1626
|
-
this.scrubbing = !1, this.emitter = new
|
|
1631
|
+
this.scrubbing = !1, this.emitter = new rt(), this.externalAdvance = !1, this.abort = new AbortController(), this.sources = [], this.deadSources = /* @__PURE__ */ new WeakSet(), this.currentIndex = -1, this.sourceController = null, this.loadToken = 0, this.chapters = [], this.currentChapter = null, this.sceneGroupList = [], this.activeSceneGroupId = "", this.progressiveQuality = -1, this.thumbTrack = null, this.shuffleMode = !1, this.autoAdvanceEnabled = !0, this.persistKey = null, this.persistVolume = !1, this.persistAutoAdvance = !1, this.decodeRecoveries = 0, this.adManager = null, this.playedOnce = !1, this.idleTimer = null, this.peekTimer = null, this.lastRetryAt = 0, this.retryTimer = null, this.errorResumeTime = 0, this.lastPlayheadTime = 0, this.pendingSeek = null, this.destroyed = !1, this.persistTimer = null;
|
|
1627
1632
|
const i = typeof t == "string" ? document.querySelector(t) : t;
|
|
1628
1633
|
if (!i) throw new Error(`[itube-player] mount target not found: ${String(t)}`);
|
|
1629
|
-
this.mount = i, this.options = e, this.labels = { ...
|
|
1634
|
+
this.mount = i, this.options = e, this.labels = { ...G, ...at(e.language), ...e.labels }, this.icons = { ...ot, ...e.icons };
|
|
1630
1635
|
const s = e.controls ?? {}, n = s.speed ?? s.settings ?? "gear";
|
|
1631
|
-
if (this.controlsOptions = { ...
|
|
1636
|
+
if (this.controlsOptions = { ...It, ...s, speed: n, settings: n }, this.actionsOptions = e.actions ?? {}, this.playbackRates = e.playbackRates ?? [0.5, 1, 1.5, 2], this.seekStep = e.seekStep ?? 15, this.playlistOptions = { title: "", autoAdvance: !0, loop: !1, shuffle: !1, startIndex: 0, layout: "sidebar", externalAdvance: !1, ...e.playlist }, this.shuffleMode = this.playlistOptions.shuffle, this.externalAdvance = this.playlistOptions.externalAdvance, e.persist) {
|
|
1632
1637
|
const y = e.persist === !0 ? {} : e.persist;
|
|
1633
1638
|
this.persistKey = y.key ?? "itube-player", this.persistVolume = y.volume !== !1, this.persistAutoAdvance = y.autoAdvance !== !1;
|
|
1634
1639
|
}
|
|
1635
|
-
const
|
|
1636
|
-
this.autoAdvanceEnabled = this.persistAutoAdvance && typeof
|
|
1637
|
-
const
|
|
1638
|
-
if (
|
|
1639
|
-
const y = typeof
|
|
1640
|
+
const o = this.readPersisted();
|
|
1641
|
+
this.autoAdvanceEnabled = this.persistAutoAdvance && typeof o?.autoAdvance == "boolean" ? o.autoAdvance : this.playlistOptions.autoAdvance, this.sources = e.source ? Array.isArray(e.source) ? [...e.source] : [e.source] : [], this.container = a("div", "imp-player", { tabindex: "0" }), e.className && this.container.classList.add(e.className);
|
|
1642
|
+
const l = e.styling;
|
|
1643
|
+
if (l?.themeColor && this.container.style.setProperty("--imp-accent", l.themeColor), l?.likeColor && this.container.style.setProperty("--imp-like", l.likeColor), l?.dislikeColor && this.container.style.setProperty("--imp-dislike", l.dislikeColor), l?.fontFamily && this.container.style.setProperty("--imp-font", l.fontFamily), l?.borderRadius !== void 0) {
|
|
1644
|
+
const y = typeof l.borderRadius == "number" ? `${l.borderRadius}px` : l.borderRadius;
|
|
1640
1645
|
this.container.style.setProperty("--imp-radius", y);
|
|
1641
1646
|
}
|
|
1642
|
-
|
|
1643
|
-
const h = this.persistVolume ?
|
|
1647
|
+
l?.playButtonStyle === "inverted" && this.container.classList.add("imp-player--play-inverted"), this.video = e.videoElement ?? a("video", "imp-video"), this.video.classList.add("imp-video"), e.playsInline !== !1 && this.video.setAttribute("playsinline", ""), e.crossOrigin !== void 0 && (this.video.crossOrigin = e.crossOrigin), this.video.preload = "metadata", e.loop && (this.video.loop = !0);
|
|
1648
|
+
const h = this.persistVolume ? o : null;
|
|
1644
1649
|
this.video.volume = x(h?.volume ?? e.volume ?? 1, 0, 1), (h?.muted ?? e.muted) && (this.video.muted = !0);
|
|
1645
1650
|
const c = a("div", "imp-layer");
|
|
1646
1651
|
this.spinner = a("div", "imp-spinner"), this.spinner.hidden = !0, this.errorBox = a("div", "imp-error"), this.errorBox.hidden = !0, this.errorText = a("div", "imp-error__text"), this.retryBtn = a("button", "imp-error__retry", { type: "button" });
|
|
@@ -1648,21 +1653,21 @@ class Ot {
|
|
|
1648
1653
|
u.textContent = this.labels.tryAgain, this.retryBtn.append(u, a("span", "imp-error__retry-spinner")), this.retryBtn.addEventListener("click", () => this.retry()), this.errorNextBtn = a("button", "imp-error__next", { type: "button" }), this.errorNextBtn.textContent = this.labels.nextVideo, this.errorNextBtn.addEventListener("click", () => {
|
|
1649
1654
|
this.clearError(), this.next();
|
|
1650
1655
|
});
|
|
1651
|
-
const
|
|
1652
|
-
|
|
1656
|
+
const f = a("div", "imp-error__actions");
|
|
1657
|
+
f.append(this.retryBtn, this.errorNextBtn), this.errorBox.append(this.errorText, f), this.pauseScreen = new Et(this.labels), this.poster = new Bt(this), this.related = new Mt(this), this.related.setOptions(e.related), this.upNext = new Ct(this), this.controls = new Tt(this), this.playlistPanel = new Pt(this, this.playlistOptions.layout, this.playlistOptions.title || void 0), this.scenesPanel = new At(this, e.scenes?.layout ?? "bottom");
|
|
1653
1658
|
const p = a("div", "imp-layer__middle");
|
|
1654
1659
|
p.append(this.spinner, this.errorBox, this.controls.center);
|
|
1655
1660
|
const m = a("div", "imp-layer__bottom");
|
|
1656
1661
|
m.append(this.controls.root), c.append(this.pauseScreen.root, this.related.root, this.upNext.root, p, m), this.container.append(this.video, c, this.poster.root, this.playlistPanel.root, this.scenesPanel.root), this.mount.append(this.container), e.pauseScreen instanceof HTMLElement ? this.pauseScreen.setCustomContent(e.pauseScreen) : typeof e.pauseScreen == "function" ? this.pauseScreen.setCustomContent(e.pauseScreen(this)) : e.pauseScreen && typeof e.pauseScreen == "object" && this.pauseScreen.setVisibility(e.pauseScreen);
|
|
1657
|
-
const
|
|
1658
|
-
|
|
1662
|
+
const v = e.adConfig ?? e.ads;
|
|
1663
|
+
v && v.adList.length > 0 && (this.adManager = new gt(
|
|
1659
1664
|
{ container: this.container, contentVideo: this.video, emitter: this.emitter, labels: this.labels, closeIcon: this.icons.close },
|
|
1660
|
-
|
|
1665
|
+
v
|
|
1661
1666
|
)), this.emitter.on("error", ({ fatal: y }) => {
|
|
1662
1667
|
if (!y) return;
|
|
1663
1668
|
const d = this.lastPlayheadTime || this.video.currentTime;
|
|
1664
1669
|
Number.isFinite(d) && d > 0 && (this.errorResumeTime = d), this.errorText.textContent = this.labels.videoNotFound, this.errorNextBtn.hidden = !this.hasNext, this.errorBox.hidden = !1, this.spinner.hidden = !0, this.poster.hide(), this.container.classList.add("imp-player--error");
|
|
1665
|
-
}),
|
|
1670
|
+
}), Rt(), this.bindVideoEvents(), this.bindIdleHide(), e.keyboard !== !1 && this.bindKeyboard(), this.video.addEventListener("pointerup", (y) => {
|
|
1666
1671
|
if (!(this.adPlaying || !this.playedOnce)) {
|
|
1667
1672
|
if (y.pointerType === "mouse") {
|
|
1668
1673
|
this.togglePlay();
|
|
@@ -1722,12 +1727,11 @@ class Ot {
|
|
|
1722
1727
|
if (i === "NotSupportedError" && this.video.readyState === 0) {
|
|
1723
1728
|
const s = this.loadToken;
|
|
1724
1729
|
this.video.addEventListener("loadedmetadata", () => {
|
|
1725
|
-
s === this.loadToken && this.video.play().catch(
|
|
1726
|
-
});
|
|
1730
|
+
s === this.loadToken && this.video.play().catch($);
|
|
1727
1731
|
}, { once: !0, signal: this.abort.signal });
|
|
1728
1732
|
return;
|
|
1729
1733
|
}
|
|
1730
|
-
i !== "AbortError" &&
|
|
1734
|
+
i !== "AbortError" && ($(e), this.playedOnce || this.poster.show());
|
|
1731
1735
|
}
|
|
1732
1736
|
}
|
|
1733
1737
|
pause() {
|
|
@@ -1762,8 +1766,17 @@ class Ot {
|
|
|
1762
1766
|
clearError() {
|
|
1763
1767
|
this.errorBox.hidden = !0, this.container.classList.remove("imp-player--error");
|
|
1764
1768
|
}
|
|
1769
|
+
/** True once the current source has started playing at least once. */
|
|
1770
|
+
get started() {
|
|
1771
|
+
return this.playedOnce;
|
|
1772
|
+
}
|
|
1765
1773
|
seek(t) {
|
|
1766
|
-
Number.isFinite(this.video.duration)
|
|
1774
|
+
if (Number.isFinite(this.video.duration)) {
|
|
1775
|
+
this.video.currentTime = x(t, 0, this.video.duration);
|
|
1776
|
+
return;
|
|
1777
|
+
}
|
|
1778
|
+
const e = this.source?.duration;
|
|
1779
|
+
typeof e == "number" && e > 0 && (this.pendingSeek = x(t, 0, e));
|
|
1767
1780
|
}
|
|
1768
1781
|
/** Relative seek, e.g. `skip(-10)`. */
|
|
1769
1782
|
skip(t) {
|
|
@@ -1832,8 +1845,8 @@ class Ot {
|
|
|
1832
1845
|
setQuality(t) {
|
|
1833
1846
|
if (this.sourceController?.kind === "hls") {
|
|
1834
1847
|
this.sourceController.setLevel(t);
|
|
1835
|
-
const
|
|
1836
|
-
this.emitter.emit("qualitychange", { label:
|
|
1848
|
+
const o = t === -1 ? this.labels.qualityAuto : this.sourceController.levels.find((l) => l.index === t)?.label ?? String(t);
|
|
1849
|
+
this.emitter.emit("qualitychange", { label: o });
|
|
1837
1850
|
return;
|
|
1838
1851
|
}
|
|
1839
1852
|
const e = this.source?.qualities;
|
|
@@ -1847,14 +1860,13 @@ class Ot {
|
|
|
1847
1860
|
this.video.currentTime = i;
|
|
1848
1861
|
} catch {
|
|
1849
1862
|
}
|
|
1850
|
-
s && this.video.play().catch(
|
|
1851
|
-
});
|
|
1863
|
+
s && this.video.play().catch($);
|
|
1852
1864
|
}
|
|
1853
1865
|
}, { once: !0, signal: this.abort.signal }), this.emitter.emit("qualitychange", { label: e[t].label ?? String(e[t].quality ?? t) });
|
|
1854
1866
|
}
|
|
1855
1867
|
// === subtitles ========================================================
|
|
1856
1868
|
get subtitleTracks() {
|
|
1857
|
-
return
|
|
1869
|
+
return K(this.source?.subtitles);
|
|
1858
1870
|
}
|
|
1859
1871
|
get activeSubtitle() {
|
|
1860
1872
|
const t = this.video.textTracks;
|
|
@@ -2015,9 +2027,20 @@ class Ot {
|
|
|
2015
2027
|
setSceneGroup(t) {
|
|
2016
2028
|
t === this.activeSceneGroupId || !this.sceneGroupList.some((e) => e.id === t) || (this.activeSceneGroupId = t, this.applyActiveSceneGroup(), this.emitter.emit("scenetypechange", { group: this.activeSceneType }));
|
|
2017
2029
|
}
|
|
2030
|
+
/**
|
|
2031
|
+
* Best duration currently known: the media's real one once metadata is in,
|
|
2032
|
+
* else the declared `source.duration` (lets scene groups and the seek bar
|
|
2033
|
+
* render before the first play), else NaN.
|
|
2034
|
+
*/
|
|
2035
|
+
get knownDuration() {
|
|
2036
|
+
const t = this.video.duration;
|
|
2037
|
+
if (Number.isFinite(t) && t > 0) return t;
|
|
2038
|
+
const e = this.source?.duration;
|
|
2039
|
+
return typeof e == "number" && e > 0 ? e : NaN;
|
|
2040
|
+
}
|
|
2018
2041
|
/** Normalize the active group's scenes into `chapters` and refresh the UI. */
|
|
2019
2042
|
applyActiveSceneGroup() {
|
|
2020
|
-
this.chapters =
|
|
2043
|
+
this.chapters = j(this.activeSceneType?.scenes ?? [], this.knownDuration), this.currentChapter = null, this.controls.progress.setChapters(this.chapters), this.controls.syncFeatureButtons(), this.scenesPanel.visible && this.scenesPanel.rebuild();
|
|
2021
2044
|
}
|
|
2022
2045
|
// === actions ==========================================================
|
|
2023
2046
|
/**
|
|
@@ -2054,16 +2077,16 @@ class Ot {
|
|
|
2054
2077
|
}
|
|
2055
2078
|
// === teardown =========================================================
|
|
2056
2079
|
destroy() {
|
|
2057
|
-
this.destroyed || (this.destroyed = !0, this.loadToken++, this.adManager?.destroy(), this.controls.destroy(), this.sourceController?.destroy(), this.abort.abort(), this.idleTimer && clearTimeout(this.idleTimer), this.peekTimer && clearTimeout(this.peekTimer), this.retryTimer && clearTimeout(this.retryTimer), this.persistTimer && (clearTimeout(this.persistTimer), this.persistTimer = null, this.persistState()), this.container.remove(),
|
|
2080
|
+
this.destroyed || (this.destroyed = !0, this.loadToken++, this.adManager?.destroy(), this.controls.destroy(), this.sourceController?.destroy(), this.abort.abort(), this.idleTimer && clearTimeout(this.idleTimer), this.peekTimer && clearTimeout(this.peekTimer), this.retryTimer && clearTimeout(this.retryTimer), this.persistTimer && (clearTimeout(this.persistTimer), this.persistTimer = null, this.persistState()), this.container.remove(), Nt(), this.emitter.emit("destroy", void 0), this.emitter.removeAll());
|
|
2058
2081
|
}
|
|
2059
2082
|
// === internals ========================================================
|
|
2060
2083
|
async loadItem(t, e, i = !1) {
|
|
2061
2084
|
const s = ++this.loadToken, n = this.sources[t];
|
|
2062
2085
|
if (!n) return;
|
|
2063
|
-
this.currentIndex = t, this.sourceController?.destroy(), this.sourceController = null, this.chapters = [], this.currentChapter = null, this.sceneGroupList = [], this.activeSceneGroupId = "", this.progressiveQuality = -1, this.playedOnce = !1, this.lastPlayheadTime = 0, this.errorResumeTime = 0, this.endPeek();
|
|
2086
|
+
this.currentIndex = t, this.sourceController?.destroy(), this.sourceController = null, this.chapters = [], this.currentChapter = null, this.sceneGroupList = [], this.activeSceneGroupId = "", this.progressiveQuality = -1, this.playedOnce = !1, this.lastPlayheadTime = 0, this.errorResumeTime = 0, this.pendingSeek = null, this.endPeek();
|
|
2064
2087
|
for (const p of [...this.video.querySelectorAll("track")]) p.remove();
|
|
2065
|
-
this.adManager?.resetForNewSource(), this.related.hide(), this.upNext.hide(), this.pauseScreen.hide(), this.scenesPanel.hide(), this.thumbTrack = null, this.decodeRecoveries = 0, this.video.poster = q(n.poster) ?? "", this.poster.setSource(n), this.pauseScreen.setSource(n), this.controls.progress.setChapters([]), this.controls.progress.setThumbnails(null), this.controls.progress.setHeatmap([]), e ? this.poster.hide() : this.poster.show(), this.playlistPanel.rebuild();
|
|
2066
|
-
for (const p of
|
|
2088
|
+
this.adManager?.resetForNewSource(), this.related.hide(), this.upNext.hide(), this.pauseScreen.hide(), this.scenesPanel.hide(), this.thumbTrack = null, this.decodeRecoveries = 0, this.video.poster = q(n.poster) ?? "", this.poster.setSource(n), this.pauseScreen.setSource(n), this.controls.progress.setChapters([]), this.controls.progress.setThumbnails(null), this.controls.progress.setHeatmap([]), typeof n.duration == "number" && n.duration > 0 && this.controls.progress.update(0, n.duration, 0), e ? this.poster.hide() : this.poster.show(), this.playlistPanel.rebuild();
|
|
2089
|
+
for (const p of K(n.subtitles)) {
|
|
2067
2090
|
const m = a("track", "", {
|
|
2068
2091
|
kind: "subtitles",
|
|
2069
2092
|
src: p.src,
|
|
@@ -2072,13 +2095,13 @@ class Ot {
|
|
|
2072
2095
|
});
|
|
2073
2096
|
p.default && m.setAttribute("default", ""), this.video.append(m);
|
|
2074
2097
|
}
|
|
2075
|
-
let
|
|
2098
|
+
let o = n.src, l = n.type;
|
|
2076
2099
|
if (n.qualities && n.qualities.length > 0) {
|
|
2077
2100
|
const p = Math.max(0, n.qualities.findIndex((m) => m.src === n.src));
|
|
2078
|
-
this.progressiveQuality = p,
|
|
2101
|
+
this.progressiveQuality = p, o = n.qualities[p].src, l = n.qualities[p].type ?? l;
|
|
2079
2102
|
}
|
|
2080
2103
|
this.video.preload = this.adManager?.hasPendingPreRoll ? "auto" : "metadata";
|
|
2081
|
-
const h = await
|
|
2104
|
+
const h = await wt(this.video, o, l, {
|
|
2082
2105
|
onLevels: () => {
|
|
2083
2106
|
s === this.loadToken && this.controls.syncFeatureButtons();
|
|
2084
2107
|
},
|
|
@@ -2089,28 +2112,26 @@ class Ot {
|
|
|
2089
2112
|
h.destroy();
|
|
2090
2113
|
return;
|
|
2091
2114
|
}
|
|
2092
|
-
if (this.sourceController = h, this.emitter.emit("sourcechange", { source: n, index: t }), n.thumbnails &&
|
|
2115
|
+
if (this.sourceController = h, this.emitter.emit("sourcechange", { source: n, index: t }), n.thumbnails && W.load(n.thumbnails).then((p) => {
|
|
2093
2116
|
s === this.loadToken && (this.thumbTrack = p, this.controls.progress.setThumbnails(p), this.scenesPanel.visible && this.scenesPanel.rebuild());
|
|
2094
|
-
}).catch((p) => this.emitter.emit("error", { message: "Failed to load thumbnails track", cause: p })), n.sceneGroups && n.sceneGroups.length > 0)
|
|
2095
|
-
this.sceneGroupList = n.sceneGroups, this.activeSceneGroupId = n.sceneGroups[0].id
|
|
2096
|
-
const p = () => {
|
|
2117
|
+
}).catch((p) => this.emitter.emit("error", { message: "Failed to load thumbnails track", cause: p })), n.sceneGroups && n.sceneGroups.length > 0)
|
|
2118
|
+
this.sceneGroupList = n.sceneGroups, this.activeSceneGroupId = n.sceneGroups[0].id, this.applyActiveSceneGroup(), Number.isFinite(this.video.duration) && this.video.duration > 0 || this.video.addEventListener("loadedmetadata", () => {
|
|
2097
2119
|
s === this.loadToken && this.applyActiveSceneGroup();
|
|
2098
|
-
};
|
|
2099
|
-
|
|
2100
|
-
} else if (n.chapters) {
|
|
2120
|
+
}, { once: !0, signal: this.abort.signal });
|
|
2121
|
+
else if (n.chapters) {
|
|
2101
2122
|
const p = (m) => {
|
|
2102
|
-
const
|
|
2103
|
-
s === this.loadToken && (this.chapters =
|
|
2123
|
+
const v = () => {
|
|
2124
|
+
s === this.loadToken && (this.chapters = j(m, this.knownDuration), this.controls.progress.setChapters(this.chapters), this.controls.syncFeatureButtons(), this.scenesPanel.visible && this.scenesPanel.rebuild());
|
|
2104
2125
|
};
|
|
2105
|
-
Number.isFinite(this.video.duration) && this.video.duration > 0 ?
|
|
2126
|
+
Number.isFinite(this.video.duration) && this.video.duration > 0 ? v() : this.video.addEventListener("loadedmetadata", v, { once: !0, signal: this.abort.signal });
|
|
2106
2127
|
};
|
|
2107
|
-
typeof n.chapters == "string" ?
|
|
2128
|
+
typeof n.chapters == "string" ? yt(n.chapters).then((m) => p(m)).catch((m) => this.emitter.emit("error", { message: "Failed to load chapters track", cause: m })) : p(n.chapters);
|
|
2108
2129
|
}
|
|
2109
|
-
const c = n.heatmap, u = c && !Array.isArray(c),
|
|
2110
|
-
if (c &&
|
|
2130
|
+
const c = n.heatmap, u = c && !Array.isArray(c), f = u ? c.values.length > 0 : !!(c && c.length > 0);
|
|
2131
|
+
if (c && f && this.controlsOptions.heatmap) {
|
|
2111
2132
|
const p = () => {
|
|
2112
2133
|
if (s !== this.loadToken) return;
|
|
2113
|
-
const m = u ?
|
|
2134
|
+
const m = u ? dt(c.values, c.mode) : ct(c, this.video.duration);
|
|
2114
2135
|
this.controls.progress.setHeatmap(m, u ? c.smoothing ?? 1 : 1);
|
|
2115
2136
|
};
|
|
2116
2137
|
u || Number.isFinite(this.video.duration) && this.video.duration > 0 ? p() : this.video.addEventListener("loadedmetadata", p, { once: !0, signal: this.abort.signal });
|
|
@@ -2127,12 +2148,22 @@ class Ot {
|
|
|
2127
2148
|
this.handleEnded();
|
|
2128
2149
|
}, { signal: t }), e.addEventListener("timeupdate", () => {
|
|
2129
2150
|
!this.adPlaying && e.currentTime > 0 && (this.lastPlayheadTime = e.currentTime), this.emitter.emit("timeupdate", { currentTime: e.currentTime, duration: e.duration || 0 }), this.adManager?.checkMidRolls(e.currentTime);
|
|
2130
|
-
const i =
|
|
2151
|
+
const i = et(this.chapters, e.currentTime);
|
|
2131
2152
|
i !== this.currentChapter && (this.currentChapter = i, this.emitter.emit("chapterchange", { chapter: i }));
|
|
2132
2153
|
}, { signal: t }), e.addEventListener("progress", () => {
|
|
2133
2154
|
this.emitter.emit("progress", { buffered: this.bufferedEnd });
|
|
2134
2155
|
}, { signal: t }), e.addEventListener("volumechange", () => {
|
|
2135
2156
|
this.emitter.emit("volumechange", { volume: e.volume, muted: e.muted }), this.persistVolume && this.schedulePersist();
|
|
2157
|
+
}, { signal: t }), e.addEventListener("loadedmetadata", () => {
|
|
2158
|
+
if (this.pendingSeek !== null) {
|
|
2159
|
+
const i = x(this.pendingSeek, 0, Number.isFinite(e.duration) ? e.duration : this.pendingSeek);
|
|
2160
|
+
this.pendingSeek = null;
|
|
2161
|
+
try {
|
|
2162
|
+
e.currentTime = i;
|
|
2163
|
+
} catch {
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
!this.playedOnce && Number.isFinite(e.duration) && this.controls.progress.update(e.currentTime, e.duration, this.bufferedEnd);
|
|
2136
2167
|
}, { signal: t }), e.addEventListener("seeking", () => this.emitter.emit("seeking", { currentTime: e.currentTime }), { signal: t }), e.addEventListener("seeked", () => this.emitter.emit("seeked", { currentTime: e.currentTime }), { signal: t }), e.addEventListener("waiting", () => {
|
|
2137
2168
|
this.spinner.hidden = !1;
|
|
2138
2169
|
}, { signal: t });
|
|
@@ -2145,17 +2176,16 @@ class Ot {
|
|
|
2145
2176
|
if (!i || this.sourceController?.kind === "hls" || e.getAttribute("src") === null && !e.currentSrc) return;
|
|
2146
2177
|
if ((i.code === MediaError.MEDIA_ERR_DECODE || /DEMUXER|PARSE|DECODE/i.test(i.message || "")) && this.decodeRecoveries < 2 && Number.isFinite(e.duration)) {
|
|
2147
2178
|
this.decodeRecoveries++;
|
|
2148
|
-
const n = e.currentTime,
|
|
2179
|
+
const n = e.currentTime, o = !e.paused;
|
|
2149
2180
|
e.load();
|
|
2150
|
-
const
|
|
2181
|
+
const l = () => {
|
|
2151
2182
|
try {
|
|
2152
2183
|
e.currentTime = n;
|
|
2153
2184
|
} catch {
|
|
2154
2185
|
}
|
|
2155
|
-
|
|
2156
|
-
});
|
|
2186
|
+
o && e.play().catch($);
|
|
2157
2187
|
};
|
|
2158
|
-
e.readyState >= 1 ?
|
|
2188
|
+
e.readyState >= 1 ? l() : e.addEventListener("loadedmetadata", l, { once: !0, signal: this.abort.signal });
|
|
2159
2189
|
return;
|
|
2160
2190
|
}
|
|
2161
2191
|
this.emitter.emit("error", { message: i.message || `Media error (code ${i.code})`, cause: i, fatal: !0 });
|
|
@@ -2273,22 +2303,22 @@ class Ot {
|
|
|
2273
2303
|
}
|
|
2274
2304
|
}
|
|
2275
2305
|
export {
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2306
|
+
rt as Emitter,
|
|
2307
|
+
Ht as Player,
|
|
2308
|
+
W as ThumbnailTrack,
|
|
2309
|
+
ct as buildHeatmapValues,
|
|
2310
|
+
et as chapterAt,
|
|
2311
|
+
ot as defaultIcons,
|
|
2312
|
+
G as defaultLabels,
|
|
2283
2313
|
_ as formatTime,
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2314
|
+
at as getLocale,
|
|
2315
|
+
ut as heatmapPath,
|
|
2316
|
+
bt as isHlsSource,
|
|
2317
|
+
yt as loadChaptersVtt,
|
|
2318
|
+
j as normalizeChapters,
|
|
2289
2319
|
qt as registerLocale,
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2320
|
+
Vt as registerLocales,
|
|
2321
|
+
Ot as registeredLanguages,
|
|
2322
|
+
pt as resolveVast
|
|
2293
2323
|
};
|
|
2294
2324
|
//# sourceMappingURL=core.js.map
|