@scienjoy/sj-ai-plus 1.0.5 → 1.0.7

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.
@@ -1,27 +1,29 @@
1
- import { defineComponent as xe, ref as d, reactive as Ve, computed as _e, watch as te, nextTick as m, onMounted as Xe, onUnmounted as Ye, resolveDirective as Ie, openBlock as D, createElementBlock as F, normalizeStyle as Te, withDirectives as f, createElementVNode as n, vShow as w, normalizeClass as ke, toDisplayString as ne, withModifiers as oe, renderSlot as ae, createCommentVNode as A, createBlock as Be, Teleport as Oe } from "vue";
2
- import ie from "../../utils/api.ts";
3
- import Ce from "../../utils/utils.ts";
4
- import je from "../../utils/videoBackgroundRemoval.ts";
5
- const Ue = { class: "digital-human-assistant" }, ze = { class: "placeholder left-placeholder" }, Fe = { class: "placeholder right-placeholder" }, Ae = { class: "window-header-left" }, Ne = { class: "window-title-text" }, Ge = { class: "window-header-btns" }, Je = { class: "disconnect-btn" }, qe = {
1
+ import { defineComponent as Se, useCssVars as Ye, ref as u, reactive as Be, computed as Te, watch as P, nextTick as p, onMounted as Ue, onUnmounted as Oe, resolveDirective as je, openBlock as S, createElementBlock as D, normalizeStyle as ke, withDirectives as w, createElementVNode as n, vShow as g, normalizeClass as J, toDisplayString as ae, withModifiers as se, renderSlot as le, createCommentVNode as $, createBlock as Ge, Teleport as ze } from "vue";
2
+ import ce from "../../utils/api.ts";
3
+ import q from "../../utils/utils.ts";
4
+ import Fe from "../../utils/videoBackgroundRemoval.ts";
5
+ const Ae = { class: "digital-human-assistant" }, Ne = { class: "placeholder left-placeholder" }, Je = { class: "placeholder right-placeholder" }, qe = { class: "window-header-left" }, Ke = { class: "window-title-text" }, Qe = { class: "window-header-btns" }, Ze = { class: "disconnect-btn" }, et = {
6
6
  class: "connect-btn",
7
7
  disabled: ""
8
- }, Ke = { class: "connect-btn" }, Qe = { class: "window-content" }, Ze = { class: "main-content-inner" }, et = { class: "window-header-left" }, tt = { class: "window-title-text" }, nt = { class: "window-header-btns" }, ot = { class: "disconnect-btn" }, at = {
8
+ }, tt = { class: "connect-btn" }, nt = { class: "window-content" }, ot = { class: "main-content-inner" }, it = { class: "window-header-left" }, at = { class: "window-title-text" }, st = { class: "window-header-btns" }, lt = { class: "disconnect-btn" }, ct = {
9
9
  class: "connect-btn",
10
10
  disabled: ""
11
- }, it = { class: "connect-btn" }, lt = { class: "window-content" }, st = { class: "window-header-left" }, ct = { class: "window-title-text" }, dt = { class: "window-header-btns" }, ut = { class: "disconnect-btn" }, rt = {
11
+ }, dt = { class: "connect-btn" }, ut = { class: "window-content" }, rt = { class: "window-header-left" }, vt = { class: "window-title-text" }, ft = { class: "window-header-btns" }, ht = { class: "disconnect-btn" }, wt = {
12
12
  class: "connect-btn",
13
13
  disabled: ""
14
- }, vt = { class: "connect-btn" }, ht = { class: "window-content" }, ft = xe({
14
+ }, gt = { class: "connect-btn" }, mt = { class: "window-content" }, pt = {
15
+ key: 0,
16
+ class: "digital-video-loading"
17
+ }, bt = Se({
15
18
  name: "SjDigitalHumanAssistant"
16
- }), bt = /* @__PURE__ */ xe({
17
- ...ft,
19
+ }), Tt = /* @__PURE__ */ Se({
20
+ ...bt,
18
21
  props: {
19
22
  windowWidth: { default: 320 },
20
23
  windowHeight: { default: 467 },
21
24
  windowTitle: { default: "数字人助手" },
22
25
  sidebarWidth: { default: "25%" },
23
- sidebarLeftTitle: { default: "左侧业务区" },
24
- sidebarRightTitle: { default: "右侧业务区" },
26
+ sidebarBgColor: { default: "#ffffff" },
25
27
  edgeThreshold: { default: 10 },
26
28
  dragThreshold: { default: 8 },
27
29
  defaultStickSide: { default: "" },
@@ -30,440 +32,439 @@ const Ue = { class: "digital-human-assistant" }, ze = { class: "placeholder left
30
32
  maxReconnectTimes: { default: 10 },
31
33
  baseUrl: { default: "" }
32
34
  },
33
- setup($, { expose: Se }) {
34
- const o = $, le = d(null), se = d(null), u = d(null), a = d(null), p = je(), ce = d(null), de = d(null), ue = d(null), P = d(null), E = d(!1), c = d(!1), h = d(!1), re = d(!0), V = d(!1), r = Ve({
35
+ setup(V, { expose: Ee }) {
36
+ Ye((e) => ({
37
+ f2c09f26: e.sidebarBgColor
38
+ }));
39
+ const i = V, de = u(null), ue = u(null), s = u(null), o = u(null), re = u(null), ve = u(null), fe = u(null), X = u(null), r = Fe(), E = u(!1), l = u(!1), f = u(!1), x = u(!1), he = u(!0), Y = u(!1), h = u(i.defaultStickSide), B = u(!1), R = u(!1), M = u(!1), K = u(!1), Q = u(!1);
40
+ let d = null, b = "";
41
+ const U = u(null), y = u(0), O = u(!1), L = u(!1), v = Be({
35
42
  x: 0,
36
43
  y: 0,
37
44
  offsetX: 0,
38
45
  offsetY: 0
39
- }), v = d(o.defaultStickSide), X = d(!1), R = d(!1), L = d(!1), N = d(!1), G = d(!1);
40
- let s = null, b = "";
41
- const Y = d(null), y = d(0), I = d(!1), H = d(!1), Ee = _e(() => ({
42
- "--sidebar-width": o.sidebarWidth,
43
- "--window-width": `${o.windowWidth}px`,
44
- "--window-height": `${o.windowHeight}px`
45
- })), Le = _e(() => ({
46
- left: `${r.x}px`,
47
- top: `${r.y}px`,
48
- width: `${o.windowWidth}px`,
49
- height: `${o.windowHeight}px`,
50
- zIndex: X.value || L.value ? 9999 : 1e3
51
- })), He = (t) => {
52
- !t && u.value ? (I.value = !1, y.value = 0, pe()) : t ? (I.value = !0, $e()) : console.warn("自动连接超时:video元素未挂载"), re.value = t;
53
- }, B = (t) => {
54
- He(!t), V.value = t, t && c.value && m(() => g());
55
- }, Me = () => {
56
- B(!0);
57
- }, ve = () => {
58
- switch (v.value) {
46
+ }), xe = Te(() => ({
47
+ "--sidebar-width": i.sidebarWidth,
48
+ "--window-width": `${i.windowWidth}px`,
49
+ "--window-height": `${i.windowHeight}px`
50
+ })), Me = Te(() => ({
51
+ left: `${v.x}px`,
52
+ top: `${v.y}px`,
53
+ width: `${i.windowWidth}px`,
54
+ height: `${i.windowHeight}px`,
55
+ zIndex: B.value || M.value ? 9999 : 1e3
56
+ })), Le = (e) => {
57
+ !e && s.value ? (O.value = !1, y.value = 0, Re()) : e ? (O.value = !0, Ve()) : console.warn("❌ 自动连接超时:video元素未挂载"), he.value = e;
58
+ }, j = (e) => {
59
+ Le(!e), Y.value = e, e && l.value ? p(() => m()) : e || (x.value = !1);
60
+ }, He = () => {
61
+ j(!0);
62
+ }, we = () => {
63
+ switch (h.value) {
59
64
  case "left":
60
- return de.value ?? P.value;
65
+ return ve.value ?? X.value;
61
66
  case "right":
62
- return ue.value ?? P.value;
67
+ return fe.value ?? X.value;
63
68
  default:
64
- return ce.value ?? P.value;
69
+ return re.value ?? X.value;
65
70
  }
66
- }, C = () => se.value?.getBoundingClientRect() || {
71
+ }, G = () => ue.value?.getBoundingClientRect() || {
67
72
  width: 0,
68
73
  height: 0,
69
74
  left: 0,
70
75
  right: 0,
71
76
  top: 0,
72
77
  bottom: 0
73
- }, he = () => le.value?.getBoundingClientRect() || {
78
+ }, ge = () => de.value?.getBoundingClientRect() || {
74
79
  width: 0,
75
80
  height: 0,
76
81
  left: 0,
77
82
  right: 0,
78
83
  top: 0,
79
84
  bottom: 0
80
- }, J = (t, e) => {
81
- const i = C();
85
+ }, Z = (e, t) => {
86
+ const c = window.innerWidth || document.documentElement.clientWidth, a = window.innerHeight || document.documentElement.clientHeight;
82
87
  return {
83
- x: Math.max(0, Math.min(t, i.width - o.windowWidth)),
84
- y: Math.max(0, Math.min(e, i.height - o.windowHeight))
88
+ x: Math.max(0, Math.min(e, c - i.windowWidth)),
89
+ y: Math.max(0, Math.min(t, a - i.windowHeight))
85
90
  };
86
- }, fe = () => {
87
- const t = C(), e = t.width - o.windowWidth - 10, i = t.height - o.windowHeight - 10;
88
- return J(e, i);
89
- }, we = () => {
90
- const t = C(), e = he();
91
- N.value = e.left <= t.left + o.edgeThreshold, G.value = e.right >= t.right - o.edgeThreshold;
92
- }, ge = () => {
93
- const t = C(), e = he(), i = e.left <= t.left + o.edgeThreshold ? "left" : e.right >= t.right - o.edgeThreshold ? "right" : "";
94
- i !== v.value && (v.value = i, u.value && (u.value.volume = i ? 0.5 : 1), M(), g()), N.value = G.value = !1;
95
- }, We = (t) => {
96
- X.value = !0, r.offsetX = t.clientX - r.x, r.offsetY = t.clientY - r.y, document.addEventListener("mousemove", q), document.addEventListener("mouseup", K);
97
- }, q = (t) => {
98
- if (!X.value) return;
99
- const e = C(), { x: i, y: l } = J(t.clientX - e.left - r.offsetX, t.clientY - e.top - r.offsetY);
100
- r.x = i, r.y = l, we();
101
- }, K = () => {
102
- ge(), X.value = !1, document.removeEventListener("mousemove", q), document.removeEventListener("mouseup", K);
103
- }, me = (t, e) => {
104
- R.value = !0, r.offsetX = e.clientX - (e.clientX - o.windowWidth / 2), r.offsetY = e.clientY - (e.clientY - 20), document.addEventListener("mousemove", O);
105
- }, O = (t) => {
91
+ }, me = () => {
92
+ const e = window.innerWidth || document.documentElement.clientWidth, t = window.innerHeight || document.documentElement.clientHeight, c = e - i.windowWidth - 10, a = t - i.windowHeight - 10;
93
+ return Z(c, a);
94
+ }, pe = () => {
95
+ const e = G(), t = ge();
96
+ K.value = t.left <= e.left + i.edgeThreshold, Q.value = t.right >= e.right - i.edgeThreshold;
97
+ }, be = () => {
98
+ const e = G(), t = ge(), c = t.left <= e.left + i.edgeThreshold ? "left" : t.right >= e.right - i.edgeThreshold ? "right" : "";
99
+ c !== h.value && (h.value = c, s.value && (s.value.volume = c ? 0.5 : 1), H(), m()), K.value = Q.value = !1;
100
+ }, Ie = () => {
101
+ x.value = !0;
102
+ }, Pe = () => {
103
+ x.value = !1;
104
+ }, De = (e) => {
105
+ B.value = !0, v.offsetX = e.clientX - v.x, v.offsetY = e.clientY - v.y, document.addEventListener("mousemove", ee), document.addEventListener("mouseup", te);
106
+ }, ee = (e) => {
107
+ if (!B.value) return;
108
+ const t = G(), { x: c, y: a } = Z(e.clientX - t.left - v.offsetX, e.clientY - t.top - v.offsetY);
109
+ v.x = c, v.y = a, pe();
110
+ }, te = () => {
111
+ be(), B.value = !1, document.removeEventListener("mousemove", ee), document.removeEventListener("mouseup", te);
112
+ }, ye = (e, t) => {
113
+ R.value = !0, v.offsetX = t.clientX - (t.clientX - i.windowWidth / 2), v.offsetY = t.clientY - (t.clientY - 20), document.addEventListener("mousemove", z);
114
+ }, z = (e) => {
106
115
  if (!R.value) return;
107
- const e = Math.abs(t.movementX), i = Math.abs(t.movementY);
108
- (e > o.dragThreshold || i > o.dragThreshold) && (L.value = !0, v.value = "", document.removeEventListener("mousemove", O), document.addEventListener("mousemove", Q), document.addEventListener("mouseup", Z));
109
- }, Q = (t) => {
110
- if (!L.value) return;
111
- const e = C(), { x: i, y: l } = J(t.clientX - e.left - r.offsetX, t.clientY - e.top - r.offsetY);
112
- r.x = i, r.y = l, we();
113
- }, Z = () => {
114
- ge(), R.value = L.value = !1, document.removeEventListener("mousemove", Q), document.removeEventListener("mouseup", Z);
115
- }, j = () => {
116
- R.value && !L.value && (R.value = !1, document.removeEventListener("mousemove", O));
117
- }, ee = async (t) => {
118
- if (!c.value || !b)
119
- return;
120
- await x(), console.log("已打断当前对话,准备播放新文本:", t);
121
- const e = {
122
- text: t,
116
+ const t = Math.abs(e.movementX), c = Math.abs(e.movementY);
117
+ (t > i.dragThreshold || c > i.dragThreshold) && (M.value = !0, h.value = "", document.removeEventListener("mousemove", z), document.addEventListener("mousemove", ne), document.addEventListener("mouseup", oe));
118
+ }, ne = (e) => {
119
+ if (!M.value) return;
120
+ const t = G(), { x: c, y: a } = Z(e.clientX - t.left - v.offsetX, e.clientY - t.top - v.offsetY);
121
+ v.x = c, v.y = a, pe();
122
+ }, oe = () => {
123
+ be(), R.value = M.value = !1, document.removeEventListener("mousemove", ne), document.removeEventListener("mouseup", oe);
124
+ }, F = () => {
125
+ R.value && !M.value && (R.value = !1, document.removeEventListener("mousemove", z));
126
+ }, ie = async (e) => {
127
+ if (!l.value || !b) return;
128
+ await T(), console.log("✅ 准备播放文本:", e);
129
+ const t = {
130
+ text: e,
123
131
  type: "echo",
124
132
  interrupt: !0,
125
133
  sessionid: parseInt(b)
126
134
  };
127
- ie.digitalHumanChat(o.baseUrl, e).then((i) => {
128
- i && Number(i.code);
129
- }).catch((i) => {
130
- console.log("api.digitalHumanChat:", i);
135
+ ce.digitalHumanChat(i.baseUrl, t).then((c) => {
136
+ c && Number(c.code) === 0 && console.log("✅ 播放指令发送成功");
137
+ }).catch((c) => {
138
+ console.error("❌ 播放指令发送失败:", c);
131
139
  });
132
- }, x = async () => {
133
- if (!c.value || !b) return;
134
- const t = {
135
- sessionid: parseInt(b)
136
- };
137
- ie.digitalHumanInterruptTalk(o.baseUrl, t).then((e) => {
138
- e && Number(e.code) === 0 && console.log("数字人对话已成功打断");
139
- }).catch((e) => {
140
- console.log("api.digitalHumanInterruptTalk:", e);
140
+ }, T = async () => {
141
+ if (!l.value || !b) return;
142
+ const e = { sessionid: parseInt(b) };
143
+ ce.digitalHumanInterruptTalk(i.baseUrl, e).then((t) => {
144
+ t && Number(t.code) === 0 && console.log("✅ 对话已打断");
145
+ }).catch((t) => {
146
+ console.error("❌ 打断对话失败:", t);
141
147
  });
142
- }, S = () => {
143
- Y.value && (clearTimeout(Y.value), Y.value = null, console.log("重连定时器已清除")), H.value = !1;
144
- }, M = (t = !1) => {
145
- if (!a.value) return;
146
- t || p.stopProcessing();
147
- const e = a.value.getContext("2d");
148
- if (e && (e.clearRect(0, 0, a.value.width, a.value.height), !t)) {
149
- const i = a.value.width, l = a.value.height;
150
- a.value.width = i, a.value.height = l;
148
+ }, k = () => {
149
+ U.value && (clearTimeout(U.value), U.value = null), L.value = !1, console.log("重连定时器已清除");
150
+ }, H = (e = !1) => {
151
+ if (!o.value) return;
152
+ e || r.stopProcessing();
153
+ const t = o.value.getContext("2d");
154
+ if (t && (t.clearRect(0, 0, o.value.width, o.value.height), !e)) {
155
+ const c = o.value.width, a = o.value.height;
156
+ o.value.width = c, o.value.height = a;
151
157
  }
152
- a.value && !t && (a.value.style.width = "", a.value.style.height = "", v.value === "" && (a.value.style.marginLeft = "", a.value.style.marginTop = ""));
153
- }, g = async (t = !1) => {
154
- if (!u.value || !a.value || !E.value || !c.value) return;
155
- await m();
156
- const e = u.value.videoWidth || o.windowWidth, i = u.value.videoHeight || o.windowHeight, l = e / i;
157
- console.log("视频原始宽高比:", l, "尺寸:", e, i);
158
- let _;
159
- const ye = ve();
160
- ye ? _ = ye.getBoundingClientRect() : _ = {
161
- width: v.value ? 0 : o.windowWidth,
162
- height: v.value ? 0 : o.windowHeight,
163
- left: 0,
164
- top: 0,
165
- right: 0,
166
- bottom: 0
167
- };
168
- const U = _.width || (v.value ? 300 : o.windowWidth), z = _.height || (v.value ? window.innerHeight - 40 : o.windowHeight), Pe = U / z;
169
- let T, k;
170
- Pe > l ? (k = z, T = k * l) : (T = U, k = T / l);
171
- const Re = window.devicePixelRatio || 1;
172
- a.value.width = Math.floor(T * Re), a.value.height = Math.floor(k * Re), a.value.style.display = "block", a.value.style.objectFit = "contain", v.value === "" ? (a.value.style.width = `${T}px`, a.value.style.height = `${k}px`, a.value.style.marginLeft = `${(U - T) / 2}px`, a.value.style.marginTop = `${(z - k) / 2}px`) : (a.value.style.width = "100%", a.value.style.height = "100%", a.value.style.marginLeft = "0", a.value.style.marginTop = "0"), console.log("Canvas适配完成:", {
173
- mode: v.value || "浮动",
174
- container: { width: U, height: z },
175
- canvas: { drawWidth: T, drawHeight: k, physicalWidth: a.value.width, physicalHeight: a.value.height }
176
- }), t || (p.videoRef.value = u.value, p.canvasRef.value = a.value, await p.processVideo());
177
- }, W = () => {
178
- if (I.value || c.value || h.value || H.value) {
179
- console.log("重连条件不满足:手动断开/已连接/正在连接/正在冷却");
158
+ o.value && !e && (o.value.style.width = "", o.value.style.height = "", h.value === "" && (o.value.style.marginLeft = "", o.value.style.marginTop = ""));
159
+ }, m = async (e = !1) => {
160
+ if (!s.value || !o.value || !E.value || !l.value) return;
161
+ await p();
162
+ const t = s.value.videoWidth || i.windowWidth, c = s.value.videoHeight || i.windowHeight, a = t / c;
163
+ let C;
164
+ const _e = we();
165
+ _e ? C = _e.getBoundingClientRect() : C = { width: 0, height: 0, left: 0, top: 0, right: 0, bottom: 0 };
166
+ const A = C.width || (h.value ? 300 : i.windowWidth), N = C.height || (h.value ? window.innerHeight - 40 : i.windowHeight), Xe = A / N;
167
+ let _, W;
168
+ Xe > a ? (W = N, _ = W * a) : (_ = A, W = _ / a);
169
+ const We = window.devicePixelRatio || 1;
170
+ o.value.width = Math.floor(_ * We), o.value.height = Math.floor(W * We), o.value.style.display = "block", o.value.style.objectFit = "contain", h.value === "" ? (o.value.style.width = `${_}px`, o.value.style.height = `${W}px`, o.value.style.marginLeft = `${(A - _) / 2}px`, o.value.style.marginTop = `${(N - W) / 2}px`) : (o.value.style.width = "100%", o.value.style.height = "100%", o.value.style.marginLeft = "0", o.value.style.marginTop = "0"), console.log("✅ Canvas适配完成:", {
171
+ mode: h.value || "浮动",
172
+ container: { width: A, height: N },
173
+ canvas: { drawWidth: _, drawHeight: W }
174
+ }), e || (r.videoRef.value = s.value, r.canvasRef.value = o.value, await r.processVideo()), !r.isInitSuccess.value && l.value && (console.log("🔄 检测到WebGPU未初始化,触发手动重连"), await r.reInitWebGPU() && await r.processVideo());
175
+ }, I = () => {
176
+ if (O.value || l.value || f.value || L.value) {
177
+ console.log("🚫 重连条件不满足");
180
178
  return;
181
179
  }
182
- if (x().then(() => {
183
- console.log("重连前已打断当前对话");
184
- }), o.maxReconnectTimes !== -1 && y.value >= o.maxReconnectTimes) {
185
- console.warn(`数字人重连已达最大次数(${o.maxReconnectTimes}),停止重连`), S(), Ce.funcElMessageShowCtrl(`数字人连接失败,已尝试${o.maxReconnectTimes}次重连,请重试!`), y.value = 0;
180
+ if (T(), i.maxReconnectTimes !== -1 && y.value >= i.maxReconnectTimes) {
181
+ console.warn(`🚫 重连已达最大次数(${i.maxReconnectTimes})`), k(), q.funcElMessageShowCtrl(`❌ 数字人连接失败,已尝试${i.maxReconnectTimes}次重连,请重试!`, "error"), y.value = 0;
186
182
  return;
187
183
  }
188
- H.value = !0, Y.value = setTimeout(() => {
184
+ L.value = !0, U.value = setTimeout(() => {
189
185
  try {
190
- y.value++, console.log(`数字人第${y.value}次重连... (最大次数:${o.maxReconnectTimes})`), pe();
186
+ y.value++, console.log(`🔄 第${y.value}次重连WebRTC...`), r.stopProcessing(), Re();
191
187
  } finally {
192
- H.value = !1;
188
+ L.value = !1;
193
189
  }
194
- }, o.reconnectInterval * 1e3);
195
- }, De = async () => {
196
- if (s)
190
+ }, i.reconnectInterval * 1e3);
191
+ }, $e = async () => {
192
+ if (d)
197
193
  try {
198
- s.addTransceiver("video", { direction: "recvonly" }), s.addTransceiver("audio", { direction: "recvonly" });
199
- const t = await s.createOffer();
200
- await s.setLocalDescription(t), await new Promise((l) => {
201
- if (s?.iceGatheringState === "complete")
202
- l();
194
+ d.addTransceiver("video", { direction: "recvonly" }), d.addTransceiver("audio", { direction: "recvonly" });
195
+ const e = await d.createOffer();
196
+ await d.setLocalDescription(e), await new Promise((a) => {
197
+ if (d?.iceGatheringState === "complete")
198
+ a();
203
199
  else {
204
- const _ = () => {
205
- s?.iceGatheringState === "complete" && (s?.removeEventListener("icegatheringstatechange", _), l());
200
+ const C = () => {
201
+ d?.iceGatheringState === "complete" && (d?.removeEventListener("icegatheringstatechange", C), a());
206
202
  };
207
- s?.addEventListener("icegatheringstatechange", _);
203
+ d?.addEventListener("icegatheringstatechange", C);
208
204
  }
209
205
  });
210
- const e = s.localDescription, i = {
211
- sdp: e.sdp,
212
- type: e.type
213
- };
214
- ie.digitalHumanOffer(o.baseUrl, i).then((l) => {
215
- l ? (b = l.sessionid, s.setRemoteDescription(new RTCSessionDescription(l)), c.value = !0, y.value = 0, S(), console.log("数字人连接成功,重置重连状态"), m(() => g())) : (c.value = !1, console.log("数字人连接失败:接口返回空"), W()), h.value = !1;
216
- }).catch((l) => {
217
- console.error("api.digitalHumanOffer 失败:", l), c.value = !1, h.value = !1, W();
206
+ const t = d.localDescription, c = { sdp: t.sdp, type: t.type };
207
+ ce.digitalHumanOffer(i.baseUrl, c).then((a) => {
208
+ a ? (b = a.sessionid, d.setRemoteDescription(new RTCSessionDescription(a)), l.value = !0, y.value = 0, k(), console.log("✅ WebRTC连接成功"), p(() => m())) : (l.value = !1, console.log("❌ WebRTC连接失败:接口返回空"), I()), f.value = !1;
209
+ }).catch((a) => {
210
+ console.error("❌ WebRTC Offer发送失败:", a), l.value = !1, f.value = !1, I();
218
211
  });
219
- } catch (t) {
220
- console.error("negotiate 失败:", t), c.value = !1, h.value = !1, W();
212
+ } catch (e) {
213
+ console.error(" WebRTC协商失败:", e), l.value = !1, f.value = !1, I();
221
214
  }
222
- }, pe = () => {
223
- if (c.value || h.value) {
224
- console.log("当前已连接/正在连接,无需重复触发");
225
- return;
226
- }
227
- h.value = !0, console.log("开始建立数字人连接...");
228
- const t = {
229
- sdpSemantics: "unified-plan"
230
- };
231
- s && (s.close(), s = null), s = new RTCPeerConnection(t), s.addEventListener("track", (e) => {
232
- e.track.kind === "video" && u.value && (u.value.srcObject = e.streams[0], u.value.onloadedmetadata = async () => {
233
- u.value && a.value && (p.videoRef.value = u.value, p.canvasRef.value = a.value, await g(), await p.processVideo());
234
- }, u.value.onresize = () => {
235
- g();
215
+ }, Re = () => {
216
+ if (l.value || f.value) return;
217
+ f.value = !0, console.log("🔄 开始建立WebRTC连接..."), d && (d.close(), d = null);
218
+ const e = { sdpSemantics: "unified-plan" };
219
+ d = new RTCPeerConnection(e), d.addEventListener("track", (t) => {
220
+ t.track.kind === "video" && s.value && (s.value.srcObject = t.streams[0], s.value.onloadedmetadata = async () => {
221
+ s.value && o.value && (r.videoRef.value = s.value, r.canvasRef.value = o.value, await m(), await r.processVideo());
222
+ }, s.value.onresize = () => {
223
+ m(!0);
236
224
  });
237
- }), s.addEventListener("iceconnectionstatechange", () => {
238
- switch (console.log("ICE连接状态变化:", s.iceConnectionState), s.iceConnectionState) {
225
+ }), d.addEventListener("iceconnectionstatechange", () => {
226
+ switch (console.log("📶 ICE状态变化:", d.iceConnectionState), d.iceConnectionState) {
239
227
  case "disconnected":
240
228
  case "failed":
241
229
  case "closed":
242
- console.log("WebRTC连接断开/失败,触发重连"), c.value = !1, h.value = !1, s = null, b = "", u.value && (u.value.srcObject = null), M(), x().then(() => {
243
- console.log("ICE连接断开,已打断对话");
244
- }), W();
230
+ console.log("📶 ICE连接断开,触发重连"), l.value = !1, f.value = !1, d = null, b = "", s.value && (s.value.srcObject = null), H(), T(), I();
245
231
  break;
246
232
  case "connected":
247
- y.value = 0, S(), console.log("ICE连接成功,重置重连状态"), m(() => g());
233
+ console.log("📶 ICE连接成功"), y.value = 0, k(), p(async () => {
234
+ !r.isInitSuccess.value && l.value && await r.reInitWebGPU() && await r.processVideo();
235
+ });
248
236
  break;
249
237
  }
250
- }), De();
251
- }, $e = () => {
252
- I.value = !0, S(), h.value = !1, p.stopProcessing(), M(), x().then(() => {
253
- console.log("手动断开连接,已打断当前对话");
254
- }), setTimeout(() => {
255
- s && (s.close(), s = null), b = "", u.value && (u.value.srcObject = null), c.value = !1, y.value = 0, console.log("手动断开连接,重置所有状态");
256
- }, 500);
257
- };
258
- Se({
259
- digitalHumanChat: ee,
260
- // 播放文本的核心方法
261
- digitalHumanInterruptTalk: x,
262
- // 打断方法
263
- isConnected: c,
264
- // 连接状态
265
- isConnecting: h,
266
- // 连接中状态
267
- reconnect: W,
268
- // 手动触发重连
269
- clearReconnectTimer: S,
270
- // 手动停止重连
271
- currentReconnectTimes: y,
272
- // 暴露当前重连次数,方便调试
273
- isWaitingReconnect: H,
274
- adaptCanvasToContainer: g
275
- // 暴露适配方法,方便父组件调用
276
- }), te(
277
- v,
278
- async (t, e) => {
279
- !E.value || !u.value || (await m(), u.value.volume = t ? 0.5 : 1, c.value && (M(), await g()));
238
+ }), $e();
239
+ }, Ve = () => {
240
+ O.value = !0, k(), f.value = !1, r.stopProcessing(), H(), T().then(() => {
241
+ setTimeout(() => {
242
+ d && (d.close(), d = null), b = "", s.value && (s.value.srcObject = null), l.value = !1, y.value = 0, console.log("✅ 手动断开连接,资源已清理");
243
+ }, 500);
244
+ });
245
+ }, Ce = q.debounce(() => {
246
+ if (h.value === "") {
247
+ const { x: e, y: t } = me();
248
+ v.x = e, v.y = t;
249
+ }
250
+ l.value && E.value && (H(!0), p(() => m(!0)));
251
+ }, 50);
252
+ return P(r.isInitSuccess, (e) => {
253
+ !e && f.value && q.funcElMessageShowCtrl("🔄 WebGPU初始化失败,正在尝试重连...", "warning");
254
+ }, { immediate: !0 }), P(
255
+ [() => r.isInitSuccess, () => l.value],
256
+ async ([e, t]) => {
257
+ !e && t && s.value && o.value ? (o.value.style.display = "none", s.value.style.opacity = "1", s.value.style.width = "100%", s.value.style.height = "100%", q.funcElMessageShowCtrl("ℹ️ 当前浏览器不支持WebGPU,将显示原始视频(无透明背景)", "info")) : e && t && s.value && o.value && (o.value.style.display = "block", s.value.style.opacity = "0");
258
+ },
259
+ { immediate: !0 }
260
+ ), P(
261
+ h,
262
+ async (e) => {
263
+ !E.value || !s.value || (await p(), s.value.volume = e ? 0.5 : 1, l.value && (H(), await m()));
280
264
  },
281
265
  { immediate: !0, deep: !0 }
282
- ), te(
283
- [() => c.value, () => o.defaultPlayText],
284
- async ([t, e], [i]) => {
285
- t && !i && e && b && (console.log("连接成功,自动播放默认文本:", e), await ee(e), m(() => g()));
266
+ ), P(
267
+ [() => l.value, () => i.defaultPlayText],
268
+ async ([e, t], [c]) => {
269
+ e && !c && t && b && (console.log("连接成功,自动播放默认文本:", t), await ie(t), p(() => m()));
286
270
  },
287
271
  { immediate: !1 }
288
- ), te(
289
- () => o.defaultPlayText,
290
- async (t) => {
291
- c.value && t && b && (console.log("默认文本加载完成,自动播放:", t), await ee(t), m(() => g()));
272
+ ), P(
273
+ () => i.defaultPlayText,
274
+ async (e) => {
275
+ l.value && e && b && (console.log("✅ 默认文本更新,自动播放:", e), await ie(e), p(() => m()));
292
276
  },
293
277
  { immediate: !0 }
294
- ), Xe(async () => {
295
- await m(), await m(), E.value = !0;
296
- const { x: t, y: e } = fe();
297
- r.x = t, r.y = e, window.addEventListener("resize", be);
298
- });
299
- const be = Ce.debounce(() => {
300
- if (v.value === "") {
301
- const { x: t, y: e } = fe();
302
- r.x = t, r.y = e;
303
- }
304
- c.value && E.value && (M(!0), m(() => g(!0)));
305
- }, 50);
306
- return Ye(() => {
307
- x().then(() => {
308
- console.log("组件卸载,已打断当前对话");
309
- }), document.removeEventListener("mousemove", O), document.removeEventListener("mousemove", Q), document.removeEventListener("mouseup", Z), document.removeEventListener("mousemove", q), document.removeEventListener("mouseup", K), window.removeEventListener("resize", be), S(), p.stopProcessing(), u.value && (u.value.srcObject = null), s && s.close();
310
- }), (t, e) => {
311
- const i = Ie("drag");
312
- return D(), F("div", {
278
+ ), Ue(async () => {
279
+ await p(), await p(), E.value = !0;
280
+ const { x: e, y: t } = me();
281
+ v.x = e, v.y = t, window.addEventListener("resize", Ce);
282
+ }), Oe(() => {
283
+ document.removeEventListener("mousemove", z), document.removeEventListener("mousemove", ne), document.removeEventListener("mouseup", oe), document.removeEventListener("mousemove", ee), document.removeEventListener("mouseup", te), window.removeEventListener("resize", Ce), k(), r.stopProcessing(), T(), d && d.close(), s.value && (s.value.srcObject = null);
284
+ }), Ee({
285
+ digitalHumanChat: ie,
286
+ // 播放文本
287
+ digitalHumanInterruptTalk: T,
288
+ // 打断对话
289
+ isConnected: l,
290
+ // 连接状态
291
+ isConnecting: f,
292
+ // 连接中状态
293
+ reconnect: I,
294
+ // 手动重连WebRTC
295
+ clearReconnectTimer: k,
296
+ // 停止重连
297
+ currentReconnectTimes: y,
298
+ // 当前重连次数
299
+ isWaitingReconnect: L,
300
+ // 重连冷却状态
301
+ adaptCanvasToContainer: m,
302
+ // 手动适配Canvas
303
+ webgpuReInit: r.reInitWebGPU,
304
+ // 手动重连WebGPU
305
+ webgpuIsInitSuccess: r.isInitSuccess,
306
+ // WebGPU初始化状态
307
+ webgpuIsProcessing: r.isProcessing
308
+ // WebGPU运行状态
309
+ }), (e, t) => {
310
+ const c = je("drag");
311
+ return S(), D("div", {
313
312
  class: "draggable-window-container",
314
- style: Te(Ee.value)
313
+ style: ke(xe.value)
315
314
  }, [
316
- f(n("div", Ue, null, 512), [
317
- [w, re.value],
318
- [i, ["digital-human-assistant", Me, !0]]
315
+ w(n("div", Ae, null, 512), [
316
+ [g, he.value],
317
+ [c, ["digital-human-assistant", He, !0]]
319
318
  ]),
320
319
  n("div", {
321
320
  ref_key: "teleportFallbackRef",
322
- ref: P,
321
+ ref: X,
323
322
  class: "teleport-fallback"
324
323
  }, null, 512),
325
- f(n("div", ze, null, 512), [
326
- [w, N.value]
324
+ w(n("div", Ne, null, 512), [
325
+ [g, K.value]
327
326
  ]),
328
- f(n("div", Fe, null, 512), [
329
- [w, G.value]
327
+ w(n("div", Je, null, 512), [
328
+ [g, Q.value]
330
329
  ]),
331
- V.value && v.value === "left" ? (D(), F("div", {
330
+ Y.value && h.value === "left" ? (S(), D("div", {
332
331
  key: 0,
333
- class: ke(["sidebar left-sidebar", { pressing: R.value }])
332
+ class: J(["sidebar left-sidebar", { pressing: R.value }])
334
333
  }, [
335
334
  n("div", {
336
335
  class: "window-header",
337
- onMousedown: e[2] || (e[2] = (l) => me("left", l)),
338
- onMouseup: j,
339
- onMouseleave: j
336
+ onMousedown: t[2] || (t[2] = (a) => ye("left", a)),
337
+ onMouseup: F,
338
+ onMouseleave: F
340
339
  }, [
341
- n("div", Ae, [
342
- n("span", Ne, ne($.windowTitle), 1),
343
- n("div", Ge, [
344
- f(n("button", Je, "未连接", 512), [
345
- [w, !c.value && !h.value]
340
+ n("div", qe, [
341
+ n("span", Ke, ae(V.windowTitle), 1),
342
+ n("div", Qe, [
343
+ w(n("button", Ze, "未连接", 512), [
344
+ [g, !l.value && !f.value]
346
345
  ]),
347
- f(n("button", qe, "连接中...", 512), [
348
- [w, h.value]
346
+ w(n("button", et, "连接中...", 512), [
347
+ [g, f.value]
349
348
  ]),
350
- f(n("button", Ke, "已连接", 512), [
351
- [w, c.value]
349
+ w(n("button", tt, "已连接", 512), [
350
+ [g, l.value]
352
351
  ])
353
352
  ])
354
353
  ]),
355
354
  n("div", {
356
355
  class: "drag-window-hide",
357
- onClick: e[0] || (e[0] = (l) => B(!1)),
358
- onMousedown: e[1] || (e[1] = oe(() => {
356
+ onClick: t[0] || (t[0] = (a) => j(!1)),
357
+ onMousedown: t[1] || (t[1] = se(() => {
359
358
  }, ["stop"]))
360
359
  }, null, 32)
361
360
  ], 32),
362
- n("div", Qe, [
363
- ae(t.$slots, "sidebar-left", {}, void 0, !0),
361
+ n("div", nt, [
362
+ le(e.$slots, "sidebar-left", {}, void 0, !0),
364
363
  n("div", {
365
364
  ref_key: "sidebarLeftVideoRef",
366
- ref: de,
365
+ ref: ve,
367
366
  class: "sidebar-video-container"
368
367
  }, null, 512)
369
368
  ])
370
- ], 2)) : A("", !0),
369
+ ], 2)) : $("", !0),
371
370
  n("div", {
372
371
  class: "main-content-outer",
373
372
  ref_key: "containerRef",
374
- ref: se
373
+ ref: ue
375
374
  }, [
376
- n("div", Ze, [
377
- ae(t.$slots, "main", {}, void 0, !0)
375
+ n("div", ot, [
376
+ le(e.$slots, "main", {}, void 0, !0)
378
377
  ]),
379
- V.value && v.value === "" ? (D(), F("div", {
378
+ Y.value && h.value === "" ? (S(), D("div", {
380
379
  key: 0,
381
380
  ref_key: "dragWindowRef",
382
- ref: le,
383
- class: "draggable-window",
384
- style: Te(Le.value)
381
+ ref: de,
382
+ class: J(["draggable-window", { "draggable-window-shadow": !l.value || x.value }]),
383
+ style: ke(Me.value),
384
+ onMouseenter: Ie,
385
+ onMouseleave: Pe
385
386
  }, [
386
387
  n("div", {
387
- class: "window-header",
388
- onMousedown: We
388
+ class: J(["window-header", { "window-header-opacity": l.value && !x.value }]),
389
+ onMousedown: De
389
390
  }, [
390
- n("div", et, [
391
- n("span", tt, ne($.windowTitle), 1),
392
- n("div", nt, [
393
- f(n("button", ot, "未连接", 512), [
394
- [w, !c.value && !h.value]
391
+ n("div", it, [
392
+ n("span", at, ae(V.windowTitle), 1),
393
+ n("div", st, [
394
+ w(n("button", lt, "未连接", 512), [
395
+ [g, !l.value && !f.value]
395
396
  ]),
396
- f(n("button", at, "连接中...", 512), [
397
- [w, h.value]
397
+ w(n("button", ct, "连接中...", 512), [
398
+ [g, f.value]
398
399
  ]),
399
- f(n("button", it, "已连接", 512), [
400
- [w, c.value]
400
+ w(n("button", dt, "已连接", 512), [
401
+ [g, l.value]
401
402
  ])
402
403
  ])
403
404
  ]),
404
405
  n("div", {
405
406
  class: "drag-window-hide",
406
- onClick: e[3] || (e[3] = (l) => B(!1)),
407
- onMousedown: e[4] || (e[4] = oe(() => {
407
+ onClick: t[3] || (t[3] = (a) => j(!1)),
408
+ onMousedown: t[4] || (t[4] = se(() => {
408
409
  }, ["stop"]))
409
410
  }, null, 32)
410
- ], 32),
411
- n("div", lt, [
411
+ ], 34),
412
+ n("div", ut, [
412
413
  n("div", {
413
414
  class: "video-container",
414
415
  ref_key: "windowVideoRef",
415
- ref: ce
416
+ ref: re
416
417
  }, null, 512)
417
418
  ])
418
- ], 4)) : A("", !0)
419
+ ], 38)) : $("", !0)
419
420
  ], 512),
420
- V.value && v.value === "right" ? (D(), F("div", {
421
+ Y.value && h.value === "right" ? (S(), D("div", {
421
422
  key: 1,
422
- class: ke(["sidebar right-sidebar", { pressing: R.value }])
423
+ class: J(["sidebar right-sidebar", { pressing: R.value }])
423
424
  }, [
424
425
  n("div", {
425
426
  class: "window-header",
426
- onMousedown: e[7] || (e[7] = (l) => me("right", l)),
427
- onMouseup: j,
428
- onMouseleave: j
427
+ onMousedown: t[7] || (t[7] = (a) => ye("right", a)),
428
+ onMouseup: F,
429
+ onMouseleave: F
429
430
  }, [
430
- n("div", st, [
431
- n("span", ct, ne($.windowTitle), 1),
432
- n("div", dt, [
433
- f(n("button", ut, "未连接", 512), [
434
- [w, !c.value && !h.value]
431
+ n("div", rt, [
432
+ n("span", vt, ae(V.windowTitle), 1),
433
+ n("div", ft, [
434
+ w(n("button", ht, "未连接", 512), [
435
+ [g, !l.value && !f.value]
435
436
  ]),
436
- f(n("button", rt, "连接中...", 512), [
437
- [w, h.value]
437
+ w(n("button", wt, "连接中...", 512), [
438
+ [g, f.value]
438
439
  ]),
439
- f(n("button", vt, "已连接", 512), [
440
- [w, c.value]
440
+ w(n("button", gt, "已连接", 512), [
441
+ [g, l.value]
441
442
  ])
442
443
  ])
443
444
  ]),
444
445
  n("div", {
445
446
  class: "drag-window-hide",
446
- onClick: e[5] || (e[5] = (l) => B(!1)),
447
- onMousedown: e[6] || (e[6] = oe(() => {
447
+ onClick: t[5] || (t[5] = (a) => j(!1)),
448
+ onMousedown: t[6] || (t[6] = se(() => {
448
449
  }, ["stop"]))
449
450
  }, null, 32)
450
451
  ], 32),
451
- n("div", ht, [
452
- ae(t.$slots, "sidebar-right", {}, void 0, !0),
452
+ n("div", mt, [
453
+ le(e.$slots, "sidebar-right", {}, void 0, !0),
453
454
  n("div", {
454
455
  ref_key: "sidebarRightVideoRef",
455
- ref: ue,
456
+ ref: fe,
456
457
  class: "sidebar-video-container"
457
458
  }, null, 512)
458
459
  ])
459
- ], 2)) : A("", !0),
460
- E.value ? (D(), Be(Oe, {
460
+ ], 2)) : $("", !0),
461
+ E.value ? (S(), Ge(ze, {
461
462
  key: 2,
462
- to: ve()
463
+ to: we()
463
464
  }, [
464
465
  n("video", {
465
466
  ref_key: "digitalHumanVideo",
466
- ref: u,
467
+ ref: s,
467
468
  class: "digital-video source-video",
468
469
  poster: "",
469
470
  playsinline: "",
@@ -471,14 +472,15 @@ const Ue = { class: "digital-human-assistant" }, ze = { class: "placeholder left
471
472
  }, null, 512),
472
473
  n("canvas", {
473
474
  ref_key: "processedCanvas",
474
- ref: a,
475
+ ref: o,
475
476
  class: "digital-video processed-canvas"
476
- }, null, 512)
477
- ], 8, ["to"])) : A("", !0)
477
+ }, null, 512),
478
+ f.value ? (S(), D("div", pt)) : $("", !0)
479
+ ], 8, ["to"])) : $("", !0)
478
480
  ], 4);
479
481
  };
480
482
  }
481
483
  });
482
484
  export {
483
- bt as default
485
+ Tt as default
484
486
  };