@zeewain/3d-avatar-sdk 1.2.3 → 1.2.4-0
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/README.md +213 -9
- package/dist/examples/test-vue2/package.json +1 -1
- package/dist/examples/test-vue3/index.html +1 -0
- package/dist/examples/test-vue3/package.json +3 -1
- package/dist/examples/test-vue3/plugins/html.ts +38 -0
- package/dist/examples/test-vue3/pnpm-lock.yaml +291 -90
- package/dist/examples/test-vue3/src/App.vue +4 -2
- package/dist/examples/test-vue3/src/components/BroadcastAPI.vue +38 -20
- package/dist/examples/test-vue3/tsconfig.node.json +2 -1
- package/dist/examples/test-vue3/vite.config.ts +4 -1
- package/dist/index.d.ts +108 -11
- package/dist/index.es5.js +389 -145
- package/dist/index.es5.umd.js +389 -145
- package/dist/index.esm.js +342 -131
- package/dist/index.umd.cjs +342 -131
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1507,6 +1507,20 @@ var BroadcastType;
|
|
|
1507
1507
|
* @fileoverview 流式播报服务重构实现模块
|
|
1508
1508
|
* @description 提供流式播报服务的重构实现,继承Unity基础服务,支持文本转语音和自定义音频播报
|
|
1509
1509
|
*/
|
|
1510
|
+
/**
|
|
1511
|
+
* 播报任务状态枚举
|
|
1512
|
+
*/
|
|
1513
|
+
var BroadcastTaskStatus;
|
|
1514
|
+
(function (BroadcastTaskStatus) {
|
|
1515
|
+
/** 请求中 */
|
|
1516
|
+
BroadcastTaskStatus["REQUESTING"] = "requesting";
|
|
1517
|
+
/** 已完成 */
|
|
1518
|
+
BroadcastTaskStatus["COMPLETED"] = "completed";
|
|
1519
|
+
/** 失败 */
|
|
1520
|
+
BroadcastTaskStatus["FAILED"] = "failed";
|
|
1521
|
+
/** 已取消 */
|
|
1522
|
+
BroadcastTaskStatus["CANCELLED"] = "cancelled";
|
|
1523
|
+
})(BroadcastTaskStatus || (BroadcastTaskStatus = {}));
|
|
1510
1524
|
/**
|
|
1511
1525
|
* 流式播报服务重构类
|
|
1512
1526
|
* @class BroadcastServiceRefactored
|
|
@@ -1536,12 +1550,20 @@ class BroadcastService extends UnityBaseService {
|
|
|
1536
1550
|
super(config);
|
|
1537
1551
|
/** 事件回调函数集合 */
|
|
1538
1552
|
this.callbacks = {};
|
|
1539
|
-
/**
|
|
1540
|
-
this.
|
|
1553
|
+
/** 播报任务队列 */
|
|
1554
|
+
this.taskQueue = [];
|
|
1555
|
+
/** 任务序号计数器 */
|
|
1556
|
+
this.taskSequence = 0;
|
|
1557
|
+
/** 当前发送任务的序号 */
|
|
1558
|
+
this.currentSendingSequence = 0;
|
|
1541
1559
|
/** 是否正在生成音频 */
|
|
1542
1560
|
this.isGeneratingAudio = false;
|
|
1543
1561
|
/** 是否已经收到音频 */
|
|
1544
1562
|
this.hasReceivedAudio = false;
|
|
1563
|
+
/** 队列处理定时器 */
|
|
1564
|
+
this.queueProcessTimer = null;
|
|
1565
|
+
/** 主请求控制器(兼容性保留) */
|
|
1566
|
+
this.activeController = null;
|
|
1545
1567
|
this.callbacks = config.callbacks || {};
|
|
1546
1568
|
this.logger.info('Broadcast service initialized', { config });
|
|
1547
1569
|
}
|
|
@@ -1590,8 +1612,9 @@ class BroadcastService extends UnityBaseService {
|
|
|
1590
1612
|
/**
|
|
1591
1613
|
* 开始播报
|
|
1592
1614
|
* @param params - 播报参数
|
|
1615
|
+
* @param isAppend - 是否追加播报
|
|
1593
1616
|
* @returns Promise<void> 播报操作的Promise
|
|
1594
|
-
* @description
|
|
1617
|
+
* @description 开始流式播报,支持文本转语音和自定义音频播报。使用队列机制确保音频按序播报
|
|
1595
1618
|
* @throws {SDKError} 当参数验证失败或播报失败时抛出错误
|
|
1596
1619
|
* @example
|
|
1597
1620
|
* ```typescript
|
|
@@ -1605,130 +1628,54 @@ class BroadcastService extends UnityBaseService {
|
|
|
1605
1628
|
* isSubtitle: true
|
|
1606
1629
|
* });
|
|
1607
1630
|
*
|
|
1608
|
-
* //
|
|
1631
|
+
* // 追加播报(会进入队列按序播报)
|
|
1609
1632
|
* await broadcastService.startBroadcast({
|
|
1610
|
-
* type: BroadcastType.
|
|
1633
|
+
* type: BroadcastType.TEXT,
|
|
1611
1634
|
* humanCode: 'human001',
|
|
1612
|
-
*
|
|
1635
|
+
* text: '这是第二段内容',
|
|
1636
|
+
* voiceCode: 'voice001',
|
|
1613
1637
|
* volume: 0.8,
|
|
1614
|
-
* isSubtitle:
|
|
1615
|
-
* });
|
|
1638
|
+
* isSubtitle: true
|
|
1639
|
+
* }, true);
|
|
1616
1640
|
* ```
|
|
1617
1641
|
*/
|
|
1618
|
-
startBroadcast(params) {
|
|
1642
|
+
startBroadcast(params, isAppend) {
|
|
1619
1643
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1620
1644
|
var _a, _b;
|
|
1621
|
-
this.logger.info(`Starting broadcast: ${params.type}`, {
|
|
1645
|
+
this.logger.info(`Starting broadcast: ${params.type}`, {
|
|
1646
|
+
humanCode: params.humanCode,
|
|
1647
|
+
isAppend,
|
|
1648
|
+
queueLength: this.taskQueue.length
|
|
1649
|
+
});
|
|
1622
1650
|
// 验证参数
|
|
1623
1651
|
this.validateBroadcastParams(params);
|
|
1624
|
-
//
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
this.hasReceivedAudio = false;
|
|
1639
|
-
this.activeController = null;
|
|
1640
|
-
});
|
|
1641
|
-
// 通知Unity开始新任务(清空队列)
|
|
1642
|
-
this.sendMessage('StartBroadcast', {
|
|
1643
|
-
callbackFun: this.uniqueCallbackName,
|
|
1644
|
-
operationType: BroadcastOperationType.START_BROADCAST,
|
|
1645
|
-
motionList: params.motionList,
|
|
1646
|
-
motionPlayMode: params.motionPlayMode
|
|
1647
|
-
});
|
|
1648
|
-
try {
|
|
1649
|
-
const apiUrl = `${ConfigManager.getInstance().getApiBaseUrl(true)}${this.getBroadcastApiPath(params.type)}`;
|
|
1650
|
-
const requestBody = {
|
|
1651
|
-
humanCode: params.humanCode,
|
|
1652
|
-
speed: params.speed,
|
|
1653
|
-
volume: params.volume >= 0 ? params.volume * 100 : undefined, // 转换为百分比
|
|
1654
|
-
isSubtitle: params.isSubtitle
|
|
1655
|
-
};
|
|
1656
|
-
// 根据播报类型设置特定参数
|
|
1657
|
-
if (params.type === BroadcastType.TEXT) {
|
|
1658
|
-
requestBody.text = params.text;
|
|
1659
|
-
requestBody.voiceCode = params.voiceCode;
|
|
1660
|
-
}
|
|
1661
|
-
else if (params.type === BroadcastType.AUDIO) {
|
|
1662
|
-
requestBody.text = params.text;
|
|
1663
|
-
requestBody.audioUrl = params.audioUrl;
|
|
1664
|
-
}
|
|
1665
|
-
this.logger.debug('Sending broadcast request', { apiUrl, requestBody });
|
|
1652
|
+
// 非追加模式下需要初始化播报
|
|
1653
|
+
if (!isAppend) {
|
|
1654
|
+
// 先停止当前播报并清空队列
|
|
1655
|
+
yield this.stopBroadcast();
|
|
1656
|
+
// 重置序号计数器
|
|
1657
|
+
this.taskSequence = 0;
|
|
1658
|
+
this.currentSendingSequence = 0;
|
|
1659
|
+
// 通知Unity开始新任务(清空队列)
|
|
1660
|
+
this.sendMessage('StartBroadcast', {
|
|
1661
|
+
callbackFun: this.uniqueCallbackName,
|
|
1662
|
+
operationType: BroadcastOperationType.START_BROADCAST,
|
|
1663
|
+
motionList: params.motionList,
|
|
1664
|
+
motionPlayMode: params.motionPlayMode
|
|
1665
|
+
});
|
|
1666
1666
|
// 触发开始回调
|
|
1667
1667
|
(_b = (_a = this.callbacks).onStart) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
1668
1668
|
this.isGeneratingAudio = true;
|
|
1669
|
-
// 发起流式播报请求
|
|
1670
|
-
yield fetchEventSource(apiUrl, {
|
|
1671
|
-
method: 'POST',
|
|
1672
|
-
headers: {
|
|
1673
|
-
'Content-Type': 'application/json',
|
|
1674
|
-
'x_auth_token': ConfigManager.getInstance().getToken()
|
|
1675
|
-
},
|
|
1676
|
-
body: JSON.stringify(requestBody),
|
|
1677
|
-
signal: this.activeController.signal,
|
|
1678
|
-
openWhenHidden: true,
|
|
1679
|
-
onmessage: (event) => {
|
|
1680
|
-
const response = JSON.parse(event.data);
|
|
1681
|
-
// 错误处理
|
|
1682
|
-
if (response.code !== 0) {
|
|
1683
|
-
this.handleBroadcastError(response.code);
|
|
1684
|
-
return;
|
|
1685
|
-
}
|
|
1686
|
-
// 流式播报
|
|
1687
|
-
if (response.data) {
|
|
1688
|
-
// 未完成播报时,更新任务ID
|
|
1689
|
-
if (!response.data.done) {
|
|
1690
|
-
this.hasReceivedAudio = true;
|
|
1691
|
-
}
|
|
1692
|
-
// 自定义音频播报时,如果服务器未返回音频URL,使用传入的audioUrl
|
|
1693
|
-
if (params.type === BroadcastType.AUDIO && params.audioUrl && !response.data.voiceUrl) {
|
|
1694
|
-
response.data.voiceUrl = params.audioUrl;
|
|
1695
|
-
}
|
|
1696
|
-
// 如果有音频URL,发送到Unity
|
|
1697
|
-
if (response.data.voiceUrl) {
|
|
1698
|
-
this.sendMessage('AppendBroadcast', {
|
|
1699
|
-
response,
|
|
1700
|
-
callbackFun: this.uniqueCallbackName,
|
|
1701
|
-
operationType: BroadcastOperationType.APPEND_BROADCAST
|
|
1702
|
-
});
|
|
1703
|
-
}
|
|
1704
|
-
if (response.data.done) {
|
|
1705
|
-
this.isGeneratingAudio = false;
|
|
1706
|
-
this.hasReceivedAudio = false;
|
|
1707
|
-
this.activeController = null;
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
},
|
|
1711
|
-
onclose: () => {
|
|
1712
|
-
var _a;
|
|
1713
|
-
// 如果不是由abort触发的关闭,需要处理
|
|
1714
|
-
if (this.isGeneratingAudio) {
|
|
1715
|
-
(_a = this.activeController) === null || _a === void 0 ? void 0 : _a.abort();
|
|
1716
|
-
}
|
|
1717
|
-
// 流结束时调用完成回调
|
|
1718
|
-
this.logger.debug('Broadcast stream closed');
|
|
1719
|
-
},
|
|
1720
|
-
onerror: (error) => {
|
|
1721
|
-
this.logger.error('Broadcast stream error', error);
|
|
1722
|
-
const sdkError = new SDKError(OperationErrorCode.OPERATION_FAILED, '服务出错了', error);
|
|
1723
|
-
this.handleError(sdkError);
|
|
1724
|
-
// 必须抛出错误,否则会循环重试请求
|
|
1725
|
-
throw new Error(`服务出错了${sdkError.message}`);
|
|
1726
|
-
}
|
|
1727
|
-
});
|
|
1728
|
-
}
|
|
1729
|
-
catch (error) {
|
|
1730
|
-
this.handleError(error);
|
|
1731
1669
|
}
|
|
1670
|
+
// 创建新的播报任务
|
|
1671
|
+
const task = this.createBroadcastTask(params);
|
|
1672
|
+
// 添加任务到队列
|
|
1673
|
+
this.addTaskToQueue(task);
|
|
1674
|
+
this.logger.debug('Broadcast task created and queued', {
|
|
1675
|
+
taskId: task.id,
|
|
1676
|
+
sequence: task.sequence,
|
|
1677
|
+
isAppend
|
|
1678
|
+
});
|
|
1732
1679
|
});
|
|
1733
1680
|
}
|
|
1734
1681
|
/**
|
|
@@ -1789,12 +1736,12 @@ class BroadcastService extends UnityBaseService {
|
|
|
1789
1736
|
*/
|
|
1790
1737
|
stopBroadcast() {
|
|
1791
1738
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1792
|
-
this.logger.info('Stopping broadcast');
|
|
1793
|
-
//
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1739
|
+
this.logger.info('Stopping broadcast and clearing queue', { queueLength: this.taskQueue.length });
|
|
1740
|
+
// 取消所有队列中的任务
|
|
1741
|
+
this.cancelAllTasks();
|
|
1742
|
+
// 重置状态
|
|
1743
|
+
this.isGeneratingAudio = false;
|
|
1744
|
+
this.hasReceivedAudio = false;
|
|
1798
1745
|
try {
|
|
1799
1746
|
yield this.sendAsyncMessage('StopBroadcast', BroadcastOperationType.STOP_BROADCAST, {});
|
|
1800
1747
|
this.logger.info('Broadcast stopped successfully');
|
|
@@ -1817,15 +1764,23 @@ class BroadcastService extends UnityBaseService {
|
|
|
1817
1764
|
/**
|
|
1818
1765
|
* 获取播报状态
|
|
1819
1766
|
* @returns 播报状态信息
|
|
1820
|
-
* @description
|
|
1767
|
+
* @description 获取当前播报服务的状态信息,包括队列状态
|
|
1821
1768
|
*/
|
|
1822
1769
|
getStatus() {
|
|
1823
1770
|
return {
|
|
1824
|
-
isActive: this.
|
|
1771
|
+
isActive: this.taskQueue.length > 0 || this.isGeneratingAudio,
|
|
1825
1772
|
isGeneratingAudio: this.isGeneratingAudio,
|
|
1826
1773
|
hasReceivedAudio: this.hasReceivedAudio,
|
|
1827
1774
|
pendingCallbacks: this.getPendingCallbackCount(),
|
|
1828
|
-
hasController: this.activeController !== null
|
|
1775
|
+
hasController: this.activeController !== null,
|
|
1776
|
+
queueInfo: {
|
|
1777
|
+
totalTasks: this.taskQueue.length,
|
|
1778
|
+
requestingTasks: this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.REQUESTING).length,
|
|
1779
|
+
completedTasks: this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.COMPLETED).length,
|
|
1780
|
+
failedTasks: this.taskQueue.filter((t) => t.status === BroadcastTaskStatus.FAILED).length,
|
|
1781
|
+
totalPendingResponses: this.taskQueue.reduce((sum, t) => sum + t.pendingResponses.length, 0),
|
|
1782
|
+
currentSendingSequence: this.currentSendingSequence
|
|
1783
|
+
}
|
|
1829
1784
|
};
|
|
1830
1785
|
}
|
|
1831
1786
|
/**
|
|
@@ -1833,15 +1788,268 @@ class BroadcastService extends UnityBaseService {
|
|
|
1833
1788
|
* @description 清理所有资源和回调
|
|
1834
1789
|
*/
|
|
1835
1790
|
destroy() {
|
|
1836
|
-
//
|
|
1837
|
-
if (this.
|
|
1838
|
-
this.
|
|
1839
|
-
this.
|
|
1791
|
+
// 清理队列处理定时器
|
|
1792
|
+
if (this.queueProcessTimer) {
|
|
1793
|
+
clearInterval(this.queueProcessTimer);
|
|
1794
|
+
this.queueProcessTimer = null;
|
|
1840
1795
|
}
|
|
1796
|
+
// 取消所有任务
|
|
1797
|
+
this.cancelAllTasks();
|
|
1841
1798
|
// 调用基类销毁方法
|
|
1842
1799
|
super.destroy();
|
|
1843
1800
|
this.logger.info('Broadcast service destroyed');
|
|
1844
1801
|
}
|
|
1802
|
+
/**
|
|
1803
|
+
* 创建播报任务
|
|
1804
|
+
* @param params - 播报参数
|
|
1805
|
+
* @returns IBroadcastTask 播报任务对象
|
|
1806
|
+
* @description 创建新的播报任务并分配唯一ID和序号
|
|
1807
|
+
* @private
|
|
1808
|
+
*/
|
|
1809
|
+
createBroadcastTask(params) {
|
|
1810
|
+
const task = {
|
|
1811
|
+
id: `broadcast_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
|
|
1812
|
+
sequence: ++this.taskSequence,
|
|
1813
|
+
params,
|
|
1814
|
+
status: BroadcastTaskStatus.REQUESTING,
|
|
1815
|
+
controller: new AbortController(),
|
|
1816
|
+
pendingResponses: [],
|
|
1817
|
+
isGenerationComplete: false,
|
|
1818
|
+
createdAt: new Date()
|
|
1819
|
+
};
|
|
1820
|
+
this.logger.debug('Created broadcast task', { taskId: task.id, sequence: task.sequence });
|
|
1821
|
+
return task;
|
|
1822
|
+
}
|
|
1823
|
+
/**
|
|
1824
|
+
* 添加任务到队列
|
|
1825
|
+
* @param task - 播报任务
|
|
1826
|
+
* @description 将任务添加到队列并立即开始请求
|
|
1827
|
+
* @private
|
|
1828
|
+
*/
|
|
1829
|
+
addTaskToQueue(task) {
|
|
1830
|
+
this.taskQueue.push(task);
|
|
1831
|
+
this.logger.debug('Task added to queue', { taskId: task.id, queueLength: this.taskQueue.length });
|
|
1832
|
+
// 立即开始该任务的请求
|
|
1833
|
+
this.startTaskRequest(task);
|
|
1834
|
+
// 开始处理队列
|
|
1835
|
+
this.processQueue();
|
|
1836
|
+
}
|
|
1837
|
+
/**
|
|
1838
|
+
* 处理队列
|
|
1839
|
+
* @description 处理队列中的任务,发起请求生成音频
|
|
1840
|
+
* @private
|
|
1841
|
+
*/
|
|
1842
|
+
processQueue() {
|
|
1843
|
+
// 启动队列处理定时器(如果尚未启动)
|
|
1844
|
+
if (!this.queueProcessTimer) {
|
|
1845
|
+
this.queueProcessTimer = setInterval(() => {
|
|
1846
|
+
this.processQueueStep();
|
|
1847
|
+
}, 100); // 每100ms检查一次队列状态
|
|
1848
|
+
}
|
|
1849
|
+
// 立即处理一次
|
|
1850
|
+
this.processQueueStep();
|
|
1851
|
+
}
|
|
1852
|
+
/**
|
|
1853
|
+
* 队列处理步骤
|
|
1854
|
+
* @description 处理队列中的单个步骤,包括发起请求和发送音频
|
|
1855
|
+
* @private
|
|
1856
|
+
*/
|
|
1857
|
+
processQueueStep() {
|
|
1858
|
+
// 按序号找到下一个要处理的任务
|
|
1859
|
+
const nextTask = this.taskQueue.find((task) => task.sequence === this.currentSendingSequence + 1
|
|
1860
|
+
&& task.pendingResponses.length > 0);
|
|
1861
|
+
if (nextTask) {
|
|
1862
|
+
this.sendNextResponse(nextTask);
|
|
1863
|
+
}
|
|
1864
|
+
// 清理已完成的任务
|
|
1865
|
+
this.cleanupCompletedTasks();
|
|
1866
|
+
// 如果队列为空,停止定时器
|
|
1867
|
+
if (this.taskQueue.length === 0 && this.queueProcessTimer) {
|
|
1868
|
+
clearInterval(this.queueProcessTimer);
|
|
1869
|
+
this.queueProcessTimer = null;
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
/**
|
|
1873
|
+
* 开始任务请求
|
|
1874
|
+
* @param task - 播报任务
|
|
1875
|
+
* @description 为任务发起流式请求生成音频
|
|
1876
|
+
* @private
|
|
1877
|
+
*/
|
|
1878
|
+
startTaskRequest(task) {
|
|
1879
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1880
|
+
task.status = BroadcastTaskStatus.REQUESTING;
|
|
1881
|
+
this.logger.debug('Starting task request', { taskId: task.id });
|
|
1882
|
+
try {
|
|
1883
|
+
const apiUrl = `${ConfigManager.getInstance().getApiBaseUrl(true)}${this.getBroadcastApiPath(task.params.type)}`;
|
|
1884
|
+
const requestBody = {
|
|
1885
|
+
humanCode: task.params.humanCode,
|
|
1886
|
+
speed: task.params.speed,
|
|
1887
|
+
volume: task.params.volume >= 0 ? task.params.volume * 100 : undefined,
|
|
1888
|
+
isSubtitle: task.params.isSubtitle
|
|
1889
|
+
};
|
|
1890
|
+
// 根据播报类型设置特定参数
|
|
1891
|
+
if (task.params.type === BroadcastType.TEXT) {
|
|
1892
|
+
requestBody.text = task.params.text;
|
|
1893
|
+
requestBody.voiceCode = task.params.voiceCode;
|
|
1894
|
+
}
|
|
1895
|
+
else if (task.params.type === BroadcastType.AUDIO) {
|
|
1896
|
+
requestBody.text = task.params.text;
|
|
1897
|
+
requestBody.audioUrl = task.params.audioUrl;
|
|
1898
|
+
}
|
|
1899
|
+
// 发起流式请求
|
|
1900
|
+
fetchEventSource(apiUrl, {
|
|
1901
|
+
method: 'POST',
|
|
1902
|
+
headers: {
|
|
1903
|
+
'Content-Type': 'application/json',
|
|
1904
|
+
'x_auth_token': ConfigManager.getInstance().getToken()
|
|
1905
|
+
},
|
|
1906
|
+
body: JSON.stringify(requestBody),
|
|
1907
|
+
signal: task.controller.signal,
|
|
1908
|
+
openWhenHidden: true,
|
|
1909
|
+
onmessage: (event) => {
|
|
1910
|
+
this.handleTaskResponse(task, event.data);
|
|
1911
|
+
},
|
|
1912
|
+
onclose: () => {
|
|
1913
|
+
this.handleTaskClose(task);
|
|
1914
|
+
},
|
|
1915
|
+
onerror: (error) => {
|
|
1916
|
+
this.handleTaskError(task, error);
|
|
1917
|
+
throw new Error(`Task ${task.id} request failed: ${error}`);
|
|
1918
|
+
}
|
|
1919
|
+
});
|
|
1920
|
+
}
|
|
1921
|
+
catch (error) {
|
|
1922
|
+
this.handleTaskError(task, error);
|
|
1923
|
+
}
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1926
|
+
/**
|
|
1927
|
+
* 处理任务响应
|
|
1928
|
+
* @param task - 播报任务
|
|
1929
|
+
* @param data - 响应数据
|
|
1930
|
+
* @description 处理任务的流式响应数据
|
|
1931
|
+
* @private
|
|
1932
|
+
*/
|
|
1933
|
+
handleTaskResponse(task, data) {
|
|
1934
|
+
try {
|
|
1935
|
+
const response = JSON.parse(data);
|
|
1936
|
+
// 错误处理
|
|
1937
|
+
if (response.code !== 0) {
|
|
1938
|
+
this.handleBroadcastError(response.code);
|
|
1939
|
+
return;
|
|
1940
|
+
}
|
|
1941
|
+
// 处理音频数据
|
|
1942
|
+
if (response.data && response.data.voiceUrl) {
|
|
1943
|
+
// 自定义音频播报时,如果服务器未返回音频URL,使用传入的audioUrl
|
|
1944
|
+
if (task.params.type === BroadcastType.AUDIO && task.params.audioUrl && !response.data.voiceUrl) {
|
|
1945
|
+
response.data.voiceUrl = task.params.audioUrl;
|
|
1946
|
+
}
|
|
1947
|
+
// 添加处理后的响应对象到待发送队列
|
|
1948
|
+
task.pendingResponses.push(response);
|
|
1949
|
+
this.logger.debug('Response added to task', { taskId: task.id, pendingCount: task.pendingResponses.length });
|
|
1950
|
+
}
|
|
1951
|
+
// 检查是否完成
|
|
1952
|
+
if (response.data && response.data.done) {
|
|
1953
|
+
task.isGenerationComplete = true;
|
|
1954
|
+
this.logger.debug('Task generation completed', { taskId: task.id, totalResponses: task.pendingResponses.length });
|
|
1955
|
+
// 任务完成生成,保持REQUESTING状态直到所有响应发送完毕
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
catch (error) {
|
|
1959
|
+
this.handleTaskError(task, error);
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
/**
|
|
1963
|
+
* 发送下一个响应
|
|
1964
|
+
* @param task - 播报任务
|
|
1965
|
+
* @description 发送任务中的第一个待发送响应到Unity,发送后立即删除
|
|
1966
|
+
* @private
|
|
1967
|
+
*/
|
|
1968
|
+
sendNextResponse(task) {
|
|
1969
|
+
var _a;
|
|
1970
|
+
if (task.pendingResponses.length === 0) {
|
|
1971
|
+
return;
|
|
1972
|
+
}
|
|
1973
|
+
// 取出第一个待发送的响应
|
|
1974
|
+
const response = task.pendingResponses.shift();
|
|
1975
|
+
this.logger.debug('Sending response to Unity', {
|
|
1976
|
+
taskId: task.id,
|
|
1977
|
+
remainingResponses: task.pendingResponses.length,
|
|
1978
|
+
voiceUrl: (_a = response.data) === null || _a === void 0 ? void 0 : _a.voiceUrl
|
|
1979
|
+
});
|
|
1980
|
+
// 发送响应到Unity
|
|
1981
|
+
this.sendMessage('AppendBroadcast', {
|
|
1982
|
+
response,
|
|
1983
|
+
callbackFun: this.uniqueCallbackName,
|
|
1984
|
+
operationType: BroadcastOperationType.APPEND_BROADCAST
|
|
1985
|
+
});
|
|
1986
|
+
// 如果任务已完成且没有更多待发送响应,标记任务完成并推进序号
|
|
1987
|
+
if (task.isGenerationComplete && task.pendingResponses.length === 0) {
|
|
1988
|
+
task.status = BroadcastTaskStatus.COMPLETED;
|
|
1989
|
+
this.currentSendingSequence = task.sequence;
|
|
1990
|
+
this.logger.debug('Task completed', { taskId: task.id });
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
/**
|
|
1994
|
+
* 处理任务关闭
|
|
1995
|
+
* @param task - 播报任务
|
|
1996
|
+
* @description 处理任务的流式连接关闭
|
|
1997
|
+
* @private
|
|
1998
|
+
*/
|
|
1999
|
+
handleTaskClose(task) {
|
|
2000
|
+
this.logger.debug('Task stream closed', { taskId: task.id });
|
|
2001
|
+
// 如果还没有标记为完成,则标记为完成
|
|
2002
|
+
if (!task.isGenerationComplete && task.status === BroadcastTaskStatus.REQUESTING) {
|
|
2003
|
+
task.isGenerationComplete = true;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
/**
|
|
2007
|
+
* 处理任务错误
|
|
2008
|
+
* @param task - 播报任务
|
|
2009
|
+
* @param error - 错误对象
|
|
2010
|
+
* @description 处理任务执行过程中的错误
|
|
2011
|
+
* @private
|
|
2012
|
+
*/
|
|
2013
|
+
handleTaskError(task, error) {
|
|
2014
|
+
var _a, _b;
|
|
2015
|
+
task.status = BroadcastTaskStatus.FAILED;
|
|
2016
|
+
task.error = error;
|
|
2017
|
+
this.logger.error(`Task failed - ${task.id}`, error);
|
|
2018
|
+
// 触发错误回调
|
|
2019
|
+
(_b = (_a = this.callbacks).onError) === null || _b === void 0 ? void 0 : _b.call(_a, error);
|
|
2020
|
+
}
|
|
2021
|
+
/**
|
|
2022
|
+
* 清理已完成的任务
|
|
2023
|
+
* @description 从队列中移除已完成、失败或取消的任务
|
|
2024
|
+
* @private
|
|
2025
|
+
*/
|
|
2026
|
+
cleanupCompletedTasks() {
|
|
2027
|
+
const beforeLength = this.taskQueue.length;
|
|
2028
|
+
this.taskQueue = this.taskQueue.filter(task => task.status !== BroadcastTaskStatus.COMPLETED
|
|
2029
|
+
&& task.status !== BroadcastTaskStatus.FAILED
|
|
2030
|
+
&& task.status !== BroadcastTaskStatus.CANCELLED);
|
|
2031
|
+
const removedCount = beforeLength - this.taskQueue.length;
|
|
2032
|
+
if (removedCount > 0) {
|
|
2033
|
+
this.logger.debug('Cleaned up completed tasks', { removedCount, remainingTasks: this.taskQueue.length });
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
/**
|
|
2037
|
+
* 取消所有任务
|
|
2038
|
+
* @description 取消队列中的所有任务
|
|
2039
|
+
* @private
|
|
2040
|
+
*/
|
|
2041
|
+
cancelAllTasks() {
|
|
2042
|
+
for (const task of this.taskQueue) {
|
|
2043
|
+
if (task.status !== BroadcastTaskStatus.COMPLETED && task.status !== BroadcastTaskStatus.FAILED) {
|
|
2044
|
+
task.controller.abort();
|
|
2045
|
+
task.status = BroadcastTaskStatus.CANCELLED;
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
this.taskQueue = [];
|
|
2049
|
+
this.taskSequence = 0;
|
|
2050
|
+
this.currentSendingSequence = 0;
|
|
2051
|
+
this.logger.debug('All tasks cancelled and queue cleared');
|
|
2052
|
+
}
|
|
1845
2053
|
/** 全局回调函数名称 */
|
|
1846
2054
|
get callbackFunctionName() {
|
|
1847
2055
|
return 'uniBroadcastCallback';
|
|
@@ -2130,13 +2338,15 @@ class ZEEAvatarSDK {
|
|
|
2130
2338
|
// 4. 创建带有唯一标识符的Avatar服务
|
|
2131
2339
|
this.avatarService = new AvatarService({
|
|
2132
2340
|
unityInstance: this.unityInstance,
|
|
2133
|
-
instanceId: this.instanceId
|
|
2341
|
+
instanceId: this.instanceId,
|
|
2342
|
+
enableDebugLog: this.config.enableDebugLog
|
|
2134
2343
|
});
|
|
2135
2344
|
// 5. 创建带有唯一标识符的播报服务
|
|
2136
2345
|
this.broadcastService = new BroadcastService({
|
|
2137
2346
|
unityInstance: this.unityInstance,
|
|
2138
2347
|
instanceId: this.instanceId,
|
|
2139
|
-
callbacks: this.config.broadcastCallbacks
|
|
2348
|
+
callbacks: this.config.broadcastCallbacks,
|
|
2349
|
+
enableDebugLog: this.config.enableDebugLog
|
|
2140
2350
|
});
|
|
2141
2351
|
// 6. 初始化数字人
|
|
2142
2352
|
const result = yield this.avatarService.initializeAvatar(avatarCode, cameraType);
|
|
@@ -2224,12 +2434,13 @@ class ZEEAvatarSDK {
|
|
|
2224
2434
|
/**
|
|
2225
2435
|
* 开始播报
|
|
2226
2436
|
* @param params 播报参数
|
|
2437
|
+
* @param isAppend 是否追加播报
|
|
2227
2438
|
* @returns Promise<void> 播报操作的Promise
|
|
2228
2439
|
*/
|
|
2229
|
-
startBroadcast(params) {
|
|
2440
|
+
startBroadcast(params, isAppend) {
|
|
2230
2441
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2231
2442
|
this.ensureInitialized();
|
|
2232
|
-
return yield this.broadcastService.startBroadcast(params);
|
|
2443
|
+
return yield this.broadcastService.startBroadcast(params, isAppend);
|
|
2233
2444
|
});
|
|
2234
2445
|
}
|
|
2235
2446
|
/**
|