virtual-human-cf 1.3.0 → 1.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 CHANGED
@@ -12,26 +12,52 @@
12
12
  - 响应式设计
13
13
 
14
14
  ## 更新日志
15
- ### 1.2.0
16
- - 新增VirtualHumanEventAdapter组件controlEvent事件,用于数字人播放周期控制指令通知
17
- ```javascript
18
- <VirtualHumanEventAdapter
19
- v-if="activeScreenClientId"
20
- @controlEvent="onControlEvent"
21
- />
22
- const onControlEvent = (event) => {
23
- console.log(event);
24
- // play 初次开始播放
25
- // resume 恢复播放
26
- // pause 暂停播放
27
- // stop 停止播放
28
- // tts_complete 文本转语音完成,不代表本地播放完成
29
- }
30
- ```
31
15
 
32
- ### 1.0.10
33
- - 新增VirtualHumanPersona组件styles属性,用于控制视频容器 宽高 绝对定位位置等
34
-
16
+ ### 1.4.0
17
+
18
+ - 新增VirtualHumanEventAdapter组件对外暴露pause、resume、stop方法
19
+
20
+ ```javascript
21
+ <VirtualHumanEventAdapter
22
+ v-if="activeScreenClientId"
23
+ @controlEvent="onControlEvent"
24
+ ref="adapterRef"
25
+ />
26
+ const adapterRef = ref(null);
27
+
28
+ // 底部有使用demo,这里不重复
29
+ // 暂停播放
30
+ adapterRef.value.pause().then(() => {}).catch(() => {});
31
+ // 恢复播放
32
+ adapterRef.value.resume().then(() => {}).catch(() => {});
33
+ // 停止播放
34
+ adapterRef.value.stop().then(() => {}).catch(() => {});
35
+
36
+ ```
37
+
38
+ ### 1.2.0
39
+
40
+ - 新增VirtualHumanEventAdapter组件controlEvent事件,用于数字人播放周期控制指令通知
41
+
42
+ ```javascript
43
+ <VirtualHumanEventAdapter
44
+ v-if="activeScreenClientId"
45
+ @controlEvent="onControlEvent"
46
+ />
47
+ const onControlEvent = (event) => {
48
+ console.log(event);
49
+ // play 初次开始播放
50
+ // resume 恢复播放
51
+ // pause 暂停播放
52
+ // stop 停止播放
53
+ // tts_complete 文本转语音完成,不代表本地播放完成
54
+ }
55
+ ```
56
+
57
+ ### 1.0.10
58
+
59
+ - 新增VirtualHumanPersona组件styles属性,用于控制视频容器 宽高 绝对定位位置等
60
+
35
61
  ## 安装
36
62
 
37
63
  ```bash
@@ -43,9 +69,9 @@ npm install virtual-human-cf
43
69
  ### 全局注册
44
70
 
45
71
  ```javascript
46
- import { createApp } from 'vue';
47
- import App from './App.vue';
48
- import VirtualHumanCF from 'virtual-human-cf';
72
+ import { createApp } from "vue";
73
+ import App from "./App.vue";
74
+ import VirtualHumanCF from "virtual-human-cf";
49
75
 
50
76
  const app = createApp(App);
51
77
  app.use(VirtualHumanCF);
@@ -54,7 +80,10 @@ app.use(VirtualHumanCF);
54
80
  ### 按需导入
55
81
 
56
82
  ```javascript
57
- import { VirtualHumanPersona, VirtualHumanEventAdapter } from 'virtual-human-cf';
83
+ import {
84
+ VirtualHumanPersona,
85
+ VirtualHumanEventAdapter,
86
+ } from "virtual-human-cf";
58
87
  ```
59
88
 
60
89
  ## 组件说明
@@ -65,24 +94,24 @@ import { VirtualHumanPersona, VirtualHumanEventAdapter } from 'virtual-human-cf'
65
94
 
66
95
  #### Props
67
96
 
