mediasfu-shared 1.2.2 → 1.2.4

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.
Files changed (94) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/audioProcessing-0z5KlcmO.js +35 -0
  3. package/dist/audioProcessing-0z5KlcmO.js.map +1 -0
  4. package/dist/audioProcessing-BpbrdCk-.cjs +34 -0
  5. package/dist/audioProcessing-BpbrdCk-.cjs.map +1 -0
  6. package/dist/consumers/audioProcessing.d.ts +8 -0
  7. package/dist/consumers/audioProcessing.d.ts.map +1 -0
  8. package/dist/consumers/connectIps.d.ts.map +1 -1
  9. package/dist/consumers/createSendTransport.d.ts.map +1 -1
  10. package/dist/consumers/gridLayout/addVideosGrid.engine.d.ts +6 -0
  11. package/dist/consumers/gridLayout/addVideosGrid.engine.d.ts.map +1 -1
  12. package/dist/consumers/index.cjs +3 -2
  13. package/dist/consumers/index.cjs.map +1 -1
  14. package/dist/consumers/index.js +14 -13
  15. package/dist/consumers/signalNewConsumerTransport.d.ts.map +1 -1
  16. package/dist/consumers/switchUserAudio.d.ts +3 -1
  17. package/dist/consumers/switchUserAudio.d.ts.map +1 -1
  18. package/dist/consumers/transportRecovery.d.ts +8 -0
  19. package/dist/consumers/transportRecovery.d.ts.map +1 -0
  20. package/dist/{getParticipantMedia-BH3d_-Q1.cjs → getParticipantMedia-CP4hE5Rg.cjs} +9 -4
  21. package/dist/getParticipantMedia-CP4hE5Rg.cjs.map +1 -0
  22. package/dist/{getParticipantMedia-CGqnSb93.js → getParticipantMedia-CvXdDj03.js} +9 -4
  23. package/dist/getParticipantMedia-CvXdDj03.js.map +1 -0
  24. package/dist/index.cjs +138 -25
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +205 -92
  29. package/dist/index.js.map +1 -1
  30. package/dist/index.native.cjs +8 -7
  31. package/dist/index.native.cjs.map +1 -1
  32. package/dist/index.native.js +19 -18
  33. package/dist/{joinLocalRoom-7ibqv7zZ.js → joinLocalRoom-Cx1y3Ojj.js} +4 -4
  34. package/dist/{joinLocalRoom-7ibqv7zZ.js.map → joinLocalRoom-Cx1y3Ojj.js.map} +1 -1
  35. package/dist/{joinLocalRoom-BJBDvTYh.cjs → joinLocalRoom-DNJ2zb8W.cjs} +10 -10
  36. package/dist/{joinLocalRoom-BJBDvTYh.cjs.map → joinLocalRoom-DNJ2zb8W.cjs.map} +1 -1
  37. package/dist/{joinRoomOnMediaSFU-y6vJ1OBo.js → joinRoomOnMediaSFU-BnAWLciF.js} +9 -3
  38. package/dist/joinRoomOnMediaSFU-BnAWLciF.js.map +1 -0
  39. package/dist/{joinRoomOnMediaSFU-CC8RVJgr.cjs → joinRoomOnMediaSFU-D2C7q1GK.cjs} +9 -3
  40. package/dist/joinRoomOnMediaSFU-D2C7q1GK.cjs.map +1 -0
  41. package/dist/methods/index.cjs +3 -3
  42. package/dist/methods/index.js +3 -3
  43. package/dist/methods/stream/clickAudio.d.ts +3 -1
  44. package/dist/methods/stream/clickAudio.d.ts.map +1 -1
  45. package/dist/methods/stream/switchAudio.d.ts +3 -1
  46. package/dist/methods/stream/switchAudio.d.ts.map +1 -1
  47. package/dist/methods/utils/headless/virtualBackground.d.ts +15 -1
  48. package/dist/methods/utils/headless/virtualBackground.d.ts.map +1 -1
  49. package/dist/methods/utils/virtualBackgroundCompositor.d.ts +4 -0
  50. package/dist/methods/utils/virtualBackgroundCompositor.d.ts.map +1 -1
  51. package/dist/methods/utils/virtualBackgroundFrameLoop.d.ts +10 -0
  52. package/dist/methods/utils/virtualBackgroundFrameLoop.d.ts.map +1 -0
  53. package/dist/sockets/SocketManager.d.ts +0 -27
  54. package/dist/sockets/SocketManager.d.ts.map +1 -1
  55. package/dist/{translationConsumerSwitch-C20MfNNq.cjs → translationConsumerSwitch-BAsQUpH6.cjs} +9 -1
  56. package/dist/translationConsumerSwitch-BAsQUpH6.cjs.map +1 -0
  57. package/dist/{translationConsumerSwitch-zKuS5wgH.js → translationConsumerSwitch-BUODiT6o.js} +20 -12
  58. package/dist/translationConsumerSwitch-BUODiT6o.js.map +1 -0
  59. package/dist/types/index.cjs +3 -3
  60. package/dist/types/index.js +3 -3
  61. package/dist/types/shared-base-types.d.ts +12 -0
  62. package/dist/types/shared-base-types.d.ts.map +1 -1
  63. package/dist/{updateParticipantAudioDecibels-bZ6R8WHj.cjs → updateParticipantAudioDecibels-BJ2PxJJD.cjs} +287 -58
  64. package/dist/updateParticipantAudioDecibels-BJ2PxJJD.cjs.map +1 -0
  65. package/dist/{updateParticipantAudioDecibels-C_MygF6q.js → updateParticipantAudioDecibels-DiJ_LFfH.js} +284 -55
  66. package/dist/updateParticipantAudioDecibels-DiJ_LFfH.js.map +1 -0
  67. package/package.json +1 -1
  68. package/src/consumers/audioProcessing.ts +26 -0
  69. package/src/consumers/connectIps.ts +46 -7
  70. package/src/consumers/createSendTransport.ts +5 -20
  71. package/src/consumers/gridLayout/addVideosGrid.engine.ts +13 -0
  72. package/src/consumers/signalNewConsumerTransport.ts +7 -25
  73. package/src/consumers/switchUserAudio.ts +18 -5
  74. package/src/consumers/transportRecovery.ts +170 -0
  75. package/src/index.ts +2 -0
  76. package/src/methods/stream/clickAudio.ts +13 -5
  77. package/src/methods/stream/switchAudio.ts +10 -1
  78. package/src/methods/utils/headless/virtualBackground.ts +55 -15
  79. package/src/methods/utils/virtualBackgroundCompositor.ts +18 -1
  80. package/src/methods/utils/virtualBackgroundFrameLoop.ts +69 -0
  81. package/src/sockets/SocketManager.ts +54 -7
  82. package/src/types/shared-base-types.ts +3 -0
  83. package/dist/getParticipantMedia-BH3d_-Q1.cjs.map +0 -1
  84. package/dist/getParticipantMedia-CGqnSb93.js.map +0 -1
  85. package/dist/joinRoomOnMediaSFU-CC8RVJgr.cjs.map +0 -1
  86. package/dist/joinRoomOnMediaSFU-y6vJ1OBo.js.map +0 -1
  87. package/dist/translationConsumerSwitch-C20MfNNq.cjs.map +0 -1
  88. package/dist/translationConsumerSwitch-zKuS5wgH.js.map +0 -1
  89. package/dist/updateParticipantAudioDecibels-C_MygF6q.js.map +0 -1
  90. package/dist/updateParticipantAudioDecibels-bZ6R8WHj.cjs.map +0 -1
  91. package/dist/validateAlphanumeric-DKn5BsUP.cjs +0 -15
  92. package/dist/validateAlphanumeric-DKn5BsUP.cjs.map +0 -1
  93. package/dist/validateAlphanumeric-Dk1JB80W.js +0 -16
  94. package/dist/validateAlphanumeric-Dk1JB80W.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import io from "socket.io-client";
