@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.
@@ -508,7 +508,7 @@
508
508
  const finalConfig = Object.assign(Object.assign({}, DEFAULT_CONFIG), config);
509
509
  this.unityInstance = finalConfig.unityInstance;
510
510
  this.targetObjectName = finalConfig.targetObjectName;
511
- this.timeout = finalConfig.timeout;
511
+ this.timeout = finalConfig.timeout || DEFAULT_CONFIG.timeout;
512
512
  this.maxRetries = finalConfig.maxRetries;
513
513
  this.instanceId = finalConfig.instanceId || 'default';
514
514
  this.logger = new SimpleLogger(finalConfig.enableDebugLog);
@@ -1029,7 +1029,7 @@
1029
1029
  },
1030
1030
  /** 生产环境配置 */
1031
1031
  prod: {
1032
- apiBaseUrl: 'https://aiip.zeewain.com'
1032
+ apiBaseUrl: 'https://ai.zeewain3d.com'
1033
1033
  }
1034
1034
  };
1035
1035
  /**
@@ -1040,7 +1040,7 @@
1040
1040
  * @example
1041
1041
  * ```typescript
1042
1042
  * const config = getEnvConfig('prod');
1043
- * console.log(config.apiBaseUrl); // https://aiip.zeewain.com/api/dh-talker
1043
+ * console.log(config.apiBaseUrl); // https://ai.zeewain3d.com/api/dh-talker
1044
1044
  * ```
1045
1045
  */
