@xmov/avatar 2.0.0-alpha.44 → 2.0.0-alpha.47

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmov/avatar",
3
- "version": "2.0.0-alpha.44",
3
+ "version": "2.0.0-alpha.47",
4
4
  "description": "魔珐数字人 JS-SDK",
5
5
  "type": "module",
6
6
  "source": "src/index.ts",
@@ -19,16 +19,11 @@ type Option = {
19
19
  resourceManager: ResourceManager;
20
20
  saveAndDownload: SaveAndDownload;
21
21
  forceSyncDecoder: () => void;
22
- reportMessage: (message: {
23
- code: EErrorCode;
24
- message: string;
25
- e?: object;
26
- }) => void;
22
+ reportMessage: (message: { code: EErrorCode; message: string; e?: object }) => void;
27
23
  onDownloadProgress: (progress: number) => void;
28
24
  onStateChange: (state: string) => void;
29
25
  onRenderChange: (state: RenderState) => void;
30
26
  sendVideoInfo: (info: { name: string; body_id: number; id: number }) => void;
31
- onError: (error: any) => void;
32
27
  sendSdkPoint: (point: string, data: any) => void;
33
28
  };
34
29
  export default class AvatarRender {
@@ -989,13 +984,13 @@ export default class AvatarRender {
989
984
  } else {
990
985
  if(this.lastRealFaceFrame === -1) {
991
986
  faceFrame = curRealFaceData;
992
- // this.options.onError({
987
+ // this.options.reportMessage({
993
988
  // code: EErrorCode.RENDER_FACE_ERROR,
994
989
  // message: `第${frameIndex}帧 实时面部数据为空,原始数据渲染`,
995
990
  // e: JSON.stringify({ bodyFrame, faceFrame }),
996
991
  // });
997
992
  } else {
998
- // this.options.onError({
993
+ // this.options.reportMessage({
999
994
  // code: EErrorCode.RENDER_FACE_ERROR,
1000
995
  // message: `第${frameIndex}帧 实时面部数据为空,插值渲染`,
1001
996
  // e: JSON.stringify({ bodyFrame, faceFrame }),
@@ -1036,30 +1031,26 @@ export default class AvatarRender {
1036
1031
  // 判断bodyFrame和faceFrame是否为空
1037
1032
  if (!bodyFrame) {
1038
1033
  this.allLostFrameCount++;
1039
- this.options.onError({
1034
+ this.options.reportMessage({
1040
1035
  code: EErrorCode.RENDER_BODY_ERROR,
1041
1036
  message: `Error: 第${frameIndex}帧 bodyFrame为空`,
1042
- e: JSON.stringify({ bodyFrame, faceFrame }),
1037
+ e: { bodyFrame, faceFrame },
1043
1038
  });
1044
1039
  } else if (!faceFrame) {
1045
1040
  this.allLostFaceFrameCount++;
1046
- this.options.onError({
1041
+ this.options.reportMessage({
1047
1042
  code: EErrorCode.RENDER_FACE_ERROR,
1048
1043
  message: `Error: 第${frameIndex}帧 faceFrame为空`,
1049
- e: JSON.stringify({ bodyFrame, faceFrame }),
1044
+ e: { bodyFrame, faceFrame },
1050
1045
  });
1051
1046
  }
1052
1047
  if(this.allLostFrameCount === this.maxLostFrameCount) {
1053
1048
  this.options.reportMessage({
1054
1049
  code: EErrorCode.RENDER_DATA_MISSING,
1055
- message: `连续${this.maxLostFrameCount}帧 身体渲染数据缺失.`,
1050
+ message: `连续${this.maxLostFrameCount}帧 身体渲染数据缺失`,
1051
+ e: { bodyFrame, faceFrame },
1056
1052
  });
1057
1053
  // 丢失过多帧,达到最大允许丢失帧数后,触发解码器对齐到最新的一帧
1058
- this.options.onError({
1059
- code: EErrorCode.RENDER_DATA_MISSING,
1060
- message: `Error: 连续${this.maxLostFrameCount}帧 身体渲染数据缺失`,
1061
- e: JSON.stringify({ bodyFrame, faceFrame }),
1062
- });
1063
1054
  this.forceSyncDecoder();
1064
1055
  this.allLostFrameCount = 0;
1065
1056
  }
@@ -1180,10 +1171,10 @@ export default class AvatarRender {
1180
1171
  rendered = true;
1181
1172
  } catch (error) {
1182
1173
  (window as any).avatarSDKLogger.error(this.TAG, "渲染帧失败:", error);
1183
- this.options.onError({
1174
+ this.options.reportMessage({
1184
1175
  code: EErrorCode.WebGL_RENDER_ERROR,
1185
1176
  message: `Error: 第${frameIndex}帧 webgl渲染异常`,
1186
- e: JSON.stringify({ bodyFrame, faceFrame, error }),
1177
+ e: { bodyFrame, faceFrame, error },
1187
1178
  });
1188
1179
  } finally {
1189
1180
  // 渲染完成后再关闭VideoFrame
@@ -158,9 +158,6 @@ export default class RenderScheduler {
158
158
  this.renderState = state;
159
159
  },
160
160
  sendVideoInfo: config.sendVideoInfo,
161
- onError: (error: any) => {
162
- this.sdk.onMessage(error);
163
- },
164
161
  });
165
162
  this.uiRenderer = new UIRenderer({
166
163
  sdk: this.sdk,
package/src/index.ts CHANGED
@@ -225,7 +225,7 @@ export default class XmovAvatar {
225
225
  if(config?.layout?.avatar?.scale){
226
226
  config.layout.avatar.scale = validateScaleWithDecimal(scale, "initializeSDK") as number | string;
227
227
  }
228
- const _config = { ...(config || {}), raw_audio: true };
228
+ const _config = { ...(config || {}), raw_audio: !isSupportMES() };
229
229
 
230
230
  if(container && container instanceof HTMLElement){
231
231
  this.el = container as HTMLElement;
@@ -279,12 +279,32 @@ export default class ParallelDecoder {
279
279
 
280
280
  _startWorker(file: bodyFile) {
281
281
  const taskId = this.currentTaskId;
282
- const worker = new Worker(workerURL);
282
+ let worker: Worker;
283
+ try {
284
+ worker = new Worker(workerURL);
285
+ } catch (err) {
286
+ this.reportMessage({
287
+ code: EErrorCode.INIT_WORKER_ERROR,
288
+ message: '初始化视频抽帧Worker失败',
289
+ e: err as object,
290
+ });
291
+ return;
292
+ }
283
293
  const id = `${file.body_id ?? file.id ?? 0}_${file.name}`;
284
294
  const data = file.data;
285
295
  const dataCopy = new ArrayBuffer(data.byteLength);
286
296
  new Uint8Array(dataCopy).set(new Uint8Array(data));
287
297
 
298
+ // 监听 Worker 运行时错误(脚本加载/解析失败等)
299
+ worker.addEventListener("error", (err) => {
300
+ if (taskId !== this.currentTaskId) return;
301
+ this.reportMessage({
302
+ code: EErrorCode.INIT_WORKER_ERROR,
303
+ message: '视频抽帧Worker运行时错误',
304
+ e: err as object,
305
+ });
306
+ });
307
+
288
308
  const onMessage = (e: MessageEvent) => {
289
309
  if (taskId !== this.currentTaskId) return; // 只处理当前任务
290
310
  if (e.data.type === "frame") {
@@ -335,6 +355,19 @@ export default class ParallelDecoder {
335
355
  }
336
356
  this._tryStartNext();
337
357
  } else if (e.data.type === "error") {
358
+ // 根据 Worker 上报的 error 内容区分错误码
359
+ // Worker 中有两处 postMessage({ type: 'error' }):
360
+ // 1. VideoDecoder error 回调 → 视频抽帧错误 (VIDEO_FRAME_EXTRACT_ERROR)
361
+ // 2. 解码配置不支持 → 视频流处理错误 (PROCESS_VIDEO_STREAM_ERROR)
362
+ const errorMsg = e.data.error ?? '';
363
+ const code = errorMsg.includes('不支持')
364
+ ? EErrorCode.PROCESS_VIDEO_STREAM_ERROR
365
+ : EErrorCode.VIDEO_FRAME_EXTRACT_ERROR;
366
+ this.reportMessage({
367
+ code,
368
+ message: errorMsg || '视频解码错误',
369
+ e: { fileName: file.name, error: errorMsg } as object,
370
+ });
338
371
  const task = this.tasks.get(id);
339
372
  if (task) {
340
373
  task.status = "error";