2
- import { v as validateAlphanumeric } from "./validateAlphanumeric-Dk1JB80W.js";
2
+ import { v as validateAlphanumeric, b as audioProcessingConstraints } from "./audioProcessing-0z5KlcmO.js";
3
3
  const createFrameworkConsumerContractError = (consumerName) => {
4
4
  return new Error(
5
5
  `${consumerName} is a render-coupled consumer helper and has no shared runtime implementation. Inject the framework-specific ${consumerName} implementation instead of calling the shared fallback export.`
@@ -765,6 +765,7 @@ async function validateApiKeyToken(value) {
765
765
  }
766
766
  return true;
767
767
  }
768
+ const CONNECT_TIMEOUT_MS = 12e3;
768
769
  async function connectSocket({ apiUserName, apiKey, apiToken, link }) {
769
770
  if (!apiUserName) {
770
771
  throw new Error("API username required.");
@@ -808,7 +809,21 @@ async function connectSocket({ apiUserName, apiKey, apiToken, link }) {
808
809
  }
809
810
  });
810
811
  }
811
- socket.on("connection-success", ({ socketId }) => {
812
+ let settled = false;
813
+ let timeoutHandle;
814
+ const cleanupHandshake = () => {
815
+ if (timeoutHandle) clearTimeout(timeoutHandle);
816
+ socket.off("connection-success", handleConnectionSuccess);
817
+ socket.off("connect_error", handleConnectError);
818
+ socket.off("disconnect", handleDisconnectBeforeReady);
819
+ };
820
+ const settle = (action) => {
821
+ if (settled) return;
822
+ settled = true;
823
+ cleanupHandshake();
824
+ action();
825
+ };
826
+ const handleConnectionSuccess = ({ socketId }) => {
812
827
  let conn = "media";
813
828
  try {
814
829
  if (link.includes("mediasfu.com") && (link.match(/c/g)?.length ?? 0) > 1) {
@@ -817,11 +832,35 @@ async function connectSocket({ apiUserName, apiKey, apiToken, link }) {
817
832
  } catch {
818
833
  }
819
834
  console.log(`Connected to ${conn} socket with ID: ${socketId}`);
820
- resolve(socket);
821
- });
822
- socket.on("connect_error", (error) => {
823
- reject(new Error("Error connecting to media socket: " + error.message));
824
- });
835
+ settle(() => resolve(socket));
836
+ };
837
+ const handleConnectError = (error) => {
838
+ settle(() => {
839
+ socket.disconnect();
840
+ reject(new Error("Error connecting to media socket: " + error.message));
841
+ });
842
+ };
843
+ const handleDisconnectBeforeReady = (reason) => {
844
+ settle(
845
+ () => reject(
846
+ new Error(
847
+ "Media socket closed before the room was ready (" + reason + ")."
848
+ )
849
+ )
850
+ );
851
+ };
852
+ socket.on("connection-success", handleConnectionSuccess);
853
+ socket.on("connect_error", handleConnectError);
854
+ socket.on("disconnect", handleDisconnectBeforeReady);
855
+ timeoutHandle = setTimeout(() => {
856
+ settle(() => {
857
+ try {
858
+ socket.disconnect();
859
+ } catch {
860
+ }
861
+ reject(new Error("Timed out connecting to media socket."));
862
+ });
863
+ }, CONNECT_TIMEOUT_MS);
825
864
  });
