@spatius/avatarkit 1.3.8 → 1.3.10-beta.1
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/CHANGELOG.md +53 -0
- package/dist/assets/{OpusDecoderWorker.worker-DVOREuTG.js → OpusDecoderWorker.worker-6yl1qL0f.js} +1530 -11428
- package/dist/assets/{OpusEncoderWorker.worker-fkLsXEK1.js → OpusEncoderWorker.worker-BTGeizmj.js} +1530 -11428
- package/dist/core/AvatarController.d.ts +81 -2
- package/dist/core/AvatarSDK.d.ts +14 -3
- package/dist/core/AvatarView.d.ts +33 -33
- package/dist/core/avatarViewRegistry.d.ts +2 -0
- package/dist/index.js +1007 -403
- package/dist/internal-telemetry.d.ts +12 -23
- package/dist/internal-telemetry.js +16 -29
- package/dist/{otel-trace-CZJAGjGg.js → otel-trace-CjdZ3saJ.js} +8306 -18303
- package/dist/types/character.d.ts +0 -13
- package/dist/types/index.d.ts +26 -8
- package/package.json +2 -3
- package/dist/rolldown-runtime-FDOR9p9I.js +0 -24
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
import { Avatar } from './Avatar';
|
|
2
|
-
import { ConnectionState, AvatarError, DrivingServiceMode, FrameStarvationMode, ConversationState, AnimationType } from '../types';
|
|
2
|
+
import { ConnectionState, AvatarError, DrivingServiceMode, FrameStarvationMode, ConversationState, AnimationType, AudioFormat, AudioFormatPatch } from '../types';
|
|
3
3
|
import { FrameRateInfo } from '../performance/FrameRateMonitor';
|
|
4
4
|
export declare class AvatarController {
|
|
5
5
|
private networkLayer?;
|
|
6
6
|
private readonly playbackMode;
|
|
7
|
+
/**
|
|
8
|
+
* 宿主**要求**的音频格式:构造时传入的值,之后由 {@link setAudioFormat} 逐字段合并。
|
|
9
|
+
* 与 `_audioFormat` 分开存,是为了让规范化可逆:22050 + Opus 上行会被规范化成
|
|
10
|
+
* 「Opus 上行关」,之后把采样率改回 16000 时上行应当自动恢复——只存规范化后的值就找
|
|
11
|
+
* 不回宿主原本要的 `opusUplinkEnabled: true` 了。唯一不可逆的一条:切到 Opus 输入时
|
|
12
|
+
* 采样率写死 48000(与 Android / iOS 的 `AudioFormat` 构造语义一致,三端同形)。
|
|
13
|
+
*/
|
|
14
|
+
private _requestedAudioFormat;
|
|
15
|
+
/**
|
|
16
|
+
* 本 view 生效的音频格式(已规范化)。**不是全局的**:同一页面里两个 view 可以跑不同
|
|
17
|
+
* 采样率。构造时定下,之后任一字段都可经 {@link setAudioFormat} 改。
|
|
18
|
+
*/
|
|
19
|
+
private _audioFormat;
|
|
20
|
+
/**
|
|
21
|
+
* 本 view 生效的音频格式(已规范化)。只读——改格式走 {@link setAudioFormat}。
|
|
22
|
+
*
|
|
23
|
+
* 对外可读,与 iOS `AvatarController.audioFormat` / Android `AvatarController.audioFormat`
|
|
24
|
+
* 对齐:宿主传进去的值会被规范化(Opus 输入归一到 48 kHz、不兼容的 Opus 上行采样率会关掉
|
|
25
|
+
* Opus 上行),读回来才能确认实际生效的是什么。
|
|
26
|
+
*/
|
|
27
|
+
get audioFormat(): AudioFormat;
|
|
7
28
|
private isStartingPlayback;
|
|
8
29
|
private currentConversationId;
|
|
9
30
|
private reqEnd;
|
|
@@ -69,6 +90,11 @@ export declare class AvatarController {
|
|
|
69
90
|
private receivedAudioBytes;
|
|
70
91
|
private receivedAnimationFrames;
|
|
71
92
|
private playbackStartedAt;
|
|
93
|
+
/**
|
|
94
|
+
* 新一轮起播时 SDK 自己打断上一轮走的也是 interrupt();那不是宿主的动作,不记
|
|
95
|
+
* lifecycle_api_called。内部调用经 interruptForNewRound() 置位后再进 interrupt()。
|
|
96
|
+
*/
|
|
97
|
+
private suppressLifecycleEvent;
|
|
72
98
|
private playbackEndedAt;
|
|
73
99
|
/**
|
|
74
100
|
* Whether this round's final animation batch (ServerResponseAnimation.end) has arrived.
|
|
@@ -127,11 +153,12 @@ export declare class AvatarController {
|
|
|
127
153
|
/**
|
|
128
154
|
* 音频字节率(bytes/s),按 **实际配置的采样率** 动态计算,而不是写死 16kHz。
|
|
129
155
|
* SDK 支持 8k/16k/22.05k/24k/32k/44.1k/48k,写死会让非 16k 的时长统计整体缩放出错。
|
|
130
|
-
* Opus 输入已被
|
|
156
|
+
* Opus 输入已被 normalizeAudioFormat 归一化成 48000,正是解码后 PCM 的真实采样率。
|
|
131
157
|
*/
|
|
132
158
|
private get audioBytesPerSecond();
|
|
133
159
|
constructor(avatar: Avatar, options?: {
|
|
134
160
|
playbackMode?: DrivingServiceMode;
|
|
161
|
+
audioFormat?: AudioFormat;
|
|
135
162
|
});
|
|
136
163
|
private handleVisibilityChange;
|
|
137
164
|
/**
|
|
@@ -168,6 +195,50 @@ export declare class AvatarController {
|
|
|
168
195
|
* on PCM exactly as before.
|
|
169
196
|
*/
|
|
170
197
|
private normalizeInputAudioToPcm;
|
|
198
|
+
/**
|
|
199
|
+
* 改本 view 的音频格式——**部分更新**:传什么改什么,没传的字段保持原状。
|
|
200
|
+
*
|
|
201
|
+
* 四个字段走同一条路,不区分「重」「轻」:**打断当前轮次 → 销毁音频上下文 → 写入新格式
|
|
202
|
+
* → direct 模式断连**。之后喂入的音频按新格式解释;下次 `start()` 时编码器、输入解码器与
|
|
203
|
+
* 会话配置都按新格式重建。
|
|
204
|
+
*
|
|
205
|
+
* - 不设 idle 门禁:「音频已喂进来、动画还在路上、尚未起播」这个中间态既不是 idle 也不在
|
|
206
|
+
* 播,恰恰必须清干净;interrupt 本就是为此存在的,idle 且无音频时它是空操作。
|
|
207
|
+
* - **只销毁音频上下文,不重建**:`AudioContext` 的采样率是构造参数、Web Audio 不允许改,
|
|
208
|
+
* 而重建需要用户手势——那是 SDK 保证不了、只有宿主知道的前提。宿主在自己的手势回调里调
|
|
209
|
+
* {@link initializeAudioContext} 重建;在那之前 `send()` 会经 `onError` 报
|
|
210
|
+
* `audioContextNotInitialized` 并返回 null,不会静默无声。
|
|
211
|
+
* - 断连而不自动重连:宿主接下来还要重建上下文,连接由它后续的 `start()` 带起。
|
|
212
|
+
*
|
|
213
|
+
* 规则:
|
|
214
|
+
* - 切到 `inputAudioFormat: 'opus'` 时采样率写死 48000(Opus 解码固定值),传了别的值也
|
|
215
|
+
* 会被改写。切回 `'pcm'` 时采样率**保持当前值**(可能是 48000)——要换就在同一次调用里
|
|
216
|
+
* 一起传 `sampleRate`。
|
|
217
|
+
* - 采样率不兼容 Opus 上行(不是 8k/16k/24k/48k)时 Opus 上行会被关掉;之后把采样率改回
|
|
218
|
+
* 兼容值,上行按宿主原本的要求自动恢复。
|
|
219
|
+
* - 传入的值与当前要求完全一致时什么都不做(不打断、不销毁、不断连)。
|
|
220
|
+
*
|
|
221
|
+
* **两种非法用法都只记一条 `logger.error` 后原样返回**,不抛异常也不进 `onError`:
|
|
222
|
+
* 1. `sampleRate` 不在支持列表里(8000 / 16000 / 22050 / 24000 / 32000 / 44100 / 48000)
|
|
223
|
+
* 2. 在 Opus 输入下传 `sampleRate`(无论是本来就是 Opus 输入,还是这一次一起切过去)
|
|
224
|
+
*
|
|
225
|
+
* 都是调用方把代码写错了,不是运行期可恢复的 SDK 故障。走 `onError` 并不更可靠:那是
|
|
226
|
+
* 可选回调,宿主未必注册、注册了也未必打到控制台;为它们新增 ErrorCode 还会平白扩大
|
|
227
|
+
* 三端公开错误码面。注释 + 日志 + 文档已经够让写代码的人当场发现。三端一致。
|
|
228
|
+
*/
|
|
229
|
+
setAudioFormat(patch: AudioFormatPatch): void;
|
|
230
|
+
/**
|
|
231
|
+
* 把错误交给宿主,同时写一条 `logger.error`。
|
|
232
|
+
*
|
|
233
|
+
* **所有 onError 都必须走这里。** 直接调 `this.onError?.()` 的写法曾让 9 个调用点里 7 个
|
|
234
|
+
* 不打日志:宿主如果没把回调接到 console(demo 的 log() 就只写页面面板),这些错误在
|
|
235
|
+
* 控制台完全不可见,排查时看起来像「什么都没发生」——一次上下文未初始化的正常拒绝,
|
|
236
|
+
* 因此被当成功能失效查了很久。
|
|
237
|
+
*
|
|
238
|
+
* 日志走 SDK 自己的 logger(受 logLevel 控制),宿主自己再打一条也无妨:重复一行日志的
|
|
239
|
+
* 代价,远小于一条错误在控制台彻底消失。
|
|
240
|
+
*/
|
|
241
|
+
private emitError;
|
|
171
242
|
/**
|
|
172
243
|
* Start service (SDK mode only)
|
|
173
244
|
*/
|
|
@@ -210,6 +281,14 @@ export declare class AvatarController {
|
|
|
210
281
|
* Animation will continue from paused frame (because animation time base comes from audio, will auto-sync)
|
|
211
282
|
*/
|
|
212
283
|
resume(): Promise<void>;
|
|
284
|
+
/**
|
|
285
|
+
* 宿主调了 close / interrupt(AvatarView.dispose 在 View 里记)。带调用栈:排查
|
|
286
|
+
* "数字人中途消失"时,这条日志直接指出是宿主哪段代码在断连后多久做了什么。
|
|
287
|
+
* 在播时记 warning,便于按级别筛出"播到一半被宿主打断"。
|
|
288
|
+
*/
|
|
289
|
+
private logLifecycleCall;
|
|
290
|
+
/** SDK 内部起新一轮时打断上一轮:走 interrupt() 但不记宿主生命周期事件。 */
|
|
291
|
+
private interruptForNewRound;
|
|
213
292
|
/**
|
|
214
293
|
* Interrupt current playback
|
|
215
294
|
*/
|
package/dist/core/AvatarSDK.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Configuration, RenderQuality } from '../types';
|
|
2
|
+
/** PCM 输入 + Opus 上行时受支持的采样率(Opus 编码器可用的采样率)。 */
|
|
2
3
|
export declare class AvatarSDK {
|
|
3
4
|
private static _initializationState;
|
|
4
5
|
private static _initializingPromise;
|
|
@@ -48,6 +49,15 @@ export declare class AvatarSDK {
|
|
|
48
49
|
/**
|
|
49
50
|
* Cleanup resources
|
|
50
51
|
*/
|
|
52
|
+
private static onPageHide;
|
|
53
|
+
/**
|
|
54
|
+
* pagehide 时直发一条 `page_unload`:整页刷新 / 关闭是"数字人整个消失"的一种来源
|
|
55
|
+
* (宿主自己 reload 切 region 就是实例),服务端只能看到一个 1001,客户端此前什么都
|
|
56
|
+
* 不留。走 emitDirectLog(fetch keepalive)而不是 logEvent——后者先写 IndexedDB 再等
|
|
57
|
+
* 批处理,页面卸载时发不出去。
|
|
58
|
+
*/
|
|
59
|
+
private static installPageHideProbe;
|
|
60
|
+
private static removePageHideProbe;
|
|
51
61
|
static cleanup(): void;
|
|
52
62
|
/**
|
|
53
63
|
* Device performance score (CPU + GPU).
|
|
@@ -63,9 +73,10 @@ export declare class AvatarSDK {
|
|
|
63
73
|
private static readonly GPU_SCORE_THRESHOLD;
|
|
64
74
|
/**
|
|
65
75
|
* Check if the current device can run the avatar.
|
|
66
|
-
* Runs a ~2s benchmark, reports device info and scores
|
|
67
|
-
*
|
|
76
|
+
* Runs a ~2s benchmark, reports device info and scores via telemetry.
|
|
77
|
+
* Returns false when neither WebGL2 nor WebGPU can be created — that is deterministic
|
|
78
|
+
* and the benchmark is skipped. Otherwise runs the benchmark and returns true; the
|
|
79
|
+
* score thresholds are not yet enforced and will be calibrated from production data.
|
|
68
80
|
*/
|
|
69
81
|
static isDeviceSupported(): Promise<boolean>;
|
|
70
|
-
private static _getGPURenderer;
|
|
71
82
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CameraConfig } from '../types';
|
|
1
|
+
import { AvatarViewOptions, CameraConfig } from '../types';
|
|
2
2
|
import { Avatar } from './Avatar';
|
|
3
3
|
import { AvatarController } from './AvatarController';
|
|
4
4
|
export declare class AvatarView {
|
|
@@ -13,6 +13,10 @@ export declare class AvatarView {
|
|
|
13
13
|
private resizeObserver;
|
|
14
14
|
private onWindowResize;
|
|
15
15
|
private onVisibilityChange;
|
|
16
|
+
private canvasSeenConnected;
|
|
17
|
+
private canvasDetachedReported;
|
|
18
|
+
private containerSeenSized;
|
|
19
|
+
private containerHiddenReported;
|
|
16
20
|
private frameCount;
|
|
17
21
|
private lastFpsUpdate;
|
|
18
22
|
private currentFPS;
|
|
@@ -32,8 +36,9 @@ export declare class AvatarView {
|
|
|
32
36
|
* Creates a unified AvatarController, internally composes network layer based on configuration
|
|
33
37
|
* @param avatar - Avatar instance
|
|
34
38
|
* @param container - Canvas container element (required)
|
|
39
|
+
* @param options - Per-view options; see {@link AvatarViewOptions}
|
|
35
40
|
*/
|
|
36
|
-
constructor(avatar: Avatar, container: HTMLElement);
|
|
41
|
+
constructor(avatar: Avatar, container: HTMLElement, options?: AvatarViewOptions);
|
|
37
42
|
/**
|
|
38
43
|
* Get controller (public interface)
|
|
39
44
|
*/
|
|
@@ -100,8 +105,12 @@ export declare class AvatarView {
|
|
|
100
105
|
* to work correctly with WebGL preserveDrawingBuffer:false.
|
|
101
106
|
*/
|
|
102
107
|
exportBitmap(): Promise<Blob | null>;
|
|
103
|
-
/**
|
|
104
|
-
|
|
108
|
+
/**
|
|
109
|
+
* 当前初始化走到哪一步。供构造函数里的最终 catch 上报 `render_init_failed.stage`:
|
|
110
|
+
* 各步骤抛的错误类型五花八门(Error / AvatarError / WASM 抛的字符串),只靠
|
|
111
|
+
* message 没法聚合,stage 才是能按环节切分的低基数字段。
|
|
112
|
+
*/
|
|
113
|
+
private _initStage;
|
|
105
114
|
/**
|
|
106
115
|
* Render a specific idle frame by index for benchmark capture.
|
|
107
116
|
* Bypasses animation loop and _renderingEnabled check.
|
|
@@ -118,11 +127,17 @@ export declare class AvatarView {
|
|
|
118
127
|
*/
|
|
119
128
|
dispose(): void;
|
|
120
129
|
/**
|
|
121
|
-
*
|
|
130
|
+
* 获取相机配置。
|
|
131
|
+
*
|
|
132
|
+
* @deprecated 1.3.9 起弃用,下个版本移除。相机由角色自身的设置决定,渲染基线也按它校准;
|
|
133
|
+
* 宿主侧改 fov / 位置会让画面偏离基线。没有替代接口——请删除宿主侧的相机覆盖逻辑。
|
|
134
|
+
* SDK 自己的评测链路(web-iframe)仍可调用。
|
|
122
135
|
*/
|
|
123
136
|
getCameraConfig(): CameraConfig | null;
|
|
124
137
|
/**
|
|
125
|
-
*
|
|
138
|
+
* 更新相机配置。
|
|
139
|
+
*
|
|
140
|
+
* @deprecated 1.3.9 起弃用,下个版本移除,理由见 {@link getCameraConfig}。
|
|
126
141
|
*/
|
|
127
142
|
updateCameraConfig(cameraConfig: CameraConfig): void;
|
|
128
143
|
/**
|
|
@@ -134,30 +149,6 @@ export declare class AvatarView {
|
|
|
134
149
|
* @param data - Raw protobuf bytes (a single Message containing ServerResponseAnimation)
|
|
135
150
|
*/
|
|
136
151
|
renderFromProtobuf(data: ArrayBuffer | Uint8Array): Promise<void>;
|
|
137
|
-
/**
|
|
138
|
-
* Play a transition from idle to the target frame in the protobuf data,
|
|
139
|
-
* then resolve when the transition is complete.
|
|
140
|
-
*
|
|
141
|
-
* The transition frames are generated and played internally at 25fps.
|
|
142
|
-
* The caller should wait for the returned Promise before pushing streaming frames.
|
|
143
|
-
*
|
|
144
|
-
* @param data - Raw protobuf bytes containing the target frame
|
|
145
|
-
* @param frameCount - Number of transition frames to generate
|
|
146
|
-
* @returns Promise that resolves when the transition playback finishes
|
|
147
|
-
*/
|
|
148
|
-
playTransitionFromProtobuf(data: ArrayBuffer | Uint8Array, frameCount: number): Promise<void>;
|
|
149
|
-
/**
|
|
150
|
-
* Play a transition from current animation back to idle,
|
|
151
|
-
* then start the idle animation loop.
|
|
152
|
-
*
|
|
153
|
-
* Generates reverse transition frames from idle→lastFrame, reverses them,
|
|
154
|
-
* plays at 25fps, then starts idle.
|
|
155
|
-
*
|
|
156
|
-
* @param data - Raw protobuf bytes containing the last animation frame
|
|
157
|
-
* @param frameCount - Number of transition frames to generate
|
|
158
|
-
* @returns Promise that resolves when idle animation starts
|
|
159
|
-
*/
|
|
160
|
-
playTransitionToIdleFromProtobuf(data: ArrayBuffer | Uint8Array, frameCount: number): Promise<void>;
|
|
161
152
|
/**
|
|
162
153
|
* Start idle animation (stop pure rendering mode, resume idle loop).
|
|
163
154
|
*/
|
|
@@ -189,10 +180,19 @@ export declare class AvatarView {
|
|
|
189
180
|
useLinear?: boolean;
|
|
190
181
|
}): Promise<unknown[]>;
|
|
191
182
|
/**
|
|
192
|
-
*
|
|
193
|
-
*
|
|
183
|
+
* canvas 是否还挂在 DOM 上。宿主卸载父组件而没调 dispose() 时,canvas 会跟着容器
|
|
184
|
+
* 一起被移除,SDK 却还在跑:没有任何现有埋点会响。渲染循环每 tick 查一次
|
|
185
|
+
* `isConnected`(不触发 layout),脱离时记一条 error,重新挂回记一条 info。
|
|
186
|
+
* 只在 canvas 曾经在 DOM 里之后才判,避免离屏构造的误报。
|
|
187
|
+
*/
|
|
188
|
+
private probeCanvasAttachment;
|
|
189
|
+
/**
|
|
190
|
+
* 容器被缩成 0×0(display:none 或父级折叠)时 ResizeObserver 会回调一次 0 尺寸。
|
|
191
|
+
* 画面还在 DOM 里但用户看不见,与 detach 是不同的消失方式,分开记。
|
|
192
|
+
* 只在容器曾有过非零尺寸之后才判。
|
|
194
193
|
*/
|
|
195
|
-
|
|
194
|
+
private probeContainerVisibility;
|
|
195
|
+
private syncCanvasSize;
|
|
196
196
|
/** 计算 canvas backing-store 像素尺寸. 默认 css × dpr;
|
|
197
197
|
* AvatarSDK.setRenderResolutionCap 启用且高度超过阈值时,
|
|
198
198
|
* 按比例缩到阈值, css 尺寸不变 (浏览器自动拉伸). */
|
|
@@ -3,6 +3,8 @@ declare class AvatarViewRegistry {
|
|
|
3
3
|
private entries;
|
|
4
4
|
register(view: AvatarView): void;
|
|
5
5
|
unregister(view: AvatarView): void;
|
|
6
|
+
/** 遍历仍存活的 view(顺手清掉已被 GC 的弱引用)。 */
|
|
7
|
+
forEachLive(fn: (view: AvatarView) => void): void;
|
|
6
8
|
applyResolutionCapToAll(): void;
|
|
7
9
|
}
|
|
8
10
|
export declare const avatarViewRegistry: AvatarViewRegistry;
|