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