@moq/watch 0.2.16 → 0.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -9
- package/backend.d.ts +2 -0
- package/backend.d.ts.map +1 -1
- package/{broadcast-CG8jZRfA.js → broadcast-80k1hgfM.js} +382 -353
- package/broadcast-80k1hgfM.js.map +1 -0
- package/broadcast.d.ts +30 -1
- package/broadcast.d.ts.map +1 -1
- package/element.d.ts +6 -2
- package/element.d.ts.map +1 -1
- package/element.js +23 -7
- package/element.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +5 -4
- package/package.json +6 -6
- package/video/renderer.d.ts +18 -0
- package/video/renderer.d.ts.map +1 -1
- package/broadcast-CG8jZRfA.js.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import * as e from "@moq/
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import * as c from "@moq/hang/
|
|
8
|
-
import * as l from "@moq/
|
|
1
|
+
import * as e from "@moq/json";
|
|
2
|
+
import * as t from "@moq/net";
|
|
3
|
+
import { Path as n, Time as r } from "@moq/net";
|
|
4
|
+
import { Effect as i, Signal as a } from "@moq/signals";
|
|
5
|
+
import * as o from "@moq/hang/catalog";
|
|
6
|
+
import { u53 as s } from "@moq/hang/catalog";
|
|
7
|
+
import * as c from "@moq/hang/container";
|
|
8
|
+
import * as l from "@moq/hang/util";
|
|
9
9
|
import * as u from "@moq/msf";
|
|
10
10
|
//#region \0rolldown/runtime.js
|
|
11
11
|
var d = Object.defineProperty, f = (e, t) => {
|
|
@@ -65,14 +65,14 @@ var C = class e {
|
|
|
65
65
|
}
|
|
66
66
|
insert(e, t) {
|
|
67
67
|
if (t.length !== this.channels) throw Error("wrong number of channels");
|
|
68
|
-
let
|
|
68
|
+
let n = Math.round(r.Second.fromMicro(e) * this.rate), i = t[0].length, a = 0, o = n + i | 0, s = Atomics.load(this.#e, h), c = s - n | 0;
|
|
69
69
|
if (c > 0) {
|
|
70
70
|
if (c >= i) return;
|
|
71
|
-
a = c,
|
|
71
|
+
a = c, n = n + c | 0;
|
|
72
72
|
}
|
|
73
73
|
let l = i - a;
|
|
74
74
|
(o - s | 0) > this.capacity && S(this.#e, h, o - this.capacity | 0);
|
|
75
|
-
let u = Atomics.load(this.#e, m), d =
|
|
75
|
+
let u = Atomics.load(this.#e, m), d = n - u | 0;
|
|
76
76
|
if (d > 0) {
|
|
77
77
|
let e = Math.min(d, this.capacity);
|
|
78
78
|
for (let t = 0; t < this.channels; t++) {
|
|
@@ -81,8 +81,8 @@ var C = class e {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
for (let e = 0; e < this.channels; e++) {
|
|
84
|
-
let
|
|
85
|
-
for (let e = 0; e < l; e++) i[x(
|
|
84
|
+
let r = t[e], i = this.#t[e];
|
|
85
|
+
for (let e = 0; e < l; e++) i[x(n + e | 0, this.capacity)] = r[a + e];
|
|
86
86
|
}
|
|
87
87
|
Atomics.store(this.#e, m, b(Atomics.load(this.#e, m), o));
|
|
88
88
|
let f = Atomics.load(this.#e, h), p = Atomics.load(this.#e, m), v = Atomics.load(this.#e, g);
|
|
@@ -119,7 +119,7 @@ var C = class e {
|
|
|
119
119
|
}
|
|
120
120
|
get timestamp() {
|
|
121
121
|
let e = Atomics.load(this.#e, h);
|
|
122
|
-
return
|
|
122
|
+
return r.Micro.fromSecond(e / this.rate);
|
|
123
123
|
}
|
|
124
124
|
get stalled() {
|
|
125
125
|
return Atomics.load(this.#e, _) === 1;
|
|
@@ -141,11 +141,11 @@ var te = class {
|
|
|
141
141
|
channels;
|
|
142
142
|
#e;
|
|
143
143
|
#t;
|
|
144
|
-
#n = new
|
|
144
|
+
#n = new a(0);
|
|
145
145
|
timestamp = this.#n;
|
|
146
|
-
#r = new
|
|
146
|
+
#r = new a(!0);
|
|
147
147
|
stalled = this.#r;
|
|
148
|
-
#i = new
|
|
148
|
+
#i = new i();
|
|
149
149
|
constructor(e, t, n, r) {
|
|
150
150
|
this.#e = e, this.channels = t, this.rate = n;
|
|
151
151
|
let i = y(t, Math.max(n, r * 2), n);
|
|
@@ -179,18 +179,18 @@ var te = class {
|
|
|
179
179
|
rate;
|
|
180
180
|
channels;
|
|
181
181
|
#e;
|
|
182
|
-
#t = new
|
|
182
|
+
#t = new a(0);
|
|
183
183
|
timestamp = this.#t;
|
|
184
|
-
#n = new
|
|
184
|
+
#n = new a(!0);
|
|
185
185
|
stalled = this.#n;
|
|
186
|
-
#r = new
|
|
187
|
-
constructor(e, t,
|
|
188
|
-
this.#e = e, this.channels = t, this.rate =
|
|
186
|
+
#r = new i();
|
|
187
|
+
constructor(e, t, n, i) {
|
|
188
|
+
this.#e = e, this.channels = t, this.rate = n;
|
|
189
189
|
let a = {
|
|
190
190
|
type: "init-post",
|
|
191
191
|
channels: t,
|
|
192
|
-
rate:
|
|
193
|
-
latency:
|
|
192
|
+
rate: n,
|
|
193
|
+
latency: r.Milli.fromSecond(i / n)
|
|
194
194
|
};
|
|
195
195
|
e.port.postMessage(a), this.#r.event(e.port, "message", (e) => {
|
|
196
196
|
let t = e.data;
|
|
@@ -208,7 +208,7 @@ var te = class {
|
|
|
208
208
|
setLatency(e) {
|
|
209
209
|
let t = {
|
|
210
210
|
type: "latency",
|
|
211
|
-
latency:
|
|
211
|
+
latency: r.Milli.fromSecond(e / this.rate)
|
|
212
212
|
};
|
|
213
213
|
this.#e.port.postMessage(t);
|
|
214
214
|
}
|
|
@@ -218,32 +218,32 @@ var te = class {
|
|
|
218
218
|
}, re = new Blob(["var __defProp = Object.defineProperty;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __esm = (fn, res) => function __init() {\n return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;\n};\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\n\n// ../net/src/path.ts\nvar init_path = __esm({\n \"../net/src/path.ts\"() {\n \"use strict\";\n }\n});\n\n// ../net/src/varint.ts\nvar MAX_U6, MAX_U14, MAX_U30, MAX_U53, MAX_U64, MAX_U62;\nvar init_varint = __esm({\n \"../net/src/varint.ts\"() {\n \"use strict\";\n MAX_U6 = 2 ** 6 - 1;\n MAX_U14 = 2 ** 14 - 1;\n MAX_U30 = 2 ** 30 - 1;\n MAX_U53 = Number.MAX_SAFE_INTEGER;\n MAX_U64 = (1n << 64n) - 1n;\n MAX_U62 = 2n ** 62n - 1n;\n }\n});\n\n// ../net/src/index.ts\ninit_path();\n\n// ../net/src/time.ts\nvar time_exports = {};\n__export(time_exports, {\n Micro: () => Micro,\n Milli: () => Milli,\n Nano: () => Nano,\n Second: () => Second\n});\nvar Nano = {\n zero: 0,\n fromMicro: (us) => us * 1e3,\n fromMilli: (ms) => ms * 1e6,\n fromSecond: (s) => s * 1e9,\n toMicro: (ns) => ns / 1e3,\n toMilli: (ns) => ns / 1e6,\n toSecond: (ns) => ns / 1e9,\n now: () => performance.now() * 1e6,\n add: (a, b) => a + b,\n sub: (a, b) => a - b,\n mul: (a, b) => a * b,\n div: (a, b) => a / b,\n max: (a, b) => Math.max(a, b),\n min: (a, b) => Math.min(a, b)\n};\nvar Micro = {\n zero: 0,\n fromNano: (ns) => ns / 1e3,\n fromMilli: (ms) => ms * 1e3,\n fromSecond: (s) => s * 1e6,\n toNano: (us) => us * 1e3,\n toMilli: (us) => us / 1e3,\n toSecond: (us) => us / 1e6,\n now: () => performance.now() * 1e3,\n add: (a, b) => a + b,\n sub: (a, b) => a - b,\n mul: (a, b) => a * b,\n div: (a, b) => a / b,\n max: (a, b) => Math.max(a, b),\n min: (a, b) => Math.min(a, b)\n};\nvar Milli = {\n zero: 0,\n fromNano: (ns) => ns / 1e6,\n fromMicro: (us) => us / 1e3,\n fromSecond: (s) => s * 1e3,\n toNano: (ms) => ms * 1e6,\n toMicro: (ms) => ms * 1e3,\n toSecond: (ms) => ms / 1e3,\n now: () => performance.now(),\n add: (a, b) => a + b,\n sub: (a, b) => a - b,\n mul: (a, b) => a * b,\n div: (a, b) => a / b,\n max: (a, b) => Math.max(a, b),\n min: (a, b) => Math.min(a, b)\n};\nvar Second = {\n zero: 0,\n fromNano: (ns) => ns / 1e9,\n fromMicro: (us) => us / 1e6,\n fromMilli: (ms) => ms / 1e3,\n toNano: (s) => s * 1e9,\n toMicro: (s) => s * 1e6,\n toMilli: (s) => s * 1e3,\n now: () => performance.now() / 1e3,\n add: (a, b) => a + b,\n sub: (a, b) => a - b,\n mul: (a, b) => a * b,\n div: (a, b) => a / b,\n max: (a, b) => Math.max(a, b),\n min: (a, b) => Math.min(a, b)\n};\n\n// ../net/src/index.ts\ninit_varint();\n\n// src/audio/ring-buffer.ts\nvar AudioRingBuffer = class {\n #buffer;\n #writeIndex = 0;\n #readIndex = 0;\n rate;\n channels;\n #stalled = true;\n constructor(props) {\n if (props.channels <= 0) throw new Error(\"invalid channels\");\n if (props.rate <= 0) throw new Error(\"invalid sample rate\");\n if (props.latency <= 0) throw new Error(\"invalid latency\");\n const samples = Math.ceil(props.rate * time_exports.Second.fromMilli(props.latency));\n if (samples === 0) throw new Error(\"empty buffer\");\n this.rate = props.rate;\n this.channels = props.channels;\n this.#buffer = [];\n for (let i = 0; i < this.channels; i++) {\n this.#buffer[i] = new Float32Array(samples);\n }\n }\n get stalled() {\n return this.#stalled;\n }\n get timestamp() {\n return time_exports.Micro.fromSecond(this.#readIndex / this.rate);\n }\n get length() {\n return this.#writeIndex - this.#readIndex;\n }\n get capacity() {\n return this.#buffer[0]?.length;\n }\n resize(latency) {\n const newCapacity = Math.ceil(this.rate * time_exports.Second.fromMilli(latency));\n if (newCapacity === this.capacity) return;\n if (newCapacity === 0) throw new Error(\"empty buffer\");\n const newBuffer = [];\n for (let i = 0; i < this.channels; i++) {\n newBuffer[i] = new Float32Array(newCapacity);\n }\n const samplesToKeep = Math.min(this.length, newCapacity);\n if (samplesToKeep > 0) {\n const copyStart = this.#writeIndex - samplesToKeep;\n for (let channel = 0; channel < this.channels; channel++) {\n const src = this.#buffer[channel];\n const dst = newBuffer[channel];\n for (let i = 0; i < samplesToKeep; i++) {\n const srcPos = (copyStart + i) % src.length;\n const dstPos = (copyStart + i) % dst.length;\n dst[dstPos] = src[srcPos];\n }\n }\n }\n this.#buffer = newBuffer;\n this.#readIndex = this.#writeIndex - samplesToKeep;\n if (samplesToKeep === 0) this.#stalled = true;\n }\n write(timestamp, data) {\n if (data.length !== this.channels) throw new Error(\"wrong number of channels\");\n let start = Math.round(time_exports.Second.fromMicro(timestamp) * this.rate);\n let samples = data[0].length;\n let offset = this.#readIndex - start;\n if (offset > samples) {\n return;\n } else if (offset > 0) {\n samples -= offset;\n start += offset;\n } else {\n offset = 0;\n }\n const end = start + samples;\n const overflow = end - this.#readIndex - this.#buffer[0].length;\n if (overflow >= 0) {\n this.#stalled = false;\n this.#readIndex += overflow;\n }\n if (start > this.#writeIndex) {\n const gapSize = Math.min(start - this.#writeIndex, this.#buffer[0].length);\n if (gapSize === 1) {\n console.warn(\"floating point inaccuracy detected\");\n }\n for (let channel = 0; channel < this.channels; channel++) {\n const dst = this.#buffer[channel];\n for (let i = 0; i < gapSize; i++) {\n const writePos = (this.#writeIndex + i) % dst.length;\n dst[writePos] = 0;\n }\n }\n }\n for (let channel = 0; channel < this.channels; channel++) {\n let src = data[channel];\n src = src.subarray(src.length - samples);\n const dst = this.#buffer[channel];\n if (src.length !== samples) throw new Error(\"mismatching number of samples\");\n for (let i = 0; i < samples; i++) {\n const writePos = (start + i) % dst.length;\n dst[writePos] = src[i];\n }\n }\n if (end > this.#writeIndex) {\n this.#writeIndex = end;\n }\n }\n read(output) {\n if (output.length !== this.channels) throw new Error(\"wrong number of channels\");\n if (this.#stalled) return 0;\n const samples = Math.min(this.#writeIndex - this.#readIndex, output[0].length);\n if (samples === 0) return 0;\n for (let channel = 0; channel < this.channels; channel++) {\n const dst = output[channel];\n const src = this.#buffer[channel];\n if (dst.length !== output[0].length) throw new Error(\"mismatching number of samples\");\n for (let i = 0; i < samples; i++) {\n const readPos = (this.#readIndex + i) % src.length;\n dst[i] = src[readPos];\n }\n }\n this.#readIndex += samples;\n return samples;\n }\n};\n\n// src/audio/shared-ring-buffer.ts\nvar WRITE = 0;\nvar READ = 1;\nvar LATENCY = 2;\nvar STALLED = 3;\nvar CONTROL_SLOTS = 4;\nfunction allocSharedRingBuffer(channels, capacity, rate) {\n if (channels <= 0) throw new Error(\"invalid channels\");\n if (capacity <= 0) throw new Error(\"invalid capacity\");\n if (rate <= 0) throw new Error(\"invalid sample rate\");\n const samples = new SharedArrayBuffer(channels * capacity * Float32Array.BYTES_PER_ELEMENT);\n const control = new SharedArrayBuffer(CONTROL_SLOTS * Int32Array.BYTES_PER_ELEMENT);\n const ctrl = new Int32Array(control);\n Atomics.store(ctrl, STALLED, 1);\n return { channels, capacity, rate, samples, control };\n}\nfunction i32Max(a, b) {\n return (a - b | 0) > 0 ? a : b;\n}\nfunction slot(idx, capacity) {\n return (idx % capacity + capacity) % capacity;\n}\nfunction casAdvance(arr, idx, candidate) {\n for (; ; ) {\n const current = Atomics.load(arr, idx);\n if ((candidate - current | 0) <= 0) return current;\n const witnessed = Atomics.compareExchange(arr, idx, current, candidate);\n if (witnessed === current) return candidate;\n }\n}\nvar SharedRingBuffer = class _SharedRingBuffer {\n channels;\n capacity;\n rate;\n init;\n #control;\n #samples;\n constructor(init) {\n this.channels = init.channels;\n this.capacity = init.capacity;\n this.rate = init.rate;\n this.init = init;\n this.#control = new Int32Array(init.control);\n this.#samples = [];\n for (let i = 0; i < this.channels; i++) {\n this.#samples.push(\n new Float32Array(init.samples, i * this.capacity * Float32Array.BYTES_PER_ELEMENT, this.capacity)\n );\n }\n }\n /**\n * Insert audio samples at the given timestamp.\n * Main thread only. Handles out-of-order writes, gap filling, and overflow.\n */\n insert(timestamp, data) {\n if (data.length !== this.channels) throw new Error(\"wrong number of channels\");\n let start = Math.round(time_exports.Second.fromMicro(timestamp) * this.rate);\n const originalLength = data[0].length;\n let offset = 0;\n const end = start + originalLength | 0;\n const read = Atomics.load(this.#control, READ);\n const behind = read - start | 0;\n if (behind > 0) {\n if (behind >= originalLength) {\n return;\n }\n offset = behind;\n start = start + behind | 0;\n }\n const samples = originalLength - offset;\n if ((end - read | 0) > this.capacity) {\n casAdvance(this.#control, READ, end - this.capacity | 0);\n }\n const write = Atomics.load(this.#control, WRITE);\n const gap = start - write | 0;\n if (gap > 0) {\n const gapSize = Math.min(gap, this.capacity);\n for (let channel = 0; channel < this.channels; channel++) {\n const dst = this.#samples[channel];\n for (let i = 0; i < gapSize; i++) {\n dst[slot(write + i | 0, this.capacity)] = 0;\n }\n }\n }\n for (let channel = 0; channel < this.channels; channel++) {\n const src = data[channel];\n const dst = this.#samples[channel];\n for (let i = 0; i < samples; i++) {\n dst[slot(start + i | 0, this.capacity)] = src[offset + i];\n }\n }\n Atomics.store(this.#control, WRITE, i32Max(Atomics.load(this.#control, WRITE), end));\n const currentRead = Atomics.load(this.#control, READ);\n const currentWrite = Atomics.load(this.#control, WRITE);\n const latency = Atomics.load(this.#control, LATENCY);\n if ((currentWrite - currentRead | 0) >= latency && latency > 0) {\n Atomics.store(this.#control, STALLED, 0);\n }\n }\n /**\n * Read audio samples into the output buffers.\n * AudioWorklet only. Returns the number of samples read.\n */\n read(output) {\n if (Atomics.load(this.#control, STALLED) === 1) return 0;\n let read = Atomics.load(this.#control, READ);\n const write = Atomics.load(this.#control, WRITE);\n const latency = Atomics.load(this.#control, LATENCY);\n const buffered = write - read | 0;\n if (latency > 0 && buffered > latency) {\n const skipTo = write - latency | 0;\n read = casAdvance(this.#control, READ, skipTo);\n }\n const available = write - read | 0;\n const count = Math.min(available, output[0].length);\n if (count <= 0) return 0;\n for (let channel = 0; channel < this.channels; channel++) {\n const src = this.#samples[channel];\n const dst = output[channel];\n for (let i = 0; i < count; i++) {\n dst[i] = src[slot(read + i | 0, this.capacity)];\n }\n }\n casAdvance(this.#control, READ, read + count | 0);\n return count;\n }\n /** Update the target latency in samples. */\n setLatency(samples) {\n Atomics.store(this.#control, LATENCY, samples);\n }\n /**\n * Allocate a new ring with `newCapacity` samples and copy the unread window\n * [READ, WRITE) plus control state into it. Used when growing capacity so\n * we don't drop buffered audio. If `newCapacity` is smaller than the unread\n * span, the oldest samples are truncated.\n *\n * Main thread only. `resize()` reads from the source `SharedRingBuffer` and\n * writes into a freshly allocated buffer from `allocSharedRingBuffer`, so it\n * relies on the same invariant as `insert()`: no concurrent main-thread\n * writers. The AudioWorklet reader is tolerated via the CAS discipline used\n * by READ/WRITE elsewhere.\n */\n resize(newCapacity) {\n const init = allocSharedRingBuffer(this.channels, newCapacity, this.rate);\n const dst = new _SharedRingBuffer(init);\n const read = Atomics.load(this.#control, READ);\n const write = Atomics.load(this.#control, WRITE);\n const latency = Atomics.load(this.#control, LATENCY);\n const stalled = Atomics.load(this.#control, STALLED);\n const available = write - read | 0;\n const copyCount = Math.max(0, Math.min(available, dst.capacity));\n const copyStart = write - copyCount | 0;\n for (let channel = 0; channel < this.channels; channel++) {\n const src = this.#samples[channel];\n const out = dst.#samples[channel];\n for (let i = 0; i < copyCount; i++) {\n const idx = copyStart + i | 0;\n out[slot(idx, dst.capacity)] = src[slot(idx, this.capacity)];\n }\n }\n Atomics.store(dst.#control, READ, copyStart);\n Atomics.store(dst.#control, WRITE, write);\n Atomics.store(dst.#control, LATENCY, latency);\n Atomics.store(dst.#control, STALLED, stalled);\n return dst;\n }\n /** Current playback timestamp derived from READ position. */\n get timestamp() {\n const read = Atomics.load(this.#control, READ);\n return time_exports.Micro.fromSecond(read / this.rate);\n }\n /** Whether the buffer is stalled (waiting to fill). */\n get stalled() {\n return Atomics.load(this.#control, STALLED) === 1;\n }\n /**\n * Number of buffered samples (WRITE - READ).\n *\n * Non-atomic: WRITE and READ are loaded separately, so a concurrent\n * writer/reader can make the two loads inconsistent. Intended for\n * tests and diagnostics, not control-flow decisions.\n */\n get length() {\n return Atomics.load(this.#control, WRITE) - Atomics.load(this.#control, READ) | 0;\n }\n};\n\n// src/audio/render-worklet.ts\nvar Render = class extends AudioWorkletProcessor {\n // Set after init, depending on which path the main thread chose.\n #backend;\n #underflow = 0;\n #stateCounter = 0;\n constructor() {\n super();\n this.port.onmessage = (event) => {\n const msg = event.data;\n if (msg.type === \"init-shared\") {\n console.log(\"[audio-worklet] init-shared: using SharedArrayBuffer path\");\n this.#backend = new SharedRingBuffer(msg);\n this.#underflow = 0;\n } else if (msg.type === \"init-post\") {\n console.log(\"[audio-worklet] init-post: using postMessage path\");\n this.#backend = new AudioRingBuffer(msg);\n this.#underflow = 0;\n } else if (msg.type === \"data\") {\n if (this.#backend instanceof AudioRingBuffer) this.#backend.write(msg.timestamp, msg.data);\n } else if (msg.type === \"latency\") {\n if (this.#backend instanceof AudioRingBuffer) this.#backend.resize(msg.latency);\n }\n };\n }\n process(_inputs, outputs, _parameters) {\n const output = outputs[0];\n const backend = this.#backend;\n const samplesRead = backend?.read(output) ?? 0;\n if (samplesRead < output[0].length) {\n this.#underflow += output[0].length - samplesRead;\n } else if (this.#underflow > 0 && backend) {\n console.debug(`audio underflow: ${Math.round(1e3 * this.#underflow / backend.rate)}ms`);\n this.#underflow = 0;\n }\n if (backend instanceof AudioRingBuffer) {\n this.#stateCounter++;\n if (this.#stateCounter >= 5) {\n this.#stateCounter = 0;\n const state = {\n type: \"state\",\n timestamp: backend.timestamp,\n stalled: backend.stalled\n };\n this.port.postMessage(state);\n }\n }\n return true;\n }\n};\nregisterProcessor(\"render\", Render);\n"], { type: "application/javascript" }), T = URL.createObjectURL(re), E = class {
|
|
219
219
|
source;
|
|
220
220
|
enabled;
|
|
221
|
-
#e = new
|
|
221
|
+
#e = new a(void 0);
|
|
222
222
|
context = this.#e;
|
|
223
|
-
#t = new
|
|
223
|
+
#t = new a(void 0);
|
|
224
224
|
root = this.#t;
|
|
225
|
-
#n = new
|
|
225
|
+
#n = new a(void 0);
|
|
226
226
|
sampleRate = this.#n;
|
|
227
|
-
#r = new
|
|
227
|
+
#r = new a(void 0);
|
|
228
228
|
stats = this.#r;
|
|
229
|
-
#i = new
|
|
229
|
+
#i = new a(void 0);
|
|
230
230
|
timestamp = this.#i;
|
|
231
|
-
#a = new
|
|
231
|
+
#a = new a(!0);
|
|
232
232
|
stalled = this.#a;
|
|
233
|
-
#o = new
|
|
234
|
-
#s = new
|
|
233
|
+
#o = new a([]);
|
|
234
|
+
#s = new a([]);
|
|
235
235
|
buffered = this.#s;
|
|
236
236
|
#c;
|
|
237
|
-
#l = new
|
|
237
|
+
#l = new i();
|
|
238
238
|
constructor(e, t) {
|
|
239
|
-
this.source = e, this.source.supported.set(D), this.enabled =
|
|
239
|
+
this.source = e, this.source.supported.set(D), this.enabled = a.from(t?.enabled ?? !1), this.#l.run(this.#u.bind(this)), this.#l.run(this.#d.bind(this)), this.#l.run(this.#f.bind(this)), this.#l.run(this.#p.bind(this));
|
|
240
240
|
}
|
|
241
241
|
#u(e) {
|
|
242
242
|
let t = e.get(this.source.config);
|
|
243
243
|
if (!t) return;
|
|
244
|
-
let
|
|
244
|
+
let n = t.sampleRate, i = t.numberOfChannels, a = new AudioContext({
|
|
245
245
|
latencyHint: "interactive",
|
|
246
|
-
sampleRate:
|
|
246
|
+
sampleRate: n
|
|
247
247
|
});
|
|
248
248
|
e.set(this.#e, a), e.cleanup(() => a.close()), e.spawn(async () => {
|
|
249
249
|
if (await a.audioWorklet.addModule(T), a.state === "closed") return;
|
|
@@ -253,11 +253,11 @@ var te = class {
|
|
|
253
253
|
outputChannelCount: [i]
|
|
254
254
|
});
|
|
255
255
|
e.cleanup(() => t.disconnect());
|
|
256
|
-
let o = this.source.sync.buffer.peek(), s = ee(t, i,
|
|
256
|
+
let o = this.source.sync.buffer.peek(), s = ee(t, i, n, Math.ceil(n * r.Second.fromMilli(o)));
|
|
257
257
|
this.#c = s, e.cleanup(() => {
|
|
258
258
|
s.close(), this.#c = void 0;
|
|
259
259
|
}), e.run((e) => {
|
|
260
|
-
let t =
|
|
260
|
+
let t = r.Milli.fromMicro(e.get(s.timestamp));
|
|
261
261
|
this.#i.set(t), this.#v(t);
|
|
262
262
|
}), e.run((e) => {
|
|
263
263
|
this.#a.set(e.get(s.stalled));
|
|
@@ -274,7 +274,7 @@ var te = class {
|
|
|
274
274
|
if (!e.get(this.#t)) return;
|
|
275
275
|
let t = this.#c;
|
|
276
276
|
if (!t) return;
|
|
277
|
-
let
|
|
277
|
+
let n = e.get(this.source.sync.buffer), i = Math.ceil(t.rate * r.Second.fromMilli(n));
|
|
278
278
|
t.setLatency(i);
|
|
279
279
|
}
|
|
280
280
|
#p(e) {
|
|
@@ -287,19 +287,19 @@ var te = class {
|
|
|
287
287
|
if (!r) return;
|
|
288
288
|
let i = e.get(t.active);
|
|
289
289
|
if (!i) return;
|
|
290
|
-
let
|
|
291
|
-
e.cleanup(() =>
|
|
290
|
+
let a = i.subscribe(n, o.PRIORITY.audio);
|
|
291
|
+
e.cleanup(() => a.close()), r.container.kind === "cmaf" ? this.#h(e, a, r) : this.#m(e, a, r);
|
|
292
292
|
}
|
|
293
|
-
#m(e, t,
|
|
294
|
-
let i =
|
|
293
|
+
#m(e, t, n) {
|
|
294
|
+
let i = n.container.kind === "loc" ? new c.Loc.Format() : new c.Legacy.Format(), a = new c.Consumer(t, {
|
|
295
295
|
format: i,
|
|
296
296
|
latency: this.source.sync.buffer
|
|
297
297
|
});
|
|
298
298
|
e.cleanup(() => a.close()), e.run((e) => {
|
|
299
299
|
let t = e.get(a.buffered), n = e.get(this.#o);
|
|
300
|
-
this.#s.update(() =>
|
|
300
|
+
this.#s.update(() => c.mergeBufferedRanges(t, n));
|
|
301
301
|
}), e.spawn(async () => {
|
|
302
|
-
if (!await
|
|
302
|
+
if (!await l.Libav.polyfill()) return;
|
|
303
303
|
let t = 0, i = new AudioDecoder({
|
|
304
304
|
output: (e) => {
|
|
305
305
|
if (t++, t <= 3) {
|
|
@@ -313,17 +313,17 @@ var te = class {
|
|
|
313
313
|
e.cleanup(() => {
|
|
314
314
|
i.state !== "closed" && i.close();
|
|
315
315
|
});
|
|
316
|
-
let o =
|
|
316
|
+
let o = n.codec === "opus" ? void 0 : n.description ? l.Hex.toBytes(n.description) : void 0;
|
|
317
317
|
for (i.configure({
|
|
318
|
-
...
|
|
318
|
+
...n,
|
|
319
319
|
description: o
|
|
320
320
|
});;) {
|
|
321
321
|
let e = await a.next();
|
|
322
322
|
if (!e) break;
|
|
323
323
|
let { frame: t } = e;
|
|
324
324
|
if (!t) continue;
|
|
325
|
-
let
|
|
326
|
-
this.source.sync.received(
|
|
325
|
+
let n = r.Milli.fromMicro(t.timestamp);
|
|
326
|
+
this.source.sync.received(n, "audio"), this.#r.update((e) => ({ bytesReceived: (e?.bytesReceived ?? 0) + t.data.byteLength }));
|
|
327
327
|
let o = new EncodedAudioChunk({
|
|
328
328
|
type: t.keyframe ? "key" : "delta",
|
|
329
329
|
data: t.data,
|
|
@@ -333,17 +333,17 @@ var te = class {
|
|
|
333
333
|
}
|
|
334
334
|
});
|
|
335
335
|
}
|
|
336
|
-
#h(e, t,
|
|
337
|
-
if (
|
|
338
|
-
let i = p(
|
|
339
|
-
format: new
|
|
336
|
+
#h(e, t, n) {
|
|
337
|
+
if (n.container.kind !== "cmaf") return;
|
|
338
|
+
let i = p(n.container.init), a = c.Cmaf.decodeInitSegment(i), o = n.codec === "opus" ? void 0 : n.description ? l.Hex.toBytes(n.description) : a.description, s = new c.Consumer(t, {
|
|
339
|
+
format: new c.Cmaf.Format(a),
|
|
340
340
|
latency: this.source.sync.buffer
|
|
341
341
|
});
|
|
342
|
-
e.cleanup(() =>
|
|
343
|
-
let t = e.get(
|
|
344
|
-
this.#s.update(() =>
|
|
342
|
+
e.cleanup(() => s.close()), e.run((e) => {
|
|
343
|
+
let t = e.get(s.buffered), n = e.get(this.#o);
|
|
344
|
+
this.#s.update(() => c.mergeBufferedRanges(t, n));
|
|
345
345
|
}), e.spawn(async () => {
|
|
346
|
-
if (!await
|
|
346
|
+
if (!await l.Libav.polyfill()) return;
|
|
347
347
|
let t = new AudioDecoder({
|
|
348
348
|
output: (e) => this.#g(e),
|
|
349
349
|
error: (e) => console.error(e)
|
|
@@ -351,33 +351,33 @@ var te = class {
|
|
|
351
351
|
for (e.cleanup(() => {
|
|
352
352
|
t.state !== "closed" && t.close();
|
|
353
353
|
}), t.configure({
|
|
354
|
-
codec:
|
|
355
|
-
sampleRate:
|
|
356
|
-
numberOfChannels:
|
|
354
|
+
codec: n.codec,
|
|
355
|
+
sampleRate: n.sampleRate,
|
|
356
|
+
numberOfChannels: n.numberOfChannels,
|
|
357
357
|
description: o
|
|
358
358
|
});;) {
|
|
359
|
-
let e = await
|
|
359
|
+
let e = await s.next();
|
|
360
360
|
if (!e) break;
|
|
361
|
-
let { frame:
|
|
362
|
-
if (!
|
|
363
|
-
let i =
|
|
364
|
-
if (this.source.sync.received(i, "audio"), this.#r.update((e) => ({ bytesReceived: (e?.bytesReceived ?? 0) +
|
|
361
|
+
let { frame: n } = e;
|
|
362
|
+
if (!n) continue;
|
|
363
|
+
let i = r.Milli.fromMicro(n.timestamp);
|
|
364
|
+
if (this.source.sync.received(i, "audio"), this.#r.update((e) => ({ bytesReceived: (e?.bytesReceived ?? 0) + n.data.byteLength })), t.state === "closed") break;
|
|
365
365
|
t.decode(new EncodedAudioChunk({
|
|
366
|
-
type:
|
|
367
|
-
data:
|
|
368
|
-
timestamp:
|
|
366
|
+
type: n.keyframe ? "key" : "delta",
|
|
367
|
+
data: n.data,
|
|
368
|
+
timestamp: n.timestamp
|
|
369
369
|
}));
|
|
370
370
|
}
|
|
371
371
|
});
|
|
372
372
|
}
|
|
373
373
|
#g(e) {
|
|
374
|
-
let t = e.timestamp,
|
|
374
|
+
let t = e.timestamp, n = r.Milli.fromMicro(t), i = this.#c;
|
|
375
375
|
if (!i) {
|
|
376
376
|
e.close();
|
|
377
377
|
return;
|
|
378
378
|
}
|
|
379
|
-
let a = e.numberOfFrames / e.sampleRate * 1e6, o =
|
|
380
|
-
this.#_(
|
|
379
|
+
let a = e.numberOfFrames / e.sampleRate * 1e6, o = r.Milli.fromMicro(a), s = r.Milli.add(n, o);
|
|
380
|
+
this.#_(n, s);
|
|
381
381
|
let c = Math.min(e.numberOfChannels, i.channels), l = [];
|
|
382
382
|
for (let t = 0; t < c; t++) {
|
|
383
383
|
let n = new Float32Array(e.numberOfFrames);
|
|
@@ -389,22 +389,22 @@ var te = class {
|
|
|
389
389
|
i.insert(t, l), e.close();
|
|
390
390
|
}
|
|
391
391
|
#_(e, t) {
|
|
392
|
-
e > t || this.#o.mutate((
|
|
393
|
-
for (let i of
|
|
394
|
-
i.start =
|
|
392
|
+
e > t || this.#o.mutate((n) => {
|
|
393
|
+
for (let i of n) if (e <= i.end + 1 && t >= i.start) {
|
|
394
|
+
i.start = r.Milli.min(i.start, e), i.end = r.Milli.max(i.end, t);
|
|
395
395
|
return;
|
|
396
396
|
}
|
|
397
|
-
|
|
397
|
+
n.push({
|
|
398
398
|
start: e,
|
|
399
399
|
end: t
|
|
400
|
-
}),
|
|
400
|
+
}), n.sort((e, t) => e.start - t.start);
|
|
401
401
|
});
|
|
402
402
|
}
|
|
403
403
|
#v(e) {
|
|
404
404
|
this.#o.mutate((t) => {
|
|
405
405
|
for (; t.length > 0;) {
|
|
406
406
|
if (t[0].end >= e) {
|
|
407
|
-
t[0].start =
|
|
407
|
+
t[0].start = r.Milli.max(t[0].start, e);
|
|
408
408
|
break;
|
|
409
409
|
}
|
|
410
410
|
t.shift();
|
|
@@ -418,9 +418,9 @@ var te = class {
|
|
|
418
418
|
async function D(e) {
|
|
419
419
|
let t;
|
|
420
420
|
if (e.codec !== "opus") {
|
|
421
|
-
if (e.description) t =
|
|
421
|
+
if (e.description) t = l.Hex.toBytes(e.description);
|
|
422
422
|
else if (e.container.kind === "cmaf") try {
|
|
423
|
-
t =
|
|
423
|
+
t = c.Cmaf.decodeInitSegment(p(e.container.init)).description;
|
|
424
424
|
} catch (t) {
|
|
425
425
|
return console.warn(`audio: malformed CMAF init segment for codec ${e.codec}`, t), !1;
|
|
426
426
|
}
|
|
@@ -437,11 +437,11 @@ var O = .001, k = .2, A = class {
|
|
|
437
437
|
volume;
|
|
438
438
|
muted;
|
|
439
439
|
paused;
|
|
440
|
-
#e = new
|
|
440
|
+
#e = new i();
|
|
441
441
|
#t = .5;
|
|
442
|
-
#n = new
|
|
442
|
+
#n = new a(void 0);
|
|
443
443
|
constructor(e, t) {
|
|
444
|
-
this.source = e, this.volume =
|
|
444
|
+
this.source = e, this.volume = a.from(t?.volume ?? .5), this.muted = a.from(t?.muted ?? !1), this.paused = a.from(t?.paused ?? t?.muted ?? !1), this.#e.run((e) => {
|
|
445
445
|
e.get(this.muted) ? (this.#t = this.volume.peek() || .5, this.volume.set(0)) : this.volume.set(this.#t);
|
|
446
446
|
}), this.#e.run((e) => {
|
|
447
447
|
let t = !e.get(this.paused) && !e.get(this.muted);
|
|
@@ -471,11 +471,11 @@ var O = .001, k = .2, A = class {
|
|
|
471
471
|
element;
|
|
472
472
|
paused;
|
|
473
473
|
#e;
|
|
474
|
-
#t = new
|
|
474
|
+
#t = new a(void 0);
|
|
475
475
|
mediaSource = this.#t;
|
|
476
|
-
#n = new
|
|
476
|
+
#n = new i();
|
|
477
477
|
constructor(e, t) {
|
|
478
|
-
this.element =
|
|
478
|
+
this.element = a.from(t?.element), this.paused = a.from(t?.paused ?? !1), this.#e = e, this.#n.run(this.#r.bind(this)), this.#n.run(this.#i.bind(this)), this.#n.run(this.#a.bind(this)), this.#n.run(this.#o.bind(this)), this.#n.run(this.#s.bind(this));
|
|
479
479
|
}
|
|
480
480
|
#r(e) {
|
|
481
481
|
let t = e.get(this.element);
|
|
@@ -490,12 +490,12 @@ var O = .001, k = .2, A = class {
|
|
|
490
490
|
#i(e) {
|
|
491
491
|
let t = e.get(this.element);
|
|
492
492
|
if (!t || e.get(this.paused)) return;
|
|
493
|
-
let
|
|
493
|
+
let n = r.Milli.toSecond(e.get(this.#e.buffer));
|
|
494
494
|
e.interval(() => {
|
|
495
495
|
let e = t.buffered;
|
|
496
496
|
if (e.length === 0) return;
|
|
497
|
-
let
|
|
498
|
-
(i > .1 || i < -.1) && (console.warn("seeking", i > 0 ? "forward" : "backward", Math.abs(i).toFixed(3), "seconds"), t.currentTime =
|
|
497
|
+
let r = e.end(e.length - 1) - n, i = r - t.currentTime;
|
|
498
|
+
(i > .1 || i < -.1) && (console.warn("seeking", i > 0 ? "forward" : "backward", Math.abs(i).toFixed(3), "seconds"), t.currentTime = r);
|
|
499
499
|
}, 100);
|
|
500
500
|
}
|
|
501
501
|
#a(e) {
|
|
@@ -520,31 +520,31 @@ var O = .001, k = .2, A = class {
|
|
|
520
520
|
#s(e) {
|
|
521
521
|
let t = e.get(this.element);
|
|
522
522
|
if (!t || e.get(this.paused)) return;
|
|
523
|
-
let
|
|
524
|
-
if (
|
|
525
|
-
let i = e.get(this.#e.buffer), a =
|
|
526
|
-
t.currentTime =
|
|
523
|
+
let n = e.get(this.#e.reference);
|
|
524
|
+
if (n === void 0) return;
|
|
525
|
+
let i = e.get(this.#e.buffer), a = r.Milli.sub(r.Milli.sub(r.Milli.now(), n), i);
|
|
526
|
+
t.currentTime = r.Milli.toSecond(a);
|
|
527
527
|
}
|
|
528
528
|
close() {
|
|
529
529
|
this.#n.close();
|
|
530
530
|
}
|
|
531
531
|
}, ae = 20, M = 100, N = class e {
|
|
532
|
-
#e = new
|
|
532
|
+
#e = new a(void 0);
|
|
533
533
|
reference = this.#e;
|
|
534
534
|
latency;
|
|
535
535
|
jitter;
|
|
536
536
|
audio;
|
|
537
537
|
video;
|
|
538
|
-
#t = new
|
|
538
|
+
#t = new a(r.Milli.zero);
|
|
539
539
|
buffer = this.#t;
|
|
540
540
|
#n;
|
|
541
|
-
timestamp = new
|
|
541
|
+
timestamp = new a(void 0);
|
|
542
542
|
#r = /* @__PURE__ */ new Map();
|
|
543
543
|
#i;
|
|
544
544
|
#a;
|
|
545
|
-
signals = new
|
|
545
|
+
signals = new i();
|
|
546
546
|
constructor(e) {
|
|
547
|
-
this.latency =
|
|
547
|
+
this.latency = a.from(e?.latency ?? "real-time"), this.jitter = new a(M), this.#i = e?.connection, this.audio = a.from(e?.audio), this.video = a.from(e?.video), this.#n = Promise.withResolvers(), this.signals.run(this.#o.bind(this)), this.signals.run(this.#s.bind(this));
|
|
548
548
|
}
|
|
549
549
|
#o(e) {
|
|
550
550
|
let t = e.get(this.latency);
|
|
@@ -562,25 +562,25 @@ var O = .001, k = .2, A = class {
|
|
|
562
562
|
this.#a = void 0, this.jitter.set(M);
|
|
563
563
|
}
|
|
564
564
|
#s(e) {
|
|
565
|
-
let t = e.get(this.jitter),
|
|
565
|
+
let t = e.get(this.jitter), n = e.get(this.video) ?? r.Milli.zero, i = e.get(this.audio) ?? r.Milli.zero, a = r.Milli.add(r.Milli.max(n, i), t);
|
|
566
566
|
this.#t.set(a), this.#n.resolve(), this.#n = Promise.withResolvers();
|
|
567
567
|
}
|
|
568
|
-
received(t,
|
|
568
|
+
received(t, n = "") {
|
|
569
569
|
this.timestamp.update((e) => e === void 0 || t > e ? t : e);
|
|
570
|
-
let i =
|
|
570
|
+
let i = r.Milli.now(), a = r.Milli.sub(i, t), o = this.#e.peek();
|
|
571
571
|
if (o !== void 0) {
|
|
572
|
-
let t =
|
|
572
|
+
let t = r.Milli.add(r.Milli.sub(o, a), this.#t.peek());
|
|
573
573
|
if (t < 0) {
|
|
574
|
-
let e = this.#r.get(
|
|
575
|
-
e ? (e.count++, e.maxMs = Math.max(e.maxMs, -t)) : this.#r.set(
|
|
574
|
+
let e = this.#r.get(n);
|
|
575
|
+
e ? (e.count++, e.maxMs = Math.max(e.maxMs, -t)) : this.#r.set(n, {
|
|
576
576
|
count: 1,
|
|
577
577
|
maxMs: -t
|
|
578
578
|
});
|
|
579
579
|
} else {
|
|
580
|
-
let t = this.#r.get(
|
|
580
|
+
let t = this.#r.get(n);
|
|
581
581
|
if (t) {
|
|
582
|
-
let
|
|
583
|
-
console.debug(`${
|
|
582
|
+
let r = n ? `sync[${n}]` : "sync", i = e.#c(t.maxMs);
|
|
583
|
+
console.debug(`${r}: ${t.count} late frame(s), max ${i} behind`), this.#r.delete(n);
|
|
584
584
|
}
|
|
585
585
|
}
|
|
586
586
|
if (a >= o) return;
|
|
@@ -589,14 +589,14 @@ var O = .001, k = .2, A = class {
|
|
|
589
589
|
}
|
|
590
590
|
now() {
|
|
591
591
|
let e = this.#e.peek();
|
|
592
|
-
if (e !== void 0) return
|
|
592
|
+
if (e !== void 0) return r.Milli.sub(r.Milli.sub(r.Milli.now(), e), this.#t.peek());
|
|
593
593
|
}
|
|
594
594
|
async wait(e) {
|
|
595
595
|
if (this.#e.peek() === void 0) throw Error("reference not set; call update() first");
|
|
596
596
|
for (;;) {
|
|
597
|
-
let t =
|
|
597
|
+
let t = r.Milli.now(), n = r.Milli.sub(t, e), i = this.#e.peek();
|
|
598
598
|
if (i === void 0) return;
|
|
599
|
-
let a =
|
|
599
|
+
let a = r.Milli.add(r.Milli.sub(i, n), this.#t.peek());
|
|
600
600
|
if (a <= 0 || a < 5) return;
|
|
601
601
|
let o = new Promise((e) => setTimeout(e, a)).then(() => !0);
|
|
602
602
|
if (await Promise.race([this.#n.promise, o])) return;
|
|
@@ -612,30 +612,30 @@ var O = .001, k = .2, A = class {
|
|
|
612
612
|
close() {
|
|
613
613
|
this.signals.close();
|
|
614
614
|
}
|
|
615
|
-
}, oe = 500,
|
|
615
|
+
}, oe = 500, se = 100, P = class {
|
|
616
616
|
enabled;
|
|
617
617
|
source;
|
|
618
|
-
#e = new
|
|
619
|
-
#t = new
|
|
618
|
+
#e = new a(void 0);
|
|
619
|
+
#t = new a(void 0);
|
|
620
620
|
frame = this.#t;
|
|
621
|
-
#n = new
|
|
621
|
+
#n = new a(void 0);
|
|
622
622
|
timestamp = this.#n;
|
|
623
|
-
#r = new
|
|
623
|
+
#r = new a(void 0);
|
|
624
624
|
display = this.#r;
|
|
625
|
-
#i = new
|
|
625
|
+
#i = new a(!1);
|
|
626
626
|
stalled = this.#i;
|
|
627
|
-
#a = new
|
|
627
|
+
#a = new a(void 0);
|
|
628
628
|
stats = this.#a;
|
|
629
|
-
#o = new
|
|
629
|
+
#o = new a([]);
|
|
630
630
|
buffered = this.#o;
|
|
631
|
-
#s = new
|
|
631
|
+
#s = new i();
|
|
632
632
|
#c() {
|
|
633
633
|
this.#t.update((e) => {
|
|
634
634
|
e?.close();
|
|
635
635
|
}), this.#n.set(void 0);
|
|
636
636
|
}
|
|
637
637
|
constructor(e, t) {
|
|
638
|
-
this.enabled =
|
|
638
|
+
this.enabled = a.from(t?.enabled ?? !1), this.source = e, this.source.supported.set(I), this.#s.run(this.#l.bind(this)), this.#s.run(this.#u.bind(this)), this.#s.run(this.#d.bind(this)), this.#s.run(this.#f.bind(this));
|
|
639
639
|
}
|
|
640
640
|
#l(e) {
|
|
641
641
|
let t = e.getAll([
|
|
@@ -653,7 +653,7 @@ var O = .001, k = .2, A = class {
|
|
|
653
653
|
this.#e.set(void 0), this.#c(), this.#o.set([]);
|
|
654
654
|
return;
|
|
655
655
|
}
|
|
656
|
-
let s = new
|
|
656
|
+
let s = new F({
|
|
657
657
|
source: this.source,
|
|
658
658
|
broadcast: o,
|
|
659
659
|
track: i,
|
|
@@ -665,7 +665,7 @@ var O = .001, k = .2, A = class {
|
|
|
665
665
|
let t = e.get(this.#e);
|
|
666
666
|
if (t) {
|
|
667
667
|
let n = e.get(s.timestamp), r = e.get(t.timestamp);
|
|
668
|
-
if (!n || r && r > n +
|
|
668
|
+
if (!n || r && r > n + se) return;
|
|
669
669
|
}
|
|
670
670
|
this.#e.set(s), s = void 0, e.close();
|
|
671
671
|
});
|
|
@@ -712,33 +712,33 @@ var O = .001, k = .2, A = class {
|
|
|
712
712
|
close() {
|
|
713
713
|
this.#c(), this.#s.close();
|
|
714
714
|
}
|
|
715
|
-
},
|
|
715
|
+
}, F = class {
|
|
716
716
|
source;
|
|
717
717
|
broadcast;
|
|
718
718
|
track;
|
|
719
719
|
config;
|
|
720
720
|
stats;
|
|
721
|
-
timestamp = new
|
|
722
|
-
frame = new
|
|
723
|
-
buffered = new
|
|
724
|
-
#e = new
|
|
725
|
-
signals = new
|
|
721
|
+
timestamp = new a(void 0);
|
|
722
|
+
frame = new a(void 0);
|
|
723
|
+
buffered = new a([]);
|
|
724
|
+
#e = new a([]);
|
|
725
|
+
signals = new i();
|
|
726
726
|
constructor(e) {
|
|
727
727
|
let { codedWidth: t, codedHeight: n, ...r } = e.config;
|
|
728
728
|
this.source = e.source, this.broadcast = e.broadcast, this.track = e.track, this.config = r, this.stats = e.stats, this.signals.run(this.#t.bind(this));
|
|
729
729
|
}
|
|
730
730
|
#t(e) {
|
|
731
|
-
let t = this.broadcast.subscribe(this.track,
|
|
731
|
+
let t = this.broadcast.subscribe(this.track, o.PRIORITY.video);
|
|
732
732
|
e.cleanup(() => t.close());
|
|
733
|
-
let
|
|
733
|
+
let n = new VideoDecoder({
|
|
734
734
|
output: async (t) => {
|
|
735
735
|
try {
|
|
736
|
-
let
|
|
737
|
-
if (
|
|
736
|
+
let n = r.Milli.fromMicro(t.timestamp);
|
|
737
|
+
if (n < (this.timestamp.peek() ?? 0)) return;
|
|
738
738
|
this.frame.peek() === void 0 && this.frame.set(t.clone());
|
|
739
|
-
let i = this.source.sync.wait(
|
|
740
|
-
if (!await Promise.race([i, e.cancel]) ||
|
|
741
|
-
this.timestamp.set(
|
|
739
|
+
let i = this.source.sync.wait(n).then(() => !0);
|
|
740
|
+
if (!await Promise.race([i, e.cancel]) || n < (this.timestamp.peek() ?? 0)) return;
|
|
741
|
+
this.timestamp.set(n), this.#a(n), this.frame.update((e) => (e?.close(), t.clone()));
|
|
742
742
|
} finally {
|
|
743
743
|
t.close();
|
|
744
744
|
}
|
|
@@ -748,20 +748,20 @@ var O = .001, k = .2, A = class {
|
|
|
748
748
|
}
|
|
749
749
|
});
|
|
750
750
|
e.cleanup(() => {
|
|
751
|
-
|
|
752
|
-
}), this.config.container.kind === "cmaf" ? this.#r(e, t,
|
|
751
|
+
n.state !== "closed" && n.close();
|
|
752
|
+
}), this.config.container.kind === "cmaf" ? this.#r(e, t, n) : this.#n(e, t, n);
|
|
753
753
|
}
|
|
754
|
-
#n(e, t,
|
|
755
|
-
let i = this.config.container.kind === "loc" ? new
|
|
754
|
+
#n(e, t, n) {
|
|
755
|
+
let i = this.config.container.kind === "loc" ? new c.Loc.Format() : new c.Legacy.Format(), a = new c.Consumer(t, {
|
|
756
756
|
format: i,
|
|
757
757
|
latency: this.source.sync.buffer
|
|
758
758
|
});
|
|
759
759
|
e.cleanup(() => a.close()), e.run((e) => {
|
|
760
760
|
let t = e.get(a.buffered), n = e.get(this.#e);
|
|
761
|
-
this.buffered.update(() =>
|
|
762
|
-
}),
|
|
761
|
+
this.buffered.update(() => c.mergeBufferedRanges(t, n));
|
|
762
|
+
}), n.configure({
|
|
763
763
|
...this.config,
|
|
764
|
-
description: this.config.description ?
|
|
764
|
+
description: this.config.description ? l.Hex.toBytes(this.config.description) : void 0,
|
|
765
765
|
optimizeForLatency: this.config.optimizeForLatency ?? !0,
|
|
766
766
|
flip: !1
|
|
767
767
|
});
|
|
@@ -775,7 +775,7 @@ var O = .001, k = .2, A = class {
|
|
|
775
775
|
o && (o.final = !0);
|
|
776
776
|
continue;
|
|
777
777
|
}
|
|
778
|
-
let s =
|
|
778
|
+
let s = r.Milli.fromMicro(t.timestamp);
|
|
779
779
|
this.source.sync.received(s, "video");
|
|
780
780
|
let c = new EncodedVideoChunk({
|
|
781
781
|
type: t.keyframe ? "key" : "delta",
|
|
@@ -788,27 +788,27 @@ var O = .001, k = .2, A = class {
|
|
|
788
788
|
}));
|
|
789
789
|
let l = o;
|
|
790
790
|
if (l && (l.group === i || l.final && l.group + 1 === i)) {
|
|
791
|
-
let e =
|
|
792
|
-
this.#i(e,
|
|
791
|
+
let e = r.Milli.fromMicro(l.timestamp), n = r.Milli.fromMicro(t.timestamp);
|
|
792
|
+
this.#i(e, n);
|
|
793
793
|
}
|
|
794
794
|
o = {
|
|
795
795
|
timestamp: t.timestamp,
|
|
796
796
|
group: i,
|
|
797
797
|
final: !1
|
|
798
|
-
},
|
|
798
|
+
}, n.decode(c);
|
|
799
799
|
}
|
|
800
800
|
});
|
|
801
801
|
}
|
|
802
|
-
#r(e, t,
|
|
802
|
+
#r(e, t, n) {
|
|
803
803
|
if (this.config.container.kind !== "cmaf") return;
|
|
804
|
-
let i = p(this.config.container.init), a =
|
|
805
|
-
format: new
|
|
804
|
+
let i = p(this.config.container.init), a = c.Cmaf.decodeInitSegment(i), o = this.config.description ? l.Hex.toBytes(this.config.description) : a.description, s = new c.Consumer(t, {
|
|
805
|
+
format: new c.Cmaf.Format(a),
|
|
806
806
|
latency: this.source.sync.buffer
|
|
807
807
|
});
|
|
808
|
-
e.cleanup(() =>
|
|
809
|
-
let t = e.get(
|
|
810
|
-
this.buffered.update(() =>
|
|
811
|
-
}),
|
|
808
|
+
e.cleanup(() => s.close()), e.run((e) => {
|
|
809
|
+
let t = e.get(s.buffered), n = e.get(this.#e);
|
|
810
|
+
this.buffered.update(() => c.mergeBufferedRanges(t, n));
|
|
811
|
+
}), n.configure({
|
|
812
812
|
codec: this.config.codec,
|
|
813
813
|
description: o,
|
|
814
814
|
optimizeForLatency: this.config.optimizeForLatency ?? !0,
|
|
@@ -817,29 +817,29 @@ var O = .001, k = .2, A = class {
|
|
|
817
817
|
let u;
|
|
818
818
|
e.spawn(async () => {
|
|
819
819
|
for (;;) {
|
|
820
|
-
let e = await
|
|
820
|
+
let e = await s.next();
|
|
821
821
|
if (!e) break;
|
|
822
822
|
let { frame: t, group: i } = e;
|
|
823
823
|
if (!t) {
|
|
824
824
|
u && (u.final = !0);
|
|
825
825
|
continue;
|
|
826
826
|
}
|
|
827
|
-
let a =
|
|
827
|
+
let a = r.Milli.fromMicro(t.timestamp);
|
|
828
828
|
this.source.sync.received(a, "video"), this.stats.update((e) => ({
|
|
829
829
|
frameCount: (e?.frameCount ?? 0) + 1,
|
|
830
830
|
bytesReceived: (e?.bytesReceived ?? 0) + t.data.byteLength
|
|
831
831
|
}));
|
|
832
832
|
let o = u;
|
|
833
833
|
if (o && (o.group === i || o.final && o.group + 1 === i)) {
|
|
834
|
-
let e =
|
|
835
|
-
this.#i(e,
|
|
834
|
+
let e = r.Milli.fromMicro(o.timestamp), n = r.Milli.fromMicro(t.timestamp);
|
|
835
|
+
this.#i(e, n);
|
|
836
836
|
}
|
|
837
837
|
if (u = {
|
|
838
838
|
timestamp: t.timestamp,
|
|
839
839
|
group: i,
|
|
840
840
|
final: !1
|
|
841
|
-
},
|
|
842
|
-
|
|
841
|
+
}, n.state === "closed") break;
|
|
842
|
+
n.decode(new EncodedVideoChunk({
|
|
843
843
|
type: t.keyframe ? "key" : "delta",
|
|
844
844
|
data: t.data,
|
|
845
845
|
timestamp: t.timestamp
|
|
@@ -848,22 +848,22 @@ var O = .001, k = .2, A = class {
|
|
|
848
848
|
});
|
|
849
849
|
}
|
|
850
850
|
#i(e, t) {
|
|
851
|
-
e > t || this.#e.mutate((
|
|
852
|
-
for (let i of
|
|
853
|
-
i.start =
|
|
851
|
+
e > t || this.#e.mutate((n) => {
|
|
852
|
+
for (let i of n) if (i.start <= t && i.end >= e) {
|
|
853
|
+
i.start = r.Milli.min(i.start, e), i.end = r.Milli.max(i.end, t);
|
|
854
854
|
return;
|
|
855
855
|
}
|
|
856
|
-
|
|
856
|
+
n.push({
|
|
857
857
|
start: e,
|
|
858
858
|
end: t
|
|
859
|
-
}),
|
|
859
|
+
}), n.sort((e, t) => e.start - t.start);
|
|
860
860
|
});
|
|
861
861
|
}
|
|
862
862
|
#a(e) {
|
|
863
863
|
this.#e.mutate((t) => {
|
|
864
864
|
for (; t.length > 0;) {
|
|
865
865
|
if (t[0].end >= e) {
|
|
866
|
-
t[0].start =
|
|
866
|
+
t[0].start = r.Milli.max(t[0].start, e);
|
|
867
867
|
break;
|
|
868
868
|
}
|
|
869
869
|
t.shift();
|
|
@@ -876,11 +876,11 @@ var O = .001, k = .2, A = class {
|
|
|
876
876
|
});
|
|
877
877
|
}
|
|
878
878
|
};
|
|
879
|
-
async function
|
|
879
|
+
async function I(e) {
|
|
880
880
|
let t;
|
|
881
|
-
if (e.description) t =
|
|
881
|
+
if (e.description) t = l.Hex.toBytes(e.description);
|
|
882
882
|
else if (e.container.kind === "cmaf") try {
|
|
883
|
-
t =
|
|
883
|
+
t = c.Cmaf.decodeInitSegment(p(e.container.init)).description;
|
|
884
884
|
} catch (t) {
|
|
885
885
|
return console.warn(`video: malformed CMAF init segment for codec ${e.codec}`, t), !1;
|
|
886
886
|
}
|
|
@@ -902,20 +902,20 @@ async function L(e) {
|
|
|
902
902
|
}
|
|
903
903
|
//#endregion
|
|
904
904
|
//#region src/video/mse.ts
|
|
905
|
-
var
|
|
905
|
+
var L = class {
|
|
906
906
|
muxer;
|
|
907
907
|
source;
|
|
908
|
-
#e = new
|
|
908
|
+
#e = new a(void 0);
|
|
909
909
|
stats = this.#e;
|
|
910
|
-
#t = new
|
|
910
|
+
#t = new a([]);
|
|
911
911
|
buffered = this.#t;
|
|
912
|
-
#n = new
|
|
912
|
+
#n = new a(!1);
|
|
913
913
|
stalled = this.#n;
|
|
914
|
-
#r = new
|
|
914
|
+
#r = new a(t.Time.Milli.zero);
|
|
915
915
|
timestamp = this.#r;
|
|
916
|
-
signals = new
|
|
916
|
+
signals = new i();
|
|
917
917
|
constructor(e, t) {
|
|
918
|
-
this.muxer = e, this.source = t, this.source.supported.set(
|
|
918
|
+
this.muxer = e, this.source = t, this.source.supported.set(R), this.signals.run(this.#i.bind(this)), this.signals.run(this.#c.bind(this)), this.signals.run(this.#l.bind(this));
|
|
919
919
|
}
|
|
920
920
|
#i(e) {
|
|
921
921
|
let t = e.get(this.muxer.element);
|
|
@@ -943,58 +943,58 @@ var R = class {
|
|
|
943
943
|
for (; e.updating;) await new Promise((t) => e.addEventListener("updateend", t, { once: !0 }));
|
|
944
944
|
for (e.appendBuffer(t); e.updating;) await new Promise((t) => e.addEventListener("updateend", t, { once: !0 }));
|
|
945
945
|
}
|
|
946
|
-
#o(
|
|
946
|
+
#o(e, n, r, i, a, s) {
|
|
947
947
|
if (i.container.kind !== "cmaf") throw Error("unreachable");
|
|
948
|
-
let l = n.subscribe(r,
|
|
949
|
-
|
|
950
|
-
let u = p(i.container.init), d =
|
|
951
|
-
|
|
952
|
-
for (await this.#a(
|
|
953
|
-
let
|
|
954
|
-
if (!
|
|
955
|
-
let n =
|
|
956
|
-
this.source.sync.received(
|
|
948
|
+
let l = n.subscribe(r, o.PRIORITY.video);
|
|
949
|
+
e.cleanup(() => l.close());
|
|
950
|
+
let u = p(i.container.init), d = c.Cmaf.decodeInitSegment(u);
|
|
951
|
+
e.spawn(async () => {
|
|
952
|
+
for (await this.#a(a, u);;) {
|
|
953
|
+
let e = await l.readFrame();
|
|
954
|
+
if (!e) return;
|
|
955
|
+
let n = c.Cmaf.decodeTimestamp(e, d);
|
|
956
|
+
this.source.sync.received(t.Time.Milli.fromMicro(n), "video"), await this.#a(a, e), s.buffered.length > 0 && s.currentTime < s.buffered.start(0) && (s.currentTime = s.buffered.start(0));
|
|
957
957
|
}
|
|
958
958
|
});
|
|
959
959
|
}
|
|
960
|
-
#s(
|
|
961
|
-
let l = n.subscribe(r,
|
|
962
|
-
|
|
963
|
-
let u = i.container.kind === "loc" ? new
|
|
960
|
+
#s(e, n, r, i, a, s) {
|
|
961
|
+
let l = n.subscribe(r, o.PRIORITY.video);
|
|
962
|
+
e.cleanup(() => l.close());
|
|
963
|
+
let u = i.container.kind === "loc" ? new c.Loc.Format() : new c.Legacy.Format(), d = new c.Consumer(l, {
|
|
964
964
|
format: u,
|
|
965
965
|
latency: this.source.sync.buffer
|
|
966
966
|
});
|
|
967
|
-
|
|
968
|
-
let
|
|
969
|
-
await this.#a(
|
|
970
|
-
let n = 1, r,
|
|
967
|
+
e.cleanup(() => d.close()), e.spawn(async () => {
|
|
968
|
+
let e = c.Cmaf.createVideoInitSegment(i);
|
|
969
|
+
await this.#a(a, e);
|
|
970
|
+
let n = 1, r, o;
|
|
971
971
|
for (;;) {
|
|
972
|
-
let
|
|
973
|
-
if (!
|
|
974
|
-
if (!
|
|
975
|
-
|
|
976
|
-
let n =
|
|
972
|
+
let e = await d.next();
|
|
973
|
+
if (!e) return;
|
|
974
|
+
if (!e.frame) continue;
|
|
975
|
+
o = e.frame;
|
|
976
|
+
let n = t.Time.Milli.fromMicro(o.timestamp);
|
|
977
977
|
this.source.sync.received(n, "video");
|
|
978
978
|
break;
|
|
979
979
|
}
|
|
980
980
|
for (;;) {
|
|
981
|
-
let
|
|
982
|
-
if (
|
|
983
|
-
let i =
|
|
981
|
+
let e = await d.next();
|
|
982
|
+
if (e && !e.frame) continue;
|
|
983
|
+
let i = e?.frame;
|
|
984
984
|
if (i) {
|
|
985
|
-
r =
|
|
986
|
-
let
|
|
987
|
-
this.source.sync.received(
|
|
985
|
+
r = t.Time.Micro.sub(i.timestamp, o.timestamp);
|
|
986
|
+
let e = t.Time.Milli.fromMicro(i.timestamp);
|
|
987
|
+
this.source.sync.received(e, "video");
|
|
988
988
|
}
|
|
989
|
-
let l =
|
|
990
|
-
data:
|
|
991
|
-
timestamp:
|
|
989
|
+
let l = c.Cmaf.encodeDataSegment({
|
|
990
|
+
data: o.data,
|
|
991
|
+
timestamp: o.timestamp,
|
|
992
992
|
duration: r ?? 0,
|
|
993
|
-
keyframe:
|
|
993
|
+
keyframe: o.keyframe,
|
|
994
994
|
sequence: n++
|
|
995
995
|
});
|
|
996
|
-
if (await this.#a(
|
|
997
|
-
|
|
996
|
+
if (await this.#a(a, l), s.buffered.length > 0 && s.currentTime < s.buffered.start(0) && (s.currentTime = s.buffered.start(0)), !i) return;
|
|
997
|
+
o = i;
|
|
998
998
|
}
|
|
999
999
|
});
|
|
1000
1000
|
}
|
|
@@ -1006,39 +1006,40 @@ var R = class {
|
|
|
1006
1006
|
};
|
|
1007
1007
|
n(), e.event(t, "waiting", n), e.event(t, "playing", n), e.event(t, "seeking", n);
|
|
1008
1008
|
}
|
|
1009
|
-
#l(
|
|
1010
|
-
let n =
|
|
1009
|
+
#l(e) {
|
|
1010
|
+
let n = e.get(this.muxer.element);
|
|
1011
1011
|
if (n) if ("requestVideoFrameCallback" in n) {
|
|
1012
1012
|
let r = n, i, a = () => {
|
|
1013
|
-
let
|
|
1014
|
-
this.#r.set(
|
|
1013
|
+
let e = t.Time.Milli.fromSecond(r.currentTime);
|
|
1014
|
+
this.#r.set(e), i = r.requestVideoFrameCallback(a);
|
|
1015
1015
|
};
|
|
1016
|
-
i = r.requestVideoFrameCallback(a),
|
|
1017
|
-
} else
|
|
1018
|
-
let
|
|
1019
|
-
this.#r.set(
|
|
1016
|
+
i = r.requestVideoFrameCallback(a), e.cleanup(() => r.cancelVideoFrameCallback(i));
|
|
1017
|
+
} else e.event(n, "timeupdate", () => {
|
|
1018
|
+
let e = t.Time.Milli.fromSecond(n.currentTime);
|
|
1019
|
+
this.#r.set(e);
|
|
1020
1020
|
});
|
|
1021
1021
|
}
|
|
1022
1022
|
close() {
|
|
1023
1023
|
this.source.close(), this.signals.close();
|
|
1024
1024
|
}
|
|
1025
1025
|
};
|
|
1026
|
-
async function
|
|
1026
|
+
async function R(e) {
|
|
1027
1027
|
return MediaSource.isTypeSupported(`video/mp4; codecs="${e.codec}"`);
|
|
1028
1028
|
}
|
|
1029
1029
|
//#endregion
|
|
1030
1030
|
//#region src/video/renderer.ts
|
|
1031
|
-
var B = class {
|
|
1031
|
+
var z = .01, B = class {
|
|
1032
1032
|
decoder;
|
|
1033
1033
|
canvas;
|
|
1034
1034
|
paused;
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
#
|
|
1039
|
-
#
|
|
1035
|
+
visible;
|
|
1036
|
+
frame = new a(void 0);
|
|
1037
|
+
timestamp = new a(void 0);
|
|
1038
|
+
#e = new a(void 0);
|
|
1039
|
+
#t = new a(!1);
|
|
1040
|
+
#n = new i();
|
|
1040
1041
|
constructor(e, t) {
|
|
1041
|
-
this.decoder = e, this.canvas =
|
|
1042
|
+
this.decoder = e, this.canvas = a.from(t?.canvas), this.paused = a.from(t?.paused ?? !1), this.visible = a.from(t?.visible ?? "0px"), this.#n.run((e) => {
|
|
1042
1043
|
let t = e.get(this.canvas);
|
|
1043
1044
|
this.#e.set(t?.getContext("2d") ?? void 0);
|
|
1044
1045
|
}), this.#n.run(this.#i.bind(this)), this.#n.run(this.#a.bind(this)), this.#n.run(this.#o.bind(this)), this.#n.run(this.#r.bind(this));
|
|
@@ -1050,17 +1051,34 @@ var B = class {
|
|
|
1050
1051
|
(n.width !== r.width || n.height !== r.height) && (n.width = r.width, n.height = r.height);
|
|
1051
1052
|
}
|
|
1052
1053
|
#i(e) {
|
|
1053
|
-
let t = e.get(this.
|
|
1054
|
-
if (
|
|
1054
|
+
let t = e.get(this.visible);
|
|
1055
|
+
if (t === "never") {
|
|
1055
1056
|
this.#t.set(!1);
|
|
1056
1057
|
return;
|
|
1057
1058
|
}
|
|
1058
|
-
|
|
1059
|
-
this.#t.set(
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1059
|
+
if (t === "always") {
|
|
1060
|
+
this.#t.set(!0), e.cleanup(() => this.#t.set(!1));
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
let n = e.get(this.canvas);
|
|
1064
|
+
if (!n) {
|
|
1065
|
+
this.#t.set(!1);
|
|
1066
|
+
return;
|
|
1067
|
+
}
|
|
1068
|
+
let r = !1, i = () => {
|
|
1069
|
+
this.#t.set(r && !document.hidden);
|
|
1070
|
+
}, a = (e) => {
|
|
1071
|
+
for (let t of e) r = t.isIntersecting, i();
|
|
1072
|
+
}, o;
|
|
1073
|
+
try {
|
|
1074
|
+
o = new IntersectionObserver(a, {
|
|
1075
|
+
threshold: z,
|
|
1076
|
+
rootMargin: t
|
|
1077
|
+
});
|
|
1078
|
+
} catch {
|
|
1079
|
+
console.warn(`moq-watch: invalid visible margin "${t}", using "0px"`), o = new IntersectionObserver(a, { threshold: z });
|
|
1080
|
+
}
|
|
1081
|
+
i(), e.event(document, "visibilitychange", i), o.observe(n), e.cleanup(() => o.disconnect()), e.cleanup(() => this.#t.set(!1));
|
|
1064
1082
|
}
|
|
1065
1083
|
#a(e) {
|
|
1066
1084
|
let t = e.get(this.paused), n = e.get(this.#t);
|
|
@@ -1074,8 +1092,8 @@ var B = class {
|
|
|
1074
1092
|
#o(e) {
|
|
1075
1093
|
let t = e.get(this.#e);
|
|
1076
1094
|
if (!t) return;
|
|
1077
|
-
let
|
|
1078
|
-
this.#s(t,
|
|
1095
|
+
let n = e.get(this.decoder.frame), i = requestAnimationFrame(() => {
|
|
1096
|
+
this.#s(t, n), n ? (this.frame.update((e) => (e?.close(), n.clone())), this.timestamp.set(r.Milli.fromMicro(n.timestamp))) : (this.frame.update((e) => {
|
|
1079
1097
|
e?.close();
|
|
1080
1098
|
}), this.timestamp.set(void 0)), i = void 0;
|
|
1081
1099
|
});
|
|
@@ -1160,17 +1178,17 @@ var G = class {
|
|
|
1160
1178
|
broadcast;
|
|
1161
1179
|
target;
|
|
1162
1180
|
catalog;
|
|
1163
|
-
#e = new
|
|
1181
|
+
#e = new a({});
|
|
1164
1182
|
available = this.#e;
|
|
1165
|
-
#t = new
|
|
1183
|
+
#t = new a(void 0);
|
|
1166
1184
|
track = this.#t;
|
|
1167
|
-
#n = new
|
|
1185
|
+
#n = new a(void 0);
|
|
1168
1186
|
config = this.#n;
|
|
1169
1187
|
sync;
|
|
1170
1188
|
supported;
|
|
1171
|
-
#r = new
|
|
1189
|
+
#r = new i();
|
|
1172
1190
|
constructor(e, t) {
|
|
1173
|
-
this.broadcast =
|
|
1191
|
+
this.broadcast = a.from(t?.broadcast), this.target = a.from(t?.target), this.sync = e, this.supported = a.from(t?.supported), this.catalog = this.#r.computed((e) => {
|
|
1174
1192
|
let t = e.get(this.broadcast);
|
|
1175
1193
|
return t ? e.get(t.catalog)?.video : void 0;
|
|
1176
1194
|
}), this.#r.run(this.#i.bind(this)), this.#r.run(this.#a.bind(this));
|
|
@@ -1229,17 +1247,17 @@ var G = class {
|
|
|
1229
1247
|
this.#r.close();
|
|
1230
1248
|
}
|
|
1231
1249
|
}, K = /* @__PURE__ */ f({
|
|
1232
|
-
Decoder: () =>
|
|
1233
|
-
Mse: () =>
|
|
1250
|
+
Decoder: () => P,
|
|
1251
|
+
Mse: () => L,
|
|
1234
1252
|
Renderer: () => B,
|
|
1235
1253
|
Source: () => G
|
|
1236
1254
|
});
|
|
1237
1255
|
//#endregion
|
|
1238
1256
|
//#region src/backend.ts
|
|
1239
|
-
function q(
|
|
1257
|
+
function q(e) {
|
|
1240
1258
|
let n = [];
|
|
1241
|
-
for (let r = 0; r <
|
|
1242
|
-
let i =
|
|
1259
|
+
for (let r = 0; r < e.length; r++) {
|
|
1260
|
+
let i = t.Time.Milli.fromSecond(e.start(r)), a = t.Time.Milli.fromSecond(e.end(r));
|
|
1243
1261
|
n.push({
|
|
1244
1262
|
start: i,
|
|
1245
1263
|
end: a
|
|
@@ -1247,55 +1265,57 @@ function q(t) {
|
|
|
1247
1265
|
}
|
|
1248
1266
|
return n;
|
|
1249
1267
|
}
|
|
1250
|
-
var
|
|
1268
|
+
var ce = class {
|
|
1251
1269
|
source;
|
|
1252
|
-
stats = new
|
|
1253
|
-
stalled = new
|
|
1254
|
-
buffered = new
|
|
1255
|
-
timestamp = new
|
|
1270
|
+
stats = new a(void 0);
|
|
1271
|
+
stalled = new a(!1);
|
|
1272
|
+
buffered = new a([]);
|
|
1273
|
+
timestamp = new a(t.Time.Milli.zero);
|
|
1256
1274
|
constructor(e) {
|
|
1257
1275
|
this.source = e;
|
|
1258
1276
|
}
|
|
1259
|
-
},
|
|
1277
|
+
}, le = class {
|
|
1260
1278
|
source;
|
|
1261
|
-
volume = new
|
|
1262
|
-
muted = new
|
|
1263
|
-
stats = new
|
|
1264
|
-
buffered = new
|
|
1265
|
-
context = new
|
|
1279
|
+
volume = new a(.5);
|
|
1280
|
+
muted = new a(!1);
|
|
1281
|
+
stats = new a(void 0);
|
|
1282
|
+
buffered = new a([]);
|
|
1283
|
+
context = new a(void 0);
|
|
1266
1284
|
constructor(e) {
|
|
1267
1285
|
this.source = e;
|
|
1268
1286
|
}
|
|
1269
|
-
},
|
|
1270
|
-
element = new
|
|
1287
|
+
}, ue = class {
|
|
1288
|
+
element = new a(void 0);
|
|
1271
1289
|
broadcast;
|
|
1272
1290
|
latency;
|
|
1273
1291
|
jitter;
|
|
1274
1292
|
paused;
|
|
1293
|
+
visible;
|
|
1275
1294
|
video;
|
|
1276
1295
|
#e;
|
|
1277
1296
|
audio;
|
|
1278
1297
|
#t;
|
|
1279
1298
|
sync;
|
|
1280
|
-
signals = new
|
|
1299
|
+
signals = new i();
|
|
1281
1300
|
constructor(e) {
|
|
1282
|
-
this.element =
|
|
1301
|
+
this.element = a.from(e?.element), this.broadcast = a.from(e?.broadcast), this.sync = new N({
|
|
1283
1302
|
latency: e?.latency,
|
|
1284
1303
|
connection: e?.connection
|
|
1285
|
-
}), this.latency = this.sync.latency, this.jitter = this.sync.jitter, this.#e = new G(this.sync, { broadcast: this.broadcast }), this.#t = new Y(this.sync, { broadcast: this.broadcast }), this.video = new
|
|
1304
|
+
}), this.latency = this.sync.latency, this.jitter = this.sync.jitter, this.#e = new G(this.sync, { broadcast: this.broadcast }), this.#t = new Y(this.sync, { broadcast: this.broadcast }), this.video = new ce(this.#e), this.audio = new le(this.#t), this.paused = a.from(e?.paused ?? !1), this.visible = a.from(e?.visible ?? "0px"), this.signals.run(this.#n.bind(this));
|
|
1286
1305
|
}
|
|
1287
1306
|
#n(e) {
|
|
1288
1307
|
let t = e.get(this.element);
|
|
1289
1308
|
t && (t instanceof HTMLCanvasElement ? this.#r(e, t) : t instanceof HTMLVideoElement && this.#i(e, t));
|
|
1290
1309
|
}
|
|
1291
1310
|
#r(e, t) {
|
|
1292
|
-
let n = new
|
|
1311
|
+
let n = new P(this.#e), r = new E(this.#t), i = new A(r, {
|
|
1293
1312
|
volume: this.audio.volume,
|
|
1294
1313
|
muted: this.audio.muted,
|
|
1295
1314
|
paused: this.paused
|
|
1296
1315
|
}), a = new B(n, {
|
|
1297
1316
|
canvas: t,
|
|
1298
|
-
paused: this.paused
|
|
1317
|
+
paused: this.paused,
|
|
1318
|
+
visible: this.visible
|
|
1299
1319
|
});
|
|
1300
1320
|
e.cleanup(() => {
|
|
1301
1321
|
n.close(), r.close(), i.close(), a.close();
|
|
@@ -1305,7 +1325,7 @@ var se = class {
|
|
|
1305
1325
|
let n = new j(this.sync, {
|
|
1306
1326
|
paused: this.paused,
|
|
1307
1327
|
element: t
|
|
1308
|
-
}), r = new
|
|
1328
|
+
}), r = new L(n, this.#e), i = new J(n, this.#t, {
|
|
1309
1329
|
volume: this.audio.volume,
|
|
1310
1330
|
muted: this.audio.muted
|
|
1311
1331
|
});
|
|
@@ -1321,14 +1341,14 @@ var se = class {
|
|
|
1321
1341
|
source;
|
|
1322
1342
|
volume;
|
|
1323
1343
|
muted;
|
|
1324
|
-
#e = new
|
|
1344
|
+
#e = new a(void 0);
|
|
1325
1345
|
stats = this.#e;
|
|
1326
|
-
#t = new
|
|
1346
|
+
#t = new a([]);
|
|
1327
1347
|
buffered = this.#t;
|
|
1328
|
-
context = new
|
|
1329
|
-
#n = new
|
|
1348
|
+
context = new a(void 0);
|
|
1349
|
+
#n = new i();
|
|
1330
1350
|
constructor(e, t, n) {
|
|
1331
|
-
this.muxer = e, this.source = t, this.source.supported.set(
|
|
1351
|
+
this.muxer = e, this.source = t, this.source.supported.set(de), this.volume = a.from(n?.volume ?? .5), this.muted = a.from(n?.muted ?? !1), this.#n.run(this.#r.bind(this)), this.#n.run(this.#s.bind(this));
|
|
1332
1352
|
}
|
|
1333
1353
|
#r(e) {
|
|
1334
1354
|
let t = e.get(this.muxer.element);
|
|
@@ -1339,8 +1359,8 @@ var se = class {
|
|
|
1339
1359
|
if (!r) return;
|
|
1340
1360
|
let i = e.get(r.active);
|
|
1341
1361
|
if (!i) return;
|
|
1342
|
-
let
|
|
1343
|
-
if (!
|
|
1362
|
+
let a = e.get(this.source.track);
|
|
1363
|
+
if (!a) return;
|
|
1344
1364
|
let s = e.get(this.source.config);
|
|
1345
1365
|
if (!s) return;
|
|
1346
1366
|
let c = `audio/mp4; codecs="${s.codec}"`, l = n.addSourceBuffer(c);
|
|
@@ -1351,53 +1371,53 @@ var se = class {
|
|
|
1351
1371
|
}), e.event(l, "updateend", () => {
|
|
1352
1372
|
this.#t.set(q(l.buffered));
|
|
1353
1373
|
});
|
|
1354
|
-
let u = i.subscribe(
|
|
1374
|
+
let u = i.subscribe(a, o.PRIORITY.audio);
|
|
1355
1375
|
e.cleanup(() => u.close()), s.container.kind === "cmaf" ? this.#a(e, u, s, l, t) : this.#o(e, u, s, l, t);
|
|
1356
1376
|
}
|
|
1357
1377
|
async #i(e, t) {
|
|
1358
1378
|
for (; e.updating;) await new Promise((t) => e.addEventListener("updateend", t, { once: !0 }));
|
|
1359
1379
|
for (e.appendBuffer(t); e.updating;) await new Promise((t) => e.addEventListener("updateend", t, { once: !0 }));
|
|
1360
1380
|
}
|
|
1361
|
-
#a(
|
|
1381
|
+
#a(e, n, r, i, a) {
|
|
1362
1382
|
if (r.container.kind !== "cmaf") throw Error("unreachable");
|
|
1363
|
-
let o = p(r.container.init),
|
|
1364
|
-
|
|
1383
|
+
let o = p(r.container.init), s = c.Cmaf.decodeInitSegment(o);
|
|
1384
|
+
e.spawn(async () => {
|
|
1365
1385
|
for (await this.#i(i, o);;) {
|
|
1366
|
-
let
|
|
1367
|
-
if (!
|
|
1368
|
-
let r =
|
|
1369
|
-
this.source.sync.received(
|
|
1386
|
+
let e = await n.readFrame();
|
|
1387
|
+
if (!e) return;
|
|
1388
|
+
let r = c.Cmaf.decodeTimestamp(e, s);
|
|
1389
|
+
this.source.sync.received(t.Time.Milli.fromMicro(r), "audio"), await this.#i(i, e), a.buffered.length > 0 && a.currentTime < a.buffered.start(0) && (a.currentTime = a.buffered.start(0));
|
|
1370
1390
|
}
|
|
1371
1391
|
});
|
|
1372
1392
|
}
|
|
1373
|
-
#o(
|
|
1374
|
-
let o = r.container.kind === "loc" ? new
|
|
1393
|
+
#o(e, n, r, i, a) {
|
|
1394
|
+
let o = r.container.kind === "loc" ? new c.Loc.Format() : new c.Legacy.Format(), s = new c.Consumer(n, {
|
|
1375
1395
|
format: o,
|
|
1376
1396
|
latency: this.source.sync.buffer
|
|
1377
1397
|
});
|
|
1378
|
-
|
|
1379
|
-
let
|
|
1380
|
-
await this.#i(i,
|
|
1398
|
+
e.cleanup(() => s.close()), e.spawn(async () => {
|
|
1399
|
+
let e = c.Cmaf.createAudioInitSegment(r);
|
|
1400
|
+
await this.#i(i, e);
|
|
1381
1401
|
let n = 1, o, l;
|
|
1382
1402
|
for (;;) {
|
|
1383
|
-
let
|
|
1384
|
-
if (!
|
|
1385
|
-
if (!
|
|
1386
|
-
l =
|
|
1387
|
-
let n =
|
|
1403
|
+
let e = await s.next();
|
|
1404
|
+
if (!e) return;
|
|
1405
|
+
if (!e.frame) continue;
|
|
1406
|
+
l = e.frame;
|
|
1407
|
+
let n = t.Time.Milli.fromMicro(l.timestamp);
|
|
1388
1408
|
this.source.sync.received(n, "audio");
|
|
1389
1409
|
break;
|
|
1390
1410
|
}
|
|
1391
1411
|
for (;;) {
|
|
1392
|
-
let
|
|
1393
|
-
if (
|
|
1394
|
-
let r =
|
|
1412
|
+
let e = await s.next();
|
|
1413
|
+
if (e && !e.frame) continue;
|
|
1414
|
+
let r = e?.frame;
|
|
1395
1415
|
if (r) {
|
|
1396
|
-
o =
|
|
1397
|
-
let
|
|
1398
|
-
this.source.sync.received(
|
|
1416
|
+
o = t.Time.Micro.sub(r.timestamp, l.timestamp);
|
|
1417
|
+
let e = t.Time.Milli.fromMicro(r.timestamp);
|
|
1418
|
+
this.source.sync.received(e, "audio");
|
|
1399
1419
|
}
|
|
1400
|
-
let u =
|
|
1420
|
+
let u = c.Cmaf.encodeDataSegment({
|
|
1401
1421
|
data: l.data,
|
|
1402
1422
|
timestamp: l.timestamp,
|
|
1403
1423
|
duration: o ?? 0,
|
|
@@ -1421,26 +1441,26 @@ var se = class {
|
|
|
1421
1441
|
this.#n.close();
|
|
1422
1442
|
}
|
|
1423
1443
|
};
|
|
1424
|
-
async function
|
|
1444
|
+
async function de(e) {
|
|
1425
1445
|
return MediaSource.isTypeSupported(`audio/mp4; codecs="${e.codec}"`);
|
|
1426
1446
|
}
|
|
1427
1447
|
//#endregion
|
|
1428
1448
|
//#region src/audio/source.ts
|
|
1429
|
-
var
|
|
1449
|
+
var fe = 128, Y = class {
|
|
1430
1450
|
broadcast;
|
|
1431
1451
|
target;
|
|
1432
1452
|
catalog;
|
|
1433
|
-
#e = new
|
|
1453
|
+
#e = new a({});
|
|
1434
1454
|
available = this.#e;
|
|
1435
|
-
#t = new
|
|
1455
|
+
#t = new a(void 0);
|
|
1436
1456
|
track = this.#t;
|
|
1437
|
-
#n = new
|
|
1457
|
+
#n = new a(void 0);
|
|
1438
1458
|
config = this.#n;
|
|
1439
1459
|
supported;
|
|
1440
1460
|
sync;
|
|
1441
|
-
#r = new
|
|
1461
|
+
#r = new i();
|
|
1442
1462
|
constructor(e, t) {
|
|
1443
|
-
this.sync = e, this.broadcast =
|
|
1463
|
+
this.sync = e, this.broadcast = a.from(t?.broadcast), this.target = a.from(t?.target), this.supported = a.from(t?.supported), this.catalog = this.#r.computed((e) => {
|
|
1444
1464
|
let t = e.get(this.broadcast);
|
|
1445
1465
|
return t ? e.get(t.catalog)?.audio : void 0;
|
|
1446
1466
|
}), this.#r.run(this.#i.bind(this)), this.#r.run(this.#a.bind(this));
|
|
@@ -1463,7 +1483,7 @@ var de = 128, Y = class {
|
|
|
1463
1483
|
};
|
|
1464
1484
|
else if (r = this.#o(t), !r) return;
|
|
1465
1485
|
e.set(this.#t, r.track), e.set(this.#n, r.config);
|
|
1466
|
-
let i = (r.config.jitter ??
|
|
1486
|
+
let i = (r.config.jitter ?? pe(r.config) ?? 0) + Math.ceil(fe / r.config.sampleRate * 1e3);
|
|
1467
1487
|
e.set(this.sync.audio, i);
|
|
1468
1488
|
}
|
|
1469
1489
|
#o(e) {
|
|
@@ -1487,24 +1507,24 @@ var de = 128, Y = class {
|
|
|
1487
1507
|
this.#r.close();
|
|
1488
1508
|
}
|
|
1489
1509
|
};
|
|
1490
|
-
function
|
|
1510
|
+
function pe(e) {
|
|
1491
1511
|
if (e.codec.startsWith("opus")) return 20;
|
|
1492
1512
|
if (e.codec.startsWith("mp4a")) return Math.ceil(1024 / e.sampleRate * 1e3);
|
|
1493
1513
|
}
|
|
1494
1514
|
//#endregion
|
|
1495
1515
|
//#region src/audio/index.ts
|
|
1496
|
-
var
|
|
1516
|
+
var me = /* @__PURE__ */ f({
|
|
1497
1517
|
Decoder: () => E,
|
|
1498
1518
|
Emitter: () => A,
|
|
1499
1519
|
Mse: () => J,
|
|
1500
1520
|
Source: () => Y
|
|
1501
|
-
}),
|
|
1502
|
-
function
|
|
1521
|
+
}), he = 48e3, X = 2;
|
|
1522
|
+
function Z(e) {
|
|
1503
1523
|
let t = "";
|
|
1504
1524
|
for (let n = 0; n < e.length; n++) t += e[n].toString(16).padStart(2, "0");
|
|
1505
1525
|
return t;
|
|
1506
1526
|
}
|
|
1507
|
-
function
|
|
1527
|
+
function Q(e) {
|
|
1508
1528
|
let t;
|
|
1509
1529
|
try {
|
|
1510
1530
|
t = e.initData ? p(e.initData) : void 0;
|
|
@@ -1519,21 +1539,21 @@ function Z(e) {
|
|
|
1519
1539
|
description: void 0
|
|
1520
1540
|
} : {
|
|
1521
1541
|
container: { kind: "legacy" },
|
|
1522
|
-
description: t ?
|
|
1542
|
+
description: t ? Z(t) : void 0
|
|
1523
1543
|
};
|
|
1524
1544
|
}
|
|
1525
1545
|
function ge(e) {
|
|
1526
1546
|
if (!e.codec) return;
|
|
1527
|
-
let { container: t, description: n } =
|
|
1547
|
+
let { container: t, description: n } = Q(e);
|
|
1528
1548
|
return {
|
|
1529
1549
|
codec: e.codec,
|
|
1530
1550
|
container: t,
|
|
1531
1551
|
description: n,
|
|
1532
|
-
codedWidth: e.width == null ? void 0 :
|
|
1533
|
-
codedHeight: e.height == null ? void 0 :
|
|
1552
|
+
codedWidth: e.width == null ? void 0 : s(e.width),
|
|
1553
|
+
codedHeight: e.height == null ? void 0 : s(e.height),
|
|
1534
1554
|
framerate: e.framerate,
|
|
1535
|
-
bitrate: e.bitrate == null ? void 0 :
|
|
1536
|
-
jitter: e.jitter == null ? void 0 :
|
|
1555
|
+
bitrate: e.bitrate == null ? void 0 : s(e.bitrate),
|
|
1556
|
+
jitter: e.jitter == null ? void 0 : s(e.jitter)
|
|
1537
1557
|
};
|
|
1538
1558
|
}
|
|
1539
1559
|
function _e(e) {
|
|
@@ -1542,18 +1562,18 @@ function _e(e) {
|
|
|
1542
1562
|
if (!e.channelConfig) return X;
|
|
1543
1563
|
let t = Number.parseInt(e.channelConfig, 10);
|
|
1544
1564
|
return Number.isFinite(t) ? t : X;
|
|
1545
|
-
})(), { container: n, description: r } =
|
|
1565
|
+
})(), { container: n, description: r } = Q(e);
|
|
1546
1566
|
return {
|
|
1547
1567
|
codec: e.codec,
|
|
1548
1568
|
container: n,
|
|
1549
1569
|
description: r,
|
|
1550
|
-
sampleRate:
|
|
1551
|
-
numberOfChannels:
|
|
1552
|
-
bitrate: e.bitrate == null ? void 0 :
|
|
1553
|
-
jitter: e.jitter == null ? void 0 :
|
|
1570
|
+
sampleRate: s(e.samplerate ?? he),
|
|
1571
|
+
numberOfChannels: s(t),
|
|
1572
|
+
bitrate: e.bitrate == null ? void 0 : s(e.bitrate),
|
|
1573
|
+
jitter: e.jitter == null ? void 0 : s(e.jitter)
|
|
1554
1574
|
};
|
|
1555
1575
|
}
|
|
1556
|
-
function
|
|
1576
|
+
function ve(e) {
|
|
1557
1577
|
let t = {}, n = {};
|
|
1558
1578
|
for (let r of e.tracks) if (r.role === "video") {
|
|
1559
1579
|
let e = ge(r);
|
|
@@ -1567,25 +1587,25 @@ function Q(e) {
|
|
|
1567
1587
|
}
|
|
1568
1588
|
//#endregion
|
|
1569
1589
|
//#region src/broadcast.ts
|
|
1570
|
-
var $ = [...
|
|
1571
|
-
function
|
|
1590
|
+
var $ = [...o.FORMATS, "manual"];
|
|
1591
|
+
function ye(e) {
|
|
1572
1592
|
if (e !== null) return $.find((t) => t === e);
|
|
1573
1593
|
}
|
|
1574
|
-
var
|
|
1594
|
+
var be = class {
|
|
1575
1595
|
connection;
|
|
1576
1596
|
enabled;
|
|
1577
1597
|
name;
|
|
1578
|
-
status = new
|
|
1598
|
+
status = new a("offline");
|
|
1579
1599
|
reload;
|
|
1580
1600
|
catalogFormat;
|
|
1581
|
-
#e = new
|
|
1601
|
+
#e = new a(void 0);
|
|
1582
1602
|
active = this.#e;
|
|
1583
1603
|
catalog;
|
|
1584
1604
|
#t;
|
|
1585
|
-
#n = new
|
|
1586
|
-
signals = new
|
|
1605
|
+
#n = new a(!1);
|
|
1606
|
+
signals = new i();
|
|
1587
1607
|
constructor(e) {
|
|
1588
|
-
this.connection =
|
|
1608
|
+
this.connection = a.from(e?.connection), this.name = a.from(e?.name ?? n.empty()), this.enabled = a.from(e?.enabled ?? !1), this.reload = a.from(e?.reload ?? !1), this.catalogFormat = a.from(e?.catalogFormat), this.catalog = a.from(e?.catalog), this.#t = e?.announced ?? new a(/* @__PURE__ */ new Set()), this.signals.run(this.#r.bind(this)), this.signals.run(this.#i.bind(this)), this.signals.run(this.#a.bind(this));
|
|
1589
1609
|
}
|
|
1590
1610
|
#r(e) {
|
|
1591
1611
|
if (!e.get(this.reload)) {
|
|
@@ -1606,33 +1626,33 @@ var ye = class {
|
|
|
1606
1626
|
let n = e.get(this.name), r = t.consume(n);
|
|
1607
1627
|
e.cleanup(() => r.close()), e.set(this.#e, r, void 0);
|
|
1608
1628
|
}
|
|
1609
|
-
#a(
|
|
1610
|
-
if (!
|
|
1611
|
-
let
|
|
1612
|
-
if (
|
|
1613
|
-
let
|
|
1614
|
-
this.status.set(
|
|
1629
|
+
#a(t) {
|
|
1630
|
+
if (!t.get(this.enabled)) return;
|
|
1631
|
+
let n = t.get(this.catalogFormat), r = t.get(this.name), i = n ?? o.detectFormat(r) ?? o.DEFAULT_FORMAT;
|
|
1632
|
+
if (i === "manual") {
|
|
1633
|
+
let e = t.get(this.catalog);
|
|
1634
|
+
this.status.set(e ? "live" : "loading");
|
|
1615
1635
|
return;
|
|
1616
1636
|
}
|
|
1617
|
-
let
|
|
1618
|
-
if (!
|
|
1637
|
+
let a = t.get(this.active);
|
|
1638
|
+
if (!a) return;
|
|
1619
1639
|
this.status.set("loading");
|
|
1620
|
-
let
|
|
1621
|
-
|
|
1622
|
-
let
|
|
1623
|
-
if (
|
|
1624
|
-
let
|
|
1625
|
-
|
|
1626
|
-
} else
|
|
1627
|
-
let e = await u.fetch(
|
|
1628
|
-
return e ?
|
|
1640
|
+
let s = i === "hang" ? "catalog.json" : "catalog", c = a.subscribe(s, o.PRIORITY.catalog);
|
|
1641
|
+
t.cleanup(() => c.close());
|
|
1642
|
+
let l;
|
|
1643
|
+
if (i === "hang") {
|
|
1644
|
+
let t = new e.Consumer(c, { schema: o.RootSchema });
|
|
1645
|
+
l = () => t.next();
|
|
1646
|
+
} else l = async () => {
|
|
1647
|
+
let e = await u.fetch(c);
|
|
1648
|
+
return e ? ve(e) : void 0;
|
|
1629
1649
|
};
|
|
1630
|
-
|
|
1650
|
+
t.spawn(async () => {
|
|
1631
1651
|
try {
|
|
1632
1652
|
for (;;) {
|
|
1633
|
-
let
|
|
1634
|
-
if (!
|
|
1635
|
-
console.debug("received catalog",
|
|
1653
|
+
let e = await Promise.race([t.cancel, l()]);
|
|
1654
|
+
if (!e) break;
|
|
1655
|
+
console.debug("received catalog", i, this.name.peek(), e), this.catalog.set(e), this.status.set("live");
|
|
1636
1656
|
}
|
|
1637
1657
|
} catch (e) {
|
|
1638
1658
|
console.warn("error fetching catalog", this.name.peek(), e);
|
|
@@ -1641,11 +1661,20 @@ var ye = class {
|
|
|
1641
1661
|
}
|
|
1642
1662
|
});
|
|
1643
1663
|
}
|
|
1664
|
+
subscribeTrack(e, t, n) {
|
|
1665
|
+
let r = new i();
|
|
1666
|
+
return r.run((r) => {
|
|
1667
|
+
let i = r.get(this.active);
|
|
1668
|
+
if (!i) return;
|
|
1669
|
+
let a = i.subscribe(e, t);
|
|
1670
|
+
r.cleanup(() => a.close()), n(a, r);
|
|
1671
|
+
}), this.signals.cleanup(() => r.close()), () => r.close();
|
|
1672
|
+
}
|
|
1644
1673
|
close() {
|
|
1645
1674
|
this.signals.close();
|
|
1646
1675
|
}
|
|
1647
1676
|
};
|
|
1648
1677
|
//#endregion
|
|
1649
|
-
export {
|
|
1678
|
+
export { ue as a, N as c, me as i, ie as l, $ as n, q as o, ye as r, K as s, be as t };
|
|
1650
1679
|
|
|
1651
|
-
//# sourceMappingURL=broadcast-
|
|
1680
|
+
//# sourceMappingURL=broadcast-80k1hgfM.js.map
|