68
- | 属性 | 类型 | 默认值 | 必填 | 说明 |
69
- |------|------|--------|------|------|
70
- | videoSrc | String | - | 是 | 视频源 URL |
71
- | visible | Boolean | true | 否 | 是否可见 |
72
- | isPlaying | Boolean | false | 否 | 是否正在播放 |
73
- | muted | Boolean | true | 否 | 是否静音 |
74
- | isDark | Boolean | false | 否 | 是否暗黑模式 |
75
- | screenClientId | String | - | 否 | 屏幕客户端 ID |
76
- | wsUrl | String | - | 否 | WebSocket 连接地址 |
77
- | styles | Object | - | 否 | 组件样式,包含 width、height、left、bottom 等属性 |
97
+ | 属性 | 类型 | 默认值 | 必填 | 说明 |
98
+ | -------------- | ------- | ------ | ---- | ------------------------------------------------- |
99
+ | videoSrc | String | - | 是 | 视频源 URL |
100
+ | visible | Boolean | true | 否 | 是否可见 |
101
+ | isPlaying | Boolean | false | 否 | 是否正在播放 |
102
+ | muted | Boolean | true | 否 | 是否静音 |
103
+ | isDark | Boolean | false | 否 | 是否暗黑模式 |
104
+ | screenClientId | String | - | 否 | 屏幕客户端 ID |
105
+ | wsUrl | String | - | 否 | WebSocket 连接地址 |
106
+ | styles | Object | - | 否 | 组件样式,包含 width、height、left、bottom 等属性 |
78
107
 
79
108
  #### Events
80
109
 
81
- | 事件名 | 说明 | 回调参数 |
82
- |--------|------|----------|
110
+ | 事件名 | 说明 | 回调参数 |
111
+ | ---------------- | ------------ | ----------------- |
83
112
  | update:isPlaying | 播放状态变更 | 播放状态(Boolean) |
84
- | update:visible | 可见性变更 | 可见状态(Boolean) |
85
- | ended | 播放结束 | - |
113
+ | update:visible | 可见性变更 | 可见状态(Boolean) |
114
+ | ended | 播放结束 | - |
86
115
 
87
116
  #### 示例
88
117
 
@@ -102,25 +131,25 @@ import { VirtualHumanPersona, VirtualHumanEventAdapter } from 'virtual-human-cf'
102
131
  </template>
103
132
 
104
133
  <script setup>
105
- import { ref } from 'vue';
106
- import { VirtualHumanPersona } from 'virtual-human-cf';
134
+ import { ref } from "vue";
135
+ import { VirtualHumanPersona } from "virtual-human-cf";
107
136
 
108
- const videoUrl = ref('https://example.com/video.mp4');
137
+ const videoUrl = ref("https://example.com/video.mp4");
109
138
  const playing = ref(false);
110
- const clientId = ref('screen-123');
111
- const websocketUrl = ref('ws://localhost:8080/ws');
139
+ const clientId = ref("screen-123");
140
+ const websocketUrl = ref("ws://localhost:8080/ws");
112
141
  const styles = ref({
113
- width:'400px',
114
- height:'500px',
115
- left: '16px',
116
- bottom:'16px'
117
- })
142
+ width: "400px",
143
+ height: "500px",
144
+ left: "16px",
145
+ bottom: "16px",
146
+ });
118
147
  const onPlayingChange = (isPlaying) => {
119
- console.log('播放状态改变:', isPlaying);
148
+ console.log("播放状态改变:", isPlaying);
120
149
  };
121
150
 
122
151
  const onEnded = () => {
123
- console.log('播放结束');
152
+ console.log("播放结束");
124
153
  };
125
154
  </script>
