@zeewain/3d-avatar-sdk 1.2.3 → 1.2.4-1
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 +5 -3
- 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 +388 -145
- package/dist/index.es5.umd.js +388 -145
- package/dist/index.esm.js +341 -131
- package/dist/index.umd.cjs +341 -131
- package/package.json +1 -1
|
@@ -299,7 +299,7 @@ function initializeSDKConfig(): ZEEAvatarSDK | null {
|
|
|
299
299
|
env: globalConfig.env,
|
|
300
300
|
apiUrl: globalConfig.apiBaseUrl,
|
|
301
301
|
resourcesUrl: globalConfig.resourcesUrl || undefined,
|
|
302
|
-
|
|
302
|
+
enableDebugLog: true,
|
|
303
303
|
// 待机动作列表:比心,左手指示(低)
|
|
304
304
|
idleMotionList: globalConfig.idleMotionListString?.split(',').filter(item => item.trim()) || [],
|
|
305
305
|
|
|
@@ -452,6 +452,7 @@ async function handleTextBroadcast(params: {
|
|
|
452
452
|
voiceCode?: string;
|
|
453
453
|
speed?: number;
|
|
454
454
|
broadcastMotionString?: string;
|
|
455
|
+
isAppend?: boolean;
|
|
455
456
|
}): Promise<void> {
|
|
456
457
|
if (!sdk.value) return;
|
|
457
458
|
|
|
@@ -470,7 +471,7 @@ async function handleTextBroadcast(params: {
|
|
|
470
471
|
motionPlayMode: 'random'
|
|
471
472
|
};
|
|
472
473
|
|
|
473
|
-
await sdk.value.startBroadcast(broadcastParams);
|
|
474
|
+
await sdk.value.startBroadcast(broadcastParams, params.isAppend);
|
|
474
475
|
addLog('文本播报已开始', 'success');
|
|
475
476
|
// ElMessage.success('文本播报已开始');
|
|
476
477
|
} catch (error) {
|
|
@@ -488,6 +489,7 @@ async function handleAudioBroadcast(params: {
|
|
|
488
489
|
speed?: number;
|
|
489
490
|
audioText?: string;
|
|
490
491
|
broadcastMotionString?: string;
|
|
492
|
+
isAppend?: boolean;
|
|
491
493
|
}): Promise<void> {
|
|
492
494
|
if (!sdk.value) return;
|
|
493
495
|
|
|
@@ -506,7 +508,7 @@ async function handleAudioBroadcast(params: {
|
|
|
506
508
|
motionPlayMode: 'random'
|
|
507
509
|
};
|
|
508
510
|
|
|
509
|
-
await sdk.value.startBroadcast(broadcastParams);
|
|
511
|
+
await sdk.value.startBroadcast(broadcastParams, params.isAppend);
|
|
510
512
|
addLog('音频播报已开始', 'success');
|
|
511
513
|
ElMessage.success('音频播报已开始');
|
|
512
514
|
} catch (error) {
|
|
@@ -115,15 +115,18 @@
|
|
|
115
115
|
</div>
|
|
116
116
|
</el-form-item>
|
|
117
117
|
<el-form-item class="action-buttons">
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
<div class="action-buttons-container">
|
|
119
|
+
<el-button
|
|
120
|
+
type="primary"
|
|
121
|
+
icon="chat-dot-round"
|
|
122
|
+
:loading="isTextLoading"
|
|
123
|
+
:disabled="!sdkStatus.canBroadcast || !textFormData.text || !textFormData.voiceCode || !globalConfig.avatarCode"
|
|
124
|
+
@click="handleTextBroadcast"
|
|
125
|
+
>
|
|
126
|
+
{{ isTextLoading ? '播报中...' : '执行文本播报' }}
|
|
127
|
+
</el-button>
|
|
128
|
+
<el-button @click="handleResetBroadcast">重置</el-button>
|
|
129
|
+
</div>
|
|
127
130
|
</el-form-item>
|
|
128
131
|
</el-form>
|
|
129
132
|
</div>
|
|
@@ -181,15 +184,18 @@
|
|
|
181
184
|
</el-form-item>
|
|
182
185
|
|
|
183
186
|
<el-form-item class="action-buttons">
|
|
184
|
-
<
|
|
187
|
+
<div class="action-buttons-container">
|
|
188
|
+
<el-button
|
|
185
189
|
type="primary"
|
|
186
190
|
icon="headset"
|
|
187
191
|
:loading="isAudioLoading"
|
|
188
192
|
:disabled="!sdkStatus.canBroadcast || !audioFormData.audioUrl || !globalConfig.avatarCode"
|
|
189
193
|
@click="handleAudioBroadcast"
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
194
|
+
>
|
|
195
|
+
{{ isAudioLoading ? '播报中...' : '执行音频播报' }}
|
|
196
|
+
</el-button>
|
|
197
|
+
<el-button @click="handleResetBroadcast">重置</el-button>
|
|
198
|
+
</div>
|
|
193
199
|
</el-form-item>
|
|
194
200
|
</el-form>
|
|
195
201
|
</div>
|
|
@@ -328,6 +334,7 @@ const isAudioLoading = ref(false);
|
|
|
328
334
|
const pauseLoading = ref(false);
|
|
329
335
|
const resumeLoading = ref(false);
|
|
330
336
|
const stopLoading = ref(false);
|
|
337
|
+
const isStartBroadcast = ref(false);
|
|
331
338
|
|
|
332
339
|
async function handleTextBroadcast() {
|
|
333
340
|
const { text, volume, speed, voiceCode, broadcastMotionString } = textFormData;
|
|
@@ -345,11 +352,12 @@ async function handleTextBroadcast() {
|
|
|
345
352
|
isTextLoading.value = true;
|
|
346
353
|
result.value = `🔄 正在执行文本播报...\n📝 播报文本: ${text.substring(0, 30)}${text.length > 30 ? '...' : ''}\n🎤 音色编码: ${voiceCode}\n🔊 音量: ${volume}\n⚡ 语速: ${speed}\n\n📡 流式播报中,请等待服务器响应...`;
|
|
347
354
|
try {
|
|
348
|
-
emit('text-broadcast', { avatarCode, text, volume, speed, voiceCode, broadcastMotionString });
|
|
355
|
+
emit('text-broadcast', { avatarCode, text, volume, speed, voiceCode, broadcastMotionString, isAppend: isStartBroadcast.value });
|
|
356
|
+
isStartBroadcast.value = true;
|
|
349
357
|
setTimeout(() => {
|
|
350
358
|
isTextLoading.value = false;
|
|
351
359
|
result.value = '✅ 文本播报请求已发送\n📋 请查看右侧日志面板获取详细信息\n\n📝 操作说明:\n- 播报将以流式方式进行\n- 可使用下方控制按钮暂停/继续/停止\n- 播报过程中会触发相应的事件回调';
|
|
352
|
-
},
|
|
360
|
+
}, 0);
|
|
353
361
|
} catch (error: any) {
|
|
354
362
|
isTextLoading.value = false;
|
|
355
363
|
result.value = `❌ 播报失败: ${error.message}\n\n🔍 可能的原因:\n- 网络连接问题\n- 音色编码不存在\n- 服务器繁忙\n- 文本内容不符合要求`;
|
|
@@ -373,7 +381,8 @@ async function handleAudioBroadcast() {
|
|
|
373
381
|
isAudioLoading.value = true;
|
|
374
382
|
result.value = `🔄 正在执行音频播报...\n🎵 音频地址: ${audioUrl}\n📝 字幕文本: ${audioText || '无'}\n🔊 音量: ${volume}\n\n📡 正在验证音频文件并加载...`;
|
|
375
383
|
try {
|
|
376
|
-
emit('audio-broadcast', { avatarCode, audioText, audioUrl, volume, broadcastMotionString });
|
|
384
|
+
emit('audio-broadcast', { avatarCode, audioText, audioUrl, volume, broadcastMotionString, isAppend: isStartBroadcast.value });
|
|
385
|
+
isStartBroadcast.value = true;
|
|
377
386
|
setTimeout(() => {
|
|
378
387
|
isAudioLoading.value = false;
|
|
379
388
|
result.value = '✅ 音频播报请求已发送\n📋 请查看右侧日志面板获取详细信息\n\n📝 操作说明:\n- 音频将直接驱动数字人口型\n- 支持MP3、WAV等格式\n- 可使用下方控制按钮进行控制';
|
|
@@ -429,7 +438,11 @@ function handleStopBroadcast() {
|
|
|
429
438
|
result.value = `❌ 停止播报失败: ${error.message}\n\n🔍 可能的原因:\n- Unity通信异常\n- 播报服务未初始化\n- 系统资源异常`;
|
|
430
439
|
}
|
|
431
440
|
}
|
|
432
|
-
|
|
441
|
+
|
|
442
|
+
function handleResetBroadcast() {
|
|
443
|
+
isStartBroadcast.value = false;
|
|
444
|
+
}
|
|
445
|
+
|
|
433
446
|
function clearResult() {
|
|
434
447
|
result.value = '等待播报操作...\n\n新版SDK特性:\n- 支持流式播报,实时响应\n- 内置事件回调机制\n- token统一管理,无需重复传递\n- 支持音量和语速控制\n- 实时播报控制(暂停/恢复/停止)';
|
|
435
448
|
}
|
|
@@ -502,10 +515,15 @@ function clearResult() {
|
|
|
502
515
|
&.action-buttons {
|
|
503
516
|
margin-bottom: 0;
|
|
504
517
|
margin-top: 25px;
|
|
505
|
-
.
|
|
518
|
+
.action-buttons-container {
|
|
506
519
|
width: 100%;
|
|
507
|
-
|
|
508
|
-
|
|
520
|
+
display: flex;
|
|
521
|
+
gap: 10px;
|
|
522
|
+
.el-button {
|
|
523
|
+
width: 100%;
|
|
524
|
+
padding: 10px 0;
|
|
525
|
+
font-weight: 500;
|
|
526
|
+
}
|
|
509
527
|
}
|
|
510
528
|
}
|
|
511
529
|
.input-help {
|
|
@@ -5,10 +5,12 @@ import vue from '@vitejs/plugin-vue';
|
|
|
5
5
|
import AutoImport from 'unplugin-auto-import/vite';
|
|
6
6
|
import Components from 'unplugin-vue-components/vite';
|
|
7
7
|
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
|
|
8
|
+
import createHtml from './plugins/html';
|
|
8
9
|
|
|
9
10
|
// https://vitejs.dev/config/
|
|
10
11
|
export default defineConfig(({ mode, command }) =>
|
|
11
12
|
{
|
|
13
|
+
const isBuild = command === 'build';
|
|
12
14
|
// 加载环境变量
|
|
13
15
|
const env = loadEnv(mode, process.cwd(), '');
|
|
14
16
|
|
|
@@ -44,7 +46,8 @@ export default defineConfig(({ mode, command }) =>
|
|
|
44
46
|
Components({
|
|
45
47
|
resolvers: [ElementPlusResolver()],
|
|
46
48
|
dts: true
|
|
47
|
-
})
|
|
49
|
+
}),
|
|
50
|
+
createHtml(isBuild)
|
|
48
51
|
],
|
|
49
52
|
resolve: {
|
|
50
53
|
alias: {
|
package/dist/index.d.ts
CHANGED
|
@@ -351,6 +351,8 @@ interface IAvatarSDKConfig {
|
|
|
351
351
|
onProgress?: (progress: number) => void;
|
|
352
352
|
/** 播报回调函数,可选 */
|
|
353
353
|
broadcastCallbacks?: IBroadcastCallbacks;
|
|
354
|
+
/** 是否启用调试日志,默认为false */
|
|
355
|
+
enableDebugLog?: boolean;
|
|
354
356
|
}
|
|
355
357
|
|
|
356
358
|
/**
|
|
@@ -511,9 +513,10 @@ declare class ZEEAvatarSDK {
|
|
|
511
513
|
/**
|
|
512
514
|
* 开始播报
|
|
513
515
|
* @param params 播报参数
|
|
516
|
+
* @param isAppend 是否追加播报
|
|
514
517
|
* @returns Promise<void> 播报操作的Promise
|
|
515
518
|
*/
|
|
516
|
-
startBroadcast(params: IBroadcastParams): Promise<void>;
|
|
519
|
+
startBroadcast(params: IBroadcastParams, isAppend?: boolean): Promise<void>;
|
|
517
520
|
/**
|
|
518
521
|
* 暂停播报
|
|
519
522
|
* @param resetIdle 是否重置空闲状态
|
|
@@ -836,12 +839,20 @@ declare class AvatarService extends UnityBaseService<AvatarOperationType> implem
|
|
|
836
839
|
declare class BroadcastService extends UnityBaseService<BroadcastOperationType> implements IBroadcastAPI {
|
|
837
840
|
/** 事件回调函数集合 */
|
|
838
841
|
private callbacks;
|
|
839
|
-
/**
|
|
840
|
-
private
|
|
842
|
+
/** 播报任务队列 */
|
|
843
|
+
private taskQueue;
|
|
844
|
+
/** 任务序号计数器 */
|
|
845
|
+
private taskSequence;
|
|
846
|
+
/** 当前发送任务的序号 */
|
|
847
|
+
private currentSendingSequence;
|
|
841
848
|
/** 是否正在生成音频 */
|
|
842
849
|
private isGeneratingAudio;
|
|
843
850
|
/** 是否已经收到音频 */
|
|
844
851
|
private hasReceivedAudio;
|
|
852
|
+
/** 队列处理定时器 */
|
|
853
|
+
private queueProcessTimer;
|
|
854
|
+
/** 主请求控制器(兼容性保留) */
|
|
855
|
+
private activeController;
|
|
845
856
|
/**
|
|
846
857
|
* 构造函数
|
|
847
858
|
* @param config - 播报服务配置
|
|
@@ -874,8 +885,9 @@ declare class BroadcastService extends UnityBaseService<BroadcastOperationType>
|
|
|
874
885
|
/**
|
|
875
886
|
* 开始播报
|
|
876
887
|
* @param params - 播报参数
|
|
888
|
+
* @param isAppend - 是否追加播报
|
|
877
889
|
* @returns Promise<void> 播报操作的Promise
|
|
878
|
-
* @description
|
|
890
|
+
* @description 开始流式播报,支持文本转语音和自定义音频播报。使用队列机制确保音频按序播报
|
|
879
891
|
* @throws {SDKError} 当参数验证失败或播报失败时抛出错误
|
|
880
892
|
* @example
|
|
881
893
|
* ```typescript
|
|
@@ -889,17 +901,18 @@ declare class BroadcastService extends UnityBaseService<BroadcastOperationType>
|
|
|
889
901
|
* isSubtitle: true
|
|
890
902
|
* });
|
|
891
903
|
*
|
|
892
|
-
* //
|
|
904
|
+
* // 追加播报(会进入队列按序播报)
|
|
893
905
|
* await broadcastService.startBroadcast({
|
|
894
|
-
* type: BroadcastType.
|
|
906
|
+
* type: BroadcastType.TEXT,
|
|
895
907
|
* humanCode: 'human001',
|
|
896
|
-
*
|
|
908
|
+
* text: '这是第二段内容',
|
|
909
|
+
* voiceCode: 'voice001',
|
|
897
910
|
* volume: 0.8,
|
|
898
|
-
* isSubtitle:
|
|
899
|
-
* });
|
|
911
|
+
* isSubtitle: true
|
|
912
|
+
* }, true);
|
|
900
913
|
* ```
|
|
901
914
|
*/
|
|
902
|
-
startBroadcast(params: IBroadcastParams): Promise<void>;
|
|
915
|
+
startBroadcast(params: IBroadcastParams, isAppend?: boolean): Promise<void>;
|
|
903
916
|
/**
|
|
904
917
|
* 暂停播报
|
|
905
918
|
* @param resetIdle - 是否重置空闲状态
|
|
@@ -940,7 +953,7 @@ declare class BroadcastService extends UnityBaseService<BroadcastOperationType>
|
|
|
940
953
|
/**
|
|
941
954
|
* 获取播报状态
|
|
942
955
|
* @returns 播报状态信息
|
|
943
|
-
* @description
|
|
956
|
+
* @description 获取当前播报服务的状态信息,包括队列状态
|
|
944
957
|
*/
|
|
945
958
|
getStatus(): {
|
|
946
959
|
isActive: boolean;
|
|
@@ -948,12 +961,96 @@ declare class BroadcastService extends UnityBaseService<BroadcastOperationType>
|
|
|
948
961
|
hasReceivedAudio: boolean;
|
|
949
962
|
pendingCallbacks: number;
|
|
950
963
|
hasController: boolean;
|
|
964
|
+
queueInfo?: {
|
|
965
|
+
totalTasks: number;
|
|
966
|
+
requestingTasks: number;
|
|
967
|
+
completedTasks: number;
|
|
968
|
+
failedTasks: number;
|
|
969
|
+
totalPendingResponses: number;
|
|
970
|
+
currentSendingSequence: number;
|
|
971
|
+
};
|
|
951
972
|
};
|
|
952
973
|
/**
|
|
953
974
|
* 销毁播报服务
|
|
954
975
|
* @description 清理所有资源和回调
|
|
955
976
|
*/
|
|
956
977
|
destroy(): void;
|
|
978
|
+
/**
|
|
979
|
+
* 创建播报任务
|
|
980
|
+
* @param params - 播报参数
|
|
981
|
+
* @returns IBroadcastTask 播报任务对象
|
|
982
|
+
* @description 创建新的播报任务并分配唯一ID和序号
|
|
983
|
+
* @private
|
|
984
|
+
*/
|
|
985
|
+
private createBroadcastTask;
|
|
986
|
+
/**
|
|
987
|
+
* 添加任务到队列
|
|
988
|
+
* @param task - 播报任务
|
|
989
|
+
* @description 将任务添加到队列并立即开始请求
|
|
990
|
+
* @private
|
|
991
|
+
*/
|
|
992
|
+
private addTaskToQueue;
|
|
993
|
+
/**
|
|
994
|
+
* 处理队列
|
|
995
|
+
* @description 处理队列中的任务,发起请求生成音频
|
|
996
|
+
* @private
|
|
997
|
+
*/
|
|
998
|
+
private processQueue;
|
|
999
|
+
/**
|
|
1000
|
+
* 队列处理步骤
|
|
1001
|
+
* @description 处理队列中的单个步骤,包括发起请求和发送音频
|
|
1002
|
+
* @private
|
|
1003
|
+
*/
|
|
1004
|
+
private processQueueStep;
|
|
1005
|
+
/**
|
|
1006
|
+
* 开始任务请求
|
|
1007
|
+
* @param task - 播报任务
|
|
1008
|
+
* @description 为任务发起流式请求生成音频
|
|
1009
|
+
* @private
|
|
1010
|
+
*/
|
|
1011
|
+
private startTaskRequest;
|
|
1012
|
+
/**
|
|
1013
|
+
* 处理任务响应
|
|
1014
|
+
* @param task - 播报任务
|
|
1015
|
+
* @param data - 响应数据
|
|
1016
|
+
* @description 处理任务的流式响应数据
|
|
1017
|
+
* @private
|
|
1018
|
+
*/
|
|
1019
|
+
private handleTaskResponse;
|
|
1020
|
+
/**
|
|
1021
|
+
* 发送下一个响应
|
|
1022
|
+
* @param task - 播报任务
|
|
1023
|
+
* @description 发送任务中的第一个待发送响应到Unity,发送后立即删除
|
|
1024
|
+
* @private
|
|
1025
|
+
*/
|
|
1026
|
+
private sendNextResponse;
|
|
1027
|
+
/**
|
|
1028
|
+
* 处理任务关闭
|
|
1029
|
+
* @param task - 播报任务
|
|
1030
|
+
* @description 处理任务的流式连接关闭
|
|
1031
|
+
* @private
|
|
1032
|
+
*/
|
|
1033
|
+
private handleTaskClose;
|
|
1034
|
+
/**
|
|
1035
|
+
* 处理任务错误
|
|
1036
|
+
* @param task - 播报任务
|
|
1037
|
+
* @param error - 错误对象
|
|
1038
|
+
* @description 处理任务执行过程中的错误
|
|
1039
|
+
* @private
|
|
1040
|
+
*/
|
|
1041
|
+
private handleTaskError;
|
|
1042
|
+
/**
|
|
1043
|
+
* 清理已完成的任务
|
|
1044
|
+
* @description 从队列中移除已完成、失败或取消的任务
|
|
1045
|
+
* @private
|
|
1046
|
+
*/
|
|
1047
|
+
private cleanupCompletedTasks;
|
|
1048
|
+
/**
|
|
1049
|
+
* 取消所有任务
|
|
1050
|
+
* @description 取消队列中的所有任务
|
|
1051
|
+
* @private
|
|
1052
|
+
*/
|
|
1053
|
+
private cancelAllTasks;
|
|
957
1054
|
/** 全局回调函数名称 */
|
|
958
1055
|
protected get callbackFunctionName(): string;
|
|
959
1056
|
/**
|