@zeewain/3d-avatar-sdk 2.1.2 → 2.1.4

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/index.esm.js CHANGED
@@ -502,7 +502,7 @@ class UnityBaseService {
502
502
  const finalConfig = Object.assign(Object.assign({}, DEFAULT_CONFIG), config);
503
503
  this.unityInstance = finalConfig.unityInstance;
504
504
  this.targetObjectName = finalConfig.targetObjectName;
505
- this.timeout = finalConfig.timeout;
505
+ this.timeout = finalConfig.timeout || DEFAULT_CONFIG.timeout;
506
506
  this.maxRetries = finalConfig.maxRetries;
507
507
  this.instanceId = finalConfig.instanceId || 'default';
508
508
  this.logger = new SimpleLogger(finalConfig.enableDebugLog);
@@ -1023,7 +1023,7 @@ const ENV_MAP = {
1023
1023
  },
1024
1024
  /** 生产环境配置 */
1025
1025
  prod: {
1026
- apiBaseUrl: 'https://aiip.zeewain.com'
1026
+ apiBaseUrl: 'https://ai.zeewain3d.com'
1027
1027
  }
1028
1028
  };
1029
1029
  /**
@@ -1034,7 +1034,7 @@ const ENV_MAP = {
1034
1034
  * @example
1035
1035
  * ```typescript
1036
1036
  * const config = getEnvConfig('prod');
1037
- * console.log(config.apiBaseUrl); // https://aiip.zeewain.com/api/dh-talker
1037
+ * console.log(config.apiBaseUrl); // https://ai.zeewain3d.com/api/dh-talker
1038
1038
  * ```
1039
1039
  */