126
155
  ```
@@ -131,27 +160,35 @@ const onEnded = () => {
131
160
 
132
161
  #### Props
133
162
 
134
- | 属性 | 类型 | 默认值 | 必填 | 说明 |
135
- |------|------|--------|------|------|
136
- | screenClientId | String | - | 是 | 屏幕客户端 ID |
137
- | wsUrl | String | - | 是 | WebSocket 连接地址 |
163
+ | 属性 | 类型 | 默认值 | 必填 | 说明 |
164
+ | -------------- | ------ | ------ | ---- | ------------------ |
165
+ | screenClientId | String | - | 是 | 屏幕客户端 ID |
166
+ | wsUrl | String | - | 是 | WebSocket 连接地址 |
138
167
 
139
168
  #### Events
140
169
 
141
- | 事件名 | 说明 | 回调参数 |
142
- |--------|------|----------|
143
- | connected | WebSocket 连接成功 | - |
144
- | eventNotifaction | 自定义事件接收器 | 载荷数据 |
145
- | end | 数字人对话结束 | 载荷数据 |
146
- | pause | 暂停播放 | 载荷数据 |
147
- | error | 错误事件 | 错误信息 |
148
- | playComplete | 播放完成,数字人对话结束,关闭数字人 | - |
149
- | controlEvent | 数字人控制事件 | 载荷数据 |
170
+ | 事件名 | 说明 | 回调参数 |
171
+ | ---------------- | ------------------------------------ | -------- |
172
+ | connected | WebSocket 连接成功 | - |
173
+ | eventNotifaction | 自定义事件接收器 | 载荷数据 |
174
+ | end | 数字人对话结束 | 载荷数据 |
175
+ | pause | 暂停播放 | 载荷数据 |
176
+ | error | 错误事件 | 错误信息 |
177
+ | playComplete | 播放完成,数字人对话结束,关闭数字人 | - |
178
+ | controlEvent | 数字人控制事件 | 载荷数据 |
179
+
180
+ #### refs
181
+
182
+ | 方法名 | 说明 | 回调参数 |
183
+ | ------ | -------- | -------- |
184
+ | pause | 暂停播放 |Promise<boolean> |
185
+ | resume | 恢复播放 |Promise<boolean> |
186
+ | stop | 停止播放 |Promise<boolean> |
150
187
 
151
188
  ```js
152
189
  // eventNotifaction 载荷数据
