@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/dist/baseRender/AvatarRenderer.d.ts +0 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.modern.js +1 -1
- package/dist/index.modern.js.map +1 -1
- package/dist/index.module.js +1 -1
- package/dist/index.module.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/baseRender/AvatarRenderer.ts +11 -20
- package/src/control/RenderScheduler.ts +0 -3
- package/src/index.ts +1 -1
- package/src/modules/decoder.ts +34 -1
package/package.json
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
1034
|
+
this.options.reportMessage({
|
|
1040
1035
|
code: EErrorCode.RENDER_BODY_ERROR,
|
|
1041
1036
|
message: `Error: 第${frameIndex}帧 bodyFrame为空`,
|
|
1042
|
-
e:
|
|
1037
|
+
e: { bodyFrame, faceFrame },
|
|
1043
1038
|
});
|
|
1044
1039
|
} else if (!faceFrame) {
|
|
1045
1040
|
this.allLostFaceFrameCount++;
|
|
1046
|
-
this.options.
|
|
1041
|
+
this.options.reportMessage({
|
|
1047
1042
|
code: EErrorCode.RENDER_FACE_ERROR,
|
|
1048
1043
|
message: `Error: 第${frameIndex}帧 faceFrame为空`,
|
|
1049
|
-
e:
|
|
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.
|
|
1174
|
+
this.options.reportMessage({
|
|
1184
1175
|
code: EErrorCode.WebGL_RENDER_ERROR,
|
|
1185
1176
|
message: `Error: 第${frameIndex}帧 webgl渲染异常`,
|
|
1186
|
-
e:
|
|
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:
|
|
228
|
+
const _config = { ...(config || {}), raw_audio: !isSupportMES() };
|
|
229
229
|
|
|
230
230
|
if(container && container instanceof HTMLElement){
|
|
231
231
|
this.el = container as HTMLElement;
|
package/src/modules/decoder.ts
CHANGED
|
@@ -279,12 +279,32 @@ export default class ParallelDecoder {
|
|
|
279
279
|
|
|
280
280
|
_startWorker(file: bodyFile) {
|
|
281
281
|
const taskId = this.currentTaskId;
|
|
282
|
-
|
|
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";
|