826
865
  }
827
866
  async function connectLocalSocket({ link }) {
@@ -847,6 +886,184 @@ async function disconnectSocket({ socket }) {
847
886
  }
848
887
  return true;
849
888
  }
889
+ function attachTransportRecovery(transport, socket, onFailure) {
890
+ let timer;
891
+ let disposed = false;
892
+ let recovering = false;
893
+ let attempts = 0;
894
+ const socketId = socket.id;
895
+ const listeners = [];
896
+ const report = (state) => {
897
+ transport.appData = { ...transport.appData, recoveryState: state };
898
+ transport.observer?.emit("recoverychange", state);
899
+ };
900
+ const clearTimer = () => {
901
+ if (timer) clearTimeout(timer);
902
+ timer = void 0;
903
+ };
904
+ const current = () => !disposed && !transport.closed && socket.connected !== false && socket.id === socketId;
905
+ const dispose = () => {
906
+ disposed = true;
907
+ clearTimer();
908
+ listeners.splice(0).forEach((cancel) => cancel());
909
+ socket.off?.("disconnect", dispose);
910
+ transport.off?.("connectionstatechange", changed);
911
+ transport.observer?.off?.("close", dispose);
912
+ };
913
+ const failed = () => {
914
+ if (disposed) return;
915
+ report("failed");
916
+ try {
917
+ onFailure();
918
+ } catch (_) {
919
+ }
920
+ try {
921
+ transport.close();
922
+ } finally {
923
+ dispose();
924
+ }
925
+ };
926
+ const waitConnected = () => new Promise((resolve, reject) => {
927
+ let settled = false;
928
+ const finish = (error) => {
929
+ if (settled) return;
930
+ settled = true;
931
+ clearTimeout(deadline);
932
+ transport.off?.("connectionstatechange", connected);
933
+ const i = listeners.indexOf(cancel);
934
+ if (i >= 0) listeners.splice(i, 1);
935
+ error ? reject(error) : resolve();
936
+ };
937
+ const connected = (state) => {
938
+ if (state === "connected") finish();
939
+ };
940
+ const cancel = () => finish(new Error("Recovery cancelled"));
941
+ const deadline = setTimeout(() => finish(new Error("ICE recovery timed out")), 1e4);
942
+ listeners.push(cancel);
943
+ transport.on("connectionstatechange", connected);
944
+ if (transport.connectionState === "connected") finish();
945
+ });
946
+ const restart = async () => {
947
+ if (!current() || recovering) return;
948
+ recovering = true;
949
+ report("recovering");
950
+ try {
951
+ while (current() && attempts < 2) {
952
+ attempts++;
953
+ try {
954
+ const iceParameters = await new Promise((resolve, reject) => {
955
+ let settled = false;
956
+ const finish = (error, value) => {
957
+ if (settled) return;
958
+ settled = true;
959
+ clearTimeout(deadline);
960
+ const i = listeners.indexOf(cancel);
961
+ if (i >= 0) listeners.splice(i, 1);
962
+ error ? reject(error) : resolve(value);
963
+ };
964
+ const cancel = () => finish(new Error("Recovery cancelled"));
965
+ const deadline = setTimeout(() => finish(new Error("ICE restart acknowledgement timed out")), 8e3);
966
+ listeners.push(cancel);
967
+ socket.emit("transport-restart-ice", { transportId: transport.id }, (response) => {
968
+ if (!response?.iceParameters || response.error) finish(new Error(response?.error || "Invalid ICE response"));
969
+ else finish(void 0, response.iceParameters);
970
+ });
971
+ });
972
+ if (!current()) return;
973
+ await new Promise((resolve, reject) => {
974
+ let settled = false;
975
+ const finish = (error) => {
976
+ if (settled) return;
977
+ settled = true;
978
+ clearTimeout(deadline);
979
+ const i = listeners.indexOf(cancel);
980
+ if (i >= 0) listeners.splice(i, 1);
981
+ error ? reject(error) : resolve();
982
+ };
983
+ const cancel = () => finish(new Error("Recovery cancelled"));
984
+ const deadline = setTimeout(() => finish(new Error("Local ICE restart timed out")), 8e3);
985
+ listeners.push(cancel);
986
+ Promise.resolve().then(() => {
987
+ if (!current()) throw new Error("Recovery cancelled");
988
+ return transport.restartIce({ iceParameters });
989
+ }).then(() => finish(), (error) => finish(error));
990
+ });
991
+ if (!current()) return;
992
+ await waitConnected();
993
+ if (!current()) return;
994
+ attempts = 0;
995
+ report("connected");
996
+ return;
997
+ } catch (_) {
998
+ if (!current()) return;
999
+ if (transport.connectionState === "connected") {
1000
+ attempts = 0;
1001
+ report("connected");
1002
+ return;
1003
+ }
1004
+ if (attempts < 2) {
1005
+ await new Promise((resolve) => {
1006
+ const cancel = () => {
1007
+ clearTimeout(delay);
1008
+ const i = listeners.indexOf(cancel);
1009
+ if (i >= 0) listeners.splice(i, 1);
1010
+ resolve();
1011
+ };
1012
+ const delay = setTimeout(cancel, 2100);
1013
+ listeners.push(cancel);
1014
+ });
1015
+ }
1016
+ }
1017
+ }
1018
+ if (current()) failed();
1019
+ } finally {
1020
+ recovering = false;
1021
+ }
1022
+ };
1023
+ const changed = (state) => {
1024
+ if (disposed) return;
1025
+ if (state === "connected") {
1026
+ clearTimer();
1027
+ if (!recovering) {
1028
+ attempts = 0;
1029
+ report("connected");
1030
+ }
1031
+ } else if (state === "disconnected") {
1032
+ if (recovering || timer) return;
1033
+ report("waiting");
1034
+ timer = setTimeout(() => {
1035
+ timer = void 0;
1036
+ void restart();
1037
+ }, 3e3);
1038
+ } else if (state === "failed") {
1039
+ clearTimer();
1040
+ void restart();
1041
+ } else if (state === "closed") dispose();
1042
+ };
1043
+ socket.on?.("disconnect", dispose);
1044
+ transport.on("connectionstatechange", changed);
1045
+ transport.observer?.once("close", dispose);
1046
+ return dispose;
1047
+ }
1048
+ function clearFailedSendState(parameters, transport, local = false) {
1049
+ const live = parameters.getCurrentParams?.() ?? parameters.getUpdatedAllParams?.() ?? parameters;
1050
+ if ((local ? live.localProducerTransport : live.producerTransport) !== transport) return;
1051
+ if (local) {
1052
+ live.updateLocalProducerTransport?.(null);
1053
+ live.updateLocalTransportCreated?.(false);
1054
+ return;
1055
+ }
1056
+ for (const kind of ["Audio", "Video", "Screen"]) {
1057
+ const key = kind.toLowerCase();
1058
+ live["update" + kind + "Producer"]?.(null);
1059
+ live["updateTransportCreated" + kind]?.(false);
1060
+ live["update" + kind + "AlreadyOn"]?.(false);
1061
+ live.socket?.emit("pauseProducerMedia", { mediaTag: key, roomName: live.roomName });
1062
+ }
1063
+ live.updateProducerTransport?.(null);
1064
+ live.updateTransportCreated?.(false);
1065
+ live.showAlert?.({ message: "Media connection could not recover. Rejoin the room to restore audio and video.", type: "danger", duration: 1e4 });
1066
+ }
850
1067
  const signalNewConsumerTransport = async ({
851
1068
  remoteProducerId,
852
1069
  islevel,
@@ -893,23 +1110,13 @@ const signalNewConsumerTransport = async ({
893
1110
  }
894
1111
  }
895
1112
  );
896
- consumerTransport.on("connectionstatechange", async (state) => {
897
- switch (state) {
898
- case "connecting":
899
- break;
900
- case "connected":
901
- break;
902
- case "failed":
903
- consumerTransport.close();
904
- if (lock_screen) {
905
- await reorderStreams2({ add: true, parameters });
906
- } else {
907
- await reorderStreams2({ add: false, parameters });
908
- }
909
- break;
910
- default:
911
- break;
912
- }
1113
+ attachTransportRecovery(consumerTransport, nsock, () => {
1114
+ const live = parameters.getCurrentParams?.() ?? parameters.getUpdatedAllParams?.() ?? parameters;
1115
+ live.updateConsumingTransports?.((live.consumingTransports || []).filter((id) => id !== remoteProducerId));
1116
+ live.updateConsumerTransports?.((live.consumerTransports || []).filter((entry) => entry.consumerTransport !== consumerTransport));
1117
+ live.showAlert?.({ message: "A remote media connection could not recover. Rejoin to restore it.", type: "danger", duration: 1e4 });
1118
+ void Promise.resolve(reorderStreams2({ add: Boolean(lock_screen), parameters })).catch(() => {
1119
+ });
913
1120
  });
914
1121
  await connectRecvTransport2({
915
1122
  consumerTransport,
@@ -1193,10 +1400,19 @@ const joinConsumeRoom = async ({
1193
1400
  };
1194
1401
  const pendingConsumeConnections = /* @__PURE__ */ new WeakMap();
1195
1402
  const normalizeConsumeEndpoint = (ip) => ip.trim().toLowerCase().replace(/\.$/, "");
1196
- const hasConsumeEndpoint = (consumeSockets, endpoint) => consumeSockets.some((socketObj) => {
1197
- const ip = Object.keys(socketObj)[0];
1198
- return Boolean(ip) && normalizeConsumeEndpoint(ip) === endpoint;
1199
- });
1403
+ const hasConsumeEndpoint = (consumeSockets, endpoint) => {
1404
+ for (let index = consumeSockets.length - 1; index >= 0; index -= 1) {
1405
+ const socketObj = consumeSockets[index];
1406
+ const ip = Object.keys(socketObj)[0];
1407
+ if (!ip || normalizeConsumeEndpoint(ip) !== endpoint) continue;
1408
+ const socket = socketObj[ip];
1409
+ if (socket?.connected && socket.id) return true;
1410
+ socket?.removeAllListeners?.();
1411
+ socket?.disconnect?.();
1412
+ consumeSockets.splice(index, 1);
1413
+ }
1414
+ return false;
1415
+ };
1200
1416
  async function reserveConsumeEndpoint(consumeSockets, ip, reservationOwner = consumeSockets) {
1201
1417
  const endpoint = normalizeConsumeEndpoint(ip);
1202
1418
  if (!endpoint || endpoint === "none") return null;
@@ -1220,6 +1436,9 @@ async function reserveConsumeEndpoint(consumeSockets, ip, reservationOwner = con
1220
1436
  return (didConnect = false) => {
1221
1437
  if (pendingForSockets?.get(endpoint) === reservation) {
1222
1438
  pendingForSockets.delete(endpoint);
1439
+ if (pendingForSockets.size === 0) {
1440
+ pendingConsumeConnections.delete(reservationOwner);
1441
+ }
1223
1442
  }
1224
1443
  resolvePending(didConnect === true);
1225
1444
  };
@@ -1256,8 +1475,9 @@ const connectIps = async ({
1256
1475
  );
1257
1476
  if (!releaseReservation) continue;
1258
1477
  let connected = false;
1478
+ let remote_sock = null;
1259
1479
  try {
1260
- const remote_sock = await connectSocket({ apiUserName, apiKey, apiToken, link: `https://${ip}.mediasfu.com` });
1480
+ remote_sock = await connectSocket({ apiUserName, apiKey, apiToken, link: `https://${ip}.mediasfu.com` });
1261
1481
  if (remote_sock.id) {
1262
1482
  if (!roomRecvIPs.includes(ip)) {
1263
1483
  roomRecvIPs.push(ip);
@@ -1288,16 +1508,36 @@ const connectIps = async ({
1288
1508
  parameters
1289
1509
  });
1290
1510
  if (!data.rtpCapabilities) {
1291
- return [consume_sockets, roomRecvIPs];
1511
+ throw new Error(`Consume room ${ip} did not return RTP capabilities.`);
1292
1512
  }
1293
1513
  }
1294
1514
  consume_sockets.push({ [ip]: remote_sock });
1295
1515
  updateConsume_sockets(consume_sockets);
1296
1516
  connected = true;
1517
+ remote_sock.on("disconnect", () => {
1518
+ const socketIndex = consume_sockets.findIndex(
1519
+ (socketObj) => socketObj[ip] === remote_sock
1520
+ );
1521
+ if (socketIndex >= 0) {
1522
+ consume_sockets.splice(socketIndex, 1);
1523
+ updateConsume_sockets(consume_sockets);
1524
+ }
1525
+ const recvIndex = roomRecvIPs.indexOf(ip);
1526
+ if (recvIndex >= 0) {
1527
+ roomRecvIPs.splice(recvIndex, 1);
1528
+ updateRoomRecvIPs(roomRecvIPs);
1529
+ }
1530
+ remote_sock?.removeAllListeners?.();
1531
+ remote_sock?.disconnect();
1532
+ });
1297
1533
  }
1298
1534
  } catch (error) {
1299
1535
  console.log("connectIps error", error);
1300
1536
  } finally {
1537
+ if (!connected && remote_sock) {
1538
+ remote_sock.removeAllListeners?.();
1539
+ remote_sock.disconnect();
1540
+ }
1301
1541
  releaseReservation(connected);
1302
1542
  }
1303
1543
  }
@@ -1813,12 +2053,7 @@ const createLocalSendTransport = async ({
1813
2053
  }
1814
2054
  }
1815
2055
  );
1816
- createdLocalTransport.on("connectionstatechange", (state) => {
1817
- if (state === "failed") {
1818
- console.error("Local transport connection failed.");
1819
- createdLocalTransport.close();
1820
- }
1821
- });
2056
+ attachTransportRecovery(createdLocalTransport, localSocket, () => clearFailedSendState(parameters, createdLocalTransport, true));
1822
2057
  localTransportCreated = true;
1823
2058
  updateLocalTransportCreated?.(localTransportCreated);
1824
2059
  await connectSendTransport2({
@@ -1909,20 +2144,7 @@ const createSendTransport = async ({
1909
2144
  }
1910
2145
  }
1911
2146
  );
1912
- createdProducerTransport.on("connectionstatechange", async (state) => {
1913
- switch (state) {
1914
- case "connecting":
1915
- break;
1916
- case "connected":
1917
- break;
1918
- case "failed":
1919
- console.log("Transport connection failed.");
1920
- createdProducerTransport.close();
1921
- break;
1922
- default:
1923
- break;
1924
- }
1925
- });
2147
+ attachTransportRecovery(createdProducerTransport, socket, () => clearFailedSendState(parameters, createdProducerTransport));
1926
2148
  transportCreated = true;
1927
2149
  parameters = parameters.getCurrentParams?.() ?? parameters;
1928
2150
  await connectSendTransport2({
@@ -4138,7 +4360,7 @@ const streamSuccessVideo = async ({
4138
4360
  }
4139
4361
  }
4140
4362
  };
4141
- async function switchUserAudio({ audioPreference, parameters }) {
4363
+ async function switchUserAudio({ audioPreference, parameters, audioProcessing }) {
4142
4364
  const {
4143
4365
  mediaDevices,
4144
4366
  prevAudioInputDevice,
@@ -4164,12 +4386,19 @@ async function switchUserAudio({ audioPreference, parameters }) {
4164
4386
  }
4165
4387
  }
4166
4388
  }
4389
+ const track = parameters.localStreamAudio?.getAudioTracks?.()[0] ?? parameters.localStream?.getAudioTracks?.()[0] ?? parameters.audioProducer?.track;
4390
+ const previousConstraints = track?.getConstraints?.() ?? {};
4391
+ const previousSettings = track?.getSettings?.() ?? {};
4392
+ const processing = {};
4393
+ for (const key of ["echoCancellation", "noiseSuppression", "autoGainControl"]) {
4394
+ const value = previousConstraints[key] ?? previousSettings[key];
4395
+ if (value !== void 0) processing[key] = value;
4396
+ }
4167
4397
  const mediaConstraints = {
4168
4398
  audio: {
4169
4399
  deviceId: { exact: audioPreference },
4170
- echoCancellation: false,
4171
- noiseSuppression: false,
4172
- autoGainControl: false
4400
+ ...processing,
4401
+ ...audioProcessingConstraints(audioProcessing)
4173
4402
  },
4174
4403
  video: false
4175
4404
  };
@@ -5429,4 +5658,4 @@ export {
5429
5658
  processConsumerTransportsAudio as y,
5430
5659
  readjust as z
5431
5660
  };
5432
- //# sourceMappingURL=updateParticipantAudioDecibels-C_MygF6q.js.map
5661
+ //# sourceMappingURL=updateParticipantAudioDecibels-DiJ_LFfH.js.map