153
190
  {
154
-
191
+
155
192
  "type": "send_event",
156
193
  // 自定义事件名称
157
194
  "event": "heightlight",
@@ -182,6 +219,7 @@ tts_complete 文本转语音完成,不代表本地播放完成
182
219
  @controlEvent="onControlEvent"
183
220
  @end="onEnd"
184
221
  @error="onError"
222
+ ref="adapterRef"
185
223
  >
186
224
  <div>其他内容</div>
187
225
  </VirtualHumanEventAdapter>
@@ -212,6 +250,28 @@ const onEnd = (payload) => {
212
250
  const onError = (error) => {
213
251
  console.error('错误:', error);
214
252
  };
253
+
254
+ const adapterRef = ref(null);
255
+ const controlFunc = () => {
256
+ // 暂停播放
257
+ adapterRef.value.pause().then(res => {
258
+ // res boolean true 暂停成功 false 暂停失败
259
+ }).catch((error) => {
260
+ console.error('暂停播放失败:', error);
261
+ });
262
+ // 恢复播放
263
+ adapterRef.value.resume().then(res => {
264
+ // res boolean true 恢复成功 false 恢复失败
265
+ }).catch((error) => {
266
+ console.error('恢复播放失败:', error);
267
+ });
268
+ // 停止播放
269
+ adapterRef.value.stop().then(res => {
270
+ // res boolean true 停止成功 false 停止失败
271
+ }).catch((error) => {
272
+ console.error('停止播放失败:', error);
273
+ });
274
+ }
215
275
  </script>
216
276
  ```
217
277
 
@@ -235,7 +295,7 @@ const onError = (error) => {
235
295
  @update:visible="onPersonaVisibleUpdate"
236
296
  @ended="onVideoEnded"
237
297
  />
238
-
298
+
239
299
  <VirtualHumanEventAdapter
240
300
  :screen-client-id="activeScreenClientId"
241
301
  :ws-url="websocketUrl"
@@ -315,4 +375,4 @@ npm run build
315
375
 
316
376
  ## 许可证
317
377
 
318
- MIT
378
+ MIT
@@ -0,0 +1,2 @@
1
+ declare const request: import('axios').AxiosInstance;
2
+ export default request;
@@ -0,0 +1,13 @@
1
+ export interface ScreenConfig {
2
+ id?: number;
3
+ name: string;
4
+ screenClientId: string;
5
+ createTime?: string;
6
+ updateTime?: string;
7
+ }
8
+ export declare const getScreenList: () => Promise<ScreenConfig[]>;
9
+ export declare const getScreenById: (id: number) => Promise<ScreenConfig>;
10
+ export declare const createScreen: (data: ScreenConfig) => Promise<boolean>;
11
+ export declare const updateScreen: (id: number, data: ScreenConfig) => Promise<boolean>;
12
+ export declare const deleteScreen: (id: number) => Promise<boolean>;
13
+ export declare const controlScreen: (screenClientId: string, action: "play" | "pause" | "stop" | "resume") => Promise<boolean>;
@@ -10,9 +10,13 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
10
10
  type: StringConstructor;
11
11
  required: true;
12
12
  };
13
- }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
14
- error: (...args: any[]) => void;
13
+ }>, {
14
+ pause: () => Promise<boolean>;
15
+ resume: () => Promise<boolean>;
16
+ stop: () => Promise<boolean>;
17
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
15
18
  pause: (...args: any[]) => void;
19
+ error: (...args: any[]) => void;
16
20
  eventNotifaction: (...args: any[]) => void;
17
21
  controlEvent: (...args: any[]) => void;
18
22
  end: (...args: any[]) => void;
@@ -28,8 +32,8 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
28
32
  required: true;
29
33
  };
30
34
  }>> & Readonly<{
31
- onError?: ((...args: any[]) => any) | undefined;
32
35
  onPause?: ((...args: any[]) => any) | undefined;
36
+ onError?: ((...args: any[]) => any) | undefined;
33
37
  onEventNotifaction?: ((...args: any[]) => any) | undefined;
34
38
  onControlEvent?: ((...args: any[]) => any) | undefined;
35
39
  onEnd?: ((...args: any[]) => any) | undefined;
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .fade-enter-active[data-v-bf23f155],.fade-leave-active[data-v-bf23f155]{transition:opacity .5s ease,transform .5s ease}.fade-enter-from[data-v-bf23f155],.fade-leave-to[data-v-bf23f155]{opacity:0;transform:translateY(10px)}.virtual-human-container[data-v-bf23f155]{position:fixed;z-index:2147483647;overflow:visible}.video-wrapper[data-v-bf23f155]{position:relative;width:100%;height:100%;border-radius:1rem;overflow:hidden;box-shadow:0 10px 25px #0000001a;background:#fff;border:2px solid transparent;transition:background-color .3s ease,box-shadow .3s ease,border-color .3s ease}.video-wrapper[data-v-bf23f155]:hover{border-color:#409eff}.virtual-human-container.is-dark .video-wrapper[data-v-bf23f155]{background:#1f2937;box-shadow:0 10px 25px #00000080}.persona-video[data-v-bf23f155]{width:100%;height:100%;object-fit:cover;transform-origin:center;transition:transform .1s ease-out}.resize-handle[data-v-bf23f155]{position:absolute;width:20px;height:20px;background:#00000080;border:2px solid rgba(255,255,255,.8);border-radius:4px;cursor:pointer;z-index:20;opacity:0;pointer-events:none;transition:opacity .3s ease,background .2s,border-color .2s}.video-wrapper:hover .resize-handle[data-v-bf23f155]{opacity:1;pointer-events:auto}.resize-handle[data-v-bf23f155]:hover{background:#000000b3;border-color:#fff}.resize-handle.top-left[data-v-bf23f155]{top:10px;left:10px;cursor:nwse-resize}.resize-handle.top-right[data-v-bf23f155]{top:10px;right:10px;cursor:nesw-resize}.resize-handle.bottom-left[data-v-bf23f155]{bottom:10px;left:10px;cursor:nesw-resize}.resize-handle.bottom-right[data-v-bf23f155]{bottom:10px;right:10px;cursor:nwse-resize}.overlay[data-v-bf23f155]{position:absolute;top:1rem;right:1rem;z-index:10}.status-badge[data-v-bf23f155]{display:flex;align-items:center;gap:.5rem;padding:.25rem .75rem;border-radius:9999px;font-size:.75rem;font-weight:500;color:#fff;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.status-badge.paused[data-v-bf23f155]{background:#ef4444cc}.status-badge.playing[data-v-bf23f155]{background:#22c55ecc}.dot[data-v-bf23f155]{width:6px;height:6px;border-radius:50%;background-color:#fff}@keyframes pulse-bf23f155{0%,to{opacity:1}50%{opacity:.5}}.animate-pulse[data-v-bf23f155]{animation:pulse-bf23f155 2s cubic-bezier(.4,0,.6,1) infinite}
1
+ .fade-enter-active[data-v-02ec3645],.fade-leave-active[data-v-02ec3645]{transition:opacity .5s ease,transform .5s ease}.fade-enter-from[data-v-02ec3645],.fade-leave-to[data-v-02ec3645]{opacity:0;transform:translateY(10px)}.virtual-human-container[data-v-02ec3645]{position:fixed;z-index:2147483647;overflow:visible}.video-wrapper[data-v-02ec3645]{position:relative;width:100%;height:100%;border-radius:1rem;overflow:hidden;box-shadow:0 10px 25px #0000001a;background:#fff;border:2px solid transparent;transition:background-color .3s ease,box-shadow .3s ease,border-color .3s ease}.video-wrapper[data-v-02ec3645]:hover{border-color:#409eff}.virtual-human-container.is-dark .video-wrapper[data-v-02ec3645]{background:#1f2937;box-shadow:0 10px 25px #00000080}.persona-video[data-v-02ec3645]{width:100%;height:100%;object-fit:cover;transform-origin:center;transition:transform .1s ease-out}.resize-handle[data-v-02ec3645]{position:absolute;width:20px;height:20px;background:#00000080;border:2px solid rgba(255,255,255,.8);border-radius:4px;cursor:pointer;z-index:20;opacity:0;pointer-events:none;transition:opacity .3s ease,background .2s,border-color .2s}.video-wrapper:hover .resize-handle[data-v-02ec3645]{opacity:1;pointer-events:auto}.resize-handle[data-v-02ec3645]:hover{background:#000000b3;border-color:#fff}.resize-handle.top-left[data-v-02ec3645]{top:10px;left:10px;cursor:nwse-resize}.resize-handle.top-right[data-v-02ec3645]{top:10px;right:10px;cursor:nesw-resize}.resize-handle.bottom-left[data-v-02ec3645]{bottom:10px;left:10px;cursor:nesw-resize}.resize-handle.bottom-right[data-v-02ec3645]{bottom:10px;right:10px;cursor:nwse-resize}.overlay[data-v-02ec3645]{position:absolute;top:1rem;right:1rem;z-index:10}.status-badge[data-v-02ec3645]{display:flex;align-items:center;gap:.5rem;padding:.25rem .75rem;border-radius:9999px;font-size:.75rem;font-weight:500;color:#fff;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.status-badge.paused[data-v-02ec3645]{background:#ef4444cc}.status-badge.playing[data-v-02ec3645]{background:#22c55ecc}.dot[data-v-02ec3645]{width:6px;height:6px;border-radius:50%;background-color:#fff}@keyframes pulse-02ec3645{0%,to{opacity:1}50%{opacity:.5}}.animate-pulse[data-v-02ec3645]{animation:pulse-02ec3645 2s cubic-bezier(.4,0,.6,1) infinite}