1046
1046
  function getEnvConfig(env = 'dev', withApiModule = true) {
@@ -1511,6 +1511,8 @@
1511
1511
  */
1512
1512
  var BroadcastTaskStatus;
1513
1513
  (function (BroadcastTaskStatus) {
1514
+ /** 等待中(尚未开始请求) */
1515
+ BroadcastTaskStatus["PENDING"] = "pending";
1514
1516
  /** 请求中 */
1515
1517
  BroadcastTaskStatus["REQUESTING"] = "requesting";
1516
1518
  /** 已完成 */
@@ -1576,7 +1578,7 @@
1576
1578
  * @override
1577
1579
  */
1578
1580
  handleCallback(operation, code, message, data) {
1579
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
1581
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
1580
1582
  // 提取 isBroadcastCompleted 参数
1581
1583
  const { isBroadcastCompleted } = JSON.parse(data || '{}');
1582
1584
  // 先调用基类处理逻辑
@@ -1588,7 +1590,14 @@
1588
1590
  if (isBroadcastCompleted) {
1589
1591
  this.broadcastCompletedCount++;
1590
1592
  const status = this.getStatus();
1591
- if (((_a = status.queueInfo) === null || _a === void 0 ? void 0 : _a.completedTasks) === this.broadcastCompletedCount) {
1593
+ // 判断是否所有任务都已完成:
1594
+ // 1. 没有待请求的任务 (PENDING)
1595
+ // 2. 没有正在请求的任务 (REQUESTING)
1596
+ // 3. Unity播放完成次数等于已完成任务数
1597
+ const isAllTasksCompleted = ((_a = status.queueInfo) === null || _a === void 0 ? void 0 : _a.pendingTasks) === 0
1598
+ && ((_b = status.queueInfo) === null || _b === void 0 ? void 0 : _b.requestingTasks) === 0
1599
+ && ((_c = status.queueInfo) === null || _c === void 0 ? void 0 : _c.completedTasks) === this.broadcastCompletedCount;
1600
+ if (isAllTasksCompleted) {
1592
1601
  // 重置状态、计数
1593
1602
  this.isBroadcastingAudio = false;
1594
1603
  this.hasReceivedAudio = false;
@@ -1598,19 +1607,19 @@
1598
1607
  this.logger.warn('Broadcast all completed');
1599
1608
  }
1600
1609
  // this.logger.warn('AAAAAA', { status: this.getStatus(), broadcastCompletedCount: this.broadcastCompletedCount });
1601
- (_c = (_b = this.callbacks).onFinish) === null || _c === void 0 ? void 0 : _c.call(_b);
1610
+ (_e = (_d = this.callbacks).onFinish) === null || _e === void 0 ? void 0 : _e.call(_d);
1602
1611
  }
1603
1612
  break;
1604
1613
  case exports.BroadcastOperationType.PAUSE_BROADCAST:
1605
- (_e = (_d = this.callbacks).onPause) === null || _e === void 0 ? void 0 : _e.call(_d);
1614
+ (_g = (_f = this.callbacks).onPause) === null || _g === void 0 ? void 0 : _g.call(_f);
1606
1615
  this.logger.debug('Broadcast paused callback triggered');
1607
1616
  break;
1608
1617
  case exports.BroadcastOperationType.RESUME_BROADCAST:
1609
- (_g = (_f = this.callbacks).onResume) === null || _g === void 0 ? void 0 : _g.call(_f);
1618
+ (_j = (_h = this.callbacks).onResume) === null || _j === void 0 ? void 0 : _j.call(_h);
1610
1619
  this.logger.debug('Broadcast resumed callback triggered');
1611
1620
  break;
1612
1621
  case exports.BroadcastOperationType.STOP_BROADCAST:
1613
- (_j = (_h = this.callbacks).onStop) === null || _j === void 0 ? void 0 : _j.call(_h);
1622
+ (_l = (_k = this.callbacks).onStop) === null || _l === void 0 ? void 0 : _l.call(_k);
1614
1623
  this.logger.debug('Broadcast stopped callback triggered');
1615
1624
  break;
1616
1625
  }
@@ -1667,7 +1676,7 @@
1667
1676
  // 重置序号计数器
1668
1677
  this.taskSequence = 0;
1669
1678
  this.currentSendingSequence = 0;
1670
- // 通知Unity开始新任务(清空队列)
1679
+ // 通知Unity开始新任务(清空队列),这里不使用sendAsyncMessage,因为startBroadcast不需要等待完成,而是在任务播报完成后通过回调通知
1671
1680
  this.sendMessage('StartBroadcast', {
1672
1681
  callbackFun: this.uniqueCallbackName,
1673
1682
  operationType: exports.BroadcastOperationType.START_BROADCAST,
@@ -1779,18 +1788,20 @@
1779
1788
  * @description 获取当前播报服务的状态信息,包括队列状态
1780
1789
  */
1781
1790
  getStatus() {
1791
+ const pendingTasks = this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.PENDING).length;
1782
1792
  const completedTasks = this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.COMPLETED).length;
1783
1793
  const requestingTasks = this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.REQUESTING).length;
1784
1794
  const failedTasks = this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.FAILED).length;
1785
1795
  const totalPendingResponses = this.taskQueue.reduce((sum, t) => sum + t.pendingResponses.length, 0);
1786
1796
  const currentSendingSequence = this.currentSendingSequence;
1787
- const isGeneratingAudio = completedTasks + failedTasks !== this.taskQueue.length;
1797
+ const isGeneratingAudio = pendingTasks + requestingTasks > 0;
1788
1798
  return {
1789
1799
  isActive: this.isBroadcastingAudio || isGeneratingAudio, // 是否正在播报音频或正在生成音频
1790
1800
  isGeneratingAudio,
1791
1801
  hasReceivedAudio: this.hasReceivedAudio,
1792
1802
  queueInfo: {
1793
1803
  totalTasks: this.taskQueue.length,
1804
+ pendingTasks,
1794
1805
  requestingTasks,
1795
1806
  completedTasks,
1796
1807
  failedTasks,
@@ -1824,7 +1835,7 @@
1824
1835
  id: `broadcast_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
1825
1836
  sequence: ++this.taskSequence,
1826
1837
  params,
1827
- status: BroadcastTaskStatus.REQUESTING,
1838
+ status: BroadcastTaskStatus.PENDING,
1828
1839
  controller: new AbortController(),
1829
1840
  pendingResponses: [],
1830
1841
  isGenerationComplete: false,
@@ -1836,46 +1847,58 @@
1836
1847
  /**
1837
1848
  * 添加任务到队列
1838
1849
  * @param task - 播报任务
1839
- * @description 将任务添加到队列并立即开始请求
1850
+ * @description 将任务添加到队列,只有当没有正在请求的任务时才开始请求(串行请求模式)
1840
1851
  * @private
1841
1852
  */
1842
1853
  addTaskToQueue(task) {
1843
1854
  this.taskQueue.push(task);
1844
- this.logger.debug('Task added to queue', { taskId: task.id, queueLength: this.taskQueue.length });
1845
- // 立即开始该任务的请求
1846
- this.startTaskRequest(task);
1855
+ this.logger.debug('Task added to queue', { taskId: task.id, params: task.params, queueLength: this.taskQueue.length });
1856
+ // 检查是否有正在请求的任务
1857
+ const hasRequestingTask = this.taskQueue.some((t) => t.status === BroadcastTaskStatus.REQUESTING);
1858
+ // 只有当没有正在请求的任务时,才开始当前任务的请求
1859
+ if (!hasRequestingTask) {
1860
+ this.startTaskRequest(task);
1861
+ }
1862
+ else {
1863
+ this.logger.debug('Task queued, waiting for previous task to complete', {
1864
+ taskId: task.id,
1865
+ pendingTasks: this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.PENDING).length
1866
+ });
1867
+ }
1847
1868
  // 开始处理队列
1848
- this.processQueue();
1869
+ this.processTaskQueue();
1849
1870
  }
1850
1871
  /**
1851
1872
  * 处理队列
1852
- * @description 处理队列中的任务,发起请求生成音频
1873
+ * @description 处理队列中的任务响应,按序号发送给unity播放
1853
1874
  * @private
1854
1875
  */
1855
- processQueue() {
1876
+ processTaskQueue() {
1856
1877
  // 启动队列处理定时器(如果尚未启动)
1857
1878
  if (!this.queueProcessTimer) {
1858
1879
  this.queueProcessTimer = setInterval(() => {
1859
- this.processQueueStep();
1880
+ this.processTaskQueueStep();
1860
1881
  }, 100); // 每100ms检查一次队列状态
1861
1882
  }
1862
1883
  // 立即处理一次
1863
- this.processQueueStep();
1884
+ this.processTaskQueueStep();
1864
1885
  }
1865
1886
  /**
1866
1887
  * 队列处理步骤
1867
- * @description 处理队列中的单个步骤,包括发起请求和发送音频
1888
+ * @description 处理队列中的单个步骤,按序号发送给unity播放
1868
1889
  * @private
1869
1890
  */
1870
- processQueueStep() {
1871
- // 按序号找到下一个要处理的任务
1891
+ processTaskQueueStep() {
1892
+ // 按序号找到下一个要处理的任务(只处理已开始请求的任务,排除 PENDING 状态)
1872
1893
  const nextTask = this.taskQueue.find((task) => task.sequence === this.currentSendingSequence + 1
1894
+ && task.status !== BroadcastTaskStatus.PENDING
1873
1895
  && task.pendingResponses.length > 0);
1874
1896
  if (nextTask) {
1875
1897
  this.sendNextResponse(nextTask);
1876
1898
  }
1877
- // 如果队列中没有剩余任务,则停止定时器
1878
- const remainingTasks = this.taskQueue.filter(task => task.status !== BroadcastTaskStatus.COMPLETED
1899
+ // 如果队列中没有剩余任务(排除待处理、已完成、失败和取消的任务),则停止定时器
1900
+ const remainingTasks = this.taskQueue.filter(task => task.status !== BroadcastTaskStatus.PENDING
1901
+ && task.status !== BroadcastTaskStatus.COMPLETED
1879
1902
  && task.status !== BroadcastTaskStatus.FAILED
1880
1903
  && task.status !== BroadcastTaskStatus.CANCELLED);
1881
1904
  if (remainingTasks.length === 0) {
@@ -1967,7 +1990,7 @@
1967
1990
  const response = JSON.parse(data);
1968
1991
  // 错误处理
1969
1992
  if (response.code !== 0) {
1970
- this.handleBroadcastError(response.code);
1993
+ this.handleBroadcastError(response.code, response.message);
1971
1994
  return;
1972
1995
  }
1973
1996
  // 处理音频数据
@@ -1979,7 +2002,7 @@
1979
2002
  }
1980
2003
  // 添加处理后的响应对象到待发送队列
1981
2004
  task.pendingResponses.push(response);
1982
- this.logger.debug('Response added to task', { taskId: task.id, pendingCount: task.pendingResponses.length });
2005
+ this.logger.debug('Response added to task', { taskId: task.id, response, pendingCount: task.pendingResponses.length });
1983
2006
  // 检查是否完成
1984
2007
  if (response.data.done) {
1985
2008
  task.isGenerationComplete = true;
@@ -1988,13 +2011,13 @@
1988
2011
  }
1989
2012
  }
1990
2013
  catch (error) {
1991
- this.handleTaskError(task, error);
2014
+ this.handleTaskError(task, new SDKError(exports.OperationErrorCode.OPERATION_FAILED, typeof error === 'string' ? error : (error.message || '播报服务错误')));
1992
2015
  }
1993
2016
  }
1994
2017
  /**
1995
- * 发送下一个响应
2018
+ * 发送下一个响应给unity播放
1996
2019
  * @param task - 播报任务
1997
- * @description 发送任务中的第一个待发送响应到Unity,发送后立即删除
2020
+ * @description 发送任务的响应数组中的第一个待发送响应到Unity(按顺序发送),发送后立即删除
1998
2021
  * @private
1999
2022
  */
2000
2023
  sendNextResponse(task) {
@@ -2009,7 +2032,7 @@
2009
2032
  remainingResponses: task.pendingResponses.length,
2010
2033
  voiceUrl: (_a = response.data) === null || _a === void 0 ? void 0 : _a.voiceUrl
2011
2034
  });
2012
- // 发送响应到Unity
2035
+ // 发送响应到Unity,这里不使用sendAsyncMessage,因为appendBroadcast不需要等待完成,而是在任务播报完成后通过startBroadcast回调通知
2013
2036
  this.sendMessage('AppendBroadcast', {
2014
2037
  response,
2015
2038
  callbackFun: this.uniqueCallbackName,
@@ -2025,7 +2048,7 @@
2025
2048
  /**
2026
2049
  * 处理任务关闭
2027
2050
  * @param task - 播报任务
2028
- * @description 处理任务的流式连接关闭
2051
+ * @description 处理任务的流式连接关闭,并启动下一个待处理任务的请求
2029
2052
  * @private
2030
2053
  */
2031
2054
  handleTaskClose(task) {
@@ -2034,12 +2057,14 @@
2034
2057
  if (!task.isGenerationComplete && task.status === BroadcastTaskStatus.REQUESTING) {
2035
2058
  task.isGenerationComplete = true;
2036
2059
  }
2060
+ // 当前任务请求完成后(流断开后),启动下一个待处理任务的请求
2061
+ this.startNextPendingTask();
2037
2062
  }
2038
2063
  /**
2039
2064
  * 处理任务错误
2040
2065
  * @param task - 播报任务
2041
2066
  * @param error - 错误对象
2042
- * @description 处理任务执行过程中的错误,防止重复触发错误回调
2067
+ * @description 处理任务执行过程中的错误,防止重复触发错误回调,并启动下一个待处理任务
2043
2068
  * @private
2044
2069
  */
2045
2070
  handleTaskError(task, error) {
@@ -2142,10 +2167,11 @@
2142
2167
  /**
2143
2168
  * 处理播报错误
2144
2169
  * @param errorCode - 错误码
2170
+ * @param errorMessage - 错误消息
2145
2171
  * @description 处理播报过程中的错误
2146
2172
  * @private
2147
2173
  */
2148
- handleBroadcastError(errorCode) {
2174
+ handleBroadcastError(errorCode, errorMessage) {
2149
2175
  // 用户权益额度不存在错误码 14001
2150
2176
  // 用户权益额度不足错误码 14002
2151
2177
  // 用户权益额度冻结失败 14003
@@ -2160,10 +2186,31 @@
2160
2186
  this.handleError(new SDKError(exports.OperationErrorCode.BROADCAST_EQUITY_FREEZE_FAILED, '用户权益额度冻结失败'));
2161
2187
  break;
2162
2188
  default:
2163
- this.handleError(new SDKError(exports.OperationErrorCode.OPERATION_FAILED, '播报服务错误'));
2189
+ this.handleError(new SDKError(exports.OperationErrorCode.OPERATION_FAILED, `${errorMessage}(${errorCode})` || `播报服务错误(${errorCode})`));
2164
2190
  break;
2165
2191
  }
2166
2192
  }
2193
+ /**
2194
+ * 启动下一个待处理任务的请求
2195
+ * @description 在当前任务请求完成或失败后,检查并启动下一个待处理任务
2196
+ * @private
2197
+ */
2198
+ startNextPendingTask() {
2199
+ // 查找下一个待处理的任务(按序号排序,取第一个 PENDING 状态的任务)
2200
+ const nextPendingTask = this.taskQueue
2201
+ .filter((t) => t.status === BroadcastTaskStatus.PENDING)
2202
+ .sort((a, b) => a.sequence - b.sequence)[0];
2203
+ if (nextPendingTask) {
2204
+ this.logger.debug('Starting next pending task', {
2205
+ taskId: nextPendingTask.id,
2206
+ sequence: nextPendingTask.sequence
2207
+ });
2208
+ this.startTaskRequest(nextPendingTask);
2209
+ }
2210
+ else {
2211
+ this.logger.debug('No pending tasks to start');
2212
+ }
2213
+ }
2167
2214
  /**
2168
2215
  * 清理队列处理定时器
2169
2216
  * @description 清理队列处理定时器
@@ -2173,6 +2220,7 @@
2173
2220
  if (this.queueProcessTimer) {
2174
2221
  clearInterval(this.queueProcessTimer);
2175
2222
  this.queueProcessTimer = null;
2223
+ this.logger.debug('Queue process timer cleared');
2176
2224
  }
2177
2225
  }
2178
2226
  /**
@@ -2365,6 +2413,7 @@
2365
2413
  */
2366
2414
  initGlobalConfig() {
2367
2415
  const config = ConfigManager.getInstance().getConfig();
2416
+ const { assetsFrom } = config;
2368
2417
  const globalParams = {
2369
2418
  token: config === null || config === void 0 ? void 0 : config.token,
2370
2419
  apiBaseUrl: ConfigManager.getInstance().getApiBaseUrl(false),
@@ -2372,14 +2421,17 @@
2372
2421
  // 純AB包方案在SDK 2.1.0 中已弃用
2373
2422
  // assetsUrl: config?.assetsUrl
2374
2423
  };
2375
- const assetModuleParams = {
2376
- isZip: true,
2377
- assetBundlePath: config === null || config === void 0 ? void 0 : config.assetsUrl
2378
- };
2379
2424
  this.unityInstance.SendMessage('AvatarSDK', 'InitializeConfig', JSON.stringify(globalParams));
2380
- this.unityInstance.SendMessage('AvatarSDK', 'InitAssetBundleModule', JSON.stringify(assetModuleParams));
2381
2425
  console.warn('[ Send Unity message ]: AvatarSDK.InitializeConfig', globalParams);
2382
- console.warn('[ Send Unity message ]: AvatarSDK.InitAssetBundleModule', assetModuleParams);
2426
+ //
2427
+ if (assetsFrom !== 'cloud') {
2428
+ const assetModuleParams = {
2429
+ isZip: true,
2430
+ assetBundlePath: config === null || config === void 0 ? void 0 : config.assetsUrl
2431
+ };
2432
+ this.unityInstance.SendMessage('AvatarSDK', 'InitAssetBundleModule', JSON.stringify(assetModuleParams));
2433
+ console.warn('[ Send Unity message ]: AvatarSDK.InitAssetBundleModule', assetModuleParams);
2434
+ }
2383
2435
  }
2384
2436
  }
2385
2437
 
@@ -2417,7 +2469,7 @@
2417
2469
  * SDK 版本号
2418
2470
  * @const {string} SDK_VERSION
2419
2471
  */
2420
- const SDK_VERSION = '2.1.2';
2472
+ const SDK_VERSION = '2.1.4';
2421
2473
 
2422
2474
  /**
2423
2475
  * @fileoverview 统一的3D数字人SDK入口类
@@ -2483,14 +2535,16 @@
2483
2535
  this.avatarService = new AvatarService({
2484
2536
  unityInstance: this.unityInstance,
2485
2537
  instanceId: this.instanceId,
2486
- enableDebugLog: config.enableDebugLog
2538
+ enableDebugLog: config.enableDebugLog,
2539
+ timeout: config.operationTimeout
2487
2540
  });
2488
2541
  // 5. 创建带有唯一标识符的播报服务
2489
2542
  this.broadcastService = new BroadcastService({
2490
2543
  unityInstance: this.unityInstance,
2491
2544
  instanceId: this.instanceId,
2492
2545
  callbacks: config.broadcastCallbacks,
2493
- enableDebugLog: config.enableDebugLog
2546
+ enableDebugLog: config.enableDebugLog,
2547
+ timeout: config.operationTimeout
2494
2548
  });
2495
2549
  // 6. 初始化数字人
2496
2550
  const result = yield this.avatarService.initializeAvatar(avatarCode, cameraType);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zeewain/3d-avatar-sdk",
3
3
  "type": "module",
4
- "version": "2.1.2",
4
+ "version": "2.1.4",
5
5
  "description": "SDK for ZEE Avatar WebGL integration",
6
6
  "author": "ZEEWain",
7
7
  "license": "MIT",
@@ -55,6 +55,7 @@
55
55
  "release:patch": "release-it patch",
56
56
  "release:minor": "release-it minor",
57
57
  "release:major": "release-it major",
58
+ "release:dry:internal": "release-it --dry-run --config .release-it.internal.json",
58
59
  "release:dry": "release-it --dry-run",
59
60
  "release:internal": "release-it --config .release-it.internal.json",
60
61
  "release:alpha": "npm run release:internal -- --preRelease=alpha",