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

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.42",
3
+ "version": "2.0.0-alpha.44",
4
4
  "description": "魔珐数字人 JS-SDK",
5
5
  "type": "module",
6
6
  "source": "src/index.ts",
@@ -225,19 +225,25 @@ export default class AudioRender {
225
225
  pause() {
226
226
  this.isPlaying = false;
227
227
  this.options.dataCacheQueue._clearAudio(this.speech_id);
228
+ this.lastFrameIndex = -1;
228
229
  this.firstFrameIndex = -1;
230
+ this.cacheFirstFrameIndex = -1;
231
+ this.cacheAudioData = [];
232
+ this.mseCacheAudioData = [];
233
+ this.oldSpeechId = -1;
229
234
  // 停止 PCM 播放
230
235
  this.audio?.stop();
231
-
236
+
232
237
  // 停止 WebM 播放
233
238
  this.mseAudioPlayer?.stop(this.addNewAudioSegment.bind(this));
234
239
  this.speech_id = -1;
235
240
  }
236
241
 
237
242
  stop(speech_id: number) {
238
- // 如果当前需要结束的是旧的语音ID,直接返回
239
- if(this.oldSpeechId >= speech_id) return;
240
-
243
+ // speech_id === -1 表示强制清理(用于 pauseRender / destroy / 断网重连场景),不受 oldSpeechId 限制
244
+ // 否则如果 oldSpeechId >= speech_id 直接返回,避免重复处理
245
+ if (speech_id !== -1 && this.oldSpeechId >= speech_id) return;
246
+
241
247
  this.isPlaying = false;
242
248
  this.options.dataCacheQueue._clearAudio(speech_id);
243
249
  this.firstFrameIndex = -1;
@@ -255,7 +261,12 @@ export default class AudioRender {
255
261
  }
256
262
  this.oldSpeechId = speech_id;
257
263
  this.speech_id = -1;
258
- if (this.cacheAudioData.length > 0) {
264
+ if (speech_id === -1) {
265
+ // 强制清理:清空所有缓存数据,不推入音频流(用于 pauseRender / destroy / 断网重连)
266
+ this.cacheFirstFrameIndex = -1;
267
+ this.cacheAudioData = [];
268
+ this.mseCacheAudioData = [];
269
+ } else if (this.cacheAudioData.length > 0) {
259
270
  this.firstFrameIndex = this.cacheFirstFrameIndex;
260
271
  this.cacheFirstFrameIndex = -1;
261
272
  // 新的缓存下来的数据,推入音频流
@@ -411,6 +411,11 @@ export default class RenderScheduler {
411
411
  clearTimeout(this._speedResetTimer);
412
412
  }
413
413
 
414
+ // 播放加速大于4,直接丢弃
415
+ if (playbackSpeed > 4) {
416
+ return;
417
+ }
418
+
414
419
  // 8. 应用速度
415
420
  this.audioRenderer.setSpeed(playbackSpeed);
416
421
 
@@ -830,6 +835,14 @@ export default class RenderScheduler {
830
835
  if (frame) {
831
836
  this.decoder._offLineMode(this.resourceManager._getOfflineIdle(), frame);
832
837
  }
838
+ // 重置所有 speechId 相关状态,避免联网后新语音被过滤
839
+ // - lastSpeechId: 用于过滤旧 sid 的音频数据(L444)
840
+ // - currentSpeechId: 用于 speak_end 时判断是否 setInterrupt
841
+ // - uiRenderer.lastSpeechId: UIRenderer 会过滤 sid < lastSpeechId 的事件(含 speak_start)
842
+ // 若不重置,联网后新语音的 speak_start 会被过滤,导致字幕正常但无音频
843
+ this.lastSpeechId = -1;
844
+ this.currentSpeechId = -1;
845
+ this.uiRenderer.lastSpeechId = -1;
833
846
  }
834
847
  _offlineRun() {
835
848
  this.decoder._offlineRun()
@@ -71,12 +71,17 @@ export class DebugOverlay {
71
71
  }
72
72
 
73
73
  public show(): void {
74
- if (this.container) {
74
+ if (!this.container) {
75
+ this.createOverlay();
76
+ }
77
+ if(this.container) {
75
78
  this.container.style.display = "block";
76
- return;
77
79
  }
78
- this.createOverlay();
79
- this.updateInterval = window.setInterval(() => this.updateTextOnly(), 200);
80
+ // 重启定时器:hide() 会清除 updateInterval,再次 show 时需要重建
81
+ // 否则界面显示但内容永不刷新
82
+ if (!this.updateInterval) {
83
+ this.updateInterval = window.setInterval(() => this.updateTextOnly(), 200);
84
+ }
80
85
  this.updateTextOnly();
81
86
  }
82
87