@moq/watch 0.2.6 → 0.2.7
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/audio/buffer.d.ts +33 -0
- package/audio/buffer.d.ts.map +1 -0
- package/audio/decoder.d.ts.map +1 -1
- package/audio/render.d.ts +20 -11
- package/audio/render.d.ts.map +1 -1
- package/audio/shared-ring-buffer.d.ts +55 -0
- package/audio/shared-ring-buffer.d.ts.map +1 -0
- package/audio/shared-ring-buffer.test.d.ts +2 -0
- package/audio/shared-ring-buffer.test.d.ts.map +1 -0
- package/audio/source.d.ts.map +1 -1
- package/backend.d.ts +2 -1
- package/backend.d.ts.map +1 -1
- package/broadcast-BMWX8K5V.js +4481 -0
- package/broadcast-BMWX8K5V.js.map +1 -0
- package/element.js +1 -1
- package/index.js +2 -2
- package/package.json +1 -1
- package/sync.d.ts +1 -0
- package/sync.d.ts.map +1 -1
- package/ui/context.d.ts.map +1 -1
- package/ui/index.js +33 -33
- package/ui/index.js.map +1 -1
- package/broadcast-BdsV4u8m.js +0 -6925
- package/broadcast-BdsV4u8m.js.map +0 -1
|
@@ -0,0 +1,4481 @@
|
|
|
1
|
+
import * as M from "@moq/lite";
|
|
2
|
+
import { Time as m, Path as $t } from "@moq/lite";
|
|
3
|
+
import { Signal as h, Effect as T } from "@moq/signals";
|
|
4
|
+
function w(t, e, n) {
|
|
5
|
+
function s(a, c) {
|
|
6
|
+
if (a._zod || Object.defineProperty(a, "_zod", {
|
|
7
|
+
value: {
|
|
8
|
+
def: c,
|
|
9
|
+
constr: o,
|
|
10
|
+
traits: /* @__PURE__ */ new Set()
|
|
11
|
+
},
|
|
12
|
+
enumerable: !1
|
|
13
|
+
}), a._zod.traits.has(t))
|
|
14
|
+
return;
|
|
15
|
+
a._zod.traits.add(t), e(a, c);
|
|
16
|
+
const u = o.prototype, l = Object.keys(u);
|
|
17
|
+
for (let d = 0; d < l.length; d++) {
|
|
18
|
+
const f = l[d];
|
|
19
|
+
f in a || (a[f] = u[f].bind(a));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const i = n?.Parent ?? Object;
|
|
23
|
+
class r extends i {
|
|
24
|
+
}
|
|
25
|
+
Object.defineProperty(r, "name", { value: t });
|
|
26
|
+
function o(a) {
|
|
27
|
+
var c;
|
|
28
|
+
const u = n?.Parent ? new r() : this;
|
|
29
|
+
s(u, a), (c = u._zod).deferred ?? (c.deferred = []);
|
|
30
|
+
for (const l of u._zod.deferred)
|
|
31
|
+
l();
|
|
32
|
+
return u;
|
|
33
|
+
}
|
|
34
|
+
return Object.defineProperty(o, "init", { value: s }), Object.defineProperty(o, Symbol.hasInstance, {
|
|
35
|
+
value: (a) => n?.Parent && a instanceof n.Parent ? !0 : a?._zod?.traits?.has(t)
|
|
36
|
+
}), Object.defineProperty(o, "name", { value: t }), o;
|
|
37
|
+
}
|
|
38
|
+
class K extends Error {
|
|
39
|
+
constructor() {
|
|
40
|
+
super("Encountered Promise during synchronous parse. Use .parseAsync() instead.");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
class Ft extends Error {
|
|
44
|
+
constructor(e) {
|
|
45
|
+
super(`Encountered unidirectional transform during encode: ${e}`), this.name = "ZodEncodeError";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const jt = {};
|
|
49
|
+
function Q(t) {
|
|
50
|
+
return jt;
|
|
51
|
+
}
|
|
52
|
+
function Zt(t, e) {
|
|
53
|
+
return typeof e == "bigint" ? e.toString() : e;
|
|
54
|
+
}
|
|
55
|
+
function Ke(t) {
|
|
56
|
+
return {
|
|
57
|
+
get value() {
|
|
58
|
+
{
|
|
59
|
+
const e = t();
|
|
60
|
+
return Object.defineProperty(this, "value", { value: e }), e;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function Je(t) {
|
|
66
|
+
const e = t.startsWith("^") ? 1 : 0, n = t.endsWith("$") ? t.length - 1 : t.length;
|
|
67
|
+
return t.slice(e, n);
|
|
68
|
+
}
|
|
69
|
+
const Re = /* @__PURE__ */ Symbol("evaluating");
|
|
70
|
+
function U(t, e, n) {
|
|
71
|
+
let s;
|
|
72
|
+
Object.defineProperty(t, e, {
|
|
73
|
+
get() {
|
|
74
|
+
if (s !== Re)
|
|
75
|
+
return s === void 0 && (s = Re, s = n()), s;
|
|
76
|
+
},
|
|
77
|
+
set(i) {
|
|
78
|
+
Object.defineProperty(t, e, {
|
|
79
|
+
value: i
|
|
80
|
+
// configurable: true,
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
configurable: !0
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const Qe = "captureStackTrace" in Error ? Error.captureStackTrace : (...t) => {
|
|
87
|
+
};
|
|
88
|
+
function pe(t) {
|
|
89
|
+
return typeof t == "object" && t !== null && !Array.isArray(t);
|
|
90
|
+
}
|
|
91
|
+
function et(t) {
|
|
92
|
+
if (pe(t) === !1)
|
|
93
|
+
return !1;
|
|
94
|
+
const e = t.constructor;
|
|
95
|
+
if (e === void 0 || typeof e != "function")
|
|
96
|
+
return !0;
|
|
97
|
+
const n = e.prototype;
|
|
98
|
+
return !(pe(n) === !1 || Object.prototype.hasOwnProperty.call(n, "isPrototypeOf") === !1);
|
|
99
|
+
}
|
|
100
|
+
function Vt(t) {
|
|
101
|
+
return et(t) ? { ...t } : Array.isArray(t) ? [...t] : t;
|
|
102
|
+
}
|
|
103
|
+
function Be(t) {
|
|
104
|
+
return t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
105
|
+
}
|
|
106
|
+
function Wt(t, e, n) {
|
|
107
|
+
const s = new t._zod.constr(e ?? t._zod.def);
|
|
108
|
+
return (!e || n?.parent) && (s._zod.parent = t), s;
|
|
109
|
+
}
|
|
110
|
+
function I(t) {
|
|
111
|
+
return {};
|
|
112
|
+
}
|
|
113
|
+
function qt(t) {
|
|
114
|
+
return Object.keys(t).filter((e) => t[e]._zod.optin === "optional" && t[e]._zod.optout === "optional");
|
|
115
|
+
}
|
|
116
|
+
const Ht = {
|
|
117
|
+
safeint: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER],
|
|
118
|
+
int32: [-2147483648, 2147483647],
|
|
119
|
+
uint32: [0, 4294967295],
|
|
120
|
+
float32: [-34028234663852886e22, 34028234663852886e22],
|
|
121
|
+
float64: [-Number.MAX_VALUE, Number.MAX_VALUE]
|
|
122
|
+
};
|
|
123
|
+
function re(t, e = 0) {
|
|
124
|
+
if (t.aborted === !0)
|
|
125
|
+
return !0;
|
|
126
|
+
for (let n = e; n < t.issues.length; n++)
|
|
127
|
+
if (t.issues[n]?.continue !== !0)
|
|
128
|
+
return !0;
|
|
129
|
+
return !1;
|
|
130
|
+
}
|
|
131
|
+
function X(t, e) {
|
|
132
|
+
return e.map((n) => {
|
|
133
|
+
var s;
|
|
134
|
+
return (s = n).path ?? (s.path = []), n.path.unshift(t), n;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function fe(t) {
|
|
138
|
+
return typeof t == "string" ? t : t?.message;
|
|
139
|
+
}
|
|
140
|
+
function ee(t, e, n) {
|
|
141
|
+
const s = { ...t, path: t.path ?? [] };
|
|
142
|
+
if (!t.message) {
|
|
143
|
+
const i = fe(t.inst?._zod.def?.error?.(t)) ?? fe(e?.error?.(t)) ?? fe(n.customError?.(t)) ?? fe(n.localeError?.(t)) ?? "Invalid input";
|
|
144
|
+
s.message = i;
|
|
145
|
+
}
|
|
146
|
+
return delete s.inst, delete s.continue, e?.reportInput || delete s.input, s;
|
|
147
|
+
}
|
|
148
|
+
const tt = (t, e) => {
|
|
149
|
+
t.name = "$ZodError", Object.defineProperty(t, "_zod", {
|
|
150
|
+
value: t._zod,
|
|
151
|
+
enumerable: !1
|
|
152
|
+
}), Object.defineProperty(t, "issues", {
|
|
153
|
+
value: e,
|
|
154
|
+
enumerable: !1
|
|
155
|
+
}), t.message = JSON.stringify(e, Zt, 2), Object.defineProperty(t, "toString", {
|
|
156
|
+
value: () => t.message,
|
|
157
|
+
enumerable: !1
|
|
158
|
+
});
|
|
159
|
+
}, Gt = w("$ZodError", tt), ye = w("$ZodError", tt, { Parent: Error }), Xt = (t) => (e, n, s, i) => {
|
|
160
|
+
const r = s ? Object.assign(s, { async: !1 }) : { async: !1 }, o = e._zod.run({ value: n, issues: [] }, r);
|
|
161
|
+
if (o instanceof Promise)
|
|
162
|
+
throw new K();
|
|
163
|
+
if (o.issues.length) {
|
|
164
|
+
const a = new (i?.Err ?? t)(o.issues.map((c) => ee(c, r, Q())));
|
|
165
|
+
throw Qe(a, i?.callee), a;
|
|
166
|
+
}
|
|
167
|
+
return o.value;
|
|
168
|
+
}, Yt = /* @__PURE__ */ Xt(ye), Kt = (t) => async (e, n, s, i) => {
|
|
169
|
+
const r = s ? Object.assign(s, { async: !0 }) : { async: !0 };
|
|
170
|
+
let o = e._zod.run({ value: n, issues: [] }, r);
|
|
171
|
+
if (o instanceof Promise && (o = await o), o.issues.length) {
|
|
172
|
+
const a = new (i?.Err ?? t)(o.issues.map((c) => ee(c, r, Q())));
|
|
173
|
+
throw Qe(a, i?.callee), a;
|
|
174
|
+
}
|
|
175
|
+
return o.value;
|
|
176
|
+
}, Jt = /* @__PURE__ */ Kt(ye), Qt = (t) => (e, n, s) => {
|
|
177
|
+
const i = s ? { ...s, async: !1 } : { async: !1 }, r = e._zod.run({ value: n, issues: [] }, i);
|
|
178
|
+
if (r instanceof Promise)
|
|
179
|
+
throw new K();
|
|
180
|
+
return r.issues.length ? {
|
|
181
|
+
success: !1,
|
|
182
|
+
error: new (t ?? Gt)(r.issues.map((o) => ee(o, i, Q())))
|
|
183
|
+
} : { success: !0, data: r.value };
|
|
184
|
+
}, nt = /* @__PURE__ */ Qt(ye), en = (t) => async (e, n, s) => {
|
|
185
|
+
const i = s ? Object.assign(s, { async: !0 }) : { async: !0 };
|
|
186
|
+
let r = e._zod.run({ value: n, issues: [] }, i);
|
|
187
|
+
return r instanceof Promise && (r = await r), r.issues.length ? {
|
|
188
|
+
success: !1,
|
|
189
|
+
error: new t(r.issues.map((o) => ee(o, i, Q())))
|
|
190
|
+
} : { success: !0, data: r.value };
|
|
191
|
+
}, st = /* @__PURE__ */ en(ye), tn = (t) => {
|
|
192
|
+
const e = t ? `[\\s\\S]{${t?.minimum ?? 0},${t?.maximum ?? ""}}` : "[\\s\\S]*";
|
|
193
|
+
return new RegExp(`^${e}$`);
|
|
194
|
+
}, nn = /^-?\d+$/, it = /^-?\d+(?:\.\d+)?$/, sn = /^(?:true|false)$/i, ze = /* @__PURE__ */ w("$ZodCheck", (t, e) => {
|
|
195
|
+
var n;
|
|
196
|
+
t._zod ?? (t._zod = {}), t._zod.def = e, (n = t._zod).onattach ?? (n.onattach = []);
|
|
197
|
+
}), rt = {
|
|
198
|
+
number: "number",
|
|
199
|
+
bigint: "bigint",
|
|
200
|
+
object: "date"
|
|
201
|
+
}, rn = /* @__PURE__ */ w("$ZodCheckLessThan", (t, e) => {
|
|
202
|
+
ze.init(t, e);
|
|
203
|
+
const n = rt[typeof e.value];
|
|
204
|
+
t._zod.onattach.push((s) => {
|
|
205
|
+
const i = s._zod.bag, r = (e.inclusive ? i.maximum : i.exclusiveMaximum) ?? Number.POSITIVE_INFINITY;
|
|
206
|
+
e.value < r && (e.inclusive ? i.maximum = e.value : i.exclusiveMaximum = e.value);
|
|
207
|
+
}), t._zod.check = (s) => {
|
|
208
|
+
(e.inclusive ? s.value <= e.value : s.value < e.value) || s.issues.push({
|
|
209
|
+
origin: n,
|
|
210
|
+
code: "too_big",
|
|
211
|
+
maximum: typeof e.value == "object" ? e.value.getTime() : e.value,
|
|
212
|
+
input: s.value,
|
|
213
|
+
inclusive: e.inclusive,
|
|
214
|
+
inst: t,
|
|
215
|
+
continue: !e.abort
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
}), on = /* @__PURE__ */ w("$ZodCheckGreaterThan", (t, e) => {
|
|
219
|
+
ze.init(t, e);
|
|
220
|
+
const n = rt[typeof e.value];
|
|
221
|
+
t._zod.onattach.push((s) => {
|
|
222
|
+
const i = s._zod.bag, r = (e.inclusive ? i.minimum : i.exclusiveMinimum) ?? Number.NEGATIVE_INFINITY;
|
|
223
|
+
e.value > r && (e.inclusive ? i.minimum = e.value : i.exclusiveMinimum = e.value);
|
|
224
|
+
}), t._zod.check = (s) => {
|
|
225
|
+
(e.inclusive ? s.value >= e.value : s.value > e.value) || s.issues.push({
|
|
226
|
+
origin: n,
|
|
227
|
+
code: "too_small",
|
|
228
|
+
minimum: typeof e.value == "object" ? e.value.getTime() : e.value,
|
|
229
|
+
input: s.value,
|
|
230
|
+
inclusive: e.inclusive,
|
|
231
|
+
inst: t,
|
|
232
|
+
continue: !e.abort
|
|
233
|
+
});
|
|
234
|
+
};
|
|
235
|
+
}), an = /* @__PURE__ */ w("$ZodCheckNumberFormat", (t, e) => {
|
|
236
|
+
ze.init(t, e), e.format = e.format || "float64";
|
|
237
|
+
const n = e.format?.includes("int"), s = n ? "int" : "number", [i, r] = Ht[e.format];
|
|
238
|
+
t._zod.onattach.push((o) => {
|
|
239
|
+
const a = o._zod.bag;
|
|
240
|
+
a.format = e.format, a.minimum = i, a.maximum = r, n && (a.pattern = nn);
|
|
241
|
+
}), t._zod.check = (o) => {
|
|
242
|
+
const a = o.value;
|
|
243
|
+
if (n) {
|
|
244
|
+
if (!Number.isInteger(a)) {
|
|
245
|
+
o.issues.push({
|
|
246
|
+
expected: s,
|
|
247
|
+
format: e.format,
|
|
248
|
+
code: "invalid_type",
|
|
249
|
+
continue: !1,
|
|
250
|
+
input: a,
|
|
251
|
+
inst: t
|
|
252
|
+
});
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (!Number.isSafeInteger(a)) {
|
|
256
|
+
a > 0 ? o.issues.push({
|
|
257
|
+
input: a,
|
|
258
|
+
code: "too_big",
|
|
259
|
+
maximum: Number.MAX_SAFE_INTEGER,
|
|
260
|
+
note: "Integers must be within the safe integer range.",
|
|
261
|
+
inst: t,
|
|
262
|
+
origin: s,
|
|
263
|
+
inclusive: !0,
|
|
264
|
+
continue: !e.abort
|
|
265
|
+
}) : o.issues.push({
|
|
266
|
+
input: a,
|
|
267
|
+
code: "too_small",
|
|
268
|
+
minimum: Number.MIN_SAFE_INTEGER,
|
|
269
|
+
note: "Integers must be within the safe integer range.",
|
|
270
|
+
inst: t,
|
|
271
|
+
origin: s,
|
|
272
|
+
inclusive: !0,
|
|
273
|
+
continue: !e.abort
|
|
274
|
+
});
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
a < i && o.issues.push({
|
|
279
|
+
origin: "number",
|
|
280
|
+
input: a,
|
|
281
|
+
code: "too_small",
|
|
282
|
+
minimum: i,
|
|
283
|
+
inclusive: !0,
|
|
284
|
+
inst: t,
|
|
285
|
+
continue: !e.abort
|
|
286
|
+
}), a > r && o.issues.push({
|
|
287
|
+
origin: "number",
|
|
288
|
+
input: a,
|
|
289
|
+
code: "too_big",
|
|
290
|
+
maximum: r,
|
|
291
|
+
inclusive: !0,
|
|
292
|
+
inst: t,
|
|
293
|
+
continue: !e.abort
|
|
294
|
+
});
|
|
295
|
+
};
|
|
296
|
+
}), cn = {
|
|
297
|
+
major: 4,
|
|
298
|
+
minor: 3,
|
|
299
|
+
patch: 6
|
|
300
|
+
}, B = /* @__PURE__ */ w("$ZodType", (t, e) => {
|
|
301
|
+
var n;
|
|
302
|
+
t ?? (t = {}), t._zod.def = e, t._zod.bag = t._zod.bag || {}, t._zod.version = cn;
|
|
303
|
+
const s = [...t._zod.def.checks ?? []];
|
|
304
|
+
t._zod.traits.has("$ZodCheck") && s.unshift(t);
|
|
305
|
+
for (const i of s)
|
|
306
|
+
for (const r of i._zod.onattach)
|
|
307
|
+
r(t);
|
|
308
|
+
if (s.length === 0)
|
|
309
|
+
(n = t._zod).deferred ?? (n.deferred = []), t._zod.deferred?.push(() => {
|
|
310
|
+
t._zod.run = t._zod.parse;
|
|
311
|
+
});
|
|
312
|
+
else {
|
|
313
|
+
const i = (o, a, c) => {
|
|
314
|
+
let u = re(o), l;
|
|
315
|
+
for (const d of a) {
|
|
316
|
+
if (d._zod.def.when) {
|
|
317
|
+
if (!d._zod.def.when(o))
|
|
318
|
+
continue;
|
|
319
|
+
} else if (u)
|
|
320
|
+
continue;
|
|
321
|
+
const f = o.issues.length, g = d._zod.check(o);
|
|
322
|
+
if (g instanceof Promise && c?.async === !1)
|
|
323
|
+
throw new K();
|
|
324
|
+
if (l || g instanceof Promise)
|
|
325
|
+
l = (l ?? Promise.resolve()).then(async () => {
|
|
326
|
+
await g, o.issues.length !== f && (u || (u = re(o, f)));
|
|
327
|
+
});
|
|
328
|
+
else {
|
|
329
|
+
if (o.issues.length === f)
|
|
330
|
+
continue;
|
|
331
|
+
u || (u = re(o, f));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return l ? l.then(() => o) : o;
|
|
335
|
+
}, r = (o, a, c) => {
|
|
336
|
+
if (re(o))
|
|
337
|
+
return o.aborted = !0, o;
|
|
338
|
+
const u = i(a, s, c);
|
|
339
|
+
if (u instanceof Promise) {
|
|
340
|
+
if (c.async === !1)
|
|
341
|
+
throw new K();
|
|
342
|
+
return u.then((l) => t._zod.parse(l, c));
|
|
343
|
+
}
|
|
344
|
+
return t._zod.parse(u, c);
|
|
345
|
+
};
|
|
346
|
+
t._zod.run = (o, a) => {
|
|
347
|
+
if (a.skipChecks)
|
|
348
|
+
return t._zod.parse(o, a);
|
|
349
|
+
if (a.direction === "backward") {
|
|
350
|
+
const u = t._zod.parse({ value: o.value, issues: [] }, { ...a, skipChecks: !0 });
|
|
351
|
+
return u instanceof Promise ? u.then((l) => r(l, o, a)) : r(u, o, a);
|
|
352
|
+
}
|
|
353
|
+
const c = t._zod.parse(o, a);
|
|
354
|
+
if (c instanceof Promise) {
|
|
355
|
+
if (a.async === !1)
|
|
356
|
+
throw new K();
|
|
357
|
+
return c.then((u) => i(u, s, a));
|
|
358
|
+
}
|
|
359
|
+
return i(c, s, a);
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
U(t, "~standard", () => ({
|
|
363
|
+
validate: (i) => {
|
|
364
|
+
try {
|
|
365
|
+
const r = nt(t, i);
|
|
366
|
+
return r.success ? { value: r.data } : { issues: r.error?.issues };
|
|
367
|
+
} catch {
|
|
368
|
+
return st(t, i).then((o) => o.success ? { value: o.data } : { issues: o.error?.issues });
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
vendor: "zod",
|
|
372
|
+
version: 1
|
|
373
|
+
}));
|
|
374
|
+
}), un = /* @__PURE__ */ w("$ZodString", (t, e) => {
|
|
375
|
+
B.init(t, e), t._zod.pattern = [...t?._zod.bag?.patterns ?? []].pop() ?? tn(t._zod.bag), t._zod.parse = (n, s) => {
|
|
376
|
+
if (e.coerce)
|
|
377
|
+
try {
|
|
378
|
+
n.value = String(n.value);
|
|
379
|
+
} catch {
|
|
380
|
+
}
|
|
381
|
+
return typeof n.value == "string" || n.issues.push({
|
|
382
|
+
expected: "string",
|
|
383
|
+
code: "invalid_type",
|
|
384
|
+
input: n.value,
|
|
385
|
+
inst: t
|
|
386
|
+
}), n;
|
|
387
|
+
};
|
|
388
|
+
}), ot = /* @__PURE__ */ w("$ZodNumber", (t, e) => {
|
|
389
|
+
B.init(t, e), t._zod.pattern = t._zod.bag.pattern ?? it, t._zod.parse = (n, s) => {
|
|
390
|
+
if (e.coerce)
|
|
391
|
+
try {
|
|
392
|
+
n.value = Number(n.value);
|
|
393
|
+
} catch {
|
|
394
|
+
}
|
|
395
|
+
const i = n.value;
|
|
396
|
+
if (typeof i == "number" && !Number.isNaN(i) && Number.isFinite(i))
|
|
397
|
+
return n;
|
|
398
|
+
const r = typeof i == "number" ? Number.isNaN(i) ? "NaN" : Number.isFinite(i) ? void 0 : "Infinity" : void 0;
|
|
399
|
+
return n.issues.push({
|
|
400
|
+
expected: "number",
|
|
401
|
+
code: "invalid_type",
|
|
402
|
+
input: i,
|
|
403
|
+
inst: t,
|
|
404
|
+
...r ? { received: r } : {}
|
|
405
|
+
}), n;
|
|
406
|
+
};
|
|
407
|
+
}), ln = /* @__PURE__ */ w("$ZodNumberFormat", (t, e) => {
|
|
408
|
+
an.init(t, e), ot.init(t, e);
|
|
409
|
+
}), dn = /* @__PURE__ */ w("$ZodBoolean", (t, e) => {
|
|
410
|
+
B.init(t, e), t._zod.pattern = sn, t._zod.parse = (n, s) => {
|
|
411
|
+
if (e.coerce)
|
|
412
|
+
try {
|
|
413
|
+
n.value = !!n.value;
|
|
414
|
+
} catch {
|
|
415
|
+
}
|
|
416
|
+
const i = n.value;
|
|
417
|
+
return typeof i == "boolean" || n.issues.push({
|
|
418
|
+
expected: "boolean",
|
|
419
|
+
code: "invalid_type",
|
|
420
|
+
input: i,
|
|
421
|
+
inst: t
|
|
422
|
+
}), n;
|
|
423
|
+
};
|
|
424
|
+
});
|
|
425
|
+
function xe(t, e, n) {
|
|
426
|
+
t.issues.length && e.issues.push(...X(n, t.issues)), e.value[n] = t.value;
|
|
427
|
+
}
|
|
428
|
+
const hn = /* @__PURE__ */ w("$ZodArray", (t, e) => {
|
|
429
|
+
B.init(t, e), t._zod.parse = (n, s) => {
|
|
430
|
+
const i = n.value;
|
|
431
|
+
if (!Array.isArray(i))
|
|
432
|
+
return n.issues.push({
|
|
433
|
+
expected: "array",
|
|
434
|
+
code: "invalid_type",
|
|
435
|
+
input: i,
|
|
436
|
+
inst: t
|
|
437
|
+
}), n;
|
|
438
|
+
n.value = Array(i.length);
|
|
439
|
+
const r = [];
|
|
440
|
+
for (let o = 0; o < i.length; o++) {
|
|
441
|
+
const a = i[o], c = e.element._zod.run({
|
|
442
|
+
value: a,
|
|
443
|
+
issues: []
|
|
444
|
+
}, s);
|
|
445
|
+
c instanceof Promise ? r.push(c.then((u) => xe(u, n, o))) : xe(c, n, o);
|
|
446
|
+
}
|
|
447
|
+
return r.length ? Promise.all(r).then(() => n) : n;
|
|
448
|
+
};
|
|
449
|
+
});
|
|
450
|
+
function ge(t, e, n, s, i) {
|
|
451
|
+
if (t.issues.length) {
|
|
452
|
+
if (i && !(n in s))
|
|
453
|
+
return;
|
|
454
|
+
e.issues.push(...X(n, t.issues));
|
|
455
|
+
}
|
|
456
|
+
t.value === void 0 ? n in s && (e.value[n] = void 0) : e.value[n] = t.value;
|
|
457
|
+
}
|
|
458
|
+
function fn(t) {
|
|
459
|
+
const e = Object.keys(t.shape);
|
|
460
|
+
for (const s of e)
|
|
461
|
+
if (!t.shape?.[s]?._zod?.traits?.has("$ZodType"))
|
|
462
|
+
throw new Error(`Invalid element at key "${s}": expected a Zod schema`);
|
|
463
|
+
const n = qt(t.shape);
|
|
464
|
+
return {
|
|
465
|
+
...t,
|
|
466
|
+
keys: e,
|
|
467
|
+
keySet: new Set(e),
|
|
468
|
+
numKeys: e.length,
|
|
469
|
+
optionalKeys: new Set(n)
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
function mn(t, e, n, s, i, r) {
|
|
473
|
+
const o = [], a = i.keySet, c = i.catchall._zod, u = c.def.type, l = c.optout === "optional";
|
|
474
|
+
for (const d in e) {
|
|
475
|
+
if (a.has(d))
|
|
476
|
+
continue;
|
|
477
|
+
if (u === "never") {
|
|
478
|
+
o.push(d);
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
const f = c.run({ value: e[d], issues: [] }, s);
|
|
482
|
+
f instanceof Promise ? t.push(f.then((g) => ge(g, n, d, e, l))) : ge(f, n, d, e, l);
|
|
483
|
+
}
|
|
484
|
+
return o.length && n.issues.push({
|
|
485
|
+
code: "unrecognized_keys",
|
|
486
|
+
keys: o,
|
|
487
|
+
input: e,
|
|
488
|
+
inst: r
|
|
489
|
+
}), t.length ? Promise.all(t).then(() => n) : n;
|
|
490
|
+
}
|
|
491
|
+
const pn = /* @__PURE__ */ w("$ZodObject", (t, e) => {
|
|
492
|
+
if (B.init(t, e), !Object.getOwnPropertyDescriptor(e, "shape")?.get) {
|
|
493
|
+
const a = e.shape;
|
|
494
|
+
Object.defineProperty(e, "shape", {
|
|
495
|
+
get: () => {
|
|
496
|
+
const c = { ...a };
|
|
497
|
+
return Object.defineProperty(e, "shape", {
|
|
498
|
+
value: c
|
|
499
|
+
}), c;
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
const s = Ke(() => fn(e));
|
|
504
|
+
U(t._zod, "propValues", () => {
|
|
505
|
+
const a = e.shape, c = {};
|
|
506
|
+
for (const u in a) {
|
|
507
|
+
const l = a[u]._zod;
|
|
508
|
+
if (l.values) {
|
|
509
|
+
c[u] ?? (c[u] = /* @__PURE__ */ new Set());
|
|
510
|
+
for (const d of l.values)
|
|
511
|
+
c[u].add(d);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return c;
|
|
515
|
+
});
|
|
516
|
+
const i = pe, r = e.catchall;
|
|
517
|
+
let o;
|
|
518
|
+
t._zod.parse = (a, c) => {
|
|
519
|
+
o ?? (o = s.value);
|
|
520
|
+
const u = a.value;
|
|
521
|
+
if (!i(u))
|
|
522
|
+
return a.issues.push({
|
|
523
|
+
expected: "object",
|
|
524
|
+
code: "invalid_type",
|
|
525
|
+
input: u,
|
|
526
|
+
inst: t
|
|
527
|
+
}), a;
|
|
528
|
+
a.value = {};
|
|
529
|
+
const l = [], d = o.shape;
|
|
530
|
+
for (const f of o.keys) {
|
|
531
|
+
const g = d[f], y = g._zod.optout === "optional", b = g._zod.run({ value: u[f], issues: [] }, c);
|
|
532
|
+
b instanceof Promise ? l.push(b.then((S) => ge(S, a, f, u, y))) : ge(b, a, f, u, y);
|
|
533
|
+
}
|
|
534
|
+
return r ? mn(l, u, a, c, s.value, t) : l.length ? Promise.all(l).then(() => a) : a;
|
|
535
|
+
};
|
|
536
|
+
});
|
|
537
|
+
function Ie(t, e, n, s) {
|
|
538
|
+
for (const r of t)
|
|
539
|
+
if (r.issues.length === 0)
|
|
540
|
+
return e.value = r.value, e;
|
|
541
|
+
const i = t.filter((r) => !re(r));
|
|
542
|
+
return i.length === 1 ? (e.value = i[0].value, i[0]) : (e.issues.push({
|
|
543
|
+
code: "invalid_union",
|
|
544
|
+
input: e.value,
|
|
545
|
+
inst: n,
|
|
546
|
+
errors: t.map((r) => r.issues.map((o) => ee(o, s, Q())))
|
|
547
|
+
}), e);
|
|
548
|
+
}
|
|
549
|
+
const at = /* @__PURE__ */ w("$ZodUnion", (t, e) => {
|
|
550
|
+
B.init(t, e), U(t._zod, "optin", () => e.options.some((i) => i._zod.optin === "optional") ? "optional" : void 0), U(t._zod, "optout", () => e.options.some((i) => i._zod.optout === "optional") ? "optional" : void 0), U(t._zod, "values", () => {
|
|
551
|
+
if (e.options.every((i) => i._zod.values))
|
|
552
|
+
return new Set(e.options.flatMap((i) => Array.from(i._zod.values)));
|
|
553
|
+
}), U(t._zod, "pattern", () => {
|
|
554
|
+
if (e.options.every((i) => i._zod.pattern)) {
|
|
555
|
+
const i = e.options.map((r) => r._zod.pattern);
|
|
556
|
+
return new RegExp(`^(${i.map((r) => Je(r.source)).join("|")})$`);
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
const n = e.options.length === 1, s = e.options[0]._zod.run;
|
|
560
|
+
t._zod.parse = (i, r) => {
|
|
561
|
+
if (n)
|
|
562
|
+
return s(i, r);
|
|
563
|
+
let o = !1;
|
|
564
|
+
const a = [];
|
|
565
|
+
for (const c of e.options) {
|
|
566
|
+
const u = c._zod.run({
|
|
567
|
+
value: i.value,
|
|
568
|
+
issues: []
|
|
569
|
+
}, r);
|
|
570
|
+
if (u instanceof Promise)
|
|
571
|
+
a.push(u), o = !0;
|
|
572
|
+
else {
|
|
573
|
+
if (u.issues.length === 0)
|
|
574
|
+
return u;
|
|
575
|
+
a.push(u);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
return o ? Promise.all(a).then((c) => Ie(c, i, t, r)) : Ie(a, i, t, r);
|
|
579
|
+
};
|
|
580
|
+
}), gn = /* @__PURE__ */ w("$ZodDiscriminatedUnion", (t, e) => {
|
|
581
|
+
e.inclusive = !1, at.init(t, e);
|
|
582
|
+
const n = t._zod.parse;
|
|
583
|
+
U(t._zod, "propValues", () => {
|
|
584
|
+
const i = {};
|
|
585
|
+
for (const r of e.options) {
|
|
586
|
+
const o = r._zod.propValues;
|
|
587
|
+
if (!o || Object.keys(o).length === 0)
|
|
588
|
+
throw new Error(`Invalid discriminated union option at index "${e.options.indexOf(r)}"`);
|
|
589
|
+
for (const [a, c] of Object.entries(o)) {
|
|
590
|
+
i[a] || (i[a] = /* @__PURE__ */ new Set());
|
|
591
|
+
for (const u of c)
|
|
592
|
+
i[a].add(u);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return i;
|
|
596
|
+
});
|
|
597
|
+
const s = Ke(() => {
|
|
598
|
+
const i = e.options, r = /* @__PURE__ */ new Map();
|
|
599
|
+
for (const o of i) {
|
|
600
|
+
const a = o._zod.propValues?.[e.discriminator];
|
|
601
|
+
if (!a || a.size === 0)
|
|
602
|
+
throw new Error(`Invalid discriminated union option at index "${e.options.indexOf(o)}"`);
|
|
603
|
+
for (const c of a) {
|
|
604
|
+
if (r.has(c))
|
|
605
|
+
throw new Error(`Duplicate discriminator value "${String(c)}"`);
|
|
606
|
+
r.set(c, o);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
return r;
|
|
610
|
+
});
|
|
611
|
+
t._zod.parse = (i, r) => {
|
|
612
|
+
const o = i.value;
|
|
613
|
+
if (!pe(o))
|
|
614
|
+
return i.issues.push({
|
|
615
|
+
code: "invalid_type",
|
|
616
|
+
expected: "object",
|
|
617
|
+
input: o,
|
|
618
|
+
inst: t
|
|
619
|
+
}), i;
|
|
620
|
+
const a = s.value.get(o?.[e.discriminator]);
|
|
621
|
+
return a ? a._zod.run(i, r) : e.unionFallback ? n(i, r) : (i.issues.push({
|
|
622
|
+
code: "invalid_union",
|
|
623
|
+
errors: [],
|
|
624
|
+
note: "No matching discriminator",
|
|
625
|
+
discriminator: e.discriminator,
|
|
626
|
+
input: o,
|
|
627
|
+
path: [e.discriminator],
|
|
628
|
+
inst: t
|
|
629
|
+
}), i);
|
|
630
|
+
};
|
|
631
|
+
}), wn = /* @__PURE__ */ w("$ZodRecord", (t, e) => {
|
|
632
|
+
B.init(t, e), t._zod.parse = (n, s) => {
|
|
633
|
+
const i = n.value;
|
|
634
|
+
if (!et(i))
|
|
635
|
+
return n.issues.push({
|
|
636
|
+
expected: "record",
|
|
637
|
+
code: "invalid_type",
|
|
638
|
+
input: i,
|
|
639
|
+
inst: t
|
|
640
|
+
}), n;
|
|
641
|
+
const r = [], o = e.keyType._zod.values;
|
|
642
|
+
if (o) {
|
|
643
|
+
n.value = {};
|
|
644
|
+
const a = /* @__PURE__ */ new Set();
|
|
645
|
+
for (const u of o)
|
|
646
|
+
if (typeof u == "string" || typeof u == "number" || typeof u == "symbol") {
|
|
647
|
+
a.add(typeof u == "number" ? u.toString() : u);
|
|
648
|
+
const l = e.valueType._zod.run({ value: i[u], issues: [] }, s);
|
|
649
|
+
l instanceof Promise ? r.push(l.then((d) => {
|
|
650
|
+
d.issues.length && n.issues.push(...X(u, d.issues)), n.value[u] = d.value;
|
|
651
|
+
})) : (l.issues.length && n.issues.push(...X(u, l.issues)), n.value[u] = l.value);
|
|
652
|
+
}
|
|
653
|
+
let c;
|
|
654
|
+
for (const u in i)
|
|
655
|
+
a.has(u) || (c = c ?? [], c.push(u));
|
|
656
|
+
c && c.length > 0 && n.issues.push({
|
|
657
|
+
code: "unrecognized_keys",
|
|
658
|
+
input: i,
|
|
659
|
+
inst: t,
|
|
660
|
+
keys: c
|
|
661
|
+
});
|
|
662
|
+
} else {
|
|
663
|
+
n.value = {};
|
|
664
|
+
for (const a of Reflect.ownKeys(i)) {
|
|
665
|
+
if (a === "__proto__")
|
|
666
|
+
continue;
|
|
667
|
+
let c = e.keyType._zod.run({ value: a, issues: [] }, s);
|
|
668
|
+
if (c instanceof Promise)
|
|
669
|
+
throw new Error("Async schemas not supported in object keys currently");
|
|
670
|
+
if (typeof a == "string" && it.test(a) && c.issues.length) {
|
|
671
|
+
const d = e.keyType._zod.run({ value: Number(a), issues: [] }, s);
|
|
672
|
+
if (d instanceof Promise)
|
|
673
|
+
throw new Error("Async schemas not supported in object keys currently");
|
|
674
|
+
d.issues.length === 0 && (c = d);
|
|
675
|
+
}
|
|
676
|
+
if (c.issues.length) {
|
|
677
|
+
e.mode === "loose" ? n.value[a] = i[a] : n.issues.push({
|
|
678
|
+
code: "invalid_key",
|
|
679
|
+
origin: "record",
|
|
680
|
+
issues: c.issues.map((d) => ee(d, s, Q())),
|
|
681
|
+
input: a,
|
|
682
|
+
path: [a],
|
|
683
|
+
inst: t
|
|
684
|
+
});
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
const l = e.valueType._zod.run({ value: i[a], issues: [] }, s);
|
|
688
|
+
l instanceof Promise ? r.push(l.then((d) => {
|
|
689
|
+
d.issues.length && n.issues.push(...X(a, d.issues)), n.value[c.value] = d.value;
|
|
690
|
+
})) : (l.issues.length && n.issues.push(...X(a, l.issues)), n.value[c.value] = l.value);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return r.length ? Promise.all(r).then(() => n) : n;
|
|
694
|
+
};
|
|
695
|
+
}), yn = /* @__PURE__ */ w("$ZodLiteral", (t, e) => {
|
|
696
|
+
if (B.init(t, e), e.values.length === 0)
|
|
697
|
+
throw new Error("Cannot create literal schema with no valid values");
|
|
698
|
+
const n = new Set(e.values);
|
|
699
|
+
t._zod.values = n, t._zod.pattern = new RegExp(`^(${e.values.map((s) => typeof s == "string" ? Be(s) : s ? Be(s.toString()) : String(s)).join("|")})$`), t._zod.parse = (s, i) => {
|
|
700
|
+
const r = s.value;
|
|
701
|
+
return n.has(r) || s.issues.push({
|
|
702
|
+
code: "invalid_value",
|
|
703
|
+
values: e.values,
|
|
704
|
+
input: r,
|
|
705
|
+
inst: t
|
|
706
|
+
}), s;
|
|
707
|
+
};
|
|
708
|
+
}), bn = /* @__PURE__ */ w("$ZodTransform", (t, e) => {
|
|
709
|
+
B.init(t, e), t._zod.parse = (n, s) => {
|
|
710
|
+
if (s.direction === "backward")
|
|
711
|
+
throw new Ft(t.constructor.name);
|
|
712
|
+
const i = e.transform(n.value, n);
|
|
713
|
+
if (s.async)
|
|
714
|
+
return (i instanceof Promise ? i : Promise.resolve(i)).then((o) => (n.value = o, n));
|
|
715
|
+
if (i instanceof Promise)
|
|
716
|
+
throw new K();
|
|
717
|
+
return n.value = i, n;
|
|
718
|
+
};
|
|
719
|
+
});
|
|
720
|
+
function Ce(t, e) {
|
|
721
|
+
return t.issues.length && e === void 0 ? { issues: [], value: void 0 } : t;
|
|
722
|
+
}
|
|
723
|
+
const vn = /* @__PURE__ */ w("$ZodOptional", (t, e) => {
|
|
724
|
+
B.init(t, e), t._zod.optin = "optional", t._zod.optout = "optional", U(t._zod, "values", () => e.innerType._zod.values ? /* @__PURE__ */ new Set([...e.innerType._zod.values, void 0]) : void 0), U(t._zod, "pattern", () => {
|
|
725
|
+
const n = e.innerType._zod.pattern;
|
|
726
|
+
return n ? new RegExp(`^(${Je(n.source)})?$`) : void 0;
|
|
727
|
+
}), t._zod.parse = (n, s) => {
|
|
728
|
+
if (e.innerType._zod.optin === "optional") {
|
|
729
|
+
const i = e.innerType._zod.run(n, s);
|
|
730
|
+
return i instanceof Promise ? i.then((r) => Ce(r, n.value)) : Ce(i, n.value);
|
|
731
|
+
}
|
|
732
|
+
return n.value === void 0 ? n : e.innerType._zod.run(n, s);
|
|
733
|
+
};
|
|
734
|
+
}), Sn = /* @__PURE__ */ w("$ZodDefault", (t, e) => {
|
|
735
|
+
B.init(t, e), t._zod.optin = "optional", U(t._zod, "values", () => e.innerType._zod.values), t._zod.parse = (n, s) => {
|
|
736
|
+
if (s.direction === "backward")
|
|
737
|
+
return e.innerType._zod.run(n, s);
|
|
738
|
+
if (n.value === void 0)
|
|
739
|
+
return n.value = e.defaultValue, n;
|
|
740
|
+
const i = e.innerType._zod.run(n, s);
|
|
741
|
+
return i instanceof Promise ? i.then((r) => Le(r, e)) : Le(i, e);
|
|
742
|
+
};
|
|
743
|
+
});
|
|
744
|
+
function Le(t, e) {
|
|
745
|
+
return t.value === void 0 && (t.value = e.defaultValue), t;
|
|
746
|
+
}
|
|
747
|
+
const Mn = /* @__PURE__ */ w("$ZodPipe", (t, e) => {
|
|
748
|
+
B.init(t, e), U(t._zod, "values", () => e.in._zod.values), U(t._zod, "optin", () => e.in._zod.optin), U(t._zod, "optout", () => e.out._zod.optout), U(t._zod, "propValues", () => e.in._zod.propValues), t._zod.parse = (n, s) => {
|
|
749
|
+
if (s.direction === "backward") {
|
|
750
|
+
const r = e.out._zod.run(n, s);
|
|
751
|
+
return r instanceof Promise ? r.then((o) => me(o, e.in, s)) : me(r, e.in, s);
|
|
752
|
+
}
|
|
753
|
+
const i = e.in._zod.run(n, s);
|
|
754
|
+
return i instanceof Promise ? i.then((r) => me(r, e.out, s)) : me(i, e.out, s);
|
|
755
|
+
};
|
|
756
|
+
});
|
|
757
|
+
function me(t, e, n) {
|
|
758
|
+
return t.issues.length ? (t.aborted = !0, t) : e._zod.run({ value: t.value, issues: t.issues }, n);
|
|
759
|
+
}
|
|
760
|
+
var Oe;
|
|
761
|
+
class _n {
|
|
762
|
+
constructor() {
|
|
763
|
+
this._map = /* @__PURE__ */ new WeakMap(), this._idmap = /* @__PURE__ */ new Map();
|
|
764
|
+
}
|
|
765
|
+
add(e, ...n) {
|
|
766
|
+
const s = n[0];
|
|
767
|
+
return this._map.set(e, s), s && typeof s == "object" && "id" in s && this._idmap.set(s.id, e), this;
|
|
768
|
+
}
|
|
769
|
+
clear() {
|
|
770
|
+
return this._map = /* @__PURE__ */ new WeakMap(), this._idmap = /* @__PURE__ */ new Map(), this;
|
|
771
|
+
}
|
|
772
|
+
remove(e) {
|
|
773
|
+
const n = this._map.get(e);
|
|
774
|
+
return n && typeof n == "object" && "id" in n && this._idmap.delete(n.id), this._map.delete(e), this;
|
|
775
|
+
}
|
|
776
|
+
get(e) {
|
|
777
|
+
const n = e._zod.parent;
|
|
778
|
+
if (n) {
|
|
779
|
+
const s = { ...this.get(n) ?? {} };
|
|
780
|
+
delete s.id;
|
|
781
|
+
const i = { ...s, ...this._map.get(e) };
|
|
782
|
+
return Object.keys(i).length ? i : void 0;
|
|
783
|
+
}
|
|
784
|
+
return this._map.get(e);
|
|
785
|
+
}
|
|
786
|
+
has(e) {
|
|
787
|
+
return this._map.has(e);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
function zn() {
|
|
791
|
+
return new _n();
|
|
792
|
+
}
|
|
793
|
+
(Oe = globalThis).__zod_globalRegistry ?? (Oe.__zod_globalRegistry = zn());
|
|
794
|
+
// @__NO_SIDE_EFFECTS__
|
|
795
|
+
function An(t, e) {
|
|
796
|
+
return new t({
|
|
797
|
+
type: "string",
|
|
798
|
+
...I()
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
// @__NO_SIDE_EFFECTS__
|
|
802
|
+
function kn(t, e) {
|
|
803
|
+
return new t({
|
|
804
|
+
type: "number",
|
|
805
|
+
checks: [],
|
|
806
|
+
...I()
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
// @__NO_SIDE_EFFECTS__
|
|
810
|
+
function Tn(t, e) {
|
|
811
|
+
return new t({
|
|
812
|
+
type: "number",
|
|
813
|
+
check: "number_format",
|
|
814
|
+
abort: !1,
|
|
815
|
+
format: "safeint",
|
|
816
|
+
...I()
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
// @__NO_SIDE_EFFECTS__
|
|
820
|
+
function En(t, e) {
|
|
821
|
+
return new t({
|
|
822
|
+
type: "boolean",
|
|
823
|
+
...I()
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
// @__NO_SIDE_EFFECTS__
|
|
827
|
+
function ct(t, e) {
|
|
828
|
+
return new rn({
|
|
829
|
+
check: "less_than",
|
|
830
|
+
...I(),
|
|
831
|
+
value: t,
|
|
832
|
+
inclusive: !0
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
// @__NO_SIDE_EFFECTS__
|
|
836
|
+
function Un(t, e) {
|
|
837
|
+
return new on({
|
|
838
|
+
check: "greater_than",
|
|
839
|
+
...I(),
|
|
840
|
+
value: t,
|
|
841
|
+
inclusive: !0
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
// @__NO_SIDE_EFFECTS__
|
|
845
|
+
function ut(t) {
|
|
846
|
+
return /* @__PURE__ */ Un(0);
|
|
847
|
+
}
|
|
848
|
+
const x = /* @__PURE__ */ w("ZodMiniType", (t, e) => {
|
|
849
|
+
if (!t._zod)
|
|
850
|
+
throw new Error("Uninitialized schema in ZodMiniType.");
|
|
851
|
+
B.init(t, e), t.def = e, t.type = e.type, t.parse = (n, s) => Yt(t, n, s, { callee: t.parse }), t.safeParse = (n, s) => nt(t, n, s), t.parseAsync = async (n, s) => Jt(t, n, s, { callee: t.parseAsync }), t.safeParseAsync = async (n, s) => st(t, n, s), t.check = (...n) => t.clone({
|
|
852
|
+
...e,
|
|
853
|
+
checks: [
|
|
854
|
+
...e.checks ?? [],
|
|
855
|
+
...n.map((s) => typeof s == "function" ? { _zod: { check: s, def: { check: "custom" }, onattach: [] } } : s)
|
|
856
|
+
]
|
|
857
|
+
}, { parent: !0 }), t.with = t.check, t.clone = (n, s) => Wt(t, n, s), t.brand = () => t, t.register = ((n, s) => (n.add(t, s), t)), t.apply = (n) => n(t);
|
|
858
|
+
}), Rn = /* @__PURE__ */ w("ZodMiniString", (t, e) => {
|
|
859
|
+
un.init(t, e), x.init(t, e);
|
|
860
|
+
});
|
|
861
|
+
// @__NO_SIDE_EFFECTS__
|
|
862
|
+
function v(t) {
|
|
863
|
+
return /* @__PURE__ */ An(Rn);
|
|
864
|
+
}
|
|
865
|
+
const lt = /* @__PURE__ */ w("ZodMiniNumber", (t, e) => {
|
|
866
|
+
ot.init(t, e), x.init(t, e);
|
|
867
|
+
});
|
|
868
|
+
// @__NO_SIDE_EFFECTS__
|
|
869
|
+
function Z(t) {
|
|
870
|
+
return /* @__PURE__ */ kn(lt);
|
|
871
|
+
}
|
|
872
|
+
const Bn = /* @__PURE__ */ w("ZodMiniNumberFormat", (t, e) => {
|
|
873
|
+
ln.init(t, e), lt.init(t, e);
|
|
874
|
+
});
|
|
875
|
+
// @__NO_SIDE_EFFECTS__
|
|
876
|
+
function dt(t) {
|
|
877
|
+
return /* @__PURE__ */ Tn(Bn);
|
|
878
|
+
}
|
|
879
|
+
const xn = /* @__PURE__ */ w("ZodMiniBoolean", (t, e) => {
|
|
880
|
+
dn.init(t, e), x.init(t, e);
|
|
881
|
+
});
|
|
882
|
+
// @__NO_SIDE_EFFECTS__
|
|
883
|
+
function ht(t) {
|
|
884
|
+
return /* @__PURE__ */ En(xn);
|
|
885
|
+
}
|
|
886
|
+
const In = /* @__PURE__ */ w("ZodMiniArray", (t, e) => {
|
|
887
|
+
hn.init(t, e), x.init(t, e);
|
|
888
|
+
});
|
|
889
|
+
// @__NO_SIDE_EFFECTS__
|
|
890
|
+
function q(t, e) {
|
|
891
|
+
return new In({
|
|
892
|
+
type: "array",
|
|
893
|
+
element: t,
|
|
894
|
+
...I()
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
const Cn = /* @__PURE__ */ w("ZodMiniObject", (t, e) => {
|
|
898
|
+
pn.init(t, e), x.init(t, e), U(t, "shape", () => e.shape);
|
|
899
|
+
});
|
|
900
|
+
// @__NO_SIDE_EFFECTS__
|
|
901
|
+
function _(t, e) {
|
|
902
|
+
const n = {
|
|
903
|
+
type: "object",
|
|
904
|
+
shape: t ?? {},
|
|
905
|
+
...I()
|
|
906
|
+
};
|
|
907
|
+
return new Cn(n);
|
|
908
|
+
}
|
|
909
|
+
const Ln = /* @__PURE__ */ w("ZodMiniUnion", (t, e) => {
|
|
910
|
+
at.init(t, e), x.init(t, e);
|
|
911
|
+
});
|
|
912
|
+
// @__NO_SIDE_EFFECTS__
|
|
913
|
+
function ft(t, e) {
|
|
914
|
+
return new Ln({
|
|
915
|
+
type: "union",
|
|
916
|
+
options: t,
|
|
917
|
+
...I()
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
const On = /* @__PURE__ */ w("ZodMiniDiscriminatedUnion", (t, e) => {
|
|
921
|
+
gn.init(t, e), x.init(t, e);
|
|
922
|
+
});
|
|
923
|
+
// @__NO_SIDE_EFFECTS__
|
|
924
|
+
function Dn(t, e, n) {
|
|
925
|
+
return new On({
|
|
926
|
+
type: "union",
|
|
927
|
+
options: e,
|
|
928
|
+
discriminator: t,
|
|
929
|
+
...I()
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
const Pn = /* @__PURE__ */ w("ZodMiniRecord", (t, e) => {
|
|
933
|
+
wn.init(t, e), x.init(t, e);
|
|
934
|
+
});
|
|
935
|
+
// @__NO_SIDE_EFFECTS__
|
|
936
|
+
function Ae(t, e, n) {
|
|
937
|
+
return new Pn({
|
|
938
|
+
type: "record",
|
|
939
|
+
keyType: t,
|
|
940
|
+
valueType: e,
|
|
941
|
+
...I()
|
|
942
|
+
});
|
|
943
|
+
}
|
|
944
|
+
const Nn = /* @__PURE__ */ w("ZodMiniLiteral", (t, e) => {
|
|
945
|
+
yn.init(t, e), x.init(t, e);
|
|
946
|
+
});
|
|
947
|
+
// @__NO_SIDE_EFFECTS__
|
|
948
|
+
function De(t, e) {
|
|
949
|
+
return new Nn({
|
|
950
|
+
type: "literal",
|
|
951
|
+
values: Array.isArray(t) ? t : [t],
|
|
952
|
+
...I()
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
const $n = /* @__PURE__ */ w("ZodMiniTransform", (t, e) => {
|
|
956
|
+
bn.init(t, e), x.init(t, e);
|
|
957
|
+
});
|
|
958
|
+
// @__NO_SIDE_EFFECTS__
|
|
959
|
+
function mt(t) {
|
|
960
|
+
return new $n({
|
|
961
|
+
type: "transform",
|
|
962
|
+
transform: t
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
const Fn = /* @__PURE__ */ w("ZodMiniOptional", (t, e) => {
|
|
966
|
+
vn.init(t, e), x.init(t, e);
|
|
967
|
+
});
|
|
968
|
+
// @__NO_SIDE_EFFECTS__
|
|
969
|
+
function p(t) {
|
|
970
|
+
return new Fn({
|
|
971
|
+
type: "optional",
|
|
972
|
+
innerType: t
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
const jn = /* @__PURE__ */ w("ZodMiniDefault", (t, e) => {
|
|
976
|
+
Sn.init(t, e), x.init(t, e);
|
|
977
|
+
});
|
|
978
|
+
// @__NO_SIDE_EFFECTS__
|
|
979
|
+
function Zn(t, e) {
|
|
980
|
+
return new jn({
|
|
981
|
+
type: "default",
|
|
982
|
+
innerType: t,
|
|
983
|
+
get defaultValue() {
|
|
984
|
+
return typeof e == "function" ? e() : Vt(e);
|
|
985
|
+
}
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
const Vn = /* @__PURE__ */ w("ZodMiniPipe", (t, e) => {
|
|
989
|
+
Mn.init(t, e), x.init(t, e);
|
|
990
|
+
});
|
|
991
|
+
// @__NO_SIDE_EFFECTS__
|
|
992
|
+
function pt(t, e) {
|
|
993
|
+
return new Vn({
|
|
994
|
+
type: "pipe",
|
|
995
|
+
in: t,
|
|
996
|
+
out: e
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
(/* @__PURE__ */ Z()).check(/* @__PURE__ */ dt(), /* @__PURE__ */ ut(), /* @__PURE__ */ ct(255)).brand("u8");
|
|
1000
|
+
const R = (/* @__PURE__ */ Z()).check(/* @__PURE__ */ dt(), /* @__PURE__ */ ut(), /* @__PURE__ */ ct(Number.MAX_SAFE_INTEGER)).brand("u53"), gt = /* @__PURE__ */ Zn(
|
|
1001
|
+
/* @__PURE__ */ Dn("kind", [
|
|
1002
|
+
// The default hang container
|
|
1003
|
+
/* @__PURE__ */ _({ kind: /* @__PURE__ */ De("legacy") }),
|
|
1004
|
+
// CMAF container with timescale for timestamp conversion
|
|
1005
|
+
/* @__PURE__ */ _({
|
|
1006
|
+
kind: /* @__PURE__ */ De("cmaf"),
|
|
1007
|
+
// Time units per second
|
|
1008
|
+
timescale: R,
|
|
1009
|
+
// Track ID used in the moof/mdat fragments
|
|
1010
|
+
trackId: R
|
|
1011
|
+
})
|
|
1012
|
+
]),
|
|
1013
|
+
{ kind: "legacy" }
|
|
1014
|
+
), Wn = /* @__PURE__ */ _({
|
|
1015
|
+
name: /* @__PURE__ */ v()
|
|
1016
|
+
}), Pe = /* @__PURE__ */ _({
|
|
1017
|
+
// See: https://w3c.github.io/webcodecs/codec_registry.html
|
|
1018
|
+
codec: /* @__PURE__ */ v(),
|
|
1019
|
+
// The container format, used to decode the timestamp and more.
|
|
1020
|
+
container: gt,
|
|
1021
|
+
// The description is used for some codecs.
|
|
1022
|
+
// If provided, we can initialize the decoder based on the catalog alone.
|
|
1023
|
+
// Otherwise, the initialization information is in-band.
|
|
1024
|
+
description: /* @__PURE__ */ p(/* @__PURE__ */ v()),
|
|
1025
|
+
// hex encoded TODO use base64
|
|
1026
|
+
// The sample rate of the audio in Hz
|
|
1027
|
+
sampleRate: R,
|
|
1028
|
+
// The number of channels in the audio
|
|
1029
|
+
numberOfChannels: R,
|
|
1030
|
+
// The bitrate of the audio in bits per second
|
|
1031
|
+
// TODO: Support up to Number.MAX_SAFE_INTEGER
|
|
1032
|
+
bitrate: /* @__PURE__ */ p(R),
|
|
1033
|
+
// The maximum jitter before the next frame is emitted in milliseconds.
|
|
1034
|
+
// The player's jitter buffer should be larger than this value.
|
|
1035
|
+
// If not provided, the player should assume each frame is flushed immediately.
|
|
1036
|
+
//
|
|
1037
|
+
// NOTE: The audio "frame" duration depends on the codec, sample rate, etc.
|
|
1038
|
+
// ex: AAC often uses 1024 samples per frame, so at 44100Hz, this would be 1024/44100 = 23ms
|
|
1039
|
+
jitter: /* @__PURE__ */ p(R)
|
|
1040
|
+
}), qn = /* @__PURE__ */ ft([
|
|
1041
|
+
/* @__PURE__ */ _({
|
|
1042
|
+
// A map of track name to rendition configuration.
|
|
1043
|
+
// This is not an array so it will work with JSON Merge Patch.
|
|
1044
|
+
renditions: /* @__PURE__ */ Ae(/* @__PURE__ */ v(), Pe)
|
|
1045
|
+
}),
|
|
1046
|
+
// Backwards compatibility: transform old {track, config} format to new object format
|
|
1047
|
+
/* @__PURE__ */ pt(
|
|
1048
|
+
/* @__PURE__ */ _({
|
|
1049
|
+
track: Wn,
|
|
1050
|
+
config: Pe
|
|
1051
|
+
}),
|
|
1052
|
+
/* @__PURE__ */ mt((t) => ({
|
|
1053
|
+
renditions: { [t.track.name]: t.config }
|
|
1054
|
+
}))
|
|
1055
|
+
)
|
|
1056
|
+
]), Hn = /* @__PURE__ */ _({
|
|
1057
|
+
hardware: /* @__PURE__ */ p(/* @__PURE__ */ q(/* @__PURE__ */ v())),
|
|
1058
|
+
software: /* @__PURE__ */ p(/* @__PURE__ */ q(/* @__PURE__ */ v())),
|
|
1059
|
+
unsupported: /* @__PURE__ */ p(/* @__PURE__ */ q(/* @__PURE__ */ v()))
|
|
1060
|
+
}), Gn = /* @__PURE__ */ _({
|
|
1061
|
+
hardware: /* @__PURE__ */ p(/* @__PURE__ */ q(/* @__PURE__ */ v())),
|
|
1062
|
+
software: /* @__PURE__ */ p(/* @__PURE__ */ q(/* @__PURE__ */ v())),
|
|
1063
|
+
unsupported: /* @__PURE__ */ p(/* @__PURE__ */ q(/* @__PURE__ */ v()))
|
|
1064
|
+
}), Xn = /* @__PURE__ */ _({
|
|
1065
|
+
video: /* @__PURE__ */ p(Hn),
|
|
1066
|
+
audio: /* @__PURE__ */ p(Gn)
|
|
1067
|
+
}), ue = /* @__PURE__ */ _({
|
|
1068
|
+
name: /* @__PURE__ */ v()
|
|
1069
|
+
}), Yn = /* @__PURE__ */ _({
|
|
1070
|
+
message: /* @__PURE__ */ p(ue),
|
|
1071
|
+
typing: /* @__PURE__ */ p(ue)
|
|
1072
|
+
}), wt = /* @__PURE__ */ _({
|
|
1073
|
+
// The relative X position of the broadcast, from -1 to +1.
|
|
1074
|
+
// This should be used for audio panning but can also be used for video positioning.
|
|
1075
|
+
x: /* @__PURE__ */ p(/* @__PURE__ */ Z()),
|
|
1076
|
+
// The relative Y position of the broadcast, from -1 to +1.
|
|
1077
|
+
// This can be used for video positioning, and maybe audio panning.
|
|
1078
|
+
y: /* @__PURE__ */ p(/* @__PURE__ */ Z()),
|
|
1079
|
+
// The relative Z index of the broadcast, where larger values are closer to the viewer.
|
|
1080
|
+
// This is used to break ties when there are multiple broadcasts at the same position.
|
|
1081
|
+
z: /* @__PURE__ */ p(/* @__PURE__ */ Z()),
|
|
1082
|
+
// The scale of the broadcast, where 1 is 100%
|
|
1083
|
+
s: /* @__PURE__ */ p(/* @__PURE__ */ Z())
|
|
1084
|
+
}), Kn = /* @__PURE__ */ _({
|
|
1085
|
+
// The initial position of the broadcaster, from -1 to +1 in both dimensions.
|
|
1086
|
+
// If not provided, then the broadcaster is assumed to be at (0,0)
|
|
1087
|
+
// This should be used for audio panning but can also be used for video positioning.
|
|
1088
|
+
initial: /* @__PURE__ */ p(wt),
|
|
1089
|
+
// If provided, then updates to the position are done via a separate Moq track.
|
|
1090
|
+
// This is used to avoid a full catalog update every time we want to update a few bytes.
|
|
1091
|
+
// TODO: These updates currently use JSON for simplicity, but we should use a binary format.
|
|
1092
|
+
track: /* @__PURE__ */ p(ue),
|
|
1093
|
+
// If set, then this broadcaster allows other peers to request position updates via this handle.
|
|
1094
|
+
// We will have to discover and subscribe to their position updates.
|
|
1095
|
+
handle: /* @__PURE__ */ p(/* @__PURE__ */ v()),
|
|
1096
|
+
// If provided, this broadcaster is signaling the location of other peers.
|
|
1097
|
+
// The payload is a JSON blob keyed by handle for each peer.
|
|
1098
|
+
peers: /* @__PURE__ */ p(ue)
|
|
1099
|
+
}), Ri = /* @__PURE__ */ Ae(/* @__PURE__ */ v(), wt), J = {
|
|
1100
|
+
catalog: 100,
|
|
1101
|
+
chat: 90,
|
|
1102
|
+
audio: 80,
|
|
1103
|
+
video: 60,
|
|
1104
|
+
typing: 40,
|
|
1105
|
+
location: 20,
|
|
1106
|
+
preview: 10
|
|
1107
|
+
}, Jn = /* @__PURE__ */ _({
|
|
1108
|
+
id: /* @__PURE__ */ p(/* @__PURE__ */ v()),
|
|
1109
|
+
name: /* @__PURE__ */ p(/* @__PURE__ */ v()),
|
|
1110
|
+
avatar: /* @__PURE__ */ p(/* @__PURE__ */ v()),
|
|
1111
|
+
// TODO allow using a track instead of a URL?
|
|
1112
|
+
color: /* @__PURE__ */ p(/* @__PURE__ */ v())
|
|
1113
|
+
}), Qn = /* @__PURE__ */ _({
|
|
1114
|
+
name: /* @__PURE__ */ v()
|
|
1115
|
+
}), Ne = /* @__PURE__ */ _({
|
|
1116
|
+
// See: https://w3c.github.io/webcodecs/codec_registry.html
|
|
1117
|
+
codec: /* @__PURE__ */ v(),
|
|
1118
|
+
// The container format, used to decode the timestamp and more.
|
|
1119
|
+
container: gt,
|
|
1120
|
+
// The description is used for some codecs.
|
|
1121
|
+
// If provided, we can initialize the decoder based on the catalog alone.
|
|
1122
|
+
// Otherwise, the initialization information is (repeated) before each key-frame.
|
|
1123
|
+
description: /* @__PURE__ */ p(/* @__PURE__ */ v()),
|
|
1124
|
+
// hex encoded TODO use base64
|
|
1125
|
+
// The width and height of the video in pixels.
|
|
1126
|
+
// NOTE: formats that don't use a description can adjust these values in-band.
|
|
1127
|
+
codedWidth: /* @__PURE__ */ p(R),
|
|
1128
|
+
codedHeight: /* @__PURE__ */ p(R),
|
|
1129
|
+
// Ratio of display width/height to coded width/height
|
|
1130
|
+
// Allows stretching/squishing individual "pixels" of the video
|
|
1131
|
+
// If not provided, the display ratio is 1:1
|
|
1132
|
+
displayAspectWidth: /* @__PURE__ */ p(R),
|
|
1133
|
+
displayAspectHeight: /* @__PURE__ */ p(R),
|
|
1134
|
+
// The frame rate of the video in frames per second
|
|
1135
|
+
framerate: /* @__PURE__ */ p(/* @__PURE__ */ Z()),
|
|
1136
|
+
// The bitrate of the video in bits per second
|
|
1137
|
+
// TODO: Support up to Number.MAX_SAFE_INTEGER
|
|
1138
|
+
bitrate: /* @__PURE__ */ p(R),
|
|
1139
|
+
// If true, the decoder will optimize for latency.
|
|
1140
|
+
// Default: true
|
|
1141
|
+
optimizeForLatency: /* @__PURE__ */ p(/* @__PURE__ */ ht()),
|
|
1142
|
+
// The maximum jitter before the next frame is emitted in milliseconds.
|
|
1143
|
+
// The player's jitter buffer should be larger than this value.
|
|
1144
|
+
// If not provided, the player should assume each frame is flushed immediately.
|
|
1145
|
+
//
|
|
1146
|
+
// ex:
|
|
1147
|
+
// - If each frame is flushed immediately, this would be 1000/fps.
|
|
1148
|
+
// - If there can be up to 3 b-frames in a row, this would be 3 * 1000/fps.
|
|
1149
|
+
// - If frames are buffered into 2s segments, this would be 2s.
|
|
1150
|
+
jitter: /* @__PURE__ */ p(R)
|
|
1151
|
+
}), es = /* @__PURE__ */ ft([
|
|
1152
|
+
/* @__PURE__ */ _({
|
|
1153
|
+
// A map of track name to rendition configuration.
|
|
1154
|
+
// This is not an array in order for it to work with JSON Merge Patch.
|
|
1155
|
+
renditions: /* @__PURE__ */ Ae(/* @__PURE__ */ v(), Ne),
|
|
1156
|
+
// Render the video at this size in pixels.
|
|
1157
|
+
// This is separate from the display aspect ratio because it does not require reinitialization.
|
|
1158
|
+
display: /* @__PURE__ */ p(
|
|
1159
|
+
/* @__PURE__ */ _({
|
|
1160
|
+
width: R,
|
|
1161
|
+
height: R
|
|
1162
|
+
})
|
|
1163
|
+
),
|
|
1164
|
+
// The rotation of the video in degrees.
|
|
1165
|
+
// Default: 0
|
|
1166
|
+
rotation: /* @__PURE__ */ p(/* @__PURE__ */ Z()),
|
|
1167
|
+
// If true, the decoder will flip the video horizontally
|
|
1168
|
+
// Default: false
|
|
1169
|
+
flip: /* @__PURE__ */ p(/* @__PURE__ */ ht())
|
|
1170
|
+
}),
|
|
1171
|
+
// Backwards compatibility: transform old array of {track, config} to new object format
|
|
1172
|
+
/* @__PURE__ */ pt(
|
|
1173
|
+
/* @__PURE__ */ q(
|
|
1174
|
+
/* @__PURE__ */ _({
|
|
1175
|
+
track: Qn,
|
|
1176
|
+
config: Ne
|
|
1177
|
+
})
|
|
1178
|
+
),
|
|
1179
|
+
/* @__PURE__ */ mt((t) => {
|
|
1180
|
+
const e = t[0]?.config;
|
|
1181
|
+
return {
|
|
1182
|
+
renditions: Object.fromEntries(t.map((n) => [n.track.name, n.config])),
|
|
1183
|
+
display: e?.displayAspectWidth !== void 0 && e?.displayAspectHeight !== void 0 ? { width: e.displayAspectWidth, height: e.displayAspectHeight } : void 0,
|
|
1184
|
+
rotation: void 0,
|
|
1185
|
+
flip: void 0
|
|
1186
|
+
};
|
|
1187
|
+
})
|
|
1188
|
+
)
|
|
1189
|
+
]), ts = /* @__PURE__ */ _({
|
|
1190
|
+
video: /* @__PURE__ */ p(es),
|
|
1191
|
+
audio: /* @__PURE__ */ p(qn),
|
|
1192
|
+
location: /* @__PURE__ */ p(Kn),
|
|
1193
|
+
user: /* @__PURE__ */ p(Jn),
|
|
1194
|
+
chat: /* @__PURE__ */ p(Yn),
|
|
1195
|
+
capabilities: /* @__PURE__ */ p(Xn),
|
|
1196
|
+
preview: /* @__PURE__ */ p(ue)
|
|
1197
|
+
});
|
|
1198
|
+
function ns(t) {
|
|
1199
|
+
const n = new TextDecoder().decode(t);
|
|
1200
|
+
try {
|
|
1201
|
+
const s = JSON.parse(n);
|
|
1202
|
+
return ts.parse(s);
|
|
1203
|
+
} catch (s) {
|
|
1204
|
+
throw console.warn("invalid catalog", n), s;
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
async function ss(t) {
|
|
1208
|
+
const e = await t.readFrame();
|
|
1209
|
+
if (e)
|
|
1210
|
+
return ns(e);
|
|
1211
|
+
}
|
|
1212
|
+
function yt(t) {
|
|
1213
|
+
return t instanceof ArrayBuffer || typeof SharedArrayBuffer < "u" && t instanceof SharedArrayBuffer;
|
|
1214
|
+
}
|
|
1215
|
+
const is = "utf-16", ve = "utf-16be", $e = "utf-16le", ae = "utf-8";
|
|
1216
|
+
function bt(t, e = {}) {
|
|
1217
|
+
let n;
|
|
1218
|
+
yt(t) ? n = new DataView(t) : n = new DataView(t.buffer, t.byteOffset, t.byteLength);
|
|
1219
|
+
let s = 0, { encoding: i } = e;
|
|
1220
|
+
if (!i) {
|
|
1221
|
+
const u = n.getUint8(0), l = n.getUint8(1);
|
|
1222
|
+
u == 239 && l == 187 && n.getUint8(2) == 191 ? (i = ae, s = 3) : u == 254 && l == 255 ? (i = ve, s = 2) : u == 255 && l == 254 ? (i = $e, s = 2) : i = ae;
|
|
1223
|
+
}
|
|
1224
|
+
if (typeof TextDecoder < "u") return new TextDecoder(i).decode(n);
|
|
1225
|
+
const { byteLength: r } = n, o = i !== ve;
|
|
1226
|
+
let a = "", c;
|
|
1227
|
+
for (; s < r; ) {
|
|
1228
|
+
switch (i) {
|
|
1229
|
+
case ae:
|
|
1230
|
+
if (c = n.getUint8(s), c < 128) s++;
|
|
1231
|
+
else if (c >= 194 && c <= 223) if (s + 1 < r) {
|
|
1232
|
+
const u = n.getUint8(s + 1);
|
|
1233
|
+
u >= 128 && u <= 191 ? (c = (c & 31) << 6 | u & 63, s += 2) : s++;
|
|
1234
|
+
} else s++;
|
|
1235
|
+
else if (c >= 224 && c <= 239) if (s + 2 <= r - 1) {
|
|
1236
|
+
const u = n.getUint8(s + 1), l = n.getUint8(s + 2);
|
|
1237
|
+
u >= 128 && u <= 191 && l >= 128 && l <= 191 ? (c = (c & 15) << 12 | (u & 63) << 6 | l & 63, s += 3) : s++;
|
|
1238
|
+
} else s++;
|
|
1239
|
+
else if (c >= 240 && c <= 244) if (s + 3 <= r - 1) {
|
|
1240
|
+
const u = n.getUint8(s + 1), l = n.getUint8(s + 2), d = n.getUint8(s + 3);
|
|
1241
|
+
u >= 128 && u <= 191 && l >= 128 && l <= 191 && d >= 128 && d <= 191 ? (c = (c & 7) << 18 | (u & 63) << 12 | (l & 63) << 6 | d & 63, s += 4) : s++;
|
|
1242
|
+
} else s++;
|
|
1243
|
+
else s++;
|
|
1244
|
+
break;
|
|
1245
|
+
case ve:
|
|
1246
|
+
case is:
|
|
1247
|
+
case $e:
|
|
1248
|
+
c = n.getUint16(s, o), s += 2;
|
|
1249
|
+
break;
|
|
1250
|
+
}
|
|
1251
|
+
a += String.fromCodePoint(c);
|
|
1252
|
+
}
|
|
1253
|
+
return a;
|
|
1254
|
+
}
|
|
1255
|
+
function rs(t) {
|
|
1256
|
+
return new TextEncoder().encode(t);
|
|
1257
|
+
}
|
|
1258
|
+
function os(t) {
|
|
1259
|
+
return { writers: t?.writers ?? {} };
|
|
1260
|
+
}
|
|
1261
|
+
const as = [
|
|
1262
|
+
"dinf",
|
|
1263
|
+
"edts",
|
|
1264
|
+
"grpl",
|
|
1265
|
+
"mdia",
|
|
1266
|
+
"meco",
|
|
1267
|
+
"mfra",
|
|
1268
|
+
"minf",
|
|
1269
|
+
"moof",
|
|
1270
|
+
"moov",
|
|
1271
|
+
"mvex",
|
|
1272
|
+
"schi",
|
|
1273
|
+
"sinf",
|
|
1274
|
+
"stbl",
|
|
1275
|
+
"strk",
|
|
1276
|
+
"traf",
|
|
1277
|
+
"trak",
|
|
1278
|
+
"tref",
|
|
1279
|
+
"udta",
|
|
1280
|
+
"vttc"
|
|
1281
|
+
];
|
|
1282
|
+
function vt(t) {
|
|
1283
|
+
return "boxes" in t || as.includes(t.type);
|
|
1284
|
+
}
|
|
1285
|
+
const Fe = "utf8", V = "uint", le = "template", je = "string", Ze = "int", Ve = "data";
|
|
1286
|
+
var k = class {
|
|
1287
|
+
/**
|
|
1288
|
+
* Constructs a new IsoBoxWriteView.
|
|
1289
|
+
*
|
|
1290
|
+
* @param size - The size of the data view.
|
|
1291
|
+
*/
|
|
1292
|
+
constructor(t, e) {
|
|
1293
|
+
this.writeUint = (n, s) => {
|
|
1294
|
+
const { dataView: i, cursor: r } = this;
|
|
1295
|
+
switch (s) {
|
|
1296
|
+
case 1:
|
|
1297
|
+
i.setUint8(r, n);
|
|
1298
|
+
break;
|
|
1299
|
+
case 2:
|
|
1300
|
+
i.setUint16(r, n);
|
|
1301
|
+
break;
|
|
1302
|
+
case 3: {
|
|
1303
|
+
const o = (n & 16776960) >> 8, a = n & 255;
|
|
1304
|
+
i.setUint16(r, o), i.setUint8(r + 2, a);
|
|
1305
|
+
break;
|
|
1306
|
+
}
|
|
1307
|
+
case 4:
|
|
1308
|
+
i.setUint32(r, n);
|
|
1309
|
+
break;
|
|
1310
|
+
case 8: {
|
|
1311
|
+
const o = Math.floor(n / Math.pow(2, 32)), a = n - o * Math.pow(2, 32);
|
|
1312
|
+
i.setUint32(r, o), i.setUint32(r + 4, a);
|
|
1313
|
+
break;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
this.cursor += s;
|
|
1317
|
+
}, this.writeInt = (n, s) => {
|
|
1318
|
+
const { dataView: i, cursor: r } = this;
|
|
1319
|
+
switch (s) {
|
|
1320
|
+
case 1:
|
|
1321
|
+
i.setInt8(r, n);
|
|
1322
|
+
break;
|
|
1323
|
+
case 2:
|
|
1324
|
+
i.setInt16(r, n);
|
|
1325
|
+
break;
|
|
1326
|
+
case 4:
|
|
1327
|
+
i.setInt32(r, n);
|
|
1328
|
+
break;
|
|
1329
|
+
case 8:
|
|
1330
|
+
const o = Math.floor(n / Math.pow(2, 32)), a = n - o * Math.pow(2, 32);
|
|
1331
|
+
i.setUint32(r, o), i.setUint32(r + 4, a);
|
|
1332
|
+
break;
|
|
1333
|
+
}
|
|
1334
|
+
this.cursor += s;
|
|
1335
|
+
}, this.writeString = (n) => {
|
|
1336
|
+
for (let s = 0, i = n.length; s < i; s++) this.writeUint(n.charCodeAt(s), 1);
|
|
1337
|
+
}, this.writeTerminatedString = (n) => {
|
|
1338
|
+
if (n.length !== 0) {
|
|
1339
|
+
for (let s = 0, i = n.length; s < i; s++) this.writeUint(n.charCodeAt(s), 1);
|
|
1340
|
+
this.writeUint(0, 1);
|
|
1341
|
+
}
|
|
1342
|
+
}, this.writeUtf8TerminatedString = (n) => {
|
|
1343
|
+
const s = rs(n);
|
|
1344
|
+
new Uint8Array(this.dataView.buffer).set(s, this.cursor), this.cursor += s.length, this.writeUint(0, 1);
|
|
1345
|
+
}, this.writeBytes = (n) => {
|
|
1346
|
+
Array.isArray(n) || (n = [n]);
|
|
1347
|
+
for (const s of n)
|
|
1348
|
+
new Uint8Array(this.dataView.buffer).set(s, this.cursor), this.cursor += s.length;
|
|
1349
|
+
}, this.writeArray = (n, s, i, r) => {
|
|
1350
|
+
const o = s === V ? this.writeUint : s === le ? this.writeTemplate : this.writeInt;
|
|
1351
|
+
for (let a = 0; a < r; a++) o(n[a] ?? 0, i);
|
|
1352
|
+
}, this.writeTemplate = (n, s) => {
|
|
1353
|
+
const r = Math.round(n * Math.pow(2, s === 4 ? 16 : 8));
|
|
1354
|
+
this.writeUint(r, s);
|
|
1355
|
+
}, this.writeBoxHeader = (n, s) => {
|
|
1356
|
+
s > 4294967295 ? (this.writeUint(1, 4), this.writeString(n), this.writeUint(s, 8)) : (this.writeUint(s, 4), this.writeString(n));
|
|
1357
|
+
}, this.dataView = new DataView(new ArrayBuffer(e)), this.cursor = 0, this.writeBoxHeader(t, e);
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* The buffer of the data view.
|
|
1361
|
+
*
|
|
1362
|
+
* @returns The buffer of the data view.
|
|
1363
|
+
*/
|
|
1364
|
+
get buffer() {
|
|
1365
|
+
return this.dataView.buffer;
|
|
1366
|
+
}
|
|
1367
|
+
/**
|
|
1368
|
+
* The length of the data view.
|
|
1369
|
+
*
|
|
1370
|
+
* @returns The length of the data view.
|
|
1371
|
+
*/
|
|
1372
|
+
get byteLength() {
|
|
1373
|
+
return this.dataView.byteLength;
|
|
1374
|
+
}
|
|
1375
|
+
/**
|
|
1376
|
+
* The offset of the data view.
|
|
1377
|
+
*
|
|
1378
|
+
* @returns The offset of the data view.
|
|
1379
|
+
*/
|
|
1380
|
+
get byteOffset() {
|
|
1381
|
+
return this.dataView.byteOffset;
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Writes a full box header to the data view.
|
|
1385
|
+
*
|
|
1386
|
+
* @param version - The version of the full box.
|
|
1387
|
+
* @param flags - The flags of the full box.
|
|
1388
|
+
*/
|
|
1389
|
+
writeFullBox(t, e) {
|
|
1390
|
+
this.writeUint(t, 1), this.writeUint(e, 3);
|
|
1391
|
+
}
|
|
1392
|
+
};
|
|
1393
|
+
function St(t, e) {
|
|
1394
|
+
return Array.from(t, (n) => us(n, e));
|
|
1395
|
+
}
|
|
1396
|
+
function ke(t, e) {
|
|
1397
|
+
const n = St(t, e);
|
|
1398
|
+
return {
|
|
1399
|
+
bytes: n,
|
|
1400
|
+
size: n.reduce((s, i) => s + i.byteLength, 0)
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
function cs(t, e) {
|
|
1404
|
+
const { bytes: s, size: i } = ke(t.boxes, e), r = 8 + i, o = new k(t.type, r);
|
|
1405
|
+
return o.writeBytes(s), o;
|
|
1406
|
+
}
|
|
1407
|
+
function us(t, e) {
|
|
1408
|
+
let n = null;
|
|
1409
|
+
if ("type" in t) {
|
|
1410
|
+
const { type: s } = t, i = e.writers?.[s];
|
|
1411
|
+
if (i ? n = i(t, e) : vt(t) ? n = cs(t, e) : "view" in t && (n = t.view), !n) throw new Error(`No writer found for box type: ${s}`);
|
|
1412
|
+
}
|
|
1413
|
+
if ("buffer" in t && (n = t), !n) throw new Error("Invalid box");
|
|
1414
|
+
return new Uint8Array(n.buffer, n.byteOffset, n.byteLength);
|
|
1415
|
+
}
|
|
1416
|
+
function ls(t, e, n) {
|
|
1417
|
+
const s = n > 0 ? n : t.byteLength - (e - t.byteOffset);
|
|
1418
|
+
return new Uint8Array(t.buffer, e, Math.max(s, 0));
|
|
1419
|
+
}
|
|
1420
|
+
function ds(t, e, n) {
|
|
1421
|
+
let s = NaN;
|
|
1422
|
+
const i = e - t.byteOffset;
|
|
1423
|
+
switch (n) {
|
|
1424
|
+
case 1:
|
|
1425
|
+
s = t.getInt8(i);
|
|
1426
|
+
break;
|
|
1427
|
+
case 2:
|
|
1428
|
+
s = t.getInt16(i);
|
|
1429
|
+
break;
|
|
1430
|
+
case 4:
|
|
1431
|
+
s = t.getInt32(i);
|
|
1432
|
+
break;
|
|
1433
|
+
case 8:
|
|
1434
|
+
const r = t.getInt32(i), o = t.getInt32(i + 4);
|
|
1435
|
+
s = r * Math.pow(2, 32) + o;
|
|
1436
|
+
break;
|
|
1437
|
+
}
|
|
1438
|
+
return s;
|
|
1439
|
+
}
|
|
1440
|
+
function H(t, e, n) {
|
|
1441
|
+
const s = e - t.byteOffset;
|
|
1442
|
+
let i = NaN, r, o;
|
|
1443
|
+
switch (n) {
|
|
1444
|
+
case 1:
|
|
1445
|
+
i = t.getUint8(s);
|
|
1446
|
+
break;
|
|
1447
|
+
case 2:
|
|
1448
|
+
i = t.getUint16(s);
|
|
1449
|
+
break;
|
|
1450
|
+
case 3:
|
|
1451
|
+
r = t.getUint16(s), o = t.getUint8(s + 2), i = (r << 8) + o;
|
|
1452
|
+
break;
|
|
1453
|
+
case 4:
|
|
1454
|
+
i = t.getUint32(s);
|
|
1455
|
+
break;
|
|
1456
|
+
case 8:
|
|
1457
|
+
r = t.getUint32(s), o = t.getUint32(s + 4), i = r * Math.pow(2, 32) + o;
|
|
1458
|
+
break;
|
|
1459
|
+
}
|
|
1460
|
+
return i;
|
|
1461
|
+
}
|
|
1462
|
+
function We(t, e, n) {
|
|
1463
|
+
let s = "";
|
|
1464
|
+
for (let i = 0; i < n; i++) {
|
|
1465
|
+
const r = H(t, e + i, 1);
|
|
1466
|
+
s += String.fromCharCode(r);
|
|
1467
|
+
}
|
|
1468
|
+
return s;
|
|
1469
|
+
}
|
|
1470
|
+
function hs(t, e, n) {
|
|
1471
|
+
const s = n / 2;
|
|
1472
|
+
return H(t, e, s) + H(t, e + s, s) / Math.pow(2, s);
|
|
1473
|
+
}
|
|
1474
|
+
function fs(t, e) {
|
|
1475
|
+
let n = "", s = e;
|
|
1476
|
+
for (; s - t.byteOffset < t.byteLength; ) {
|
|
1477
|
+
const i = H(t, s, 1);
|
|
1478
|
+
if (i === 0) break;
|
|
1479
|
+
n += String.fromCharCode(i), s++;
|
|
1480
|
+
}
|
|
1481
|
+
return n;
|
|
1482
|
+
}
|
|
1483
|
+
function ms(t, e) {
|
|
1484
|
+
const n = t.byteLength - (e - t.byteOffset);
|
|
1485
|
+
return n > 0 ? bt(new DataView(t.buffer, e, n), { encoding: ae }) : "";
|
|
1486
|
+
}
|
|
1487
|
+
function ps(t, e) {
|
|
1488
|
+
const n = t.byteLength - (e - t.byteOffset);
|
|
1489
|
+
let s = "";
|
|
1490
|
+
if (n > 0) {
|
|
1491
|
+
const i = new DataView(t.buffer, e, n);
|
|
1492
|
+
let r = 0;
|
|
1493
|
+
for (; r < n && i.getUint8(r) !== 0; r++) ;
|
|
1494
|
+
s = bt(new DataView(t.buffer, e, r), { encoding: ae });
|
|
1495
|
+
}
|
|
1496
|
+
return s;
|
|
1497
|
+
}
|
|
1498
|
+
var gs = class Mt {
|
|
1499
|
+
/**
|
|
1500
|
+
* Creates a new IsoView instance. Similar to DataView, but with additional
|
|
1501
|
+
* methods for reading ISO BMFF data. It implements the iterator protocol,
|
|
1502
|
+
* so it can be used in a for...of loop.
|
|
1503
|
+
*
|
|
1504
|
+
* @param raw - The raw data to view.
|
|
1505
|
+
* @param config - The configuration for the IsoView.
|
|
1506
|
+
*/
|
|
1507
|
+
constructor(e, n) {
|
|
1508
|
+
this.truncated = !1, this.slice = (s, i) => {
|
|
1509
|
+
const r = new Mt(new DataView(this.dataView.buffer, s, i), this.config), o = this.offset - s, a = i - o;
|
|
1510
|
+
return this.offset += a, r.jump(o), r;
|
|
1511
|
+
}, this.read = (s, i = 0) => {
|
|
1512
|
+
const { dataView: r, offset: o } = this;
|
|
1513
|
+
let a, c = i;
|
|
1514
|
+
switch (s) {
|
|
1515
|
+
case V:
|
|
1516
|
+
a = H(r, o, i);
|
|
1517
|
+
break;
|
|
1518
|
+
case Ze:
|
|
1519
|
+
a = ds(r, o, i);
|
|
1520
|
+
break;
|
|
1521
|
+
case le:
|
|
1522
|
+
a = hs(r, o, i);
|
|
1523
|
+
break;
|
|
1524
|
+
case je:
|
|
1525
|
+
i === -1 ? (a = fs(r, o), c = a.length + 1) : a = We(r, o, i);
|
|
1526
|
+
break;
|
|
1527
|
+
case Ve:
|
|
1528
|
+
a = ls(r, o, i), c = a.length;
|
|
1529
|
+
break;
|
|
1530
|
+
case Fe:
|
|
1531
|
+
i === -1 ? (a = ps(r, o), c = a.length + 1) : a = ms(r, o);
|
|
1532
|
+
break;
|
|
1533
|
+
default:
|
|
1534
|
+
a = -1;
|
|
1535
|
+
}
|
|
1536
|
+
return this.offset += c, a;
|
|
1537
|
+
}, this.readUint = (s) => this.read(V, s), this.readInt = (s) => this.read(Ze, s), this.readString = (s) => this.read(je, s), this.readTemplate = (s) => this.read(le, s), this.readData = (s) => this.read(Ve, s), this.readUtf8 = (s) => this.read(Fe, s), this.readFullBox = () => ({
|
|
1538
|
+
version: this.readUint(1),
|
|
1539
|
+
flags: this.readUint(3)
|
|
1540
|
+
}), this.readArray = (s, i, r) => {
|
|
1541
|
+
const o = [];
|
|
1542
|
+
for (let a = 0; a < r; a++) o.push(this.read(s, i));
|
|
1543
|
+
return o;
|
|
1544
|
+
}, this.jump = (s) => {
|
|
1545
|
+
this.offset += s;
|
|
1546
|
+
}, this.readBox = () => {
|
|
1547
|
+
const { dataView: s, offset: i } = this;
|
|
1548
|
+
let r = 0;
|
|
1549
|
+
const o = H(s, i, 4), a = We(s, i + 4, 4), c = {
|
|
1550
|
+
size: o,
|
|
1551
|
+
type: a
|
|
1552
|
+
};
|
|
1553
|
+
r += 8, c.size === 1 && (c.largesize = H(s, i + r, 8), r += 8);
|
|
1554
|
+
const u = c.size === 0 ? this.bytesRemaining : c.largesize ?? c.size;
|
|
1555
|
+
if (this.cursor + u > s.byteLength)
|
|
1556
|
+
throw this.truncated = !0, new Error("Truncated box");
|
|
1557
|
+
return this.jump(r), a === "uuid" && (c.usertype = this.readArray("uint", 1, 16)), c.view = this.slice(i, u), c;
|
|
1558
|
+
}, this.readBoxes = (s = -1) => {
|
|
1559
|
+
const i = [];
|
|
1560
|
+
for (const r of this)
|
|
1561
|
+
if (i.push(r), s > 0 && i.length >= s) break;
|
|
1562
|
+
return i;
|
|
1563
|
+
}, this.readEntries = (s, i) => {
|
|
1564
|
+
const r = [];
|
|
1565
|
+
for (let o = 0; o < s; o++) r.push(i());
|
|
1566
|
+
return r;
|
|
1567
|
+
}, this.dataView = yt(e) ? new DataView(e) : e instanceof DataView ? e : new DataView(e.buffer, e.byteOffset, e.byteLength), this.offset = this.dataView.byteOffset, this.config = n || {};
|
|
1568
|
+
}
|
|
1569
|
+
/**
|
|
1570
|
+
* The buffer of the data view.
|
|
1571
|
+
*/
|
|
1572
|
+
get buffer() {
|
|
1573
|
+
return this.dataView.buffer;
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* The byte offset of the data view.
|
|
1577
|
+
*/
|
|
1578
|
+
get byteOffset() {
|
|
1579
|
+
return this.dataView.byteOffset;
|
|
1580
|
+
}
|
|
1581
|
+
/**
|
|
1582
|
+
* The byte length of the data view.
|
|
1583
|
+
*/
|
|
1584
|
+
get byteLength() {
|
|
1585
|
+
return this.dataView.byteLength;
|
|
1586
|
+
}
|
|
1587
|
+
/**
|
|
1588
|
+
* The current byteoffset in the data view.
|
|
1589
|
+
*/
|
|
1590
|
+
get cursor() {
|
|
1591
|
+
return this.offset - this.dataView.byteOffset;
|
|
1592
|
+
}
|
|
1593
|
+
/**
|
|
1594
|
+
* Whether the end of the data view has been reached.
|
|
1595
|
+
*/
|
|
1596
|
+
get done() {
|
|
1597
|
+
return this.cursor >= this.dataView.byteLength || this.truncated;
|
|
1598
|
+
}
|
|
1599
|
+
/**
|
|
1600
|
+
* The number of bytes remaining in the data view.
|
|
1601
|
+
*/
|
|
1602
|
+
get bytesRemaining() {
|
|
1603
|
+
return this.dataView.byteLength - this.cursor;
|
|
1604
|
+
}
|
|
1605
|
+
/**
|
|
1606
|
+
* Iterates over the boxes in the data view.
|
|
1607
|
+
*
|
|
1608
|
+
* @returns A generator of boxes.
|
|
1609
|
+
*/
|
|
1610
|
+
*[Symbol.iterator]() {
|
|
1611
|
+
const { readers: e = {} } = this.config;
|
|
1612
|
+
for (; !this.done; ) try {
|
|
1613
|
+
const n = this.readBox(), { type: s, view: i } = n, r = e[s] || e[s.trim()];
|
|
1614
|
+
if (r && Object.assign(n, r(i, s)), vt(n) && !n.boxes) {
|
|
1615
|
+
const o = [];
|
|
1616
|
+
for (const a of i) o.push(a);
|
|
1617
|
+
n.boxes = o;
|
|
1618
|
+
}
|
|
1619
|
+
yield n;
|
|
1620
|
+
} catch (n) {
|
|
1621
|
+
if (n instanceof Error && n.message === "Truncated box") break;
|
|
1622
|
+
throw n;
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
};
|
|
1626
|
+
function _t(t, e) {
|
|
1627
|
+
const n = [];
|
|
1628
|
+
for (const s of new gs(t, e)) n.push(s);
|
|
1629
|
+
return n;
|
|
1630
|
+
}
|
|
1631
|
+
function ws(t, e) {
|
|
1632
|
+
return St(t, os(e));
|
|
1633
|
+
}
|
|
1634
|
+
function ys(t) {
|
|
1635
|
+
return {
|
|
1636
|
+
type: "mdat",
|
|
1637
|
+
data: t.readData(-1)
|
|
1638
|
+
};
|
|
1639
|
+
}
|
|
1640
|
+
function bs(t) {
|
|
1641
|
+
return {
|
|
1642
|
+
type: "mfhd",
|
|
1643
|
+
...t.readFullBox(),
|
|
1644
|
+
sequenceNumber: t.readUint(4)
|
|
1645
|
+
};
|
|
1646
|
+
}
|
|
1647
|
+
function vs(t) {
|
|
1648
|
+
const { version: e, flags: n } = t.readFullBox();
|
|
1649
|
+
return {
|
|
1650
|
+
type: "tfdt",
|
|
1651
|
+
version: e,
|
|
1652
|
+
flags: n,
|
|
1653
|
+
baseMediaDecodeTime: t.readUint(e == 1 ? 8 : 4)
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
function Ss(t) {
|
|
1657
|
+
const { version: e, flags: n } = t.readFullBox();
|
|
1658
|
+
return {
|
|
1659
|
+
type: "tfhd",
|
|
1660
|
+
version: e,
|
|
1661
|
+
flags: n,
|
|
1662
|
+
trackId: t.readUint(4),
|
|
1663
|
+
baseDataOffset: n & 1 ? t.readUint(8) : void 0,
|
|
1664
|
+
sampleDescriptionIndex: n & 2 ? t.readUint(4) : void 0,
|
|
1665
|
+
defaultSampleDuration: n & 8 ? t.readUint(4) : void 0,
|
|
1666
|
+
defaultSampleSize: n & 16 ? t.readUint(4) : void 0,
|
|
1667
|
+
defaultSampleFlags: n & 32 ? t.readUint(4) : void 0
|
|
1668
|
+
};
|
|
1669
|
+
}
|
|
1670
|
+
function Ms(t) {
|
|
1671
|
+
const { version: e, flags: n } = t.readFullBox(), s = t.readUint(4);
|
|
1672
|
+
let i, r;
|
|
1673
|
+
n & 1 && (i = t.readInt(4)), n & 4 && (r = t.readUint(4));
|
|
1674
|
+
const o = t.readEntries(s, () => {
|
|
1675
|
+
const a = {};
|
|
1676
|
+
return n & 256 && (a.sampleDuration = t.readUint(4)), n & 512 && (a.sampleSize = t.readUint(4)), n & 1024 && (a.sampleFlags = t.readUint(4)), n & 2048 && (a.sampleCompositionTimeOffset = e === 1 ? t.readInt(4) : t.readUint(4)), a;
|
|
1677
|
+
});
|
|
1678
|
+
return {
|
|
1679
|
+
type: "trun",
|
|
1680
|
+
version: e,
|
|
1681
|
+
flags: n,
|
|
1682
|
+
sampleCount: s,
|
|
1683
|
+
dataOffset: i,
|
|
1684
|
+
firstSampleFlags: r,
|
|
1685
|
+
samples: o
|
|
1686
|
+
};
|
|
1687
|
+
}
|
|
1688
|
+
function _s(t, e) {
|
|
1689
|
+
const r = t.entries.length, { bytes: o, size: a } = ke(t.entries, e), c = new k("dref", 16 + a);
|
|
1690
|
+
return c.writeFullBox(t.version, t.flags), c.writeUint(r, 4), c.writeBytes(o), c;
|
|
1691
|
+
}
|
|
1692
|
+
function zs(t) {
|
|
1693
|
+
const i = t.compatibleBrands.length * 4, r = new k("ftyp", 16 + i);
|
|
1694
|
+
r.writeString(t.majorBrand), r.writeUint(t.minorVersion, 4);
|
|
1695
|
+
for (const o of t.compatibleBrands) r.writeString(o);
|
|
1696
|
+
return r;
|
|
1697
|
+
}
|
|
1698
|
+
function As(t) {
|
|
1699
|
+
const o = t.name.length + 1, a = new k("hdlr", 32 + o);
|
|
1700
|
+
return a.writeFullBox(t.version, t.flags), a.writeUint(t.preDefined, 4), a.writeString(t.handlerType), a.writeArray(t.reserved, V, 4, 3), a.writeTerminatedString(t.name), a;
|
|
1701
|
+
}
|
|
1702
|
+
function ks(t) {
|
|
1703
|
+
const e = new k("mdat", 8 + t.data.length);
|
|
1704
|
+
return e.writeBytes(t.data), e;
|
|
1705
|
+
}
|
|
1706
|
+
function Ts(t) {
|
|
1707
|
+
const e = t.version === 1 ? 8 : 4, n = 8, s = 4, i = e * 3, r = new k("mdhd", n + s + i + 4 + 2 + 2);
|
|
1708
|
+
r.writeFullBox(t.version, t.flags), r.writeUint(t.creationTime, e), r.writeUint(t.modificationTime, e), r.writeUint(t.timescale, 4), r.writeUint(t.duration, e);
|
|
1709
|
+
const o = t.language.length >= 3 ? (t.language.charCodeAt(0) - 96 & 31) << 10 | (t.language.charCodeAt(1) - 96 & 31) << 5 | t.language.charCodeAt(2) - 96 & 31 : 0;
|
|
1710
|
+
return r.writeUint(o, 2), r.writeUint(t.preDefined, 2), r;
|
|
1711
|
+
}
|
|
1712
|
+
function Es(t) {
|
|
1713
|
+
const e = new k("mfhd", 16);
|
|
1714
|
+
return e.writeFullBox(t.version, t.flags), e.writeUint(t.sequenceNumber, 4), e;
|
|
1715
|
+
}
|
|
1716
|
+
function Us(t) {
|
|
1717
|
+
const e = t.version === 1 ? 8 : 4, n = 8, s = 4, i = e * 3, r = new k("mvhd", n + s + i + 4 + 4 + 2 + 2 + 8 + 36 + 24 + 4);
|
|
1718
|
+
return r.writeFullBox(t.version, t.flags), r.writeUint(t.creationTime, e), r.writeUint(t.modificationTime, e), r.writeUint(t.timescale, 4), r.writeUint(t.duration, e), r.writeTemplate(t.rate, 4), r.writeTemplate(t.volume, 2), r.writeUint(t.reserved1, 2), r.writeArray(t.reserved2, V, 4, 2), r.writeArray(t.matrix, le, 4, 9), r.writeArray(t.preDefined, V, 4, 6), r.writeUint(t.nextTrackId, 4), r;
|
|
1719
|
+
}
|
|
1720
|
+
function Rs(t) {
|
|
1721
|
+
const e = new k("smhd", 16);
|
|
1722
|
+
return e.writeFullBox(t.version, t.flags), e.writeUint(t.balance, 2), e.writeUint(t.reserved, 2), e;
|
|
1723
|
+
}
|
|
1724
|
+
function Bs(t, e) {
|
|
1725
|
+
const r = t.entries.length, { bytes: o, size: a } = ke(t.entries, e), c = new k("stsd", 16 + a);
|
|
1726
|
+
return c.writeFullBox(t.version, t.flags), c.writeUint(r, 4), c.writeBytes(o), c;
|
|
1727
|
+
}
|
|
1728
|
+
function xs(t) {
|
|
1729
|
+
const i = t.entryCount * 8, r = new k("stts", 16 + i);
|
|
1730
|
+
r.writeFullBox(t.version, t.flags), r.writeUint(t.entryCount, 4);
|
|
1731
|
+
for (const o of t.entries)
|
|
1732
|
+
r.writeUint(o.sampleCount, 4), r.writeUint(o.sampleDelta, 4);
|
|
1733
|
+
return r;
|
|
1734
|
+
}
|
|
1735
|
+
function Is(t) {
|
|
1736
|
+
const e = t.version === 1 ? 8 : 4, n = 8, s = 4, i = e, r = new k("tfdt", n + s + i);
|
|
1737
|
+
return r.writeFullBox(t.version, t.flags), r.writeUint(t.baseMediaDecodeTime, e), r;
|
|
1738
|
+
}
|
|
1739
|
+
function Cs(t) {
|
|
1740
|
+
const i = t.flags & 1 ? 8 : 0, r = t.flags & 2 ? 4 : 0, o = t.flags & 8 ? 4 : 0, a = t.flags & 16 ? 4 : 0, c = t.flags & 32 ? 4 : 0, u = new k("tfhd", 16 + i + r + o + a + c);
|
|
1741
|
+
return u.writeFullBox(t.version, t.flags), u.writeUint(t.trackId, 4), t.flags & 1 && u.writeUint(t.baseDataOffset ?? 0, 8), t.flags & 2 && u.writeUint(t.sampleDescriptionIndex ?? 0, 4), t.flags & 8 && u.writeUint(t.defaultSampleDuration ?? 0, 4), t.flags & 16 && u.writeUint(t.defaultSampleSize ?? 0, 4), t.flags & 32 && u.writeUint(t.defaultSampleFlags ?? 0, 4), u;
|
|
1742
|
+
}
|
|
1743
|
+
function Ls(t) {
|
|
1744
|
+
const e = t.version === 1 ? 8 : 4, n = 8, s = 4, i = e * 3, r = new k("tkhd", n + s + i + 4 + 4 + 8 + 2 + 2 + 2 + 2 + 36 + 4 + 4);
|
|
1745
|
+
return r.writeFullBox(t.version, t.flags), r.writeUint(t.creationTime, e), r.writeUint(t.modificationTime, e), r.writeUint(t.trackId, 4), r.writeUint(t.reserved1, 4), r.writeUint(t.duration, e), r.writeArray(t.reserved2, V, 4, 2), r.writeUint(t.layer, 2), r.writeUint(t.alternateGroup, 2), r.writeTemplate(t.volume, 2), r.writeUint(t.reserved3, 2), r.writeArray(t.matrix, le, 4, 9), r.writeTemplate(t.width, 4), r.writeTemplate(t.height, 4), r;
|
|
1746
|
+
}
|
|
1747
|
+
function Os(t) {
|
|
1748
|
+
const e = new k("trex", 32);
|
|
1749
|
+
return e.writeFullBox(t.version, t.flags), e.writeUint(t.trackId, 4), e.writeUint(t.defaultSampleDescriptionIndex, 4), e.writeUint(t.defaultSampleDuration, 4), e.writeUint(t.defaultSampleSize, 4), e.writeUint(t.defaultSampleFlags, 4), e;
|
|
1750
|
+
}
|
|
1751
|
+
function Ds(t) {
|
|
1752
|
+
const i = t.flags & 1 ? 4 : 0, r = t.flags & 4 ? 4 : 0;
|
|
1753
|
+
let o = 0;
|
|
1754
|
+
t.flags & 256 && (o += 4), t.flags & 512 && (o += 4), t.flags & 1024 && (o += 4), t.flags & 2048 && (o += 4);
|
|
1755
|
+
const a = o * t.sampleCount, c = new k("trun", 16 + i + r + a);
|
|
1756
|
+
c.writeFullBox(t.version, t.flags), c.writeUint(t.sampleCount, 4), t.flags & 1 && c.writeUint(t.dataOffset ?? 0, 4), t.flags & 4 && c.writeUint(t.firstSampleFlags ?? 0, 4);
|
|
1757
|
+
for (const u of t.samples)
|
|
1758
|
+
t.flags & 256 && c.writeUint(u.sampleDuration ?? 0, 4), t.flags & 512 && c.writeUint(u.sampleSize ?? 0, 4), t.flags & 1024 && c.writeUint(u.sampleFlags ?? 0, 4), t.flags & 2048 && c.writeUint(u.sampleCompositionTimeOffset ?? 0, 4);
|
|
1759
|
+
return c;
|
|
1760
|
+
}
|
|
1761
|
+
function Ps(t) {
|
|
1762
|
+
const s = t.location.length + 1, i = new k("url ", 12 + s);
|
|
1763
|
+
return i.writeFullBox(t.version, t.flags), i.writeTerminatedString(t.location), i;
|
|
1764
|
+
}
|
|
1765
|
+
function Ns(t) {
|
|
1766
|
+
const e = new k("vmhd", 20);
|
|
1767
|
+
return e.writeFullBox(t.version, t.flags), e.writeUint(t.graphicsmode, 2), e.writeArray(t.opcolor, V, 2, 3), e;
|
|
1768
|
+
}
|
|
1769
|
+
const zt = {
|
|
1770
|
+
mfhd: bs,
|
|
1771
|
+
tfhd: Ss,
|
|
1772
|
+
tfdt: vs,
|
|
1773
|
+
trun: Ms,
|
|
1774
|
+
mdat: ys
|
|
1775
|
+
};
|
|
1776
|
+
function Y(t, e) {
|
|
1777
|
+
for (const n of t) {
|
|
1778
|
+
if (e(n))
|
|
1779
|
+
return n;
|
|
1780
|
+
const s = n.boxes;
|
|
1781
|
+
if (s && Array.isArray(s)) {
|
|
1782
|
+
const i = Y(s, e);
|
|
1783
|
+
if (i) return i;
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
function At(t) {
|
|
1788
|
+
const e = new ArrayBuffer(t.byteLength);
|
|
1789
|
+
return new Uint8Array(e).set(t), e;
|
|
1790
|
+
}
|
|
1791
|
+
function oe(t) {
|
|
1792
|
+
return (e) => e.type === t;
|
|
1793
|
+
}
|
|
1794
|
+
function kt(t, e) {
|
|
1795
|
+
const n = _t(At(t), { readers: zt });
|
|
1796
|
+
return (Y(n, oe("tfdt"))?.baseMediaDecodeTime ?? 0) * 1e6 / e;
|
|
1797
|
+
}
|
|
1798
|
+
function Tt(t, e) {
|
|
1799
|
+
const n = _t(At(t), { readers: zt }), i = Y(n, oe("tfdt"))?.baseMediaDecodeTime ?? 0, r = Y(n, oe("tfhd")), o = r?.defaultSampleDuration ?? 0, a = r?.defaultSampleSize ?? 0, c = r?.defaultSampleFlags ?? 0, u = Y(n, oe("trun"));
|
|
1800
|
+
if (!u)
|
|
1801
|
+
throw new Error("No trun box found in data segment");
|
|
1802
|
+
const l = Y(n, oe("mdat"));
|
|
1803
|
+
if (!l)
|
|
1804
|
+
throw new Error("No mdat box found in data segment");
|
|
1805
|
+
const d = l.data;
|
|
1806
|
+
if (!d)
|
|
1807
|
+
throw new Error("No data in mdat box");
|
|
1808
|
+
const f = [];
|
|
1809
|
+
let g = 0, y = i;
|
|
1810
|
+
for (let b = 0; b < u.sampleCount; b++) {
|
|
1811
|
+
const S = u.samples[b] ?? {}, E = S.sampleSize ?? a, z = S.sampleDuration ?? o;
|
|
1812
|
+
if (E <= 0)
|
|
1813
|
+
throw new Error(`Invalid sample size ${E} for sample ${b} in trun`);
|
|
1814
|
+
if (z <= 0)
|
|
1815
|
+
throw new Error(`Invalid sample duration ${z} for sample ${b} in trun`);
|
|
1816
|
+
if (g + E > d.length)
|
|
1817
|
+
throw new Error(
|
|
1818
|
+
`Sample ${b} would overflow mdat: offset=${g}, size=${E}, mdatLength=${d.length}`
|
|
1819
|
+
);
|
|
1820
|
+
const W = b === 0 && u.firstSampleFlags !== void 0 ? u.firstSampleFlags : S.sampleFlags ?? c, D = S.sampleCompositionTimeOffset ?? 0, P = new Uint8Array(d.slice(g, g + E));
|
|
1821
|
+
g += E;
|
|
1822
|
+
const N = y + D, $ = Math.round(N * 1e6 / e), A = W === 0 || (W & 65536) === 0;
|
|
1823
|
+
f.push({
|
|
1824
|
+
data: P,
|
|
1825
|
+
timestamp: $,
|
|
1826
|
+
keyframe: A
|
|
1827
|
+
}), y += z;
|
|
1828
|
+
}
|
|
1829
|
+
return f;
|
|
1830
|
+
}
|
|
1831
|
+
function O(t) {
|
|
1832
|
+
if (t = t.startsWith("0x") ? t.slice(2) : t, t.length % 2)
|
|
1833
|
+
throw new Error("invalid hex string length");
|
|
1834
|
+
const e = t.match(/.{2}/g);
|
|
1835
|
+
if (!e)
|
|
1836
|
+
throw new Error("invalid hex string format");
|
|
1837
|
+
return new Uint8Array(e.map((n) => parseInt(n, 16)));
|
|
1838
|
+
}
|
|
1839
|
+
const we = [65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824], $s = {
|
|
1840
|
+
// Init segment boxes
|
|
1841
|
+
ftyp: zs,
|
|
1842
|
+
mvhd: Us,
|
|
1843
|
+
tkhd: Ls,
|
|
1844
|
+
mdhd: Ts,
|
|
1845
|
+
hdlr: As,
|
|
1846
|
+
vmhd: Ns,
|
|
1847
|
+
smhd: Rs,
|
|
1848
|
+
"url ": Ps,
|
|
1849
|
+
dref: _s,
|
|
1850
|
+
stsd: Bs,
|
|
1851
|
+
stts: xs,
|
|
1852
|
+
trex: Os,
|
|
1853
|
+
// Data segment boxes
|
|
1854
|
+
mfhd: Es,
|
|
1855
|
+
tfhd: Cs,
|
|
1856
|
+
tfdt: Is,
|
|
1857
|
+
trun: Ds,
|
|
1858
|
+
mdat: ks
|
|
1859
|
+
// For boxes without library writers, we create them manually as Uint8Arrays
|
|
1860
|
+
};
|
|
1861
|
+
function ce(t) {
|
|
1862
|
+
return ws(t, { writers: $s });
|
|
1863
|
+
}
|
|
1864
|
+
function Te(t, e, n, s) {
|
|
1865
|
+
const i = 12 + s.length, r = new Uint8Array(i), o = new DataView(r.buffer);
|
|
1866
|
+
return o.setUint32(0, i, !1), r[4] = t.charCodeAt(0), r[5] = t.charCodeAt(1), r[6] = t.charCodeAt(2), r[7] = t.charCodeAt(3), o.setUint32(8, e << 24 | n, !1), r.set(s, 12), r;
|
|
1867
|
+
}
|
|
1868
|
+
function Et() {
|
|
1869
|
+
const t = new Uint8Array(4);
|
|
1870
|
+
return Te("stsc", 0, 0, t);
|
|
1871
|
+
}
|
|
1872
|
+
function Ut() {
|
|
1873
|
+
const t = new Uint8Array(8);
|
|
1874
|
+
return Te("stsz", 0, 0, t);
|
|
1875
|
+
}
|
|
1876
|
+
function Rt() {
|
|
1877
|
+
const t = new Uint8Array(4);
|
|
1878
|
+
return Te("stco", 0, 0, t);
|
|
1879
|
+
}
|
|
1880
|
+
function Fs(t, e, n) {
|
|
1881
|
+
const s = 8 + n.length, r = 8 + (78 + s), o = new Uint8Array(r), a = new DataView(o.buffer);
|
|
1882
|
+
let c = 0;
|
|
1883
|
+
return a.setUint32(c, r, !1), c += 4, o[c++] = 97, o[c++] = 118, o[c++] = 99, o[c++] = 49, c += 6, a.setUint16(c, 1, !1), c += 2, a.setUint16(c, 0, !1), c += 2, a.setUint16(c, 0, !1), c += 2, c += 12, a.setUint16(c, t, !1), c += 2, a.setUint16(c, e, !1), c += 2, a.setUint32(c, 4718592, !1), c += 4, a.setUint32(c, 4718592, !1), c += 4, a.setUint32(c, 0, !1), c += 4, a.setUint16(c, 1, !1), c += 2, c += 32, a.setUint16(c, 24, !1), c += 2, a.setUint16(c, 65535, !1), c += 2, a.setUint32(c, s, !1), c += 4, o[c++] = 97, o[c++] = 118, o[c++] = 99, o[c++] = 67, o.set(n, c), o;
|
|
1884
|
+
}
|
|
1885
|
+
function qe(t) {
|
|
1886
|
+
const { codedWidth: e, codedHeight: n, description: s, container: i } = t;
|
|
1887
|
+
if (!e || !n || !s)
|
|
1888
|
+
throw new Error("Missing required fields to create video init segment");
|
|
1889
|
+
const r = i.kind === "cmaf" ? i.timescale : 1e6, o = i.kind === "cmaf" ? i.trackId : 1, a = {
|
|
1890
|
+
type: "ftyp",
|
|
1891
|
+
majorBrand: "isom",
|
|
1892
|
+
minorVersion: 512,
|
|
1893
|
+
compatibleBrands: ["isom", "iso6", "mp41"]
|
|
1894
|
+
}, c = {
|
|
1895
|
+
type: "mvhd",
|
|
1896
|
+
version: 0,
|
|
1897
|
+
flags: 0,
|
|
1898
|
+
creationTime: 0,
|
|
1899
|
+
modificationTime: 0,
|
|
1900
|
+
timescale: r,
|
|
1901
|
+
duration: 0,
|
|
1902
|
+
// Unknown/fragmented
|
|
1903
|
+
rate: 65536,
|
|
1904
|
+
// 1.0 in 16.16 fixed point
|
|
1905
|
+
volume: 256,
|
|
1906
|
+
// 1.0 in 8.8 fixed point
|
|
1907
|
+
reserved1: 0,
|
|
1908
|
+
reserved2: [0, 0],
|
|
1909
|
+
matrix: we,
|
|
1910
|
+
preDefined: [0, 0, 0, 0, 0, 0],
|
|
1911
|
+
nextTrackId: o + 1
|
|
1912
|
+
}, u = {
|
|
1913
|
+
type: "tkhd",
|
|
1914
|
+
version: 0,
|
|
1915
|
+
flags: 3,
|
|
1916
|
+
// Track enabled + in movie
|
|
1917
|
+
creationTime: 0,
|
|
1918
|
+
modificationTime: 0,
|
|
1919
|
+
trackId: o,
|
|
1920
|
+
reserved1: 0,
|
|
1921
|
+
duration: 0,
|
|
1922
|
+
reserved2: [0, 0],
|
|
1923
|
+
layer: 0,
|
|
1924
|
+
alternateGroup: 0,
|
|
1925
|
+
volume: 0,
|
|
1926
|
+
// Video tracks have 0 volume
|
|
1927
|
+
reserved3: 0,
|
|
1928
|
+
matrix: we,
|
|
1929
|
+
width: e * 65536,
|
|
1930
|
+
// 16.16 fixed point (avoid << which produces signed int)
|
|
1931
|
+
height: n * 65536
|
|
1932
|
+
}, l = {
|
|
1933
|
+
type: "mdhd",
|
|
1934
|
+
version: 0,
|
|
1935
|
+
flags: 0,
|
|
1936
|
+
creationTime: 0,
|
|
1937
|
+
modificationTime: 0,
|
|
1938
|
+
timescale: r,
|
|
1939
|
+
duration: 0,
|
|
1940
|
+
language: "und",
|
|
1941
|
+
preDefined: 0
|
|
1942
|
+
}, d = {
|
|
1943
|
+
type: "hdlr",
|
|
1944
|
+
version: 0,
|
|
1945
|
+
flags: 0,
|
|
1946
|
+
preDefined: 0,
|
|
1947
|
+
handlerType: "vide",
|
|
1948
|
+
reserved: [0, 0, 0],
|
|
1949
|
+
name: "VideoHandler"
|
|
1950
|
+
}, f = {
|
|
1951
|
+
type: "vmhd",
|
|
1952
|
+
version: 0,
|
|
1953
|
+
flags: 1,
|
|
1954
|
+
// Required to be 1
|
|
1955
|
+
graphicsmode: 0,
|
|
1956
|
+
opcolor: [0, 0, 0]
|
|
1957
|
+
}, b = {
|
|
1958
|
+
type: "dinf",
|
|
1959
|
+
boxes: [{
|
|
1960
|
+
type: "dref",
|
|
1961
|
+
version: 0,
|
|
1962
|
+
flags: 0,
|
|
1963
|
+
entryCount: 1,
|
|
1964
|
+
entries: [{
|
|
1965
|
+
type: "url ",
|
|
1966
|
+
version: 0,
|
|
1967
|
+
flags: 1,
|
|
1968
|
+
// Self-contained flag
|
|
1969
|
+
location: ""
|
|
1970
|
+
}]
|
|
1971
|
+
}]
|
|
1972
|
+
}, E = {
|
|
1973
|
+
type: "stsd",
|
|
1974
|
+
version: 0,
|
|
1975
|
+
flags: 0,
|
|
1976
|
+
entryCount: 1,
|
|
1977
|
+
// biome-ignore lint/suspicious/noExplicitAny: Raw avc1 box since library doesn't handle avcC children
|
|
1978
|
+
entries: [Fs(e, n, O(s))]
|
|
1979
|
+
}, z = {
|
|
1980
|
+
type: "stts",
|
|
1981
|
+
version: 0,
|
|
1982
|
+
flags: 0,
|
|
1983
|
+
entryCount: 0,
|
|
1984
|
+
entries: []
|
|
1985
|
+
}, W = Et(), D = Ut(), P = Rt(), be = ce([a, {
|
|
1986
|
+
type: "moov",
|
|
1987
|
+
boxes: [c, {
|
|
1988
|
+
type: "trak",
|
|
1989
|
+
boxes: [u, {
|
|
1990
|
+
type: "mdia",
|
|
1991
|
+
boxes: [l, d, {
|
|
1992
|
+
type: "minf",
|
|
1993
|
+
boxes: [f, b, {
|
|
1994
|
+
type: "stbl",
|
|
1995
|
+
// biome-ignore lint/suspicious/noExplicitAny: Raw boxes for types without library writers
|
|
1996
|
+
boxes: [E, z, W, D, P]
|
|
1997
|
+
}]
|
|
1998
|
+
}]
|
|
1999
|
+
}]
|
|
2000
|
+
}, {
|
|
2001
|
+
type: "mvex",
|
|
2002
|
+
boxes: [{
|
|
2003
|
+
type: "trex",
|
|
2004
|
+
version: 0,
|
|
2005
|
+
flags: 0,
|
|
2006
|
+
trackId: o,
|
|
2007
|
+
defaultSampleDescriptionIndex: 1,
|
|
2008
|
+
defaultSampleDuration: 0,
|
|
2009
|
+
defaultSampleSize: 0,
|
|
2010
|
+
defaultSampleFlags: 0
|
|
2011
|
+
}]
|
|
2012
|
+
}]
|
|
2013
|
+
}]), de = be.reduce((L, F) => L + F.byteLength, 0), he = new Uint8Array(de);
|
|
2014
|
+
let ne = 0;
|
|
2015
|
+
for (const L of be)
|
|
2016
|
+
he.set(new Uint8Array(L.buffer, L.byteOffset, L.byteLength), ne), ne += L.byteLength;
|
|
2017
|
+
return he;
|
|
2018
|
+
}
|
|
2019
|
+
function He(t) {
|
|
2020
|
+
const { sampleRate: e, numberOfChannels: n, description: s, codec: i, container: r } = t, o = r.kind === "cmaf" ? r.timescale : 1e6, a = r.kind === "cmaf" ? r.trackId : 1, c = {
|
|
2021
|
+
type: "ftyp",
|
|
2022
|
+
majorBrand: "isom",
|
|
2023
|
+
minorVersion: 512,
|
|
2024
|
+
compatibleBrands: ["isom", "iso6", "mp41"]
|
|
2025
|
+
}, u = {
|
|
2026
|
+
type: "mvhd",
|
|
2027
|
+
version: 0,
|
|
2028
|
+
flags: 0,
|
|
2029
|
+
creationTime: 0,
|
|
2030
|
+
modificationTime: 0,
|
|
2031
|
+
timescale: o,
|
|
2032
|
+
duration: 0,
|
|
2033
|
+
rate: 65536,
|
|
2034
|
+
volume: 256,
|
|
2035
|
+
reserved1: 0,
|
|
2036
|
+
reserved2: [0, 0],
|
|
2037
|
+
matrix: we,
|
|
2038
|
+
preDefined: [0, 0, 0, 0, 0, 0],
|
|
2039
|
+
nextTrackId: a + 1
|
|
2040
|
+
}, l = {
|
|
2041
|
+
type: "tkhd",
|
|
2042
|
+
version: 0,
|
|
2043
|
+
flags: 3,
|
|
2044
|
+
creationTime: 0,
|
|
2045
|
+
modificationTime: 0,
|
|
2046
|
+
trackId: a,
|
|
2047
|
+
reserved1: 0,
|
|
2048
|
+
duration: 0,
|
|
2049
|
+
reserved2: [0, 0],
|
|
2050
|
+
layer: 0,
|
|
2051
|
+
alternateGroup: 0,
|
|
2052
|
+
volume: 256,
|
|
2053
|
+
// Audio tracks have volume (1.0 in 8.8 fixed point)
|
|
2054
|
+
reserved3: 0,
|
|
2055
|
+
matrix: we,
|
|
2056
|
+
width: 0,
|
|
2057
|
+
height: 0
|
|
2058
|
+
}, d = {
|
|
2059
|
+
type: "mdhd",
|
|
2060
|
+
version: 0,
|
|
2061
|
+
flags: 0,
|
|
2062
|
+
creationTime: 0,
|
|
2063
|
+
modificationTime: 0,
|
|
2064
|
+
timescale: o,
|
|
2065
|
+
duration: 0,
|
|
2066
|
+
language: "und",
|
|
2067
|
+
preDefined: 0
|
|
2068
|
+
}, f = {
|
|
2069
|
+
type: "hdlr",
|
|
2070
|
+
version: 0,
|
|
2071
|
+
flags: 0,
|
|
2072
|
+
preDefined: 0,
|
|
2073
|
+
handlerType: "soun",
|
|
2074
|
+
reserved: [0, 0, 0],
|
|
2075
|
+
name: "SoundHandler"
|
|
2076
|
+
}, g = {
|
|
2077
|
+
type: "smhd",
|
|
2078
|
+
version: 0,
|
|
2079
|
+
flags: 0,
|
|
2080
|
+
balance: 0,
|
|
2081
|
+
reserved: 0
|
|
2082
|
+
}, S = {
|
|
2083
|
+
type: "dinf",
|
|
2084
|
+
boxes: [{
|
|
2085
|
+
type: "dref",
|
|
2086
|
+
version: 0,
|
|
2087
|
+
flags: 0,
|
|
2088
|
+
entryCount: 1,
|
|
2089
|
+
entries: [{
|
|
2090
|
+
type: "url ",
|
|
2091
|
+
version: 0,
|
|
2092
|
+
flags: 1,
|
|
2093
|
+
location: ""
|
|
2094
|
+
}]
|
|
2095
|
+
}]
|
|
2096
|
+
}, z = {
|
|
2097
|
+
type: "stsd",
|
|
2098
|
+
version: 0,
|
|
2099
|
+
flags: 0,
|
|
2100
|
+
entryCount: 1,
|
|
2101
|
+
// biome-ignore lint/suspicious/noExplicitAny: Raw sample entry box
|
|
2102
|
+
entries: [js(i, e, n, s)]
|
|
2103
|
+
}, W = {
|
|
2104
|
+
type: "stts",
|
|
2105
|
+
version: 0,
|
|
2106
|
+
flags: 0,
|
|
2107
|
+
entryCount: 0,
|
|
2108
|
+
entries: []
|
|
2109
|
+
}, D = Et(), P = Ut(), N = Rt(), de = ce([c, {
|
|
2110
|
+
type: "moov",
|
|
2111
|
+
boxes: [u, {
|
|
2112
|
+
type: "trak",
|
|
2113
|
+
boxes: [l, {
|
|
2114
|
+
type: "mdia",
|
|
2115
|
+
boxes: [d, f, {
|
|
2116
|
+
type: "minf",
|
|
2117
|
+
boxes: [g, S, {
|
|
2118
|
+
type: "stbl",
|
|
2119
|
+
// biome-ignore lint/suspicious/noExplicitAny: Raw boxes for types without library writers
|
|
2120
|
+
boxes: [z, W, D, P, N]
|
|
2121
|
+
}]
|
|
2122
|
+
}]
|
|
2123
|
+
}]
|
|
2124
|
+
}, {
|
|
2125
|
+
type: "mvex",
|
|
2126
|
+
boxes: [{
|
|
2127
|
+
type: "trex",
|
|
2128
|
+
version: 0,
|
|
2129
|
+
flags: 0,
|
|
2130
|
+
trackId: a,
|
|
2131
|
+
defaultSampleDescriptionIndex: 1,
|
|
2132
|
+
defaultSampleDuration: 0,
|
|
2133
|
+
defaultSampleSize: 0,
|
|
2134
|
+
defaultSampleFlags: 0
|
|
2135
|
+
}]
|
|
2136
|
+
}]
|
|
2137
|
+
}]), he = de.reduce((F, Nt) => F + Nt.byteLength, 0), ne = new Uint8Array(he);
|
|
2138
|
+
let L = 0;
|
|
2139
|
+
for (const F of de)
|
|
2140
|
+
ne.set(new Uint8Array(F.buffer, F.byteOffset, F.byteLength), L), L += F.byteLength;
|
|
2141
|
+
return ne;
|
|
2142
|
+
}
|
|
2143
|
+
function js(t, e, n, s) {
|
|
2144
|
+
if (t.startsWith("mp4a"))
|
|
2145
|
+
return Zs(e, n, s);
|
|
2146
|
+
if (t === "opus")
|
|
2147
|
+
return Vs(e, n, s);
|
|
2148
|
+
throw new Error(`Unsupported audio codec: ${t}`);
|
|
2149
|
+
}
|
|
2150
|
+
function Zs(t, e, n) {
|
|
2151
|
+
const s = qs(t, e, n), r = 8 + (28 + s.length), o = new Uint8Array(r), a = new DataView(o.buffer);
|
|
2152
|
+
let c = 0;
|
|
2153
|
+
return a.setUint32(c, r, !1), c += 4, o[c++] = 109, o[c++] = 112, o[c++] = 52, o[c++] = 97, c += 6, a.setUint16(c, 1, !1), c += 2, c += 8, a.setUint16(c, e, !1), c += 2, a.setUint16(c, 16, !1), c += 2, a.setUint16(c, 0, !1), c += 2, a.setUint16(c, 0, !1), c += 2, a.setUint32(c, t * 65536, !1), c += 4, o.set(s, c), o;
|
|
2154
|
+
}
|
|
2155
|
+
function Vs(t, e, n) {
|
|
2156
|
+
const s = Hs(e, t, n), r = 8 + (28 + s.length), o = new Uint8Array(r), a = new DataView(o.buffer);
|
|
2157
|
+
let c = 0;
|
|
2158
|
+
return a.setUint32(c, r, !1), c += 4, o[c++] = 79, o[c++] = 112, o[c++] = 117, o[c++] = 115, c += 6, a.setUint16(c, 1, !1), c += 2, c += 8, a.setUint16(c, e, !1), c += 2, a.setUint16(c, 16, !1), c += 2, a.setUint16(c, 0, !1), c += 2, a.setUint16(c, 0, !1), c += 2, a.setUint32(c, t * 65536, !1), c += 4, o.set(s, c), o;
|
|
2159
|
+
}
|
|
2160
|
+
function Ws(t, e) {
|
|
2161
|
+
const s = {
|
|
2162
|
+
96e3: 0,
|
|
2163
|
+
88200: 1,
|
|
2164
|
+
64e3: 2,
|
|
2165
|
+
48e3: 3,
|
|
2166
|
+
44100: 4,
|
|
2167
|
+
32e3: 5,
|
|
2168
|
+
24e3: 6,
|
|
2169
|
+
22050: 7,
|
|
2170
|
+
16e3: 8,
|
|
2171
|
+
12e3: 9,
|
|
2172
|
+
11025: 10,
|
|
2173
|
+
8e3: 11,
|
|
2174
|
+
7350: 12
|
|
2175
|
+
}[t] ?? 4, r = 2 << 3 | s >> 1, o = (s & 1) << 7 | e << 3;
|
|
2176
|
+
return new Uint8Array([r, o]);
|
|
2177
|
+
}
|
|
2178
|
+
function qs(t, e, n) {
|
|
2179
|
+
const s = n ? O(n) : Ws(t, e), i = s.length, r = 15 + i, o = 5 + r + 3, a = 14 + o, c = new Uint8Array(a), u = new DataView(c.buffer);
|
|
2180
|
+
let l = 0;
|
|
2181
|
+
return u.setUint32(l, a, !1), l += 4, c[l++] = 101, c[l++] = 115, c[l++] = 100, c[l++] = 115, u.setUint32(l, 0, !1), l += 4, c[l++] = 3, c[l++] = o, u.setUint16(l, 0, !1), l += 2, c[l++] = 0, c[l++] = 4, c[l++] = r, c[l++] = 64, c[l++] = 21, c[l++] = 0, c[l++] = 0, c[l++] = 0, u.setUint32(l, 0, !1), l += 4, u.setUint32(l, 0, !1), l += 4, c[l++] = 5, c[l++] = i, c.set(s, l), l += i, c[l++] = 6, c[l++] = 1, c[l++] = 2, c;
|
|
2182
|
+
}
|
|
2183
|
+
function Hs(t, e, n) {
|
|
2184
|
+
if (n) {
|
|
2185
|
+
const a = O(n), c = 8 + a.length, u = new Uint8Array(c);
|
|
2186
|
+
return new DataView(u.buffer).setUint32(0, c, !1), u[4] = 100, u[5] = 79, u[6] = 112, u[7] = 115, u.set(a, 8), u;
|
|
2187
|
+
}
|
|
2188
|
+
const s = 19, i = new Uint8Array(s), r = new DataView(i.buffer);
|
|
2189
|
+
let o = 0;
|
|
2190
|
+
return r.setUint32(o, s, !1), o += 4, i[o++] = 100, i[o++] = 79, i[o++] = 112, i[o++] = 115, i[o++] = 0, i[o++] = t, r.setUint16(o, 312, !1), o += 2, r.setUint32(o, e, !1), o += 4, r.setInt16(o, 0, !1), o += 2, i[o++] = 0, i;
|
|
2191
|
+
}
|
|
2192
|
+
function Bt(t) {
|
|
2193
|
+
const { data: e, timestamp: n, duration: s, keyframe: i, sequence: r, trackId: o = 1 } = t, a = i ? 33554432 : 16842752, c = {
|
|
2194
|
+
type: "mfhd",
|
|
2195
|
+
version: 0,
|
|
2196
|
+
flags: 0,
|
|
2197
|
+
sequenceNumber: r
|
|
2198
|
+
}, u = {
|
|
2199
|
+
type: "tfhd",
|
|
2200
|
+
version: 0,
|
|
2201
|
+
flags: 131072,
|
|
2202
|
+
trackId: o
|
|
2203
|
+
}, l = {
|
|
2204
|
+
type: "tfdt",
|
|
2205
|
+
version: 1,
|
|
2206
|
+
// version 1 for 64-bit baseMediaDecodeTime
|
|
2207
|
+
flags: 0,
|
|
2208
|
+
baseMediaDecodeTime: n
|
|
2209
|
+
}, d = {
|
|
2210
|
+
type: "trun",
|
|
2211
|
+
version: 0,
|
|
2212
|
+
flags: 1793,
|
|
2213
|
+
sampleCount: 1,
|
|
2214
|
+
dataOffset: 0,
|
|
2215
|
+
// Will be calculated after we know moof size
|
|
2216
|
+
samples: [
|
|
2217
|
+
{
|
|
2218
|
+
sampleDuration: s,
|
|
2219
|
+
sampleSize: e.byteLength,
|
|
2220
|
+
sampleFlags: a
|
|
2221
|
+
}
|
|
2222
|
+
]
|
|
2223
|
+
}, g = {
|
|
2224
|
+
type: "moof",
|
|
2225
|
+
boxes: [c, {
|
|
2226
|
+
type: "traf",
|
|
2227
|
+
boxes: [u, l, d]
|
|
2228
|
+
}]
|
|
2229
|
+
}, y = ce([g]);
|
|
2230
|
+
let b = 0;
|
|
2231
|
+
for (const A of y)
|
|
2232
|
+
b += A.byteLength;
|
|
2233
|
+
d.dataOffset = b + 8;
|
|
2234
|
+
const S = ce([g]);
|
|
2235
|
+
b = 0;
|
|
2236
|
+
for (const A of S)
|
|
2237
|
+
b += A.byteLength;
|
|
2238
|
+
const E = new ArrayBuffer(e.byteLength), z = new Uint8Array(E);
|
|
2239
|
+
z.set(e);
|
|
2240
|
+
const D = ce([{
|
|
2241
|
+
type: "mdat",
|
|
2242
|
+
data: z
|
|
2243
|
+
}]);
|
|
2244
|
+
let P = 0;
|
|
2245
|
+
for (const A of D)
|
|
2246
|
+
P += A.byteLength;
|
|
2247
|
+
const N = new Uint8Array(b + P);
|
|
2248
|
+
let $ = 0;
|
|
2249
|
+
for (const A of S)
|
|
2250
|
+
N.set(new Uint8Array(A.buffer, A.byteOffset, A.byteLength), $), $ += A.byteLength;
|
|
2251
|
+
for (const A of D)
|
|
2252
|
+
N.set(new Uint8Array(A.buffer, A.byteOffset, A.byteLength), $), $ += A.byteLength;
|
|
2253
|
+
return N;
|
|
2254
|
+
}
|
|
2255
|
+
class te {
|
|
2256
|
+
#e;
|
|
2257
|
+
#t;
|
|
2258
|
+
#n = [];
|
|
2259
|
+
#s;
|
|
2260
|
+
// the active group sequence number
|
|
2261
|
+
// Wake up the consumer when a new frame is available.
|
|
2262
|
+
#i;
|
|
2263
|
+
#r = new h([]);
|
|
2264
|
+
buffered = this.#r;
|
|
2265
|
+
#o = new T();
|
|
2266
|
+
constructor(e, n) {
|
|
2267
|
+
this.#e = e, this.#t = h.from(n?.latency ?? M.Time.Milli.zero), this.#o.spawn(this.#a.bind(this)), this.#o.cleanup(() => {
|
|
2268
|
+
this.#e.close();
|
|
2269
|
+
for (const s of this.#n)
|
|
2270
|
+
s.consumer.close();
|
|
2271
|
+
this.#n.length = 0;
|
|
2272
|
+
});
|
|
2273
|
+
}
|
|
2274
|
+
async #a() {
|
|
2275
|
+
for (; ; ) {
|
|
2276
|
+
const e = await this.#e.nextGroup();
|
|
2277
|
+
if (!e) break;
|
|
2278
|
+
if (this.#s === void 0 && (this.#s = e.sequence), e.sequence < this.#s) {
|
|
2279
|
+
console.warn(`skipping old group: ${e.sequence} < ${this.#s}`), e.close();
|
|
2280
|
+
continue;
|
|
2281
|
+
}
|
|
2282
|
+
const n = {
|
|
2283
|
+
consumer: e,
|
|
2284
|
+
frames: []
|
|
2285
|
+
};
|
|
2286
|
+
this.#n.push(n), this.#n.sort((s, i) => s.consumer.sequence - i.consumer.sequence), this.#o.spawn(this.#c.bind(this, n));
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
async #c(e) {
|
|
2290
|
+
try {
|
|
2291
|
+
let n = !0;
|
|
2292
|
+
for (; ; ) {
|
|
2293
|
+
const s = await e.consumer.readFrame();
|
|
2294
|
+
if (!s) break;
|
|
2295
|
+
const { data: i, timestamp: r } = te.#d(s), o = {
|
|
2296
|
+
data: i,
|
|
2297
|
+
timestamp: r,
|
|
2298
|
+
keyframe: n
|
|
2299
|
+
};
|
|
2300
|
+
n = !1, e.frames.push(o), (e.latest === void 0 || r > e.latest) && (e.latest = r), this.#l(), e.consumer.sequence === this.#s ? (this.#i?.(), this.#i = void 0) : this.#u();
|
|
2301
|
+
}
|
|
2302
|
+
} catch {
|
|
2303
|
+
} finally {
|
|
2304
|
+
e.done = !0, e.consumer.sequence === this.#s && (this.#s += 1), this.#l(), this.#i?.(), this.#i = void 0, e.consumer.close();
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
#u() {
|
|
2308
|
+
if (this.#s === void 0) return;
|
|
2309
|
+
let e = !1;
|
|
2310
|
+
for (; this.#n.length >= 2; ) {
|
|
2311
|
+
const n = M.Time.Micro.fromMilli(this.#t.peek());
|
|
2312
|
+
let s, i;
|
|
2313
|
+
for (const a of this.#n) {
|
|
2314
|
+
if (a.latest === void 0) continue;
|
|
2315
|
+
const c = a.frames.at(0)?.timestamp ?? a.latest;
|
|
2316
|
+
(s === void 0 || c < s) && (s = c), (i === void 0 || a.latest > i) && (i = a.latest);
|
|
2317
|
+
}
|
|
2318
|
+
if (s === void 0 || i === void 0 || i - s <= n) break;
|
|
2319
|
+
const o = this.#n.shift();
|
|
2320
|
+
if (!o) break;
|
|
2321
|
+
this.#s = this.#n[0]?.consumer.sequence, console.warn(`skipping slow group: ${o.consumer.sequence} -> ${this.#s}`), o.consumer.close(), o.frames.length = 0, e = !0;
|
|
2322
|
+
}
|
|
2323
|
+
e && (this.#l(), this.#i?.(), this.#i = void 0);
|
|
2324
|
+
}
|
|
2325
|
+
// Returns the next frame in order, along with the group number.
|
|
2326
|
+
// If frame is undefined, the group is done.
|
|
2327
|
+
async next() {
|
|
2328
|
+
for (; ; ) {
|
|
2329
|
+
if (this.#n.length > 0 && this.#s !== void 0 && this.#n[0].consumer.sequence <= this.#s) {
|
|
2330
|
+
const n = this.#n[0].frames.shift();
|
|
2331
|
+
if (n)
|
|
2332
|
+
return this.#l(), { frame: n, group: this.#n[0].consumer.sequence };
|
|
2333
|
+
if (this.#s > this.#n[0].consumer.sequence || this.#n[0].done) {
|
|
2334
|
+
this.#n[0].consumer.sequence === this.#s && (this.#s += 1);
|
|
2335
|
+
const s = this.#n.shift();
|
|
2336
|
+
if (s)
|
|
2337
|
+
return this.#l(), { frame: void 0, group: s.consumer.sequence };
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
if (this.#i)
|
|
2341
|
+
throw new Error("multiple calls to decode not supported");
|
|
2342
|
+
const e = new Promise((n) => {
|
|
2343
|
+
this.#i = n;
|
|
2344
|
+
}).then(() => !0);
|
|
2345
|
+
if (!await Promise.race([e, this.#o.closed])) {
|
|
2346
|
+
this.#i = void 0;
|
|
2347
|
+
return;
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
// NOTE: A keyframe is always the first frame in a group, so it's not encoded on the wire.
|
|
2352
|
+
static #d(e) {
|
|
2353
|
+
const [n, s] = M.Varint.decode(e);
|
|
2354
|
+
return { timestamp: n, data: s };
|
|
2355
|
+
}
|
|
2356
|
+
#l() {
|
|
2357
|
+
const e = [];
|
|
2358
|
+
let n;
|
|
2359
|
+
for (const s of this.#n) {
|
|
2360
|
+
const i = s.frames.at(0);
|
|
2361
|
+
if (!i || s.latest === void 0) continue;
|
|
2362
|
+
const r = M.Time.Milli.fromMicro(i.timestamp), o = M.Time.Milli.fromMicro(s.latest), a = e.at(-1), c = n?.done && n.consumer.sequence + 1 === s.consumer.sequence;
|
|
2363
|
+
a && (a.end >= r || c) ? a.end = M.Time.Milli.max(a.end, o) : e.push({ start: r, end: o }), n = s;
|
|
2364
|
+
}
|
|
2365
|
+
this.#r.set(e);
|
|
2366
|
+
}
|
|
2367
|
+
close() {
|
|
2368
|
+
this.#o.close();
|
|
2369
|
+
for (const e of this.#n)
|
|
2370
|
+
e.consumer.close(), e.frames.length = 0;
|
|
2371
|
+
this.#n.length = 0;
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
let Se;
|
|
2375
|
+
async function Ge() {
|
|
2376
|
+
return globalThis.AudioEncoder && globalThis.AudioDecoder ? !0 : (Se || (console.warn("using Opus polyfill; performance may be degraded"), Se = Promise.all([
|
|
2377
|
+
import("./libav-opus-af-BlMWboA7.js"),
|
|
2378
|
+
import("./main-DGBFe0O7.js")
|
|
2379
|
+
]).then(async ([t, e]) => (await e.load({
|
|
2380
|
+
LibAV: t,
|
|
2381
|
+
polyfill: !0
|
|
2382
|
+
}), !0))), await Se);
|
|
2383
|
+
}
|
|
2384
|
+
const j = 0, C = 1, se = 2, G = 3, Gs = 4;
|
|
2385
|
+
function xt(t, e, n) {
|
|
2386
|
+
if (t <= 0) throw new Error("invalid channels");
|
|
2387
|
+
if (e <= 0) throw new Error("invalid capacity");
|
|
2388
|
+
if (n <= 0) throw new Error("invalid sample rate");
|
|
2389
|
+
const s = new SharedArrayBuffer(t * e * Float32Array.BYTES_PER_ELEMENT), i = new SharedArrayBuffer(Gs * Int32Array.BYTES_PER_ELEMENT), r = new Int32Array(i);
|
|
2390
|
+
return Atomics.store(r, G, 1), { channels: t, capacity: e, rate: n, samples: s, control: i };
|
|
2391
|
+
}
|
|
2392
|
+
function Xs(t, e) {
|
|
2393
|
+
return (t - e | 0) > 0 ? t : e;
|
|
2394
|
+
}
|
|
2395
|
+
function ie(t, e) {
|
|
2396
|
+
return (t % e + e) % e;
|
|
2397
|
+
}
|
|
2398
|
+
function Me(t, e, n) {
|
|
2399
|
+
for (; ; ) {
|
|
2400
|
+
const s = Atomics.load(t, e);
|
|
2401
|
+
if ((n - s | 0) <= 0) return s;
|
|
2402
|
+
if (Atomics.compareExchange(t, e, s, n) === s) return n;
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
class Ee {
|
|
2406
|
+
channels;
|
|
2407
|
+
capacity;
|
|
2408
|
+
rate;
|
|
2409
|
+
init;
|
|
2410
|
+
#e;
|
|
2411
|
+
#t;
|
|
2412
|
+
constructor(e) {
|
|
2413
|
+
this.channels = e.channels, this.capacity = e.capacity, this.rate = e.rate, this.init = e, this.#e = new Int32Array(e.control), this.#t = [];
|
|
2414
|
+
for (let n = 0; n < this.channels; n++)
|
|
2415
|
+
this.#t.push(
|
|
2416
|
+
new Float32Array(e.samples, n * this.capacity * Float32Array.BYTES_PER_ELEMENT, this.capacity)
|
|
2417
|
+
);
|
|
2418
|
+
}
|
|
2419
|
+
/**
|
|
2420
|
+
* Insert audio samples at the given timestamp.
|
|
2421
|
+
* Main thread only. Handles out-of-order writes, gap filling, and overflow.
|
|
2422
|
+
*/
|
|
2423
|
+
insert(e, n) {
|
|
2424
|
+
if (n.length !== this.channels) throw new Error("wrong number of channels");
|
|
2425
|
+
let s = Math.round(m.Second.fromMicro(e) * this.rate);
|
|
2426
|
+
const i = n[0].length;
|
|
2427
|
+
let r = 0;
|
|
2428
|
+
const o = s + i | 0, a = Atomics.load(this.#e, C), c = a - s | 0;
|
|
2429
|
+
if (c > 0) {
|
|
2430
|
+
if (c >= i)
|
|
2431
|
+
return;
|
|
2432
|
+
r = c, s = s + c | 0;
|
|
2433
|
+
}
|
|
2434
|
+
const u = i - r;
|
|
2435
|
+
(o - a | 0) > this.capacity && Me(this.#e, C, o - this.capacity | 0);
|
|
2436
|
+
const l = Atomics.load(this.#e, j), d = s - l | 0;
|
|
2437
|
+
if (d > 0) {
|
|
2438
|
+
const b = Math.min(d, this.capacity);
|
|
2439
|
+
for (let S = 0; S < this.channels; S++) {
|
|
2440
|
+
const E = this.#t[S];
|
|
2441
|
+
for (let z = 0; z < b; z++)
|
|
2442
|
+
E[ie(l + z | 0, this.capacity)] = 0;
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
for (let b = 0; b < this.channels; b++) {
|
|
2446
|
+
const S = n[b], E = this.#t[b];
|
|
2447
|
+
for (let z = 0; z < u; z++)
|
|
2448
|
+
E[ie(s + z | 0, this.capacity)] = S[r + z];
|
|
2449
|
+
}
|
|
2450
|
+
Atomics.store(this.#e, j, Xs(Atomics.load(this.#e, j), o));
|
|
2451
|
+
const f = Atomics.load(this.#e, C), g = Atomics.load(this.#e, j), y = Atomics.load(this.#e, se);
|
|
2452
|
+
(g - f | 0) >= y && y > 0 && Atomics.store(this.#e, G, 0);
|
|
2453
|
+
}
|
|
2454
|
+
/**
|
|
2455
|
+
* Read audio samples into the output buffers.
|
|
2456
|
+
* AudioWorklet only. Returns the number of samples read.
|
|
2457
|
+
*/
|
|
2458
|
+
read(e) {
|
|
2459
|
+
if (Atomics.load(this.#e, G) === 1) return 0;
|
|
2460
|
+
let n = Atomics.load(this.#e, C);
|
|
2461
|
+
const s = Atomics.load(this.#e, j), i = Atomics.load(this.#e, se), r = s - n | 0;
|
|
2462
|
+
if (i > 0 && r > i) {
|
|
2463
|
+
const c = s - i | 0;
|
|
2464
|
+
n = Me(this.#e, C, c);
|
|
2465
|
+
}
|
|
2466
|
+
const o = s - n | 0, a = Math.min(o, e[0].length);
|
|
2467
|
+
if (a <= 0) return 0;
|
|
2468
|
+
for (let c = 0; c < this.channels; c++) {
|
|
2469
|
+
const u = this.#t[c], l = e[c];
|
|
2470
|
+
for (let d = 0; d < a; d++)
|
|
2471
|
+
l[d] = u[ie(n + d | 0, this.capacity)];
|
|
2472
|
+
}
|
|
2473
|
+
return Me(this.#e, C, n + a | 0), a;
|
|
2474
|
+
}
|
|
2475
|
+
/** Update the target latency in samples. */
|
|
2476
|
+
setLatency(e) {
|
|
2477
|
+
Atomics.store(this.#e, se, e);
|
|
2478
|
+
}
|
|
2479
|
+
/**
|
|
2480
|
+
* Allocate a new ring with `newCapacity` samples and copy the unread window
|
|
2481
|
+
* [READ, WRITE) plus control state into it. Used when growing capacity so
|
|
2482
|
+
* we don't drop buffered audio. If `newCapacity` is smaller than the unread
|
|
2483
|
+
* span, the oldest samples are truncated.
|
|
2484
|
+
*
|
|
2485
|
+
* Main thread only. `resize()` reads from the source `SharedRingBuffer` and
|
|
2486
|
+
* writes into a freshly allocated buffer from `allocSharedRingBuffer`, so it
|
|
2487
|
+
* relies on the same invariant as `insert()`: no concurrent main-thread
|
|
2488
|
+
* writers. The AudioWorklet reader is tolerated via the CAS discipline used
|
|
2489
|
+
* by READ/WRITE elsewhere.
|
|
2490
|
+
*/
|
|
2491
|
+
resize(e) {
|
|
2492
|
+
const n = xt(this.channels, e, this.rate), s = new Ee(n), i = Atomics.load(this.#e, C), r = Atomics.load(this.#e, j), o = Atomics.load(this.#e, se), a = Atomics.load(this.#e, G), c = r - i | 0, u = Math.max(0, Math.min(c, s.capacity)), l = r - u | 0;
|
|
2493
|
+
for (let d = 0; d < this.channels; d++) {
|
|
2494
|
+
const f = this.#t[d], g = s.#t[d];
|
|
2495
|
+
for (let y = 0; y < u; y++) {
|
|
2496
|
+
const b = l + y | 0;
|
|
2497
|
+
g[ie(b, s.capacity)] = f[ie(b, this.capacity)];
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
return Atomics.store(s.#e, C, l), Atomics.store(s.#e, j, r), Atomics.store(s.#e, se, o), Atomics.store(s.#e, G, a), s;
|
|
2501
|
+
}
|
|
2502
|
+
/** Current playback timestamp derived from READ position. */
|
|
2503
|
+
get timestamp() {
|
|
2504
|
+
const e = Atomics.load(this.#e, C);
|
|
2505
|
+
return m.Micro.fromSecond(e / this.rate);
|
|
2506
|
+
}
|
|
2507
|
+
/** Whether the buffer is stalled (waiting to fill). */
|
|
2508
|
+
get stalled() {
|
|
2509
|
+
return Atomics.load(this.#e, G) === 1;
|
|
2510
|
+
}
|
|
2511
|
+
/**
|
|
2512
|
+
* Number of buffered samples (WRITE - READ).
|
|
2513
|
+
*
|
|
2514
|
+
* Non-atomic: WRITE and READ are loaded separately, so a concurrent
|
|
2515
|
+
* writer/reader can make the two loads inconsistent. Intended for
|
|
2516
|
+
* tests and diagnostics, not control-flow decisions.
|
|
2517
|
+
*/
|
|
2518
|
+
get length() {
|
|
2519
|
+
return Atomics.load(this.#e, j) - Atomics.load(this.#e, C) | 0;
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
function Ys() {
|
|
2523
|
+
return !(typeof SharedArrayBuffer > "u" || typeof crossOriginIsolated < "u" && !crossOriginIsolated);
|
|
2524
|
+
}
|
|
2525
|
+
function Ks(t, e, n, s) {
|
|
2526
|
+
return Ys() ? (console.log("[audio] using SharedArrayBuffer audio buffer"), new Js(t, e, n, s)) : (console.log("[audio] using postMessage audio buffer (SharedArrayBuffer unavailable)"), new Qs(t, e, n, s));
|
|
2527
|
+
}
|
|
2528
|
+
class Js {
|
|
2529
|
+
rate;
|
|
2530
|
+
channels;
|
|
2531
|
+
#e;
|
|
2532
|
+
#t;
|
|
2533
|
+
#n = new h(0);
|
|
2534
|
+
timestamp = this.#n;
|
|
2535
|
+
#s = new h(!0);
|
|
2536
|
+
stalled = this.#s;
|
|
2537
|
+
#i = new T();
|
|
2538
|
+
constructor(e, n, s, i) {
|
|
2539
|
+
this.#e = e, this.channels = n, this.rate = s;
|
|
2540
|
+
const r = Math.max(s, i * 2), o = xt(n, r, s);
|
|
2541
|
+
this.#t = new Ee(o), this.#t.setLatency(i);
|
|
2542
|
+
const a = { type: "init-shared", ...o };
|
|
2543
|
+
e.port.postMessage(a), this.#i.interval(() => {
|
|
2544
|
+
this.#n.set(this.#t.timestamp), this.#s.set(this.#t.stalled);
|
|
2545
|
+
}, 50);
|
|
2546
|
+
}
|
|
2547
|
+
insert(e, n) {
|
|
2548
|
+
this.#t.insert(e, n);
|
|
2549
|
+
}
|
|
2550
|
+
setLatency(e) {
|
|
2551
|
+
if (this.#t.capacity < e * 1.5) {
|
|
2552
|
+
const n = Math.max(this.rate, e * 2);
|
|
2553
|
+
this.#t = this.#t.resize(n), this.#t.setLatency(e);
|
|
2554
|
+
const s = { type: "init-shared", ...this.#t.init };
|
|
2555
|
+
this.#e.port.postMessage(s);
|
|
2556
|
+
} else
|
|
2557
|
+
this.#t.setLatency(e);
|
|
2558
|
+
}
|
|
2559
|
+
close() {
|
|
2560
|
+
this.#i.close();
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
class Qs {
|
|
2564
|
+
rate;
|
|
2565
|
+
channels;
|
|
2566
|
+
#e;
|
|
2567
|
+
#t = new h(0);
|
|
2568
|
+
timestamp = this.#t;
|
|
2569
|
+
#n = new h(!0);
|
|
2570
|
+
stalled = this.#n;
|
|
2571
|
+
#s = new T();
|
|
2572
|
+
constructor(e, n, s, i) {
|
|
2573
|
+
this.#e = e, this.channels = n, this.rate = s;
|
|
2574
|
+
const r = m.Milli.fromSecond(i / s), o = { type: "init-post", channels: n, rate: s, latency: r };
|
|
2575
|
+
e.port.postMessage(o), this.#s.event(e.port, "message", (a) => {
|
|
2576
|
+
const c = a.data;
|
|
2577
|
+
c?.type === "state" && (this.#t.set(c.timestamp), this.#n.set(c.stalled));
|
|
2578
|
+
}), e.port.start();
|
|
2579
|
+
}
|
|
2580
|
+
insert(e, n) {
|
|
2581
|
+
const s = { type: "data", data: n, timestamp: e };
|
|
2582
|
+
this.#e.port.postMessage(
|
|
2583
|
+
s,
|
|
2584
|
+
n.map((i) => i.buffer)
|
|
2585
|
+
);
|
|
2586
|
+
}
|
|
2587
|
+
setLatency(e) {
|
|
2588
|
+
const s = { type: "latency", latency: m.Milli.fromSecond(e / this.rate) };
|
|
2589
|
+
this.#e.port.postMessage(s);
|
|
2590
|
+
}
|
|
2591
|
+
close() {
|
|
2592
|
+
this.#s.close();
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
const ei = `var __defProp = Object.defineProperty;
|
|
2596
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2597
|
+
var __esm = (fn, res) => function __init() {
|
|
2598
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
2599
|
+
};
|
|
2600
|
+
var __export = (target, all) => {
|
|
2601
|
+
for (var name in all)
|
|
2602
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
2603
|
+
};
|
|
2604
|
+
|
|
2605
|
+
// ../lite/src/path.ts
|
|
2606
|
+
var init_path = __esm({
|
|
2607
|
+
"../lite/src/path.ts"() {
|
|
2608
|
+
"use strict";
|
|
2609
|
+
}
|
|
2610
|
+
});
|
|
2611
|
+
|
|
2612
|
+
// ../lite/src/varint.ts
|
|
2613
|
+
var MAX_U6, MAX_U14, MAX_U30, MAX_U53, MAX_U64, MAX_U62;
|
|
2614
|
+
var init_varint = __esm({
|
|
2615
|
+
"../lite/src/varint.ts"() {
|
|
2616
|
+
"use strict";
|
|
2617
|
+
MAX_U6 = 2 ** 6 - 1;
|
|
2618
|
+
MAX_U14 = 2 ** 14 - 1;
|
|
2619
|
+
MAX_U30 = 2 ** 30 - 1;
|
|
2620
|
+
MAX_U53 = Number.MAX_SAFE_INTEGER;
|
|
2621
|
+
MAX_U64 = (1n << 64n) - 1n;
|
|
2622
|
+
MAX_U62 = 2n ** 62n - 1n;
|
|
2623
|
+
}
|
|
2624
|
+
});
|
|
2625
|
+
|
|
2626
|
+
// ../lite/src/index.ts
|
|
2627
|
+
init_path();
|
|
2628
|
+
|
|
2629
|
+
// ../lite/src/time.ts
|
|
2630
|
+
var time_exports = {};
|
|
2631
|
+
__export(time_exports, {
|
|
2632
|
+
Micro: () => Micro,
|
|
2633
|
+
Milli: () => Milli,
|
|
2634
|
+
Nano: () => Nano,
|
|
2635
|
+
Second: () => Second
|
|
2636
|
+
});
|
|
2637
|
+
var Nano = {
|
|
2638
|
+
zero: 0,
|
|
2639
|
+
fromMicro: (us) => us * 1e3,
|
|
2640
|
+
fromMilli: (ms) => ms * 1e6,
|
|
2641
|
+
fromSecond: (s) => s * 1e9,
|
|
2642
|
+
toMicro: (ns) => ns / 1e3,
|
|
2643
|
+
toMilli: (ns) => ns / 1e6,
|
|
2644
|
+
toSecond: (ns) => ns / 1e9,
|
|
2645
|
+
now: () => performance.now() * 1e6,
|
|
2646
|
+
add: (a, b) => a + b,
|
|
2647
|
+
sub: (a, b) => a - b,
|
|
2648
|
+
mul: (a, b) => a * b,
|
|
2649
|
+
div: (a, b) => a / b,
|
|
2650
|
+
max: (a, b) => Math.max(a, b),
|
|
2651
|
+
min: (a, b) => Math.min(a, b)
|
|
2652
|
+
};
|
|
2653
|
+
var Micro = {
|
|
2654
|
+
zero: 0,
|
|
2655
|
+
fromNano: (ns) => ns / 1e3,
|
|
2656
|
+
fromMilli: (ms) => ms * 1e3,
|
|
2657
|
+
fromSecond: (s) => s * 1e6,
|
|
2658
|
+
toNano: (us) => us * 1e3,
|
|
2659
|
+
toMilli: (us) => us / 1e3,
|
|
2660
|
+
toSecond: (us) => us / 1e6,
|
|
2661
|
+
now: () => performance.now() * 1e3,
|
|
2662
|
+
add: (a, b) => a + b,
|
|
2663
|
+
sub: (a, b) => a - b,
|
|
2664
|
+
mul: (a, b) => a * b,
|
|
2665
|
+
div: (a, b) => a / b,
|
|
2666
|
+
max: (a, b) => Math.max(a, b),
|
|
2667
|
+
min: (a, b) => Math.min(a, b)
|
|
2668
|
+
};
|
|
2669
|
+
var Milli = {
|
|
2670
|
+
zero: 0,
|
|
2671
|
+
fromNano: (ns) => ns / 1e6,
|
|
2672
|
+
fromMicro: (us) => us / 1e3,
|
|
2673
|
+
fromSecond: (s) => s * 1e3,
|
|
2674
|
+
toNano: (ms) => ms * 1e6,
|
|
2675
|
+
toMicro: (ms) => ms * 1e3,
|
|
2676
|
+
toSecond: (ms) => ms / 1e3,
|
|
2677
|
+
now: () => performance.now(),
|
|
2678
|
+
add: (a, b) => a + b,
|
|
2679
|
+
sub: (a, b) => a - b,
|
|
2680
|
+
mul: (a, b) => a * b,
|
|
2681
|
+
div: (a, b) => a / b,
|
|
2682
|
+
max: (a, b) => Math.max(a, b),
|
|
2683
|
+
min: (a, b) => Math.min(a, b)
|
|
2684
|
+
};
|
|
2685
|
+
var Second = {
|
|
2686
|
+
zero: 0,
|
|
2687
|
+
fromNano: (ns) => ns / 1e9,
|
|
2688
|
+
fromMicro: (us) => us / 1e6,
|
|
2689
|
+
fromMilli: (ms) => ms / 1e3,
|
|
2690
|
+
toNano: (s) => s * 1e9,
|
|
2691
|
+
toMicro: (s) => s * 1e6,
|
|
2692
|
+
toMilli: (s) => s * 1e3,
|
|
2693
|
+
now: () => performance.now() / 1e3,
|
|
2694
|
+
add: (a, b) => a + b,
|
|
2695
|
+
sub: (a, b) => a - b,
|
|
2696
|
+
mul: (a, b) => a * b,
|
|
2697
|
+
div: (a, b) => a / b,
|
|
2698
|
+
max: (a, b) => Math.max(a, b),
|
|
2699
|
+
min: (a, b) => Math.min(a, b)
|
|
2700
|
+
};
|
|
2701
|
+
|
|
2702
|
+
// ../lite/src/index.ts
|
|
2703
|
+
init_varint();
|
|
2704
|
+
|
|
2705
|
+
// src/audio/ring-buffer.ts
|
|
2706
|
+
var AudioRingBuffer = class {
|
|
2707
|
+
#buffer;
|
|
2708
|
+
#writeIndex = 0;
|
|
2709
|
+
#readIndex = 0;
|
|
2710
|
+
rate;
|
|
2711
|
+
channels;
|
|
2712
|
+
#stalled = true;
|
|
2713
|
+
constructor(props) {
|
|
2714
|
+
if (props.channels <= 0) throw new Error("invalid channels");
|
|
2715
|
+
if (props.rate <= 0) throw new Error("invalid sample rate");
|
|
2716
|
+
if (props.latency <= 0) throw new Error("invalid latency");
|
|
2717
|
+
const samples = Math.ceil(props.rate * time_exports.Second.fromMilli(props.latency));
|
|
2718
|
+
if (samples === 0) throw new Error("empty buffer");
|
|
2719
|
+
this.rate = props.rate;
|
|
2720
|
+
this.channels = props.channels;
|
|
2721
|
+
this.#buffer = [];
|
|
2722
|
+
for (let i = 0; i < this.channels; i++) {
|
|
2723
|
+
this.#buffer[i] = new Float32Array(samples);
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
get stalled() {
|
|
2727
|
+
return this.#stalled;
|
|
2728
|
+
}
|
|
2729
|
+
get timestamp() {
|
|
2730
|
+
return time_exports.Micro.fromSecond(this.#readIndex / this.rate);
|
|
2731
|
+
}
|
|
2732
|
+
get length() {
|
|
2733
|
+
return this.#writeIndex - this.#readIndex;
|
|
2734
|
+
}
|
|
2735
|
+
get capacity() {
|
|
2736
|
+
return this.#buffer[0]?.length;
|
|
2737
|
+
}
|
|
2738
|
+
resize(latency) {
|
|
2739
|
+
const newCapacity = Math.ceil(this.rate * time_exports.Second.fromMilli(latency));
|
|
2740
|
+
if (newCapacity === this.capacity) return;
|
|
2741
|
+
if (newCapacity === 0) throw new Error("empty buffer");
|
|
2742
|
+
const newBuffer = [];
|
|
2743
|
+
for (let i = 0; i < this.channels; i++) {
|
|
2744
|
+
newBuffer[i] = new Float32Array(newCapacity);
|
|
2745
|
+
}
|
|
2746
|
+
const samplesToKeep = Math.min(this.length, newCapacity);
|
|
2747
|
+
if (samplesToKeep > 0) {
|
|
2748
|
+
const copyStart = this.#writeIndex - samplesToKeep;
|
|
2749
|
+
for (let channel = 0; channel < this.channels; channel++) {
|
|
2750
|
+
const src = this.#buffer[channel];
|
|
2751
|
+
const dst = newBuffer[channel];
|
|
2752
|
+
for (let i = 0; i < samplesToKeep; i++) {
|
|
2753
|
+
const srcPos = (copyStart + i) % src.length;
|
|
2754
|
+
const dstPos = (copyStart + i) % dst.length;
|
|
2755
|
+
dst[dstPos] = src[srcPos];
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
this.#buffer = newBuffer;
|
|
2760
|
+
this.#readIndex = this.#writeIndex - samplesToKeep;
|
|
2761
|
+
if (samplesToKeep === 0) this.#stalled = true;
|
|
2762
|
+
}
|
|
2763
|
+
write(timestamp, data) {
|
|
2764
|
+
if (data.length !== this.channels) throw new Error("wrong number of channels");
|
|
2765
|
+
let start = Math.round(time_exports.Second.fromMicro(timestamp) * this.rate);
|
|
2766
|
+
let samples = data[0].length;
|
|
2767
|
+
let offset = this.#readIndex - start;
|
|
2768
|
+
if (offset > samples) {
|
|
2769
|
+
return;
|
|
2770
|
+
} else if (offset > 0) {
|
|
2771
|
+
samples -= offset;
|
|
2772
|
+
start += offset;
|
|
2773
|
+
} else {
|
|
2774
|
+
offset = 0;
|
|
2775
|
+
}
|
|
2776
|
+
const end = start + samples;
|
|
2777
|
+
const overflow = end - this.#readIndex - this.#buffer[0].length;
|
|
2778
|
+
if (overflow >= 0) {
|
|
2779
|
+
this.#stalled = false;
|
|
2780
|
+
this.#readIndex += overflow;
|
|
2781
|
+
}
|
|
2782
|
+
if (start > this.#writeIndex) {
|
|
2783
|
+
const gapSize = Math.min(start - this.#writeIndex, this.#buffer[0].length);
|
|
2784
|
+
if (gapSize === 1) {
|
|
2785
|
+
console.warn("floating point inaccuracy detected");
|
|
2786
|
+
}
|
|
2787
|
+
for (let channel = 0; channel < this.channels; channel++) {
|
|
2788
|
+
const dst = this.#buffer[channel];
|
|
2789
|
+
for (let i = 0; i < gapSize; i++) {
|
|
2790
|
+
const writePos = (this.#writeIndex + i) % dst.length;
|
|
2791
|
+
dst[writePos] = 0;
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
for (let channel = 0; channel < this.channels; channel++) {
|
|
2796
|
+
let src = data[channel];
|
|
2797
|
+
src = src.subarray(src.length - samples);
|
|
2798
|
+
const dst = this.#buffer[channel];
|
|
2799
|
+
if (src.length !== samples) throw new Error("mismatching number of samples");
|
|
2800
|
+
for (let i = 0; i < samples; i++) {
|
|
2801
|
+
const writePos = (start + i) % dst.length;
|
|
2802
|
+
dst[writePos] = src[i];
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
if (end > this.#writeIndex) {
|
|
2806
|
+
this.#writeIndex = end;
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
read(output) {
|
|
2810
|
+
if (output.length !== this.channels) throw new Error("wrong number of channels");
|
|
2811
|
+
if (this.#stalled) return 0;
|
|
2812
|
+
const samples = Math.min(this.#writeIndex - this.#readIndex, output[0].length);
|
|
2813
|
+
if (samples === 0) return 0;
|
|
2814
|
+
for (let channel = 0; channel < this.channels; channel++) {
|
|
2815
|
+
const dst = output[channel];
|
|
2816
|
+
const src = this.#buffer[channel];
|
|
2817
|
+
if (dst.length !== output[0].length) throw new Error("mismatching number of samples");
|
|
2818
|
+
for (let i = 0; i < samples; i++) {
|
|
2819
|
+
const readPos = (this.#readIndex + i) % src.length;
|
|
2820
|
+
dst[i] = src[readPos];
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2823
|
+
this.#readIndex += samples;
|
|
2824
|
+
return samples;
|
|
2825
|
+
}
|
|
2826
|
+
};
|
|
2827
|
+
|
|
2828
|
+
// src/audio/shared-ring-buffer.ts
|
|
2829
|
+
var WRITE = 0;
|
|
2830
|
+
var READ = 1;
|
|
2831
|
+
var LATENCY = 2;
|
|
2832
|
+
var STALLED = 3;
|
|
2833
|
+
var CONTROL_SLOTS = 4;
|
|
2834
|
+
function allocSharedRingBuffer(channels, capacity, rate) {
|
|
2835
|
+
if (channels <= 0) throw new Error("invalid channels");
|
|
2836
|
+
if (capacity <= 0) throw new Error("invalid capacity");
|
|
2837
|
+
if (rate <= 0) throw new Error("invalid sample rate");
|
|
2838
|
+
const samples = new SharedArrayBuffer(channels * capacity * Float32Array.BYTES_PER_ELEMENT);
|
|
2839
|
+
const control = new SharedArrayBuffer(CONTROL_SLOTS * Int32Array.BYTES_PER_ELEMENT);
|
|
2840
|
+
const ctrl = new Int32Array(control);
|
|
2841
|
+
Atomics.store(ctrl, STALLED, 1);
|
|
2842
|
+
return { channels, capacity, rate, samples, control };
|
|
2843
|
+
}
|
|
2844
|
+
function i32Max(a, b) {
|
|
2845
|
+
return (a - b | 0) > 0 ? a : b;
|
|
2846
|
+
}
|
|
2847
|
+
function slot(idx, capacity) {
|
|
2848
|
+
return (idx % capacity + capacity) % capacity;
|
|
2849
|
+
}
|
|
2850
|
+
function casAdvance(arr, idx, candidate) {
|
|
2851
|
+
for (; ; ) {
|
|
2852
|
+
const current = Atomics.load(arr, idx);
|
|
2853
|
+
if ((candidate - current | 0) <= 0) return current;
|
|
2854
|
+
const witnessed = Atomics.compareExchange(arr, idx, current, candidate);
|
|
2855
|
+
if (witnessed === current) return candidate;
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
var SharedRingBuffer = class _SharedRingBuffer {
|
|
2859
|
+
channels;
|
|
2860
|
+
capacity;
|
|
2861
|
+
rate;
|
|
2862
|
+
init;
|
|
2863
|
+
#control;
|
|
2864
|
+
#samples;
|
|
2865
|
+
constructor(init) {
|
|
2866
|
+
this.channels = init.channels;
|
|
2867
|
+
this.capacity = init.capacity;
|
|
2868
|
+
this.rate = init.rate;
|
|
2869
|
+
this.init = init;
|
|
2870
|
+
this.#control = new Int32Array(init.control);
|
|
2871
|
+
this.#samples = [];
|
|
2872
|
+
for (let i = 0; i < this.channels; i++) {
|
|
2873
|
+
this.#samples.push(
|
|
2874
|
+
new Float32Array(init.samples, i * this.capacity * Float32Array.BYTES_PER_ELEMENT, this.capacity)
|
|
2875
|
+
);
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
/**
|
|
2879
|
+
* Insert audio samples at the given timestamp.
|
|
2880
|
+
* Main thread only. Handles out-of-order writes, gap filling, and overflow.
|
|
2881
|
+
*/
|
|
2882
|
+
insert(timestamp, data) {
|
|
2883
|
+
if (data.length !== this.channels) throw new Error("wrong number of channels");
|
|
2884
|
+
let start = Math.round(time_exports.Second.fromMicro(timestamp) * this.rate);
|
|
2885
|
+
const originalLength = data[0].length;
|
|
2886
|
+
let offset = 0;
|
|
2887
|
+
const end = start + originalLength | 0;
|
|
2888
|
+
const read = Atomics.load(this.#control, READ);
|
|
2889
|
+
const behind = read - start | 0;
|
|
2890
|
+
if (behind > 0) {
|
|
2891
|
+
if (behind >= originalLength) {
|
|
2892
|
+
return;
|
|
2893
|
+
}
|
|
2894
|
+
offset = behind;
|
|
2895
|
+
start = start + behind | 0;
|
|
2896
|
+
}
|
|
2897
|
+
const samples = originalLength - offset;
|
|
2898
|
+
if ((end - read | 0) > this.capacity) {
|
|
2899
|
+
casAdvance(this.#control, READ, end - this.capacity | 0);
|
|
2900
|
+
}
|
|
2901
|
+
const write = Atomics.load(this.#control, WRITE);
|
|
2902
|
+
const gap = start - write | 0;
|
|
2903
|
+
if (gap > 0) {
|
|
2904
|
+
const gapSize = Math.min(gap, this.capacity);
|
|
2905
|
+
for (let channel = 0; channel < this.channels; channel++) {
|
|
2906
|
+
const dst = this.#samples[channel];
|
|
2907
|
+
for (let i = 0; i < gapSize; i++) {
|
|
2908
|
+
dst[slot(write + i | 0, this.capacity)] = 0;
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
for (let channel = 0; channel < this.channels; channel++) {
|
|
2913
|
+
const src = data[channel];
|
|
2914
|
+
const dst = this.#samples[channel];
|
|
2915
|
+
for (let i = 0; i < samples; i++) {
|
|
2916
|
+
dst[slot(start + i | 0, this.capacity)] = src[offset + i];
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
Atomics.store(this.#control, WRITE, i32Max(Atomics.load(this.#control, WRITE), end));
|
|
2920
|
+
const currentRead = Atomics.load(this.#control, READ);
|
|
2921
|
+
const currentWrite = Atomics.load(this.#control, WRITE);
|
|
2922
|
+
const latency = Atomics.load(this.#control, LATENCY);
|
|
2923
|
+
if ((currentWrite - currentRead | 0) >= latency && latency > 0) {
|
|
2924
|
+
Atomics.store(this.#control, STALLED, 0);
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
/**
|
|
2928
|
+
* Read audio samples into the output buffers.
|
|
2929
|
+
* AudioWorklet only. Returns the number of samples read.
|
|
2930
|
+
*/
|
|
2931
|
+
read(output) {
|
|
2932
|
+
if (Atomics.load(this.#control, STALLED) === 1) return 0;
|
|
2933
|
+
let read = Atomics.load(this.#control, READ);
|
|
2934
|
+
const write = Atomics.load(this.#control, WRITE);
|
|
2935
|
+
const latency = Atomics.load(this.#control, LATENCY);
|
|
2936
|
+
const buffered = write - read | 0;
|
|
2937
|
+
if (latency > 0 && buffered > latency) {
|
|
2938
|
+
const skipTo = write - latency | 0;
|
|
2939
|
+
read = casAdvance(this.#control, READ, skipTo);
|
|
2940
|
+
}
|
|
2941
|
+
const available = write - read | 0;
|
|
2942
|
+
const count = Math.min(available, output[0].length);
|
|
2943
|
+
if (count <= 0) return 0;
|
|
2944
|
+
for (let channel = 0; channel < this.channels; channel++) {
|
|
2945
|
+
const src = this.#samples[channel];
|
|
2946
|
+
const dst = output[channel];
|
|
2947
|
+
for (let i = 0; i < count; i++) {
|
|
2948
|
+
dst[i] = src[slot(read + i | 0, this.capacity)];
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
casAdvance(this.#control, READ, read + count | 0);
|
|
2952
|
+
return count;
|
|
2953
|
+
}
|
|
2954
|
+
/** Update the target latency in samples. */
|
|
2955
|
+
setLatency(samples) {
|
|
2956
|
+
Atomics.store(this.#control, LATENCY, samples);
|
|
2957
|
+
}
|
|
2958
|
+
/**
|
|
2959
|
+
* Allocate a new ring with \`newCapacity\` samples and copy the unread window
|
|
2960
|
+
* [READ, WRITE) plus control state into it. Used when growing capacity so
|
|
2961
|
+
* we don't drop buffered audio. If \`newCapacity\` is smaller than the unread
|
|
2962
|
+
* span, the oldest samples are truncated.
|
|
2963
|
+
*
|
|
2964
|
+
* Main thread only. \`resize()\` reads from the source \`SharedRingBuffer\` and
|
|
2965
|
+
* writes into a freshly allocated buffer from \`allocSharedRingBuffer\`, so it
|
|
2966
|
+
* relies on the same invariant as \`insert()\`: no concurrent main-thread
|
|
2967
|
+
* writers. The AudioWorklet reader is tolerated via the CAS discipline used
|
|
2968
|
+
* by READ/WRITE elsewhere.
|
|
2969
|
+
*/
|
|
2970
|
+
resize(newCapacity) {
|
|
2971
|
+
const init = allocSharedRingBuffer(this.channels, newCapacity, this.rate);
|
|
2972
|
+
const dst = new _SharedRingBuffer(init);
|
|
2973
|
+
const read = Atomics.load(this.#control, READ);
|
|
2974
|
+
const write = Atomics.load(this.#control, WRITE);
|
|
2975
|
+
const latency = Atomics.load(this.#control, LATENCY);
|
|
2976
|
+
const stalled = Atomics.load(this.#control, STALLED);
|
|
2977
|
+
const available = write - read | 0;
|
|
2978
|
+
const copyCount = Math.max(0, Math.min(available, dst.capacity));
|
|
2979
|
+
const copyStart = write - copyCount | 0;
|
|
2980
|
+
for (let channel = 0; channel < this.channels; channel++) {
|
|
2981
|
+
const src = this.#samples[channel];
|
|
2982
|
+
const out = dst.#samples[channel];
|
|
2983
|
+
for (let i = 0; i < copyCount; i++) {
|
|
2984
|
+
const idx = copyStart + i | 0;
|
|
2985
|
+
out[slot(idx, dst.capacity)] = src[slot(idx, this.capacity)];
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
Atomics.store(dst.#control, READ, copyStart);
|
|
2989
|
+
Atomics.store(dst.#control, WRITE, write);
|
|
2990
|
+
Atomics.store(dst.#control, LATENCY, latency);
|
|
2991
|
+
Atomics.store(dst.#control, STALLED, stalled);
|
|
2992
|
+
return dst;
|
|
2993
|
+
}
|
|
2994
|
+
/** Current playback timestamp derived from READ position. */
|
|
2995
|
+
get timestamp() {
|
|
2996
|
+
const read = Atomics.load(this.#control, READ);
|
|
2997
|
+
return time_exports.Micro.fromSecond(read / this.rate);
|
|
2998
|
+
}
|
|
2999
|
+
/** Whether the buffer is stalled (waiting to fill). */
|
|
3000
|
+
get stalled() {
|
|
3001
|
+
return Atomics.load(this.#control, STALLED) === 1;
|
|
3002
|
+
}
|
|
3003
|
+
/**
|
|
3004
|
+
* Number of buffered samples (WRITE - READ).
|
|
3005
|
+
*
|
|
3006
|
+
* Non-atomic: WRITE and READ are loaded separately, so a concurrent
|
|
3007
|
+
* writer/reader can make the two loads inconsistent. Intended for
|
|
3008
|
+
* tests and diagnostics, not control-flow decisions.
|
|
3009
|
+
*/
|
|
3010
|
+
get length() {
|
|
3011
|
+
return Atomics.load(this.#control, WRITE) - Atomics.load(this.#control, READ) | 0;
|
|
3012
|
+
}
|
|
3013
|
+
};
|
|
3014
|
+
|
|
3015
|
+
// src/audio/render-worklet.ts
|
|
3016
|
+
var Render = class extends AudioWorkletProcessor {
|
|
3017
|
+
// Set after init, depending on which path the main thread chose.
|
|
3018
|
+
#backend;
|
|
3019
|
+
#underflow = 0;
|
|
3020
|
+
#stateCounter = 0;
|
|
3021
|
+
constructor() {
|
|
3022
|
+
super();
|
|
3023
|
+
this.port.onmessage = (event) => {
|
|
3024
|
+
const msg = event.data;
|
|
3025
|
+
if (msg.type === "init-shared") {
|
|
3026
|
+
console.log("[audio-worklet] init-shared: using SharedArrayBuffer path");
|
|
3027
|
+
this.#backend = new SharedRingBuffer(msg);
|
|
3028
|
+
this.#underflow = 0;
|
|
3029
|
+
} else if (msg.type === "init-post") {
|
|
3030
|
+
console.log("[audio-worklet] init-post: using postMessage path");
|
|
3031
|
+
this.#backend = new AudioRingBuffer(msg);
|
|
3032
|
+
this.#underflow = 0;
|
|
3033
|
+
} else if (msg.type === "data") {
|
|
3034
|
+
if (this.#backend instanceof AudioRingBuffer) this.#backend.write(msg.timestamp, msg.data);
|
|
3035
|
+
} else if (msg.type === "latency") {
|
|
3036
|
+
if (this.#backend instanceof AudioRingBuffer) this.#backend.resize(msg.latency);
|
|
3037
|
+
}
|
|
3038
|
+
};
|
|
3039
|
+
}
|
|
3040
|
+
process(_inputs, outputs, _parameters) {
|
|
3041
|
+
const output = outputs[0];
|
|
3042
|
+
const backend = this.#backend;
|
|
3043
|
+
const samplesRead = backend?.read(output) ?? 0;
|
|
3044
|
+
if (samplesRead < output[0].length) {
|
|
3045
|
+
this.#underflow += output[0].length - samplesRead;
|
|
3046
|
+
} else if (this.#underflow > 0 && backend) {
|
|
3047
|
+
console.debug(\`audio underflow: \${Math.round(1e3 * this.#underflow / backend.rate)}ms\`);
|
|
3048
|
+
this.#underflow = 0;
|
|
3049
|
+
}
|
|
3050
|
+
if (backend instanceof AudioRingBuffer) {
|
|
3051
|
+
this.#stateCounter++;
|
|
3052
|
+
if (this.#stateCounter >= 5) {
|
|
3053
|
+
this.#stateCounter = 0;
|
|
3054
|
+
const state = {
|
|
3055
|
+
type: "state",
|
|
3056
|
+
timestamp: backend.timestamp,
|
|
3057
|
+
stalled: backend.stalled
|
|
3058
|
+
};
|
|
3059
|
+
this.port.postMessage(state);
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
return true;
|
|
3063
|
+
}
|
|
3064
|
+
};
|
|
3065
|
+
registerProcessor("render", Render);
|
|
3066
|
+
`, ti = new Blob([ei], { type: "application/javascript" }), ni = URL.createObjectURL(ti);
|
|
3067
|
+
let si = class {
|
|
3068
|
+
source;
|
|
3069
|
+
enabled;
|
|
3070
|
+
#e = new h(void 0);
|
|
3071
|
+
context = this.#e;
|
|
3072
|
+
// The root of the audio graph, which can be used for custom visualizations.
|
|
3073
|
+
#t = new h(void 0);
|
|
3074
|
+
// Downcast to AudioNode so it matches Publish.Audio
|
|
3075
|
+
root = this.#t;
|
|
3076
|
+
#n = new h(void 0);
|
|
3077
|
+
sampleRate = this.#n;
|
|
3078
|
+
#s = new h(void 0);
|
|
3079
|
+
stats = this.#s;
|
|
3080
|
+
// Current playback timestamp from worklet
|
|
3081
|
+
#i = new h(void 0);
|
|
3082
|
+
timestamp = this.#i;
|
|
3083
|
+
// Whether the audio buffer is stalled (waiting to fill)
|
|
3084
|
+
#r = new h(!0);
|
|
3085
|
+
stalled = this.#r;
|
|
3086
|
+
// Decode buffer: audio sent to worklet but not yet played
|
|
3087
|
+
#o = new h([]);
|
|
3088
|
+
// Combined buffered ranges (network jitter + decode buffer)
|
|
3089
|
+
#a = new h([]);
|
|
3090
|
+
buffered = this.#a;
|
|
3091
|
+
// Audio ring bridging main thread and worklet (shared memory or postMessage transport).
|
|
3092
|
+
#c;
|
|
3093
|
+
#u = new T();
|
|
3094
|
+
constructor(e, n) {
|
|
3095
|
+
this.source = e, this.source.supported.set(ii), this.enabled = h.from(n?.enabled ?? !1), this.#u.run(this.#d.bind(this)), this.#u.run(this.#l.bind(this)), this.#u.run(this.#f.bind(this)), this.#u.run(this.#m.bind(this));
|
|
3096
|
+
}
|
|
3097
|
+
#d(e) {
|
|
3098
|
+
const n = e.get(this.source.config);
|
|
3099
|
+
if (!n) return;
|
|
3100
|
+
const s = n.sampleRate, i = n.numberOfChannels, r = new AudioContext({
|
|
3101
|
+
latencyHint: "interactive",
|
|
3102
|
+
// We don't use real-time because of the buffer.
|
|
3103
|
+
sampleRate: s
|
|
3104
|
+
});
|
|
3105
|
+
e.set(this.#e, r), e.cleanup(() => r.close()), e.spawn(async () => {
|
|
3106
|
+
if (await r.audioWorklet.addModule(ni), r.state === "closed") return;
|
|
3107
|
+
const o = new AudioWorkletNode(r, "render", {
|
|
3108
|
+
channelCount: i,
|
|
3109
|
+
channelCountMode: "explicit",
|
|
3110
|
+
outputChannelCount: [i]
|
|
3111
|
+
});
|
|
3112
|
+
e.cleanup(() => o.disconnect());
|
|
3113
|
+
const a = this.source.sync.buffer.peek(), c = Math.ceil(s * m.Second.fromMilli(a)), u = Ks(o, i, s, c);
|
|
3114
|
+
this.#c = u, e.cleanup(() => {
|
|
3115
|
+
u.close(), this.#c = void 0;
|
|
3116
|
+
}), e.run((l) => {
|
|
3117
|
+
const d = m.Milli.fromMicro(l.get(u.timestamp));
|
|
3118
|
+
this.#i.set(d), this.#y(d);
|
|
3119
|
+
}), e.run((l) => {
|
|
3120
|
+
this.#r.set(l.get(u.stalled));
|
|
3121
|
+
}), e.set(this.#t, o);
|
|
3122
|
+
});
|
|
3123
|
+
}
|
|
3124
|
+
#l(e) {
|
|
3125
|
+
const n = e.getAll([this.enabled, this.#e]);
|
|
3126
|
+
if (!n) return;
|
|
3127
|
+
const [s, i] = n;
|
|
3128
|
+
i.resume();
|
|
3129
|
+
}
|
|
3130
|
+
#f(e) {
|
|
3131
|
+
if (!e.get(this.#t)) return;
|
|
3132
|
+
const s = this.#c;
|
|
3133
|
+
if (!s) return;
|
|
3134
|
+
const i = e.get(this.source.sync.buffer), r = Math.ceil(s.rate * m.Second.fromMilli(i));
|
|
3135
|
+
s.setLatency(r);
|
|
3136
|
+
}
|
|
3137
|
+
#m(e) {
|
|
3138
|
+
if (!e.get(this.enabled)) return;
|
|
3139
|
+
const s = e.get(this.source.broadcast);
|
|
3140
|
+
if (!s) return;
|
|
3141
|
+
const i = e.get(this.source.track);
|
|
3142
|
+
if (!i) return;
|
|
3143
|
+
const r = e.get(this.source.config);
|
|
3144
|
+
if (!r) return;
|
|
3145
|
+
const o = e.get(s.active);
|
|
3146
|
+
if (!o) return;
|
|
3147
|
+
const a = o.subscribe(i, J.audio);
|
|
3148
|
+
e.cleanup(() => a.close()), r.container.kind === "cmaf" ? this.#g(e, a, r) : this.#p(e, a, r);
|
|
3149
|
+
}
|
|
3150
|
+
#p(e, n, s) {
|
|
3151
|
+
const i = new te(n, {
|
|
3152
|
+
latency: this.source.sync.buffer
|
|
3153
|
+
});
|
|
3154
|
+
e.cleanup(() => i.close()), e.run((r) => {
|
|
3155
|
+
const o = r.get(i.buffered), a = r.get(this.#o);
|
|
3156
|
+
this.#a.update(() => ri(o, a));
|
|
3157
|
+
}), e.spawn(async () => {
|
|
3158
|
+
if (!await Ge()) return;
|
|
3159
|
+
let o = 0;
|
|
3160
|
+
const a = new AudioDecoder({
|
|
3161
|
+
output: (u) => {
|
|
3162
|
+
if (o++, o <= 3) {
|
|
3163
|
+
u.close();
|
|
3164
|
+
return;
|
|
3165
|
+
}
|
|
3166
|
+
this.#h(u);
|
|
3167
|
+
},
|
|
3168
|
+
error: (u) => console.error(u)
|
|
3169
|
+
});
|
|
3170
|
+
e.cleanup(() => {
|
|
3171
|
+
a.state !== "closed" && a.close();
|
|
3172
|
+
});
|
|
3173
|
+
const c = s.description ? O(s.description) : void 0;
|
|
3174
|
+
for (a.configure({
|
|
3175
|
+
...s,
|
|
3176
|
+
description: c
|
|
3177
|
+
}); ; ) {
|
|
3178
|
+
const u = await i.next();
|
|
3179
|
+
if (!u) break;
|
|
3180
|
+
const { frame: l } = u;
|
|
3181
|
+
if (!l) continue;
|
|
3182
|
+
const d = m.Milli.fromMicro(l.timestamp);
|
|
3183
|
+
this.source.sync.received(d, "audio"), this.#s.update((g) => ({
|
|
3184
|
+
bytesReceived: (g?.bytesReceived ?? 0) + l.data.byteLength
|
|
3185
|
+
}));
|
|
3186
|
+
const f = new EncodedAudioChunk({
|
|
3187
|
+
type: l.keyframe ? "key" : "delta",
|
|
3188
|
+
data: l.data,
|
|
3189
|
+
timestamp: l.timestamp
|
|
3190
|
+
});
|
|
3191
|
+
a.decode(f);
|
|
3192
|
+
}
|
|
3193
|
+
});
|
|
3194
|
+
}
|
|
3195
|
+
#g(e, n, s) {
|
|
3196
|
+
if (s.container.kind !== "cmaf") return;
|
|
3197
|
+
const { timescale: i } = s.container, r = s.description ? O(s.description) : void 0;
|
|
3198
|
+
e.run((o) => {
|
|
3199
|
+
const a = o.get(this.#o);
|
|
3200
|
+
this.#a.update(() => a);
|
|
3201
|
+
}), e.spawn(async () => {
|
|
3202
|
+
if (!await Ge()) return;
|
|
3203
|
+
const a = new AudioDecoder({
|
|
3204
|
+
output: (c) => this.#h(c),
|
|
3205
|
+
error: (c) => console.error(c)
|
|
3206
|
+
});
|
|
3207
|
+
for (e.cleanup(() => {
|
|
3208
|
+
a.state !== "closed" && a.close();
|
|
3209
|
+
}), a.configure({
|
|
3210
|
+
codec: s.codec,
|
|
3211
|
+
sampleRate: s.sampleRate,
|
|
3212
|
+
numberOfChannels: s.numberOfChannels,
|
|
3213
|
+
description: r
|
|
3214
|
+
}); ; ) {
|
|
3215
|
+
const c = await n.nextGroup();
|
|
3216
|
+
if (!c) break;
|
|
3217
|
+
e.spawn(async () => {
|
|
3218
|
+
try {
|
|
3219
|
+
for (; ; ) {
|
|
3220
|
+
const u = await c.readFrame();
|
|
3221
|
+
if (!u) break;
|
|
3222
|
+
const l = Tt(u, i);
|
|
3223
|
+
for (const d of l) {
|
|
3224
|
+
const f = m.Milli.fromMicro(d.timestamp);
|
|
3225
|
+
this.source.sync.received(f, "audio"), this.#s.update((y) => ({
|
|
3226
|
+
bytesReceived: (y?.bytesReceived ?? 0) + d.data.byteLength
|
|
3227
|
+
}));
|
|
3228
|
+
const g = new EncodedAudioChunk({
|
|
3229
|
+
type: d.keyframe ? "key" : "delta",
|
|
3230
|
+
data: d.data,
|
|
3231
|
+
timestamp: d.timestamp
|
|
3232
|
+
});
|
|
3233
|
+
a.decode(g);
|
|
3234
|
+
}
|
|
3235
|
+
}
|
|
3236
|
+
} finally {
|
|
3237
|
+
c.close();
|
|
3238
|
+
}
|
|
3239
|
+
});
|
|
3240
|
+
}
|
|
3241
|
+
});
|
|
3242
|
+
}
|
|
3243
|
+
#h(e) {
|
|
3244
|
+
const n = e.timestamp, s = m.Milli.fromMicro(n), i = this.#c;
|
|
3245
|
+
if (!i) {
|
|
3246
|
+
e.close();
|
|
3247
|
+
return;
|
|
3248
|
+
}
|
|
3249
|
+
const r = e.numberOfFrames / e.sampleRate * 1e6, o = m.Milli.fromMicro(r), a = m.Milli.add(s, o);
|
|
3250
|
+
this.#w(s, a);
|
|
3251
|
+
const c = Math.min(e.numberOfChannels, i.channels), u = [];
|
|
3252
|
+
for (let l = 0; l < c; l++) {
|
|
3253
|
+
const d = new Float32Array(e.numberOfFrames);
|
|
3254
|
+
e.copyTo(d, { format: "f32-planar", planeIndex: l }), u.push(d);
|
|
3255
|
+
}
|
|
3256
|
+
i.insert(n, u), e.close();
|
|
3257
|
+
}
|
|
3258
|
+
#w(e, n) {
|
|
3259
|
+
e > n || this.#o.mutate((s) => {
|
|
3260
|
+
for (const i of s)
|
|
3261
|
+
if (e <= i.end + 1 && n >= i.start) {
|
|
3262
|
+
i.start = m.Milli.min(i.start, e), i.end = m.Milli.max(i.end, n);
|
|
3263
|
+
return;
|
|
3264
|
+
}
|
|
3265
|
+
s.push({ start: e, end: n }), s.sort((i, r) => i.start - r.start);
|
|
3266
|
+
});
|
|
3267
|
+
}
|
|
3268
|
+
#y(e) {
|
|
3269
|
+
this.#o.mutate((n) => {
|
|
3270
|
+
for (; n.length > 0; ) {
|
|
3271
|
+
if (n[0].end >= e) {
|
|
3272
|
+
n[0].start = m.Milli.max(n[0].start, e);
|
|
3273
|
+
break;
|
|
3274
|
+
}
|
|
3275
|
+
n.shift();
|
|
3276
|
+
}
|
|
3277
|
+
});
|
|
3278
|
+
}
|
|
3279
|
+
close() {
|
|
3280
|
+
this.#u.close();
|
|
3281
|
+
}
|
|
3282
|
+
};
|
|
3283
|
+
async function ii(t) {
|
|
3284
|
+
const e = t.description ? O(t.description) : void 0;
|
|
3285
|
+
return (await AudioDecoder.isConfigSupported({
|
|
3286
|
+
...t,
|
|
3287
|
+
description: e
|
|
3288
|
+
})).supported ?? !1;
|
|
3289
|
+
}
|
|
3290
|
+
function ri(t, e) {
|
|
3291
|
+
if (t.length === 0) return e;
|
|
3292
|
+
if (e.length === 0) return t;
|
|
3293
|
+
const n = [], s = [...t, ...e].sort((i, r) => i.start - r.start);
|
|
3294
|
+
for (const i of s) {
|
|
3295
|
+
const r = n.at(-1);
|
|
3296
|
+
r && r.end >= i.start ? r.end = m.Milli.max(r.end, i.end) : n.push({ ...i });
|
|
3297
|
+
}
|
|
3298
|
+
return n;
|
|
3299
|
+
}
|
|
3300
|
+
const Xe = 1e-3, _e = 0.2;
|
|
3301
|
+
class oi {
|
|
3302
|
+
source;
|
|
3303
|
+
volume;
|
|
3304
|
+
muted;
|
|
3305
|
+
// Similar to muted, but controls whether we download audio at all.
|
|
3306
|
+
// That way we can be "muted" but also download audio for visualizations.
|
|
3307
|
+
paused;
|
|
3308
|
+
#e = new T();
|
|
3309
|
+
// The volume to use when unmuted.
|
|
3310
|
+
#t = 0.5;
|
|
3311
|
+
// The gain node used to adjust the volume.
|
|
3312
|
+
#n = new h(void 0);
|
|
3313
|
+
constructor(e, n) {
|
|
3314
|
+
this.source = e, this.volume = h.from(n?.volume ?? 0.5), this.muted = h.from(n?.muted ?? !1), this.paused = h.from(n?.paused ?? n?.muted ?? !1), this.#e.run((s) => {
|
|
3315
|
+
s.get(this.muted) ? (this.#t = this.volume.peek() || 0.5, this.volume.set(0)) : this.volume.set(this.#t);
|
|
3316
|
+
}), this.#e.run((s) => {
|
|
3317
|
+
const i = !s.get(this.paused) && !s.get(this.muted);
|
|
3318
|
+
this.source.enabled.set(i);
|
|
3319
|
+
}), this.#e.run((s) => {
|
|
3320
|
+
const i = s.get(this.volume);
|
|
3321
|
+
this.muted.set(i === 0);
|
|
3322
|
+
}), this.#e.run((s) => {
|
|
3323
|
+
const i = s.get(this.source.root);
|
|
3324
|
+
if (!i) return;
|
|
3325
|
+
const r = new GainNode(i.context, { gain: s.get(this.volume) });
|
|
3326
|
+
i.connect(r), s.set(this.#n, r), s.run((o) => {
|
|
3327
|
+
o.get(this.source.enabled) && (r.connect(i.context.destination), o.cleanup(() => r.disconnect()));
|
|
3328
|
+
});
|
|
3329
|
+
}), this.#e.run((s) => {
|
|
3330
|
+
const i = s.get(this.#n);
|
|
3331
|
+
if (!i) return;
|
|
3332
|
+
s.cleanup(() => i.gain.cancelScheduledValues(i.context.currentTime));
|
|
3333
|
+
const r = s.get(this.volume);
|
|
3334
|
+
r < Xe ? (i.gain.exponentialRampToValueAtTime(Xe, i.context.currentTime + _e), i.gain.setValueAtTime(0, i.context.currentTime + _e + 0.01)) : i.gain.exponentialRampToValueAtTime(r, i.context.currentTime + _e);
|
|
3335
|
+
});
|
|
3336
|
+
}
|
|
3337
|
+
close() {
|
|
3338
|
+
this.#e.close();
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3341
|
+
class It {
|
|
3342
|
+
element;
|
|
3343
|
+
paused;
|
|
3344
|
+
#e;
|
|
3345
|
+
#t = new h(void 0);
|
|
3346
|
+
mediaSource = this.#t;
|
|
3347
|
+
#n = new T();
|
|
3348
|
+
constructor(e, n) {
|
|
3349
|
+
this.element = h.from(n?.element), this.paused = h.from(n?.paused ?? !1), this.#e = e, this.#n.run(this.#s.bind(this)), this.#n.run(this.#i.bind(this)), this.#n.run(this.#r.bind(this)), this.#n.run(this.#o.bind(this)), this.#n.run(this.#a.bind(this));
|
|
3350
|
+
}
|
|
3351
|
+
#s(e) {
|
|
3352
|
+
const n = e.get(this.element);
|
|
3353
|
+
if (!n) return;
|
|
3354
|
+
const s = new MediaSource();
|
|
3355
|
+
n.src = URL.createObjectURL(s), e.cleanup(() => URL.revokeObjectURL(n.src)), e.event(
|
|
3356
|
+
s,
|
|
3357
|
+
"sourceopen",
|
|
3358
|
+
() => {
|
|
3359
|
+
e.set(this.#t, s);
|
|
3360
|
+
},
|
|
3361
|
+
{ once: !0 }
|
|
3362
|
+
), e.event(s, "error", (i) => {
|
|
3363
|
+
console.error("[MSE] MediaSource error event:", i);
|
|
3364
|
+
});
|
|
3365
|
+
}
|
|
3366
|
+
#i(e) {
|
|
3367
|
+
const n = e.get(this.element);
|
|
3368
|
+
if (!n || e.get(this.paused)) return;
|
|
3369
|
+
const i = m.Milli.toSecond(e.get(this.#e.buffer));
|
|
3370
|
+
e.interval(() => {
|
|
3371
|
+
const r = n.buffered;
|
|
3372
|
+
if (r.length === 0) return;
|
|
3373
|
+
const a = r.end(r.length - 1) - i, c = a - n.currentTime;
|
|
3374
|
+
(c > 0.1 || c < -0.1) && (console.warn("seeking", c > 0 ? "forward" : "backward", Math.abs(c).toFixed(3), "seconds"), n.currentTime = a);
|
|
3375
|
+
}, 100);
|
|
3376
|
+
}
|
|
3377
|
+
#r(e) {
|
|
3378
|
+
const n = e.get(this.element);
|
|
3379
|
+
if (!n) return;
|
|
3380
|
+
const s = e.get(this.mediaSource);
|
|
3381
|
+
s && e.interval(async () => {
|
|
3382
|
+
for (const i of s.sourceBuffers) {
|
|
3383
|
+
for (; i.updating; )
|
|
3384
|
+
await new Promise((r) => i.addEventListener("updateend", r, { once: !0 }));
|
|
3385
|
+
n.currentTime > 10 && i.remove(0, n.currentTime - 10);
|
|
3386
|
+
}
|
|
3387
|
+
}, 1e3);
|
|
3388
|
+
}
|
|
3389
|
+
#o(e) {
|
|
3390
|
+
const n = e.get(this.element);
|
|
3391
|
+
if (!n) return;
|
|
3392
|
+
const s = e.get(this.paused);
|
|
3393
|
+
s && !n.paused ? n.pause() : !s && n.paused && n.play().catch((i) => {
|
|
3394
|
+
console.error("[MSE] MediaElement play error:", i);
|
|
3395
|
+
});
|
|
3396
|
+
}
|
|
3397
|
+
// Seek to the target position based on the reference and latency.
|
|
3398
|
+
#a(e) {
|
|
3399
|
+
const n = e.get(this.element);
|
|
3400
|
+
if (!n || e.get(this.paused)) return;
|
|
3401
|
+
const i = e.get(this.#e.reference);
|
|
3402
|
+
if (i === void 0) return;
|
|
3403
|
+
const r = e.get(this.#e.buffer), o = m.Milli.sub(m.Milli.sub(m.Milli.now(), i), r);
|
|
3404
|
+
n.currentTime = m.Milli.toSecond(o);
|
|
3405
|
+
}
|
|
3406
|
+
close() {
|
|
3407
|
+
this.#n.close();
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
const xi = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
3411
|
+
__proto__: null,
|
|
3412
|
+
Muxer: It
|
|
3413
|
+
}, Symbol.toStringTag, { value: "Module" })), ai = 20, Ye = 100;
|
|
3414
|
+
class Ue {
|
|
3415
|
+
// The earliest time we've received a frame, relative to its timestamp.
|
|
3416
|
+
// This will keep being updated as we catch up to the live playhead then will be relatively static.
|
|
3417
|
+
#e = new h(void 0);
|
|
3418
|
+
reference = this.#e;
|
|
3419
|
+
// The latency setting: "real-time" auto-computes jitter from RTT, a number sets a fixed jitter.
|
|
3420
|
+
latency;
|
|
3421
|
+
// The jitter buffer in milliseconds (always numeric).
|
|
3422
|
+
// In "real-time" mode this is updated automatically from RTT.
|
|
3423
|
+
// When latency is a number, jitter equals that number.
|
|
3424
|
+
jitter;
|
|
3425
|
+
// Any additional delay required for audio or video.
|
|
3426
|
+
audio;
|
|
3427
|
+
video;
|
|
3428
|
+
// The total buffer required: jitter + max(audio, video).
|
|
3429
|
+
#t = new h(m.Milli.zero);
|
|
3430
|
+
buffer = this.#t;
|
|
3431
|
+
// A ghetto way to learn when the reference/buffer changes.
|
|
3432
|
+
// There's probably a way to use Effect, but lets keep it simple for now.
|
|
3433
|
+
#n;
|
|
3434
|
+
// The media timestamp of the most recently received frame.
|
|
3435
|
+
timestamp = new h(void 0);
|
|
3436
|
+
// Per-label late-frame tracking: accumulate count and max lateness, flush on recovery.
|
|
3437
|
+
#s = /* @__PURE__ */ new Map();
|
|
3438
|
+
// RTT signal from the connection (PROBE or getStats).
|
|
3439
|
+
rtt;
|
|
3440
|
+
// Minimum RTT seen, used as the baseline for jitter calculation.
|
|
3441
|
+
// Avoids inflating jitter due to bufferbloat.
|
|
3442
|
+
#i;
|
|
3443
|
+
signals = new T();
|
|
3444
|
+
constructor(e) {
|
|
3445
|
+
this.latency = h.from(e?.latency ?? "real-time"), this.jitter = new h(Ye), this.rtt = e?.rtt, this.audio = h.from(e?.audio), this.video = h.from(e?.video), this.#n = Promise.withResolvers(), this.signals.run(this.#r.bind(this)), this.signals.run(this.#o.bind(this));
|
|
3446
|
+
}
|
|
3447
|
+
#r(e) {
|
|
3448
|
+
const n = e.get(this.latency);
|
|
3449
|
+
if (typeof n == "number") {
|
|
3450
|
+
this.#i = void 0, this.jitter.set(n);
|
|
3451
|
+
return;
|
|
3452
|
+
}
|
|
3453
|
+
if (this.rtt) {
|
|
3454
|
+
const s = e.get(this.rtt);
|
|
3455
|
+
if (s !== void 0) {
|
|
3456
|
+
this.#i = this.#i !== void 0 ? Math.min(this.#i, s) : s;
|
|
3457
|
+
const i = Math.max(ai, this.#i * 1.25);
|
|
3458
|
+
this.jitter.set(i);
|
|
3459
|
+
return;
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
this.#i = void 0, this.jitter.set(Ye);
|
|
3463
|
+
}
|
|
3464
|
+
#o(e) {
|
|
3465
|
+
const n = e.get(this.jitter), s = e.get(this.video) ?? m.Milli.zero, i = e.get(this.audio) ?? m.Milli.zero, r = m.Milli.add(m.Milli.max(s, i), n);
|
|
3466
|
+
this.#t.set(r), this.#n.resolve(), this.#n = Promise.withResolvers();
|
|
3467
|
+
}
|
|
3468
|
+
// Update the reference if this is the earliest frame we've seen, relative to its timestamp.
|
|
3469
|
+
received(e, n = "") {
|
|
3470
|
+
this.timestamp.update((o) => o === void 0 || e > o ? e : o);
|
|
3471
|
+
const s = m.Milli.now(), i = m.Milli.sub(s, e), r = this.#e.peek();
|
|
3472
|
+
if (r !== void 0) {
|
|
3473
|
+
const o = m.Milli.add(m.Milli.sub(r, i), this.#t.peek());
|
|
3474
|
+
if (o < 0) {
|
|
3475
|
+
const a = this.#s.get(n);
|
|
3476
|
+
a ? (a.count++, a.maxMs = Math.max(a.maxMs, -o)) : this.#s.set(n, { count: 1, maxMs: -o });
|
|
3477
|
+
} else {
|
|
3478
|
+
const a = this.#s.get(n);
|
|
3479
|
+
if (a) {
|
|
3480
|
+
const c = n ? `sync[${n}]` : "sync", u = Ue.#a(a.maxMs);
|
|
3481
|
+
console.debug(`${c}: ${a.count} late frame(s), max ${u} behind`), this.#s.delete(n);
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
if (i >= r)
|
|
3485
|
+
return;
|
|
3486
|
+
}
|
|
3487
|
+
this.#e.set(i), this.#n.resolve(), this.#n = Promise.withResolvers();
|
|
3488
|
+
}
|
|
3489
|
+
// The PTS that should be rendering right now, derived from the reference + buffer.
|
|
3490
|
+
// Returns undefined if no frames have been received yet.
|
|
3491
|
+
now() {
|
|
3492
|
+
const e = this.#e.peek();
|
|
3493
|
+
if (e !== void 0)
|
|
3494
|
+
return m.Milli.sub(m.Milli.sub(m.Milli.now(), e), this.#t.peek());
|
|
3495
|
+
}
|
|
3496
|
+
// Sleep until it's time to render this frame.
|
|
3497
|
+
async wait(e) {
|
|
3498
|
+
if (this.#e.peek() === void 0)
|
|
3499
|
+
throw new Error("reference not set; call update() first");
|
|
3500
|
+
for (; ; ) {
|
|
3501
|
+
const s = m.Milli.now(), i = m.Milli.sub(s, e), r = this.#e.peek();
|
|
3502
|
+
if (r === void 0) return;
|
|
3503
|
+
const o = m.Milli.add(m.Milli.sub(r, i), this.#t.peek());
|
|
3504
|
+
if (o <= 0 || o < 5) return;
|
|
3505
|
+
const a = new Promise((u) => setTimeout(u, o)).then(() => !0);
|
|
3506
|
+
if (await Promise.race([this.#n.promise, a])) return;
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
static #a(e) {
|
|
3510
|
+
if (e = Math.round(e), e < 1e3) return `${e}ms`;
|
|
3511
|
+
const n = e / 1e3;
|
|
3512
|
+
if (n < 60) return `${Math.round(n * 10) / 10}s`;
|
|
3513
|
+
const s = n / 60;
|
|
3514
|
+
return `${Math.round(s * 10) / 10}m`;
|
|
3515
|
+
}
|
|
3516
|
+
close() {
|
|
3517
|
+
this.signals.close();
|
|
3518
|
+
}
|
|
3519
|
+
}
|
|
3520
|
+
const ci = 500, ui = 100;
|
|
3521
|
+
class li {
|
|
3522
|
+
enabled;
|
|
3523
|
+
// Don't download any longer
|
|
3524
|
+
source;
|
|
3525
|
+
// The current track running, held so we can cancel it when the new track is ready.
|
|
3526
|
+
#e = new h(void 0);
|
|
3527
|
+
// Expose the current frame to render as a signal
|
|
3528
|
+
#t = new h(void 0);
|
|
3529
|
+
frame = this.#t;
|
|
3530
|
+
// The timestamp of the current frame.
|
|
3531
|
+
#n = new h(void 0);
|
|
3532
|
+
timestamp = this.#n;
|
|
3533
|
+
// The display size of the video in pixels, ideally sourced from the catalog.
|
|
3534
|
+
#s = new h(void 0);
|
|
3535
|
+
display = this.#s;
|
|
3536
|
+
#i = new h(!1);
|
|
3537
|
+
stalled = this.#i;
|
|
3538
|
+
#r = new h(void 0);
|
|
3539
|
+
stats = this.#r;
|
|
3540
|
+
// Combined buffered ranges (network jitter + decode buffer)
|
|
3541
|
+
#o = new h([]);
|
|
3542
|
+
buffered = this.#o;
|
|
3543
|
+
#a = new T();
|
|
3544
|
+
constructor(e, n) {
|
|
3545
|
+
this.enabled = h.from(n?.enabled ?? !1), this.source = e, this.source.supported.set(fi), this.#a.run(this.#c.bind(this)), this.#a.run(this.#u.bind(this)), this.#a.run(this.#d.bind(this)), this.#a.run(this.#l.bind(this));
|
|
3546
|
+
}
|
|
3547
|
+
#c(e) {
|
|
3548
|
+
const n = e.getAll([this.enabled, this.source.broadcast, this.source.track, this.source.config]);
|
|
3549
|
+
if (!n) {
|
|
3550
|
+
this.#e.set(void 0);
|
|
3551
|
+
return;
|
|
3552
|
+
}
|
|
3553
|
+
const [s, i, r, o] = n, a = e.get(i.active);
|
|
3554
|
+
if (!a) return;
|
|
3555
|
+
let c = new di({
|
|
3556
|
+
source: this.source,
|
|
3557
|
+
broadcast: a,
|
|
3558
|
+
track: r,
|
|
3559
|
+
config: o,
|
|
3560
|
+
stats: this.#r
|
|
3561
|
+
});
|
|
3562
|
+
e.cleanup(() => c?.close()), e.run((u) => {
|
|
3563
|
+
if (!c) return;
|
|
3564
|
+
const l = u.get(this.#e);
|
|
3565
|
+
if (l) {
|
|
3566
|
+
const d = u.get(c.timestamp), f = u.get(l.timestamp);
|
|
3567
|
+
if (!d || f && f > d + ui) return;
|
|
3568
|
+
}
|
|
3569
|
+
this.#e.set(c), c = void 0, u.close();
|
|
3570
|
+
});
|
|
3571
|
+
}
|
|
3572
|
+
#u(e) {
|
|
3573
|
+
const n = e.get(this.#e);
|
|
3574
|
+
if (!n) {
|
|
3575
|
+
this.#o.set([]);
|
|
3576
|
+
return;
|
|
3577
|
+
}
|
|
3578
|
+
e.cleanup(() => n.close()), e.run((s) => {
|
|
3579
|
+
const i = s.get(n.frame);
|
|
3580
|
+
this.#t.update((r) => (r?.close(), i?.clone()));
|
|
3581
|
+
}), e.proxy(this.#n, n.timestamp), e.proxy(this.#o, n.buffered);
|
|
3582
|
+
}
|
|
3583
|
+
#d(e) {
|
|
3584
|
+
const n = e.get(this.source.catalog);
|
|
3585
|
+
if (!n) return;
|
|
3586
|
+
const s = n.display;
|
|
3587
|
+
if (s) {
|
|
3588
|
+
e.set(this.#s, {
|
|
3589
|
+
width: s.width,
|
|
3590
|
+
height: s.height
|
|
3591
|
+
});
|
|
3592
|
+
return;
|
|
3593
|
+
}
|
|
3594
|
+
const i = e.get(this.frame);
|
|
3595
|
+
i && e.set(this.#s, {
|
|
3596
|
+
width: i.displayWidth,
|
|
3597
|
+
height: i.displayHeight
|
|
3598
|
+
});
|
|
3599
|
+
}
|
|
3600
|
+
#l(e) {
|
|
3601
|
+
if (!e.get(this.enabled)) return;
|
|
3602
|
+
if (!e.get(this.frame)) {
|
|
3603
|
+
this.#i.set(!0);
|
|
3604
|
+
return;
|
|
3605
|
+
}
|
|
3606
|
+
this.#i.set(!1), e.timer(() => {
|
|
3607
|
+
this.#i.set(!0);
|
|
3608
|
+
}, ci);
|
|
3609
|
+
}
|
|
3610
|
+
close() {
|
|
3611
|
+
this.#t.update((e) => {
|
|
3612
|
+
e?.close();
|
|
3613
|
+
}), this.#a.close();
|
|
3614
|
+
}
|
|
3615
|
+
}
|
|
3616
|
+
class di {
|
|
3617
|
+
source;
|
|
3618
|
+
broadcast;
|
|
3619
|
+
track;
|
|
3620
|
+
config;
|
|
3621
|
+
stats;
|
|
3622
|
+
timestamp = new h(void 0);
|
|
3623
|
+
frame = new h(void 0);
|
|
3624
|
+
// Network jitter + decode buffer.
|
|
3625
|
+
buffered = new h([]);
|
|
3626
|
+
// Decoded frames waiting to be rendered.
|
|
3627
|
+
#e = new h([]);
|
|
3628
|
+
signals = new T();
|
|
3629
|
+
constructor(e) {
|
|
3630
|
+
const { codedWidth: n, codedHeight: s, ...i } = e.config;
|
|
3631
|
+
this.source = e.source, this.broadcast = e.broadcast, this.track = e.track, this.config = i, this.stats = e.stats, this.signals.run(this.#t.bind(this));
|
|
3632
|
+
}
|
|
3633
|
+
#t(e) {
|
|
3634
|
+
const n = this.broadcast.subscribe(this.track, J.video);
|
|
3635
|
+
e.cleanup(() => n.close());
|
|
3636
|
+
const s = new VideoDecoder({
|
|
3637
|
+
output: async (i) => {
|
|
3638
|
+
try {
|
|
3639
|
+
const r = m.Milli.fromMicro(i.timestamp);
|
|
3640
|
+
if (r < (this.timestamp.peek() ?? 0))
|
|
3641
|
+
return;
|
|
3642
|
+
this.frame.peek() === void 0 && this.frame.set(i.clone());
|
|
3643
|
+
const o = this.source.sync.wait(r).then(() => !0);
|
|
3644
|
+
if (!await Promise.race([o, e.cancel]) || r < (this.timestamp.peek() ?? 0))
|
|
3645
|
+
return;
|
|
3646
|
+
this.timestamp.set(r), this.#r(r), this.frame.update((c) => (c?.close(), i.clone()));
|
|
3647
|
+
} finally {
|
|
3648
|
+
i.close();
|
|
3649
|
+
}
|
|
3650
|
+
},
|
|
3651
|
+
// TODO bubble up error
|
|
3652
|
+
error: (i) => {
|
|
3653
|
+
console.error(i), e.close();
|
|
3654
|
+
}
|
|
3655
|
+
});
|
|
3656
|
+
e.cleanup(() => {
|
|
3657
|
+
s.state !== "closed" && s.close();
|
|
3658
|
+
}), this.config.container.kind === "cmaf" ? this.#s(e, n, s) : this.#n(e, n, s);
|
|
3659
|
+
}
|
|
3660
|
+
#n(e, n, s) {
|
|
3661
|
+
const i = new te(n, {
|
|
3662
|
+
latency: this.source.sync.buffer
|
|
3663
|
+
});
|
|
3664
|
+
e.cleanup(() => i.close()), e.run((o) => {
|
|
3665
|
+
const a = o.get(i.buffered), c = o.get(this.#e);
|
|
3666
|
+
this.buffered.update(() => hi(a, c));
|
|
3667
|
+
}), s.configure({
|
|
3668
|
+
...this.config,
|
|
3669
|
+
description: this.config.description ? O(this.config.description) : void 0,
|
|
3670
|
+
optimizeForLatency: this.config.optimizeForLatency ?? !0,
|
|
3671
|
+
// @ts-expect-error Only supported by Chrome, so the renderer has to flip manually.
|
|
3672
|
+
flip: !1
|
|
3673
|
+
});
|
|
3674
|
+
let r;
|
|
3675
|
+
e.spawn(async () => {
|
|
3676
|
+
for (; ; ) {
|
|
3677
|
+
const o = await Promise.race([i.next(), e.cancel]);
|
|
3678
|
+
if (!o) break;
|
|
3679
|
+
const { frame: a, group: c } = o;
|
|
3680
|
+
if (!a) {
|
|
3681
|
+
r && (r.final = !0);
|
|
3682
|
+
continue;
|
|
3683
|
+
}
|
|
3684
|
+
const u = m.Milli.fromMicro(a.timestamp);
|
|
3685
|
+
this.source.sync.received(u, "video");
|
|
3686
|
+
const l = new EncodedVideoChunk({
|
|
3687
|
+
type: a.keyframe ? "key" : "delta",
|
|
3688
|
+
data: a.data,
|
|
3689
|
+
timestamp: a.timestamp
|
|
3690
|
+
});
|
|
3691
|
+
if (this.stats.update((d) => ({
|
|
3692
|
+
frameCount: (d?.frameCount ?? 0) + 1,
|
|
3693
|
+
bytesReceived: (d?.bytesReceived ?? 0) + a.data.byteLength
|
|
3694
|
+
})), r?.group === c || r?.final && r.group + 1 === c) {
|
|
3695
|
+
const d = m.Milli.fromMicro(r.timestamp), f = m.Milli.fromMicro(a.timestamp);
|
|
3696
|
+
this.#i(d, f);
|
|
3697
|
+
}
|
|
3698
|
+
r = {
|
|
3699
|
+
timestamp: a.timestamp,
|
|
3700
|
+
group: c,
|
|
3701
|
+
final: !1
|
|
3702
|
+
}, s.decode(l);
|
|
3703
|
+
}
|
|
3704
|
+
});
|
|
3705
|
+
}
|
|
3706
|
+
#s(e, n, s) {
|
|
3707
|
+
if (this.config.container.kind !== "cmaf") return;
|
|
3708
|
+
const { timescale: i } = this.config.container, r = this.config.description ? O(this.config.description) : void 0;
|
|
3709
|
+
s.configure({
|
|
3710
|
+
codec: this.config.codec,
|
|
3711
|
+
description: r,
|
|
3712
|
+
optimizeForLatency: this.config.optimizeForLatency ?? !0,
|
|
3713
|
+
// @ts-expect-error Only supported by Chrome, so the renderer has to flip manually.
|
|
3714
|
+
flip: !1
|
|
3715
|
+
}), e.run((o) => {
|
|
3716
|
+
const a = o.get(this.#e);
|
|
3717
|
+
this.buffered.update(() => a);
|
|
3718
|
+
}), e.spawn(async () => {
|
|
3719
|
+
for (; ; ) {
|
|
3720
|
+
const o = await Promise.race([n.nextGroup(), e.cancel]);
|
|
3721
|
+
if (!o) break;
|
|
3722
|
+
e.spawn(async () => {
|
|
3723
|
+
let a;
|
|
3724
|
+
try {
|
|
3725
|
+
for (; ; ) {
|
|
3726
|
+
const c = await Promise.race([o.readFrame(), e.cancel]);
|
|
3727
|
+
if (!c) break;
|
|
3728
|
+
const u = Tt(c, i);
|
|
3729
|
+
for (const l of u) {
|
|
3730
|
+
const d = new EncodedVideoChunk({
|
|
3731
|
+
type: l.keyframe ? "key" : "delta",
|
|
3732
|
+
data: l.data,
|
|
3733
|
+
timestamp: l.timestamp
|
|
3734
|
+
}), f = m.Milli.fromMicro(l.timestamp);
|
|
3735
|
+
if (this.source.sync.received(f, "video"), this.stats.update((g) => ({
|
|
3736
|
+
frameCount: (g?.frameCount ?? 0) + 1,
|
|
3737
|
+
bytesReceived: (g?.bytesReceived ?? 0) + l.data.byteLength
|
|
3738
|
+
})), a !== void 0) {
|
|
3739
|
+
const g = m.Milli.fromMicro(a), y = m.Milli.fromMicro(l.timestamp);
|
|
3740
|
+
this.#i(g, y);
|
|
3741
|
+
}
|
|
3742
|
+
a = l.timestamp, s.decode(d);
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
} finally {
|
|
3746
|
+
o.close();
|
|
3747
|
+
}
|
|
3748
|
+
});
|
|
3749
|
+
}
|
|
3750
|
+
});
|
|
3751
|
+
}
|
|
3752
|
+
// Add a range to the decode buffer (decoded, waiting to render)
|
|
3753
|
+
#i(e, n) {
|
|
3754
|
+
e > n || this.#e.mutate((s) => {
|
|
3755
|
+
for (const i of s)
|
|
3756
|
+
if (i.start <= n && i.end >= e) {
|
|
3757
|
+
i.start = m.Milli.min(i.start, e), i.end = m.Milli.max(i.end, n);
|
|
3758
|
+
return;
|
|
3759
|
+
}
|
|
3760
|
+
s.push({ start: e, end: n }), s.sort((i, r) => i.start - r.start);
|
|
3761
|
+
});
|
|
3762
|
+
}
|
|
3763
|
+
// Trim the decode buffer up to the rendered timestamp
|
|
3764
|
+
#r(e) {
|
|
3765
|
+
this.#e.mutate((n) => {
|
|
3766
|
+
for (; n.length > 0; ) {
|
|
3767
|
+
if (n[0].end >= e) {
|
|
3768
|
+
n[0].start = m.Milli.max(n[0].start, e);
|
|
3769
|
+
break;
|
|
3770
|
+
}
|
|
3771
|
+
n.shift();
|
|
3772
|
+
}
|
|
3773
|
+
});
|
|
3774
|
+
}
|
|
3775
|
+
close() {
|
|
3776
|
+
this.signals.close(), this.frame.update((e) => {
|
|
3777
|
+
e?.close();
|
|
3778
|
+
});
|
|
3779
|
+
}
|
|
3780
|
+
}
|
|
3781
|
+
function hi(t, e) {
|
|
3782
|
+
if (t.length === 0) return e;
|
|
3783
|
+
if (e.length === 0) return t;
|
|
3784
|
+
const n = [], s = [...t, ...e].sort((i, r) => i.start - r.start);
|
|
3785
|
+
for (const i of s) {
|
|
3786
|
+
const r = n.at(-1);
|
|
3787
|
+
r && r.end >= i.start ? r.end = m.Milli.max(r.end, i.end) : n.push({ ...i });
|
|
3788
|
+
}
|
|
3789
|
+
return n;
|
|
3790
|
+
}
|
|
3791
|
+
async function fi(t) {
|
|
3792
|
+
const e = t.description ? O(t.description) : void 0, { supported: n } = await VideoDecoder.isConfigSupported({
|
|
3793
|
+
codec: t.codec,
|
|
3794
|
+
description: e,
|
|
3795
|
+
optimizeForLatency: t.optimizeForLatency ?? !0
|
|
3796
|
+
});
|
|
3797
|
+
if (n) return !0;
|
|
3798
|
+
if (t.codec.startsWith("avc3.")) {
|
|
3799
|
+
const s = `avc1.${t.codec.slice(5)}`;
|
|
3800
|
+
if ((await VideoDecoder.isConfigSupported({
|
|
3801
|
+
codec: s,
|
|
3802
|
+
description: e,
|
|
3803
|
+
optimizeForLatency: t.optimizeForLatency ?? !0
|
|
3804
|
+
})).supported)
|
|
3805
|
+
return t.codec = s, !0;
|
|
3806
|
+
}
|
|
3807
|
+
return !1;
|
|
3808
|
+
}
|
|
3809
|
+
let mi = class {
|
|
3810
|
+
muxer;
|
|
3811
|
+
source;
|
|
3812
|
+
// TODO implement stats
|
|
3813
|
+
#e = new h(void 0);
|
|
3814
|
+
stats = this.#e;
|
|
3815
|
+
#t = new h([]);
|
|
3816
|
+
buffered = this.#t;
|
|
3817
|
+
#n = new h(!1);
|
|
3818
|
+
stalled = this.#n;
|
|
3819
|
+
#s = new h(M.Time.Milli.zero);
|
|
3820
|
+
timestamp = this.#s;
|
|
3821
|
+
signals = new T();
|
|
3822
|
+
constructor(e, n) {
|
|
3823
|
+
this.muxer = e, this.source = n, this.source.supported.set(pi), this.signals.run(this.#i.bind(this)), this.signals.run(this.#c.bind(this)), this.signals.run(this.#u.bind(this));
|
|
3824
|
+
}
|
|
3825
|
+
#i(e) {
|
|
3826
|
+
const n = e.get(this.muxer.element);
|
|
3827
|
+
if (!n) return;
|
|
3828
|
+
const s = e.get(this.muxer.mediaSource);
|
|
3829
|
+
if (!s) return;
|
|
3830
|
+
const i = e.get(this.source.broadcast);
|
|
3831
|
+
if (!i) return;
|
|
3832
|
+
const r = e.get(i.active);
|
|
3833
|
+
if (!r) return;
|
|
3834
|
+
const o = e.get(this.source.track);
|
|
3835
|
+
if (!o) return;
|
|
3836
|
+
const a = e.get(this.source.config);
|
|
3837
|
+
if (!a) return;
|
|
3838
|
+
const c = `video/mp4; codecs="${a.codec}"`, u = s.addSourceBuffer(c);
|
|
3839
|
+
e.cleanup(() => {
|
|
3840
|
+
s.removeSourceBuffer(u), u.abort();
|
|
3841
|
+
}), e.event(u, "error", (l) => {
|
|
3842
|
+
console.error("[MSE] SourceBuffer error:", l);
|
|
3843
|
+
}), e.event(u, "updateend", () => {
|
|
3844
|
+
this.#t.set(Ct(u.buffered));
|
|
3845
|
+
}), a.container.kind === "cmaf" ? this.#o(e, r, o, a, u, n) : this.#a(e, r, o, a, u, n);
|
|
3846
|
+
}
|
|
3847
|
+
async #r(e, n) {
|
|
3848
|
+
for (; e.updating; )
|
|
3849
|
+
await new Promise((s) => e.addEventListener("updateend", s, { once: !0 }));
|
|
3850
|
+
for (e.appendBuffer(n); e.updating; )
|
|
3851
|
+
await new Promise((s) => e.addEventListener("updateend", s, { once: !0 }));
|
|
3852
|
+
}
|
|
3853
|
+
#o(e, n, s, i, r, o) {
|
|
3854
|
+
if (i.container.kind !== "cmaf") throw new Error("unreachable");
|
|
3855
|
+
const a = n.subscribe(s, J.video);
|
|
3856
|
+
e.cleanup(() => a.close());
|
|
3857
|
+
const c = i.container.timescale;
|
|
3858
|
+
e.spawn(async () => {
|
|
3859
|
+
const u = qe(i);
|
|
3860
|
+
for (await this.#r(r, u); ; ) {
|
|
3861
|
+
const l = await a.readFrame();
|
|
3862
|
+
if (!l) return;
|
|
3863
|
+
const d = kt(l, c);
|
|
3864
|
+
this.source.sync.received(M.Time.Milli.fromMicro(d), "video"), await this.#r(r, l), o.buffered.length > 0 && o.currentTime < o.buffered.start(0) && (o.currentTime = o.buffered.start(0));
|
|
3865
|
+
}
|
|
3866
|
+
});
|
|
3867
|
+
}
|
|
3868
|
+
#a(e, n, s, i, r, o) {
|
|
3869
|
+
const a = n.subscribe(s, J.video);
|
|
3870
|
+
e.cleanup(() => a.close());
|
|
3871
|
+
const c = new te(a, {
|
|
3872
|
+
latency: this.source.sync.buffer
|
|
3873
|
+
});
|
|
3874
|
+
e.cleanup(() => c.close()), e.spawn(async () => {
|
|
3875
|
+
const u = qe(i);
|
|
3876
|
+
await this.#r(r, u);
|
|
3877
|
+
let l = 1, d, f;
|
|
3878
|
+
for (; ; ) {
|
|
3879
|
+
const g = await c.next();
|
|
3880
|
+
if (!g) return;
|
|
3881
|
+
if (!g.frame) continue;
|
|
3882
|
+
f = g.frame;
|
|
3883
|
+
const y = M.Time.Milli.fromMicro(f.timestamp);
|
|
3884
|
+
this.source.sync.received(y, "video");
|
|
3885
|
+
break;
|
|
3886
|
+
}
|
|
3887
|
+
for (; ; ) {
|
|
3888
|
+
const g = await c.next();
|
|
3889
|
+
if (g && !g.frame) continue;
|
|
3890
|
+
const y = g?.frame;
|
|
3891
|
+
if (y) {
|
|
3892
|
+
d = M.Time.Micro.sub(y.timestamp, f.timestamp);
|
|
3893
|
+
const S = M.Time.Milli.fromMicro(y.timestamp);
|
|
3894
|
+
this.source.sync.received(S, "video");
|
|
3895
|
+
}
|
|
3896
|
+
const b = Bt({
|
|
3897
|
+
data: f.data,
|
|
3898
|
+
timestamp: f.timestamp,
|
|
3899
|
+
duration: d ?? 0,
|
|
3900
|
+
// Default to 0 duration if there's literally one frame then stream FIN.
|
|
3901
|
+
keyframe: f.keyframe,
|
|
3902
|
+
sequence: l++
|
|
3903
|
+
});
|
|
3904
|
+
if (await this.#r(r, b), o.buffered.length > 0 && o.currentTime < o.buffered.start(0) && (o.currentTime = o.buffered.start(0)), !y) return;
|
|
3905
|
+
f = y;
|
|
3906
|
+
}
|
|
3907
|
+
});
|
|
3908
|
+
}
|
|
3909
|
+
#c(e) {
|
|
3910
|
+
const n = e.get(this.muxer.element);
|
|
3911
|
+
if (!n) return;
|
|
3912
|
+
const s = () => {
|
|
3913
|
+
this.#n.set(n.readyState <= HTMLMediaElement.HAVE_CURRENT_DATA);
|
|
3914
|
+
};
|
|
3915
|
+
s(), e.event(n, "waiting", s), e.event(n, "playing", s), e.event(n, "seeking", s);
|
|
3916
|
+
}
|
|
3917
|
+
#u(e) {
|
|
3918
|
+
const n = e.get(this.muxer.element);
|
|
3919
|
+
if (n)
|
|
3920
|
+
if ("requestVideoFrameCallback" in n) {
|
|
3921
|
+
const s = n;
|
|
3922
|
+
let i;
|
|
3923
|
+
const r = () => {
|
|
3924
|
+
const o = M.Time.Milli.fromSecond(s.currentTime);
|
|
3925
|
+
this.#s.set(o), i = s.requestVideoFrameCallback(r);
|
|
3926
|
+
};
|
|
3927
|
+
i = s.requestVideoFrameCallback(r), e.cleanup(() => s.cancelVideoFrameCallback(i));
|
|
3928
|
+
} else
|
|
3929
|
+
e.event(n, "timeupdate", () => {
|
|
3930
|
+
const s = M.Time.Milli.fromSecond(n.currentTime);
|
|
3931
|
+
this.#s.set(s);
|
|
3932
|
+
});
|
|
3933
|
+
}
|
|
3934
|
+
close() {
|
|
3935
|
+
this.source.close(), this.signals.close();
|
|
3936
|
+
}
|
|
3937
|
+
};
|
|
3938
|
+
async function pi(t) {
|
|
3939
|
+
return MediaSource.isTypeSupported(`video/mp4; codecs="${t.codec}"`);
|
|
3940
|
+
}
|
|
3941
|
+
class gi {
|
|
3942
|
+
decoder;
|
|
3943
|
+
// The canvas to render the video to.
|
|
3944
|
+
canvas;
|
|
3945
|
+
// Whether the video is paused.
|
|
3946
|
+
paused;
|
|
3947
|
+
// The most recently rendered frame, updated after each rAF paint.
|
|
3948
|
+
frame = new h(void 0);
|
|
3949
|
+
// The media timestamp of the most recently rendered frame.
|
|
3950
|
+
timestamp = new h(void 0);
|
|
3951
|
+
#e = new h(void 0);
|
|
3952
|
+
#t = new h(!1);
|
|
3953
|
+
#n = new T();
|
|
3954
|
+
constructor(e, n) {
|
|
3955
|
+
this.decoder = e, this.canvas = h.from(n?.canvas), this.paused = h.from(n?.paused ?? !1), this.#n.run((s) => {
|
|
3956
|
+
const i = s.get(this.canvas);
|
|
3957
|
+
this.#e.set(i?.getContext("2d") ?? void 0);
|
|
3958
|
+
}), this.#n.run(this.#i.bind(this)), this.#n.run(this.#r.bind(this)), this.#n.run(this.#o.bind(this)), this.#n.run(this.#s.bind(this));
|
|
3959
|
+
}
|
|
3960
|
+
#s(e) {
|
|
3961
|
+
const n = e.getAll([this.canvas, this.decoder.display]);
|
|
3962
|
+
if (!n) return;
|
|
3963
|
+
const [s, i] = n;
|
|
3964
|
+
(s.width !== i.width || s.height !== i.height) && (s.width = i.width, s.height = i.height);
|
|
3965
|
+
}
|
|
3966
|
+
// Track whether the canvas is visible in the viewport and the tab is focused.
|
|
3967
|
+
#i(e) {
|
|
3968
|
+
const n = e.get(this.canvas);
|
|
3969
|
+
if (!n) {
|
|
3970
|
+
this.#t.set(!1);
|
|
3971
|
+
return;
|
|
3972
|
+
}
|
|
3973
|
+
let s = !1;
|
|
3974
|
+
const i = () => {
|
|
3975
|
+
this.#t.set(s && !document.hidden);
|
|
3976
|
+
}, r = new IntersectionObserver(
|
|
3977
|
+
(o) => {
|
|
3978
|
+
for (const a of o)
|
|
3979
|
+
s = a.isIntersecting, i();
|
|
3980
|
+
},
|
|
3981
|
+
{ threshold: 0.01 }
|
|
3982
|
+
);
|
|
3983
|
+
e.event(document, "visibilitychange", i), r.observe(n), e.cleanup(() => r.disconnect()), e.cleanup(() => this.#t.set(!1));
|
|
3984
|
+
}
|
|
3985
|
+
// Detect when video should be downloaded.
|
|
3986
|
+
#r(e) {
|
|
3987
|
+
const n = e.get(this.paused), s = e.get(this.#t);
|
|
3988
|
+
if (e.cleanup(() => this.decoder.enabled.set(!1)), !n) {
|
|
3989
|
+
this.decoder.enabled.set(s);
|
|
3990
|
+
return;
|
|
3991
|
+
}
|
|
3992
|
+
const i = e.get(this.frame);
|
|
3993
|
+
this.decoder.enabled.set(!i);
|
|
3994
|
+
}
|
|
3995
|
+
#o(e) {
|
|
3996
|
+
const n = e.get(this.#e);
|
|
3997
|
+
if (!n) return;
|
|
3998
|
+
const s = e.get(this.paused);
|
|
3999
|
+
let i;
|
|
4000
|
+
s || (i = e.get(this.decoder.frame));
|
|
4001
|
+
let r = requestAnimationFrame(() => {
|
|
4002
|
+
const o = i ?? this.frame.peek();
|
|
4003
|
+
this.#a(n, o), i && (this.frame.update((a) => (a?.close(), i.clone())), this.timestamp.set(m.Milli.fromMicro(i.timestamp))), r = void 0;
|
|
4004
|
+
});
|
|
4005
|
+
e.cleanup(() => {
|
|
4006
|
+
i?.close(), r && cancelAnimationFrame(r);
|
|
4007
|
+
});
|
|
4008
|
+
}
|
|
4009
|
+
#a(e, n) {
|
|
4010
|
+
if (!n) {
|
|
4011
|
+
e.fillStyle = "#000", e.fillRect(0, 0, e.canvas.width, e.canvas.height);
|
|
4012
|
+
return;
|
|
4013
|
+
}
|
|
4014
|
+
e.save(), e.fillStyle = "#000", e.fillRect(0, 0, e.canvas.width, e.canvas.height), this.decoder.source.catalog.peek()?.flip && (e.scale(-1, 1), e.translate(-e.canvas.width, 0)), e.drawImage(n, 0, 0, e.canvas.width, e.canvas.height), e.restore();
|
|
4015
|
+
}
|
|
4016
|
+
// Close the track and all associated resources.
|
|
4017
|
+
close() {
|
|
4018
|
+
this.frame.update((e) => {
|
|
4019
|
+
e?.close();
|
|
4020
|
+
}), this.#n.close();
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
function wi(t) {
|
|
4024
|
+
return (e) => {
|
|
4025
|
+
const n = [], s = [];
|
|
4026
|
+
for (const [i, r] of e)
|
|
4027
|
+
if (r.codedWidth && r.codedHeight) {
|
|
4028
|
+
const o = r.codedWidth * r.codedHeight;
|
|
4029
|
+
o <= t ? n.push({ name: i, size: o }) : s.push({ name: i, size: o });
|
|
4030
|
+
}
|
|
4031
|
+
return n.sort((i, r) => r.size - i.size), n.length > 0 ? n.map((i) => i.name) : s.length > 0 ? (s.sort((i, r) => i.size - r.size), [s[0].name]) : e.map(([i]) => i);
|
|
4032
|
+
};
|
|
4033
|
+
}
|
|
4034
|
+
function yi(t) {
|
|
4035
|
+
return (e) => {
|
|
4036
|
+
const n = [], s = [];
|
|
4037
|
+
for (const [i, r] of e)
|
|
4038
|
+
r.bitrate != null && r.bitrate <= t ? n.push({ name: i, bitrate: r.bitrate }) : r.bitrate != null && s.push({ name: i, bitrate: r.bitrate });
|
|
4039
|
+
return n.sort((i, r) => r.bitrate - i.bitrate), n.length > 0 ? n.map((i) => i.name) : s.length > 0 ? (s.sort((i, r) => i.bitrate - r.bitrate), [s[0].name]) : e.map(([i]) => i);
|
|
4040
|
+
};
|
|
4041
|
+
}
|
|
4042
|
+
function bi(t) {
|
|
4043
|
+
let e = t[0];
|
|
4044
|
+
for (const n of t) {
|
|
4045
|
+
const [, s] = n, [, i] = e, r = (s.codedWidth ?? 0) * (s.codedHeight ?? 0), o = (i.codedWidth ?? 0) * (i.codedHeight ?? 0);
|
|
4046
|
+
if (r !== o) {
|
|
4047
|
+
r > o && (e = n);
|
|
4048
|
+
continue;
|
|
4049
|
+
}
|
|
4050
|
+
(s.bitrate ?? 0) > (i.bitrate ?? 0) && (e = n);
|
|
4051
|
+
}
|
|
4052
|
+
return e[0];
|
|
4053
|
+
}
|
|
4054
|
+
let vi = class {
|
|
4055
|
+
broadcast;
|
|
4056
|
+
target;
|
|
4057
|
+
#e = new h(void 0);
|
|
4058
|
+
catalog = this.#e;
|
|
4059
|
+
#t = new h({});
|
|
4060
|
+
available = this.#t;
|
|
4061
|
+
// The name of the active rendition.
|
|
4062
|
+
#n = new h(void 0);
|
|
4063
|
+
track = this.#n;
|
|
4064
|
+
#s = new h(void 0);
|
|
4065
|
+
config = this.#s;
|
|
4066
|
+
sync;
|
|
4067
|
+
supported;
|
|
4068
|
+
#i = new T();
|
|
4069
|
+
constructor(e, n) {
|
|
4070
|
+
this.broadcast = h.from(n?.broadcast), this.target = h.from(n?.target), this.sync = e, this.supported = h.from(n?.supported), this.#i.run(this.#r.bind(this)), this.#i.run(this.#o.bind(this)), this.#i.run(this.#a.bind(this));
|
|
4071
|
+
}
|
|
4072
|
+
#r(e) {
|
|
4073
|
+
const n = e.get(this.broadcast);
|
|
4074
|
+
if (!n) return;
|
|
4075
|
+
const s = e.get(n.catalog)?.video;
|
|
4076
|
+
s && e.set(this.#e, s);
|
|
4077
|
+
}
|
|
4078
|
+
#o(e) {
|
|
4079
|
+
const n = e.get(this.supported);
|
|
4080
|
+
if (!n) return;
|
|
4081
|
+
const s = e.get(this.#e)?.renditions ?? {};
|
|
4082
|
+
e.spawn(async () => {
|
|
4083
|
+
const i = {};
|
|
4084
|
+
for (const [r, o] of Object.entries(s))
|
|
4085
|
+
await n(o) && (i[r] = o);
|
|
4086
|
+
Object.keys(i).length === 0 && Object.keys(s).length > 0 && console.warn("[Source] No supported video renditions found:", s), this.#t.set(i);
|
|
4087
|
+
});
|
|
4088
|
+
}
|
|
4089
|
+
#a(e) {
|
|
4090
|
+
const n = e.get(this.#t);
|
|
4091
|
+
if (Object.keys(n).length === 0) return;
|
|
4092
|
+
const s = e.get(this.target);
|
|
4093
|
+
if (s?.name && s.name in n) {
|
|
4094
|
+
const c = n[s.name];
|
|
4095
|
+
e.set(this.#n, s.name), e.set(this.#s, c), e.set(this.sync.video, c.jitter);
|
|
4096
|
+
return;
|
|
4097
|
+
}
|
|
4098
|
+
let i = s;
|
|
4099
|
+
if (!s?.bitrate) {
|
|
4100
|
+
const c = e.get(this.broadcast), l = (c ? e.get(c.connection) : void 0)?.recvBandwidth;
|
|
4101
|
+
if (l) {
|
|
4102
|
+
const d = e.get(l);
|
|
4103
|
+
if (d != null) {
|
|
4104
|
+
const f = Math.round(d * 0.8);
|
|
4105
|
+
i = { ...s, bitrate: f };
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
4108
|
+
}
|
|
4109
|
+
const r = this.#c(n, i);
|
|
4110
|
+
if (!r) return;
|
|
4111
|
+
const o = n[r];
|
|
4112
|
+
e.set(this.#n, r), e.set(this.#s, o);
|
|
4113
|
+
const a = o.jitter ?? (o.framerate ? Math.ceil(1e3 / o.framerate) : void 0);
|
|
4114
|
+
e.set(this.sync.video, a);
|
|
4115
|
+
}
|
|
4116
|
+
/**
|
|
4117
|
+
* Select the best rendition using a generic filter system.
|
|
4118
|
+
*
|
|
4119
|
+
* Each enabled filter returns matching renditions sorted by preference.
|
|
4120
|
+
* The first rendition present in every filter's output is selected.
|
|
4121
|
+
* If no rendition satisfies all filters, a warning is logged.
|
|
4122
|
+
*/
|
|
4123
|
+
#c(e, n) {
|
|
4124
|
+
const s = Object.entries(e);
|
|
4125
|
+
if (s.length === 0) return;
|
|
4126
|
+
if (s.length === 1) return s[0][0];
|
|
4127
|
+
const i = [];
|
|
4128
|
+
if (n?.pixels != null && i.push(wi(n.pixels)), n?.bitrate != null && i.push(yi(n.bitrate)), i.length === 0)
|
|
4129
|
+
return bi(s);
|
|
4130
|
+
const r = i.map((a) => a(s)), o = r.map((a) => new Set(a));
|
|
4131
|
+
for (const a of r[0])
|
|
4132
|
+
if (o.every((c) => c.has(a)))
|
|
4133
|
+
return a;
|
|
4134
|
+
console.warn("conflicting rendition filters, no rendition satisfies all criteria");
|
|
4135
|
+
}
|
|
4136
|
+
close() {
|
|
4137
|
+
this.#i.close();
|
|
4138
|
+
}
|
|
4139
|
+
};
|
|
4140
|
+
function Ct(t) {
|
|
4141
|
+
const e = [];
|
|
4142
|
+
for (let n = 0; n < t.length; n++) {
|
|
4143
|
+
const s = M.Time.Milli.fromSecond(t.start(n)), i = M.Time.Milli.fromSecond(t.end(n));
|
|
4144
|
+
e.push({ start: s, end: i });
|
|
4145
|
+
}
|
|
4146
|
+
return e;
|
|
4147
|
+
}
|
|
4148
|
+
class Si {
|
|
4149
|
+
// The source of the video.
|
|
4150
|
+
source;
|
|
4151
|
+
// The stats of the video.
|
|
4152
|
+
stats = new h(void 0);
|
|
4153
|
+
// We're currently stalled waiting for the next frame
|
|
4154
|
+
stalled = new h(!1);
|
|
4155
|
+
// Buffered time ranges
|
|
4156
|
+
buffered = new h([]);
|
|
4157
|
+
// The timestamp of the current frame
|
|
4158
|
+
timestamp = new h(M.Time.Milli.zero);
|
|
4159
|
+
constructor(e) {
|
|
4160
|
+
this.source = e;
|
|
4161
|
+
}
|
|
4162
|
+
}
|
|
4163
|
+
class Mi {
|
|
4164
|
+
source;
|
|
4165
|
+
// The volume of the audio, between 0 and 1.
|
|
4166
|
+
volume = new h(0.5);
|
|
4167
|
+
// Whether the audio is muted.
|
|
4168
|
+
muted = new h(!1);
|
|
4169
|
+
// The stats of the audio.
|
|
4170
|
+
stats = new h(void 0);
|
|
4171
|
+
// Buffered time ranges
|
|
4172
|
+
buffered = new h([]);
|
|
4173
|
+
constructor(e) {
|
|
4174
|
+
this.source = e;
|
|
4175
|
+
}
|
|
4176
|
+
}
|
|
4177
|
+
class Li {
|
|
4178
|
+
element = new h(void 0);
|
|
4179
|
+
broadcast;
|
|
4180
|
+
latency;
|
|
4181
|
+
jitter;
|
|
4182
|
+
paused;
|
|
4183
|
+
video;
|
|
4184
|
+
#e;
|
|
4185
|
+
audio;
|
|
4186
|
+
#t;
|
|
4187
|
+
// Used to sync audio and video playback at a target delay.
|
|
4188
|
+
sync;
|
|
4189
|
+
signals = new T();
|
|
4190
|
+
constructor(e) {
|
|
4191
|
+
this.element = h.from(e?.element), this.broadcast = h.from(e?.broadcast), this.sync = new Ue({ latency: e?.latency, rtt: e?.rtt }), this.latency = this.sync.latency, this.jitter = this.sync.jitter, this.#e = new vi(this.sync, {
|
|
4192
|
+
broadcast: this.broadcast
|
|
4193
|
+
}), this.#t = new ki(this.sync, {
|
|
4194
|
+
broadcast: this.broadcast
|
|
4195
|
+
}), this.video = new Si(this.#e), this.audio = new Mi(this.#t), this.paused = h.from(e?.paused ?? !1), this.signals.run(this.#n.bind(this));
|
|
4196
|
+
}
|
|
4197
|
+
#n(e) {
|
|
4198
|
+
const n = e.get(this.element);
|
|
4199
|
+
n && (n instanceof HTMLCanvasElement ? this.#s(e, n) : n instanceof HTMLVideoElement && this.#i(e, n));
|
|
4200
|
+
}
|
|
4201
|
+
#s(e, n) {
|
|
4202
|
+
const s = new li(this.#e), i = new si(this.#t), r = new oi(i, {
|
|
4203
|
+
volume: this.audio.volume,
|
|
4204
|
+
muted: this.audio.muted,
|
|
4205
|
+
paused: this.paused
|
|
4206
|
+
}), o = new gi(s, { canvas: n, paused: this.paused });
|
|
4207
|
+
e.cleanup(() => {
|
|
4208
|
+
s.close(), i.close(), r.close(), o.close();
|
|
4209
|
+
}), e.proxy(this.video.stats, s.stats), e.proxy(this.video.buffered, s.buffered), e.proxy(this.video.stalled, s.stalled), e.proxy(this.video.timestamp, s.timestamp), e.proxy(this.audio.stats, i.stats), e.proxy(this.audio.buffered, i.buffered);
|
|
4210
|
+
}
|
|
4211
|
+
#i(e, n) {
|
|
4212
|
+
const s = new It(this.sync, {
|
|
4213
|
+
paused: this.paused,
|
|
4214
|
+
element: n
|
|
4215
|
+
}), i = new mi(s, this.#e), r = new _i(s, this.#t, {
|
|
4216
|
+
volume: this.audio.volume,
|
|
4217
|
+
muted: this.audio.muted
|
|
4218
|
+
});
|
|
4219
|
+
e.cleanup(() => {
|
|
4220
|
+
i.close(), r.close(), s.close();
|
|
4221
|
+
}), e.proxy(this.video.stats, i.stats), e.proxy(this.video.buffered, i.buffered), e.proxy(this.video.stalled, i.stalled), e.proxy(this.video.timestamp, i.timestamp), e.proxy(this.audio.stats, r.stats), e.proxy(this.audio.buffered, r.buffered);
|
|
4222
|
+
}
|
|
4223
|
+
close() {
|
|
4224
|
+
this.signals.close();
|
|
4225
|
+
}
|
|
4226
|
+
}
|
|
4227
|
+
class _i {
|
|
4228
|
+
muxer;
|
|
4229
|
+
source;
|
|
4230
|
+
volume;
|
|
4231
|
+
muted;
|
|
4232
|
+
#e = new h(void 0);
|
|
4233
|
+
stats = this.#e;
|
|
4234
|
+
#t = new h([]);
|
|
4235
|
+
buffered = this.#t;
|
|
4236
|
+
#n = new T();
|
|
4237
|
+
constructor(e, n, s) {
|
|
4238
|
+
this.muxer = e, this.source = n, this.source.supported.set(zi), this.volume = h.from(s?.volume ?? 0.5), this.muted = h.from(s?.muted ?? !1), this.#n.run(this.#s.bind(this)), this.#n.run(this.#a.bind(this));
|
|
4239
|
+
}
|
|
4240
|
+
#s(e) {
|
|
4241
|
+
const n = e.get(this.muxer.element);
|
|
4242
|
+
if (!n) return;
|
|
4243
|
+
const s = e.get(this.muxer.mediaSource);
|
|
4244
|
+
if (!s) return;
|
|
4245
|
+
const i = e.get(this.source.broadcast);
|
|
4246
|
+
if (!i) return;
|
|
4247
|
+
const r = e.get(i.active);
|
|
4248
|
+
if (!r) return;
|
|
4249
|
+
const o = e.get(this.source.track);
|
|
4250
|
+
if (!o) return;
|
|
4251
|
+
const a = e.get(this.source.config);
|
|
4252
|
+
if (!a) return;
|
|
4253
|
+
const c = `audio/mp4; codecs="${a.codec}"`, u = s.addSourceBuffer(c);
|
|
4254
|
+
e.cleanup(() => {
|
|
4255
|
+
s.removeSourceBuffer(u), u.abort();
|
|
4256
|
+
}), e.event(u, "error", (d) => {
|
|
4257
|
+
console.error("[MSE] SourceBuffer error:", d);
|
|
4258
|
+
}), e.event(u, "updateend", () => {
|
|
4259
|
+
this.#t.set(Ct(u.buffered));
|
|
4260
|
+
});
|
|
4261
|
+
const l = r.subscribe(o, J.audio);
|
|
4262
|
+
e.cleanup(() => l.close()), a.container.kind === "cmaf" ? this.#r(e, l, a, u, n) : this.#o(e, l, a, u, n);
|
|
4263
|
+
}
|
|
4264
|
+
async #i(e, n) {
|
|
4265
|
+
for (; e.updating; )
|
|
4266
|
+
await new Promise((s) => e.addEventListener("updateend", s, { once: !0 }));
|
|
4267
|
+
for (e.appendBuffer(n); e.updating; )
|
|
4268
|
+
await new Promise((s) => e.addEventListener("updateend", s, { once: !0 }));
|
|
4269
|
+
}
|
|
4270
|
+
#r(e, n, s, i, r) {
|
|
4271
|
+
if (s.container.kind !== "cmaf") throw new Error("unreachable");
|
|
4272
|
+
const o = s.container.timescale;
|
|
4273
|
+
e.spawn(async () => {
|
|
4274
|
+
const a = He(s);
|
|
4275
|
+
for (await this.#i(i, a); ; ) {
|
|
4276
|
+
const c = await n.readFrame();
|
|
4277
|
+
if (!c) return;
|
|
4278
|
+
const u = kt(c, o);
|
|
4279
|
+
this.source.sync.received(M.Time.Milli.fromMicro(u), "audio"), await this.#i(i, c), r.buffered.length > 0 && r.currentTime < r.buffered.start(0) && (r.currentTime = r.buffered.start(0));
|
|
4280
|
+
}
|
|
4281
|
+
});
|
|
4282
|
+
}
|
|
4283
|
+
#o(e, n, s, i, r) {
|
|
4284
|
+
const o = new te(n, {
|
|
4285
|
+
latency: this.source.sync.buffer
|
|
4286
|
+
});
|
|
4287
|
+
e.cleanup(() => o.close()), e.spawn(async () => {
|
|
4288
|
+
const a = He(s);
|
|
4289
|
+
await this.#i(i, a);
|
|
4290
|
+
let c = 1, u, l;
|
|
4291
|
+
for (; ; ) {
|
|
4292
|
+
const d = await o.next();
|
|
4293
|
+
if (!d) return;
|
|
4294
|
+
if (!d.frame) continue;
|
|
4295
|
+
l = d.frame;
|
|
4296
|
+
const f = M.Time.Milli.fromMicro(l.timestamp);
|
|
4297
|
+
this.source.sync.received(f, "audio");
|
|
4298
|
+
break;
|
|
4299
|
+
}
|
|
4300
|
+
for (; ; ) {
|
|
4301
|
+
const d = await o.next();
|
|
4302
|
+
if (d && !d.frame) continue;
|
|
4303
|
+
const f = d?.frame;
|
|
4304
|
+
if (f) {
|
|
4305
|
+
u = M.Time.Micro.sub(f.timestamp, l.timestamp);
|
|
4306
|
+
const y = M.Time.Milli.fromMicro(f.timestamp);
|
|
4307
|
+
this.source.sync.received(y, "audio");
|
|
4308
|
+
}
|
|
4309
|
+
const g = Bt({
|
|
4310
|
+
data: l.data,
|
|
4311
|
+
timestamp: l.timestamp,
|
|
4312
|
+
duration: u ?? 0,
|
|
4313
|
+
// Default to 0 duration if there's literally one frame then stream FIN.
|
|
4314
|
+
keyframe: l.keyframe,
|
|
4315
|
+
sequence: c++
|
|
4316
|
+
});
|
|
4317
|
+
if (await this.#i(i, g), r.buffered.length > 0 && r.currentTime < r.buffered.start(0) && (r.currentTime = r.buffered.start(0)), !f) return;
|
|
4318
|
+
l = f;
|
|
4319
|
+
}
|
|
4320
|
+
});
|
|
4321
|
+
}
|
|
4322
|
+
#a(e) {
|
|
4323
|
+
const n = e.get(this.muxer.element);
|
|
4324
|
+
if (!n) return;
|
|
4325
|
+
const s = e.get(this.volume), i = e.get(this.muted);
|
|
4326
|
+
i && !n.muted ? n.muted = !0 : !i && n.muted && (n.muted = !1), s !== n.volume && (n.volume = s), e.event(n, "volumechange", () => {
|
|
4327
|
+
this.volume.set(n.volume);
|
|
4328
|
+
});
|
|
4329
|
+
}
|
|
4330
|
+
close() {
|
|
4331
|
+
this.#n.close();
|
|
4332
|
+
}
|
|
4333
|
+
}
|
|
4334
|
+
async function zi(t) {
|
|
4335
|
+
return MediaSource.isTypeSupported(`audio/mp4; codecs="${t.codec}"`);
|
|
4336
|
+
}
|
|
4337
|
+
const Ai = 128;
|
|
4338
|
+
class ki {
|
|
4339
|
+
broadcast;
|
|
4340
|
+
target;
|
|
4341
|
+
#e = new h(void 0);
|
|
4342
|
+
catalog = this.#e;
|
|
4343
|
+
#t = new h({});
|
|
4344
|
+
available = this.#t;
|
|
4345
|
+
#n = new h(void 0);
|
|
4346
|
+
track = this.#n;
|
|
4347
|
+
#s = new h(void 0);
|
|
4348
|
+
config = this.#s;
|
|
4349
|
+
supported;
|
|
4350
|
+
// Used to target a latency and synchronize playback of video with audio.
|
|
4351
|
+
sync;
|
|
4352
|
+
#i = new T();
|
|
4353
|
+
constructor(e, n) {
|
|
4354
|
+
this.sync = e, this.broadcast = h.from(n?.broadcast), this.target = h.from(n?.target), this.supported = h.from(n?.supported), this.#i.run(this.#r.bind(this)), this.#i.run(this.#o.bind(this)), this.#i.run(this.#a.bind(this));
|
|
4355
|
+
}
|
|
4356
|
+
#r(e) {
|
|
4357
|
+
const n = e.get(this.broadcast);
|
|
4358
|
+
if (!n) return;
|
|
4359
|
+
const s = e.get(n.catalog)?.audio;
|
|
4360
|
+
s && e.set(this.#e, s);
|
|
4361
|
+
}
|
|
4362
|
+
#o(e) {
|
|
4363
|
+
const n = e.get(this.#e)?.renditions ?? {}, s = e.get(this.supported);
|
|
4364
|
+
s && e.spawn(async () => {
|
|
4365
|
+
const i = {};
|
|
4366
|
+
for (const [r, o] of Object.entries(n))
|
|
4367
|
+
await s(o) && (i[r] = o);
|
|
4368
|
+
Object.keys(i).length === 0 && Object.keys(n).length > 0 && console.warn("no supported audio renditions found:", n), this.#t.set(i);
|
|
4369
|
+
});
|
|
4370
|
+
}
|
|
4371
|
+
#a(e) {
|
|
4372
|
+
const n = e.get(this.#t);
|
|
4373
|
+
if (Object.keys(n).length === 0) return;
|
|
4374
|
+
const s = e.get(this.target);
|
|
4375
|
+
let i;
|
|
4376
|
+
if (s?.name && s.name in n)
|
|
4377
|
+
i = { track: s.name, config: n[s.name] };
|
|
4378
|
+
else if (i = this.#c(n), !i) return;
|
|
4379
|
+
e.set(this.#n, i.track), e.set(this.#s, i.config);
|
|
4380
|
+
const r = i.config.jitter ?? Ti(i.config) ?? 0, o = Math.ceil(Ai / i.config.sampleRate * 1e3), a = r + o;
|
|
4381
|
+
e.set(this.sync.audio, a);
|
|
4382
|
+
}
|
|
4383
|
+
/**
|
|
4384
|
+
* Select rendition based on the configured strategy.
|
|
4385
|
+
*/
|
|
4386
|
+
#c(e) {
|
|
4387
|
+
const n = Object.entries(e);
|
|
4388
|
+
if (n.length !== 0) {
|
|
4389
|
+
for (const [s, i] of n)
|
|
4390
|
+
if (i.container.kind === "legacy")
|
|
4391
|
+
return { track: s, config: i };
|
|
4392
|
+
for (const [s, i] of n)
|
|
4393
|
+
if (i.container.kind === "cmaf")
|
|
4394
|
+
return { track: s, config: i };
|
|
4395
|
+
}
|
|
4396
|
+
}
|
|
4397
|
+
close() {
|
|
4398
|
+
this.#i.close();
|
|
4399
|
+
}
|
|
4400
|
+
}
|
|
4401
|
+
function Ti(t) {
|
|
4402
|
+
if (t.codec.startsWith("opus"))
|
|
4403
|
+
return 20;
|
|
4404
|
+
if (t.codec.startsWith("mp4a"))
|
|
4405
|
+
return Math.ceil(1024 / t.sampleRate * 1e3);
|
|
4406
|
+
}
|
|
4407
|
+
class Oi {
|
|
4408
|
+
connection;
|
|
4409
|
+
enabled;
|
|
4410
|
+
name;
|
|
4411
|
+
status = new h("offline");
|
|
4412
|
+
reload;
|
|
4413
|
+
#e = new h(void 0);
|
|
4414
|
+
active = this.#e;
|
|
4415
|
+
#t = new h(void 0);
|
|
4416
|
+
catalog = this.#t;
|
|
4417
|
+
// All actively announced broadcast paths from the connection.
|
|
4418
|
+
#n;
|
|
4419
|
+
signals = new T();
|
|
4420
|
+
constructor(e) {
|
|
4421
|
+
this.connection = h.from(e?.connection), this.name = h.from(e?.name ?? $t.empty()), this.enabled = h.from(e?.enabled ?? !1), this.reload = h.from(e?.reload ?? !1), this.#n = e?.announced ?? new h(/* @__PURE__ */ new Set()), this.signals.run(this.#i.bind(this)), this.signals.run(this.#r.bind(this));
|
|
4422
|
+
}
|
|
4423
|
+
#s(e) {
|
|
4424
|
+
if (!e.get(this.reload)) return !0;
|
|
4425
|
+
const s = e.get(this.name);
|
|
4426
|
+
return e.get(this.#n).has(s);
|
|
4427
|
+
}
|
|
4428
|
+
#i(e) {
|
|
4429
|
+
if (!e.get(this.enabled) || !this.#s(e)) return;
|
|
4430
|
+
const s = e.get(this.connection);
|
|
4431
|
+
if (!s) return;
|
|
4432
|
+
const i = e.get(this.name), r = s.consume(i);
|
|
4433
|
+
e.cleanup(() => r.close()), e.set(this.#e, r, void 0);
|
|
4434
|
+
}
|
|
4435
|
+
#r(e) {
|
|
4436
|
+
const n = e.getAll([this.enabled, this.active]);
|
|
4437
|
+
if (!n) return;
|
|
4438
|
+
const [s, i] = n;
|
|
4439
|
+
this.status.set("loading");
|
|
4440
|
+
const r = i.subscribe("catalog.json", J.catalog);
|
|
4441
|
+
e.cleanup(() => r.close()), e.spawn(async () => {
|
|
4442
|
+
try {
|
|
4443
|
+
for (; ; ) {
|
|
4444
|
+
const o = await Promise.race([e.cancel, ss(r)]);
|
|
4445
|
+
if (!o) break;
|
|
4446
|
+
console.debug("received catalog", this.name.peek(), o), this.#t.set(o), this.status.set("live");
|
|
4447
|
+
}
|
|
4448
|
+
} catch (o) {
|
|
4449
|
+
console.warn("error fetching catalog", this.name.peek(), o);
|
|
4450
|
+
} finally {
|
|
4451
|
+
this.#t.set(void 0), this.status.set("offline");
|
|
4452
|
+
}
|
|
4453
|
+
});
|
|
4454
|
+
}
|
|
4455
|
+
close() {
|
|
4456
|
+
this.signals.close();
|
|
4457
|
+
}
|
|
4458
|
+
}
|
|
4459
|
+
export {
|
|
4460
|
+
Oi as B,
|
|
4461
|
+
li as D,
|
|
4462
|
+
oi as E,
|
|
4463
|
+
mi as M,
|
|
4464
|
+
J as P,
|
|
4465
|
+
gi as R,
|
|
4466
|
+
vi as S,
|
|
4467
|
+
p as a,
|
|
4468
|
+
ht as b,
|
|
4469
|
+
si as c,
|
|
4470
|
+
_i as d,
|
|
4471
|
+
ki as e,
|
|
4472
|
+
Ri as f,
|
|
4473
|
+
wt as g,
|
|
4474
|
+
Li as h,
|
|
4475
|
+
Ue as i,
|
|
4476
|
+
xi as m,
|
|
4477
|
+
_ as o,
|
|
4478
|
+
v as s,
|
|
4479
|
+
Ct as t
|
|
4480
|
+
};
|
|
4481
|
+
//# sourceMappingURL=broadcast-BMWX8K5V.js.map
|