@spatialwalk/avatarkit 1.0.0-beta.76 → 1.0.0-beta.77
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/dist/{StreamingAudioPlayer-CuNtk6eL.js → StreamingAudioPlayer-BtOgYxcz.js} +79 -9
- package/dist/avatar_core_wasm-e68766db.wasm +0 -0
- package/dist/core/AvatarController.d.ts +1 -0
- package/dist/{index-ZN-iK3b8.js → index-CTh2onXJ.js} +2677 -206
- package/dist/index.js +1 -1
- package/dist/renderer/webgpu/flameGPUBuffers.d.ts +137 -0
- package/dist/renderer/webgpu/flamePipeline.d.ts +71 -0
- package/dist/renderer/webgpu/gpuRadixSort.d.ts +47 -0
- package/dist/renderer/webgpu/transformPipeline.d.ts +97 -0
- package/dist/renderer/webgpu/webgpuRenderer.d.ts +57 -0
- package/dist/types/index.d.ts +1 -2
- package/dist/wasm/avatarCoreAdapter.d.ts +49 -0
- package/dist/wasm/avatarCoreMemory.d.ts +13 -0
- package/package.json +14 -13
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { A as APP_CONFIG, l as logger, e as errorToMessage, a as logEvent } from "./index-
|
|
4
|
+
import { A as APP_CONFIG, l as logger, e as errorToMessage, a as logEvent } from "./index-CTh2onXJ.js";
|
|
5
5
|
class StreamingAudioPlayer {
|
|
6
6
|
// Mark if AudioContext is being resumed, avoid concurrent resume requests
|
|
7
7
|
constructor(options) {
|
|
@@ -40,6 +40,18 @@ class StreamingAudioPlayer {
|
|
|
40
40
|
// Timestamp of last getCurrentTime log (for throttling)
|
|
41
41
|
// Track start time (absolute time) and duration of each scheduled chunk for accurate current playback time calculation
|
|
42
42
|
__publicField(this, "scheduledChunkInfo", []);
|
|
43
|
+
// 🚀 Chunk 合并优化:减少 AudioNode 创建数量
|
|
44
|
+
__publicField(this, "pendingChunks", []);
|
|
45
|
+
// 待合并的小 chunk
|
|
46
|
+
__publicField(this, "pendingBytesTotal", 0);
|
|
47
|
+
// 待合并的总字节数
|
|
48
|
+
__publicField(this, "isFirstMerge", true);
|
|
49
|
+
// 是否是首次合并(用于首包缓冲)
|
|
50
|
+
// 合并阈值:动态计算
|
|
51
|
+
__publicField(this, "MERGE_THRESHOLD_MS", 500);
|
|
52
|
+
// 后续合并阈值(500ms)
|
|
53
|
+
__publicField(this, "FIRST_BUFFER_THRESHOLD_MS", 250);
|
|
54
|
+
// 首包缓冲阈值(250ms)- 牺牲一点延迟换取流畅播放
|
|
43
55
|
// Volume control
|
|
44
56
|
__publicField(this, "gainNode", null);
|
|
45
57
|
__publicField(this, "volume", 1);
|
|
@@ -153,6 +165,37 @@ class StreamingAudioPlayer {
|
|
|
153
165
|
}
|
|
154
166
|
}
|
|
155
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* 🚀 合并待处理的小 chunks 成一个大 chunk
|
|
170
|
+
*/
|
|
171
|
+
mergePendingChunks() {
|
|
172
|
+
if (this.pendingChunks.length === 0) {
|
|
173
|
+
return new Uint8Array(0);
|
|
174
|
+
}
|
|
175
|
+
if (this.pendingChunks.length === 1) {
|
|
176
|
+
const result = this.pendingChunks[0];
|
|
177
|
+
this.pendingChunks = [];
|
|
178
|
+
this.pendingBytesTotal = 0;
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
const merged = new Uint8Array(this.pendingBytesTotal);
|
|
182
|
+
let offset = 0;
|
|
183
|
+
for (const chunk of this.pendingChunks) {
|
|
184
|
+
merged.set(chunk, offset);
|
|
185
|
+
offset += chunk.length;
|
|
186
|
+
}
|
|
187
|
+
this.pendingChunks = [];
|
|
188
|
+
this.pendingBytesTotal = 0;
|
|
189
|
+
return merged;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* 计算合并阈值(基于实际采样率)
|
|
193
|
+
* @param isFirst 是否是首次合并(使用较小的首包缓冲阈值)
|
|
194
|
+
*/
|
|
195
|
+
getMergeThresholdBytes(isFirst = false) {
|
|
196
|
+
const thresholdMs = isFirst ? this.FIRST_BUFFER_THRESHOLD_MS : this.MERGE_THRESHOLD_MS;
|
|
197
|
+
return this.sampleRate * this.channelCount * 2 * (thresholdMs / 1e3);
|
|
198
|
+
}
|
|
156
199
|
/**
|
|
157
200
|
* Add audio chunk (16-bit PCM)
|
|
158
201
|
*/
|
|
@@ -166,14 +209,29 @@ class StreamingAudioPlayer {
|
|
|
166
209
|
logger.errorWithError("[StreamingAudioPlayer] Failed to ensure AudioContext running in addChunk:", err);
|
|
167
210
|
});
|
|
168
211
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
212
|
+
if (pcmData.length > 0) {
|
|
213
|
+
this.pendingChunks.push(pcmData);
|
|
214
|
+
this.pendingBytesTotal += pcmData.length;
|
|
215
|
+
}
|
|
216
|
+
const mergeThreshold = this.getMergeThresholdBytes(this.isFirstMerge);
|
|
217
|
+
const shouldMerge = isLast || this.pendingBytesTotal >= mergeThreshold;
|
|
218
|
+
if (shouldMerge && this.pendingBytesTotal > 0) {
|
|
219
|
+
const mergedData = this.mergePendingChunks();
|
|
220
|
+
this.audioChunks.push({ data: mergedData, isLast });
|
|
221
|
+
this.isFirstMerge = false;
|
|
222
|
+
this.log(`Added merged chunk ${this.audioChunks.length}`, {
|
|
223
|
+
size: mergedData.length,
|
|
224
|
+
totalChunks: this.audioChunks.length,
|
|
225
|
+
isLast,
|
|
226
|
+
isPlaying: this.isPlaying,
|
|
227
|
+
scheduledChunks: this.scheduledChunks
|
|
228
|
+
});
|
|
229
|
+
} else if (isLast && this.pendingBytesTotal === 0) {
|
|
230
|
+
this.audioChunks.push({ data: new Uint8Array(0), isLast: true });
|
|
231
|
+
} else {
|
|
232
|
+
this.log(`Accumulating chunk, pending: ${this.pendingBytesTotal} bytes (threshold: ${mergeThreshold}, isFirstMerge: ${this.isFirstMerge})`);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
177
235
|
if (this.autoContinue && this.isPaused) {
|
|
178
236
|
this.log("[StreamingAudioPlayer] autoContinue=true, auto-resuming playback");
|
|
179
237
|
this.autoContinue = false;
|
|
@@ -201,6 +259,9 @@ class StreamingAudioPlayer {
|
|
|
201
259
|
this.sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
202
260
|
this.audioChunks = [];
|
|
203
261
|
this.scheduledChunks = 0;
|
|
262
|
+
this.pendingChunks = [];
|
|
263
|
+
this.pendingBytesTotal = 0;
|
|
264
|
+
this.isFirstMerge = true;
|
|
204
265
|
this.pausedTimeOffset = 0;
|
|
205
266
|
this.pausedAt = 0;
|
|
206
267
|
this.pausedAudioContextTime = 0;
|
|
@@ -510,6 +571,9 @@ class StreamingAudioPlayer {
|
|
|
510
571
|
this.activeSources.clear();
|
|
511
572
|
this.audioChunks = [];
|
|
512
573
|
this.scheduledChunks = 0;
|
|
574
|
+
this.pendingChunks = [];
|
|
575
|
+
this.pendingBytesTotal = 0;
|
|
576
|
+
this.isFirstMerge = true;
|
|
513
577
|
this.autoContinue = false;
|
|
514
578
|
this.log("[StreamingAudioPlayer] Playback stopped, state reset");
|
|
515
579
|
}
|
|
@@ -570,6 +634,9 @@ class StreamingAudioPlayer {
|
|
|
570
634
|
}
|
|
571
635
|
this.audioChunks = [];
|
|
572
636
|
this.scheduledChunks = 0;
|
|
637
|
+
this.pendingChunks = [];
|
|
638
|
+
this.pendingBytesTotal = 0;
|
|
639
|
+
this.isFirstMerge = true;
|
|
573
640
|
this.sessionStartTime = 0;
|
|
574
641
|
this.pausedTimeOffset = 0;
|
|
575
642
|
this.pausedAt = 0;
|
|
@@ -589,6 +656,9 @@ class StreamingAudioPlayer {
|
|
|
589
656
|
this.stop();
|
|
590
657
|
this.audioChunks = [];
|
|
591
658
|
this.scheduledChunks = 0;
|
|
659
|
+
this.pendingChunks = [];
|
|
660
|
+
this.pendingBytesTotal = 0;
|
|
661
|
+
this.isFirstMerge = true;
|
|
592
662
|
this.sessionStartTime = 0;
|
|
593
663
|
this.pausedAt = 0;
|
|
594
664
|
this.scheduledTime = 0;
|
|
File without changes
|