@spatius/avatarkit 1.3.1-beta.2 → 1.3.1-beta.3

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 CHANGED
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.3.1-beta.2] - 2026-07-17
9
+
10
+ ### Fixed
11
+ - Fixed playback getting stuck when audio was sent while the connection was still being established and the session later reconnected: the audio clock could freeze, leaving the avatar frozen on a single frame instead of animating in sync with the audio.
12
+ - Fixed the avatar not returning to idle after a playback round finished in that same send-then-connect scenario; it now correctly transitions back to idle when playback ends.
13
+
8
14
  ## [1.3.1-beta.1] - 2026-07-16
9
15
 
10
16
  ### Changed
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { A as APP_CONFIG, l as logger, e as errorToMessage, a as logEvent } from "./index-CPolDcOo.js";
4
+ import { A as APP_CONFIG, l as logger, e as errorToMessage, a as logEvent } from "./index-CFPt9NwR.js";
5
5
  class StreamingAudioPlayer {
6
6
  // Mark if AudioContext is being resumed, avoid concurrent resume requests
7
7
  constructor(options) {
@@ -12940,7 +12940,7 @@ const _AnimationPlayer = class _AnimationPlayer {
12940
12940
  if (this.streamingPlayer) {
12941
12941
  return;
12942
12942
  }
12943
- const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-2bLnaLam.js");
12943
+ const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-CF0Yrsmz.js");
12944
12944
  const { AvatarSDK: AvatarSDK2 } = await Promise.resolve().then(() => AvatarSDK$1);
12945
12945
  const audioFormat = AvatarSDK2.getAudioFormat();
12946
12946
  this.streamingPlayer = new StreamingAudioPlayer({
@@ -15080,7 +15080,7 @@ class AvatarSDK {
15080
15080
  __publicField(AvatarSDK, "_initializationState", "uninitialized");
15081
15081
  __publicField(AvatarSDK, "_initializingPromise", null);
15082
15082
  __publicField(AvatarSDK, "_configuration", null);
15083
- __publicField(AvatarSDK, "_version", "1.3.1-beta.2");
15083
+ __publicField(AvatarSDK, "_version", "1.3.1-beta.3");
15084
15084
  __publicField(AvatarSDK, "_avatarCore", null);
15085
15085
  __publicField(AvatarSDK, "_cachedDeviceScore", null);
15086
15086
  __publicField(AvatarSDK, "_rendererBackend", null);
@@ -16494,16 +16494,13 @@ class AvatarController {
16494
16494
  count: this.frameStarvationEvents.length,
16495
16495
  max_ms: settled.length > 0 ? Math.max(...settled) : 0,
16496
16496
  total_ms: totalStallMs,
16497
- // 卡顿率 = 卡顿总时长 / 已播放时长(fps.duration_ms;打断轮即播到打断那刻,
16498
- // 上限为音频时长)。播放时长为 0 时记 0。
16497
+ // 卡顿率 = 卡顿总时长 / 已播放时长(fps.duration_ms;打断轮即播到打断那刻,上限音频时长)
16499
16498
  ratio: stats.durationMs > 0 ? Number((totalStallMs / stats.durationMs).toFixed(4)) : 0,
16500
16499
  req_end: this.frameStarvationEvents.some((e2) => e2.reqEnd),
16501
- // 每次卡顿明细:开始时间戳(timelineNow,与 tap/anim 同轴)/ 卡顿时的音频时刻 /
16502
- // 等了多久(null=卡到播放结束没恢复)/ 卡顿开始与恢复时已收到的动画帧数
16503
- // (frames_at_recover - frames_at_enter = 卡顿期间到帧量)。
16500
+ // 每次卡顿明细:开始时间戳 / 卡顿时的音频时刻(ms) / 等了多久(null=没恢复) / 卡顿开始与恢复时的动画帧数
16504
16501
  events: this.frameStarvationEvents.map((e2) => ({
16505
16502
  start_ts: Math.round(e2.startTs),
16506
- audio_time: Number(e2.audioTime.toFixed(3)),
16503
+ audio_time_ms: Math.round(e2.audioTime * 1e3),
16507
16504
  duration_ms: e2.durationMs,
16508
16505
  frames_at_enter: e2.framesAtEnter,
16509
16506
  frames_at_recover: e2.framesAtRecover
@@ -16535,7 +16532,9 @@ class AvatarController {
16535
16532
  const latency = ((_a = this.networkLayer) == null ? void 0 : _a.getDrivingServiceLatency()) ?? null;
16536
16533
  logMetric("playback_quality", stall.count > 0 || audioStall.count > 0 ? "warning" : "info", {
16537
16534
  avatar_id: this.avatar.id,
16538
- conversation_id: ((_b = this.networkLayer) == null ? void 0 : _b.getCurrentConversationId()) || void 0,
16535
+ // backend 模式无 networkLayer,conversation_id 存于本地 currentConversationId;
16536
+ // 对齐 playback_ended 的兜底顺序,避免 backend 上报 conversation_id=undefined。
16537
+ conversation_id: this.currentConversationId || ((_b = this.networkLayer) == null ? void 0 : _b.getCurrentConversationId()) || void 0,
16539
16538
  end_reason: this.playbackEndReason,
16540
16539
  // 是否降级模式(audio-only 无动画帧):为 true 时 fps/animation_frame_count 空是预期
16541
16540
  is_fallback: this.isFallbackMode,
@@ -16545,10 +16544,10 @@ class AvatarController {
16545
16544
  audio_ended: this.reqEnd,
16546
16545
  animation_frame_count: this.receivedAnimationFrames,
16547
16546
  animation_ended: this.animationEnded,
16548
- fps,
16549
- stall,
16550
- audio_stall: audioStall,
16551
- ...latency ? { latency } : {}
16547
+ fps: JSON.stringify(fps),
16548
+ stall: JSON.stringify(stall),
16549
+ audio_stall: JSON.stringify(audioStall),
16550
+ ...latency ? { latency: JSON.stringify(resolveMarks(latency)) } : {}
16552
16551
  });
16553
16552
  this.frameStarvationEvents = [];
16554
16553
  this.isFrameStarved = false;
@@ -17261,7 +17260,8 @@ class AvatarController {
17261
17260
  this.isStartingPlayback = false;
17262
17261
  logEvent("playback_started", "info", {
17263
17262
  avatar_id: this.avatar.id,
17264
- conversation_id: ((_a = this.networkLayer) == null ? void 0 : _a.getCurrentConversationId()) || void 0
17263
+ // backend 模式无 networkLayer,取本地 currentConversationId 兜底(同 playback_ended/quality)
17264
+ conversation_id: this.currentConversationId || ((_a = this.networkLayer) == null ? void 0 : _a.getCurrentConversationId()) || void 0
17265
17265
  });
17266
17266
  } catch (error) {
17267
17267
  const message = error instanceof Error ? error.message : String(error);
@@ -17330,7 +17330,7 @@ class AvatarController {
17330
17330
  state.reported = true;
17331
17331
  logEvent("playback_stuck_after_transition", "error", {
17332
17332
  avatar_id: this.avatar.id,
17333
- conversation_id: ((_e2 = this.networkLayer) == null ? void 0 : _e2.getCurrentConversationId()) || void 0,
17333
+ conversation_id: this.currentConversationId || ((_e2 = this.networkLayer) == null ? void 0 : _e2.getCurrentConversationId()) || void 0,
17334
17334
  // 诊断信息(包含 audio_context_state 用于诊断,但不作为触发条件)
17335
17335
  audio_context_state: audioContextState,
17336
17336
  audio_time: audioTime,
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { m, b, c, p, f, d, o, g, C, n, i, j, D, E, F, k, L, h, R, q, T, r } from "./index-CPolDcOo.js";
1
+ import { m, b, c, p, f, d, o, g, C, n, i, j, D, E, F, k, L, h, R, q, T, r } from "./index-CFPt9NwR.js";
2
2
  export {
3
3
  m as AnimationType,
4
4
  b as Avatar,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spatius/avatarkit",
3
3
  "type": "module",
4
- "version": "1.3.1-beta.2",
4
+ "version": "1.3.1-beta.3",
5
5
  "packageManager": "pnpm@10.18.2",
6
6
  "description": "AvatarKit SDK - Real-time Avatar Rendering SDK for Web",
7
7
  "author": "AvatarKit Team",