@streaming-cdn/rtc-web 1.3.27 → 1.4.0
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/README.md +10 -1
- package/dist/index.d.ts +9 -1
- package/dist/rtc-web-avatar-vrm.es.js +59 -54
- package/dist/rtc-web-avatar-vrm.umd.js +1 -1
- package/dist/rtc-web.es.js +139 -102
- package/dist/rtc-web.umd.js +1 -1
- package/package.json +1 -1
package/dist/rtc-web.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const st = 0.02, rt = 1.4;
|
|
2
2
|
function ge(a, e, t = 0.02, i = 1.4) {
|
|
3
3
|
const n = a.filter((r) => r.level >= t);
|
|
4
4
|
if (n.length === 0) return null;
|
|
@@ -937,7 +937,7 @@ class xe {
|
|
|
937
937
|
}
|
|
938
938
|
send(e) {
|
|
939
939
|
this.socket?.readyState === WebSocket.OPEN && this.socket.send(JSON.stringify({
|
|
940
|
-
clientMessageId: e.clientMessageId ??
|
|
940
|
+
clientMessageId: e.clientMessageId ?? Ne(),
|
|
941
941
|
...e
|
|
942
942
|
}));
|
|
943
943
|
}
|
|
@@ -945,10 +945,10 @@ class xe {
|
|
|
945
945
|
for (const t of e?.getTracks() ?? []) t.stop();
|
|
946
946
|
}
|
|
947
947
|
}
|
|
948
|
-
function
|
|
948
|
+
function Ne() {
|
|
949
949
|
return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
950
950
|
}
|
|
951
|
-
function
|
|
951
|
+
function ot(a, e = {}) {
|
|
952
952
|
const t = e.document ?? globalThis.document, i = !!(t && t.pictureInPictureEnabled);
|
|
953
953
|
let n = null;
|
|
954
954
|
function s() {
|
|
@@ -976,7 +976,7 @@ function rt(a, e = {}) {
|
|
|
976
976
|
}
|
|
977
977
|
};
|
|
978
978
|
}
|
|
979
|
-
function
|
|
979
|
+
function ct(a, e) {
|
|
980
980
|
const t = e.document ?? globalThis.document, i = e.fetchImplementation ?? globalThis.fetch.bind(globalThis), n = Z(e.credential.signalingUrl, globalThis.location?.href).origin, s = e.mimeType ?? "video/webm", o = e.height ?? 720, r = Math.round(o * 16 / 9);
|
|
981
981
|
let c = null, l = null, d = null, u = null, v = 0, p = [], S = !1;
|
|
982
982
|
async function T(y, k, f, M = "application/json") {
|
|
@@ -1007,14 +1007,14 @@ function ot(a, e) {
|
|
|
1007
1007
|
};
|
|
1008
1008
|
l = setInterval(() => {
|
|
1009
1009
|
const b = a.getRemoteStreams(), I = a.getLocalStream(), C = [
|
|
1010
|
-
...b.map((
|
|
1010
|
+
...b.map((N) => ({ key: N.participant.participantId, stream: N.stream, label: N.participant.displayName })),
|
|
1011
1011
|
...I ? [{ key: "local", stream: I, label: "me" }] : []
|
|
1012
1012
|
];
|
|
1013
1013
|
f.fillStyle = "#101418", f.fillRect(0, 0, r, o);
|
|
1014
|
-
const
|
|
1015
|
-
C.forEach((
|
|
1016
|
-
const te = R(
|
|
1017
|
-
te.videoWidth > 0 && f.drawImage(te,
|
|
1014
|
+
const U = Math.max(1, Math.ceil(Math.sqrt(C.length))), Q = Math.max(1, Math.ceil(C.length / U)), q = r / U, g = o / Q;
|
|
1015
|
+
C.forEach((N, ee) => {
|
|
1016
|
+
const te = R(N.key, N.stream), W = ee % U * q, $ = Math.floor(ee / U) * g;
|
|
1017
|
+
te.videoWidth > 0 && f.drawImage(te, W + 2, $ + 2, q - 4, g - 4), f.fillStyle = "rgba(0,0,0,.6)", f.fillRect(W + 8, $ + g - 30, Math.min(q - 16, 12 + N.label.length * 9), 22), f.fillStyle = "#fff", f.font = "14px system-ui", f.fillText(N.label, W + 14, $ + g - 14);
|
|
1018
1018
|
});
|
|
1019
1019
|
}, 66);
|
|
1020
1020
|
const L = k.captureStream(15);
|
|
@@ -1064,7 +1064,7 @@ function ot(a, e) {
|
|
|
1064
1064
|
}
|
|
1065
1065
|
};
|
|
1066
1066
|
}
|
|
1067
|
-
const
|
|
1067
|
+
const Ue = ["none", "blur", "aurora", "cybergrid", "bokeh", "sunset", "image"], Oe = ["none", "snow", "confetti", "vignette"], se = {
|
|
1068
1068
|
aurora(a, e, t, i) {
|
|
1069
1069
|
const n = a.createLinearGradient(0, 0, 0, t);
|
|
1070
1070
|
n.addColorStop(0, "#050b1e"), n.addColorStop(1, "#0b2540"), a.fillStyle = n, a.fillRect(0, 0, e, t);
|
|
@@ -1101,7 +1101,7 @@ const Ne = ["none", "blur", "aurora", "cybergrid", "bokeh", "sunset", "image"],
|
|
|
1101
1101
|
n.addColorStop(0, "#2b1055"), n.addColorStop(0.55, "#d1548a"), n.addColorStop(1, "#ffb36b"), a.fillStyle = n, a.fillRect(0, 0, e, t), a.fillStyle = "#ffdf8e", a.beginPath(), a.arc(e * 0.5, t * 0.62 + Math.sin(i / 4e3) * 4, t * 0.13, 0, Math.PI * 2), a.fill(), a.fillStyle = "rgba(20,8,40,0.85)", a.fillRect(0, t * 0.78, e, t * 0.22);
|
|
1102
1102
|
}
|
|
1103
1103
|
};
|
|
1104
|
-
function
|
|
1104
|
+
function lt(a, e = {}) {
|
|
1105
1105
|
const t = e.document ?? globalThis.document;
|
|
1106
1106
|
let i = e.width ?? 1280, n = e.height ?? 720;
|
|
1107
1107
|
const s = !!(e.width || e.height), o = e.frameRate ?? 24, r = a instanceof MediaStreamTrack ? a : a.getVideoTracks()[0];
|
|
@@ -1161,10 +1161,10 @@ function ct(a, e = {}) {
|
|
|
1161
1161
|
track: E.getVideoTracks()[0],
|
|
1162
1162
|
stream: E,
|
|
1163
1163
|
setBackground(m, h) {
|
|
1164
|
-
c =
|
|
1164
|
+
c = Ue.includes(m) ? m : "none", h !== void 0 && (d = h), c === "none" && (v = null);
|
|
1165
1165
|
},
|
|
1166
1166
|
setOverlay(m) {
|
|
1167
|
-
l =
|
|
1167
|
+
l = Oe.includes(m) ? m : "none";
|
|
1168
1168
|
},
|
|
1169
1169
|
setSegmenter(m) {
|
|
1170
1170
|
u = m, m || (v = null);
|
|
@@ -1195,7 +1195,7 @@ function D(a, e) {
|
|
|
1195
1195
|
const t = a.find((i) => i.categoryName === e);
|
|
1196
1196
|
return t ? Math.max(0, Math.min(1, t.score)) : 0;
|
|
1197
1197
|
}
|
|
1198
|
-
function
|
|
1198
|
+
function qe(a) {
|
|
1199
1199
|
if (!a || a.length < 16) return { yaw: 0, pitch: 0, roll: 0 };
|
|
1200
1200
|
a[0], a[4];
|
|
1201
1201
|
const e = a[8], t = a[1], i = a[5], n = a[9], s = a[10], o = Math.atan2(e, s), r = Math.asin(Math.max(-1, Math.min(1, -n))), c = Math.atan2(t, i);
|
|
@@ -1203,7 +1203,7 @@ function Oe(a) {
|
|
|
1203
1203
|
}
|
|
1204
1204
|
function Ve(a, e, t = 1) {
|
|
1205
1205
|
if (!a || a.length === 0) return ve();
|
|
1206
|
-
const i =
|
|
1206
|
+
const i = qe(e), n = (D(a, "eyeLookOutRight") + D(a, "eyeLookInLeft")) / 2, s = (D(a, "eyeLookOutLeft") + D(a, "eyeLookInRight")) / 2, o = (D(a, "eyeLookUpLeft") + D(a, "eyeLookUpRight")) / 2, r = (D(a, "eyeLookDownLeft") + D(a, "eyeLookDownRight")) / 2, c = (D(a, "mouthSmileLeft") + D(a, "mouthSmileRight")) / 2, l = (D(a, "mouthFrownLeft") + D(a, "mouthFrownRight")) / 2, d = D(a, "eyeBlinkLeft"), u = D(a, "eyeBlinkRight"), v = Math.min(1, Math.abs(i.yaw) / 0.35) * Math.max(0, Math.min(1, t)), p = (d + u) / 2;
|
|
1207
1207
|
return {
|
|
1208
1208
|
blinkLeft: d + (p - d) * v,
|
|
1209
1209
|
blinkRight: u + (p - u) * v,
|
|
@@ -1249,10 +1249,10 @@ function je(a, e, t, i, n) {
|
|
|
1249
1249
|
if (E <= 0.12) continue;
|
|
1250
1250
|
const m = u(w) * 0.82, h = Math.max(0.2, E), b = A < 0 ? e.blinkLeft : e.blinkRight, I = Math.max(0.06, 1 - b), C = e.browUp * r * 0.14;
|
|
1251
1251
|
a.strokeStyle = "#4a2e18", a.lineWidth = r * 0.07, a.lineCap = "round", a.beginPath(), a.moveTo(m - r * 0.2 * h, -r * 0.42 - C + p), a.quadraticCurveTo(m, -r * 0.52 - C + p, m + r * 0.2 * h, -r * 0.44 - C + p), a.stroke();
|
|
1252
|
-
const
|
|
1253
|
-
a.fillStyle = "#ffffff", a.beginPath(), a.ellipse(m,
|
|
1252
|
+
const U = -r * 0.18 + p;
|
|
1253
|
+
a.fillStyle = "#ffffff", a.beginPath(), a.ellipse(m, U, r * 0.16 * h, r * 0.12 * I, 0, 0, Math.PI * 2), a.fill(), a.fillStyle = "#22303c", a.beginPath(), a.ellipse(
|
|
1254
1254
|
m + e.pupilX * r * 0.07 * h,
|
|
1255
|
-
|
|
1255
|
+
U + e.pupilY * r * 0.05,
|
|
1256
1256
|
r * 0.06 * h,
|
|
1257
1257
|
r * 0.06 * I,
|
|
1258
1258
|
0,
|
|
@@ -1280,7 +1280,7 @@ function ce() {
|
|
|
1280
1280
|
};
|
|
1281
1281
|
}
|
|
1282
1282
|
const G = (a) => Math.max(0, Math.min(1, a));
|
|
1283
|
-
function
|
|
1283
|
+
function dt(a, e = {}) {
|
|
1284
1284
|
const t = e.document ?? globalThis.document;
|
|
1285
1285
|
let i = e.width ?? 1280, n = e.height ?? 720;
|
|
1286
1286
|
const s = !!(e.width || e.height), o = e.frameRate ?? 24, r = a instanceof MediaStreamTrack ? a : a.getVideoTracks()[0];
|
|
@@ -1302,8 +1302,8 @@ function lt(a, e = {}) {
|
|
|
1302
1302
|
let k = ve(), f = null, M = 0;
|
|
1303
1303
|
function R(w) {
|
|
1304
1304
|
if (w.length <= 454) return;
|
|
1305
|
-
const E = w[10], m = w[152], h = w[234], b = w[454], I = (h.x + b.x) / 2 * i, C = (h.y + b.y) / 2 * n,
|
|
1306
|
-
f = f ? { x: f.x + (
|
|
1305
|
+
const E = w[10], m = w[152], h = w[234], b = w[454], I = (h.x + b.x) / 2 * i, C = (h.y + b.y) / 2 * n, U = Math.hypot((m.x - E.x) * i, (m.y - E.y) * n), Q = Math.max(0.6, Math.cos(k.headPitch)), q = { x: I, y: C, radius: Math.max(24, U / Q * 0.8) };
|
|
1306
|
+
f = f ? { x: f.x + (q.x - f.x) * 0.4, y: f.y + (q.y - f.y) * 0.4, radius: f.radius + (q.radius - f.radius) * 0.15 } : q;
|
|
1307
1307
|
}
|
|
1308
1308
|
function L(w) {
|
|
1309
1309
|
if (c && p.readyState >= 2) {
|
|
@@ -1404,7 +1404,7 @@ async function Qe(a, e) {
|
|
|
1404
1404
|
const c = new Blob([r]).stream().pipeThrough(new DecompressionStream("deflate-raw"));
|
|
1405
1405
|
return new Response(c).arrayBuffer();
|
|
1406
1406
|
}
|
|
1407
|
-
async function
|
|
1407
|
+
async function ht(a) {
|
|
1408
1408
|
const e = typeof File < "u" && a instanceof File ? await a.arrayBuffer() : a;
|
|
1409
1409
|
if (!Te(e)) return [];
|
|
1410
1410
|
try {
|
|
@@ -1429,11 +1429,11 @@ class x extends Error {
|
|
|
1429
1429
|
function Ce(a) {
|
|
1430
1430
|
return a.filter((e) => /\.vrm$/i.test(e.path) && !e.path.endsWith("/") && !e.path.split("/").some((t) => t === "__MACOSX" || t.startsWith("._")));
|
|
1431
1431
|
}
|
|
1432
|
-
function
|
|
1432
|
+
function O(a) {
|
|
1433
1433
|
const e = typeof a == "string" ? a.trim() : "";
|
|
1434
1434
|
return e.length > 0 ? e : null;
|
|
1435
1435
|
}
|
|
1436
|
-
function
|
|
1436
|
+
function We(a) {
|
|
1437
1437
|
const e = new DataView(a);
|
|
1438
1438
|
if (a.byteLength < 20 || e.getUint32(0, !0) !== ze)
|
|
1439
1439
|
throw new x("model_not_glb", "The file is not a binary glTF (.vrm / .glb) model.");
|
|
@@ -1457,24 +1457,24 @@ function $e(a) {
|
|
|
1457
1457
|
if (o) {
|
|
1458
1458
|
const r = Array.isArray(o.authors) ? o.authors.filter((c) => typeof c == "string") : [];
|
|
1459
1459
|
return {
|
|
1460
|
-
title:
|
|
1460
|
+
title: O(o.name),
|
|
1461
1461
|
author: r.length ? r.join(", ") : null,
|
|
1462
|
-
allowedUser:
|
|
1463
|
-
commercialUse:
|
|
1464
|
-
licenseName:
|
|
1465
|
-
licenseUrl:
|
|
1462
|
+
allowedUser: O(o.avatarPermission),
|
|
1463
|
+
commercialUse: O(o.commercialUsage),
|
|
1464
|
+
licenseName: O(o.licenseUrl) ? "VRM 1.0" : null,
|
|
1465
|
+
licenseUrl: O(o.licenseUrl) ?? O(o.otherLicenseUrl)
|
|
1466
1466
|
};
|
|
1467
1467
|
}
|
|
1468
1468
|
return {
|
|
1469
|
-
title:
|
|
1470
|
-
author:
|
|
1471
|
-
allowedUser:
|
|
1472
|
-
commercialUse:
|
|
1473
|
-
licenseName:
|
|
1474
|
-
licenseUrl:
|
|
1469
|
+
title: O(s?.title),
|
|
1470
|
+
author: O(s?.author),
|
|
1471
|
+
allowedUser: O(s?.allowedUserName),
|
|
1472
|
+
commercialUse: O(s?.commercialUssageName),
|
|
1473
|
+
licenseName: O(s?.licenseName),
|
|
1474
|
+
licenseUrl: O(s?.otherLicenseUrl)
|
|
1475
1475
|
};
|
|
1476
1476
|
}
|
|
1477
|
-
function
|
|
1477
|
+
function $e() {
|
|
1478
1478
|
return new Promise((a, e) => {
|
|
1479
1479
|
if (typeof indexedDB > "u") {
|
|
1480
1480
|
e(new x("storage_unavailable", "This browser cannot store imported avatar models."));
|
|
@@ -1487,7 +1487,7 @@ function We() {
|
|
|
1487
1487
|
});
|
|
1488
1488
|
}
|
|
1489
1489
|
async function H(a, e) {
|
|
1490
|
-
const t = await
|
|
1490
|
+
const t = await $e();
|
|
1491
1491
|
try {
|
|
1492
1492
|
return await new Promise((i, n) => {
|
|
1493
1493
|
const s = e(t.transaction(z, a).objectStore(z));
|
|
@@ -1504,7 +1504,7 @@ const Ee = (a) => ({
|
|
|
1504
1504
|
importedAt: a.importedAt,
|
|
1505
1505
|
license: a.license
|
|
1506
1506
|
});
|
|
1507
|
-
async function
|
|
1507
|
+
async function ut(a, e = {}) {
|
|
1508
1508
|
const t = e.maxBytes ?? _e, i = typeof File < "u" && a instanceof File;
|
|
1509
1509
|
let n = i ? a.name : null, s = i ? await a.arrayBuffer() : a;
|
|
1510
1510
|
if (Te(s)) {
|
|
@@ -1516,7 +1516,7 @@ async function ht(a, e = {}) {
|
|
|
1516
1516
|
"model_too_large",
|
|
1517
1517
|
"The model is larger than the " + Math.round(t / 1024 / 1024) + " MB limit."
|
|
1518
1518
|
);
|
|
1519
|
-
const o =
|
|
1519
|
+
const o = We(s);
|
|
1520
1520
|
if (!o)
|
|
1521
1521
|
throw new x("model_not_vrm", "The file is a glTF model but carries no VRM character data.");
|
|
1522
1522
|
const r = o.title || (n ? n.replace(/\.(vrm|glb)$/i, "") : null), c = {
|
|
@@ -1559,13 +1559,13 @@ async function Je(a, e, t) {
|
|
|
1559
1559
|
function le(a) {
|
|
1560
1560
|
return a === "zip_encrypted" ? "archive_encrypted" : a === "zip_unsupported" ? "archive_unsupported" : "archive_unreadable";
|
|
1561
1561
|
}
|
|
1562
|
-
async function
|
|
1562
|
+
async function mt() {
|
|
1563
1563
|
return (await H("readonly", (e) => e.getAll()) ?? []).map(Ee).sort((e, t) => t.importedAt.localeCompare(e.importedAt));
|
|
1564
1564
|
}
|
|
1565
|
-
async function
|
|
1565
|
+
async function pt(a) {
|
|
1566
1566
|
return (await H("readonly", (t) => t.get(a)))?.data ?? null;
|
|
1567
1567
|
}
|
|
1568
|
-
async function
|
|
1568
|
+
async function ft(a) {
|
|
1569
1569
|
await H("readwrite", (e) => e.delete(a));
|
|
1570
1570
|
}
|
|
1571
1571
|
class Ge extends EventTarget {
|
|
@@ -1622,7 +1622,7 @@ class Ge extends EventTarget {
|
|
|
1622
1622
|
localStream: this.options.localStream,
|
|
1623
1623
|
simulcast: this.options.simulcast ?? !0,
|
|
1624
1624
|
onEvent: (i, n) => this.handleNativeEvent(i, n)
|
|
1625
|
-
}), await this.client.initialize(), this.startStats(), this.emit("initialized", { mode: this.mode, sdkVersion:
|
|
1625
|
+
}), await this.client.initialize(), this.startStats(), this.emit("initialized", { mode: this.mode, sdkVersion: at }), this.options.autoJoin && await this.join(), this;
|
|
1626
1626
|
} catch (e) {
|
|
1627
1627
|
this.state = "failed";
|
|
1628
1628
|
const t = fe(e, "RTC initialization failed");
|
|
@@ -1786,7 +1786,7 @@ class Ge extends EventTarget {
|
|
|
1786
1786
|
}), d;
|
|
1787
1787
|
}
|
|
1788
1788
|
async collectQualitySample(e = "runtime") {
|
|
1789
|
-
const t = this.options.statsProvider ? await this.options.statsProvider() : {}, i = this.peerConnection ? await
|
|
1789
|
+
const t = this.options.statsProvider ? await this.options.statsProvider() : {}, i = this.peerConnection ? await tt(this.peerConnection, this.previousCounters) : null;
|
|
1790
1790
|
i?.counters && (this.previousCounters = i.counters);
|
|
1791
1791
|
const s = { ...{
|
|
1792
1792
|
sampleType: e,
|
|
@@ -1819,9 +1819,9 @@ class Ge extends EventTarget {
|
|
|
1819
1819
|
transportProtocol: null,
|
|
1820
1820
|
candidateType: null,
|
|
1821
1821
|
qualityLimitationReason: null,
|
|
1822
|
-
deviceMemoryGb:
|
|
1822
|
+
deviceMemoryGb: nt(),
|
|
1823
1823
|
effectiveConnectionType: me()?.effectiveType ?? null
|
|
1824
|
-
}, ...i?.sample ?? {}, ...t, sampleType: e, sampledAt: (/* @__PURE__ */ new Date()).toISOString() }, o =
|
|
1824
|
+
}, ...i?.sample ?? {}, ...t, sampleType: e, sampledAt: (/* @__PURE__ */ new Date()).toISOString() }, o = it(s);
|
|
1825
1825
|
return s.networkScore = o.networkScore, s.estimatedMos = o.estimatedMos, this.latestQuality = s, s;
|
|
1826
1826
|
}
|
|
1827
1827
|
async reportQuality(e) {
|
|
@@ -1906,7 +1906,7 @@ class Ge extends EventTarget {
|
|
|
1906
1906
|
this.dispatchEvent(new CustomEvent(e, { detail: i })), this.options.onEvent?.(i);
|
|
1907
1907
|
}
|
|
1908
1908
|
}
|
|
1909
|
-
async function
|
|
1909
|
+
async function gt(a) {
|
|
1910
1910
|
return new Ge(a).initialize();
|
|
1911
1911
|
}
|
|
1912
1912
|
let _ = null;
|
|
@@ -1967,7 +1967,8 @@ class Ke {
|
|
|
1967
1967
|
}
|
|
1968
1968
|
}
|
|
1969
1969
|
}
|
|
1970
|
-
|
|
1970
|
+
const Xe = 6e4;
|
|
1971
|
+
class Ze extends EventTarget {
|
|
1971
1972
|
options;
|
|
1972
1973
|
socket = null;
|
|
1973
1974
|
stopped = !1;
|
|
@@ -1989,6 +1990,8 @@ class Xe extends EventTarget {
|
|
|
1989
1990
|
seenInvitationIds = /* @__PURE__ */ new Set();
|
|
1990
1991
|
invitationExpiryTimers = /* @__PURE__ */ new Map();
|
|
1991
1992
|
startCallRequest = null;
|
|
1993
|
+
/** Bumped by disconnect() so a request still in flight cannot re-claim the call slot it just freed. */
|
|
1994
|
+
callGeneration = 0;
|
|
1992
1995
|
lastDisconnect = null;
|
|
1993
1996
|
constructor(e) {
|
|
1994
1997
|
if (super(), !e.token && !e.tokenProvider) throw new Error("A client token or tokenProvider is required");
|
|
@@ -2007,10 +2010,18 @@ class Xe extends EventTarget {
|
|
|
2007
2010
|
/** Binds media lifetime to a call. Terminal call states automatically leave and destroy it. */
|
|
2008
2011
|
attachMediaClient(e, t) {
|
|
2009
2012
|
if (!e.trim()) throw new Error("callId is required");
|
|
2010
|
-
return this.mediaClients.set(e, t), () => {
|
|
2011
|
-
this.mediaClients.get(e) === t && this.mediaClients.delete(e);
|
|
2013
|
+
return this.mediaClients.set(e, t), this.clearInvitationExpiry(e), () => {
|
|
2014
|
+
this.mediaClients.get(e) === t && (this.mediaClients.delete(e), this.activeCallIds.has(e) && this.armCallWatchdog(e));
|
|
2012
2015
|
};
|
|
2013
2016
|
}
|
|
2017
|
+
/**
|
|
2018
|
+
* Arms the self-release timer for a call that holds the single call slot but
|
|
2019
|
+
* has no media attached. Every path that claims the slot arms this, so no
|
|
2020
|
+
* failure can hold it for the life of the page.
|
|
2021
|
+
*/
|
|
2022
|
+
armCallWatchdog(e) {
|
|
2023
|
+
this.scheduleInvitationExpiry(e, new Date(Date.now() + Xe).toISOString());
|
|
2024
|
+
}
|
|
2014
2025
|
/**
|
|
2015
2026
|
* Rings everyone in `targets` as a single call and connects whoever answers
|
|
2016
2027
|
* first; the rest stop ringing on their own. `target` still works and means a
|
|
@@ -2021,51 +2032,77 @@ class Xe extends EventTarget {
|
|
|
2021
2032
|
if (this.activeCallIds.size > 0) throw new Error("Another call is already active");
|
|
2022
2033
|
const t = e.targets?.length ? e.targets : e.target ? [e.target] : [];
|
|
2023
2034
|
if (t.length === 0) throw new Error("startCall requires at least one target");
|
|
2024
|
-
const i = { mode: e.mode, targets: t, metadata: e.metadata, idempotencyKey: e.idempotencyKey }, n = (async () => {
|
|
2035
|
+
const i = { mode: e.mode, targets: t, metadata: e.metadata, idempotencyKey: e.idempotencyKey }, n = this.callGeneration, s = (async () => {
|
|
2025
2036
|
await this.callAudio.unlock(), this.callAudio.startRingback();
|
|
2026
|
-
let
|
|
2037
|
+
let o;
|
|
2027
2038
|
try {
|
|
2028
|
-
|
|
2039
|
+
o = await this.request("/v1/rtc/client/calls", {
|
|
2029
2040
|
method: "POST",
|
|
2030
2041
|
headers: e.idempotencyKey ? { "idempotency-key": e.idempotencyKey } : void 0,
|
|
2031
2042
|
body: JSON.stringify(i)
|
|
2032
2043
|
});
|
|
2033
|
-
} catch (
|
|
2034
|
-
throw this.callAudio.stop(),
|
|
2044
|
+
} catch (c) {
|
|
2045
|
+
throw this.callAudio.stop(), c;
|
|
2035
2046
|
}
|
|
2036
|
-
|
|
2047
|
+
!o.credential && o.callerCredential && (o.credential = o.callerCredential);
|
|
2048
|
+
const r = String(o.call?.id ?? "") || null;
|
|
2049
|
+
if (r && n === this.callGeneration) {
|
|
2050
|
+
this.outgoingCallId = r, this.activeCallIds.add(r);
|
|
2051
|
+
const c = o.call?.expiresAt;
|
|
2052
|
+
this.scheduleInvitationExpiry(r, typeof c == "string" ? c : void 0);
|
|
2053
|
+
} else r && this.callAction(r, "cancel").catch(() => {
|
|
2054
|
+
});
|
|
2055
|
+
return this.emit("outgoingcall", o), o;
|
|
2037
2056
|
})();
|
|
2038
|
-
this.startCallRequest =
|
|
2057
|
+
this.startCallRequest = s;
|
|
2039
2058
|
try {
|
|
2040
|
-
return await
|
|
2059
|
+
return await s;
|
|
2041
2060
|
} finally {
|
|
2042
|
-
this.startCallRequest ===
|
|
2061
|
+
this.startCallRequest === s && (this.startCallRequest = null);
|
|
2043
2062
|
}
|
|
2044
2063
|
}
|
|
2045
2064
|
async accept(e = this.currentCall?.id) {
|
|
2046
2065
|
if (!e) throw new Error("No incoming call is available");
|
|
2047
2066
|
const t = await this.callAction(e, "accept");
|
|
2048
|
-
return this.activeCallIds.add(e), this.
|
|
2067
|
+
return this.activeCallIds.add(e), this.armCallWatchdog(e), this.callAudio.stop(), this.dismiss(e), this.emit("callaccepted", t), t;
|
|
2049
2068
|
}
|
|
2069
|
+
// Local release runs in a finally on all four: it must never depend on a
|
|
2070
|
+
// network round trip. A hang-up while offline, or after the server already
|
|
2071
|
+
// swept the call terminal (which answers 409), used to leave the call id in
|
|
2072
|
+
// the active set for the life of the page, and startCall() refuses while any
|
|
2073
|
+
// id is held.
|
|
2050
2074
|
async reject(e = this.currentCall?.id) {
|
|
2051
2075
|
if (!e) throw new Error("No incoming call is available");
|
|
2052
|
-
|
|
2053
|
-
|
|
2076
|
+
let t;
|
|
2077
|
+
try {
|
|
2078
|
+
return t = await this.callAction(e, "reject");
|
|
2079
|
+
} finally {
|
|
2080
|
+
this.releaseMedia(e), this.showTerminal(e, "Call declined"), this.emit("callrejected", t ?? { call: { id: e } });
|
|
2081
|
+
}
|
|
2054
2082
|
}
|
|
2055
2083
|
async busy(e = this.currentCall?.id) {
|
|
2056
2084
|
if (!e) throw new Error("No incoming call is available");
|
|
2057
|
-
|
|
2058
|
-
|
|
2085
|
+
try {
|
|
2086
|
+
return await this.callAction(e, "busy");
|
|
2087
|
+
} finally {
|
|
2088
|
+
this.releaseMedia(e), this.showTerminal(e, "Line busy");
|
|
2089
|
+
}
|
|
2059
2090
|
}
|
|
2060
2091
|
async end(e) {
|
|
2061
2092
|
this.callAudio.stop();
|
|
2062
|
-
|
|
2063
|
-
|
|
2093
|
+
try {
|
|
2094
|
+
return await this.callAction(e, "end");
|
|
2095
|
+
} finally {
|
|
2096
|
+
this.releaseMedia(e), this.showTerminal(e, "Call ended");
|
|
2097
|
+
}
|
|
2064
2098
|
}
|
|
2065
2099
|
async cancel(e) {
|
|
2066
2100
|
this.callAudio.stop();
|
|
2067
|
-
|
|
2068
|
-
|
|
2101
|
+
try {
|
|
2102
|
+
return await this.callAction(e, "cancel");
|
|
2103
|
+
} finally {
|
|
2104
|
+
this.releaseMedia(e), this.showTerminal(e, "Call cancelled");
|
|
2105
|
+
}
|
|
2069
2106
|
}
|
|
2070
2107
|
/** Injects an incoming call received through the application's own push or signaling channel. */
|
|
2071
2108
|
handleIncomingCall(e) {
|
|
@@ -2113,10 +2150,10 @@ class Xe extends EventTarget {
|
|
|
2113
2150
|
/** Applies a call state received through the application's own push or signaling channel. */
|
|
2114
2151
|
handleCallUpdate(e) {
|
|
2115
2152
|
const t = e.id === this.currentCall?.id || e.id === this.outgoingCallId, i = ["answered_elsewhere", "rejected", "busy", "cancelled", "ended", "failed", "missed"];
|
|
2116
|
-
(e.status === "accepted"
|
|
2153
|
+
i.includes(e.status) && this.clearInvitationExpiry(e.id), e.status === "accepted" && (this.mediaClients.has(e.id) ? this.clearInvitationExpiry(e.id) : this.armCallWatchdog(e.id)), t && e.status === "accepted" ? (this.activeCallIds.add(e.id), this.callAudio.stop(), this.dismiss(e.id)) : t && i.includes(e.status) && this.showTerminal(e.id, et(e.status)), i.includes(e.status) && this.releaseMedia(e.id), this.emit("callupdated", e);
|
|
2117
2154
|
}
|
|
2118
2155
|
disconnect() {
|
|
2119
|
-
this.stopped = !0, this.reconnectTimer && clearTimeout(this.reconnectTimer), this.heartbeatTimer && clearInterval(this.heartbeatTimer), this.tokenRefreshTimer && clearTimeout(this.tokenRefreshTimer), this.reconnectTimer = null, this.heartbeatTimer = null, this.tokenRefreshTimer = null, this.socket?.close(1e3, "Client disconnected"), this.socket = null, this.callAudio.stop(), this.dismiss();
|
|
2156
|
+
this.stopped = !0, this.callGeneration += 1, this.reconnectTimer && clearTimeout(this.reconnectTimer), this.heartbeatTimer && clearInterval(this.heartbeatTimer), this.tokenRefreshTimer && clearTimeout(this.tokenRefreshTimer), this.reconnectTimer = null, this.heartbeatTimer = null, this.tokenRefreshTimer = null, this.socket?.close(1e3, "Client disconnected"), this.socket = null, this.callAudio.stop(), this.dismiss();
|
|
2120
2157
|
for (const e of this.invitationExpiryTimers.values()) clearTimeout(e);
|
|
2121
2158
|
this.invitationExpiryTimers.clear();
|
|
2122
2159
|
for (const e of this.mediaClients.keys()) this.releaseMedia(e);
|
|
@@ -2306,7 +2343,7 @@ class Xe extends EventTarget {
|
|
|
2306
2343
|
}, Math.min(t, 2147e6));
|
|
2307
2344
|
}
|
|
2308
2345
|
releaseMedia(e) {
|
|
2309
|
-
this.activeCallIds.delete(e), this.seenInvitationIds.delete(e);
|
|
2346
|
+
this.clearInvitationExpiry(e), this.activeCallIds.delete(e), this.seenInvitationIds.delete(e);
|
|
2310
2347
|
const t = this.mediaClients.get(e);
|
|
2311
2348
|
t && (this.mediaClients.delete(e), t.leave().catch(() => {
|
|
2312
2349
|
}).finally(() => t.destroy()));
|
|
@@ -2322,8 +2359,8 @@ class Xe extends EventTarget {
|
|
|
2322
2359
|
this.dispatchEvent(new CustomEvent(e, { detail: i })), this.options.onEvent?.(i);
|
|
2323
2360
|
}
|
|
2324
2361
|
}
|
|
2325
|
-
function
|
|
2326
|
-
const e = new
|
|
2362
|
+
function yt(a) {
|
|
2363
|
+
const e = new Ze(a);
|
|
2327
2364
|
return a.autoConnect !== !1 && a.signalingUrl && e.connect(), e;
|
|
2328
2365
|
}
|
|
2329
2366
|
function de(a) {
|
|
@@ -2342,7 +2379,7 @@ function he(a, e, t, i) {
|
|
|
2342
2379
|
fontWeight: "700"
|
|
2343
2380
|
}), n;
|
|
2344
2381
|
}
|
|
2345
|
-
function
|
|
2382
|
+
function et(a) {
|
|
2346
2383
|
return {
|
|
2347
2384
|
rejected: "Call declined",
|
|
2348
2385
|
busy: "Line busy",
|
|
@@ -2360,7 +2397,7 @@ function ue(a) {
|
|
|
2360
2397
|
role: "participant"
|
|
2361
2398
|
};
|
|
2362
2399
|
}
|
|
2363
|
-
async function
|
|
2400
|
+
async function tt(a, e) {
|
|
2364
2401
|
const t = await a.getStats(), i = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
|
|
2365
2402
|
let s = 0, o = 0, r = 0, c = 0, l = 0, d = 0, u = 0, v = 0, p = 0, S = 0, T = 0, y = 0, k = 0, f = 0, M = 0, R = null, L = null, P = null, A = null, w = null, E = null;
|
|
2366
2403
|
t.forEach((g) => {
|
|
@@ -2368,17 +2405,17 @@ async function et(a, e) {
|
|
|
2368
2405
|
}), t.forEach((g) => {
|
|
2369
2406
|
if (g.type === "inbound-rtp" && !g.isRemote && (s += Number(g.bytesReceived ?? 0), r += Math.max(0, Number(g.packetsLost ?? 0)), c += Math.max(0, Number(g.packetsReceived ?? 0)), Number.isFinite(g.jitter) && (l += Number(g.jitter), d += 1), u = Math.max(u, Number(g.framesPerSecond ?? 0)), v = Math.max(v, Number(g.frameWidth ?? 0)), T = Math.max(T, Number(g.frameHeight ?? 0)), y += Number(g.framesDropped ?? 0), k += Number(g.freezeCount ?? 0), f += Number(g.totalFreezesDuration ?? 0), M += Number(g.concealedSamples ?? 0), w ||= i.get(String(g.codecId ?? "")) ?? null), g.type === "outbound-rtp" && !g.isRemote && (p = Math.max(p, Number(g.frameWidth ?? 0)), S = Math.max(S, Number(g.frameHeight ?? 0)), o += Number(g.bytesSent ?? 0), E ||= g.qualityLimitationReason ? String(g.qualityLimitationReason) : null, w ||= i.get(String(g.codecId ?? "")) ?? null), g.type === "candidate-pair" && (g.selected || g.nominated) && g.state === "succeeded") {
|
|
2370
2407
|
R = Number.isFinite(g.currentRoundTripTime) ? Number(g.currentRoundTripTime) : R, L = Number.isFinite(g.availableOutgoingBitrate) ? Number(g.availableOutgoingBitrate) : L;
|
|
2371
|
-
const
|
|
2372
|
-
P =
|
|
2408
|
+
const N = n.get(g.localCandidateId);
|
|
2409
|
+
P = N?.candidateType ? String(N.candidateType) : P, A = N?.protocol ? String(N.protocol) : A;
|
|
2373
2410
|
}
|
|
2374
2411
|
});
|
|
2375
|
-
const m = Date.now(), h = e ? Math.max(1e-3, (m - e.timestamp) / 1e3) : 0, b = e ? Math.max(0, Math.round((s - e.inboundBytes) * 8 / h)) : null, I = e ? Math.max(0, Math.round((o - e.outboundBytes) * 8 / h)) : null, C = r + c,
|
|
2412
|
+
const m = Date.now(), h = e ? Math.max(1e-3, (m - e.timestamp) / 1e3) : 0, b = e ? Math.max(0, Math.round((s - e.inboundBytes) * 8 / h)) : null, I = e ? Math.max(0, Math.round((o - e.outboundBytes) * 8 / h)) : null, C = r + c, U = e ? Math.max(0, r - e.packetsLost) : r, Q = e ? Math.max(0, c - e.packetsReceived) : c, q = U + Q;
|
|
2376
2413
|
return {
|
|
2377
2414
|
counters: { timestamp: m, inboundBytes: s, outboundBytes: o, packetsLost: r, packetsReceived: c },
|
|
2378
2415
|
sample: {
|
|
2379
2416
|
rttMs: R === null ? null : R * 1e3,
|
|
2380
2417
|
jitterMs: d ? l / d * 1e3 : null,
|
|
2381
|
-
packetLossPct:
|
|
2418
|
+
packetLossPct: q ? U / q * 100 : null,
|
|
2382
2419
|
packetLossCumulativePct: C ? r / C * 100 : null,
|
|
2383
2420
|
packetsLost: r,
|
|
2384
2421
|
packetsReceived: c,
|
|
@@ -2403,7 +2440,7 @@ async function et(a, e) {
|
|
|
2403
2440
|
}
|
|
2404
2441
|
};
|
|
2405
2442
|
}
|
|
2406
|
-
function
|
|
2443
|
+
function it(a) {
|
|
2407
2444
|
let e = a.mediaScore == null ? 5 : Math.round(pe(Number(a.mediaScore), 0, 5));
|
|
2408
2445
|
const t = Y(a.packetLossPct) ?? 0, i = Y(a.rttMs) ?? 0, n = Y(a.jitterMs) ?? 0, s = String(a.connectionState ?? "unknown").toLowerCase();
|
|
2409
2446
|
["failed", "closed", "disconnected"].includes(s) ? e = 0 : ["reconnecting", "checking"].includes(s) && (e = Math.min(e, 2)), t >= 15 ? e = Math.min(e, 0) : t >= 8 ? e = Math.min(e, 1) : t >= 3 ? e = Math.min(e, 2) : t >= 1 && (e = Math.min(e, 3)), i >= 1200 ? e = Math.min(e, 0) : i >= 800 ? e = Math.min(e, 1) : i >= 400 ? e = Math.min(e, 2) : i >= 250 && (e = Math.min(e, 3)), n >= 150 ? e = Math.min(e, 1) : n >= 80 ? e = Math.min(e, 2) : n >= 40 && (e = Math.min(e, 3));
|
|
@@ -2413,7 +2450,7 @@ function tt(a) {
|
|
|
2413
2450
|
function me() {
|
|
2414
2451
|
return navigator.connection ?? null;
|
|
2415
2452
|
}
|
|
2416
|
-
function
|
|
2453
|
+
function nt() {
|
|
2417
2454
|
const a = Number(navigator.deviceMemory);
|
|
2418
2455
|
return Number.isFinite(a) ? a : null;
|
|
2419
2456
|
}
|
|
@@ -2430,37 +2467,37 @@ function B(a) {
|
|
|
2430
2467
|
function fe(a, e) {
|
|
2431
2468
|
return a instanceof Error ? a : new Error(e);
|
|
2432
2469
|
}
|
|
2433
|
-
const
|
|
2470
|
+
const at = "1.4.0";
|
|
2434
2471
|
export {
|
|
2435
2472
|
_e as AVATAR_MODEL_MAX_BYTES,
|
|
2436
2473
|
oe as AVATAR_TUNING_DEFAULTS,
|
|
2437
2474
|
x as AvatarModelError,
|
|
2438
|
-
|
|
2439
|
-
|
|
2475
|
+
Ue as BACKGROUND_PRESETS,
|
|
2476
|
+
Oe as OVERLAY_EFFECTS,
|
|
2440
2477
|
Ge as RtcClient,
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2478
|
+
Ze as RtcIncomingClient,
|
|
2479
|
+
st as SPEAKER_NOISE_FLOOR,
|
|
2480
|
+
rt as SPEAKER_TAKEOVER_RATIO,
|
|
2481
|
+
dt as createAvatarPipeline,
|
|
2482
|
+
ct as createCallRecorder,
|
|
2483
|
+
ot as createPictureInPictureController,
|
|
2484
|
+
gt as createRtcClient,
|
|
2485
|
+
yt as createRtcIncomingClient,
|
|
2486
|
+
lt as createVideoEffectsPipeline,
|
|
2450
2487
|
je as drawAvatar,
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2488
|
+
qe as headPoseFromMatrix,
|
|
2489
|
+
ut as importAvatarModel,
|
|
2490
|
+
ht as listArchiveModels,
|
|
2491
|
+
mt as listAvatarModels,
|
|
2455
2492
|
ve as neutralRig,
|
|
2456
2493
|
ge as pickActiveSpeaker,
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2494
|
+
pt as readAvatarModel,
|
|
2495
|
+
We as readAvatarModelMetadata,
|
|
2496
|
+
ft as removeAvatarModel,
|
|
2460
2497
|
Ve as rigFromBlendshapes,
|
|
2461
2498
|
se as scenePainters,
|
|
2462
2499
|
re as smoothRig,
|
|
2463
2500
|
ce as stylizedAvatarRenderer,
|
|
2464
2501
|
Ye as unlockRtcCallAudio,
|
|
2465
|
-
|
|
2502
|
+
at as version
|
|
2466
2503
|
};
|