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