@spatius/avatarkit 1.3.5-beta.1 → 1.3.6

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.
@@ -1,142 +0,0 @@
1
- import { t as logger } from "./logger-BCrlTIt2.js";
2
- //#region audio/OpusDecoderProxy.ts
3
- var OpusDecoderProxy = class OpusDecoderProxy {
4
- worker = null;
5
- fallbackDecoder = null;
6
- pending = /* @__PURE__ */ new Map();
7
- seq = 0;
8
- backend = "main-thread";
9
- constructor() {}
10
- /**
11
- * Create the decoder, selecting the best backend. Never rejects: it degrades
12
- * through worker → main-thread so a connection always gets a working decoder.
13
- * Resolves once the chosen backend is ready.
14
- */
15
- static async create() {
16
- const proxy = new OpusDecoderProxy();
17
- try {
18
- await proxy.startWorker();
19
- proxy.backend = "worker";
20
- return proxy;
21
- } catch (err) {
22
- logger.warn("[Opus][DecoderProxy] Worker unavailable, falling back to main-thread decode:", err instanceof Error ? err.message : String(err));
23
- }
24
- const { OggOpusDecoder } = await import("./OpusCodec-BYwstcZb.js").then((n) => n.n);
25
- proxy.fallbackDecoder = new OggOpusDecoder();
26
- proxy.backend = "main-thread";
27
- return proxy;
28
- }
29
- startWorker() {
30
- return new Promise((resolve, reject) => {
31
- let worker;
32
- try {
33
- worker = new Worker(new URL(
34
- /* @vite-ignore */
35
- "" + new URL("assets/OpusDecoderWorker.worker-DkKhJmGs.js", import.meta.url).href,
36
- "" + import.meta.url
37
- ), { type: "module" });
38
- } catch (err) {
39
- reject(err instanceof Error ? err : new Error(String(err)));
40
- return;
41
- }
42
- let ready = false;
43
- const initTimeout = setTimeout(() => {
44
- if (!ready) {
45
- worker.terminate();
46
- reject(/* @__PURE__ */ new Error("worker init timeout"));
47
- }
48
- }, 3e3);
49
- worker.onmessage = (e) => {
50
- const d = e.data;
51
- if (d.type === "ready") {
52
- ready = true;
53
- clearTimeout(initTimeout);
54
- this.worker = worker;
55
- resolve();
56
- return;
57
- }
58
- if (d.type === "pcm") {
59
- this.pending.get(d.seq)?.resolve({
60
- pcm: new Uint8Array(d.pcm),
61
- segments: d.segments ?? [],
62
- segmentTs: (d.segmentTs ?? []).map((ts) => ts - performance.timeOrigin)
63
- });
64
- this.pending.delete(d.seq);
65
- return;
66
- }
67
- if (d.type === "error") {
68
- this.pending.get(d.seq)?.reject(new Error(d.message));
69
- this.pending.delete(d.seq);
70
- }
71
- };
72
- worker.onerror = (e) => {
73
- clearTimeout(initTimeout);
74
- const err = new Error(e.message || "worker error");
75
- if (!ready) {
76
- reject(err);
77
- return;
78
- }
79
- for (const p of this.pending.values()) p.reject(err);
80
- this.pending.clear();
81
- };
82
- worker.postMessage({ type: "init" });
83
- });
84
- }
85
- /**
86
- * Decode one slice of an Ogg Opus stream, resolving with the PCM16 (mono LE)
87
- * decoded so far (possibly empty for header-only slices). On the worker path the
88
- * main thread stays free while decoding runs; on the fallback path this blocks
89
- * the main thread (same as the legacy synchronous behavior).
90
- *
91
- * The caller (AvatarController) must serialize these in feed order — the decoder
92
- * is stateful. See its inputDecodeChain.
93
- */
94
- decode(ogg) {
95
- if (this.worker) {
96
- const seq = this.seq++;
97
- return new Promise((resolve, reject) => {
98
- this.pending.set(seq, {
99
- resolve,
100
- reject
101
- });
102
- this.worker.postMessage({
103
- type: "decode",
104
- ogg,
105
- seq
106
- });
107
- });
108
- }
109
- if (this.fallbackDecoder) try {
110
- const segments = [];
111
- const segmentTs = [];
112
- const pcm = this.fallbackDecoder.decode(ogg, (seg) => {
113
- segments.push(seg.length);
114
- segmentTs.push(performance.now());
115
- });
116
- return Promise.resolve({
117
- pcm,
118
- segments,
119
- segmentTs
120
- });
121
- } catch (err) {
122
- return Promise.reject(err instanceof Error ? err : new Error(String(err)));
123
- }
124
- return Promise.reject(/* @__PURE__ */ new Error("OpusDecoderProxy not initialized"));
125
- }
126
- /** Tear down whichever backend is active. Call once on disconnect. */
127
- destroy() {
128
- for (const p of this.pending.values()) p.reject(/* @__PURE__ */ new Error("decoder destroyed"));
129
- this.pending.clear();
130
- if (this.worker) {
131
- this.worker.postMessage({ type: "destroy" });
132
- this.worker.terminate();
133
- this.worker = null;
134
- }
135
- if (this.fallbackDecoder) {
136
- this.fallbackDecoder.destroy();
137
- this.fallbackDecoder = null;
138
- }
139
- }
140
- };
141
- //#endregion
142
- export { OpusDecoderProxy };
@@ -1,170 +0,0 @@
1
- import { n as __exportAll } from "./rolldown-runtime-B-1-B7_t.js";
2
- import { t as logger } from "./logger-BCrlTIt2.js";
3
- //#region audio/OpusEncoderProxy.ts
4
- var OpusEncoderProxy_exports = /* @__PURE__ */ __exportAll({
5
- OpusEncoderProxy: () => OpusEncoderProxy,
6
- setOpusEncodeFrameSink: () => setOpusEncodeFrameSink
7
- });
8
- /**
9
- * 逐帧编码时刻的接收钩子。由 `AnimationWebSocketClient` 装上,转交 trace 打点。
10
- *
11
- * 与解码那侧同理:编码在 Worker 里逐帧进行,结果打成页一起返回;只有把每帧的时刻
12
- * 带回来,span 才能按音频秒数切,而不是把整批耗时算成一段。
13
- * @internal
14
- */
15
- var onEncodeFrames = null;
16
- /** @internal */
17
- function setOpusEncodeFrameSink(fn) {
18
- onEncodeFrames = fn;
19
- }
20
- var OpusEncoderProxy = class OpusEncoderProxy {
21
- worker = null;
22
- fallbackEncoder = null;
23
- pending = /* @__PURE__ */ new Map();
24
- seq = 0;
25
- sampleRate;
26
- bitrate;
27
- backend = "main-thread";
28
- constructor(sampleRate, bitrate) {
29
- this.sampleRate = sampleRate;
30
- this.bitrate = bitrate;
31
- }
32
- /**
33
- * Create the encoder, selecting the best backend. Never rejects: it degrades
34
- * through worker → main-thread so a connection always gets a working encoder.
35
- * Resolves once the chosen backend is ready.
36
- */
37
- static async create(sampleRate, bitrate) {
38
- const proxy = new OpusEncoderProxy(sampleRate, bitrate);
39
- try {
40
- await proxy.startWorker();
41
- proxy.backend = "worker";
42
- return proxy;
43
- } catch (err) {
44
- logger.warn("[Opus][Proxy] Worker unavailable, falling back to main-thread encode:", err instanceof Error ? err.message : String(err));
45
- }
46
- const { OggOpusEncoder } = await import("./OpusCodec-BYwstcZb.js").then((n) => n.n);
47
- proxy.fallbackEncoder = new OggOpusEncoder(sampleRate, bitrate);
48
- proxy.backend = "main-thread";
49
- return proxy;
50
- }
51
- startWorker() {
52
- return new Promise((resolve, reject) => {
53
- let worker;
54
- try {
55
- worker = new Worker(new URL(
56
- /* @vite-ignore */
57
- "" + new URL("assets/OpusEncoderWorker.worker-Bu8QRO55.js", import.meta.url).href,
58
- "" + import.meta.url
59
- ), { type: "module" });
60
- } catch (err) {
61
- reject(err instanceof Error ? err : new Error(String(err)));
62
- return;
63
- }
64
- let ready = false;
65
- const initTimeout = setTimeout(() => {
66
- if (!ready) {
67
- worker.terminate();
68
- reject(/* @__PURE__ */ new Error("worker init timeout"));
69
- }
70
- }, 3e3);
71
- worker.onmessage = (e) => {
72
- const d = e.data;
73
- if (d.type === "ready") {
74
- ready = true;
75
- clearTimeout(initTimeout);
76
- this.worker = worker;
77
- resolve();
78
- return;
79
- }
80
- if (d.type === "pages") {
81
- if (!d.last) {
82
- this.pending.get(d.seq)?.onPages(d.pages);
83
- return;
84
- }
85
- onEncodeFrames?.(d.frames ?? [], (d.frameTs ?? []).map((ts) => ts - performance.timeOrigin));
86
- this.pending.get(d.seq)?.resolve(d.pages);
87
- this.pending.delete(d.seq);
88
- return;
89
- }
90
- if (d.type === "error") {
91
- this.pending.get(d.seq)?.reject(new Error(d.message));
92
- this.pending.delete(d.seq);
93
- }
94
- };
95
- worker.onerror = (e) => {
96
- clearTimeout(initTimeout);
97
- const err = new Error(e.message || "worker error");
98
- if (!ready) {
99
- reject(err);
100
- return;
101
- }
102
- for (const p of this.pending.values()) p.reject(err);
103
- this.pending.clear();
104
- };
105
- worker.postMessage({
106
- type: "init",
107
- sampleRate: this.sampleRate,
108
- bitrate: this.bitrate
109
- });
110
- });
111
- }
112
- /**
113
- * Encode one PCM chunk, resolving with the Ogg pages to send (in order). On the
114
- * worker path the main thread stays free while encoding runs; on the fallback
115
- * path this blocks the main thread (same as the legacy behavior).
116
- */
117
- /**
118
- * @param onPages 每凑满 1 秒音频回调一次那一批页,调用方应立刻发出去。
119
- * 返回的 Promise 只带**收尾批**(通常为空)——所有页都从这个回调出去,等
120
- * Promise 再发会退回「整段编完才发」,白等一秒以上(见 OpusCodec.encode)。
121
- */
122
- encode(reqId, pcm, end, onPages = () => {}) {
123
- if (this.worker) {
124
- const seq = this.seq++;
125
- return new Promise((resolve, reject) => {
126
- this.pending.set(seq, {
127
- resolve,
128
- reject,
129
- onPages
130
- });
131
- this.worker.postMessage({
132
- type: "encode",
133
- reqId,
134
- pcm,
135
- end,
136
- seq
137
- });
138
- });
139
- }
140
- if (this.fallbackEncoder) try {
141
- const frames = [];
142
- const frameTs = [];
143
- const pages = this.fallbackEncoder.encode(reqId, pcm, end, (pcmBytes) => {
144
- frames.push(pcmBytes);
145
- frameTs.push(performance.now());
146
- }, onPages);
147
- onEncodeFrames?.(frames, frameTs);
148
- return Promise.resolve(pages);
149
- } catch (err) {
150
- return Promise.reject(err instanceof Error ? err : new Error(String(err)));
151
- }
152
- return Promise.reject(/* @__PURE__ */ new Error("OpusEncoderProxy not initialized"));
153
- }
154
- /** Tear down whichever backend is active. Call once on disconnect. */
155
- destroy() {
156
- for (const p of this.pending.values()) p.reject(/* @__PURE__ */ new Error("encoder destroyed"));
157
- this.pending.clear();
158
- if (this.worker) {
159
- this.worker.postMessage({ type: "destroy" });
160
- this.worker.terminate();
161
- this.worker = null;
162
- }
163
- if (this.fallbackEncoder) {
164
- this.fallbackEncoder.destroy();
165
- this.fallbackEncoder = null;
166
- }
167
- }
168
- };
169
- //#endregion
170
- export { setOpusEncodeFrameSink as n, OpusEncoderProxy_exports as t };