1040
1040
  function getEnvConfig(env = 'dev', withApiModule = true) {
@@ -1505,6 +1505,8 @@ var BroadcastType;
1505
1505
  */
1506
1506
  var BroadcastTaskStatus;
1507
1507
  (function (BroadcastTaskStatus) {
1508
+ /** 等待中(尚未开始请求) */
1509
+ BroadcastTaskStatus["PENDING"] = "pending";
1508
1510
  /** 请求中 */
1509
1511
  BroadcastTaskStatus["REQUESTING"] = "requesting";
1510
1512
  /** 已完成 */
@@ -1570,7 +1572,7 @@ class BroadcastService extends UnityBaseService {
1570
1572
  * @override
1571
1573
  */
1572
1574
  handleCallback(operation, code, message, data) {
1573
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
1575
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
1574
1576
  // 提取 isBroadcastCompleted 参数
1575
1577
  const { isBroadcastCompleted } = JSON.parse(data || '{}');
1576
1578
  // 先调用基类处理逻辑
@@ -1582,7 +1584,14 @@ class BroadcastService extends UnityBaseService {
1582
1584
  if (isBroadcastCompleted) {
1583
1585
  this.broadcastCompletedCount++;
1584
1586
  const status = this.getStatus();
1585
- if (((_a = status.queueInfo) === null || _a === void 0 ? void 0 : _a.completedTasks) === this.broadcastCompletedCount) {
1587
+ // 判断是否所有任务都已完成:
1588
+ // 1. 没有待请求的任务 (PENDING)
1589
+ // 2. 没有正在请求的任务 (REQUESTING)
1590
+ // 3. Unity播放完成次数等于已完成任务数
1591
+ const isAllTasksCompleted = ((_a = status.queueInfo) === null || _a === void 0 ? void 0 : _a.pendingTasks) === 0
1592
+ && ((_b = status.queueInfo) === null || _b === void 0 ? void 0 : _b.requestingTasks) === 0
1593
+ && ((_c = status.queueInfo) === null || _c === void 0 ? void 0 : _c.completedTasks) === this.broadcastCompletedCount;
1594
+ if (isAllTasksCompleted) {
1586
1595
  // 重置状态、计数
1587
1596
  this.isBroadcastingAudio = false;
1588
1597
  this.hasReceivedAudio = false;
@@ -1592,19 +1601,19 @@ class BroadcastService extends UnityBaseService {
1592
1601
  this.logger.warn('Broadcast all completed');
1593
1602
  }
1594
1603
  // this.logger.warn('AAAAAA', { status: this.getStatus(), broadcastCompletedCount: this.broadcastCompletedCount });
1595
- (_c = (_b = this.callbacks).onFinish) === null || _c === void 0 ? void 0 : _c.call(_b);
1604
+ (_e = (_d = this.callbacks).onFinish) === null || _e === void 0 ? void 0 : _e.call(_d);
1596
1605
  }
1597
1606
  break;
1598
1607
  case BroadcastOperationType.PAUSE_BROADCAST:
1599
- (_e = (_d = this.callbacks).onPause) === null || _e === void 0 ? void 0 : _e.call(_d);
1608
+ (_g = (_f = this.callbacks).onPause) === null || _g === void 0 ? void 0 : _g.call(_f);
1600
1609
  this.logger.debug('Broadcast paused callback triggered');
1601
1610
  break;
1602
1611
  case BroadcastOperationType.RESUME_BROADCAST:
1603
- (_g = (_f = this.callbacks).onResume) === null || _g === void 0 ? void 0 : _g.call(_f);
1612
+ (_j = (_h = this.callbacks).onResume) === null || _j === void 0 ? void 0 : _j.call(_h);
1604
1613
  this.logger.debug('Broadcast resumed callback triggered');
1605
1614
  break;
1606
1615
  case BroadcastOperationType.STOP_BROADCAST:
1607
- (_j = (_h = this.callbacks).onStop) === null || _j === void 0 ? void 0 : _j.call(_h);
1616
+ (_l = (_k = this.callbacks).onStop) === null || _l === void 0 ? void 0 : _l.call(_k);
1608
1617
  this.logger.debug('Broadcast stopped callback triggered');
1609
1618
  break;
1610
1619
  }
@@ -1661,7 +1670,7 @@ class BroadcastService extends UnityBaseService {
1661
1670
  // 重置序号计数器
1662
1671
  this.taskSequence = 0;
1663
1672
  this.currentSendingSequence = 0;
1664
- // 通知Unity开始新任务(清空队列)
1673
+ // 通知Unity开始新任务(清空队列),这里不使用sendAsyncMessage,因为startBroadcast不需要等待完成,而是在任务播报完成后通过回调通知
1665
1674
  this.sendMessage('StartBroadcast', {
1666
1675
  callbackFun: this.uniqueCallbackName,
1667
1676
  operationType: BroadcastOperationType.START_BROADCAST,
@@ -1773,18 +1782,20 @@ class BroadcastService extends UnityBaseService {
1773
1782
  * @description 获取当前播报服务的状态信息,包括队列状态
1774
1783
  */
1775
1784
  getStatus() {
1785
+ const pendingTasks = this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.PENDING).length;
1776
1786
  const completedTasks = this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.COMPLETED).length;
1777
1787
  const requestingTasks = this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.REQUESTING).length;
1778
1788
  const failedTasks = this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.FAILED).length;
1779
1789
  const totalPendingResponses = this.taskQueue.reduce((sum, t) => sum + t.pendingResponses.length, 0);
1780
1790
  const currentSendingSequence = this.currentSendingSequence;
1781
- const isGeneratingAudio = completedTasks + failedTasks !== this.taskQueue.length;
1791
+ const isGeneratingAudio = pendingTasks + requestingTasks > 0;
1782
1792
  return {
1783
1793
  isActive: this.isBroadcastingAudio || isGeneratingAudio, // 是否正在播报音频或正在生成音频
1784
1794
  isGeneratingAudio,
1785
1795
  hasReceivedAudio: this.hasReceivedAudio,
1786
1796
  queueInfo: {
1787
1797
  totalTasks: this.taskQueue.length,
1798
+ pendingTasks,
1788
1799
  requestingTasks,
1789
1800
  completedTasks,
1790
1801
  failedTasks,
@@ -1818,7 +1829,7 @@ class BroadcastService extends UnityBaseService {
1818
1829
  id: `broadcast_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
1819
1830
  sequence: ++this.taskSequence,
1820
1831
  params,
1821
- status: BroadcastTaskStatus.REQUESTING,
1832
+ status: BroadcastTaskStatus.PENDING,
1822
1833
  controller: new AbortController(),
1823
1834
  pendingResponses: [],
1824
1835
  isGenerationComplete: false,
@@ -1830,46 +1841,58 @@ class BroadcastService extends UnityBaseService {
1830
1841
  /**
1831
1842
  * 添加任务到队列
1832
1843
  * @param task - 播报任务
1833
- * @description 将任务添加到队列并立即开始请求
1844
+ * @description 将任务添加到队列,只有当没有正在请求的任务时才开始请求(串行请求模式)
1834
1845
  * @private
1835
1846
  */
1836
1847
  addTaskToQueue(task) {
1837
1848
  this.taskQueue.push(task);
1838
- this.logger.debug('Task added to queue', { taskId: task.id, queueLength: this.taskQueue.length });
1839
- // 立即开始该任务的请求
1840
- this.startTaskRequest(task);
1849
+ this.logger.debug('Task added to queue', { taskId: task.id, params: task.params, queueLength: this.taskQueue.length });
1850
+ // 检查是否有正在请求的任务
1851
+ const hasRequestingTask = this.taskQueue.some((t) => t.status === BroadcastTaskStatus.REQUESTING);
1852
+ // 只有当没有正在请求的任务时,才开始当前任务的请求
1853
+ if (!hasRequestingTask) {
1854
+ this.startTaskRequest(task);
1855
+ }
1856
+ else {
1857
+ this.logger.debug('Task queued, waiting for previous task to complete', {
1858
+ taskId: task.id,
1859
+ pendingTasks: this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.PENDING).length
1860
+ });
1861
+ }
1841
1862
  // 开始处理队列
1842
- this.processQueue();
1863
+ this.processTaskQueue();
1843
1864
  }
1844
1865
  /**
1845
1866
  * 处理队列
1846
- * @description 处理队列中的任务,发起请求生成音频
1867
+ * @description 处理队列中的任务响应,按序号发送给unity播放
1847
1868
  * @private
1848
1869
  */
1849
- processQueue() {
1870
+ processTaskQueue() {
1850
1871
  // 启动队列处理定时器(如果尚未启动)
1851
1872
  if (!this.queueProcessTimer) {
1852
1873
  this.queueProcessTimer = setInterval(() => {
1853
- this.processQueueStep();
1874
+ this.processTaskQueueStep();
1854
1875
  }, 100); // 每100ms检查一次队列状态
1855
1876
  }
1856
1877
  // 立即处理一次
1857
- this.processQueueStep();
1878
+ this.processTaskQueueStep();
1858
1879
  }
1859
1880
  /**
1860
1881
  * 队列处理步骤
1861
- * @description 处理队列中的单个步骤,包括发起请求和发送音频
1882
+ * @description 处理队列中的单个步骤,按序号发送给unity播放
1862
1883
  * @private
1863
1884
  */
1864
- processQueueStep() {
1865
- // 按序号找到下一个要处理的任务
1885
+ processTaskQueueStep() {
1886
+ // 按序号找到下一个要处理的任务(只处理已开始请求的任务,排除 PENDING 状态)
1866
1887
  const nextTask = this.taskQueue.find((task) => task.sequence === this.currentSendingSequence + 1
1888
+ && task.status !== BroadcastTaskStatus.PENDING
1867
1889
  && task.pendingResponses.length > 0);
1868
1890
  if (nextTask) {
1869
1891
  this.sendNextResponse(nextTask);
1870
1892
  }
1871
- // 如果队列中没有剩余任务,则停止定时器
1872
- const remainingTasks = this.taskQueue.filter(task => task.status !== BroadcastTaskStatus.COMPLETED
1893
+ // 如果队列中没有剩余任务(排除待处理、已完成、失败和取消的任务),则停止定时器
1894
+ const remainingTasks = this.taskQueue.filter(task => task.status !== BroadcastTaskStatus.PENDING
1895
+ && task.status !== BroadcastTaskStatus.COMPLETED
1873
1896
  && task.status !== BroadcastTaskStatus.FAILED
1874
1897
  && task.status !== BroadcastTaskStatus.CANCELLED);
1875
1898
  if (remainingTasks.length === 0) {
@@ -1961,7 +1984,7 @@ class BroadcastService extends UnityBaseService {
1961
1984
  const response = JSON.parse(data);
1962
1985
  // 错误处理
1963
1986
  if (response.code !== 0) {
1964
- this.handleBroadcastError(response.code);
1987
+ this.handleBroadcastError(response.code, response.message);
1965
1988
  return;
1966
1989
  }
1967
1990
  // 处理音频数据
@@ -1973,7 +1996,7 @@ class BroadcastService extends UnityBaseService {
1973
1996
  }
1974
1997
  // 添加处理后的响应对象到待发送队列
1975
1998
  task.pendingResponses.push(response);
1976
- this.logger.debug('Response added to task', { taskId: task.id, pendingCount: task.pendingResponses.length });
1999
+ this.logger.debug('Response added to task', { taskId: task.id, response, pendingCount: task.pendingResponses.length });
1977
2000
  // 检查是否完成
1978
2001
  if (response.data.done) {
1979
2002
  task.isGenerationComplete = true;
@@ -1982,13 +2005,13 @@ class BroadcastService extends UnityBaseService {
1982
2005
  }
1983
2006
  }
1984
2007
  catch (error) {
1985
- this.handleTaskError(task, error);
2008
+ this.handleTaskError(task, new SDKError(OperationErrorCode.OPERATION_FAILED, typeof error === 'string' ? error : (error.message || '播报服务错误')));
1986
2009
  }
1987
2010
  }
1988
2011
  /**
1989
- * 发送下一个响应
2012
+ * 发送下一个响应给unity播放
1990
2013
  * @param task - 播报任务
1991
- * @description 发送任务中的第一个待发送响应到Unity,发送后立即删除
2014
+ * @description 发送任务的响应数组中的第一个待发送响应到Unity(按顺序发送),发送后立即删除
1992
2015
  * @private
1993
2016
  */
1994
2017
  sendNextResponse(task) {
@@ -2003,7 +2026,7 @@ class BroadcastService extends UnityBaseService {
2003
2026
  remainingResponses: task.pendingResponses.length,
2004
2027
  voiceUrl: (_a = response.data) === null || _a === void 0 ? void 0 : _a.voiceUrl
2005
2028
  });
2006
- // 发送响应到Unity
2029
+ // 发送响应到Unity,这里不使用sendAsyncMessage,因为appendBroadcast不需要等待完成,而是在任务播报完成后通过startBroadcast回调通知
2007
2030
  this.sendMessage('AppendBroadcast', {
2008
2031
  response,
2009
2032
  callbackFun: this.uniqueCallbackName,
@@ -2019,7 +2042,7 @@ class BroadcastService extends UnityBaseService {
2019
2042
  /**
2020
2043
  * 处理任务关闭
2021
2044
  * @param task - 播报任务
2022
- * @description 处理任务的流式连接关闭
2045
+ * @description 处理任务的流式连接关闭,并启动下一个待处理任务的请求
2023
2046
  * @private
2024
2047
  */
2025
2048
  handleTaskClose(task) {
@@ -2028,12 +2051,14 @@ class BroadcastService extends UnityBaseService {
2028
2051
  if (!task.isGenerationComplete && task.status === BroadcastTaskStatus.REQUESTING) {
2029
2052
  task.isGenerationComplete = true;
2030
2053
  }
2054
+ // 当前任务请求完成后(流断开后),启动下一个待处理任务的请求
2055
+ this.startNextPendingTask();
2031
2056
  }
2032
2057
  /**
2033
2058
  * 处理任务错误
2034
2059
  * @param task - 播报任务
2035
2060
  * @param error - 错误对象
2036
- * @description 处理任务执行过程中的错误,防止重复触发错误回调
2061
+ * @description 处理任务执行过程中的错误,防止重复触发错误回调,并启动下一个待处理任务
2037
2062
  * @private
2038
2063
  */
2039
2064
  handleTaskError(task, error) {
@@ -2136,10 +2161,11 @@ class BroadcastService extends UnityBaseService {
2136
2161
  /**
2137
2162
  * 处理播报错误
2138
2163
  * @param errorCode - 错误码
2164
+ * @param errorMessage - 错误消息
2139
2165
  * @description 处理播报过程中的错误
2140
2166
  * @private
2141
2167
  */
2142
- handleBroadcastError(errorCode) {
2168
+ handleBroadcastError(errorCode, errorMessage) {
2143
2169
  // 用户权益额度不存在错误码 14001
2144
2170
  // 用户权益额度不足错误码 14002
2145
2171
  // 用户权益额度冻结失败 14003
@@ -2154,10 +2180,31 @@ class BroadcastService extends UnityBaseService {
2154
2180
  this.handleError(new SDKError(OperationErrorCode.BROADCAST_EQUITY_FREEZE_FAILED, '用户权益额度冻结失败'));
2155
2181
  break;
2156
2182
  default:
2157
- this.handleError(new SDKError(OperationErrorCode.OPERATION_FAILED, '播报服务错误'));
2183
+ this.handleError(new SDKError(OperationErrorCode.OPERATION_FAILED, `${errorMessage}(${errorCode})` || `播报服务错误(${errorCode})`));
2158
2184
  break;
2159
2185
  }
2160
2186
  }
2187
+ /**
2188
+ * 启动下一个待处理任务的请求
2189
+ * @description 在当前任务请求完成或失败后,检查并启动下一个待处理任务
2190
+ * @private
2191
+ */
2192
+ startNextPendingTask() {
2193
+ // 查找下一个待处理的任务(按序号排序,取第一个 PENDING 状态的任务)
2194
+ const nextPendingTask = this.taskQueue
2195
+ .filter((t) => t.status === BroadcastTaskStatus.PENDING)
2196
+ .sort((a, b) => a.sequence - b.sequence)[0];
2197
+ if (nextPendingTask) {
2198
+ this.logger.debug('Starting next pending task', {
2199
+ taskId: nextPendingTask.id,
2200
+ sequence: nextPendingTask.sequence
2201
+ });
2202
+ this.startTaskRequest(nextPendingTask);
2203
+ }
2204
+ else {
2205
+ this.logger.debug('No pending tasks to start');
2206
+ }
2207
+ }
2161
2208
  /**
2162
2209
  * 清理队列处理定时器
2163
2210
  * @description 清理队列处理定时器
@@ -2167,6 +2214,7 @@ class BroadcastService extends UnityBaseService {
2167
2214
  if (this.queueProcessTimer) {
2168
2215
  clearInterval(this.queueProcessTimer);
2169
2216
  this.queueProcessTimer = null;
2217
+ this.logger.debug('Queue process timer cleared');
2170
2218
  }
2171
2219
  }
2172
2220
  /**
@@ -2359,6 +2407,7 @@ class ZEEAvatarLoader {
2359
2407
  */
2360
2408
  initGlobalConfig() {
2361
2409
  const config = ConfigManager.getInstance().getConfig();
2410
+ const { assetsFrom } = config;
2362
2411
  const globalParams = {
2363
2412
  token: config === null || config === void 0 ? void 0 : config.token,
2364
2413
  apiBaseUrl: ConfigManager.getInstance().getApiBaseUrl(false),
@@ -2366,14 +2415,17 @@ class ZEEAvatarLoader {
2366
2415
  // 純AB包方案在SDK 2.1.0 中已弃用
2367
2416
  // assetsUrl: config?.assetsUrl
2368
2417
  };
2369
- const assetModuleParams = {
2370
- isZip: true,
2371
- assetBundlePath: config === null || config === void 0 ? void 0 : config.assetsUrl
2372
- };
2373
2418
  this.unityInstance.SendMessage('AvatarSDK', 'InitializeConfig', JSON.stringify(globalParams));
2374
- this.unityInstance.SendMessage('AvatarSDK', 'InitAssetBundleModule', JSON.stringify(assetModuleParams));
2375
2419
  console.warn('[ Send Unity message ]: AvatarSDK.InitializeConfig', globalParams);
2376
- console.warn('[ Send Unity message ]: AvatarSDK.InitAssetBundleModule', assetModuleParams);
2420
+ //
2421
+ if (assetsFrom !== 'cloud') {
2422
+ const assetModuleParams = {
2423
+ isZip: true,
2424
+ assetBundlePath: config === null || config === void 0 ? void 0 : config.assetsUrl
2425
+ };
2426
+ this.unityInstance.SendMessage('AvatarSDK', 'InitAssetBundleModule', JSON.stringify(assetModuleParams));
2427
+ console.warn('[ Send Unity message ]: AvatarSDK.InitAssetBundleModule', assetModuleParams);
2428
+ }
2377
2429
  }
2378
2430
  }
2379
2431
 
@@ -2411,7 +2463,7 @@ function compareVersionCompatibility(version1, version2) {
2411
2463
  * SDK 版本号
2412
2464
  * @const {string} SDK_VERSION
2413
2465
  */
2414
- const SDK_VERSION = '2.1.2';
2466
+ const SDK_VERSION = '2.1.4';
2415
2467
 
2416
2468
  /**
2417
2469
  * @fileoverview 统一的3D数字人SDK入口类
@@ -2477,14 +2529,16 @@ class ZEEAvatarSDK {
2477
2529
  this.avatarService = new AvatarService({
2478
2530
  unityInstance: this.unityInstance,
2479
2531
  instanceId: this.instanceId,
2480
- enableDebugLog: config.enableDebugLog
2532
+ enableDebugLog: config.enableDebugLog,
2533
+ timeout: config.operationTimeout
2481
2534
  });
2482
2535
  // 5. 创建带有唯一标识符的播报服务
2483
2536
  this.broadcastService = new BroadcastService({
2484
2537
  unityInstance: this.unityInstance,
2485
2538
  instanceId: this.instanceId,
2486
2539
  callbacks: config.broadcastCallbacks,
2487
- enableDebugLog: config.enableDebugLog
2540
+ enableDebugLog: config.enableDebugLog,
2541
+ timeout: config.operationTimeout
2488
2542
  });
2489
2543
  // 6. 初始化数字人
2490
2544
  const result = yield this.avatarService.initializeAvatar(avatarCode, cameraType);