virtual-human-cf 1.0.10 → 1.0.11

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/style.css CHANGED
@@ -1 +1 @@
1
- .fade-enter-active[data-v-892abb8d],.fade-leave-active[data-v-892abb8d]{transition:opacity .5s ease,transform .5s ease}.fade-enter-from[data-v-892abb8d],.fade-leave-to[data-v-892abb8d]{opacity:0;transform:translateY(10px)}.virtual-human-container[data-v-892abb8d]{position:fixed;z-index:2147483647;overflow:visible}.video-wrapper[data-v-892abb8d]{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-892abb8d]:hover{border-color:#409eff}.virtual-human-container.is-dark .video-wrapper[data-v-892abb8d]{background:#1f2937;box-shadow:0 10px 25px #00000080}.persona-video[data-v-892abb8d]{width:100%;height:100%;object-fit:cover;transform-origin:center;transition:transform .1s ease-out}.resize-handle[data-v-892abb8d]{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-892abb8d]{opacity:1;pointer-events:auto}.resize-handle[data-v-892abb8d]:hover{background:#000000b3;border-color:#fff}.resize-handle.top-left[data-v-892abb8d]{top:10px;left:10px;cursor:nwse-resize}.resize-handle.top-right[data-v-892abb8d]{top:10px;right:10px;cursor:nesw-resize}.resize-handle.bottom-left[data-v-892abb8d]{bottom:10px;left:10px;cursor:nesw-resize}.resize-handle.bottom-right[data-v-892abb8d]{bottom:10px;right:10px;cursor:nwse-resize}.overlay[data-v-892abb8d]{position:absolute;top:1rem;right:1rem;z-index:10}.status-badge[data-v-892abb8d]{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-892abb8d]{background:#ef4444cc}.status-badge.playing[data-v-892abb8d]{background:#22c55ecc}.dot[data-v-892abb8d]{width:6px;height:6px;border-radius:50%;background-color:#fff}@keyframes pulse-892abb8d{0%,to{opacity:1}50%{opacity:.5}}.animate-pulse[data-v-892abb8d]{animation:pulse-892abb8d 2s cubic-bezier(.4,0,.6,1) infinite}
1
+ .fade-enter-active[data-v-7325596e],.fade-leave-active[data-v-7325596e]{transition:opacity .5s ease,transform .5s ease}.fade-enter-from[data-v-7325596e],.fade-leave-to[data-v-7325596e]{opacity:0;transform:translateY(10px)}.virtual-human-container[data-v-7325596e]{position:fixed;z-index:2147483647;overflow:visible}.video-wrapper[data-v-7325596e]{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-7325596e]:hover{border-color:#409eff}.virtual-human-container.is-dark .video-wrapper[data-v-7325596e]{background:#1f2937;box-shadow:0 10px 25px #00000080}.persona-video[data-v-7325596e]{width:100%;height:100%;object-fit:cover;transform-origin:center;transition:transform .1s ease-out}.resize-handle[data-v-7325596e]{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-7325596e]{opacity:1;pointer-events:auto}.resize-handle[data-v-7325596e]:hover{background:#000000b3;border-color:#fff}.resize-handle.top-left[data-v-7325596e]{top:10px;left:10px;cursor:nwse-resize}.resize-handle.top-right[data-v-7325596e]{top:10px;right:10px;cursor:nesw-resize}.resize-handle.bottom-left[data-v-7325596e]{bottom:10px;left:10px;cursor:nesw-resize}.resize-handle.bottom-right[data-v-7325596e]{bottom:10px;right:10px;cursor:nwse-resize}.overlay[data-v-7325596e]{position:absolute;top:1rem;right:1rem;z-index:10}.status-badge[data-v-7325596e]{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-7325596e]{background:#ef4444cc}.status-badge.playing[data-v-7325596e]{background:#22c55ecc}.dot[data-v-7325596e]{width:6px;height:6px;border-radius:50%;background-color:#fff}@keyframes pulse-7325596e{0%,to{opacity:1}50%{opacity:.5}}.animate-pulse[data-v-7325596e]{animation:pulse-7325596e 2s cubic-bezier(.4,0,.6,1) infinite}
@@ -1,4 +1,4 @@
1
- import { defineComponent as H, ref as w, watch as C, onMounted as E, onUnmounted as x, openBlock as A, createBlock as B, Transition as W, withCtx as $, createElementBlock as R, normalizeStyle as F, normalizeClass as N, createElementVNode as U, createCommentVNode as T, renderSlot as q } from "vue";
1
+ import { defineComponent as H, ref as g, watch as C, onMounted as E, onUnmounted as _, openBlock as A, createBlock as B, Transition as W, withCtx as $, createElementBlock as R, normalizeStyle as F, normalizeClass as N, createElementVNode as U, createCommentVNode as T, renderSlot as q } from "vue";
2
2
  const M = ["src", "muted"], z = /* @__PURE__ */ H({
3
3
  __name: "VirtualHumanPersona",
4
4
  props: {
@@ -49,51 +49,51 @@ const M = ["src", "muted"], z = /* @__PURE__ */ H({
49
49
  }
50
50
  },
51
51
  emits: ["update:isPlaying", "ended", "update:visible"],
52
- setup(r, { emit: g }) {
53
- const e = r, a = g, n = w(null), h = w(null), t = w(null), d = w(!1), f = () => {
52
+ setup(r, { emit: b }) {
53
+ const e = r, n = b, a = g(null), h = g(null), t = g(null), d = g(!1), f = () => {
54
54
  if (t.value && t.value.close(), !(!e.wsUrl || !e.screenClientId))
55
55
  try {
56
- const l = new URL(e.wsUrl);
57
- l.searchParams.append("sessionId", e.screenClientId + "-persona"), t.value = new WebSocket(l.toString()), t.value.onopen = () => {
56
+ const i = new URL(e.wsUrl);
57
+ i.searchParams.append("sessionId", e.screenClientId + "-persona"), t.value = new WebSocket(i.toString()), t.value.onopen = () => {
58
58
  d.value = !0, console.log(`[VirtualHumanPersona] Connected to ${e.wsUrl} for session ${e.screenClientId}-persona`);
59
59
  }, t.value.onmessage = (u) => {
60
60
  try {
61
- const i = JSON.parse(u.data);
62
- m(i);
63
- } catch (i) {
64
- console.error("[VirtualHumanPersona] Failed to parse message:", u.data, i);
61
+ const c = JSON.parse(u.data);
62
+ m(c);
63
+ } catch (c) {
64
+ console.error("[VirtualHumanPersona] Failed to parse message:", u.data, c);
65
65
  }
66
66
  }, t.value.onerror = (u) => {
67
67
  console.error("[VirtualHumanPersona] WebSocket error:", u);
68
68
  }, t.value.onclose = () => {
69
69
  d.value = !1, console.log("[VirtualHumanPersona] WebSocket disconnected");
70
70
  };
71
- } catch (l) {
72
- console.error("[VirtualHumanPersona] Failed to initialize WebSocket:", l);
71
+ } catch (i) {
72
+ console.error("[VirtualHumanPersona] Failed to initialize WebSocket:", i);
73
73
  }
74
- }, m = (l) => {
75
- const { type: u, action: i } = l;
76
- u === "control" && (i === "play" || i === "resume" ? (a("update:isPlaying", !0), a("update:visible", !0)) : i === "pause" ? a("update:isPlaying", !1) : i === "stop" && (a("update:isPlaying", !1), a("update:visible", !1), n.value && (n.value.currentTime = 0)));
74
+ }, m = (i) => {
75
+ const { type: u, action: c } = i;
76
+ u === "control" && (c === "play" || c === "resume" ? (n("update:isPlaying", !0), n("update:visible", !0)) : c === "pause" ? (n("update:isPlaying", !1), n("update:visible", !0)) : c === "stop" && (n("update:isPlaying", !1), n("update:visible", !1), a.value && (a.value.currentTime = 0)));
77
77
  };
78
78
  C(() => e.screenClientId, () => {
79
79
  e.screenClientId && e.wsUrl && f();
80
80
  }), C(() => e.wsUrl, () => {
81
81
  e.screenClientId && e.wsUrl && f();
82
- }), C(() => e.isPlaying, (l) => {
83
- n.value && (l ? n.value.play().catch((u) => console.error("Video play failed:", u)) : n.value.pause());
82
+ }), C(() => e.isPlaying, (i) => {
83
+ a.value && (i ? a.value.play().catch((u) => console.error("Video play failed:", u)) : a.value.pause());
84
84
  });
85
85
  const v = () => {
86
- e.isPlaying || a("update:isPlaying", !0);
86
+ e.isPlaying || n("update:isPlaying", !0);
87
87
  }, S = () => {
88
- e.isPlaying && a("update:isPlaying", !1);
88
+ e.isPlaying && n("update:isPlaying", !1);
89
89
  }, k = () => {
90
- a("update:isPlaying", !1), a("ended");
90
+ n("update:isPlaying", !1), n("ended");
91
91
  };
92
92
  return E(() => {
93
- e.isPlaying && n.value && n.value.play().catch((l) => console.error("Video play failed:", l)), e.screenClientId && e.wsUrl && f();
94
- }), x(() => {
93
+ e.isPlaying && a.value && a.value.play().catch((i) => console.error("Video play failed:", i)), e.screenClientId && e.wsUrl && f();
94
+ }), _(() => {
95
95
  t.value && t.value.close();
96
- }), (l, u) => (A(), B(W, { name: "fade" }, {
96
+ }), (i, u) => (A(), B(W, { name: "fade" }, {
97
97
  default: $(() => [
98
98
  r.visible ? (A(), R("div", {
99
99
  key: 0,
@@ -107,14 +107,14 @@ const M = ["src", "muted"], z = /* @__PURE__ */ H({
107
107
  }, [
108
108
  U("video", {
109
109
  ref_key: "videoRef",
110
- ref: n,
110
+ ref: a,
111
111
  src: r.videoSrc,
112
112
  class: "persona-video",
113
113
  muted: r.muted,
114
114
  playsinline: "",
115
115
  loop: "",
116
116
  autoPlay: "",
117
- disablePictureInPicture: "false",
117
+ disablePictureInPicture: !1,
118
118
  onPlay: v,
119
119
  onPause: S,
120
120
  onEnded: k
@@ -125,12 +125,12 @@ const M = ["src", "muted"], z = /* @__PURE__ */ H({
125
125
  _: 1
126
126
  }));
127
127
  }
128
- }), D = (r, g) => {
128
+ }), D = (r, b) => {
129
129
  const e = r.__vccOpts || r;
130
- for (const [a, n] of g)
131
- e[a] = n;
130
+ for (const [n, a] of b)
131
+ e[n] = a;
132
132
  return e;
133
- }, O = /* @__PURE__ */ D(z, [["__scopeId", "data-v-892abb8d"]]), J = /* @__PURE__ */ H({
133
+ }, O = /* @__PURE__ */ D(z, [["__scopeId", "data-v-7325596e"]]), J = /* @__PURE__ */ H({
134
134
  __name: "VirtualHumanEventAdapter",
135
135
  props: {
136
136
  // 屏幕客户端ID
@@ -145,24 +145,24 @@ const M = ["src", "muted"], z = /* @__PURE__ */ H({
145
145
  }
146
146
  },
147
147
  emits: ["eventNotifaction", "end", "pause", "connected", "error", "playComplete"],
148
- setup(r, { emit: g }) {
149
- const e = r, a = g, n = w(null), h = w(!1);
148
+ setup(r, { emit: b }) {
149
+ const e = r, n = b, a = g(null), h = g(!1);
150
150
  let t = null, d = 0, f = !1, m = 0, v = !1;
151
151
  const S = () => {
152
152
  t || (t = new (window.AudioContext || window.webkitAudioContext)({
153
153
  sampleRate: 24e3
154
154
  })), t.state === "suspended" && !v && t.resume();
155
155
  }, k = () => {
156
- f && m === 0 && (a("playComplete", e.screenClientId), f = !1);
157
- }, l = (s) => {
156
+ f && m === 0 && (n("playComplete", e.screenClientId), f = !1);
157
+ }, i = (s) => {
158
158
  if (S(), !!t)
159
159
  try {
160
- const o = window.atob(s), c = o.length, b = new Uint8Array(c);
161
- for (let p = 0; p < c; p++)
162
- b[p] = o.charCodeAt(p);
163
- const y = new Int16Array(b.buffer), V = new Float32Array(y.length);
164
- for (let p = 0; p < y.length; p++)
165
- V[p] = y[p] / 32768;
160
+ const o = window.atob(s), l = o.length, y = new Uint8Array(l);
161
+ for (let p = 0; p < l; p++)
162
+ y[p] = o.charCodeAt(p);
163
+ const w = new Int16Array(y.buffer), V = new Float32Array(w.length);
164
+ for (let p = 0; p < w.length; p++)
165
+ V[p] = w[p] / 32768;
166
166
  const I = t.createBuffer(1, V.length, 24e3);
167
167
  I.getChannelData(0).set(V);
168
168
  const P = t.createBufferSource();
@@ -192,58 +192,58 @@ const M = ["src", "muted"], z = /* @__PURE__ */ H({
192
192
  default:
193
193
  console.warn(`[VirtualHumanEventAdapter] Unknown control action: ${s}`);
194
194
  }
195
- }, i = () => {
196
- n.value && n.value.close();
195
+ }, c = () => {
196
+ a.value && a.value.close();
197
197
  try {
198
198
  const s = new URL(e.wsUrl);
199
- s.searchParams.append("sessionId", e.screenClientId + "-event"), n.value = new WebSocket(s.toString()), n.value.onopen = () => {
200
- h.value = !0, a("connected"), console.log(`[VirtualHumanEventAdapter] Connected to ${e.wsUrl} for session ${e.screenClientId}-event`);
201
- }, n.value.onmessage = (o) => {
199
+ s.searchParams.append("sessionId", e.screenClientId + "-event"), a.value = new WebSocket(s.toString()), a.value.onopen = () => {
200
+ h.value = !0, n("connected"), console.log(`[VirtualHumanEventAdapter] Connected to ${e.wsUrl} for session ${e.screenClientId}-event`);
201
+ }, a.value.onmessage = (o) => {
202
202
  try {
203
- const c = JSON.parse(o.data);
204
- _(c);
205
- } catch (c) {
206
- console.error("[VirtualHumanEventAdapter] Failed to parse message:", o.data, c);
203
+ const l = JSON.parse(o.data);
204
+ x(l);
205
+ } catch (l) {
206
+ console.error("[VirtualHumanEventAdapter] Failed to parse message:", o.data, l);
207
207
  }
208
- }, n.value.onerror = (o) => {
209
- console.error("[VirtualHumanEventAdapter] WebSocket error:", o), a("error", o);
210
- }, n.value.onclose = () => {
208
+ }, a.value.onerror = (o) => {
209
+ console.error("[VirtualHumanEventAdapter] WebSocket error:", o), n("error", o);
210
+ }, a.value.onclose = () => {
211
211
  h.value = !1, console.log("[VirtualHumanEventAdapter] WebSocket disconnected");
212
212
  };
213
213
  } catch (s) {
214
- console.error("[VirtualHumanEventAdapter] Failed to initialize WebSocket:", s), a("error", s);
214
+ console.error("[VirtualHumanEventAdapter] Failed to initialize WebSocket:", s), n("error", s);
215
215
  }
216
- }, _ = (s) => {
217
- const { type: o, payload: c, action: b } = s;
218
- switch (console.log("msgmsg-002", s), o) {
216
+ }, x = (s) => {
217
+ const { type: o, payload: l, action: y } = s;
218
+ switch (o) {
219
219
  case "audio":
220
- const y = (c == null ? void 0 : c.data) || s.data;
221
- y && l(y);
220
+ const w = (l == null ? void 0 : l.data) || s.data;
221
+ w && i(w);
222
222
  break;
223
223
  case "send_event":
224
- s.event && a("eventNotifaction", s);
224
+ s.event && (console.log("adapter send_event:", s), n("eventNotifaction", s));
225
225
  break;
226
226
  case "control":
227
- b && u(b);
227
+ y && (console.log("adapter control:", y), u(y));
228
228
  break;
229
229
  case "end":
230
- a("end", c);
230
+ console.log("adapter end:", l), n("end", l);
231
231
  break;
232
232
  case "pause":
233
- a("pause", c);
233
+ console.log("adapter pause:", l), n("pause", l);
234
234
  break;
235
235
  default:
236
236
  console.warn(`[VirtualHumanEventAdapter] Unknown message type: ${o}`);
237
237
  }
238
238
  };
239
239
  return C(() => e.screenClientId, () => {
240
- e.screenClientId && e.wsUrl && i();
240
+ e.screenClientId && e.wsUrl && c();
241
241
  }), C(() => e.wsUrl, () => {
242
- e.screenClientId && e.wsUrl && i();
242
+ e.screenClientId && e.wsUrl && c();
243
243
  }), E(() => {
244
- e.screenClientId && e.wsUrl && i();
245
- }), x(() => {
246
- n.value && n.value.close(), t && t.close();
244
+ e.screenClientId && e.wsUrl && c();
245
+ }), _(() => {
246
+ a.value && a.value.close(), t && t.close();
247
247
  }), (s, o) => q(s.$slots, "default");
248
248
  }
249
249
  }), L = (r) => {
@@ -1 +1 @@
1
- (function(f,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],n):(f=typeof globalThis<"u"?globalThis:f||self,n(f.VirtualHumanCf={},f.Vue))})(this,function(f,n){"use strict";const H=["src","muted"],U=((o,b)=>{const e=o.__vccOpts||o;for(const[s,a]of b)e[s]=a;return e})(n.defineComponent({__name:"VirtualHumanPersona",props:{videoSrc:{type:String,required:!0},visible:{type:Boolean,default:!1},isPlaying:{type:Boolean,default:!1},muted:{type:Boolean,default:!0},isDark:{type:Boolean,default:!1},screenClientId:{type:String,required:!1},wsUrl:{type:String,required:!1},styles:{type:Object,default:()=>({width:"400px",height:"500px",left:"16px",bottom:"16px"})}},emits:["update:isPlaying","ended","update:visible"],setup(o,{emit:b}){const e=o,s=b,a=n.ref(null),C=n.ref(null),t=n.ref(null),p=n.ref(!1),m=()=>{if(t.value&&t.value.close(),!(!e.wsUrl||!e.screenClientId))try{const i=new URL(e.wsUrl);i.searchParams.append("sessionId",e.screenClientId+"-persona"),t.value=new WebSocket(i.toString()),t.value.onopen=()=>{p.value=!0,console.log(`[VirtualHumanPersona] Connected to ${e.wsUrl} for session ${e.screenClientId}-persona`)},t.value.onmessage=u=>{try{const c=JSON.parse(u.data);w(c)}catch(c){console.error("[VirtualHumanPersona] Failed to parse message:",u.data,c)}},t.value.onerror=u=>{console.error("[VirtualHumanPersona] WebSocket error:",u)},t.value.onclose=()=>{p.value=!1,console.log("[VirtualHumanPersona] WebSocket disconnected")}}catch(i){console.error("[VirtualHumanPersona] Failed to initialize WebSocket:",i)}},w=i=>{const{type:u,action:c}=i;u==="control"&&(c==="play"||c==="resume"?(s("update:isPlaying",!0),s("update:visible",!0)):c==="pause"?s("update:isPlaying",!1):c==="stop"&&(s("update:isPlaying",!1),s("update:visible",!1),a.value&&(a.value.currentTime=0)))};n.watch(()=>e.screenClientId,()=>{e.screenClientId&&e.wsUrl&&m()}),n.watch(()=>e.wsUrl,()=>{e.screenClientId&&e.wsUrl&&m()}),n.watch(()=>e.isPlaying,i=>{a.value&&(i?a.value.play().catch(u=>console.error("Video play failed:",u)):a.value.pause())});const g=()=>{e.isPlaying||s("update:isPlaying",!0)},S=()=>{e.isPlaying&&s("update:isPlaying",!1)},k=()=>{s("update:isPlaying",!1),s("ended")};return n.onMounted(()=>{e.isPlaying&&a.value&&a.value.play().catch(i=>console.error("Video play failed:",i)),e.screenClientId&&e.wsUrl&&m()}),n.onUnmounted(()=>{t.value&&t.value.close()}),(i,u)=>(n.openBlock(),n.createBlock(n.Transition,{name:"fade"},{default:n.withCtx(()=>[o.visible?(n.openBlock(),n.createElementBlock("div",{key:0,class:n.normalizeClass(["virtual-human-container",{"is-dark":o.isDark}]),style:n.normalizeStyle(o.styles)},[n.createElementVNode("div",{class:"video-wrapper",ref_key:"wrapperRef",ref:C},[n.createElementVNode("video",{ref_key:"videoRef",ref:a,src:o.videoSrc,class:"persona-video",muted:o.muted,playsinline:"",loop:"",autoPlay:"",disablePictureInPicture:"false",onPlay:g,onPause:S,onEnded:k},null,40,H)],512)],6)):n.createCommentVNode("",!0)]),_:1}))}}),[["__scopeId","data-v-892abb8d"]]),A=n.defineComponent({__name:"VirtualHumanEventAdapter",props:{screenClientId:{type:String,required:!0},wsUrl:{type:String,required:!0}},emits:["eventNotifaction","end","pause","connected","error","playComplete"],setup(o,{emit:b}){const e=o,s=b,a=n.ref(null),C=n.ref(!1);let t=null,p=0,m=!1,w=0,g=!1;const S=()=>{t||(t=new(window.AudioContext||window.webkitAudioContext)({sampleRate:24e3})),t.state==="suspended"&&!g&&t.resume()},k=()=>{m&&w===0&&(s("playComplete",e.screenClientId),m=!1)},i=r=>{if(S(),!!t)try{const l=window.atob(r),d=l.length,v=new Uint8Array(d);for(let y=0;y<d;y++)v[y]=l.charCodeAt(y);const h=new Int16Array(v.buffer),V=new Float32Array(h.length);for(let y=0;y<h.length;y++)V[y]=h[y]/32768;const I=t.createBuffer(1,V.length,24e3);I.getChannelData(0).set(V);const P=t.createBufferSource();P.buffer=I,P.connect(t.destination),p<t.currentTime&&(p=t.currentTime),P.start(p),p+=I.duration,w++,P.onended=()=>{w--,k()}}catch(l){console.error("[VirtualHumanEventAdapter] Failed to decode and play audio:",l)}},u=r=>{switch(r){case"play":m=!1,w=0,p=0,g=!1,t&&t.state==="suspended"&&t.resume();break;case"resume":g=!1,t&&t.state==="suspended"&&t.resume();break;case"pause":g=!0,t&&t.state==="running"&&t.suspend();break;case"stop":g=!1,t&&(t.close(),t=null),p=0,m=!1,w=0;break;case"tts_complete":m=!0,k();break;default:console.warn(`[VirtualHumanEventAdapter] Unknown control action: ${r}`)}},c=()=>{a.value&&a.value.close();try{const r=new URL(e.wsUrl);r.searchParams.append("sessionId",e.screenClientId+"-event"),a.value=new WebSocket(r.toString()),a.value.onopen=()=>{C.value=!0,s("connected"),console.log(`[VirtualHumanEventAdapter] Connected to ${e.wsUrl} for session ${e.screenClientId}-event`)},a.value.onmessage=l=>{try{const d=JSON.parse(l.data);E(d)}catch(d){console.error("[VirtualHumanEventAdapter] Failed to parse message:",l.data,d)}},a.value.onerror=l=>{console.error("[VirtualHumanEventAdapter] WebSocket error:",l),s("error",l)},a.value.onclose=()=>{C.value=!1,console.log("[VirtualHumanEventAdapter] WebSocket disconnected")}}catch(r){console.error("[VirtualHumanEventAdapter] Failed to initialize WebSocket:",r),s("error",r)}},E=r=>{const{type:l,payload:d,action:v}=r;switch(console.log("msgmsg-002",r),l){case"audio":const h=(d==null?void 0:d.data)||r.data;h&&i(h);break;case"send_event":r.event&&s("eventNotifaction",r);break;case"control":v&&u(v);break;case"end":s("end",d);break;case"pause":s("pause",d);break;default:console.warn(`[VirtualHumanEventAdapter] Unknown message type: ${l}`)}};return n.watch(()=>e.screenClientId,()=>{e.screenClientId&&e.wsUrl&&c()}),n.watch(()=>e.wsUrl,()=>{e.screenClientId&&e.wsUrl&&c()}),n.onMounted(()=>{e.screenClientId&&e.wsUrl&&c()}),n.onUnmounted(()=>{a.value&&a.value.close(),t&&t.close()}),(r,l)=>n.renderSlot(r.$slots,"default")}}),_={install:o=>{o.component("VirtualHumanPersona",U),o.component("VirtualHumanEventAdapter",A)}};f.VirtualHumanEventAdapter=A,f.VirtualHumanPersona=U,f.default=_,Object.defineProperties(f,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
1
+ (function(f,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],n):(f=typeof globalThis<"u"?globalThis:f||self,n(f.VirtualHumanCf={},f.Vue))})(this,function(f,n){"use strict";const H=["src","muted"],U=((r,b)=>{const e=r.__vccOpts||r;for(const[a,o]of b)e[a]=o;return e})(n.defineComponent({__name:"VirtualHumanPersona",props:{videoSrc:{type:String,required:!0},visible:{type:Boolean,default:!1},isPlaying:{type:Boolean,default:!1},muted:{type:Boolean,default:!0},isDark:{type:Boolean,default:!1},screenClientId:{type:String,required:!1},wsUrl:{type:String,required:!1},styles:{type:Object,default:()=>({width:"400px",height:"500px",left:"16px",bottom:"16px"})}},emits:["update:isPlaying","ended","update:visible"],setup(r,{emit:b}){const e=r,a=b,o=n.ref(null),C=n.ref(null),t=n.ref(null),p=n.ref(!1),m=()=>{if(t.value&&t.value.close(),!(!e.wsUrl||!e.screenClientId))try{const c=new URL(e.wsUrl);c.searchParams.append("sessionId",e.screenClientId+"-persona"),t.value=new WebSocket(c.toString()),t.value.onopen=()=>{p.value=!0,console.log(`[VirtualHumanPersona] Connected to ${e.wsUrl} for session ${e.screenClientId}-persona`)},t.value.onmessage=u=>{try{const d=JSON.parse(u.data);w(d)}catch(d){console.error("[VirtualHumanPersona] Failed to parse message:",u.data,d)}},t.value.onerror=u=>{console.error("[VirtualHumanPersona] WebSocket error:",u)},t.value.onclose=()=>{p.value=!1,console.log("[VirtualHumanPersona] WebSocket disconnected")}}catch(c){console.error("[VirtualHumanPersona] Failed to initialize WebSocket:",c)}},w=c=>{const{type:u,action:d}=c;u==="control"&&(d==="play"||d==="resume"?(a("update:isPlaying",!0),a("update:visible",!0)):d==="pause"?(a("update:isPlaying",!1),a("update:visible",!0)):d==="stop"&&(a("update:isPlaying",!1),a("update:visible",!1),o.value&&(o.value.currentTime=0)))};n.watch(()=>e.screenClientId,()=>{e.screenClientId&&e.wsUrl&&m()}),n.watch(()=>e.wsUrl,()=>{e.screenClientId&&e.wsUrl&&m()}),n.watch(()=>e.isPlaying,c=>{o.value&&(c?o.value.play().catch(u=>console.error("Video play failed:",u)):o.value.pause())});const g=()=>{e.isPlaying||a("update:isPlaying",!0)},S=()=>{e.isPlaying&&a("update:isPlaying",!1)},k=()=>{a("update:isPlaying",!1),a("ended")};return n.onMounted(()=>{e.isPlaying&&o.value&&o.value.play().catch(c=>console.error("Video play failed:",c)),e.screenClientId&&e.wsUrl&&m()}),n.onUnmounted(()=>{t.value&&t.value.close()}),(c,u)=>(n.openBlock(),n.createBlock(n.Transition,{name:"fade"},{default:n.withCtx(()=>[r.visible?(n.openBlock(),n.createElementBlock("div",{key:0,class:n.normalizeClass(["virtual-human-container",{"is-dark":r.isDark}]),style:n.normalizeStyle(r.styles)},[n.createElementVNode("div",{class:"video-wrapper",ref_key:"wrapperRef",ref:C},[n.createElementVNode("video",{ref_key:"videoRef",ref:o,src:r.videoSrc,class:"persona-video",muted:r.muted,playsinline:"",loop:"",autoPlay:"",disablePictureInPicture:!1,onPlay:g,onPause:S,onEnded:k},null,40,H)],512)],6)):n.createCommentVNode("",!0)]),_:1}))}}),[["__scopeId","data-v-7325596e"]]),A=n.defineComponent({__name:"VirtualHumanEventAdapter",props:{screenClientId:{type:String,required:!0},wsUrl:{type:String,required:!0}},emits:["eventNotifaction","end","pause","connected","error","playComplete"],setup(r,{emit:b}){const e=r,a=b,o=n.ref(null),C=n.ref(!1);let t=null,p=0,m=!1,w=0,g=!1;const S=()=>{t||(t=new(window.AudioContext||window.webkitAudioContext)({sampleRate:24e3})),t.state==="suspended"&&!g&&t.resume()},k=()=>{m&&w===0&&(a("playComplete",e.screenClientId),m=!1)},c=s=>{if(S(),!!t)try{const l=window.atob(s),i=l.length,h=new Uint8Array(i);for(let y=0;y<i;y++)h[y]=l.charCodeAt(y);const v=new Int16Array(h.buffer),V=new Float32Array(v.length);for(let y=0;y<v.length;y++)V[y]=v[y]/32768;const I=t.createBuffer(1,V.length,24e3);I.getChannelData(0).set(V);const P=t.createBufferSource();P.buffer=I,P.connect(t.destination),p<t.currentTime&&(p=t.currentTime),P.start(p),p+=I.duration,w++,P.onended=()=>{w--,k()}}catch(l){console.error("[VirtualHumanEventAdapter] Failed to decode and play audio:",l)}},u=s=>{switch(s){case"play":m=!1,w=0,p=0,g=!1,t&&t.state==="suspended"&&t.resume();break;case"resume":g=!1,t&&t.state==="suspended"&&t.resume();break;case"pause":g=!0,t&&t.state==="running"&&t.suspend();break;case"stop":g=!1,t&&(t.close(),t=null),p=0,m=!1,w=0;break;case"tts_complete":m=!0,k();break;default:console.warn(`[VirtualHumanEventAdapter] Unknown control action: ${s}`)}},d=()=>{o.value&&o.value.close();try{const s=new URL(e.wsUrl);s.searchParams.append("sessionId",e.screenClientId+"-event"),o.value=new WebSocket(s.toString()),o.value.onopen=()=>{C.value=!0,a("connected"),console.log(`[VirtualHumanEventAdapter] Connected to ${e.wsUrl} for session ${e.screenClientId}-event`)},o.value.onmessage=l=>{try{const i=JSON.parse(l.data);E(i)}catch(i){console.error("[VirtualHumanEventAdapter] Failed to parse message:",l.data,i)}},o.value.onerror=l=>{console.error("[VirtualHumanEventAdapter] WebSocket error:",l),a("error",l)},o.value.onclose=()=>{C.value=!1,console.log("[VirtualHumanEventAdapter] WebSocket disconnected")}}catch(s){console.error("[VirtualHumanEventAdapter] Failed to initialize WebSocket:",s),a("error",s)}},E=s=>{const{type:l,payload:i,action:h}=s;switch(l){case"audio":const v=(i==null?void 0:i.data)||s.data;v&&c(v);break;case"send_event":s.event&&(console.log("adapter send_event:",s),a("eventNotifaction",s));break;case"control":h&&(console.log("adapter control:",h),u(h));break;case"end":console.log("adapter end:",i),a("end",i);break;case"pause":console.log("adapter pause:",i),a("pause",i);break;default:console.warn(`[VirtualHumanEventAdapter] Unknown message type: ${l}`)}};return n.watch(()=>e.screenClientId,()=>{e.screenClientId&&e.wsUrl&&d()}),n.watch(()=>e.wsUrl,()=>{e.screenClientId&&e.wsUrl&&d()}),n.onMounted(()=>{e.screenClientId&&e.wsUrl&&d()}),n.onUnmounted(()=>{o.value&&o.value.close(),t&&t.close()}),(s,l)=>n.renderSlot(s.$slots,"default")}}),_={install:r=>{r.component("VirtualHumanPersona",U),r.component("VirtualHumanEventAdapter",A)}};f.VirtualHumanEventAdapter=A,f.VirtualHumanPersona=U,f.default=_,Object.defineProperties(f,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "virtual-human-cf",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "Vue3 Digital Human Component Package by cf ",
5
5
  "main": "dist/virtual-human-cf.umd.js",
6
6
  "module": "dist/virtual-human-cf.es.js",
@@ -175,7 +175,7 @@ const connectWebSocket = () => {
175
175
 
176
176
  const handleMessage = (msg: any) => {
177
177
  const { type, payload, action } = msg;
178
- console.log("msgmsg-002",msg)
178
+
179
179
  switch (type) {
180
180
  // 接收音频
181
181
  case 'audio':
@@ -187,21 +187,25 @@ const handleMessage = (msg: any) => {
187
187
  // 接收事件通知
188
188
  case 'send_event':
189
189
  if (msg.event) {
190
+ console.log("adapter send_event:",msg)
190
191
  emit('eventNotifaction', msg);
191
192
  }
192
193
  break;
193
194
  // 控制指令接口
194
195
  case 'control':
195
196
  if (action) {
197
+ console.log("adapter control:",action)
196
198
  handleControlMessage(action);
197
199
  }
198
200
  break;
199
201
  case 'end':
200
202
  // 触发数字人对话结束事件
203
+ console.log("adapter end:",payload)
201
204
  emit('end', payload);
202
205
  break;
203
206
  case 'pause':
204
207
  // 触发暂停播放事件
208
+ console.log("adapter pause:",payload)
205
209
  emit('pause', payload);
206
210
  break;
207
211
  default:
@@ -15,7 +15,7 @@
15
15
  playsinline
16
16
  loop
17
17
  autoPlay
18
- disablePictureInPicture="false"
18
+ :disablePictureInPicture="false"
19
19
  @play="handlePlay"
20
20
  @pause="handlePause"
21
21
  @ended="handleEnded"
@@ -132,6 +132,7 @@ const handleMessage = (msg: any) => {
132
132
  } else if (action === 'pause') {
133
133
  emit('update:isPlaying', false);
134
134
  // 暂停时不隐藏视频
135
+ emit('update:visible', true);
135
136
  } else if (action === 'stop') {
136
137
  emit('update:isPlaying', false);
137
138
  emit('update:visible', false);