@streamoji/aitwin 0.3.0 → 0.3.3
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/aitwin.cjs +3 -3
- package/dist/aitwin.js +1549 -1406
- package/dist/index.d.ts +51 -0
- package/package.json +1 -1
package/dist/aitwin.js
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { forwardRef as
|
|
3
|
-
import { PipecatClient as
|
|
4
|
-
import { WebSocketTransport as
|
|
5
|
-
const
|
|
6
|
-
publicBase:
|
|
7
|
-
},
|
|
8
|
-
version:
|
|
9
|
-
},
|
|
10
|
-
function
|
|
1
|
+
import { jsxs as Kn, jsx as zt } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as jn, useRef as P, useState as Qe, useEffect as Me, useCallback as he, useMemo as Qt, useImperativeHandle as Gn } from "react";
|
|
3
|
+
import { PipecatClient as zn } from "@pipecat-ai/client-js";
|
|
4
|
+
import { WebSocketTransport as Qn, DailyMediaManager as Yn, ProtobufFrameSerializer as Jn } from "@pipecat-ai/websocket-transport";
|
|
5
|
+
const Xn = "https://pub-607ad1fc22e2400eb57d17240aab857c.r2.dev", _n = {
|
|
6
|
+
publicBase: Xn
|
|
7
|
+
}, Zn = "0.3.3", er = {
|
|
8
|
+
version: Zn
|
|
9
|
+
}, tr = {}, tt = "https://ai.aitwin.me", xt = `${_n.publicBase}/custom-faces`, nr = `${_n.publicBase}/aitwin-workers/v${er.version}/visemeDiffPreview.worker.js`;
|
|
10
|
+
function rr(e) {
|
|
11
11
|
if (e) return e;
|
|
12
|
-
const t = typeof import.meta < "u" ?
|
|
13
|
-
return t?.trim() ? t.trim() :
|
|
14
|
-
}
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
]),
|
|
19
|
-
[
|
|
20
|
-
[
|
|
21
|
-
[
|
|
22
|
-
},
|
|
23
|
-
google:
|
|
24
|
-
inworld:
|
|
25
|
-
cartesia:
|
|
12
|
+
const t = typeof import.meta < "u" ? tr?.VITE_AITWIN_WORKER_URL : void 0;
|
|
13
|
+
return t?.trim() ? t.trim() : nr;
|
|
14
|
+
}
|
|
15
|
+
const sr = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin", yn = "eng_a7f2b9c1", Pt = "eng_d4e8f3a2", Ne = "eng_c9b1e6d4", Le = Ne, Sn = /* @__PURE__ */ new Set([
|
|
16
|
+
Pt,
|
|
17
|
+
Ne
|
|
18
|
+
]), kn = {
|
|
19
|
+
[yn]: "oculus_direct",
|
|
20
|
+
[Ne]: "oculus_direct",
|
|
21
|
+
[Pt]: "inworld_word"
|
|
22
|
+
}, Yt = {
|
|
23
|
+
google: yn,
|
|
24
|
+
inworld: Pt,
|
|
25
|
+
cartesia: Ne
|
|
26
26
|
};
|
|
27
|
-
function
|
|
28
|
-
return
|
|
27
|
+
function ir(e) {
|
|
28
|
+
return kn[e];
|
|
29
29
|
}
|
|
30
|
-
function
|
|
31
|
-
return e ===
|
|
30
|
+
function ar(e) {
|
|
31
|
+
return e === Ne;
|
|
32
32
|
}
|
|
33
|
-
function
|
|
34
|
-
if (e.ttsEngineId && e.ttsEngineId in
|
|
33
|
+
function or(e) {
|
|
34
|
+
if (e.ttsEngineId && e.ttsEngineId in kn)
|
|
35
35
|
return e.ttsEngineId;
|
|
36
36
|
const t = e.tts?.toLowerCase();
|
|
37
|
-
return t && t in
|
|
37
|
+
return t && t in Yt ? Yt[t] : Le;
|
|
38
38
|
}
|
|
39
|
-
class
|
|
39
|
+
class Tt extends Error {
|
|
40
40
|
constructor(t = "AI twin not found") {
|
|
41
41
|
super(t), this.name = "AiTwinNotFoundError";
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
async function
|
|
44
|
+
async function cr(e, t = sr) {
|
|
45
45
|
const n = new URL(t);
|
|
46
46
|
n.searchParams.set("id", e);
|
|
47
47
|
const r = await fetch(n.toString());
|
|
48
48
|
if (r.status === 404)
|
|
49
|
-
throw new
|
|
49
|
+
throw new Tt();
|
|
50
50
|
if (!r.ok)
|
|
51
51
|
throw new Error(`getAiTwin failed (${r.status})`);
|
|
52
52
|
const s = await r.json();
|
|
53
53
|
if (!s.success)
|
|
54
|
-
throw new
|
|
55
|
-
const { tts: i, token: o, ...a } = s.data,
|
|
54
|
+
throw new Tt(s.error ?? "AI twin not found");
|
|
55
|
+
const { tts: i, token: o, ...a } = s.data, l = String(a.authToken ?? o ?? "").trim() || void 0;
|
|
56
56
|
return {
|
|
57
57
|
...a,
|
|
58
|
-
ttsEngineId:
|
|
59
|
-
authToken:
|
|
58
|
+
ttsEngineId: or(s.data),
|
|
59
|
+
authToken: l
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
|
-
const
|
|
63
|
-
async function
|
|
64
|
-
const e = await fetch(
|
|
62
|
+
const ur = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken", lr = "client_6TNvp3SCs4Og0a1ijm9TommXLql1", fr = "kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1", dr = "6TNvp3SCs4Og0a1ijm9TommXLql1", mr = "Swaraj Mali";
|
|
63
|
+
async function kt() {
|
|
64
|
+
const e = await fetch(ur, {
|
|
65
65
|
method: "POST",
|
|
66
66
|
headers: {
|
|
67
67
|
"Content-Type": "application/json",
|
|
68
|
-
"Client-Id":
|
|
69
|
-
"Client-Secret":
|
|
68
|
+
"Client-Id": lr,
|
|
69
|
+
"Client-Secret": fr
|
|
70
70
|
},
|
|
71
71
|
body: JSON.stringify({
|
|
72
|
-
userId:
|
|
73
|
-
userName:
|
|
72
|
+
userId: dr,
|
|
73
|
+
userName: mr
|
|
74
74
|
})
|
|
75
75
|
});
|
|
76
76
|
if (!e.ok)
|
|
@@ -80,7 +80,7 @@ async function gt() {
|
|
|
80
80
|
throw new Error("getAuthToken returned no token");
|
|
81
81
|
return n;
|
|
82
82
|
}
|
|
83
|
-
async function
|
|
83
|
+
async function hr(e, t = tt) {
|
|
84
84
|
const n = await fetch(`${t.replace(/\/$/, "")}/api/session-value`, {
|
|
85
85
|
headers: { Authorization: `Bearer ${e}` }
|
|
86
86
|
});
|
|
@@ -90,7 +90,7 @@ async function er(e, t = Je) {
|
|
|
90
90
|
if (!r.value) throw new Error("Session value response missing value");
|
|
91
91
|
return r;
|
|
92
92
|
}
|
|
93
|
-
function
|
|
93
|
+
function wr(e) {
|
|
94
94
|
const t = e.trim();
|
|
95
95
|
if (t.length % 2 !== 0) throw new Error("Invalid hex key");
|
|
96
96
|
const n = new Uint8Array(t.length / 2);
|
|
@@ -98,20 +98,20 @@ function tr(e) {
|
|
|
98
98
|
n[r / 2] = Number.parseInt(t.slice(r, r + 2), 16);
|
|
99
99
|
return n;
|
|
100
100
|
}
|
|
101
|
-
function
|
|
101
|
+
function it(e) {
|
|
102
102
|
return Uint8Array.from(e);
|
|
103
103
|
}
|
|
104
|
-
function
|
|
104
|
+
function gr(e, t) {
|
|
105
105
|
const n = new Uint8Array(e.length + t.length);
|
|
106
106
|
return n.set(e, 0), n.set(t, e.length), n;
|
|
107
107
|
}
|
|
108
|
-
async function
|
|
108
|
+
async function pr(e, t) {
|
|
109
109
|
if (!t) throw new Error("Asset key is required for encrypted assets");
|
|
110
110
|
if (e.byteLength < 28)
|
|
111
111
|
throw new Error("Encrypted payload too small");
|
|
112
|
-
const n = new Uint8Array(e), r =
|
|
112
|
+
const n = new Uint8Array(e), r = it(n.subarray(0, 12)), s = it(n.subarray(12, 28)), i = it(n.subarray(28)), o = it(gr(i, s)), a = await crypto.subtle.importKey(
|
|
113
113
|
"raw",
|
|
114
|
-
|
|
114
|
+
wr(t),
|
|
115
115
|
{ name: "AES-GCM" },
|
|
116
116
|
!1,
|
|
117
117
|
["decrypt"]
|
|
@@ -122,35 +122,35 @@ async function rr(e, t) {
|
|
|
122
122
|
o
|
|
123
123
|
);
|
|
124
124
|
}
|
|
125
|
-
let
|
|
126
|
-
const
|
|
127
|
-
function
|
|
125
|
+
let At = null;
|
|
126
|
+
const It = /* @__PURE__ */ new Set();
|
|
127
|
+
function at(e) {
|
|
128
128
|
return e.includes("/custom-faces/");
|
|
129
129
|
}
|
|
130
|
-
function
|
|
130
|
+
function ut(e) {
|
|
131
131
|
const t = e.binBase.trim().replace(/\/$/, ""), n = e.twinBase.trim().replace(/\/$/, "");
|
|
132
|
-
if (!(e.encrypted ||
|
|
132
|
+
if (!(e.encrypted || at(t) || at(n)))
|
|
133
133
|
return { twinBase: n, binBase: t, encrypted: !1 };
|
|
134
|
-
const s =
|
|
134
|
+
const s = at(t) ? t : at(n) ? n : t;
|
|
135
135
|
return { twinBase: s, binBase: s, encrypted: !0 };
|
|
136
136
|
}
|
|
137
|
-
function
|
|
138
|
-
return
|
|
137
|
+
function Ve(e) {
|
|
138
|
+
return ut(e).encrypted;
|
|
139
139
|
}
|
|
140
|
-
function
|
|
140
|
+
function Jt(e, t = xt) {
|
|
141
141
|
const n = `${t.replace(/\/$/, "")}/${e}`;
|
|
142
142
|
return { twinBase: n, binBase: n, encrypted: !0 };
|
|
143
143
|
}
|
|
144
|
-
function
|
|
144
|
+
function _r(e, t) {
|
|
145
145
|
return (e ?? t)?.trim() || void 0;
|
|
146
146
|
}
|
|
147
|
-
function
|
|
148
|
-
|
|
149
|
-
for (const t of
|
|
147
|
+
function yr(e) {
|
|
148
|
+
At = ut(e);
|
|
149
|
+
for (const t of It) t();
|
|
150
150
|
}
|
|
151
|
-
function
|
|
151
|
+
function Sr(e, t) {
|
|
152
152
|
const n = typeof globalThis.location < "u" ? globalThis.location.href : void 0;
|
|
153
|
-
if (!n) return
|
|
153
|
+
if (!n) return ut(e);
|
|
154
154
|
const r = (s) => {
|
|
155
155
|
try {
|
|
156
156
|
return new URL(s, n).href.replace(/\/$/, "");
|
|
@@ -158,44 +158,44 @@ function ar(e, t) {
|
|
|
158
158
|
return s;
|
|
159
159
|
}
|
|
160
160
|
};
|
|
161
|
-
return
|
|
161
|
+
return ut({
|
|
162
162
|
twinBase: r(e.twinBase),
|
|
163
163
|
binBase: r(e.binBase),
|
|
164
164
|
encrypted: e.encrypted
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
|
-
function
|
|
168
|
-
if (!
|
|
167
|
+
function Pe() {
|
|
168
|
+
if (!At)
|
|
169
169
|
throw new Error("Twin assets not configured; call setActiveTwinAssets first");
|
|
170
|
-
return
|
|
170
|
+
return At;
|
|
171
171
|
}
|
|
172
|
-
function
|
|
173
|
-
return
|
|
172
|
+
function kr(e) {
|
|
173
|
+
return It.add(e), () => It.delete(e);
|
|
174
174
|
}
|
|
175
|
-
function
|
|
176
|
-
const e =
|
|
177
|
-
return
|
|
175
|
+
function Xt() {
|
|
176
|
+
const e = Pe();
|
|
177
|
+
return Ve(e) ? `${e.binBase}/sil.bin` : `${e.twinBase}/sil.png`;
|
|
178
178
|
}
|
|
179
|
-
function
|
|
180
|
-
const e =
|
|
181
|
-
return
|
|
179
|
+
function vr() {
|
|
180
|
+
const e = Pe();
|
|
181
|
+
return Ve(e) ? `${e.binBase}/idle.bin` : `${e.twinBase}/idle.mp4`;
|
|
182
182
|
}
|
|
183
|
-
function
|
|
184
|
-
const e =
|
|
185
|
-
return
|
|
183
|
+
function Er() {
|
|
184
|
+
const e = Pe();
|
|
185
|
+
return Ve(e) ? e.binBase : e.twinBase;
|
|
186
186
|
}
|
|
187
|
-
function
|
|
188
|
-
return
|
|
187
|
+
function mt() {
|
|
188
|
+
return Ve(Pe());
|
|
189
189
|
}
|
|
190
|
-
function
|
|
191
|
-
const e =
|
|
192
|
-
return
|
|
190
|
+
function br() {
|
|
191
|
+
const e = Pe();
|
|
192
|
+
return Ve(e) ? `${e.binBase}/atlas.bin` : `${e.twinBase}/atlas.json`;
|
|
193
193
|
}
|
|
194
|
-
function
|
|
195
|
-
const e =
|
|
196
|
-
return
|
|
194
|
+
function Tr() {
|
|
195
|
+
const e = Pe();
|
|
196
|
+
return Ve(e) ? `${e.binBase}/expression_atlas.bin` : `${e.twinBase}/expression_atlas.json`;
|
|
197
197
|
}
|
|
198
|
-
function
|
|
198
|
+
function vn(e) {
|
|
199
199
|
const t = e.split(/\r?\n/);
|
|
200
200
|
let n = "", r = "";
|
|
201
201
|
for (const i of t)
|
|
@@ -210,7 +210,7 @@ function un(e) {
|
|
|
210
210
|
}
|
|
211
211
|
return { event: n, data: s };
|
|
212
212
|
}
|
|
213
|
-
const
|
|
213
|
+
const Ar = [
|
|
214
214
|
"aa",
|
|
215
215
|
"CH",
|
|
216
216
|
"DD",
|
|
@@ -226,14 +226,14 @@ const dr = [
|
|
|
226
226
|
"kk",
|
|
227
227
|
"nn",
|
|
228
228
|
"sil"
|
|
229
|
-
],
|
|
230
|
-
|
|
229
|
+
], Ir = new Map(
|
|
230
|
+
Ar.map((e) => [e.toLowerCase(), e])
|
|
231
231
|
);
|
|
232
|
-
function
|
|
232
|
+
function Rr(e) {
|
|
233
233
|
const t = (e ?? "").trim();
|
|
234
|
-
return t ?
|
|
234
|
+
return t ? Ir.get(t.toLowerCase()) ?? "sil" : "sil";
|
|
235
235
|
}
|
|
236
|
-
const
|
|
236
|
+
const Dr = {
|
|
237
237
|
aei: ["aa", "E", "I"],
|
|
238
238
|
o: ["O", "U"],
|
|
239
239
|
ee: ["I"],
|
|
@@ -245,12 +245,12 @@ const wr = {
|
|
|
245
245
|
qw: ["U", "O"],
|
|
246
246
|
cdgknstxyz: ["DD", "SS", "kk", "CH"]
|
|
247
247
|
};
|
|
248
|
-
function
|
|
248
|
+
function Mr(e) {
|
|
249
249
|
if (!e) return ["sil"];
|
|
250
250
|
const t = e.toLowerCase();
|
|
251
|
-
return
|
|
251
|
+
return Dr[t] ?? ["sil"];
|
|
252
252
|
}
|
|
253
|
-
function
|
|
253
|
+
function Cr(e, t) {
|
|
254
254
|
const n = e.word.length;
|
|
255
255
|
if (n <= 0) return 0;
|
|
256
256
|
const r = e.wduration;
|
|
@@ -258,33 +258,40 @@ function _r(e, t) {
|
|
|
258
258
|
const s = Math.max(0, Math.min(1, (t - e.wtime) / r));
|
|
259
259
|
return Math.min(n - 1, Math.floor(s * n));
|
|
260
260
|
}
|
|
261
|
-
function
|
|
261
|
+
function Ue(e, t) {
|
|
262
262
|
const n = Math.max(0, Math.min(e.length - 1, t));
|
|
263
263
|
return e[n] ?? "";
|
|
264
264
|
}
|
|
265
|
-
function
|
|
266
|
-
const n = e.toLowerCase()
|
|
265
|
+
function Ft(e, t) {
|
|
266
|
+
const n = e.toLowerCase().replace(/[^a-z']/g, "");
|
|
267
|
+
return !n || Ue(n, t) !== "w" || t > 0 && Ue(n, t - 1) === "q" ? !1 : t === 0 && /^w[aeiouy]/.test(n);
|
|
268
|
+
}
|
|
269
|
+
function xr(e, t) {
|
|
270
|
+
const n = e.toLowerCase(), r = Ue(n, t), s = n.slice(Math.max(0, t - 1), t + 2);
|
|
267
271
|
return r === "i" || r === "y" ? "I" : s.includes("ee") || r === "e" || n.includes("ea") ? "E" : "aa";
|
|
268
272
|
}
|
|
269
|
-
function
|
|
273
|
+
function Pr(e, t) {
|
|
270
274
|
const n = e.toLowerCase(), r = n.slice(
|
|
271
275
|
Math.max(0, t - 1),
|
|
272
276
|
Math.min(n.length, t + 3)
|
|
273
277
|
);
|
|
274
278
|
if (/oo|ou|uw/.test(r)) return "U";
|
|
275
|
-
|
|
279
|
+
if (Ft(n, t)) return "FF";
|
|
280
|
+
const s = Ue(n, t);
|
|
276
281
|
return s === "u" || s === "w" ? "U" : "O";
|
|
277
282
|
}
|
|
278
|
-
function
|
|
279
|
-
const n = e.toLowerCase()
|
|
283
|
+
function Fr(e, t) {
|
|
284
|
+
const n = e.toLowerCase();
|
|
285
|
+
if (Ft(n, t)) return "FF";
|
|
286
|
+
const r = n.slice(Math.max(0, t - 2), t + 1);
|
|
280
287
|
if (/qu/.test(r)) return "U";
|
|
281
288
|
const s = n.slice(
|
|
282
289
|
Math.max(0, t - 1),
|
|
283
290
|
Math.min(n.length, t + 3)
|
|
284
291
|
);
|
|
285
|
-
return /wo|wh/.test(s) ||
|
|
292
|
+
return /wo|wh/.test(s) || Ue(n, t) === "o" ? "O" : "U";
|
|
286
293
|
}
|
|
287
|
-
const
|
|
294
|
+
const ot = {
|
|
288
295
|
d: "DD",
|
|
289
296
|
t: "DD",
|
|
290
297
|
n: "DD",
|
|
@@ -296,50 +303,50 @@ const nt = {
|
|
|
296
303
|
x: "CH",
|
|
297
304
|
j: "CH"
|
|
298
305
|
};
|
|
299
|
-
function
|
|
300
|
-
const n = e.toLowerCase(), r =
|
|
301
|
-
if (
|
|
306
|
+
function Br(e, t) {
|
|
307
|
+
const n = e.toLowerCase(), r = Ue(n, t);
|
|
308
|
+
if (ot[r]) return ot[r];
|
|
302
309
|
for (let s = 0; s < n.length; s++) {
|
|
303
310
|
const i = n[s];
|
|
304
|
-
if (
|
|
311
|
+
if (ot[i]) return ot[i];
|
|
305
312
|
}
|
|
306
313
|
return "DD";
|
|
307
314
|
}
|
|
308
|
-
function
|
|
309
|
-
const r =
|
|
315
|
+
function Or(e, t, n) {
|
|
316
|
+
const r = Mr(e);
|
|
310
317
|
if (r.length === 1) return r[0];
|
|
311
318
|
const s = t.trim();
|
|
312
319
|
if (!s) return r[0];
|
|
313
320
|
const i = (e ?? "").toLowerCase(), o = Math.max(0, n);
|
|
314
321
|
switch (i) {
|
|
315
322
|
case "aei":
|
|
316
|
-
return
|
|
323
|
+
return xr(s, o);
|
|
317
324
|
case "o":
|
|
318
|
-
return
|
|
325
|
+
return Pr(s, o);
|
|
319
326
|
case "qw":
|
|
320
|
-
return
|
|
327
|
+
return Fr(s, o);
|
|
321
328
|
case "cdgknstxyz":
|
|
322
|
-
return
|
|
329
|
+
return Br(s, o);
|
|
323
330
|
default:
|
|
324
331
|
return r[0];
|
|
325
332
|
}
|
|
326
333
|
}
|
|
327
|
-
const
|
|
328
|
-
function
|
|
334
|
+
const Bt = 16e3;
|
|
335
|
+
function En(e) {
|
|
329
336
|
const t = Number(e);
|
|
330
|
-
return Number.isFinite(t) && t > 0 ? t :
|
|
337
|
+
return Number.isFinite(t) && t > 0 ? t : Bt;
|
|
331
338
|
}
|
|
332
|
-
function
|
|
339
|
+
function Lr(e) {
|
|
333
340
|
let t = e.trim();
|
|
334
341
|
const n = t.indexOf(",");
|
|
335
342
|
t.startsWith("data:") && n >= 0 && (t = t.slice(n + 1)), t = t.replace(/\s+/g, "").replace(/-/g, "+").replace(/_/g, "/");
|
|
336
343
|
const r = t.length % 4;
|
|
337
344
|
return r !== 0 && (t += "=".repeat(4 - r)), t;
|
|
338
345
|
}
|
|
339
|
-
function
|
|
346
|
+
function Ur(e) {
|
|
340
347
|
return e.length >= 4 && e[0] === 82 && e[1] === 73 && e[2] === 70 && e[3] === 70;
|
|
341
348
|
}
|
|
342
|
-
function
|
|
349
|
+
function Zt(e, t, n = Bt) {
|
|
343
350
|
const r = t.byteOffset % 2 === 0 ? t : t.slice(), s = new Int16Array(
|
|
344
351
|
r.buffer,
|
|
345
352
|
r.byteOffset,
|
|
@@ -350,15 +357,15 @@ function Wt(e, t, n = Dt) {
|
|
|
350
357
|
const o = e.createBuffer(1, i.length, n);
|
|
351
358
|
return o.copyToChannel(i, 0), o;
|
|
352
359
|
}
|
|
353
|
-
function
|
|
354
|
-
const t =
|
|
360
|
+
function Nr(e) {
|
|
361
|
+
const t = Lr(e), n = window.atob(t), r = new Uint8Array(n.length);
|
|
355
362
|
for (let s = 0; s < n.length; s++)
|
|
356
363
|
r[s] = n.charCodeAt(s);
|
|
357
364
|
return r;
|
|
358
365
|
}
|
|
359
|
-
async function
|
|
360
|
-
const r =
|
|
361
|
-
if (
|
|
366
|
+
async function Vr(e, t, n = Bt) {
|
|
367
|
+
const r = Nr(t), s = En(n);
|
|
368
|
+
if (Ur(r)) {
|
|
362
369
|
const i = r.buffer.slice(
|
|
363
370
|
r.byteOffset,
|
|
364
371
|
r.byteOffset + r.byteLength
|
|
@@ -366,7 +373,7 @@ async function Ar(e, t, n = Dt) {
|
|
|
366
373
|
return e.decodeAudioData(i);
|
|
367
374
|
}
|
|
368
375
|
if (r.length >= 2 && r.length % 2 === 0)
|
|
369
|
-
return
|
|
376
|
+
return Zt(e, r, s);
|
|
370
377
|
try {
|
|
371
378
|
const i = r.buffer.slice(
|
|
372
379
|
r.byteOffset,
|
|
@@ -374,256 +381,250 @@ async function Ar(e, t, n = Dt) {
|
|
|
374
381
|
);
|
|
375
382
|
return await e.decodeAudioData(i);
|
|
376
383
|
} catch {
|
|
377
|
-
return
|
|
384
|
+
return Zt(e, r, s);
|
|
378
385
|
}
|
|
379
386
|
}
|
|
380
|
-
function
|
|
387
|
+
function Ye(e) {
|
|
381
388
|
let t = 0;
|
|
382
389
|
for (const n of e)
|
|
383
390
|
t = Math.max(t, n.vtime + n.vduration);
|
|
384
391
|
return t;
|
|
385
392
|
}
|
|
386
|
-
function
|
|
393
|
+
function $r(e, t) {
|
|
387
394
|
for (const n of e)
|
|
388
395
|
if (t >= n.wtime && t < n.wtime + n.wduration)
|
|
389
396
|
return n;
|
|
390
397
|
return null;
|
|
391
398
|
}
|
|
392
|
-
function
|
|
399
|
+
function bn(e, t) {
|
|
393
400
|
const n = [], r = [];
|
|
394
|
-
let s = null, i = !1, o = !1, a = !1,
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
},
|
|
398
|
-
for (const
|
|
401
|
+
let s = null, i = !1, o = !1, a = !1, l = !1, f = 0, u = 0, _ = 0, m = 0, p = null, v = 1, d = t, y = !1, h = null, E = 0;
|
|
402
|
+
const b = () => {
|
|
403
|
+
p != null && (clearTimeout(p), p = null);
|
|
404
|
+
}, V = () => {
|
|
405
|
+
for (const g of r) {
|
|
399
406
|
try {
|
|
400
|
-
|
|
407
|
+
g.onended = null, g.stop(0);
|
|
401
408
|
} catch {
|
|
402
409
|
}
|
|
403
410
|
try {
|
|
404
|
-
|
|
411
|
+
g.disconnect();
|
|
405
412
|
} catch {
|
|
406
413
|
}
|
|
407
414
|
}
|
|
408
415
|
r.length = 0;
|
|
409
|
-
},
|
|
410
|
-
for (const
|
|
411
|
-
|
|
412
|
-
},
|
|
413
|
-
if (!(
|
|
414
|
-
if (a && s &&
|
|
415
|
-
const
|
|
416
|
-
if (
|
|
417
|
-
|
|
418
|
-
const D =
|
|
419
|
-
|
|
420
|
-
|
|
416
|
+
}, Q = () => {
|
|
417
|
+
for (const g of r)
|
|
418
|
+
g.playbackRate.value = v;
|
|
419
|
+
}, N = () => {
|
|
420
|
+
if (!(y || !l || i || r.length > 0 || n.length > 0)) {
|
|
421
|
+
if (a && s && u > 0) {
|
|
422
|
+
const g = (s.currentTime - u) * 1e3;
|
|
423
|
+
if (g < E) {
|
|
424
|
+
b();
|
|
425
|
+
const D = v > 0 ? (E - g) / v : E - g;
|
|
426
|
+
p = setTimeout(() => {
|
|
427
|
+
y || (o = !1, p = null, e.onSpeakingDone(), e.onNotify());
|
|
421
428
|
}, Math.max(0, D));
|
|
422
429
|
return;
|
|
423
430
|
}
|
|
424
431
|
}
|
|
425
|
-
o = !1,
|
|
432
|
+
o = !1, b(), e.onSpeakingDone(), e.onNotify();
|
|
426
433
|
}
|
|
427
|
-
}, G = (
|
|
428
|
-
const D =
|
|
434
|
+
}, G = (g) => {
|
|
435
|
+
const D = Ye(g);
|
|
429
436
|
if (D <= 0) {
|
|
430
437
|
e.onSpeakingDone(), e.onNotify();
|
|
431
438
|
return;
|
|
432
439
|
}
|
|
433
|
-
o = !0,
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
},
|
|
438
|
-
},
|
|
439
|
-
D.length !== 0 && (
|
|
440
|
-
const
|
|
441
|
-
if (!
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
word:
|
|
445
|
-
wtime:
|
|
446
|
-
wduration:
|
|
447
|
-
queueIndex:
|
|
440
|
+
o = !0, f = performance.now(), e.onSpeakingStart(), e.onNotify(), b();
|
|
441
|
+
const L = v > 0 ? D / v : D;
|
|
442
|
+
p = setTimeout(() => {
|
|
443
|
+
y || (o = !1, p = null, e.onSpeakingDone(), e.onNotify());
|
|
444
|
+
}, L);
|
|
445
|
+
}, Z = (g, D, L, F) => {
|
|
446
|
+
D.length !== 0 && (F && (_ = L), D.forEach((T) => {
|
|
447
|
+
const z = String(T.word ?? "").trim();
|
|
448
|
+
if (!z) return;
|
|
449
|
+
const ee = Math.round((T.start ?? 0) * 1e3), se = T.duration != null ? Math.round(T.duration * 1e3) : T.end != null ? Math.max(1, Math.round((T.end - (T.start ?? 0)) * 1e3)) : 0;
|
|
450
|
+
g.push({
|
|
451
|
+
word: z,
|
|
452
|
+
wtime: _ + ee,
|
|
453
|
+
wduration: se,
|
|
454
|
+
queueIndex: g.length,
|
|
448
455
|
gesture: T.gesture ?? null,
|
|
449
456
|
emphasis: T.emphasis === !0
|
|
450
457
|
});
|
|
451
458
|
}));
|
|
452
|
-
},
|
|
453
|
-
|
|
454
|
-
const
|
|
455
|
-
if (!
|
|
456
|
-
const
|
|
457
|
-
let
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
oe?.word ?? "",
|
|
465
|
-
ee
|
|
466
|
-
);
|
|
467
|
-
}
|
|
468
|
-
m.push({
|
|
469
|
-
viseme: fe,
|
|
459
|
+
}, S = (g, D, L, F, T, $) => {
|
|
460
|
+
L.length !== 0 && (T && (_ = F), L.forEach((z) => {
|
|
461
|
+
const ee = String(z.symbol ?? z.viseme ?? "").trim();
|
|
462
|
+
if (!ee) return;
|
|
463
|
+
const se = Math.round((z.start ?? 0) * 1e3), O = Math.max(1, Math.round((z.duration ?? 0) * 1e3)), K = _ + se, ae = $r(D, K), de = ae ? Cr(ae, K) : 0;
|
|
464
|
+
let X;
|
|
465
|
+
ir($) === "oculus_direct" ? (X = Rr(ee), X === "U" && ae && Ft(ae.word, de) && (X = "FF")) : X = Or(
|
|
466
|
+
ee,
|
|
467
|
+
ae?.word ?? "",
|
|
468
|
+
de
|
|
469
|
+
), g.push({
|
|
470
|
+
viseme: X,
|
|
470
471
|
weight: 1,
|
|
471
|
-
vtime:
|
|
472
|
-
vduration:
|
|
472
|
+
vtime: K,
|
|
473
|
+
vduration: O
|
|
473
474
|
});
|
|
474
475
|
}), e.onNotify());
|
|
475
|
-
}, A = (
|
|
476
|
-
|
|
477
|
-
|
|
476
|
+
}, A = (g, D, L, F, T, $, z) => {
|
|
477
|
+
Z(D, F, T, $), S(
|
|
478
|
+
g,
|
|
478
479
|
D,
|
|
479
|
-
|
|
480
|
+
L,
|
|
480
481
|
T,
|
|
481
|
-
|
|
482
|
-
|
|
482
|
+
$,
|
|
483
|
+
z
|
|
483
484
|
);
|
|
484
|
-
},
|
|
485
|
-
if (
|
|
485
|
+
}, M = async (g, D, L, F, T, $, z) => {
|
|
486
|
+
if (y || !L?.trim())
|
|
486
487
|
return;
|
|
487
|
-
const
|
|
488
|
+
const ee = En(z?.sampleRate), se = z?.newStream === !0;
|
|
488
489
|
if (i) {
|
|
489
490
|
n.push({
|
|
490
|
-
audio:
|
|
491
|
-
visemes:
|
|
491
|
+
audio: L,
|
|
492
|
+
visemes: F,
|
|
492
493
|
words: T,
|
|
493
|
-
isNewSegment:
|
|
494
|
-
sampleRate:
|
|
495
|
-
newStream:
|
|
494
|
+
isNewSegment: $,
|
|
495
|
+
sampleRate: ee,
|
|
496
|
+
newStream: se
|
|
496
497
|
});
|
|
497
498
|
return;
|
|
498
499
|
}
|
|
499
500
|
i = !0;
|
|
500
501
|
try {
|
|
501
|
-
const
|
|
502
|
-
s || (s = new
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
502
|
+
const O = window.AudioContext || window.webkitAudioContext;
|
|
503
|
+
s || (s = new O());
|
|
504
|
+
const K = s;
|
|
505
|
+
K.state === "suspended" && await K.resume(), h || (h = K.createMediaStreamDestination());
|
|
506
|
+
const ae = await Vr(
|
|
507
|
+
K,
|
|
508
|
+
L,
|
|
509
|
+
ee
|
|
509
510
|
);
|
|
510
511
|
a = !0;
|
|
511
|
-
const
|
|
512
|
-
let
|
|
513
|
-
const
|
|
514
|
-
|
|
515
|
-
const
|
|
516
|
-
if (
|
|
512
|
+
const de = K.currentTime;
|
|
513
|
+
let X = m;
|
|
514
|
+
const ge = !o;
|
|
515
|
+
X < de && (X = de + 0.1), m = X + ae.duration;
|
|
516
|
+
const te = K.createBufferSource();
|
|
517
|
+
if (te.buffer = ae, te.playbackRate.value = v, te.connect(K.destination), h && te.connect(h), r.push(te), y) {
|
|
517
518
|
r.pop();
|
|
518
519
|
return;
|
|
519
520
|
}
|
|
520
|
-
if (
|
|
521
|
-
o = !0, e.onSpeakingStart(),
|
|
522
|
-
const
|
|
523
|
-
|
|
521
|
+
if (ge) {
|
|
522
|
+
o = !0, e.onSpeakingStart(), se ? (u = X, _ = 0, E = 0, g.length = 0, D.length = 0, z?.onNewStream?.()) : u <= 0 && (u = X);
|
|
523
|
+
const ye = (X - de) * 1e3;
|
|
524
|
+
f = performance.now() + ye;
|
|
524
525
|
}
|
|
525
|
-
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
},
|
|
529
|
-
const
|
|
526
|
+
te.onended = () => {
|
|
527
|
+
const ye = r.indexOf(te);
|
|
528
|
+
ye >= 0 && r.splice(ye, 1), N(), e.onNotify();
|
|
529
|
+
}, te.start(X);
|
|
530
|
+
const Fe = (X - u) * 1e3;
|
|
530
531
|
A(
|
|
531
|
-
|
|
532
|
+
g,
|
|
532
533
|
D,
|
|
533
|
-
|
|
534
|
+
F,
|
|
534
535
|
T,
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
),
|
|
539
|
-
} catch (
|
|
540
|
-
console.error("[avatarChunkPlayback] audio chunk failed:",
|
|
536
|
+
Fe,
|
|
537
|
+
$,
|
|
538
|
+
d
|
|
539
|
+
), E = Math.max(E, Ye(g));
|
|
540
|
+
} catch (O) {
|
|
541
|
+
console.error("[avatarChunkPlayback] audio chunk failed:", O);
|
|
541
542
|
} finally {
|
|
542
|
-
if (i = !1,
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
|
|
543
|
+
if (i = !1, y) return;
|
|
544
|
+
const O = n.shift();
|
|
545
|
+
O ? await M(
|
|
546
|
+
g,
|
|
546
547
|
D,
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
548
|
+
O.audio,
|
|
549
|
+
O.visemes,
|
|
550
|
+
O.words,
|
|
551
|
+
O.isNewSegment,
|
|
551
552
|
{
|
|
552
|
-
sampleRate:
|
|
553
|
-
newStream:
|
|
554
|
-
onNewStream:
|
|
553
|
+
sampleRate: O.sampleRate,
|
|
554
|
+
newStream: O.newStream,
|
|
555
|
+
onNewStream: z?.onNewStream
|
|
555
556
|
}
|
|
556
|
-
) :
|
|
557
|
+
) : N();
|
|
557
558
|
}
|
|
558
559
|
};
|
|
559
560
|
return {
|
|
560
|
-
setStreamTtsEngineId: (
|
|
561
|
-
|
|
561
|
+
setStreamTtsEngineId: (g) => {
|
|
562
|
+
d = g;
|
|
562
563
|
},
|
|
563
|
-
setPlaybackSpeed: (
|
|
564
|
-
|
|
564
|
+
setPlaybackSpeed: (g) => {
|
|
565
|
+
v = Math.max(0.1, Math.min(1, g)), Q();
|
|
565
566
|
},
|
|
566
|
-
getPlaybackSpeed: () =>
|
|
567
|
-
resetForNewStream: (
|
|
568
|
-
|
|
567
|
+
getPlaybackSpeed: () => v,
|
|
568
|
+
resetForNewStream: (g) => {
|
|
569
|
+
y = !1, l = !1, d = g, E = 0;
|
|
569
570
|
},
|
|
570
571
|
/** Next sentence in the same bot turn — keep viseme tail, allow more chunks. */
|
|
571
572
|
resumeBotStream: () => {
|
|
572
|
-
|
|
573
|
+
l = !1;
|
|
573
574
|
},
|
|
574
575
|
/** Call from a user gesture before bot audio (connect / unlock). */
|
|
575
576
|
primeAudioContext: async () => {
|
|
576
|
-
const
|
|
577
|
-
s || (s = new
|
|
577
|
+
const g = window.AudioContext || window.webkitAudioContext;
|
|
578
|
+
s || (s = new g()), s.state === "suspended" && await s.resume(), s && !h && (h = s.createMediaStreamDestination());
|
|
578
579
|
},
|
|
579
580
|
stop: () => {
|
|
580
|
-
|
|
581
|
+
y = !0, b(), V(), n.length = 0, i = !1, o = !1, a = !1, l = !1, _ = 0, m = 0, u = 0, f = 0, E = 0;
|
|
581
582
|
},
|
|
582
|
-
markStreamComplete: (
|
|
583
|
-
if (
|
|
584
|
-
G(
|
|
583
|
+
markStreamComplete: (g) => {
|
|
584
|
+
if (E = Math.max(E, Ye(g)), l = !0, !a && g.length > 0) {
|
|
585
|
+
G(g);
|
|
585
586
|
return;
|
|
586
587
|
}
|
|
587
|
-
|
|
588
|
+
N();
|
|
588
589
|
},
|
|
589
|
-
playAudioChunk:
|
|
590
|
-
queueTimingsOnly: (
|
|
591
|
-
if (
|
|
592
|
-
let
|
|
593
|
-
T &&
|
|
594
|
-
|
|
590
|
+
playAudioChunk: M,
|
|
591
|
+
queueTimingsOnly: (g, D, L, F, T) => {
|
|
592
|
+
if (y) return;
|
|
593
|
+
let $ = _;
|
|
594
|
+
T && g.length > 0 && ($ = Ye(g)), A(
|
|
595
|
+
g,
|
|
595
596
|
D,
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
597
|
+
L,
|
|
598
|
+
F,
|
|
599
|
+
$,
|
|
599
600
|
T,
|
|
600
|
-
|
|
601
|
-
),
|
|
601
|
+
d
|
|
602
|
+
), E = Math.max(E, Ye(g));
|
|
602
603
|
},
|
|
603
|
-
getPlaybackElapsedMs: () => a && s &&
|
|
604
|
+
getPlaybackElapsedMs: () => a && s && u > 0 ? Math.max(
|
|
604
605
|
0,
|
|
605
|
-
(s.currentTime -
|
|
606
|
-
) : o ? Math.max(0, (performance.now() -
|
|
607
|
-
isSpeaking: () => o ? !0 : !a || !s ||
|
|
608
|
-
getVoiceStream: () =>
|
|
609
|
-
getPlaybackStartPerf: () =>
|
|
606
|
+
(s.currentTime - u) * 1e3
|
|
607
|
+
) : o ? Math.max(0, (performance.now() - f) * v) : 0,
|
|
608
|
+
isSpeaking: () => o ? !0 : !a || !s || u <= 0 ? !1 : (s.currentTime - u) * 1e3 < E,
|
|
609
|
+
getVoiceStream: () => h ? h.stream : null,
|
|
610
|
+
getPlaybackStartPerf: () => f,
|
|
610
611
|
/** User spoke over the bot — drop in-flight chunks until the next utterance. */
|
|
611
612
|
bargeIn: () => {
|
|
612
|
-
|
|
613
|
+
y = !0, l = !1, b(), V(), n.length = 0, i = !1, o = !1, a = !1, _ = 0, m = 0, u = 0, f = 0, E = 0;
|
|
613
614
|
},
|
|
614
615
|
interrupt: () => {
|
|
615
|
-
|
|
616
|
+
y = !0, l = !1, b(), V(), n.length = 0, i = !1, o = !1, a = !1, _ = 0, m = 0, u = 0, f = 0, E = 0;
|
|
616
617
|
}
|
|
617
618
|
};
|
|
618
619
|
}
|
|
619
|
-
function
|
|
620
|
+
function ht(e, t) {
|
|
620
621
|
let n = null;
|
|
621
622
|
for (const r of e)
|
|
622
623
|
t < r.vtime || t >= r.vtime + r.vduration || (!n || r.vtime >= n.vtime) && (n = r);
|
|
623
624
|
return n ? n.viseme : "sil";
|
|
624
625
|
}
|
|
625
|
-
function
|
|
626
|
-
const r =
|
|
626
|
+
function Wr(e, t, n = 120) {
|
|
627
|
+
const r = ht(e, t);
|
|
627
628
|
if (r !== "sil") return r;
|
|
628
629
|
let s = null;
|
|
629
630
|
for (const i of e) {
|
|
@@ -633,95 +634,95 @@ function Rr(e, t, n = 120) {
|
|
|
633
634
|
}
|
|
634
635
|
return s?.viseme ?? "sil";
|
|
635
636
|
}
|
|
636
|
-
function
|
|
637
|
+
function yi(e, t) {
|
|
637
638
|
for (const n of e)
|
|
638
639
|
if (t >= n.wtime && t < n.wtime + n.wduration)
|
|
639
640
|
return n;
|
|
640
641
|
return null;
|
|
641
642
|
}
|
|
642
|
-
const
|
|
643
|
-
function
|
|
643
|
+
const Ot = 0.5, Lt = 1.5, Tn = "Olivia", An = "f786b574-daa5-4673-aa0c-cbe3e8534c02", wt = 0.85;
|
|
644
|
+
function en(e, t = tt) {
|
|
644
645
|
const n = `${t.replace(/\/$/, "")}/avatar_ttsWithPoses`, r = [], s = [], i = [];
|
|
645
|
-
let o = "neutral", a = "",
|
|
646
|
-
const
|
|
646
|
+
let o = "neutral", a = "", l = Le;
|
|
647
|
+
const f = /* @__PURE__ */ new Set(), u = () => f.forEach((v) => v()), _ = bn(
|
|
647
648
|
{
|
|
648
649
|
onSpeakingStart: () => e("speaking"),
|
|
649
650
|
onSpeakingDone: () => e("done"),
|
|
650
|
-
onNotify:
|
|
651
|
+
onNotify: u
|
|
651
652
|
},
|
|
652
653
|
Le
|
|
653
|
-
),
|
|
654
|
-
|
|
654
|
+
), m = () => {
|
|
655
|
+
_.stop(), r.length = 0, s.length = 0, i.length = 0, o = "neutral", e("idle"), u();
|
|
655
656
|
};
|
|
656
657
|
return {
|
|
657
|
-
setDeveloperToken: (
|
|
658
|
-
a =
|
|
658
|
+
setDeveloperToken: (v) => {
|
|
659
|
+
a = v;
|
|
659
660
|
},
|
|
660
|
-
setTtsEngineId: (
|
|
661
|
-
|
|
661
|
+
setTtsEngineId: (v) => {
|
|
662
|
+
l = v;
|
|
662
663
|
},
|
|
663
|
-
getTtsEngineId: () =>
|
|
664
|
-
speak: async (
|
|
665
|
-
|
|
666
|
-
const
|
|
667
|
-
if (!
|
|
664
|
+
getTtsEngineId: () => l,
|
|
665
|
+
speak: async (v, d) => {
|
|
666
|
+
m(), e("loading");
|
|
667
|
+
const y = a.trim();
|
|
668
|
+
if (!y)
|
|
668
669
|
throw new Error("Developer token required for avatar_ttsWithPoses");
|
|
669
|
-
const
|
|
670
|
-
|
|
671
|
-
const
|
|
672
|
-
|
|
673
|
-
Math.min(
|
|
674
|
-
),
|
|
675
|
-
user_query:
|
|
676
|
-
ttsEngineId:
|
|
677
|
-
speakingRate:
|
|
670
|
+
const h = d?.ttsEngineId ?? l ?? Le;
|
|
671
|
+
_.resetForNewStream(h), _.setStreamTtsEngineId(h);
|
|
672
|
+
const E = d?.voiceId ?? Tn, b = d?.speakingRate ?? wt, V = Math.max(
|
|
673
|
+
Ot,
|
|
674
|
+
Math.min(Lt, b)
|
|
675
|
+
), Q = {
|
|
676
|
+
user_query: v,
|
|
677
|
+
ttsEngineId: h,
|
|
678
|
+
speakingRate: V,
|
|
678
679
|
tenant: "aiTwin"
|
|
679
680
|
};
|
|
680
|
-
|
|
681
|
+
Sn.has(h) && (Q.voice_id = E);
|
|
681
682
|
try {
|
|
682
|
-
const
|
|
683
|
+
const N = await fetch(n, {
|
|
683
684
|
method: "POST",
|
|
684
685
|
headers: {
|
|
685
686
|
"Content-Type": "application/json",
|
|
686
|
-
Authorization: `Bearer ${
|
|
687
|
+
Authorization: `Bearer ${y}`
|
|
687
688
|
},
|
|
688
|
-
body: JSON.stringify(
|
|
689
|
+
body: JSON.stringify(Q)
|
|
689
690
|
});
|
|
690
|
-
if (!
|
|
691
|
-
throw new Error(`avatar_ttsWithPoses failed (${
|
|
692
|
-
const G =
|
|
691
|
+
if (!N.ok)
|
|
692
|
+
throw new Error(`avatar_ttsWithPoses failed (${N.status})`);
|
|
693
|
+
const G = N.body;
|
|
693
694
|
if (!G) throw new Error("No response body");
|
|
694
|
-
const
|
|
695
|
+
const Z = G.getReader(), S = new TextDecoder();
|
|
695
696
|
let A = "";
|
|
696
|
-
const
|
|
697
|
-
const
|
|
698
|
-
if (
|
|
699
|
-
if (
|
|
700
|
-
const D =
|
|
701
|
-
D ? await
|
|
697
|
+
const M = async (I) => {
|
|
698
|
+
const g = vn(I);
|
|
699
|
+
if (g) {
|
|
700
|
+
if (g.event === "audio") {
|
|
701
|
+
const D = g.data.chunk, L = g.data.visemes ?? [], F = g.data.words ?? [], T = g.data.is_new_segment ?? !1, $ = g.data.sample_rate;
|
|
702
|
+
D ? await _.playAudioChunk(
|
|
702
703
|
r,
|
|
703
704
|
s,
|
|
704
705
|
D,
|
|
705
|
-
|
|
706
|
-
|
|
706
|
+
L,
|
|
707
|
+
F,
|
|
707
708
|
T,
|
|
708
|
-
{ sampleRate:
|
|
709
|
-
) : (
|
|
709
|
+
{ sampleRate: $ }
|
|
710
|
+
) : (L.length > 0 || F.length > 0) && _.queueTimingsOnly(
|
|
710
711
|
r,
|
|
711
712
|
s,
|
|
712
|
-
|
|
713
|
-
|
|
713
|
+
L,
|
|
714
|
+
F,
|
|
714
715
|
T
|
|
715
716
|
);
|
|
716
|
-
} else if (
|
|
717
|
-
const D =
|
|
717
|
+
} else if (g.event === "metadata") {
|
|
718
|
+
const D = g.data.mood;
|
|
718
719
|
typeof D == "string" && D.trim() && (o = D.trim());
|
|
719
|
-
const
|
|
720
|
-
if (Array.isArray(
|
|
720
|
+
const L = g.data.sentence_emotions;
|
|
721
|
+
if (Array.isArray(L)) {
|
|
721
722
|
i.length = 0;
|
|
722
|
-
for (const
|
|
723
|
-
if (!
|
|
724
|
-
const T =
|
|
723
|
+
for (const F of L) {
|
|
724
|
+
if (!F || typeof F != "object") continue;
|
|
725
|
+
const T = F;
|
|
725
726
|
i.push({
|
|
726
727
|
sentence_index: Number(T.sentence_index ?? 0),
|
|
727
728
|
text: String(T.text ?? ""),
|
|
@@ -732,47 +733,47 @@ function Ht(e, t = Je) {
|
|
|
732
733
|
});
|
|
733
734
|
}
|
|
734
735
|
}
|
|
735
|
-
|
|
736
|
-
} else if (
|
|
736
|
+
u();
|
|
737
|
+
} else if (g.event === "error")
|
|
737
738
|
throw new Error(
|
|
738
|
-
String(
|
|
739
|
+
String(g.data.message ?? "avatar_ttsWithPoses stream error")
|
|
739
740
|
);
|
|
740
741
|
}
|
|
741
742
|
};
|
|
742
743
|
for (; ; ) {
|
|
743
|
-
const { done:
|
|
744
|
-
|
|
744
|
+
const { done: I, value: g } = await Z.read();
|
|
745
|
+
g && (A += S.decode(g, { stream: !0 }));
|
|
745
746
|
const D = A.split(`
|
|
746
747
|
|
|
747
748
|
`);
|
|
748
749
|
A = D.pop() ?? "";
|
|
749
|
-
for (const
|
|
750
|
-
if (
|
|
751
|
-
A.trim() && await
|
|
750
|
+
for (const L of D) await M(L);
|
|
751
|
+
if (I) {
|
|
752
|
+
A.trim() && await M(A.trim()), _.markStreamComplete(r);
|
|
752
753
|
break;
|
|
753
754
|
}
|
|
754
755
|
}
|
|
755
|
-
} catch (
|
|
756
|
-
throw console.error("[avatarTtsLipsync]",
|
|
756
|
+
} catch (N) {
|
|
757
|
+
throw console.error("[avatarTtsLipsync]", N), m(), e("error"), N;
|
|
757
758
|
}
|
|
758
759
|
},
|
|
759
|
-
stop:
|
|
760
|
+
stop: m,
|
|
760
761
|
getVisemeQueue: () => r,
|
|
761
762
|
getWordQueue: () => s,
|
|
762
763
|
getSentenceEmotions: () => i,
|
|
763
764
|
getStreamMood: () => o,
|
|
764
|
-
getPlaybackElapsedMs: () =>
|
|
765
|
-
isSpeaking: () =>
|
|
766
|
-
getVoiceStream: () =>
|
|
767
|
-
setPlaybackSpeed: (
|
|
768
|
-
|
|
765
|
+
getPlaybackElapsedMs: () => _.getPlaybackElapsedMs(),
|
|
766
|
+
isSpeaking: () => _.isSpeaking(),
|
|
767
|
+
getVoiceStream: () => _.getVoiceStream(),
|
|
768
|
+
setPlaybackSpeed: (v) => {
|
|
769
|
+
_.setPlaybackSpeed(v);
|
|
769
770
|
},
|
|
770
|
-
getPlaybackSpeed: () =>
|
|
771
|
-
subscribe: (
|
|
771
|
+
getPlaybackSpeed: () => _.getPlaybackSpeed(),
|
|
772
|
+
subscribe: (v) => (f.add(v), () => f.delete(v))
|
|
772
773
|
};
|
|
773
774
|
}
|
|
774
|
-
const
|
|
775
|
-
class
|
|
775
|
+
const In = 16e3, Rn = 16e3;
|
|
776
|
+
class qr extends Jn {
|
|
776
777
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
777
778
|
async deserialize(t) {
|
|
778
779
|
try {
|
|
@@ -784,7 +785,7 @@ class Dr extends Ln {
|
|
|
784
785
|
}
|
|
785
786
|
}
|
|
786
787
|
}
|
|
787
|
-
class
|
|
788
|
+
class Hr extends Yn {
|
|
788
789
|
constructor() {
|
|
789
790
|
super(
|
|
790
791
|
!0,
|
|
@@ -792,42 +793,42 @@ class xr extends On {
|
|
|
792
793
|
void 0,
|
|
793
794
|
void 0,
|
|
794
795
|
512,
|
|
795
|
-
|
|
796
|
-
|
|
796
|
+
In,
|
|
797
|
+
Rn
|
|
797
798
|
);
|
|
798
799
|
}
|
|
799
800
|
/** Pipecat protobuf bot audio is unused — playback comes from avatar_audio_chunk. */
|
|
800
801
|
bufferBotAudio(t, n) {
|
|
801
802
|
}
|
|
802
803
|
}
|
|
803
|
-
const
|
|
804
|
-
function
|
|
805
|
-
return
|
|
804
|
+
const Kr = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
805
|
+
function jr(e) {
|
|
806
|
+
return Kr.test(e.trim());
|
|
806
807
|
}
|
|
807
|
-
function
|
|
808
|
+
function Gr(e) {
|
|
808
809
|
const t = e.replace(/\/$/, "");
|
|
809
810
|
return t.startsWith("https://") ? `wss://${t.slice(8)}` : t.startsWith("http://") ? `ws://${t.slice(7)}` : t;
|
|
810
811
|
}
|
|
811
|
-
function
|
|
812
|
+
function zr(e) {
|
|
812
813
|
if (e.wsUrl?.trim()) return e.wsUrl.trim();
|
|
813
814
|
const t = e.authToken?.trim();
|
|
814
815
|
if (!t)
|
|
815
816
|
throw new Error(
|
|
816
817
|
"Voice connect requires authToken (same JWT as SSE Authorization Bearer)."
|
|
817
818
|
);
|
|
818
|
-
const n = e.apiBase ??
|
|
819
|
+
const n = e.apiBase ?? tt, r = new URL(`${Gr(n)}/ws/voice`);
|
|
819
820
|
r.searchParams.set("authToken", t), r.searchParams.set("tenant", "aiTwin");
|
|
820
821
|
const s = e.voiceId?.trim();
|
|
821
|
-
s &&
|
|
822
|
+
s && jr(s) && r.searchParams.set("voiceId", s);
|
|
822
823
|
const i = e.personaId?.trim();
|
|
823
824
|
i && r.searchParams.set("personaId", i);
|
|
824
|
-
const o = e.speakingRate ??
|
|
825
|
+
const o = e.speakingRate ?? wt;
|
|
825
826
|
return r.searchParams.set(
|
|
826
827
|
"speaking_rate",
|
|
827
|
-
String(Math.max(
|
|
828
|
+
String(Math.max(Ot, Math.min(Lt, o)))
|
|
828
829
|
), e.ttsStream === !1 ? r.searchParams.set("tts_stream", "false") : r.searchParams.set("tts_stream", "true"), r.toString();
|
|
829
830
|
}
|
|
830
|
-
function
|
|
831
|
+
function vt(e, t) {
|
|
831
832
|
if (!Array.isArray(e)) return [];
|
|
832
833
|
const n = [];
|
|
833
834
|
for (const r of e)
|
|
@@ -841,7 +842,7 @@ function _t(e, t) {
|
|
|
841
842
|
});
|
|
842
843
|
return n;
|
|
843
844
|
}
|
|
844
|
-
function
|
|
845
|
+
function Qr(e) {
|
|
845
846
|
if (!e || typeof e != "object") return null;
|
|
846
847
|
const t = e, r = (t.data && typeof t.data == "object" && !Array.isArray(t.data) ? t.data : null) || t;
|
|
847
848
|
return {
|
|
@@ -849,406 +850,406 @@ function Fr(e) {
|
|
|
849
850
|
type: String(r.type ?? t.type ?? "server-message")
|
|
850
851
|
};
|
|
851
852
|
}
|
|
852
|
-
function
|
|
853
|
+
function Et(e) {
|
|
853
854
|
return e.is_new_segment === !0 || Number(e.audio_offset_ms ?? -1) === 0 ? !0 : Number(e.chunk_index ?? -1) === 0;
|
|
854
855
|
}
|
|
855
|
-
function
|
|
856
|
+
function Yr(e) {
|
|
856
857
|
return e?.transport?._mediaManager?._wavStreamPlayer ?? null;
|
|
857
858
|
}
|
|
858
|
-
function
|
|
859
|
+
function Jr(e, t = {}) {
|
|
859
860
|
const n = [], r = [], s = [], i = [];
|
|
860
|
-
let o = "", a = "neutral",
|
|
861
|
-
const
|
|
862
|
-
let
|
|
863
|
-
const
|
|
864
|
-
let
|
|
861
|
+
let o = "", a = "neutral", l = Ne, f = !1, u = null, _ = null, m = { ...t }, p = 0, v = null;
|
|
862
|
+
const d = /* @__PURE__ */ new Set(), y = [];
|
|
863
|
+
let h = !1, E = null, b = !0, V = "default";
|
|
864
|
+
const Q = /* @__PURE__ */ new Set();
|
|
865
|
+
let N = null, G = 0, Z = !1, S = null;
|
|
865
866
|
const A = () => {
|
|
866
|
-
|
|
867
|
-
},
|
|
867
|
+
S != null && (clearTimeout(S), S = null);
|
|
868
|
+
}, M = () => d.forEach((c) => c()), I = bn(
|
|
868
869
|
{
|
|
869
870
|
onSpeakingStart: () => e("speaking"),
|
|
870
871
|
onSpeakingDone: () => e("done"),
|
|
871
|
-
onNotify:
|
|
872
|
+
onNotify: M
|
|
872
873
|
},
|
|
873
|
-
|
|
874
|
-
),
|
|
875
|
-
if (
|
|
874
|
+
l
|
|
875
|
+
), g = () => {
|
|
876
|
+
if (E) return E;
|
|
876
877
|
const c = new MessageChannel();
|
|
877
878
|
return c.port1.onmessage = () => {
|
|
878
|
-
const
|
|
879
|
-
|
|
880
|
-
},
|
|
879
|
+
const k = y.shift();
|
|
880
|
+
k !== void 0 && $e(k), y.length > 0 ? c.port2.postMessage(null) : h = !1;
|
|
881
|
+
}, E = c, c;
|
|
881
882
|
}, D = (c) => {
|
|
882
|
-
|
|
883
|
-
},
|
|
884
|
-
if (!
|
|
885
|
-
const
|
|
886
|
-
|
|
883
|
+
y.push(c), !h && (h = !0, g().port2.postMessage(null));
|
|
884
|
+
}, L = () => I.getPlaybackElapsedMs(), F = (c, k = o) => {
|
|
885
|
+
if (!m.onLipsyncDebug) return;
|
|
886
|
+
const x = L(), j = n;
|
|
887
|
+
m.onLipsyncDebug({
|
|
887
888
|
event: c,
|
|
888
|
-
spokenText:
|
|
889
|
+
spokenText: k,
|
|
889
890
|
mood: a,
|
|
890
|
-
playbackAnchorPerf:
|
|
891
|
-
playbackElapsedMs:
|
|
892
|
-
queueLength:
|
|
893
|
-
activeViseme:
|
|
894
|
-
segments: i.map((
|
|
895
|
-
...
|
|
896
|
-
visemes: [...
|
|
891
|
+
playbackAnchorPerf: I.getPlaybackStartPerf(),
|
|
892
|
+
playbackElapsedMs: x,
|
|
893
|
+
queueLength: j.length,
|
|
894
|
+
activeViseme: ht(j, x),
|
|
895
|
+
segments: i.map((ne) => ({
|
|
896
|
+
...ne,
|
|
897
|
+
visemes: [...ne.visemes]
|
|
897
898
|
}))
|
|
898
899
|
});
|
|
899
|
-
}, T = (c,
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
const
|
|
903
|
-
|
|
900
|
+
}, T = (c, k) => {
|
|
901
|
+
m.onLipsyncDebug && (v = { event: c, spokenText: k }, p === 0 && (p = requestAnimationFrame(() => {
|
|
902
|
+
p = 0;
|
|
903
|
+
const x = v;
|
|
904
|
+
v = null, x && F(x.event, x.spokenText);
|
|
904
905
|
})));
|
|
905
|
-
},
|
|
906
|
-
|
|
907
|
-
},
|
|
908
|
-
const c =
|
|
906
|
+
}, $ = () => {
|
|
907
|
+
b = !0, Q.clear();
|
|
908
|
+
}, z = () => {
|
|
909
|
+
const c = Yr(u);
|
|
909
910
|
if (c) {
|
|
910
|
-
|
|
911
|
+
V = `bot-${Date.now()}`, c.interruptedTrackIds = { [V]: !0 };
|
|
911
912
|
try {
|
|
912
913
|
c.interrupt?.();
|
|
913
914
|
} catch {
|
|
914
915
|
}
|
|
915
916
|
}
|
|
916
|
-
const
|
|
917
|
+
const k = _;
|
|
917
918
|
try {
|
|
918
|
-
|
|
919
|
+
k?.interrupt?.();
|
|
919
920
|
} catch {
|
|
920
921
|
}
|
|
921
|
-
},
|
|
922
|
-
const
|
|
923
|
-
return
|
|
924
|
-
},
|
|
925
|
-
|
|
926
|
-
const
|
|
927
|
-
|
|
928
|
-
},
|
|
922
|
+
}, ee = (c) => {
|
|
923
|
+
const k = c.context_id?.trim();
|
|
924
|
+
return k && Q.has(k) ? !0 : b ? !1 : !(c.type === "avatar_metadata" || Et(c));
|
|
925
|
+
}, se = (c) => {
|
|
926
|
+
b = !1;
|
|
927
|
+
const k = c.context_id?.trim();
|
|
928
|
+
k && Q.add(k), A(), Z = !1, y.length = 0, h = !1, N?.abort(), N = null, G += 1, z(), I.bargeIn(), O(), e("idle"), T("interrupt"), M();
|
|
929
|
+
}, O = () => {
|
|
929
930
|
n.length = 0, r.length = 0, i.length = 0, o = "", a = "neutral", s.length = 0;
|
|
930
|
-
},
|
|
931
|
-
|
|
932
|
-
},
|
|
933
|
-
|
|
934
|
-
},
|
|
935
|
-
typeof c.mood == "string" && c.mood.trim() && (a = c.mood.trim()), Array.isArray(c.sentence_emotions) && c.sentence_emotions.length > 0 && (
|
|
936
|
-
...
|
|
931
|
+
}, K = () => {
|
|
932
|
+
I.stop(), O(), T("reset"), M();
|
|
933
|
+
}, ae = () => {
|
|
934
|
+
K(), e("idle"), M();
|
|
935
|
+
}, de = (c, k) => {
|
|
936
|
+
typeof c.mood == "string" && c.mood.trim() && (a = c.mood.trim()), Array.isArray(c.sentence_emotions) && c.sentence_emotions.length > 0 && (k && (s.length = 0), s.push(
|
|
937
|
+
...vt(c.sentence_emotions, a)
|
|
937
938
|
));
|
|
938
|
-
},
|
|
939
|
-
if (
|
|
939
|
+
}, X = (c) => {
|
|
940
|
+
if (ee({ ...c, type: "avatar_metadata" }))
|
|
940
941
|
return;
|
|
941
|
-
|
|
942
|
-
const
|
|
943
|
-
|
|
944
|
-
...
|
|
945
|
-
), Array.isArray(c.gestures) && c.gestures, T("metadata",
|
|
946
|
-
},
|
|
947
|
-
if (!
|
|
948
|
-
const
|
|
949
|
-
(
|
|
942
|
+
$(), Z = !0;
|
|
943
|
+
const k = String(c.spoken_text ?? c.text ?? "").trim();
|
|
944
|
+
k && (o = k), I.resetForNewStream(l), typeof c.mood == "string" && c.mood.trim() && (a = c.mood.trim()), s.length = 0, s.push(
|
|
945
|
+
...vt(c.sentence_emotions, a)
|
|
946
|
+
), Array.isArray(c.gestures) && c.gestures, T("metadata", k), M();
|
|
947
|
+
}, ge = (c, k, x, j) => {
|
|
948
|
+
if (!m.onLipsyncDebug) return;
|
|
949
|
+
const ne = n.slice(x), ke = j.filter(
|
|
950
|
+
(ie) => String(ie.symbol ?? ie.viseme ?? "").trim()
|
|
950
951
|
);
|
|
951
952
|
i.push({
|
|
952
|
-
spokenText:
|
|
953
|
-
audioOffsetMs:
|
|
953
|
+
spokenText: k,
|
|
954
|
+
audioOffsetMs: ne[0]?.vtime ?? 0,
|
|
954
955
|
isNewSegment: !!c.is_new_segment,
|
|
955
956
|
chunkDurationMs: c.chunk_duration_ms != null ? Number(c.chunk_duration_ms) : null,
|
|
956
957
|
receivedAtMs: performance.now(),
|
|
957
|
-
visemes:
|
|
958
|
-
const
|
|
958
|
+
visemes: ne.map((ie, Y) => {
|
|
959
|
+
const pe = ke[Y];
|
|
959
960
|
return {
|
|
960
|
-
rawSymbol: String(
|
|
961
|
-
viseme:
|
|
962
|
-
startSec: Number(
|
|
963
|
-
durationSec: Number(
|
|
964
|
-
vtimeMs:
|
|
965
|
-
vdurationMs:
|
|
961
|
+
rawSymbol: String(pe?.symbol ?? pe?.viseme ?? ie.viseme).trim(),
|
|
962
|
+
viseme: ie.viseme,
|
|
963
|
+
startSec: Number(pe?.start ?? 0),
|
|
964
|
+
durationSec: Number(pe?.duration ?? 0),
|
|
965
|
+
vtimeMs: ie.vtime,
|
|
966
|
+
vdurationMs: ie.vduration
|
|
966
967
|
};
|
|
967
968
|
})
|
|
968
969
|
});
|
|
969
|
-
},
|
|
970
|
-
if (
|
|
971
|
-
A(),
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
const
|
|
975
|
-
|
|
970
|
+
}, te = (c) => {
|
|
971
|
+
if (ee(c)) return;
|
|
972
|
+
A(), Et(c) && $();
|
|
973
|
+
const k = String(c.spoken_text ?? c.text ?? "").trim(), x = Et(c), j = c.visemes ?? [], ne = c.words ?? [], ke = String(c.chunk ?? "").trim(), ie = Z;
|
|
974
|
+
ie && (Z = !1), k && (o = k), de(c, x), ie ? I.resetForNewStream(l) : x && I.resumeBotStream();
|
|
975
|
+
const Y = n.length;
|
|
976
|
+
I.playAudioChunk(
|
|
976
977
|
n,
|
|
977
978
|
r,
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
979
|
+
ke,
|
|
980
|
+
j,
|
|
981
|
+
ne,
|
|
982
|
+
x,
|
|
982
983
|
{
|
|
983
984
|
sampleRate: c.sample_rate,
|
|
984
|
-
newStream:
|
|
985
|
+
newStream: ie,
|
|
985
986
|
onNewStream: () => {
|
|
986
987
|
i.length = 0;
|
|
987
988
|
}
|
|
988
989
|
}
|
|
989
990
|
).then(() => {
|
|
990
|
-
|
|
991
|
+
ge(c, k, Y, j), T("audio_chunk", k);
|
|
991
992
|
});
|
|
992
|
-
},
|
|
993
|
-
if (
|
|
994
|
-
(c.is_new_segment || Number(c.audio_offset_ms ?? -1) === 0) &&
|
|
993
|
+
}, Fe = (c) => {
|
|
994
|
+
if (ee(c)) return;
|
|
995
|
+
(c.is_new_segment || Number(c.audio_offset_ms ?? -1) === 0) && $(), console.warn(
|
|
995
996
|
"[realtimeVoice] avatar_lipsync is deprecated — expect avatar_audio_chunk"
|
|
996
997
|
);
|
|
997
|
-
const
|
|
998
|
-
|
|
999
|
-
const
|
|
1000
|
-
|
|
998
|
+
const k = String(c.spoken_text ?? c.text ?? "").trim();
|
|
999
|
+
k && (o = k), de(c, !!c.is_new_segment);
|
|
1000
|
+
const x = n.length;
|
|
1001
|
+
I.queueTimingsOnly(
|
|
1001
1002
|
n,
|
|
1002
1003
|
r,
|
|
1003
1004
|
c.visemes ?? [],
|
|
1004
1005
|
c.words ?? [],
|
|
1005
1006
|
!!c.is_new_segment
|
|
1006
|
-
),
|
|
1007
|
+
), ge(
|
|
1007
1008
|
c,
|
|
1008
|
-
|
|
1009
|
-
|
|
1009
|
+
k,
|
|
1010
|
+
x,
|
|
1010
1011
|
c.visemes ?? []
|
|
1011
|
-
), T("lipsync",
|
|
1012
|
-
},
|
|
1013
|
-
const
|
|
1014
|
-
if (!
|
|
1015
|
-
const
|
|
1016
|
-
if (!
|
|
1012
|
+
), T("lipsync", k), M();
|
|
1013
|
+
}, ye = async (c) => {
|
|
1014
|
+
const k = String(c.text ?? "").trim();
|
|
1015
|
+
if (!k) return;
|
|
1016
|
+
const x = m.authToken?.trim();
|
|
1017
|
+
if (!x) {
|
|
1017
1018
|
console.error("[realtimeVoice] avatar_speak requires authToken");
|
|
1018
1019
|
return;
|
|
1019
1020
|
}
|
|
1020
|
-
|
|
1021
|
-
const
|
|
1022
|
-
|
|
1023
|
-
const
|
|
1024
|
-
|
|
1025
|
-
const
|
|
1026
|
-
|
|
1027
|
-
Math.min(
|
|
1028
|
-
),
|
|
1029
|
-
user_query:
|
|
1030
|
-
ttsEngineId:
|
|
1031
|
-
speakingRate:
|
|
1021
|
+
N?.abort();
|
|
1022
|
+
const j = new AbortController();
|
|
1023
|
+
N = j;
|
|
1024
|
+
const ne = ++G;
|
|
1025
|
+
$(), I.resetForNewStream(l), o = k;
|
|
1026
|
+
const ie = `${(m.apiBase ?? tt).replace(/\/$/, "")}/avatar_ttsWithPoses`, Y = m.voiceId?.trim() || An, pe = m.speakingRate ?? wt, rt = Math.max(
|
|
1027
|
+
Ot,
|
|
1028
|
+
Math.min(Lt, pe)
|
|
1029
|
+
), qe = {
|
|
1030
|
+
user_query: k,
|
|
1031
|
+
ttsEngineId: l,
|
|
1032
|
+
speakingRate: rt,
|
|
1032
1033
|
tenant: "aiTwin"
|
|
1033
1034
|
};
|
|
1034
|
-
|
|
1035
|
+
Sn.has(l) && (qe.voice_id = Y);
|
|
1035
1036
|
try {
|
|
1036
|
-
const
|
|
1037
|
+
const ve = await fetch(ie, {
|
|
1037
1038
|
method: "POST",
|
|
1038
1039
|
headers: {
|
|
1039
1040
|
"Content-Type": "application/json",
|
|
1040
|
-
Authorization: `Bearer ${
|
|
1041
|
+
Authorization: `Bearer ${x}`
|
|
1041
1042
|
},
|
|
1042
|
-
body: JSON.stringify(
|
|
1043
|
-
signal:
|
|
1043
|
+
body: JSON.stringify(qe),
|
|
1044
|
+
signal: j.signal
|
|
1044
1045
|
});
|
|
1045
|
-
if (
|
|
1046
|
-
throw new Error(`avatar_ttsWithPoses failed (${
|
|
1047
|
-
const
|
|
1048
|
-
if (!
|
|
1049
|
-
const
|
|
1050
|
-
let
|
|
1051
|
-
const
|
|
1052
|
-
if (
|
|
1046
|
+
if (!ve.ok)
|
|
1047
|
+
throw new Error(`avatar_ttsWithPoses failed (${ve.status})`);
|
|
1048
|
+
const He = ve.body;
|
|
1049
|
+
if (!He) throw new Error("No response body");
|
|
1050
|
+
const Ie = He.getReader(), st = new TextDecoder();
|
|
1051
|
+
let oe = "";
|
|
1052
|
+
const Ee = async (q) => {
|
|
1053
|
+
if (ne !== G || j.signal.aborted || !b)
|
|
1053
1054
|
return;
|
|
1054
|
-
const
|
|
1055
|
-
if (
|
|
1056
|
-
if (
|
|
1057
|
-
const
|
|
1058
|
-
|
|
1055
|
+
const C = vn(q);
|
|
1056
|
+
if (C) {
|
|
1057
|
+
if (C.event === "audio") {
|
|
1058
|
+
const fe = C.data.chunk, J = C.data.visemes ?? [], le = C.data.words ?? [], Ke = C.data.is_new_segment ?? !1, Re = C.data.sample_rate;
|
|
1059
|
+
fe ? await I.playAudioChunk(
|
|
1059
1060
|
n,
|
|
1060
1061
|
r,
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
{ sampleRate:
|
|
1066
|
-
) : (
|
|
1062
|
+
fe,
|
|
1063
|
+
J,
|
|
1064
|
+
le,
|
|
1065
|
+
Ke,
|
|
1066
|
+
{ sampleRate: Re }
|
|
1067
|
+
) : (J.length > 0 || le.length > 0) && I.queueTimingsOnly(
|
|
1067
1068
|
n,
|
|
1068
1069
|
r,
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1070
|
+
J,
|
|
1071
|
+
le,
|
|
1072
|
+
Ke
|
|
1072
1073
|
);
|
|
1073
|
-
} else if (
|
|
1074
|
-
const
|
|
1075
|
-
typeof
|
|
1076
|
-
const
|
|
1077
|
-
Array.isArray(
|
|
1078
|
-
...
|
|
1079
|
-
)),
|
|
1080
|
-
} else if (
|
|
1074
|
+
} else if (C.event === "metadata") {
|
|
1075
|
+
const fe = C.data.mood;
|
|
1076
|
+
typeof fe == "string" && fe.trim() && (a = fe.trim());
|
|
1077
|
+
const J = C.data.sentence_emotions;
|
|
1078
|
+
Array.isArray(J) && (s.length = 0, s.push(
|
|
1079
|
+
...vt(J, a)
|
|
1080
|
+
)), M();
|
|
1081
|
+
} else if (C.event === "error")
|
|
1081
1082
|
throw new Error(
|
|
1082
|
-
String(
|
|
1083
|
+
String(C.data.message ?? "avatar_ttsWithPoses stream error")
|
|
1083
1084
|
);
|
|
1084
1085
|
}
|
|
1085
1086
|
};
|
|
1086
|
-
for (; !(
|
|
1087
|
-
const { done:
|
|
1088
|
-
|
|
1089
|
-
const
|
|
1087
|
+
for (; !(ne !== G || j.signal.aborted || !b); ) {
|
|
1088
|
+
const { done: q, value: C } = await Ie.read();
|
|
1089
|
+
C && (oe += st.decode(C, { stream: !0 }));
|
|
1090
|
+
const fe = oe.split(`
|
|
1090
1091
|
|
|
1091
1092
|
`);
|
|
1092
|
-
|
|
1093
|
-
for (const
|
|
1094
|
-
if (
|
|
1095
|
-
|
|
1093
|
+
oe = fe.pop() ?? "";
|
|
1094
|
+
for (const J of fe) await Ee(J);
|
|
1095
|
+
if (q) {
|
|
1096
|
+
oe.trim() && await Ee(oe.trim()), ne === G && !j.signal.aborted && b && I.markStreamComplete(n);
|
|
1096
1097
|
break;
|
|
1097
1098
|
}
|
|
1098
1099
|
}
|
|
1099
|
-
} catch (
|
|
1100
|
-
if (
|
|
1101
|
-
console.error("[realtimeVoice] avatar_speak failed:",
|
|
1100
|
+
} catch (ve) {
|
|
1101
|
+
if (j.signal.aborted || !b) return;
|
|
1102
|
+
console.error("[realtimeVoice] avatar_speak failed:", ve), e("error"), M();
|
|
1102
1103
|
} finally {
|
|
1103
|
-
|
|
1104
|
+
N === j && (N = null);
|
|
1104
1105
|
}
|
|
1105
|
-
},
|
|
1106
|
-
const
|
|
1107
|
-
if (!
|
|
1106
|
+
}, $e = (c) => {
|
|
1107
|
+
const k = Qr(c);
|
|
1108
|
+
if (!k) {
|
|
1108
1109
|
console.warn("[realtimeVoice] server message with no payload", c);
|
|
1109
1110
|
return;
|
|
1110
1111
|
}
|
|
1111
|
-
const
|
|
1112
|
-
switch (
|
|
1112
|
+
const x = String(k.type ?? "unknown");
|
|
1113
|
+
switch (x !== "avatar_metadata" && x !== "avatar_audio_chunk" && x !== "avatar_lipsync" && x !== "avatar_interrupt" && x !== "error" && console.debug("[realtimeVoice] server message", x, k), x) {
|
|
1113
1114
|
case "avatar_metadata":
|
|
1114
|
-
|
|
1115
|
+
X(k);
|
|
1115
1116
|
break;
|
|
1116
1117
|
case "avatar_audio_chunk":
|
|
1117
|
-
|
|
1118
|
+
te(k);
|
|
1118
1119
|
break;
|
|
1119
1120
|
case "avatar_lipsync":
|
|
1120
|
-
|
|
1121
|
+
Fe(k);
|
|
1121
1122
|
break;
|
|
1122
1123
|
case "avatar_interrupt":
|
|
1123
|
-
|
|
1124
|
+
se(k);
|
|
1124
1125
|
break;
|
|
1125
1126
|
case "error": {
|
|
1126
|
-
const
|
|
1127
|
-
console.error("[realtimeVoice] server error:",
|
|
1127
|
+
const j = String(k.message ?? "Voice session error");
|
|
1128
|
+
console.error("[realtimeVoice] server error:", j), e("error"), M();
|
|
1128
1129
|
break;
|
|
1129
1130
|
}
|
|
1130
1131
|
case "avatar_speak":
|
|
1131
|
-
|
|
1132
|
+
ye(k);
|
|
1132
1133
|
break;
|
|
1133
1134
|
}
|
|
1134
|
-
},
|
|
1135
|
-
transport: new
|
|
1136
|
-
mediaManager:
|
|
1137
|
-
serializer: new
|
|
1138
|
-
recorderSampleRate:
|
|
1139
|
-
playerSampleRate:
|
|
1135
|
+
}, nt = () => u || (_ = new Hr(), u = new zn({
|
|
1136
|
+
transport: new Qn({
|
|
1137
|
+
mediaManager: _,
|
|
1138
|
+
serializer: new qr(),
|
|
1139
|
+
recorderSampleRate: In,
|
|
1140
|
+
playerSampleRate: Rn
|
|
1140
1141
|
}),
|
|
1141
1142
|
enableCam: !1,
|
|
1142
1143
|
enableMic: !0,
|
|
1143
1144
|
callbacks: {
|
|
1144
1145
|
onBotReady: () => {
|
|
1145
|
-
|
|
1146
|
+
f = !0, e("idle"), M();
|
|
1146
1147
|
},
|
|
1147
1148
|
onDisconnected: () => {
|
|
1148
|
-
|
|
1149
|
+
f = !1, ae();
|
|
1149
1150
|
},
|
|
1150
1151
|
onError: (c) => {
|
|
1151
|
-
const
|
|
1152
|
-
console.error("[realtimeVoice]",
|
|
1152
|
+
const k = typeof c == "object" && c !== null && "data" in c ? String(c.data ?? c) : String(c);
|
|
1153
|
+
console.error("[realtimeVoice]", k, c), e("error"), M();
|
|
1153
1154
|
},
|
|
1154
1155
|
onTransportStateChanged: (c) => {
|
|
1155
|
-
c === "error" && (e("error"),
|
|
1156
|
+
c === "error" && (e("error"), M());
|
|
1156
1157
|
},
|
|
1157
1158
|
onServerMessage: (c) => {
|
|
1158
1159
|
D(c);
|
|
1159
1160
|
},
|
|
1160
1161
|
onUserStartedSpeaking: () => {
|
|
1161
|
-
|
|
1162
|
+
se({});
|
|
1162
1163
|
},
|
|
1163
1164
|
onBotStartedSpeaking: () => {
|
|
1164
1165
|
T("bot_started");
|
|
1165
1166
|
},
|
|
1166
1167
|
onBotStoppedSpeaking: () => {
|
|
1167
|
-
|
|
1168
|
-
|
|
1168
|
+
b && (A(), S = setTimeout(() => {
|
|
1169
|
+
S = null, b && (I.markStreamComplete(n), T("bot_stopped"));
|
|
1169
1170
|
}, 450));
|
|
1170
1171
|
},
|
|
1171
1172
|
onUserTranscript: (c) => {
|
|
1172
|
-
|
|
1173
|
+
m.onUserTranscript?.(c.text, !!c.final);
|
|
1173
1174
|
},
|
|
1174
1175
|
onBotOutput: (c) => {
|
|
1175
|
-
|
|
1176
|
+
m.onBotOutput?.(c.text);
|
|
1176
1177
|
}
|
|
1177
1178
|
}
|
|
1178
|
-
}),
|
|
1179
|
+
}), u);
|
|
1179
1180
|
return {
|
|
1180
1181
|
setDeveloperToken: (c) => {
|
|
1181
1182
|
},
|
|
1182
1183
|
setTtsEngineId: (c) => {
|
|
1183
|
-
|
|
1184
|
+
l = c, I.setStreamTtsEngineId(c);
|
|
1184
1185
|
},
|
|
1185
|
-
getTtsEngineId: () =>
|
|
1186
|
-
speak: async (c,
|
|
1187
|
-
const
|
|
1188
|
-
if (
|
|
1189
|
-
if (!
|
|
1186
|
+
getTtsEngineId: () => l,
|
|
1187
|
+
speak: async (c, k) => {
|
|
1188
|
+
const x = c.trim();
|
|
1189
|
+
if (x) {
|
|
1190
|
+
if (!u || !f)
|
|
1190
1191
|
throw new Error(
|
|
1191
1192
|
"Realtime voice is not connected. Call connect() first."
|
|
1192
1193
|
);
|
|
1193
|
-
|
|
1194
|
+
K(), await u.sendText(x);
|
|
1194
1195
|
}
|
|
1195
1196
|
},
|
|
1196
1197
|
stop: () => {
|
|
1197
|
-
|
|
1198
|
+
N?.abort(), N = null, G += 1, $(), K(), e("idle"), M();
|
|
1198
1199
|
},
|
|
1199
1200
|
connect: async (c) => {
|
|
1200
|
-
if (c && (
|
|
1201
|
+
if (c && (m = { ...m, ...c }), !m.authToken?.trim())
|
|
1201
1202
|
throw new Error(
|
|
1202
1203
|
"Voice connect requires authToken (same JWT as SSE Authorization Bearer)."
|
|
1203
1204
|
);
|
|
1204
1205
|
e("loading");
|
|
1205
|
-
const
|
|
1206
|
-
await
|
|
1207
|
-
const
|
|
1208
|
-
console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):",
|
|
1206
|
+
const k = nt();
|
|
1207
|
+
await k.initDevices();
|
|
1208
|
+
const x = zr(m);
|
|
1209
|
+
console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):", x);
|
|
1209
1210
|
try {
|
|
1210
|
-
await
|
|
1211
|
-
} catch (
|
|
1212
|
-
|
|
1213
|
-
const
|
|
1214
|
-
throw new Error(`${
|
|
1211
|
+
await k.connect({ wsUrl: x });
|
|
1212
|
+
} catch (j) {
|
|
1213
|
+
f = !1, e("error"), M();
|
|
1214
|
+
const ne = j instanceof Error ? j.message : "Realtime voice connect failed (WebSocket 101 only means upgrade OK — check authToken/origin/RTVI handshake)";
|
|
1215
|
+
throw new Error(`${ne} — ${x}`);
|
|
1215
1216
|
}
|
|
1216
|
-
|
|
1217
|
+
f = !0, e("idle"), M();
|
|
1217
1218
|
},
|
|
1218
1219
|
disconnect: async () => {
|
|
1219
|
-
if (A(),
|
|
1220
|
+
if (A(), Z = !1, y.length = 0, h = !1, N?.abort(), N = null, G += 1, $(), u)
|
|
1220
1221
|
try {
|
|
1221
|
-
await
|
|
1222
|
+
await u.disconnect();
|
|
1222
1223
|
} catch (c) {
|
|
1223
1224
|
console.error("[realtimeVoice] disconnect failed:", c);
|
|
1224
1225
|
}
|
|
1225
|
-
|
|
1226
|
+
f = !1, ae();
|
|
1226
1227
|
},
|
|
1227
|
-
isConnected: () =>
|
|
1228
|
+
isConnected: () => f,
|
|
1228
1229
|
unlockAudio: async () => {
|
|
1229
|
-
await
|
|
1230
|
+
await I.primeAudioContext();
|
|
1230
1231
|
},
|
|
1231
1232
|
getVisemeQueue: () => n,
|
|
1232
1233
|
getWordQueue: () => r,
|
|
1233
1234
|
getSentenceEmotions: () => s,
|
|
1234
1235
|
getStreamMood: () => a,
|
|
1235
|
-
getPlaybackElapsedMs:
|
|
1236
|
-
isSpeaking: () =>
|
|
1237
|
-
getVoiceStream: () =>
|
|
1236
|
+
getPlaybackElapsedMs: L,
|
|
1237
|
+
isSpeaking: () => I.isSpeaking(),
|
|
1238
|
+
getVoiceStream: () => I.getVoiceStream(),
|
|
1238
1239
|
setPlaybackSpeed: (c) => {
|
|
1239
|
-
|
|
1240
|
+
I.setPlaybackSpeed(c);
|
|
1240
1241
|
},
|
|
1241
|
-
getPlaybackSpeed: () =>
|
|
1242
|
-
subscribe: (c) => (
|
|
1242
|
+
getPlaybackSpeed: () => I.getPlaybackSpeed(),
|
|
1243
|
+
subscribe: (c) => (d.add(c), () => d.delete(c))
|
|
1243
1244
|
};
|
|
1244
1245
|
}
|
|
1245
|
-
function
|
|
1246
|
+
function Xr(e, t, n) {
|
|
1246
1247
|
return {
|
|
1247
1248
|
width: e.crop?.source_width ?? t,
|
|
1248
1249
|
height: e.crop?.source_height ?? n
|
|
1249
1250
|
};
|
|
1250
1251
|
}
|
|
1251
|
-
function
|
|
1252
|
+
function Zr(e, t) {
|
|
1252
1253
|
const n = e.crop;
|
|
1253
1254
|
return {
|
|
1254
1255
|
x: t?.source_x ?? n?.x ?? 0,
|
|
@@ -1257,21 +1258,21 @@ function Nr(e, t) {
|
|
|
1257
1258
|
height: t?.source_h ?? n?.height ?? e.frame_height ?? 0
|
|
1258
1259
|
};
|
|
1259
1260
|
}
|
|
1260
|
-
function
|
|
1261
|
+
function es(e) {
|
|
1261
1262
|
return e ? (e.w ?? 0) > 0 && (e.h ?? 0) > 0 : !1;
|
|
1262
1263
|
}
|
|
1263
|
-
async function
|
|
1264
|
+
async function gt(e, t) {
|
|
1264
1265
|
const n = await fetch(e);
|
|
1265
1266
|
if (!n.ok) throw new Error(`Failed to load encrypted asset: ${e}`);
|
|
1266
1267
|
const r = await n.arrayBuffer();
|
|
1267
|
-
return
|
|
1268
|
+
return pr(r, t);
|
|
1268
1269
|
}
|
|
1269
|
-
async function
|
|
1270
|
+
async function ts(e, t) {
|
|
1270
1271
|
if (!t) throw new Error("Missing asset key for encrypted JSON");
|
|
1271
|
-
const n = await
|
|
1272
|
+
const n = await gt(e, t), r = new TextDecoder().decode(n);
|
|
1272
1273
|
return JSON.parse(r);
|
|
1273
1274
|
}
|
|
1274
|
-
async function
|
|
1275
|
+
async function ns(e) {
|
|
1275
1276
|
const t = new Blob([e], { type: "image/webp" }), n = URL.createObjectURL(t);
|
|
1276
1277
|
return new Promise((r, s) => {
|
|
1277
1278
|
const i = new Image();
|
|
@@ -1282,7 +1283,7 @@ async function Wr(e) {
|
|
|
1282
1283
|
}, i.src = n;
|
|
1283
1284
|
});
|
|
1284
1285
|
}
|
|
1285
|
-
async function
|
|
1286
|
+
async function rs(e) {
|
|
1286
1287
|
const t = new Blob([e], { type: "image/png" }), n = URL.createObjectURL(t);
|
|
1287
1288
|
return new Promise((r, s) => {
|
|
1288
1289
|
const i = new Image();
|
|
@@ -1293,28 +1294,28 @@ async function Hr(e) {
|
|
|
1293
1294
|
}, i.src = n;
|
|
1294
1295
|
});
|
|
1295
1296
|
}
|
|
1296
|
-
function
|
|
1297
|
+
function ss(e) {
|
|
1297
1298
|
const t = new Blob([e], { type: "video/mp4" });
|
|
1298
1299
|
return URL.createObjectURL(t);
|
|
1299
1300
|
}
|
|
1300
|
-
async function
|
|
1301
|
-
const t =
|
|
1302
|
-
if (!
|
|
1301
|
+
async function is(e) {
|
|
1302
|
+
const t = vr();
|
|
1303
|
+
if (!mt()) return t;
|
|
1303
1304
|
if (!e) throw new Error("Missing asset key for encrypted idle video");
|
|
1304
|
-
const n = await
|
|
1305
|
-
return
|
|
1305
|
+
const n = await gt(t, e);
|
|
1306
|
+
return ss(n);
|
|
1306
1307
|
}
|
|
1307
|
-
function
|
|
1308
|
+
function Ut(e, t) {
|
|
1308
1309
|
return `${e}/${t}_minus_sil.png`;
|
|
1309
1310
|
}
|
|
1310
|
-
const
|
|
1311
|
-
function
|
|
1311
|
+
const Dn = 5;
|
|
1312
|
+
function Mn(e) {
|
|
1312
1313
|
const t = e?.composite_threshold;
|
|
1313
1314
|
if (typeof t == "number" && t > 0) return t;
|
|
1314
1315
|
const n = e?.crop?.content_threshold;
|
|
1315
|
-
return typeof n == "number" && n > 0 ? n :
|
|
1316
|
+
return typeof n == "number" && n > 0 ? n : Dn;
|
|
1316
1317
|
}
|
|
1317
|
-
const
|
|
1318
|
+
const Si = [
|
|
1318
1319
|
"aa",
|
|
1319
1320
|
"E",
|
|
1320
1321
|
"I",
|
|
@@ -1329,11 +1330,11 @@ const ri = [
|
|
|
1329
1330
|
"RR",
|
|
1330
1331
|
"kk",
|
|
1331
1332
|
"nn"
|
|
1332
|
-
],
|
|
1333
|
+
], Rt = [
|
|
1333
1334
|
"t01_0.25",
|
|
1334
1335
|
"t02_0.50",
|
|
1335
1336
|
"t03_0.75"
|
|
1336
|
-
],
|
|
1337
|
+
], as = Rt.length, tn = /* @__PURE__ */ new Set([
|
|
1337
1338
|
"aa__kk",
|
|
1338
1339
|
"aa__nn",
|
|
1339
1340
|
"aa__sil",
|
|
@@ -1440,75 +1441,75 @@ const ri = [
|
|
|
1440
1441
|
"U__nn",
|
|
1441
1442
|
"U__sil"
|
|
1442
1443
|
]);
|
|
1443
|
-
function
|
|
1444
|
+
function nn(e, t) {
|
|
1444
1445
|
return `${e}__${t}`;
|
|
1445
1446
|
}
|
|
1446
|
-
function
|
|
1447
|
+
function rn(e, t) {
|
|
1447
1448
|
return `pairs/${e}/${t}_minus_sil.png`;
|
|
1448
1449
|
}
|
|
1449
|
-
function
|
|
1450
|
+
function lt(e) {
|
|
1450
1451
|
return `${e}_minus_sil.png`;
|
|
1451
1452
|
}
|
|
1452
|
-
function
|
|
1453
|
+
function os(e, t) {
|
|
1453
1454
|
if (t.has(e)) return e;
|
|
1454
1455
|
const n = /^pairs\/([^/]+)\//.exec(e);
|
|
1455
1456
|
if (!n) return null;
|
|
1456
1457
|
const r = n[1].split("__")[1];
|
|
1457
1458
|
if (!r || r === "sil") return null;
|
|
1458
|
-
const s =
|
|
1459
|
+
const s = lt(r);
|
|
1459
1460
|
return t.has(s) ? s : null;
|
|
1460
1461
|
}
|
|
1461
|
-
function
|
|
1462
|
+
function Cn(e, t) {
|
|
1462
1463
|
return e.filter((n) => t.has(n));
|
|
1463
1464
|
}
|
|
1464
|
-
function
|
|
1465
|
-
const r =
|
|
1466
|
-
return
|
|
1465
|
+
function cs(e, t, n) {
|
|
1466
|
+
const r = Nt(e, t);
|
|
1467
|
+
return Cn(r, n).length > 0;
|
|
1467
1468
|
}
|
|
1468
|
-
function
|
|
1469
|
+
function Nt(e, t) {
|
|
1469
1470
|
if (e === t) return [];
|
|
1470
|
-
const n = [], r =
|
|
1471
|
-
if (
|
|
1472
|
-
for (const i of
|
|
1473
|
-
n.push(
|
|
1471
|
+
const n = [], r = nn(e, t);
|
|
1472
|
+
if (tn.has(r)) {
|
|
1473
|
+
for (const i of Rt)
|
|
1474
|
+
n.push(rn(r, i));
|
|
1474
1475
|
return n;
|
|
1475
1476
|
}
|
|
1476
|
-
const s =
|
|
1477
|
-
if (
|
|
1478
|
-
for (let i =
|
|
1479
|
-
n.push(
|
|
1477
|
+
const s = nn(t, e);
|
|
1478
|
+
if (tn.has(s)) {
|
|
1479
|
+
for (let i = as - 1; i >= 0; i--)
|
|
1480
|
+
n.push(rn(s, Rt[i]));
|
|
1480
1481
|
return n;
|
|
1481
1482
|
}
|
|
1482
1483
|
return [];
|
|
1483
1484
|
}
|
|
1484
|
-
function
|
|
1485
|
+
function us(e) {
|
|
1485
1486
|
return e < 16 ? [] : e < 35 ? [1] : e < 51 ? [0, 2] : [0, 1, 2];
|
|
1486
1487
|
}
|
|
1487
|
-
function
|
|
1488
|
-
return
|
|
1488
|
+
function ls(e, t) {
|
|
1489
|
+
return us(t).map((r) => e[r]).filter((r) => r != null);
|
|
1489
1490
|
}
|
|
1490
|
-
function
|
|
1491
|
+
function fs(e, t, n, r) {
|
|
1491
1492
|
if (r <= 0) return 0;
|
|
1492
1493
|
const i = Math.max(1, n - t) / r, o = e - t, a = Math.floor(o / i);
|
|
1493
1494
|
return Math.min(r - 1, Math.max(0, a));
|
|
1494
1495
|
}
|
|
1495
|
-
function
|
|
1496
|
+
function ds(e, t, n) {
|
|
1496
1497
|
if (!n) return `${e}/${t}`;
|
|
1497
1498
|
const r = t.split("/").pop() ?? t, s = r.includes(".") ? r.slice(0, r.lastIndexOf(".")) : r;
|
|
1498
1499
|
return `${e}/${s}.bin`;
|
|
1499
1500
|
}
|
|
1500
|
-
const
|
|
1501
|
+
const ms = [0.32, 0.24, 0.16, 0.08, 0], hs = ms.map(
|
|
1501
1502
|
(e) => `eyes_${e.toFixed(2)}`
|
|
1502
|
-
),
|
|
1503
|
+
), ws = [
|
|
1503
1504
|
"eyes_0.32",
|
|
1504
1505
|
"eyes_0.16",
|
|
1505
1506
|
"eyes_0.00"
|
|
1506
|
-
],
|
|
1507
|
+
], gs = [
|
|
1507
1508
|
"eyes_0.32",
|
|
1508
1509
|
"eyes_0.16",
|
|
1509
1510
|
"eyes_0.08",
|
|
1510
1511
|
"eyes_0.00"
|
|
1511
|
-
],
|
|
1512
|
+
], sn = 2, ps = -30, Dt = 20, _s = {
|
|
1512
1513
|
fear: -30,
|
|
1513
1514
|
anger: -20,
|
|
1514
1515
|
sad: -10,
|
|
@@ -1517,24 +1518,24 @@ const Zr = [0.32, 0.24, 0.16, 0.08, 0], es = Zr.map(
|
|
|
1517
1518
|
happy: 0,
|
|
1518
1519
|
disgust: 20
|
|
1519
1520
|
};
|
|
1520
|
-
function
|
|
1521
|
+
function Vt(e) {
|
|
1521
1522
|
return `brow_${e}`;
|
|
1522
1523
|
}
|
|
1523
|
-
function
|
|
1524
|
-
return
|
|
1524
|
+
function $t(e) {
|
|
1525
|
+
return _s[e];
|
|
1525
1526
|
}
|
|
1526
|
-
function
|
|
1527
|
-
return Math.max(
|
|
1527
|
+
function xe(e) {
|
|
1528
|
+
return Math.max(ps, Math.min(Dt, e));
|
|
1528
1529
|
}
|
|
1529
|
-
function
|
|
1530
|
+
function ys(e, t) {
|
|
1530
1531
|
if (e === t) return [];
|
|
1531
|
-
const n = e < t ?
|
|
1532
|
+
const n = e < t ? sn : -sn, r = [];
|
|
1532
1533
|
let s = e;
|
|
1533
1534
|
for (; s !== t; )
|
|
1534
1535
|
s += n, r.push(s);
|
|
1535
1536
|
return r;
|
|
1536
1537
|
}
|
|
1537
|
-
const
|
|
1538
|
+
const Ss = {
|
|
1538
1539
|
fear: "fear",
|
|
1539
1540
|
afraid: "fear",
|
|
1540
1541
|
anxiety: "fear",
|
|
@@ -1559,61 +1560,61 @@ const as = {
|
|
|
1559
1560
|
};
|
|
1560
1561
|
function Oe(e, t = "neutral") {
|
|
1561
1562
|
const n = String(e ?? "").trim().toLowerCase();
|
|
1562
|
-
return n ?
|
|
1563
|
+
return n ? Ss[n] ?? t : t;
|
|
1563
1564
|
}
|
|
1564
|
-
function
|
|
1565
|
-
return e === 0 ? null :
|
|
1565
|
+
function xn(e) {
|
|
1566
|
+
return e === 0 ? null : Ut(Vt(e), "eyes_standard");
|
|
1566
1567
|
}
|
|
1567
|
-
function
|
|
1568
|
-
return
|
|
1568
|
+
function Pn(e) {
|
|
1569
|
+
return xn($t(e));
|
|
1569
1570
|
}
|
|
1570
|
-
function
|
|
1571
|
-
const n =
|
|
1572
|
-
return !t || t === "eyes_standard" ?
|
|
1571
|
+
function an(e, t) {
|
|
1572
|
+
const n = Vt($t(e));
|
|
1573
|
+
return !t || t === "eyes_standard" ? Pn(e) : e === "neutral" && t === "eyes_standard" ? null : Ut(n, t);
|
|
1573
1574
|
}
|
|
1574
|
-
function
|
|
1575
|
+
function ks(e, t) {
|
|
1575
1576
|
const n = [];
|
|
1576
1577
|
for (const r of t)
|
|
1577
|
-
n.push(
|
|
1578
|
+
n.push(an(e, r));
|
|
1578
1579
|
for (let r = t.length - 2; r >= 0; r--)
|
|
1579
|
-
n.push(
|
|
1580
|
-
return n.push(
|
|
1580
|
+
n.push(an(e, t[r]));
|
|
1581
|
+
return n.push(Pn(e)), n;
|
|
1581
1582
|
}
|
|
1582
|
-
function
|
|
1583
|
-
return e === 0 ? null :
|
|
1583
|
+
function vs(e) {
|
|
1584
|
+
return e === 0 ? null : Ut(Vt(e), "eyes_standard");
|
|
1584
1585
|
}
|
|
1585
|
-
function
|
|
1586
|
-
return
|
|
1586
|
+
function Es(e, t) {
|
|
1587
|
+
return ys(e, t).map(vs).filter((n) => n != null);
|
|
1587
1588
|
}
|
|
1588
|
-
const
|
|
1589
|
-
function
|
|
1589
|
+
const bs = 6;
|
|
1590
|
+
function Ts(e, t) {
|
|
1590
1591
|
for (const n of e)
|
|
1591
1592
|
if (t >= n.wtime && t < n.wtime + n.wduration)
|
|
1592
1593
|
return n;
|
|
1593
1594
|
return null;
|
|
1594
1595
|
}
|
|
1595
|
-
function
|
|
1596
|
-
const t =
|
|
1597
|
-
return t >=
|
|
1596
|
+
function As(e) {
|
|
1597
|
+
const t = xe(e);
|
|
1598
|
+
return t >= Dt ? Dt : xe(t + bs);
|
|
1598
1599
|
}
|
|
1599
|
-
function
|
|
1600
|
-
const r =
|
|
1601
|
-
return
|
|
1600
|
+
function Is(e, t, n) {
|
|
1601
|
+
const r = xe(n);
|
|
1602
|
+
return Ts(t, e)?.emphasis ? As(r) : r;
|
|
1602
1603
|
}
|
|
1603
|
-
function
|
|
1604
|
+
function on(e) {
|
|
1604
1605
|
if (!e) return 0;
|
|
1605
1606
|
const t = e.match(/^brow_(-?\d+)\//);
|
|
1606
1607
|
if (!t?.[1]) return null;
|
|
1607
1608
|
const n = Number.parseInt(t[1], 10);
|
|
1608
|
-
return Number.isFinite(n) ?
|
|
1609
|
+
return Number.isFinite(n) ? xe(n) : null;
|
|
1609
1610
|
}
|
|
1610
|
-
function
|
|
1611
|
+
function Xe(e, t) {
|
|
1611
1612
|
return e + Math.random() * (t - e);
|
|
1612
1613
|
}
|
|
1613
|
-
function
|
|
1614
|
-
return
|
|
1614
|
+
function ct() {
|
|
1615
|
+
return Xe(14, 32);
|
|
1615
1616
|
}
|
|
1616
|
-
function
|
|
1617
|
+
function Rs(e = {}) {
|
|
1617
1618
|
const {
|
|
1618
1619
|
initialDelayMs: t = 800 + Math.random() * 1200,
|
|
1619
1620
|
intervalMinMs: n = 2200,
|
|
@@ -1622,133 +1623,133 @@ function hs(e = {}) {
|
|
|
1622
1623
|
doubleBlinkGapMinMs: i = 120,
|
|
1623
1624
|
doubleBlinkGapMaxMs: o = 220,
|
|
1624
1625
|
fullBlinkChance: a = 0.75,
|
|
1625
|
-
postEmotionChangeDelayMs:
|
|
1626
|
-
minDwellMs:
|
|
1626
|
+
postEmotionChangeDelayMs: l = 380,
|
|
1627
|
+
minDwellMs: f = 550
|
|
1627
1628
|
} = e;
|
|
1628
|
-
let
|
|
1629
|
+
let u = "neutral", _ = "neutral", m = 0, p = 0, v = 0, d = {
|
|
1629
1630
|
kind: "idle",
|
|
1630
1631
|
nextBlinkAt: performance.now() + t
|
|
1631
|
-
},
|
|
1632
|
-
function S
|
|
1633
|
-
|
|
1632
|
+
}, y = null, h = "__eyes_open__|neutral|brow:0";
|
|
1633
|
+
function E(S = u) {
|
|
1634
|
+
h = `${y ?? "__eyes_open__"}|${S}|brow:${p}`;
|
|
1634
1635
|
}
|
|
1635
|
-
function
|
|
1636
|
-
|
|
1637
|
-
const
|
|
1638
|
-
|
|
1636
|
+
function b(S, A = u) {
|
|
1637
|
+
y = S;
|
|
1638
|
+
const M = on(S);
|
|
1639
|
+
M != null ? p = M : S == null && (p = 0), E(A);
|
|
1639
1640
|
}
|
|
1640
|
-
function
|
|
1641
|
-
return
|
|
1641
|
+
function V(S) {
|
|
1642
|
+
return xn(S);
|
|
1642
1643
|
}
|
|
1643
|
-
function
|
|
1644
|
-
const
|
|
1645
|
-
if (
|
|
1646
|
-
|
|
1644
|
+
function Q(S, A, M) {
|
|
1645
|
+
const I = xe(A), g = xe(M);
|
|
1646
|
+
if (m = g, I === g) {
|
|
1647
|
+
b(V(g));
|
|
1647
1648
|
return;
|
|
1648
1649
|
}
|
|
1649
1650
|
const D = [
|
|
1650
|
-
...
|
|
1651
|
-
|
|
1651
|
+
...Es(I, g),
|
|
1652
|
+
V(g)
|
|
1652
1653
|
];
|
|
1653
|
-
|
|
1654
|
+
d = {
|
|
1654
1655
|
kind: "browBlend",
|
|
1655
1656
|
paths: D,
|
|
1656
1657
|
index: 0,
|
|
1657
|
-
holdUntil:
|
|
1658
|
-
targetBrow:
|
|
1659
|
-
},
|
|
1658
|
+
holdUntil: S + ct(),
|
|
1659
|
+
targetBrow: g
|
|
1660
|
+
}, b(D[0] ?? null);
|
|
1660
1661
|
}
|
|
1661
|
-
function
|
|
1662
|
-
|
|
1662
|
+
function N(S, A) {
|
|
1663
|
+
d = {
|
|
1663
1664
|
kind: "idle",
|
|
1664
|
-
nextBlinkAt:
|
|
1665
|
-
},
|
|
1665
|
+
nextBlinkAt: S + Xe(n, r)
|
|
1666
|
+
}, _ = A, b(V(m), A);
|
|
1666
1667
|
}
|
|
1667
|
-
function G(
|
|
1668
|
-
const
|
|
1669
|
-
|
|
1668
|
+
function G(S, A, M) {
|
|
1669
|
+
const I = M ? ws : Math.random() < a ? hs : gs;
|
|
1670
|
+
d = {
|
|
1670
1671
|
kind: "playing",
|
|
1671
|
-
paths:
|
|
1672
|
+
paths: ks(A, I),
|
|
1672
1673
|
index: 0,
|
|
1673
|
-
holdUntil:
|
|
1674
|
+
holdUntil: S + ct(),
|
|
1674
1675
|
after: "idle",
|
|
1675
1676
|
blinkEmotion: A
|
|
1676
|
-
},
|
|
1677
|
+
}, _ = A, b(d.paths[0] ?? null, A);
|
|
1677
1678
|
}
|
|
1678
|
-
function
|
|
1679
|
-
if (
|
|
1680
|
-
for (;
|
|
1681
|
-
|
|
1682
|
-
const A =
|
|
1683
|
-
|
|
1679
|
+
function Z(S) {
|
|
1680
|
+
if (d.kind === "browBlend") {
|
|
1681
|
+
for (; S >= d.holdUntil && d.index < d.paths.length - 1; )
|
|
1682
|
+
d.index += 1, d.holdUntil = S + ct();
|
|
1683
|
+
const A = d.paths[d.index] ?? null;
|
|
1684
|
+
b(A), S >= d.holdUntil && d.index >= d.paths.length - 1 && (p = d.targetBrow, m = d.targetBrow, b(V(d.targetBrow)), d = {
|
|
1684
1685
|
kind: "idle",
|
|
1685
|
-
nextBlinkAt:
|
|
1686
|
+
nextBlinkAt: S + l
|
|
1686
1687
|
});
|
|
1687
1688
|
return;
|
|
1688
1689
|
}
|
|
1689
|
-
if (
|
|
1690
|
-
|
|
1690
|
+
if (d.kind === "idle") {
|
|
1691
|
+
b(V(m), _), S >= d.nextBlinkAt && G(S, _, !1);
|
|
1691
1692
|
return;
|
|
1692
1693
|
}
|
|
1693
|
-
if (
|
|
1694
|
-
|
|
1694
|
+
if (d.kind === "doublePause") {
|
|
1695
|
+
b(V(m), d.blinkEmotion), S >= d.resumeAt && G(S, d.blinkEmotion, !0);
|
|
1695
1696
|
return;
|
|
1696
1697
|
}
|
|
1697
|
-
if (
|
|
1698
|
-
for (;
|
|
1699
|
-
|
|
1700
|
-
if (
|
|
1701
|
-
if (
|
|
1702
|
-
|
|
1698
|
+
if (d.kind === "playing") {
|
|
1699
|
+
for (; S >= d.holdUntil && d.index < d.paths.length - 1; )
|
|
1700
|
+
d.index += 1, d.holdUntil = S + ct();
|
|
1701
|
+
if (b(d.paths[d.index] ?? null, d.blinkEmotion), S >= d.holdUntil && d.index >= d.paths.length - 1) {
|
|
1702
|
+
if (d.after === "resumeIdle") {
|
|
1703
|
+
N(S + l, u);
|
|
1703
1704
|
return;
|
|
1704
1705
|
}
|
|
1705
|
-
if (
|
|
1706
|
-
|
|
1706
|
+
if (d.after === "doublePause") {
|
|
1707
|
+
d = {
|
|
1707
1708
|
kind: "doublePause",
|
|
1708
|
-
resumeAt:
|
|
1709
|
-
blinkEmotion:
|
|
1710
|
-
},
|
|
1709
|
+
resumeAt: S + Xe(i, o),
|
|
1710
|
+
blinkEmotion: d.blinkEmotion
|
|
1711
|
+
}, b(V(m), d.blinkEmotion);
|
|
1711
1712
|
return;
|
|
1712
1713
|
}
|
|
1713
|
-
if (
|
|
1714
|
-
|
|
1714
|
+
if (d.after === "idle" && Math.random() < s) {
|
|
1715
|
+
d = {
|
|
1715
1716
|
kind: "doublePause",
|
|
1716
|
-
resumeAt:
|
|
1717
|
-
blinkEmotion:
|
|
1718
|
-
},
|
|
1717
|
+
resumeAt: S + Xe(i, o),
|
|
1718
|
+
blinkEmotion: d.blinkEmotion
|
|
1719
|
+
}, b(V(m), d.blinkEmotion);
|
|
1719
1720
|
return;
|
|
1720
1721
|
}
|
|
1721
|
-
|
|
1722
|
+
N(S, d.blinkEmotion);
|
|
1722
1723
|
}
|
|
1723
1724
|
}
|
|
1724
1725
|
}
|
|
1725
1726
|
return {
|
|
1726
|
-
advance:
|
|
1727
|
-
setTargetEmotion(
|
|
1728
|
-
const A = Oe(
|
|
1729
|
-
if (A ===
|
|
1730
|
-
const
|
|
1731
|
-
|
|
1727
|
+
advance: Z,
|
|
1728
|
+
setTargetEmotion(S) {
|
|
1729
|
+
const A = Oe(S, u);
|
|
1730
|
+
if (A === u) return;
|
|
1731
|
+
const M = performance.now();
|
|
1732
|
+
f > 0 && A !== u && !(u === "neutral" && A !== "neutral") && M - v < f || (u = A, _ = A, v = M);
|
|
1732
1733
|
},
|
|
1733
|
-
setTargetEyebrow(
|
|
1734
|
-
const A =
|
|
1735
|
-
if (A ===
|
|
1736
|
-
const
|
|
1737
|
-
|
|
1734
|
+
setTargetEyebrow(S) {
|
|
1735
|
+
const A = xe(S);
|
|
1736
|
+
if (A === m && d.kind !== "browBlend") return;
|
|
1737
|
+
const M = performance.now(), I = d.kind === "browBlend" ? on(y) ?? p : p;
|
|
1738
|
+
m = A, !(A === I && d.kind !== "browBlend") && (d.kind === "playing" || d.kind === "doublePause" || Q(M, I, A));
|
|
1738
1739
|
},
|
|
1739
|
-
getTargetEmotion: () =>
|
|
1740
|
-
getTargetEyebrow: () =>
|
|
1741
|
-
getExpressionPath: () =>
|
|
1742
|
-
getDrawKey: () =>
|
|
1740
|
+
getTargetEmotion: () => u,
|
|
1741
|
+
getTargetEyebrow: () => m,
|
|
1742
|
+
getExpressionPath: () => y,
|
|
1743
|
+
getDrawKey: () => h,
|
|
1743
1744
|
reset() {
|
|
1744
|
-
|
|
1745
|
-
performance.now() +
|
|
1745
|
+
u = "neutral", _ = "neutral", m = 0, p = 0, v = 0, N(
|
|
1746
|
+
performance.now() + Xe(n, r),
|
|
1746
1747
|
"neutral"
|
|
1747
1748
|
);
|
|
1748
1749
|
}
|
|
1749
1750
|
};
|
|
1750
1751
|
}
|
|
1751
|
-
function
|
|
1752
|
+
function Ds() {
|
|
1752
1753
|
const e = document.createElement("video");
|
|
1753
1754
|
e.muted = !0, e.playsInline = !0, e.preload = "auto", e.setAttribute("playsinline", ""), e.loop = !0;
|
|
1754
1755
|
let t = !1, n = null, r = "";
|
|
@@ -1758,15 +1759,15 @@ function ws() {
|
|
|
1758
1759
|
return {
|
|
1759
1760
|
async load(i) {
|
|
1760
1761
|
t && r === i || (s(), t = !1, r = i, i.startsWith("blob:") && (n = i), await new Promise((o, a) => {
|
|
1761
|
-
const
|
|
1762
|
-
const
|
|
1763
|
-
if (!Number.isFinite(
|
|
1762
|
+
const l = () => {
|
|
1763
|
+
const f = e.duration;
|
|
1764
|
+
if (!Number.isFinite(f) || f <= 0) {
|
|
1764
1765
|
a(new Error(`Idle video has invalid duration: ${i}`));
|
|
1765
1766
|
return;
|
|
1766
1767
|
}
|
|
1767
1768
|
t = !0, e.currentTime = 0, o();
|
|
1768
1769
|
};
|
|
1769
|
-
e.addEventListener("loadeddata",
|
|
1770
|
+
e.addEventListener("loadeddata", l, { once: !0 }), e.addEventListener(
|
|
1770
1771
|
"error",
|
|
1771
1772
|
() => a(new Error(`Failed to load idle video: ${i}`)),
|
|
1772
1773
|
{ once: !0 }
|
|
@@ -1791,17 +1792,17 @@ function ws() {
|
|
|
1791
1792
|
}
|
|
1792
1793
|
};
|
|
1793
1794
|
}
|
|
1794
|
-
const
|
|
1795
|
-
function
|
|
1795
|
+
const Ms = 50, Fn = 400;
|
|
1796
|
+
function Cs(e, t, n) {
|
|
1796
1797
|
return e.filter((r) => {
|
|
1797
1798
|
const s = r.queueIndex ?? -1;
|
|
1798
1799
|
return s >= t && s <= n;
|
|
1799
1800
|
});
|
|
1800
1801
|
}
|
|
1801
|
-
function
|
|
1802
|
+
function xs(e, t) {
|
|
1802
1803
|
const n = [];
|
|
1803
1804
|
for (const r of e) {
|
|
1804
|
-
const s =
|
|
1805
|
+
const s = Cs(
|
|
1805
1806
|
t,
|
|
1806
1807
|
r.start_word,
|
|
1807
1808
|
r.end_word
|
|
@@ -1810,108 +1811,108 @@ function ps(e, t) {
|
|
|
1810
1811
|
const i = s[0], o = s[s.length - 1];
|
|
1811
1812
|
n.push({
|
|
1812
1813
|
sentence: r,
|
|
1813
|
-
startMs: Math.max(0, i.wtime -
|
|
1814
|
-
endMs: o.wtime + o.wduration +
|
|
1814
|
+
startMs: Math.max(0, i.wtime - Ms),
|
|
1815
|
+
endMs: o.wtime + o.wduration + Fn
|
|
1815
1816
|
});
|
|
1816
1817
|
}
|
|
1817
1818
|
return n.sort((r, s) => r.startMs - s.startMs);
|
|
1818
1819
|
}
|
|
1819
|
-
function
|
|
1820
|
+
function Ps(e, t, n, r = "neutral") {
|
|
1820
1821
|
const s = Oe(r);
|
|
1821
1822
|
if (t.length === 0) return s;
|
|
1822
1823
|
if (n.length === 0 || e < n[0].wtime)
|
|
1823
1824
|
return Oe(t[0]?.emotion, s);
|
|
1824
|
-
const i =
|
|
1825
|
+
const i = xs(t, n);
|
|
1825
1826
|
let o = null;
|
|
1826
|
-
for (const
|
|
1827
|
-
e >=
|
|
1827
|
+
for (const f of i)
|
|
1828
|
+
e >= f.startMs && e <= f.endMs && (o = f);
|
|
1828
1829
|
if (o)
|
|
1829
1830
|
return Oe(o.sentence.emotion, s);
|
|
1830
|
-
const a = n[n.length - 1],
|
|
1831
|
-
return e >
|
|
1831
|
+
const a = n[n.length - 1], l = a.wtime + a.wduration;
|
|
1832
|
+
return e > l + Fn ? Oe(
|
|
1832
1833
|
t[t.length - 1]?.emotion,
|
|
1833
1834
|
s
|
|
1834
1835
|
) : s;
|
|
1835
1836
|
}
|
|
1836
|
-
function
|
|
1837
|
+
function Bn(e, t, n, r, s = Dn) {
|
|
1837
1838
|
const i = new OffscreenCanvas(n, r), o = i.getContext("2d", { willReadFrequently: !0 });
|
|
1838
1839
|
o.drawImage(e, 0, 0, n, r);
|
|
1839
|
-
const a = o.getImageData(0, 0, n, r),
|
|
1840
|
-
|
|
1841
|
-
const
|
|
1842
|
-
for (const
|
|
1843
|
-
|
|
1844
|
-
const
|
|
1845
|
-
for (let
|
|
1846
|
-
const
|
|
1847
|
-
Math.max(
|
|
1840
|
+
const a = o.getImageData(0, 0, n, r), l = o.createImageData(n, r);
|
|
1841
|
+
l.data.set(a.data);
|
|
1842
|
+
const u = new OffscreenCanvas(n, r).getContext("2d", { willReadFrequently: !0 });
|
|
1843
|
+
for (const _ of t) {
|
|
1844
|
+
u.clearRect(0, 0, n, r), u.drawImage(_, 0, 0, n, r);
|
|
1845
|
+
const m = u.getImageData(0, 0, n, r);
|
|
1846
|
+
for (let p = 0; p < l.data.length; p += 4) {
|
|
1847
|
+
const v = m.data[p], d = m.data[p + 1], y = m.data[p + 2];
|
|
1848
|
+
Math.max(v, d, y) > s && (l.data[p] = v, l.data[p + 1] = d, l.data[p + 2] = y, l.data[p + 3] = 255);
|
|
1848
1849
|
}
|
|
1849
1850
|
}
|
|
1850
|
-
return o.putImageData(
|
|
1851
|
+
return o.putImageData(l, 0, 0), i;
|
|
1851
1852
|
}
|
|
1852
|
-
let
|
|
1853
|
-
const
|
|
1854
|
-
function
|
|
1855
|
-
|
|
1853
|
+
let Ce = null, Ze = null;
|
|
1854
|
+
const ft = /* @__PURE__ */ new Map();
|
|
1855
|
+
function Fs() {
|
|
1856
|
+
Ce = null, Ze = null, ft.clear();
|
|
1856
1857
|
}
|
|
1857
|
-
|
|
1858
|
-
function
|
|
1859
|
-
return e ??
|
|
1858
|
+
kr(Fs);
|
|
1859
|
+
function Bs(e) {
|
|
1860
|
+
return e ?? Ze ?? void 0;
|
|
1860
1861
|
}
|
|
1861
|
-
function
|
|
1862
|
+
function Wt(e) {
|
|
1862
1863
|
return new Promise((t, n) => {
|
|
1863
1864
|
const r = new Image();
|
|
1864
1865
|
r.decoding = "async", r.onload = () => t(r), r.onerror = () => n(new Error(`Failed to load image: ${e}`)), r.src = e;
|
|
1865
1866
|
});
|
|
1866
1867
|
}
|
|
1867
|
-
async function
|
|
1868
|
-
return
|
|
1869
|
-
await
|
|
1870
|
-
) :
|
|
1868
|
+
async function Os(e) {
|
|
1869
|
+
return mt() ? rs(
|
|
1870
|
+
await gt(Xt(), e ?? "")
|
|
1871
|
+
) : Wt(Xt());
|
|
1871
1872
|
}
|
|
1872
|
-
async function
|
|
1873
|
-
const s = n ? await
|
|
1874
|
-
if (!
|
|
1875
|
-
return
|
|
1873
|
+
async function cn(e, t, n, r) {
|
|
1874
|
+
const s = n ? await ts(e, r) : await fetch(e).then((f) => {
|
|
1875
|
+
if (!f.ok) throw new Error(`Failed to load ${e}`);
|
|
1876
|
+
return f.json();
|
|
1876
1877
|
}), i = s.sheets?.[0];
|
|
1877
1878
|
if (!i?.path) throw new Error(`${e} has no sheets[0].path`);
|
|
1878
|
-
const o = n ? await
|
|
1879
|
-
await
|
|
1880
|
-
|
|
1879
|
+
const o = n ? await ns(
|
|
1880
|
+
await gt(
|
|
1881
|
+
ds(t, i.path, n),
|
|
1881
1882
|
r ?? ""
|
|
1882
1883
|
)
|
|
1883
|
-
) : await
|
|
1884
|
-
for (const
|
|
1885
|
-
|
|
1886
|
-
const
|
|
1887
|
-
for (const
|
|
1888
|
-
|
|
1889
|
-
return { atlas: o, atlasMeta: s, cellByPath: a, sheetByIndex:
|
|
1890
|
-
}
|
|
1891
|
-
async function
|
|
1892
|
-
const t =
|
|
1884
|
+
) : await Wt(`${t}/${i.path}`), a = /* @__PURE__ */ new Map();
|
|
1885
|
+
for (const f of s.cells ?? [])
|
|
1886
|
+
f.path && a.set(f.path, f);
|
|
1887
|
+
const l = /* @__PURE__ */ new Map();
|
|
1888
|
+
for (const f of s.sheets ?? [])
|
|
1889
|
+
l.set(f.index, f);
|
|
1890
|
+
return { atlas: o, atlasMeta: s, cellByPath: a, sheetByIndex: l, diffBase: t };
|
|
1891
|
+
}
|
|
1892
|
+
async function Mt(e) {
|
|
1893
|
+
const t = Bs(e), n = mt();
|
|
1893
1894
|
if (n && !t)
|
|
1894
1895
|
throw new Error("Encrypted assets enabled but no key provided");
|
|
1895
|
-
if (
|
|
1896
|
-
const i = await
|
|
1896
|
+
if (Ce && (!n || Ze === (t ?? null))) {
|
|
1897
|
+
const i = await Ce;
|
|
1897
1898
|
return {
|
|
1898
|
-
...
|
|
1899
|
+
...et(i),
|
|
1899
1900
|
visemePaths: [...i.viseme.cellByPath.keys()]
|
|
1900
1901
|
};
|
|
1901
1902
|
}
|
|
1902
|
-
|
|
1903
|
-
const r =
|
|
1904
|
-
|
|
1905
|
-
const i = await
|
|
1906
|
-
|
|
1903
|
+
Ze = t ?? null, ft.clear();
|
|
1904
|
+
const r = Er();
|
|
1905
|
+
Ce = (async () => {
|
|
1906
|
+
const i = await Os(t), o = await cn(
|
|
1907
|
+
br(),
|
|
1907
1908
|
r,
|
|
1908
1909
|
n,
|
|
1909
1910
|
t
|
|
1910
1911
|
);
|
|
1911
1912
|
let a = null;
|
|
1912
1913
|
try {
|
|
1913
|
-
a = await
|
|
1914
|
-
|
|
1914
|
+
a = await cn(
|
|
1915
|
+
Tr(),
|
|
1915
1916
|
r,
|
|
1916
1917
|
n,
|
|
1917
1918
|
t
|
|
@@ -1921,221 +1922,340 @@ async function Tt(e) {
|
|
|
1921
1922
|
}
|
|
1922
1923
|
return { sil: i, viseme: o, expression: a };
|
|
1923
1924
|
})();
|
|
1924
|
-
const s = await
|
|
1925
|
-
return { ...
|
|
1925
|
+
const s = await Ce;
|
|
1926
|
+
return { ...et(s), visemePaths: [...s.viseme.cellByPath.keys()] };
|
|
1926
1927
|
}
|
|
1927
|
-
async function
|
|
1928
|
-
if (await
|
|
1929
|
-
return
|
|
1928
|
+
async function On(e) {
|
|
1929
|
+
if (await Mt(e), !Ce) throw new Error("Assets not loaded");
|
|
1930
|
+
return Ce;
|
|
1930
1931
|
}
|
|
1931
|
-
function
|
|
1932
|
-
return
|
|
1932
|
+
function et(e) {
|
|
1933
|
+
return Xr(
|
|
1933
1934
|
e.viseme.atlasMeta,
|
|
1934
1935
|
e.sil.naturalWidth,
|
|
1935
1936
|
e.sil.naturalHeight
|
|
1936
1937
|
);
|
|
1937
1938
|
}
|
|
1938
|
-
function
|
|
1939
|
+
function Ls(e, t) {
|
|
1939
1940
|
const n = document.createElement("canvas");
|
|
1940
1941
|
return n.width = t.w, n.height = t.h, n.getContext("2d", { willReadFrequently: !0 }).drawImage(e.atlas, t.x, t.y, t.w, t.h, 0, 0, t.w, t.h), n;
|
|
1941
1942
|
}
|
|
1942
|
-
async function
|
|
1943
|
-
const r = `${t.diffBase}::${n}`, s =
|
|
1943
|
+
async function un(e, t, n) {
|
|
1944
|
+
const r = `${t.diffBase}::${n}`, s = ft.get(r);
|
|
1944
1945
|
if (s) return s;
|
|
1945
1946
|
const i = (async () => {
|
|
1946
1947
|
const o = t.cellByPath.get(n);
|
|
1947
1948
|
if (!o) throw new Error(`No atlas cell for path: ${n}`);
|
|
1948
|
-
const a =
|
|
1949
|
-
if (
|
|
1950
|
-
const
|
|
1951
|
-
|
|
1952
|
-
const
|
|
1953
|
-
return
|
|
1949
|
+
const a = Zr(t.atlasMeta, o), l = et(e);
|
|
1950
|
+
if (es(o)) {
|
|
1951
|
+
const _ = Ls(t, o), m = document.createElement("canvas");
|
|
1952
|
+
m.width = l.width, m.height = l.height;
|
|
1953
|
+
const p = m.getContext("2d");
|
|
1954
|
+
return p.fillStyle = "#000", p.fillRect(0, 0, l.width, l.height), p.drawImage(_, a.x, a.y), m;
|
|
1954
1955
|
}
|
|
1955
|
-
const
|
|
1956
|
-
if (
|
|
1957
|
-
return
|
|
1956
|
+
const f = `${t.diffBase}/${n}`, u = await Wt(f);
|
|
1957
|
+
if (u.naturalWidth === l.width && u.naturalHeight === l.height)
|
|
1958
|
+
return u;
|
|
1958
1959
|
throw new Error(`Diff PNG wrong size for ${n}`);
|
|
1959
1960
|
})();
|
|
1960
|
-
return
|
|
1961
|
+
return ft.set(r, i), i;
|
|
1961
1962
|
}
|
|
1962
|
-
async function
|
|
1963
|
+
async function ln(e, t, n, r, s, i) {
|
|
1963
1964
|
if (s) {
|
|
1964
|
-
const { width:
|
|
1965
|
+
const { width: p, height: v } = s;
|
|
1965
1966
|
if (i && !i() || t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA)
|
|
1966
1967
|
return;
|
|
1967
|
-
const
|
|
1968
|
-
|
|
1969
|
-
const
|
|
1970
|
-
if (
|
|
1971
|
-
(e.width !==
|
|
1972
|
-
const
|
|
1973
|
-
|
|
1968
|
+
const d = document.createElement("canvas");
|
|
1969
|
+
d.width = p, d.height = v;
|
|
1970
|
+
const y = d.getContext("2d");
|
|
1971
|
+
if (y.clearRect(0, 0, p, v), y.drawImage(t, 0, 0, p, v), i && !i()) return;
|
|
1972
|
+
(e.width !== p || e.height !== v) && (e.width = p, e.height = v);
|
|
1973
|
+
const h = e.getContext("2d");
|
|
1974
|
+
h.clearRect(0, 0, p, v), h.drawImage(d, 0, 0);
|
|
1974
1975
|
return;
|
|
1975
1976
|
}
|
|
1976
|
-
const o = await
|
|
1977
|
-
(e.width !==
|
|
1978
|
-
const
|
|
1979
|
-
if (
|
|
1980
|
-
const
|
|
1981
|
-
|
|
1977
|
+
const o = await On(), a = Mn(o.viseme.atlasMeta), { width: l, height: f } = et(o);
|
|
1978
|
+
(e.width !== l || e.height !== f) && (e.width = l, e.height = f);
|
|
1979
|
+
const u = [], _ = e.getContext("2d");
|
|
1980
|
+
if (_.clearRect(0, 0, l, f), t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA) {
|
|
1981
|
+
const p = o.sil;
|
|
1982
|
+
_.drawImage(p, 0, 0, l, f);
|
|
1982
1983
|
return;
|
|
1983
1984
|
}
|
|
1984
|
-
if (
|
|
1985
|
-
|
|
1985
|
+
if (u.length === 0) {
|
|
1986
|
+
_.drawImage(t, 0, 0, l, f);
|
|
1986
1987
|
return;
|
|
1987
1988
|
}
|
|
1988
|
-
const
|
|
1989
|
-
|
|
1989
|
+
const m = Bn(t, u, l, f, a);
|
|
1990
|
+
_.drawImage(m, 0, 0);
|
|
1990
1991
|
}
|
|
1991
|
-
async function
|
|
1992
|
-
const r = await
|
|
1992
|
+
async function Ct(e, t, n) {
|
|
1993
|
+
const r = await On(Ze ?? void 0), s = Mn(r.viseme.atlasMeta), { width: i, height: o } = et(r);
|
|
1993
1994
|
(e.width !== i || e.height !== o) && (e.width = i, e.height = o);
|
|
1994
1995
|
const a = [];
|
|
1995
1996
|
if (t.mouthPath) {
|
|
1996
|
-
const
|
|
1997
|
-
|
|
1997
|
+
const u = new Set(r.viseme.cellByPath.keys()), _ = os(t.mouthPath, u) ?? (u.has(t.mouthPath) ? t.mouthPath : null);
|
|
1998
|
+
_ && a.push(await un(r, r.viseme, _));
|
|
1998
1999
|
}
|
|
1999
2000
|
t.expressionPath && r.expression && a.push(
|
|
2000
|
-
await
|
|
2001
|
+
await un(r, r.expression, t.expressionPath)
|
|
2001
2002
|
);
|
|
2002
|
-
const
|
|
2003
|
-
if (
|
|
2004
|
-
|
|
2003
|
+
const l = e.getContext("2d");
|
|
2004
|
+
if (l.clearRect(0, 0, i, o), a.length === 0) {
|
|
2005
|
+
l.drawImage(r.sil, 0, 0, i, o);
|
|
2005
2006
|
return;
|
|
2006
2007
|
}
|
|
2007
|
-
const
|
|
2008
|
+
const f = Bn(
|
|
2008
2009
|
r.sil,
|
|
2009
2010
|
a,
|
|
2010
2011
|
i,
|
|
2011
2012
|
o,
|
|
2012
2013
|
s
|
|
2013
2014
|
);
|
|
2014
|
-
|
|
2015
|
+
l.drawImage(f, 0, 0);
|
|
2015
2016
|
}
|
|
2016
|
-
async function
|
|
2017
|
-
await
|
|
2017
|
+
async function Us(e) {
|
|
2018
|
+
await Ct(e, { mouthPath: null, expressionPath: null });
|
|
2018
2019
|
}
|
|
2019
|
-
function
|
|
2020
|
+
function Ns(e) {
|
|
2020
2021
|
const t = /* @__PURE__ */ new Map();
|
|
2021
2022
|
for (const n of e)
|
|
2022
2023
|
t.has(n.vtime) || t.set(n.vtime, n);
|
|
2023
2024
|
return [...t.values()].sort((n, r) => n.vtime - r.vtime);
|
|
2024
2025
|
}
|
|
2025
|
-
function
|
|
2026
|
-
const t =
|
|
2026
|
+
function Vs(e) {
|
|
2027
|
+
const t = Ns(e), n = [];
|
|
2027
2028
|
for (let r = 0; r < t.length - 1; r++) {
|
|
2028
2029
|
const s = t[r].viseme, i = t[r + 1].viseme, o = t[r].vtime, a = t[r + 1].vtime;
|
|
2029
2030
|
s === i || a <= o || n.push({ from: s, to: i, fromVtime: o, toVtime: a });
|
|
2030
2031
|
}
|
|
2031
2032
|
return n;
|
|
2032
2033
|
}
|
|
2033
|
-
function
|
|
2034
|
+
function $s(e, t) {
|
|
2034
2035
|
let n = null;
|
|
2035
2036
|
for (const r of e)
|
|
2036
2037
|
t >= r.fromVtime && t < r.toVtime && (n = r);
|
|
2037
2038
|
return n;
|
|
2038
2039
|
}
|
|
2039
|
-
function
|
|
2040
|
+
function Ws(e, t) {
|
|
2040
2041
|
return { gapMs: Math.max(0, t - e), holdEnd: e, transStart: e };
|
|
2041
2042
|
}
|
|
2042
|
-
|
|
2043
|
-
function
|
|
2044
|
-
|
|
2043
|
+
let Ln = null;
|
|
2044
|
+
function fn(e) {
|
|
2045
|
+
Ln = e;
|
|
2045
2046
|
}
|
|
2046
|
-
function
|
|
2047
|
+
function dt() {
|
|
2048
|
+
return Ln;
|
|
2049
|
+
}
|
|
2050
|
+
function qs(e) {
|
|
2051
|
+
return `${e.from}→${e.to}@${e.fromVtime}`;
|
|
2052
|
+
}
|
|
2053
|
+
function dn() {
|
|
2054
|
+
return {
|
|
2055
|
+
rafTicksSpeaking: 0,
|
|
2056
|
+
rafTicksDeduped: 0,
|
|
2057
|
+
drawsRequested: 0,
|
|
2058
|
+
drawsDisplayed: 0,
|
|
2059
|
+
queueSuperseded: 0,
|
|
2060
|
+
workerStale: 0,
|
|
2061
|
+
rifeFramesOmittedByGap: 0,
|
|
2062
|
+
transitionFramesSampled: 0,
|
|
2063
|
+
transitionFramesDisplayed: 0,
|
|
2064
|
+
transitionFramesMissed: 0
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2067
|
+
function Hs() {
|
|
2068
|
+
let e = dn();
|
|
2069
|
+
const t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set();
|
|
2070
|
+
let s = "", i = -1, o = "";
|
|
2071
|
+
const a = () => {
|
|
2072
|
+
e = dn(), t.clear(), n.clear(), r.clear(), s = "", i = -1, o = "";
|
|
2073
|
+
}, l = (u) => {
|
|
2074
|
+
t.add(u);
|
|
2075
|
+
}, f = (u) => {
|
|
2076
|
+
u && r.add(u);
|
|
2077
|
+
};
|
|
2078
|
+
return {
|
|
2079
|
+
reset: a,
|
|
2080
|
+
onRafTickSpeaking() {
|
|
2081
|
+
e.rafTicksSpeaking += 1;
|
|
2082
|
+
},
|
|
2083
|
+
onDrawDeduped() {
|
|
2084
|
+
e.rafTicksDeduped += 1;
|
|
2085
|
+
},
|
|
2086
|
+
onDrawRequested() {
|
|
2087
|
+
e.drawsRequested += 1;
|
|
2088
|
+
},
|
|
2089
|
+
onQueueSuperseded() {
|
|
2090
|
+
e.queueSuperseded += 1;
|
|
2091
|
+
},
|
|
2092
|
+
onWorkerStale() {
|
|
2093
|
+
e.workerStale += 1;
|
|
2094
|
+
},
|
|
2095
|
+
onTransitionSample(u, _) {
|
|
2096
|
+
const m = qs(u);
|
|
2097
|
+
e.transitionFramesSampled += 1, m !== s && (s = m, i = -1, o !== m && (o = m, e.rifeFramesOmittedByGap += u.omittedByGap)), _ && n.add(_), i >= 0 && u.frameIdx > i + 1 && (e.transitionFramesMissed += u.frameIdx - i - 1), i = u.frameIdx;
|
|
2098
|
+
},
|
|
2099
|
+
onDrawDisplayed(u, _) {
|
|
2100
|
+
if (e.drawsDisplayed += 1, u.transitionMeta) {
|
|
2101
|
+
e.transitionFramesDisplayed += 1;
|
|
2102
|
+
const p = u.transitionMeta;
|
|
2103
|
+
l(p.fromVtime), l(p.toVtime), f(u.mouthPath);
|
|
2104
|
+
return;
|
|
2105
|
+
}
|
|
2106
|
+
if (u.label.includes("→")) {
|
|
2107
|
+
e.transitionFramesDisplayed += 1;
|
|
2108
|
+
return;
|
|
2109
|
+
}
|
|
2110
|
+
const m = u.label.trim();
|
|
2111
|
+
if (!(!m || m === "sil")) {
|
|
2112
|
+
for (const p of _)
|
|
2113
|
+
if (p.viseme === m && u.elapsedMs >= p.vtime && u.elapsedMs < p.vtime + p.vduration) {
|
|
2114
|
+
l(p.vtime);
|
|
2115
|
+
break;
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
},
|
|
2119
|
+
snapshot(u, _) {
|
|
2120
|
+
let m = 0, p = 0;
|
|
2121
|
+
for (const h of u)
|
|
2122
|
+
if (h.viseme !== "sil") {
|
|
2123
|
+
if (h.vtime >= _) break;
|
|
2124
|
+
m += 1, t.has(h.vtime) && (p += 1);
|
|
2125
|
+
}
|
|
2126
|
+
const v = m > 0 ? Math.round(p / m * 100) : 100, d = e.queueSuperseded + e.workerStale + Math.max(0, e.drawsRequested - e.drawsDisplayed), y = m - p;
|
|
2127
|
+
return {
|
|
2128
|
+
...e,
|
|
2129
|
+
renderLoss: d,
|
|
2130
|
+
visemeSlotsTotal: m,
|
|
2131
|
+
visemeSlotsCovered: p,
|
|
2132
|
+
visemeCoveragePct: v,
|
|
2133
|
+
transitionFramesUniqueSampled: n.size,
|
|
2134
|
+
transitionFramesUniquePainted: r.size,
|
|
2135
|
+
drawsDeduped: e.rafTicksDeduped,
|
|
2136
|
+
renderSkips: e.rafTicksDeduped + d,
|
|
2137
|
+
visemesShown: p,
|
|
2138
|
+
visemesSkipped: y,
|
|
2139
|
+
rifeTransitionFramesSkipped: e.transitionFramesMissed
|
|
2140
|
+
};
|
|
2141
|
+
}
|
|
2142
|
+
};
|
|
2143
|
+
}
|
|
2144
|
+
const Un = 400, Ks = 200, js = 600, Nn = "__sil__";
|
|
2145
|
+
function Gs(e) {
|
|
2146
|
+
return e.lastDrawnKey ? e.lastDrawnKey.split("|")[0] === Nn : !1;
|
|
2147
|
+
}
|
|
2148
|
+
function zs() {
|
|
2047
2149
|
return { lastDrawnKey: "" };
|
|
2048
2150
|
}
|
|
2049
|
-
function
|
|
2151
|
+
function _e(e) {
|
|
2050
2152
|
e.lastDrawnKey = "", e.transitionCache = void 0;
|
|
2051
2153
|
}
|
|
2052
|
-
function
|
|
2154
|
+
function Qs(e, t) {
|
|
2053
2155
|
if (t?.transitionCache && t.transitionCache.queueLength === e.length)
|
|
2054
2156
|
return t.transitionCache.transitions;
|
|
2055
|
-
const n =
|
|
2157
|
+
const n = Vs(e);
|
|
2056
2158
|
return t && (t.transitionCache = { queueLength: e.length, transitions: n }), n;
|
|
2057
2159
|
}
|
|
2058
|
-
function
|
|
2160
|
+
function Ys(e, t) {
|
|
2059
2161
|
let n = "sil";
|
|
2060
2162
|
for (const r of e)
|
|
2061
2163
|
r.viseme !== "sil" && (t != null && r.vtime > t || (n = r.viseme));
|
|
2062
2164
|
return n;
|
|
2063
2165
|
}
|
|
2064
|
-
function
|
|
2166
|
+
function Js(e, t, n, r = 120) {
|
|
2065
2167
|
if (n !== "sil")
|
|
2066
2168
|
return n;
|
|
2067
|
-
const s =
|
|
2068
|
-
return s !== "sil" ? s :
|
|
2169
|
+
const s = Wr(e, t, r);
|
|
2170
|
+
return s !== "sil" ? s : Ys(e, t);
|
|
2069
2171
|
}
|
|
2070
|
-
function
|
|
2071
|
-
return e === "sil" ? !1 : t ?
|
|
2172
|
+
function Xs(e, t) {
|
|
2173
|
+
return e === "sil" ? !1 : t ? cs(e, "sil", t) : Nt(e, "sil").length > 0;
|
|
2072
2174
|
}
|
|
2073
|
-
function
|
|
2074
|
-
return
|
|
2175
|
+
function Zs() {
|
|
2176
|
+
return Un + js;
|
|
2075
2177
|
}
|
|
2076
|
-
function
|
|
2077
|
-
return e ??
|
|
2178
|
+
function mn(e) {
|
|
2179
|
+
return e ?? Nn;
|
|
2078
2180
|
}
|
|
2079
|
-
function
|
|
2181
|
+
function ei(e, t, n, r) {
|
|
2080
2182
|
if (e.length === 0)
|
|
2081
2183
|
return { diffPath: null, label: "sil" };
|
|
2082
|
-
const s =
|
|
2184
|
+
const s = Qs(e, r), i = $s(s, t);
|
|
2083
2185
|
if (i) {
|
|
2084
|
-
const a = i.toVtime - i.fromVtime,
|
|
2085
|
-
if (t >=
|
|
2086
|
-
let
|
|
2087
|
-
n && (
|
|
2088
|
-
const
|
|
2089
|
-
if (
|
|
2090
|
-
const
|
|
2186
|
+
const a = i.toVtime - i.fromVtime, l = Ws(i.fromVtime, i.toVtime);
|
|
2187
|
+
if (t >= l.transStart && t < i.toVtime) {
|
|
2188
|
+
let f = Nt(i.from, i.to);
|
|
2189
|
+
n && (f = Cn(f, n));
|
|
2190
|
+
const u = ls(f, a);
|
|
2191
|
+
if (u.length > 0) {
|
|
2192
|
+
const _ = fs(
|
|
2091
2193
|
t,
|
|
2092
|
-
|
|
2194
|
+
l.transStart,
|
|
2093
2195
|
i.toVtime,
|
|
2094
|
-
|
|
2196
|
+
u.length
|
|
2095
2197
|
);
|
|
2096
|
-
return {
|
|
2198
|
+
return {
|
|
2199
|
+
diffPath: u[_] ?? u[u.length - 1],
|
|
2200
|
+
label: `${i.from}→${i.to}`,
|
|
2201
|
+
transitionMeta: {
|
|
2202
|
+
from: i.from,
|
|
2203
|
+
to: i.to,
|
|
2204
|
+
fromVtime: i.fromVtime,
|
|
2205
|
+
toVtime: i.toVtime,
|
|
2206
|
+
frameIdx: _,
|
|
2207
|
+
frameCount: u.length,
|
|
2208
|
+
fullFrameCount: f.length,
|
|
2209
|
+
omittedByGap: Math.max(0, f.length - u.length)
|
|
2210
|
+
}
|
|
2211
|
+
};
|
|
2097
2212
|
}
|
|
2098
|
-
return { diffPath:
|
|
2213
|
+
return { diffPath: lt(i.to), label: i.to };
|
|
2099
2214
|
}
|
|
2100
2215
|
}
|
|
2101
|
-
const o =
|
|
2102
|
-
return o === "sil" ? { diffPath: null, label: "sil" } : { diffPath:
|
|
2216
|
+
const o = ht(e, t);
|
|
2217
|
+
return o === "sil" ? { diffPath: null, label: "sil" } : { diffPath: lt(o), label: o };
|
|
2103
2218
|
}
|
|
2104
|
-
function
|
|
2105
|
-
const n = t ??
|
|
2106
|
-
return `${
|
|
2219
|
+
function Vn(e, t) {
|
|
2220
|
+
const n = t ?? mn(e.expressionPath);
|
|
2221
|
+
return `${mn(e.mouthPath)}|${n}`;
|
|
2107
2222
|
}
|
|
2108
|
-
function
|
|
2109
|
-
const
|
|
2110
|
-
mouthPath:
|
|
2223
|
+
function ti(e, t, n, r, s, i, o, a, l, f) {
|
|
2224
|
+
const u = ei(t, n, l, i), _ = {
|
|
2225
|
+
mouthPath: u.diffPath,
|
|
2111
2226
|
expressionPath: r
|
|
2112
|
-
},
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2227
|
+
}, m = Vn(_, s), p = dt();
|
|
2228
|
+
if (u.transitionMeta && p?.onTransitionSample(u.transitionMeta, u.diffPath), m === i.lastDrawnKey) {
|
|
2229
|
+
p?.onDrawDeduped();
|
|
2230
|
+
return;
|
|
2231
|
+
}
|
|
2232
|
+
p?.onDrawRequested(), a(u), o(e, _, m, (v) => {
|
|
2233
|
+
v === m && (i.lastDrawnKey = m);
|
|
2234
|
+
});
|
|
2116
2235
|
}
|
|
2117
|
-
function
|
|
2118
|
-
const a = { mouthPath: null, expressionPath: t },
|
|
2119
|
-
!(o != null) &&
|
|
2236
|
+
function hn(e, t, n, r, s, i, o = null) {
|
|
2237
|
+
const a = { mouthPath: null, expressionPath: t }, l = o != null ? `|idle@${Math.round(o * 1e3)}` : "", f = Vn(a, n) + l;
|
|
2238
|
+
!(o != null) && f === r.lastDrawnKey || (i(
|
|
2120
2239
|
o != null ? "idle" : "sil"
|
|
2121
|
-
), s(e, a,
|
|
2122
|
-
|
|
2240
|
+
), s(e, a, f, (_) => {
|
|
2241
|
+
_ === f && (r.lastDrawnKey = f);
|
|
2123
2242
|
}));
|
|
2124
2243
|
}
|
|
2125
|
-
|
|
2126
|
-
|
|
2244
|
+
const ni = 3;
|
|
2245
|
+
function $n(e) {
|
|
2246
|
+
let t = 0;
|
|
2247
|
+
const n = [];
|
|
2248
|
+
let r = !1, s = !1;
|
|
2127
2249
|
const i = async () => {
|
|
2128
2250
|
if (!r) {
|
|
2129
2251
|
r = !0;
|
|
2130
2252
|
try {
|
|
2131
|
-
for (; n; ) {
|
|
2132
|
-
const a = n;
|
|
2133
|
-
n
|
|
2134
|
-
const u = ++t, l = await e(a.diffs, u, a);
|
|
2135
|
-
n || l && u === t && a.onDisplayed?.(a.drawKey);
|
|
2253
|
+
for (; n.length > 0; ) {
|
|
2254
|
+
const a = n.shift(), l = ++t, f = await e(a.diffs, l, a);
|
|
2255
|
+
n.length > 0 || f && l === t && a.onDisplayed?.(a.drawKey);
|
|
2136
2256
|
}
|
|
2137
2257
|
} finally {
|
|
2138
|
-
r = !1, n && i();
|
|
2258
|
+
r = !1, n.length > 0 && i();
|
|
2139
2259
|
}
|
|
2140
2260
|
}
|
|
2141
2261
|
}, o = () => {
|
|
@@ -2144,11 +2264,12 @@ function In(e) {
|
|
|
2144
2264
|
}));
|
|
2145
2265
|
};
|
|
2146
2266
|
return {
|
|
2147
|
-
enqueue(a,
|
|
2148
|
-
|
|
2267
|
+
enqueue(a, l, f) {
|
|
2268
|
+
const u = n.findIndex((_) => _.drawKey === l);
|
|
2269
|
+
u >= 0 ? n[u] = { diffs: a, drawKey: l, onDisplayed: f } : (n.length >= ni && (n.shift(), dt()?.onQueueSuperseded()), n.push({ diffs: a, drawKey: l, onDisplayed: f })), o();
|
|
2149
2270
|
},
|
|
2150
2271
|
reset() {
|
|
2151
|
-
t += 1, n =
|
|
2272
|
+
t += 1, n.length = 0;
|
|
2152
2273
|
},
|
|
2153
2274
|
isLatestSeq(a) {
|
|
2154
2275
|
return a === t;
|
|
@@ -2158,9 +2279,9 @@ function In(e) {
|
|
|
2158
2279
|
}
|
|
2159
2280
|
};
|
|
2160
2281
|
}
|
|
2161
|
-
const
|
|
2162
|
-
async function
|
|
2163
|
-
let t =
|
|
2282
|
+
const wn = -1, gn = /* @__PURE__ */ new Map();
|
|
2283
|
+
async function ri(e) {
|
|
2284
|
+
let t = gn.get(e);
|
|
2164
2285
|
if (!t) {
|
|
2165
2286
|
const n = await fetch(e);
|
|
2166
2287
|
if (!n.ok)
|
|
@@ -2168,41 +2289,41 @@ async function Vs(e) {
|
|
|
2168
2289
|
`Failed to fetch worker script (${n.status}): ${e}`
|
|
2169
2290
|
);
|
|
2170
2291
|
const r = await n.blob();
|
|
2171
|
-
t = URL.createObjectURL(r),
|
|
2292
|
+
t = URL.createObjectURL(r), gn.set(e, t);
|
|
2172
2293
|
}
|
|
2173
2294
|
return new Worker(t, { name: "visemeDiffPreview" });
|
|
2174
2295
|
}
|
|
2175
|
-
function
|
|
2296
|
+
function si() {
|
|
2176
2297
|
return typeof Worker < "u" && typeof OffscreenCanvas < "u";
|
|
2177
2298
|
}
|
|
2178
|
-
function
|
|
2299
|
+
function ii(e, t) {
|
|
2179
2300
|
(e.width !== t.width || e.height !== t.height) && (e.width = t.width, e.height = t.height);
|
|
2180
2301
|
const n = e.getContext("2d");
|
|
2181
2302
|
n && n.drawImage(t, 0, 0);
|
|
2182
2303
|
}
|
|
2183
|
-
function
|
|
2304
|
+
function pn(e, t) {
|
|
2184
2305
|
let n = 0, r = null;
|
|
2185
|
-
const s =
|
|
2306
|
+
const s = $n(async (i, o) => (await Mt(), await Ct(e, i), s.isLatestSeq(o)));
|
|
2186
2307
|
return {
|
|
2187
2308
|
usesWorker: !1,
|
|
2188
2309
|
async loadAssets(i) {
|
|
2189
|
-
const o = await
|
|
2310
|
+
const o = await Mt(i);
|
|
2190
2311
|
return r = o.visemePaths ? new Set(o.visemePaths) : null, o;
|
|
2191
2312
|
},
|
|
2192
2313
|
getVisemeAtlasPaths() {
|
|
2193
2314
|
return r;
|
|
2194
2315
|
},
|
|
2195
2316
|
async renderSilOnly() {
|
|
2196
|
-
n += 1, s.reset(), await
|
|
2317
|
+
n += 1, s.reset(), await Us(e);
|
|
2197
2318
|
},
|
|
2198
|
-
drawLiveFrame(i, o, a,
|
|
2199
|
-
s.enqueue(o, a,
|
|
2319
|
+
drawLiveFrame(i, o, a, l) {
|
|
2320
|
+
s.enqueue(o, a, l);
|
|
2200
2321
|
},
|
|
2201
2322
|
async renderViseme(i, o) {
|
|
2202
2323
|
n += 1;
|
|
2203
2324
|
const a = n;
|
|
2204
|
-
t.onStatus?.(o), await
|
|
2205
|
-
mouthPath:
|
|
2325
|
+
t.onStatus?.(o), await Ct(i, {
|
|
2326
|
+
mouthPath: lt(o),
|
|
2206
2327
|
expressionPath: null
|
|
2207
2328
|
});
|
|
2208
2329
|
},
|
|
@@ -2211,183 +2332,183 @@ function rn(e, t) {
|
|
|
2211
2332
|
}
|
|
2212
2333
|
};
|
|
2213
2334
|
}
|
|
2214
|
-
function
|
|
2215
|
-
let r = null, s = 1, i = 0, o = !1, a = !1,
|
|
2216
|
-
const
|
|
2217
|
-
drawKey:
|
|
2218
|
-
onDisplayed:
|
|
2219
|
-
}), await
|
|
2335
|
+
function ai(e, t, n) {
|
|
2336
|
+
let r = null, s = 1, i = 0, o = !1, a = !1, l = null;
|
|
2337
|
+
const f = /* @__PURE__ */ new Map(), u = $n(async (y, h, E) => (f.set(h, {
|
|
2338
|
+
drawKey: E.drawKey,
|
|
2339
|
+
onDisplayed: E.onDisplayed
|
|
2340
|
+
}), await v(
|
|
2220
2341
|
{
|
|
2221
2342
|
type: "drawFrame",
|
|
2222
|
-
diffPath:
|
|
2223
|
-
expressionDiffPath:
|
|
2224
|
-
liveSeq:
|
|
2343
|
+
diffPath: y.mouthPath,
|
|
2344
|
+
expressionDiffPath: y.expressionPath,
|
|
2345
|
+
liveSeq: h
|
|
2225
2346
|
},
|
|
2226
2347
|
void 0,
|
|
2227
2348
|
!0
|
|
2228
|
-
), !1)),
|
|
2229
|
-
if (
|
|
2230
|
-
let
|
|
2231
|
-
for (const [
|
|
2232
|
-
|
|
2233
|
-
|
|
2349
|
+
), !1)), _ = (y) => {
|
|
2350
|
+
if (y === wn) {
|
|
2351
|
+
let b = -1, V;
|
|
2352
|
+
for (const [Q, N] of f)
|
|
2353
|
+
Q >= b && (b = Q, V = N);
|
|
2354
|
+
b >= 0 && f.delete(b), V?.onDisplayed?.(V.drawKey);
|
|
2234
2355
|
return;
|
|
2235
2356
|
}
|
|
2236
|
-
const
|
|
2237
|
-
|
|
2238
|
-
},
|
|
2239
|
-
a || !r || r.postMessage(
|
|
2240
|
-
},
|
|
2357
|
+
const h = -y, E = f.get(h);
|
|
2358
|
+
f.delete(h), E?.onDisplayed?.(E.drawKey);
|
|
2359
|
+
}, m = /* @__PURE__ */ new Map(), p = (y, h) => {
|
|
2360
|
+
a || !r || r.postMessage(y, []);
|
|
2361
|
+
}, v = (y, h, E = !1) => {
|
|
2241
2362
|
if (a) return Promise.resolve();
|
|
2242
|
-
const
|
|
2243
|
-
return new Promise((
|
|
2244
|
-
|
|
2245
|
-
resolve: (
|
|
2246
|
-
reject:
|
|
2247
|
-
generation: typeof
|
|
2248
|
-
expectRenderDone:
|
|
2249
|
-
}),
|
|
2363
|
+
const b = s++;
|
|
2364
|
+
return new Promise((V, Q) => {
|
|
2365
|
+
m.set(b, {
|
|
2366
|
+
resolve: (N) => V(N),
|
|
2367
|
+
reject: Q,
|
|
2368
|
+
generation: typeof y.generation == "number" ? y.generation : void 0,
|
|
2369
|
+
expectRenderDone: E
|
|
2370
|
+
}), p({ ...y, requestId: b });
|
|
2250
2371
|
});
|
|
2251
|
-
},
|
|
2252
|
-
r = await
|
|
2372
|
+
}, d = (async () => {
|
|
2373
|
+
r = await ri(n), r.onmessage = (y) => {
|
|
2253
2374
|
if (a) return;
|
|
2254
|
-
const
|
|
2255
|
-
if (
|
|
2256
|
-
t.onStatus?.(
|
|
2375
|
+
const h = y.data;
|
|
2376
|
+
if (h.type === "status") {
|
|
2377
|
+
t.onStatus?.(h.label);
|
|
2257
2378
|
return;
|
|
2258
2379
|
}
|
|
2259
|
-
if (
|
|
2260
|
-
const
|
|
2261
|
-
if (!
|
|
2262
|
-
|
|
2380
|
+
if (h.type === "frame") {
|
|
2381
|
+
const b = h.generation < 0;
|
|
2382
|
+
if (!b && h.generation !== i) {
|
|
2383
|
+
h.bitmap.close();
|
|
2263
2384
|
return;
|
|
2264
2385
|
}
|
|
2265
|
-
if (
|
|
2266
|
-
const
|
|
2267
|
-
if (!
|
|
2268
|
-
|
|
2386
|
+
if (b && !(h.generation === wn)) {
|
|
2387
|
+
const Q = -h.generation;
|
|
2388
|
+
if (!u.isLatestSeq(Q)) {
|
|
2389
|
+
dt()?.onWorkerStale(), h.bitmap.close();
|
|
2269
2390
|
return;
|
|
2270
2391
|
}
|
|
2271
2392
|
}
|
|
2272
|
-
if (
|
|
2273
|
-
|
|
2393
|
+
if (b && t.shouldAcceptLiveFrame && !t.shouldAcceptLiveFrame()) {
|
|
2394
|
+
dt()?.onWorkerStale(), h.bitmap.close();
|
|
2274
2395
|
return;
|
|
2275
2396
|
}
|
|
2276
|
-
|
|
2397
|
+
ii(e, h.bitmap), h.bitmap.close(), b && _(h.generation);
|
|
2277
2398
|
return;
|
|
2278
2399
|
}
|
|
2279
|
-
const
|
|
2280
|
-
if (
|
|
2281
|
-
switch (
|
|
2400
|
+
const E = m.get(h.requestId);
|
|
2401
|
+
if (E)
|
|
2402
|
+
switch (h.type) {
|
|
2282
2403
|
case "ready":
|
|
2283
|
-
|
|
2404
|
+
m.delete(h.requestId), E.resolve();
|
|
2284
2405
|
break;
|
|
2285
2406
|
case "loadAssetsDone":
|
|
2286
|
-
|
|
2407
|
+
m.delete(h.requestId), l = h.visemePaths?.length ? new Set(h.visemePaths) : null, E.resolve({ width: h.width, height: h.height, visemePaths: h.visemePaths });
|
|
2287
2408
|
break;
|
|
2288
2409
|
case "renderDone":
|
|
2289
|
-
if (
|
|
2410
|
+
if (E.expectRenderDone && E.generation != null && h.generation !== E.generation)
|
|
2290
2411
|
return;
|
|
2291
|
-
|
|
2412
|
+
m.delete(h.requestId), E.resolve();
|
|
2292
2413
|
break;
|
|
2293
2414
|
case "renderAborted":
|
|
2294
|
-
|
|
2415
|
+
m.delete(h.requestId), E.resolve();
|
|
2295
2416
|
break;
|
|
2296
2417
|
case "error":
|
|
2297
|
-
|
|
2418
|
+
m.delete(h.requestId), t.onError?.(h.message), E.reject(new Error(h.message));
|
|
2298
2419
|
break;
|
|
2299
2420
|
}
|
|
2300
|
-
}, r.onerror = (
|
|
2421
|
+
}, r.onerror = (y) => {
|
|
2301
2422
|
if (a) return;
|
|
2302
|
-
const
|
|
2303
|
-
t.onError?.(
|
|
2304
|
-
for (const [,
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
}, await
|
|
2423
|
+
const h = y.message || "Worker error";
|
|
2424
|
+
t.onError?.(h);
|
|
2425
|
+
for (const [, E] of m)
|
|
2426
|
+
E.reject(new Error(h));
|
|
2427
|
+
m.clear();
|
|
2428
|
+
}, await v({ type: "init" }), o = !0;
|
|
2308
2429
|
})();
|
|
2309
2430
|
return {
|
|
2310
2431
|
usesWorker: !0,
|
|
2311
|
-
async loadAssets(
|
|
2432
|
+
async loadAssets(y) {
|
|
2312
2433
|
if (a) return { width: 842, height: 1264 };
|
|
2313
|
-
if (await
|
|
2434
|
+
if (await d, a) return { width: 842, height: 1264 };
|
|
2314
2435
|
if (!o) throw new Error("Worker init failed");
|
|
2315
|
-
return await
|
|
2436
|
+
return await v({
|
|
2316
2437
|
type: "loadAssets",
|
|
2317
|
-
keyHex:
|
|
2318
|
-
urls:
|
|
2438
|
+
keyHex: y,
|
|
2439
|
+
urls: Sr(Pe())
|
|
2319
2440
|
}) ?? { width: 842, height: 1264 };
|
|
2320
2441
|
},
|
|
2321
2442
|
getVisemeAtlasPaths() {
|
|
2322
|
-
return
|
|
2443
|
+
return l;
|
|
2323
2444
|
},
|
|
2324
2445
|
async renderSilOnly() {
|
|
2325
|
-
if (a || (await
|
|
2326
|
-
i += 1,
|
|
2327
|
-
const
|
|
2328
|
-
await
|
|
2329
|
-
{ type: "renderSil", generation:
|
|
2446
|
+
if (a || (await d, a)) return;
|
|
2447
|
+
i += 1, u.reset(), f.clear();
|
|
2448
|
+
const y = i;
|
|
2449
|
+
await v({ type: "cancelLiveDraws" }), await v(
|
|
2450
|
+
{ type: "renderSil", generation: y },
|
|
2330
2451
|
void 0,
|
|
2331
2452
|
!0
|
|
2332
2453
|
);
|
|
2333
2454
|
},
|
|
2334
|
-
drawLiveFrame(
|
|
2335
|
-
a ||
|
|
2336
|
-
a ||
|
|
2455
|
+
drawLiveFrame(y, h, E, b) {
|
|
2456
|
+
a || d.then(() => {
|
|
2457
|
+
a || u.enqueue(h, E, b);
|
|
2337
2458
|
});
|
|
2338
2459
|
},
|
|
2339
|
-
async renderViseme(
|
|
2340
|
-
if (a || (await
|
|
2341
|
-
i += 1,
|
|
2342
|
-
const
|
|
2460
|
+
async renderViseme(y, h, E = {}) {
|
|
2461
|
+
if (a || (await d, a)) return;
|
|
2462
|
+
i += 1, u.reset(), f.clear();
|
|
2463
|
+
const b = i;
|
|
2343
2464
|
try {
|
|
2344
|
-
await
|
|
2465
|
+
await v({ type: "cancelLiveDraws" }), await v(
|
|
2345
2466
|
{
|
|
2346
2467
|
type: "renderViseme",
|
|
2347
|
-
generation:
|
|
2348
|
-
to:
|
|
2349
|
-
from:
|
|
2350
|
-
transitionDurationMs:
|
|
2351
|
-
gapMs:
|
|
2352
|
-
threshold:
|
|
2468
|
+
generation: b,
|
|
2469
|
+
to: h,
|
|
2470
|
+
from: E.from,
|
|
2471
|
+
transitionDurationMs: E.transitionDurationMs,
|
|
2472
|
+
gapMs: E.gapMs,
|
|
2473
|
+
threshold: E.threshold
|
|
2353
2474
|
},
|
|
2354
2475
|
void 0,
|
|
2355
2476
|
!0
|
|
2356
2477
|
);
|
|
2357
|
-
} catch (
|
|
2358
|
-
if (
|
|
2359
|
-
throw
|
|
2478
|
+
} catch (V) {
|
|
2479
|
+
if (V?.name === "AbortError") return;
|
|
2480
|
+
throw V;
|
|
2360
2481
|
}
|
|
2361
2482
|
},
|
|
2362
2483
|
dispose() {
|
|
2363
2484
|
if (!a) {
|
|
2364
|
-
a = !0, i += 1,
|
|
2365
|
-
for (const [,
|
|
2366
|
-
|
|
2367
|
-
|
|
2485
|
+
a = !0, i += 1, u.reset(), f.clear();
|
|
2486
|
+
for (const [, y] of m)
|
|
2487
|
+
y.resolve();
|
|
2488
|
+
m.clear(), r?.terminate(), r = null;
|
|
2368
2489
|
}
|
|
2369
2490
|
}
|
|
2370
2491
|
};
|
|
2371
2492
|
}
|
|
2372
|
-
function
|
|
2373
|
-
if (
|
|
2374
|
-
return
|
|
2375
|
-
const n =
|
|
2493
|
+
function oi(e, t = {}) {
|
|
2494
|
+
if (!si())
|
|
2495
|
+
return pn(e, t);
|
|
2496
|
+
const n = rr(t.workerScriptUrl);
|
|
2376
2497
|
try {
|
|
2377
|
-
return
|
|
2498
|
+
return ai(e, t, n);
|
|
2378
2499
|
} catch {
|
|
2379
|
-
return
|
|
2500
|
+
return pn(e, t);
|
|
2380
2501
|
}
|
|
2381
2502
|
}
|
|
2382
|
-
class
|
|
2503
|
+
class ci extends Error {
|
|
2383
2504
|
constructor(t, n) {
|
|
2384
2505
|
super(`${t} timed out after ${Math.round(n / 1e3)}s`), this.name = "LoadTimeoutError";
|
|
2385
2506
|
}
|
|
2386
2507
|
}
|
|
2387
|
-
function
|
|
2508
|
+
function bt(e, t, n) {
|
|
2388
2509
|
return new Promise((r, s) => {
|
|
2389
2510
|
const i = globalThis.setTimeout(() => {
|
|
2390
|
-
s(new
|
|
2511
|
+
s(new ci(n, t));
|
|
2391
2512
|
}, t);
|
|
2392
2513
|
e.then(
|
|
2393
2514
|
(o) => {
|
|
@@ -2399,15 +2520,15 @@ function yt(e, t, n) {
|
|
|
2399
2520
|
);
|
|
2400
2521
|
});
|
|
2401
2522
|
}
|
|
2402
|
-
const
|
|
2523
|
+
const ui = {
|
|
2403
2524
|
position: "relative",
|
|
2404
2525
|
display: "inline-block",
|
|
2405
2526
|
lineHeight: 0
|
|
2406
|
-
},
|
|
2527
|
+
}, li = {
|
|
2407
2528
|
display: "block",
|
|
2408
2529
|
maxWidth: "100%",
|
|
2409
2530
|
height: "auto"
|
|
2410
|
-
},
|
|
2531
|
+
}, fi = {
|
|
2411
2532
|
position: "absolute",
|
|
2412
2533
|
inset: 0,
|
|
2413
2534
|
display: "flex",
|
|
@@ -2419,13 +2540,13 @@ const js = {
|
|
|
2419
2540
|
fontSize: "0.875rem",
|
|
2420
2541
|
textAlign: "center"
|
|
2421
2542
|
};
|
|
2422
|
-
function
|
|
2423
|
-
return
|
|
2543
|
+
function Je(e) {
|
|
2544
|
+
return ar(e) ? An : Tn;
|
|
2424
2545
|
}
|
|
2425
|
-
function
|
|
2546
|
+
function Te(e, t) {
|
|
2426
2547
|
return t?.isSpeaking() ? t : e.isSpeaking() ? e : t?.isConnected() ? t : e;
|
|
2427
2548
|
}
|
|
2428
|
-
const
|
|
2549
|
+
const ki = jn(function({
|
|
2429
2550
|
id: t,
|
|
2430
2551
|
avatarId: n,
|
|
2431
2552
|
faceId: r,
|
|
@@ -2433,509 +2554,531 @@ const si = Mn(function({
|
|
|
2433
2554
|
authToken: i,
|
|
2434
2555
|
apiBase: o,
|
|
2435
2556
|
ttsEngineId: a = Le,
|
|
2436
|
-
voiceId:
|
|
2437
|
-
speakingRate:
|
|
2438
|
-
className:
|
|
2439
|
-
style:
|
|
2440
|
-
canvasStyle:
|
|
2441
|
-
onStatusChange:
|
|
2442
|
-
onDisplayStatus:
|
|
2443
|
-
onError:
|
|
2444
|
-
onReady:
|
|
2445
|
-
showErrorOverlay:
|
|
2446
|
-
onUserTranscript:
|
|
2447
|
-
onBotOutput:
|
|
2448
|
-
onRealtimeLipsyncDebug:
|
|
2449
|
-
|
|
2450
|
-
|
|
2557
|
+
voiceId: l,
|
|
2558
|
+
speakingRate: f = wt,
|
|
2559
|
+
className: u,
|
|
2560
|
+
style: _,
|
|
2561
|
+
canvasStyle: m,
|
|
2562
|
+
onStatusChange: p,
|
|
2563
|
+
onDisplayStatus: v,
|
|
2564
|
+
onError: d,
|
|
2565
|
+
onReady: y,
|
|
2566
|
+
showErrorOverlay: h = !0,
|
|
2567
|
+
onUserTranscript: E,
|
|
2568
|
+
onBotOutput: b,
|
|
2569
|
+
onRealtimeLipsyncDebug: V,
|
|
2570
|
+
onFrameRenderStats: Q
|
|
2571
|
+
}, N) {
|
|
2572
|
+
const G = P(null), Z = P(null), S = P(zs()), A = P(Rs()), M = P(0), I = P(0), g = P(0), D = P(null), L = P(null), F = P(!1), T = P(!1), $ = P(!1), z = P("sil"), ee = P(0), se = P(!1), O = P(
|
|
2451
2573
|
null
|
|
2452
|
-
), K =
|
|
2453
|
-
|
|
2454
|
-
|
|
2574
|
+
), K = P(!1), [ae, de] = Qe("idle"), [X, ge] = Qe(null), [te, Fe] = Qe(!1), [ye, $e] = Qe(!1), [nt, qt] = Qe({ width: 842, height: 1264 }), Se = P(i ?? null), Ae = o?.trim() || tt, We = P(null), ue = P(null), c = P(!1), k = P({ width: 842, height: 1264 }), x = P(null), j = P("sil"), ne = P(void 0), ke = P(/* @__PURE__ */ new Map()), ie = P(y), Y = P(v), pe = P(d), rt = P(E), qe = P(b), ve = P(V), He = P(Q), Ie = P(Hs());
|
|
2575
|
+
ie.current = y, Y.current = v, pe.current = d, rt.current = E, qe.current = b, ve.current = V, He.current = Q, Me(() => {
|
|
2576
|
+
const w = Ie.current;
|
|
2577
|
+
return fn(w), () => fn(null);
|
|
2578
|
+
}, []);
|
|
2579
|
+
const st = he(
|
|
2455
2580
|
(w) => {
|
|
2456
|
-
const R = w?.ttsEngineId ?? a ?? ue.current?.ttsEngineId ?? Le,
|
|
2457
|
-
return { ttsEngineId: R, voiceId:
|
|
2581
|
+
const R = w?.ttsEngineId ?? a ?? ue.current?.ttsEngineId ?? Le, B = w?.voiceId ?? l ?? ue.current?.voiceId ?? Je(R);
|
|
2582
|
+
return { ttsEngineId: R, voiceId: B };
|
|
2458
2583
|
},
|
|
2459
|
-
[a,
|
|
2460
|
-
),
|
|
2461
|
-
|
|
2462
|
-
}, []),
|
|
2584
|
+
[a, l]
|
|
2585
|
+
), oe = he((w) => {
|
|
2586
|
+
ge(w), pe.current?.(w);
|
|
2587
|
+
}, []), Ee = he(
|
|
2463
2588
|
(w) => {
|
|
2464
|
-
|
|
2589
|
+
de(w), p?.(w);
|
|
2465
2590
|
},
|
|
2466
|
-
[
|
|
2467
|
-
),
|
|
2468
|
-
|
|
2469
|
-
),
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
), i &&
|
|
2474
|
-
|
|
2475
|
-
const w =
|
|
2476
|
-
w && (w.disconnect(),
|
|
2477
|
-
}), [
|
|
2478
|
-
const
|
|
2479
|
-
|
|
2591
|
+
[p]
|
|
2592
|
+
), q = P(
|
|
2593
|
+
en(Ee, Ae)
|
|
2594
|
+
), C = P(null);
|
|
2595
|
+
Me(() => (q.current = en(
|
|
2596
|
+
Ee,
|
|
2597
|
+
Ae
|
|
2598
|
+
), i && q.current.setDeveloperToken(i), q.current.setTtsEngineId(a), () => {
|
|
2599
|
+
q.current.stop();
|
|
2600
|
+
const w = C.current;
|
|
2601
|
+
w && (w.disconnect(), C.current = null);
|
|
2602
|
+
}), [Ee, i, a, Ae]);
|
|
2603
|
+
const fe = he(() => (C.current || (C.current = Jr(
|
|
2604
|
+
Ee,
|
|
2480
2605
|
{
|
|
2481
|
-
speakingRate:
|
|
2482
|
-
onUserTranscript: (w, R) =>
|
|
2483
|
-
onBotOutput: (w) =>
|
|
2484
|
-
onLipsyncDebug: (w) =>
|
|
2606
|
+
speakingRate: f,
|
|
2607
|
+
onUserTranscript: (w, R) => rt.current?.(w, R),
|
|
2608
|
+
onBotOutput: (w) => qe.current?.(w),
|
|
2609
|
+
onLipsyncDebug: (w) => ve.current?.(w)
|
|
2485
2610
|
}
|
|
2486
|
-
),
|
|
2487
|
-
|
|
2488
|
-
}, []),
|
|
2489
|
-
|
|
2490
|
-
}, []),
|
|
2491
|
-
!K.current || !
|
|
2492
|
-
if (
|
|
2493
|
-
|
|
2494
|
-
|
|
2611
|
+
), C.current.setTtsEngineId(a)), C.current), [Ee, f, a]), J = he(() => {
|
|
2612
|
+
D.current != null && (clearTimeout(D.current), D.current = null);
|
|
2613
|
+
}, []), le = he(() => {
|
|
2614
|
+
L.current != null && (clearTimeout(L.current), L.current = null), $.current = !1;
|
|
2615
|
+
}, []), Ke = he(() => {
|
|
2616
|
+
!K.current || !O.current || (le(), $.current = !0, L.current = setTimeout(() => {
|
|
2617
|
+
if (L.current = null, Te(
|
|
2618
|
+
q.current,
|
|
2619
|
+
C.current
|
|
2495
2620
|
).isSpeaking()) {
|
|
2496
|
-
|
|
2621
|
+
$.current = !1;
|
|
2497
2622
|
return;
|
|
2498
2623
|
}
|
|
2499
|
-
if (
|
|
2500
|
-
|
|
2624
|
+
if (F.current) {
|
|
2625
|
+
$.current = !1;
|
|
2501
2626
|
return;
|
|
2502
2627
|
}
|
|
2503
|
-
const w =
|
|
2628
|
+
const w = O.current;
|
|
2504
2629
|
if (!w) {
|
|
2505
|
-
|
|
2630
|
+
$.current = !1;
|
|
2506
2631
|
return;
|
|
2507
2632
|
}
|
|
2508
2633
|
w.restart(), w.setActive(!0);
|
|
2509
2634
|
const R = w.getVideo();
|
|
2510
|
-
let
|
|
2511
|
-
const
|
|
2512
|
-
|
|
2513
|
-
},
|
|
2514
|
-
|
|
2635
|
+
let B = !1;
|
|
2636
|
+
const W = () => {
|
|
2637
|
+
B || (B = !0, R.removeEventListener("playing", U), $.current = !1);
|
|
2638
|
+
}, U = () => {
|
|
2639
|
+
W();
|
|
2515
2640
|
};
|
|
2516
|
-
if (R.addEventListener("playing",
|
|
2517
|
-
|
|
2641
|
+
if (R.addEventListener("playing", U, { once: !0 }), R.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && !R.paused) {
|
|
2642
|
+
W();
|
|
2518
2643
|
return;
|
|
2519
2644
|
}
|
|
2520
|
-
setTimeout(
|
|
2521
|
-
},
|
|
2522
|
-
}, [
|
|
2523
|
-
if (
|
|
2524
|
-
|
|
2645
|
+
setTimeout(W, 300);
|
|
2646
|
+
}, Ks));
|
|
2647
|
+
}, [le]), Re = he(() => {
|
|
2648
|
+
if (J(), Y.current?.("sil"), F.current = !1, !K.current || !O.current) {
|
|
2649
|
+
$.current = !1;
|
|
2525
2650
|
return;
|
|
2526
2651
|
}
|
|
2527
|
-
|
|
2528
|
-
}, [
|
|
2652
|
+
Ke();
|
|
2653
|
+
}, [J, Ke]), pt = he(
|
|
2529
2654
|
async (w) => {
|
|
2530
|
-
const R = I.current,
|
|
2531
|
-
w?.fallbackOnly || (
|
|
2655
|
+
const R = I.current, B = Z.current, W = G.current, U = () => {
|
|
2656
|
+
w?.fallbackOnly || (F.current = !1);
|
|
2532
2657
|
};
|
|
2533
|
-
if (!
|
|
2534
|
-
|
|
2658
|
+
if (!B || !W || !te) {
|
|
2659
|
+
U();
|
|
2535
2660
|
return;
|
|
2536
2661
|
}
|
|
2537
|
-
if (
|
|
2538
|
-
|
|
2539
|
-
|
|
2662
|
+
if (Te(
|
|
2663
|
+
q.current,
|
|
2664
|
+
C.current
|
|
2540
2665
|
).isSpeaking()) {
|
|
2541
|
-
|
|
2666
|
+
U();
|
|
2542
2667
|
return;
|
|
2543
2668
|
}
|
|
2544
2669
|
if (w?.fallbackOnly) {
|
|
2545
|
-
if (!
|
|
2546
|
-
|
|
2547
|
-
|
|
2670
|
+
if (!F.current || (_e(S.current), await B.renderSilOnly(), R !== I.current) || Te(
|
|
2671
|
+
q.current,
|
|
2672
|
+
C.current
|
|
2548
2673
|
).isSpeaking())
|
|
2549
2674
|
return;
|
|
2550
|
-
|
|
2675
|
+
Re();
|
|
2551
2676
|
return;
|
|
2552
2677
|
}
|
|
2553
|
-
if (
|
|
2554
|
-
|
|
2678
|
+
if (Gs(S.current)) {
|
|
2679
|
+
_e(S.current), Re();
|
|
2555
2680
|
return;
|
|
2556
2681
|
}
|
|
2557
|
-
const
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2682
|
+
const ce = Js(
|
|
2683
|
+
Te(
|
|
2684
|
+
q.current,
|
|
2685
|
+
C.current
|
|
2561
2686
|
).getVisemeQueue(),
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
),
|
|
2565
|
-
|
|
2566
|
-
|
|
2687
|
+
ee.current,
|
|
2688
|
+
z.current
|
|
2689
|
+
), we = Xs(
|
|
2690
|
+
ce,
|
|
2691
|
+
x.current
|
|
2567
2692
|
);
|
|
2568
|
-
if (
|
|
2569
|
-
if (await
|
|
2570
|
-
|
|
2571
|
-
|
|
2693
|
+
if (_e(S.current), !we) {
|
|
2694
|
+
if (await B.renderSilOnly(), R !== I.current || Te(
|
|
2695
|
+
q.current,
|
|
2696
|
+
C.current
|
|
2572
2697
|
).isSpeaking())
|
|
2573
2698
|
return;
|
|
2574
|
-
|
|
2699
|
+
Re();
|
|
2575
2700
|
return;
|
|
2576
2701
|
}
|
|
2577
2702
|
try {
|
|
2578
|
-
await
|
|
2579
|
-
from:
|
|
2580
|
-
transitionDurationMs:
|
|
2703
|
+
await B.renderViseme(W, "sil", {
|
|
2704
|
+
from: ce,
|
|
2705
|
+
transitionDurationMs: Un
|
|
2581
2706
|
});
|
|
2582
|
-
} catch (
|
|
2583
|
-
if (
|
|
2584
|
-
throw
|
|
2707
|
+
} catch (be) {
|
|
2708
|
+
if (be?.name !== "AbortError")
|
|
2709
|
+
throw be;
|
|
2585
2710
|
}
|
|
2586
2711
|
if (R !== I.current) {
|
|
2587
|
-
|
|
2712
|
+
U();
|
|
2588
2713
|
return;
|
|
2589
2714
|
}
|
|
2590
|
-
if (
|
|
2591
|
-
|
|
2592
|
-
|
|
2715
|
+
if (Te(
|
|
2716
|
+
q.current,
|
|
2717
|
+
C.current
|
|
2593
2718
|
).isSpeaking()) {
|
|
2594
|
-
|
|
2719
|
+
U();
|
|
2595
2720
|
return;
|
|
2596
2721
|
}
|
|
2597
|
-
|
|
2722
|
+
Re();
|
|
2598
2723
|
},
|
|
2599
|
-
[
|
|
2600
|
-
),
|
|
2601
|
-
if (
|
|
2602
|
-
|
|
2724
|
+
[te, Re]
|
|
2725
|
+
), je = he(() => {
|
|
2726
|
+
if (T.current || F.current) return;
|
|
2727
|
+
T.current = !0, F.current = !0, J();
|
|
2603
2728
|
const w = I.current;
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
}),
|
|
2607
|
-
|
|
2608
|
-
},
|
|
2609
|
-
}, [
|
|
2729
|
+
pt().finally(() => {
|
|
2730
|
+
T.current = !1;
|
|
2731
|
+
}), D.current = setTimeout(() => {
|
|
2732
|
+
D.current = null, w === I.current && pt({ fallbackOnly: !0 });
|
|
2733
|
+
}, Zs());
|
|
2734
|
+
}, [J, pt]), Ht = he(async () => {
|
|
2610
2735
|
const w = Math.floor(Date.now() / 1e3);
|
|
2611
|
-
if (
|
|
2612
|
-
return
|
|
2613
|
-
const R =
|
|
2614
|
-
|
|
2615
|
-
const
|
|
2616
|
-
return
|
|
2617
|
-
key:
|
|
2618
|
-
expiresAt:
|
|
2619
|
-
},
|
|
2620
|
-
}, [
|
|
2621
|
-
|
|
2622
|
-
i && (
|
|
2623
|
-
}, [i]),
|
|
2624
|
-
|
|
2625
|
-
}, [a]),
|
|
2626
|
-
const w =
|
|
2736
|
+
if (We.current && w < We.current.expiresAt - 60)
|
|
2737
|
+
return We.current.key;
|
|
2738
|
+
const R = Se.current ?? await kt();
|
|
2739
|
+
Se.current = R, q.current.setDeveloperToken(R);
|
|
2740
|
+
const B = await hr(R, Ae);
|
|
2741
|
+
return We.current = {
|
|
2742
|
+
key: B.value,
|
|
2743
|
+
expiresAt: B.expiresAt
|
|
2744
|
+
}, B.value;
|
|
2745
|
+
}, [Ae]);
|
|
2746
|
+
Me(() => {
|
|
2747
|
+
i && (Se.current = i, q.current.setDeveloperToken(i));
|
|
2748
|
+
}, [i]), Me(() => {
|
|
2749
|
+
q.current.setTtsEngineId(a), C.current?.setTtsEngineId(a), ue.current && (ue.current.ttsEngineId = a);
|
|
2750
|
+
}, [a]), Me(() => {
|
|
2751
|
+
const w = l ?? Je(a);
|
|
2627
2752
|
ue.current && (ue.current.voiceId = w);
|
|
2628
|
-
}, [
|
|
2629
|
-
const
|
|
2630
|
-
() =>
|
|
2753
|
+
}, [l, a]);
|
|
2754
|
+
const De = Qt(
|
|
2755
|
+
() => _r(n, r),
|
|
2631
2756
|
[n, r]
|
|
2632
|
-
),
|
|
2633
|
-
return
|
|
2634
|
-
if (!t && !s && !
|
|
2635
|
-
|
|
2757
|
+
), Wn = Qt(() => s ? JSON.stringify(s) : De ? `face:${De}` : `id:${t ?? ""}`, [s, De, t]);
|
|
2758
|
+
return Me(() => {
|
|
2759
|
+
if (!t && !s && !De) {
|
|
2760
|
+
oe("AiTwin requires `assets`, `avatarId`/`faceId`, or `id`");
|
|
2636
2761
|
return;
|
|
2637
2762
|
}
|
|
2638
2763
|
let w = !1;
|
|
2639
|
-
|
|
2640
|
-
const R =
|
|
2764
|
+
c.current = !1, Fe(!1), $e(!1), ge(null), ue.current = null, O.current = null, K.current = !1;
|
|
2765
|
+
const R = G.current;
|
|
2641
2766
|
if (!R) return;
|
|
2642
|
-
let
|
|
2767
|
+
let B = null;
|
|
2643
2768
|
return (async () => {
|
|
2644
2769
|
try {
|
|
2645
|
-
let
|
|
2770
|
+
let W, U, ce, we;
|
|
2646
2771
|
if (s)
|
|
2647
|
-
|
|
2648
|
-
else if (
|
|
2649
|
-
|
|
2772
|
+
W = s, U = a, ce = l ?? Je(U);
|
|
2773
|
+
else if (De)
|
|
2774
|
+
Y.current?.("loadFace"), W = Jt(De), U = a, ce = l ?? Je(U);
|
|
2650
2775
|
else {
|
|
2651
|
-
|
|
2652
|
-
const
|
|
2653
|
-
|
|
2776
|
+
Y.current?.("getAiTwin");
|
|
2777
|
+
const H = await bt(
|
|
2778
|
+
cr(t),
|
|
2654
2779
|
3e4,
|
|
2655
2780
|
"getAiTwin"
|
|
2656
2781
|
);
|
|
2657
2782
|
if (w) return;
|
|
2658
|
-
if (!
|
|
2783
|
+
if (!H.faceId?.trim())
|
|
2659
2784
|
throw new Error("getAiTwin returned no faceId");
|
|
2660
|
-
|
|
2785
|
+
U = H.ttsEngineId, ce = l ?? H.voiceId ?? Je(U), we = H.knowledgeContextId?.trim() || void 0, W = Jt(H.faceId);
|
|
2661
2786
|
}
|
|
2662
|
-
ue.current = { ttsEngineId:
|
|
2663
|
-
onStatus: (
|
|
2664
|
-
w ||
|
|
2787
|
+
ue.current = { ttsEngineId: U, voiceId: ce, personaId: we }, yr(W), O.current = Ds(), B = oi(R, {
|
|
2788
|
+
onStatus: (H) => {
|
|
2789
|
+
w || Y.current?.(H);
|
|
2665
2790
|
},
|
|
2666
|
-
onError: (
|
|
2667
|
-
w ||
|
|
2791
|
+
onError: (H) => {
|
|
2792
|
+
w || oe(H);
|
|
2668
2793
|
},
|
|
2669
|
-
shouldAcceptLiveFrame: () =>
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
).isSpeaking() && !
|
|
2673
|
-
}),
|
|
2674
|
-
const
|
|
2794
|
+
shouldAcceptLiveFrame: () => Te(
|
|
2795
|
+
q.current,
|
|
2796
|
+
C.current
|
|
2797
|
+
).isSpeaking() && !F.current
|
|
2798
|
+
}), Z.current = B, Y.current?.("auth");
|
|
2799
|
+
const be = Se.current ?? i ?? await bt(kt(), 3e4, "getAuthToken");
|
|
2675
2800
|
if (w) return;
|
|
2676
|
-
|
|
2677
|
-
const
|
|
2801
|
+
Se.current = be, q.current.setDeveloperToken(be), q.current.setTtsEngineId(U);
|
|
2802
|
+
const Ge = mt() ? await Ht() : void 0;
|
|
2678
2803
|
if (w) return;
|
|
2679
|
-
|
|
2680
|
-
const
|
|
2681
|
-
|
|
2804
|
+
Y.current?.("loadAssets");
|
|
2805
|
+
const re = await bt(
|
|
2806
|
+
B.loadAssets(Ge),
|
|
2682
2807
|
18e4,
|
|
2683
2808
|
"load face assets"
|
|
2684
2809
|
);
|
|
2685
|
-
if (!w &&
|
|
2686
|
-
|
|
2687
|
-
w ||
|
|
2810
|
+
if (!w && re.width > 0 && re.height > 0 && (k.current = re, qt(re)), w) return;
|
|
2811
|
+
x.current = B.getVisemeAtlasPaths(), c.current = !0, Fe(!0), ie.current?.(), B.renderSilOnly().then(() => {
|
|
2812
|
+
w || Y.current?.("sil");
|
|
2688
2813
|
}), (async () => {
|
|
2689
2814
|
try {
|
|
2690
|
-
const
|
|
2691
|
-
if (await
|
|
2692
|
-
K.current = !0,
|
|
2693
|
-
const
|
|
2694
|
-
await
|
|
2815
|
+
const H = await is(Ge);
|
|
2816
|
+
if (await O.current.load(H), w) return;
|
|
2817
|
+
K.current = !0, $e(!0), _e(S.current), O.current.setActive(!0);
|
|
2818
|
+
const me = O.current.getVideo();
|
|
2819
|
+
await ln(
|
|
2695
2820
|
R,
|
|
2696
|
-
|
|
2821
|
+
me,
|
|
2697
2822
|
null,
|
|
2698
2823
|
void 0,
|
|
2699
|
-
|
|
2700
|
-
), w ||
|
|
2701
|
-
} catch (
|
|
2824
|
+
k.current
|
|
2825
|
+
), w || Y.current?.("idle");
|
|
2826
|
+
} catch (H) {
|
|
2702
2827
|
if (w) return;
|
|
2703
|
-
K.current = !1,
|
|
2828
|
+
K.current = !1, $e(!1), console.warn("[AiTwin] Idle video unavailable:", H);
|
|
2704
2829
|
}
|
|
2705
2830
|
})();
|
|
2706
|
-
} catch (
|
|
2831
|
+
} catch (W) {
|
|
2707
2832
|
if (w) return;
|
|
2708
|
-
if (
|
|
2709
|
-
|
|
2833
|
+
if (W instanceof Tt) {
|
|
2834
|
+
oe(W.message);
|
|
2710
2835
|
return;
|
|
2711
2836
|
}
|
|
2712
|
-
|
|
2837
|
+
oe(W instanceof Error ? W.message : "Failed to load AI twin");
|
|
2713
2838
|
}
|
|
2714
2839
|
})(), () => {
|
|
2715
|
-
w = !0,
|
|
2840
|
+
w = !0, O.current?.dispose(), B?.dispose(), Z.current = null;
|
|
2716
2841
|
};
|
|
2717
|
-
}, [
|
|
2842
|
+
}, [Wn, s, De, t, a, l, i, Ht, oe]), Me(() => {
|
|
2718
2843
|
const w = { current: !1 }, R = () => {
|
|
2719
|
-
const
|
|
2720
|
-
|
|
2721
|
-
|
|
2844
|
+
const B = G.current, W = Z.current, U = Te(
|
|
2845
|
+
q.current,
|
|
2846
|
+
C.current
|
|
2722
2847
|
);
|
|
2723
|
-
if (!
|
|
2724
|
-
|
|
2848
|
+
if (!B || !W || !te) {
|
|
2849
|
+
M.current = requestAnimationFrame(R);
|
|
2725
2850
|
return;
|
|
2726
2851
|
}
|
|
2727
|
-
const
|
|
2728
|
-
|
|
2729
|
-
const
|
|
2730
|
-
if (
|
|
2731
|
-
K.current &&
|
|
2732
|
-
const
|
|
2733
|
-
|
|
2734
|
-
const
|
|
2735
|
-
|
|
2736
|
-
const Be =
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2852
|
+
const ce = U.isSpeaking(), we = ce && !se.current, be = se.current && !ce;
|
|
2853
|
+
we && (J(), le(), F.current = !1, T.current = !1, _e(S.current), Ie.current.reset(), ne.current = void 0, g.current = 0, z.current = "sil", ee.current = 0, O.current?.setActive(!1)), be && (A.current.reset(), O.current?.setActive(!1), je());
|
|
2854
|
+
const Ge = be || F.current || $.current;
|
|
2855
|
+
if (ce) {
|
|
2856
|
+
K.current && O.current?.setActive(!1);
|
|
2857
|
+
const re = U.getVisemeQueue(), H = U.getPlaybackElapsedMs();
|
|
2858
|
+
ee.current = H;
|
|
2859
|
+
const me = re.length > 0 ? ht(re, H) : "sil";
|
|
2860
|
+
me !== "sil" && (z.current = me);
|
|
2861
|
+
const Be = Ps(
|
|
2862
|
+
H,
|
|
2863
|
+
U.getSentenceEmotions(),
|
|
2864
|
+
U.getWordQueue(),
|
|
2865
|
+
U.getStreamMood()
|
|
2741
2866
|
);
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2867
|
+
A.current.setTargetEmotion(Be), A.current.setTargetEyebrow(
|
|
2868
|
+
Is(
|
|
2869
|
+
H,
|
|
2870
|
+
U.getWordQueue(),
|
|
2871
|
+
$t(Be)
|
|
2747
2872
|
)
|
|
2748
|
-
),
|
|
2749
|
-
const
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
(
|
|
2758
|
-
|
|
2759
|
-
|
|
2873
|
+
), A.current.advance(performance.now());
|
|
2874
|
+
const _t = A.current.getExpressionPath(), yt = A.current.getDrawKey();
|
|
2875
|
+
ti(
|
|
2876
|
+
B,
|
|
2877
|
+
re,
|
|
2878
|
+
H,
|
|
2879
|
+
_t,
|
|
2880
|
+
yt,
|
|
2881
|
+
S.current,
|
|
2882
|
+
(ze, Kt, jt, qn) => {
|
|
2883
|
+
const Gt = {
|
|
2884
|
+
label: j.current,
|
|
2885
|
+
elapsedMs: H,
|
|
2886
|
+
mouthPath: Kt.mouthPath,
|
|
2887
|
+
transitionMeta: ne.current
|
|
2888
|
+
};
|
|
2889
|
+
ke.current.set(jt, Gt), W.drawLiveFrame(ze, Kt, jt, (St) => {
|
|
2890
|
+
const Hn = ke.current.get(St) ?? Gt;
|
|
2891
|
+
ke.current.delete(St), Ie.current.onDrawDisplayed(
|
|
2892
|
+
Hn,
|
|
2893
|
+
re
|
|
2894
|
+
), qn?.(St);
|
|
2895
|
+
});
|
|
2896
|
+
},
|
|
2897
|
+
(ze) => {
|
|
2898
|
+
j.current = ze.label, ne.current = ze.transitionMeta, Y.current?.(ze.label);
|
|
2899
|
+
},
|
|
2900
|
+
x.current
|
|
2901
|
+
), Ie.current.onRafTickSpeaking(), He.current?.(
|
|
2902
|
+
Ie.current.snapshot(re, H)
|
|
2760
2903
|
);
|
|
2761
|
-
} else if (!
|
|
2762
|
-
const
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2904
|
+
} else if (!Ge && K.current && O.current) {
|
|
2905
|
+
const re = O.current, H = re.getVideo();
|
|
2906
|
+
H.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA ? (re.setActive(!0), w.current || (w.current = !0, ln(
|
|
2907
|
+
B,
|
|
2908
|
+
H,
|
|
2766
2909
|
null,
|
|
2767
2910
|
void 0,
|
|
2768
|
-
|
|
2769
|
-
() => !
|
|
2770
|
-
).then(() =>
|
|
2911
|
+
k.current,
|
|
2912
|
+
() => !U.isSpeaking() && !F.current && !$.current
|
|
2913
|
+
).then(() => Y.current?.("idle")).finally(() => {
|
|
2771
2914
|
w.current = !1;
|
|
2772
|
-
}))) :
|
|
2773
|
-
|
|
2915
|
+
}))) : hn(
|
|
2916
|
+
B,
|
|
2774
2917
|
null,
|
|
2775
2918
|
"__sil__",
|
|
2776
|
-
|
|
2777
|
-
(
|
|
2778
|
-
(
|
|
2919
|
+
S.current,
|
|
2920
|
+
(me, Be, _t, yt) => W.drawLiveFrame(me, Be, _t, yt),
|
|
2921
|
+
(me) => Y.current?.(me)
|
|
2779
2922
|
);
|
|
2780
|
-
} else
|
|
2781
|
-
|
|
2923
|
+
} else Ge || hn(
|
|
2924
|
+
B,
|
|
2782
2925
|
null,
|
|
2783
2926
|
"__sil__",
|
|
2784
|
-
|
|
2785
|
-
(
|
|
2786
|
-
(
|
|
2927
|
+
S.current,
|
|
2928
|
+
(re, H, me, Be) => W.drawLiveFrame(re, H, me, Be),
|
|
2929
|
+
(re) => Y.current?.(re)
|
|
2787
2930
|
);
|
|
2788
|
-
|
|
2931
|
+
se.current = ce, M.current = requestAnimationFrame(R);
|
|
2789
2932
|
};
|
|
2790
|
-
return
|
|
2791
|
-
cancelAnimationFrame(
|
|
2933
|
+
return M.current = requestAnimationFrame(R), () => {
|
|
2934
|
+
cancelAnimationFrame(M.current), J(), le(), q.current.stop(), C.current?.stop();
|
|
2792
2935
|
};
|
|
2793
2936
|
}, [
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
le,
|
|
2798
|
-
re
|
|
2799
|
-
]), Pn(
|
|
2937
|
+
te,
|
|
2938
|
+
ye,
|
|
2939
|
+
je,
|
|
2800
2940
|
J,
|
|
2941
|
+
le
|
|
2942
|
+
]), Gn(
|
|
2943
|
+
N,
|
|
2801
2944
|
() => ({
|
|
2802
2945
|
speakText: async (w, R) => {
|
|
2803
|
-
const
|
|
2804
|
-
if (!
|
|
2805
|
-
const
|
|
2806
|
-
if (!
|
|
2946
|
+
const B = w.trim();
|
|
2947
|
+
if (!B) return;
|
|
2948
|
+
const W = Z.current;
|
|
2949
|
+
if (!W || !c.current && !te)
|
|
2807
2950
|
throw new Error("AI twin is not ready");
|
|
2808
|
-
const { ttsEngineId:
|
|
2809
|
-
|
|
2951
|
+
const { ttsEngineId: U, voiceId: ce } = st(R);
|
|
2952
|
+
ge(null), I.current += 1, J(), le(), F.current = !1, T.current = !1, z.current = "sil", ee.current = 0, _e(S.current), A.current.reset(), se.current = !1;
|
|
2810
2953
|
try {
|
|
2811
|
-
K.current ? (
|
|
2812
|
-
voiceId:
|
|
2813
|
-
speakingRate: R?.speakingRate ??
|
|
2814
|
-
ttsEngineId:
|
|
2954
|
+
K.current ? (O.current?.setActive(!1), O.current?.restart(), _e(S.current)) : await W.renderSilOnly(), await q.current.speak(B, {
|
|
2955
|
+
voiceId: ce,
|
|
2956
|
+
speakingRate: R?.speakingRate ?? f,
|
|
2957
|
+
ttsEngineId: U
|
|
2815
2958
|
});
|
|
2816
|
-
} catch (
|
|
2817
|
-
throw
|
|
2959
|
+
} catch (we) {
|
|
2960
|
+
throw oe(we instanceof Error ? we.message : "TTS failed"), we;
|
|
2818
2961
|
}
|
|
2819
2962
|
},
|
|
2820
2963
|
stop: () => {
|
|
2821
|
-
I.current += 1,
|
|
2964
|
+
I.current += 1, J(), le(), F.current = !1, T.current = !1, q.current.stop(), C.current?.stop(), _e(S.current), se.current = !1, je();
|
|
2822
2965
|
},
|
|
2823
2966
|
setTtsEngineId: (w) => {
|
|
2824
|
-
|
|
2967
|
+
q.current.setTtsEngineId(w), C.current?.setTtsEngineId(w), ue.current && (ue.current.ttsEngineId = w);
|
|
2825
2968
|
},
|
|
2826
2969
|
renderViseme: async (w, R) => {
|
|
2827
|
-
const
|
|
2828
|
-
if (!
|
|
2970
|
+
const B = Z.current, W = G.current;
|
|
2971
|
+
if (!B || !W || !c.current)
|
|
2829
2972
|
throw new Error("AI twin is not ready");
|
|
2830
|
-
await
|
|
2973
|
+
await B.renderViseme(W, w, {
|
|
2831
2974
|
from: R?.from,
|
|
2832
2975
|
transitionDurationMs: R?.transitionDurationMs,
|
|
2833
2976
|
gapMs: R?.gapMs,
|
|
2834
|
-
onStatus: (
|
|
2977
|
+
onStatus: (U) => Y.current?.(U)
|
|
2835
2978
|
});
|
|
2836
2979
|
},
|
|
2837
|
-
isReady: () =>
|
|
2838
|
-
getStatus: () =>
|
|
2980
|
+
isReady: () => c.current,
|
|
2981
|
+
getStatus: () => ae,
|
|
2839
2982
|
connect: async (w = {}) => {
|
|
2840
|
-
|
|
2983
|
+
ge(null);
|
|
2841
2984
|
try {
|
|
2842
2985
|
let R = w.authToken?.trim();
|
|
2843
|
-
R || (R =
|
|
2844
|
-
const
|
|
2845
|
-
await
|
|
2986
|
+
R || (R = Se.current ?? i ?? await kt(), Se.current = R);
|
|
2987
|
+
const B = w.voiceId?.trim() ?? l ?? ue.current?.voiceId, W = w.personaId?.trim() ?? ue.current?.personaId, U = fe();
|
|
2988
|
+
await U.unlockAudio(), await U.connect({
|
|
2846
2989
|
...w,
|
|
2847
|
-
apiBase: w.apiBase?.trim() ||
|
|
2990
|
+
apiBase: w.apiBase?.trim() || Ae,
|
|
2848
2991
|
authToken: R,
|
|
2849
|
-
voiceId:
|
|
2850
|
-
personaId:
|
|
2851
|
-
speakingRate: w.speakingRate ??
|
|
2992
|
+
voiceId: B,
|
|
2993
|
+
personaId: W,
|
|
2994
|
+
speakingRate: w.speakingRate ?? f
|
|
2852
2995
|
});
|
|
2853
2996
|
} catch (R) {
|
|
2854
|
-
throw
|
|
2997
|
+
throw oe(
|
|
2855
2998
|
R instanceof Error ? R.message : "Voice connect failed"
|
|
2856
2999
|
), R;
|
|
2857
3000
|
}
|
|
2858
3001
|
},
|
|
2859
3002
|
disconnect: async () => {
|
|
2860
|
-
const w =
|
|
2861
|
-
w && (I.current += 1,
|
|
3003
|
+
const w = C.current;
|
|
3004
|
+
w && (I.current += 1, J(), le(), F.current = !1, T.current = !1, _e(S.current), se.current = !1, await w.disconnect(), je());
|
|
2862
3005
|
},
|
|
2863
|
-
isConnected: () =>
|
|
2864
|
-
getVoiceStream: () =>
|
|
3006
|
+
isConnected: () => C.current?.isConnected() ?? !1,
|
|
3007
|
+
getVoiceStream: () => C.current?.getVoiceStream() ?? q.current?.getVoiceStream() ?? null
|
|
2865
3008
|
}),
|
|
2866
3009
|
[
|
|
2867
|
-
|
|
2868
|
-
|
|
3010
|
+
te,
|
|
3011
|
+
f,
|
|
2869
3012
|
i,
|
|
2870
|
-
|
|
3013
|
+
l,
|
|
3014
|
+
J,
|
|
2871
3015
|
le,
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
Z
|
|
3016
|
+
je,
|
|
3017
|
+
oe,
|
|
3018
|
+
st,
|
|
3019
|
+
fe,
|
|
3020
|
+
ae
|
|
2878
3021
|
]
|
|
2879
|
-
), /* @__PURE__ */
|
|
2880
|
-
/* @__PURE__ */
|
|
3022
|
+
), /* @__PURE__ */ Kn("div", { className: u, style: { ...ui, ..._ }, children: [
|
|
3023
|
+
/* @__PURE__ */ zt(
|
|
2881
3024
|
"canvas",
|
|
2882
3025
|
{
|
|
2883
|
-
ref:
|
|
2884
|
-
width:
|
|
2885
|
-
height:
|
|
2886
|
-
style: { ...
|
|
3026
|
+
ref: G,
|
|
3027
|
+
width: nt.width,
|
|
3028
|
+
height: nt.height,
|
|
3029
|
+
style: { ...li, ...m },
|
|
2887
3030
|
"aria-label": t ? `AI twin ${t}` : "AI twin face"
|
|
2888
3031
|
}
|
|
2889
3032
|
),
|
|
2890
|
-
|
|
3033
|
+
h && X ? /* @__PURE__ */ zt("div", { style: fi, children: X }) : null
|
|
2891
3034
|
] });
|
|
2892
|
-
}),
|
|
2893
|
-
function
|
|
3035
|
+
}), di = "thumbnail.webp";
|
|
3036
|
+
function vi(e, t = xt) {
|
|
2894
3037
|
const n = e.trim();
|
|
2895
3038
|
if (!n)
|
|
2896
3039
|
throw new Error("faceId is required");
|
|
2897
|
-
return `${t.replace(/\/$/, "")}/${n}/${
|
|
3040
|
+
return `${t.replace(/\/$/, "")}/${n}/${di}`;
|
|
2898
3041
|
}
|
|
2899
|
-
const
|
|
2900
|
-
function
|
|
3042
|
+
const mi = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
|
|
3043
|
+
function hi(e = ".png") {
|
|
2901
3044
|
const t = e.toLowerCase();
|
|
2902
|
-
return
|
|
3045
|
+
return mi.has(t) ? `source${t}` : "source.png";
|
|
2903
3046
|
}
|
|
2904
|
-
function
|
|
3047
|
+
function Ei(e, t = xt, n = ".png") {
|
|
2905
3048
|
const r = e.trim();
|
|
2906
3049
|
if (!r)
|
|
2907
3050
|
throw new Error("faceId is required");
|
|
2908
|
-
return `${t.replace(/\/$/, "")}/${r}/${
|
|
3051
|
+
return `${t.replace(/\/$/, "")}/${r}/${hi(n)}`;
|
|
2909
3052
|
}
|
|
2910
3053
|
export {
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
3054
|
+
di as AI_TWIN_THUMBNAIL_FILENAME,
|
|
3055
|
+
ki as AiTwin,
|
|
3056
|
+
Tt as AiTwinNotFoundError,
|
|
2914
3057
|
Le as DEFAULT_TTS_ENGINE_ID,
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
3058
|
+
In as MIC_SAMPLE_RATE,
|
|
3059
|
+
Ar as OCULUS_VISEME_IDS,
|
|
3060
|
+
Rn as PLAYBACK_SAMPLE_RATE,
|
|
3061
|
+
Lt as SPEAKING_RATE_MAX,
|
|
3062
|
+
Ot as SPEAKING_RATE_MIN,
|
|
3063
|
+
Ne as TTS_ENGINE_CARTESIA,
|
|
3064
|
+
yn as TTS_ENGINE_GOOGLE,
|
|
3065
|
+
Pt as TTS_ENGINE_INWORLD,
|
|
3066
|
+
Si as VISEME_IDS,
|
|
3067
|
+
An as VISEME_TEST_CARTESIA_VOICE_ID,
|
|
3068
|
+
wt as VISEME_TEST_SPEAKING_RATE,
|
|
3069
|
+
Tn as VISEME_TEST_VOICE_ID,
|
|
3070
|
+
hi as aiTwinSourceFilename,
|
|
3071
|
+
zr as buildVoiceWebSocketUrl,
|
|
3072
|
+
en as createAvatarTtsLipsyncController,
|
|
3073
|
+
Jr as createRealtimeVoiceLipsyncController,
|
|
3074
|
+
Jt as faceAssetUrls,
|
|
3075
|
+
cr as fetchAiTwin,
|
|
3076
|
+
kt as fetchDevAuthToken,
|
|
3077
|
+
Ei as getAiTwinSourceUrl,
|
|
3078
|
+
vi as getAiTwinThumbnailUrl,
|
|
3079
|
+
Rr as normalizeOculusViseme,
|
|
3080
|
+
_r as resolveDirectFaceId,
|
|
3081
|
+
ht as resolveVisemeAtTime,
|
|
3082
|
+
yi as resolveWordAtTime,
|
|
3083
|
+
yr as setActiveTwinAssets
|
|
2941
3084
|
};
|