@xmov/avatar 2.0.0-alpha.48 → 2.0.0-alpha.50
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/control/RenderScheduler.d.ts +1 -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/control/RenderScheduler.ts +36 -5
- package/src/modules/ResourceManager.ts +1 -1
package/package.json
CHANGED
|
@@ -338,9 +338,10 @@ export default class RenderScheduler {
|
|
|
338
338
|
} else {
|
|
339
339
|
nowFaceData.push(faceData[i]);
|
|
340
340
|
}
|
|
341
|
-
nowFaceData.length && this.dataCacheQueue._updateFacial(nowFaceData);
|
|
342
|
-
realFaceData.length && this.dataCacheQueue._updateRealFacial(realFaceData);
|
|
343
341
|
}
|
|
342
|
+
// 分类完成后一次性入队,避免循环内对累加数组重复 push 导致队列数据重复
|
|
343
|
+
nowFaceData.length && this.dataCacheQueue._updateFacial(nowFaceData);
|
|
344
|
+
realFaceData.length && this.dataCacheQueue._updateRealFacial(realFaceData);
|
|
344
345
|
break;
|
|
345
346
|
case EFrameDataType.AUDIO:
|
|
346
347
|
const audioData = data as IRawAudioFrameData[];
|
|
@@ -492,7 +493,34 @@ export default class RenderScheduler {
|
|
|
492
493
|
code: EErrorCode.EVENT_TRIGGERED,
|
|
493
494
|
message: 'WARNING: 有新的speak_start事件,但是上一轮仍未结束,触发兜底结束',
|
|
494
495
|
});
|
|
495
|
-
|
|
496
|
+
const currentSpeakStart = d.flatMap(item => item.e ?? []).find(ev => ev.type === 'speak_start');
|
|
497
|
+
const newSpeakId = currentSpeakStart?.speech_id ?? 0;
|
|
498
|
+
const playingSpeechId = this.audioRenderer.speech_id;
|
|
499
|
+
// 仅当正在播放的确实是上一轮(sid 小于新一轮)时才打断旧轮次。
|
|
500
|
+
// 若事件晚于音频到达(playingSpeechId 已是新一轮 sid),此时播放的就是新一轮,
|
|
501
|
+
// 不能用 interrupt()(其目标取 audioRenderer.speech_id),否则会误清新一轮的音频队列、
|
|
502
|
+
// 字幕事件,并因 lastSpeechId/oldSpeechId 更新导致后续音视频帧全部被丢弃,
|
|
503
|
+
// 表现为"有口型、无字幕、无音频"。
|
|
504
|
+
if (playingSpeechId !== -1 && playingSpeechId < newSpeakId) {
|
|
505
|
+
this.interrupt('new_speak_start', playingSpeechId);
|
|
506
|
+
// stop() 内部有 oldSpeechId >= speech_id 的防重入守卫:当 speech_id 停留在
|
|
507
|
+
// 异常残留值(如初始值 0,长会话中 isPlaying 卡死为 true)时 stop 会被拦截,
|
|
508
|
+
// isPlaying/speech_id 无法复位,导致新一轮音频在 _updateAudio 中永远走缓存分支
|
|
509
|
+
// 不播放(日志表现:缓存数据长度持续增长且无"开始播放")。
|
|
510
|
+
// 这里检测到 stop 未生效(speech_id 未复位为 -1)时,用 pause() 强制复位,
|
|
511
|
+
// pause 会 flush 已缓存音频并把 speech_id/oldSpeechId 重置,新一轮可正常起播。
|
|
512
|
+
if (this.audioRenderer.speech_id !== -1) {
|
|
513
|
+
this.audioRenderer.pause();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
// 新 speak_start 已到来,立即复位 interrupt 并更新轮次状态,
|
|
517
|
+
// 避免依赖 UIRenderer 在 sf 帧处理事件时(sf==当前帧且事件在 compose 后被处理)被漏处理,
|
|
518
|
+
// 导致新轮次实际说话期间仍被强制渲染为闭嘴表情
|
|
519
|
+
if (currentSpeakStart) {
|
|
520
|
+
this.currentSpeechId = currentSpeakStart.speech_id ?? 0;
|
|
521
|
+
this.avatarRenderer.setInterrupt(false);
|
|
522
|
+
this.uiRenderer.lastSpeechId = currentSpeakStart.speech_id ?? 0;
|
|
523
|
+
}
|
|
496
524
|
}
|
|
497
525
|
|
|
498
526
|
// 2. 处理过期speak_start
|
|
@@ -879,10 +907,13 @@ export default class RenderScheduler {
|
|
|
879
907
|
this.avatarRenderer.setWalkConfig(walkConfig);
|
|
880
908
|
}
|
|
881
909
|
|
|
882
|
-
|
|
910
|
+
// targetSpeechId: 显式指定要打断的轮次 sid。缺省时取 audioRenderer.speech_id(当前播放轮次)。
|
|
911
|
+
// 当事件晚于音频到达时,audioRenderer.speech_id 可能已经切换到新一轮,此时必须显式传旧 sid,
|
|
912
|
+
// 避免误清新一轮的音频与字幕。
|
|
913
|
+
interrupt(type?: string, targetSpeechId?: number): number{
|
|
883
914
|
const start = Date.now();
|
|
884
915
|
// 插入中断字幕和语音结束事件
|
|
885
|
-
const speech_id = this.audioRenderer.speech_id;
|
|
916
|
+
const speech_id = targetSpeechId ?? this.audioRenderer.speech_id;
|
|
886
917
|
if(type === "in_offline_mode") {
|
|
887
918
|
this.lastSpeechId = -1;
|
|
888
919
|
} else {
|
|
@@ -205,7 +205,7 @@ export default class ResourceManager {
|
|
|
205
205
|
private isProcessingVideo = false; // 防止在视频处理过程中清理缓存
|
|
206
206
|
private cacheServer?: CacheManager;
|
|
207
207
|
private startSessionTimer: any = null;
|
|
208
|
-
private audioOnlyMode: boolean;
|
|
208
|
+
private audioOnlyMode: boolean = false;
|
|
209
209
|
|
|
210
210
|
// 新增:正在下载的视频跟踪
|
|
211
211
|
private downloadingVideos = new Map<string, Promise<ArrayBuffer | undefined>>();
|