mediasfu-shared 1.2.3 → 1.2.5

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 (86) hide show
  1. package/CHANGELOG.md +4 -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/createSendTransport.d.ts.map +1 -1
  9. package/dist/consumers/gridLayout/addVideosGrid.engine.d.ts +6 -0
  10. package/dist/consumers/gridLayout/addVideosGrid.engine.d.ts.map +1 -1
  11. package/dist/consumers/index.cjs +3 -2
  12. package/dist/consumers/index.cjs.map +1 -1
  13. package/dist/consumers/index.js +14 -13
  14. package/dist/consumers/signalNewConsumerTransport.d.ts.map +1 -1
  15. package/dist/consumers/switchUserAudio.d.ts +3 -1
  16. package/dist/consumers/switchUserAudio.d.ts.map +1 -1
  17. package/dist/consumers/transportRecovery.d.ts +8 -0
  18. package/dist/consumers/transportRecovery.d.ts.map +1 -0
  19. package/dist/{getParticipantMedia-AwwtMCTz.cjs → getParticipantMedia-CP4hE5Rg.cjs} +9 -4
  20. package/dist/getParticipantMedia-CP4hE5Rg.cjs.map +1 -0
  21. package/dist/{getParticipantMedia-CyaOk2oD.js → getParticipantMedia-CvXdDj03.js} +9 -4
  22. package/dist/getParticipantMedia-CvXdDj03.js.map +1 -0
  23. package/dist/index.cjs +106 -22
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +173 -89
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.native.cjs +8 -7
  30. package/dist/index.native.cjs.map +1 -1
  31. package/dist/index.native.js +19 -18
  32. package/dist/{joinLocalRoom-Bu3gz27d.js → joinLocalRoom-Cx1y3Ojj.js} +4 -4
  33. package/dist/{joinLocalRoom-Bu3gz27d.js.map → joinLocalRoom-Cx1y3Ojj.js.map} +1 -1
  34. package/dist/{joinLocalRoom-Cii5D5IG.cjs → joinLocalRoom-DNJ2zb8W.cjs} +10 -10
  35. package/dist/{joinLocalRoom-Cii5D5IG.cjs.map → joinLocalRoom-DNJ2zb8W.cjs.map} +1 -1
  36. package/dist/{joinRoomOnMediaSFU-y6vJ1OBo.js → joinRoomOnMediaSFU-BnAWLciF.js} +9 -3
  37. package/dist/joinRoomOnMediaSFU-BnAWLciF.js.map +1 -0
  38. package/dist/{joinRoomOnMediaSFU-CC8RVJgr.cjs → joinRoomOnMediaSFU-D2C7q1GK.cjs} +9 -3
  39. package/dist/joinRoomOnMediaSFU-D2C7q1GK.cjs.map +1 -0
  40. package/dist/methods/index.cjs +3 -3
  41. package/dist/methods/index.js +3 -3
  42. package/dist/methods/stream/clickAudio.d.ts +3 -1
  43. package/dist/methods/stream/clickAudio.d.ts.map +1 -1
  44. package/dist/methods/stream/switchAudio.d.ts +3 -1
  45. package/dist/methods/stream/switchAudio.d.ts.map +1 -1
  46. package/dist/methods/utils/headless/virtualBackground.d.ts +3 -1
  47. package/dist/methods/utils/headless/virtualBackground.d.ts.map +1 -1
  48. package/dist/methods/utils/virtualBackgroundFrameLoop.d.ts +10 -0
  49. package/dist/methods/utils/virtualBackgroundFrameLoop.d.ts.map +1 -0
  50. package/dist/{translationConsumerSwitch-C20MfNNq.cjs → translationConsumerSwitch-BAsQUpH6.cjs} +9 -1
  51. package/dist/translationConsumerSwitch-BAsQUpH6.cjs.map +1 -0
  52. package/dist/{translationConsumerSwitch-zKuS5wgH.js → translationConsumerSwitch-BUODiT6o.js} +20 -12
  53. package/dist/translationConsumerSwitch-BUODiT6o.js.map +1 -0
  54. package/dist/types/index.cjs +3 -3
  55. package/dist/types/index.js +3 -3
  56. package/dist/types/shared-base-types.d.ts +12 -0
  57. package/dist/types/shared-base-types.d.ts.map +1 -1
  58. package/dist/{updateParticipantAudioDecibels-QZyahisU.cjs → updateParticipantAudioDecibels-BJ2PxJJD.cjs} +203 -46
  59. package/dist/updateParticipantAudioDecibels-BJ2PxJJD.cjs.map +1 -0
  60. package/dist/{updateParticipantAudioDecibels-CnEXJBmc.js → updateParticipantAudioDecibels-DiJ_LFfH.js} +200 -43
  61. package/dist/updateParticipantAudioDecibels-DiJ_LFfH.js.map +1 -0
  62. package/package.json +1 -1
  63. package/src/consumers/audioProcessing.ts +26 -0
  64. package/src/consumers/createSendTransport.ts +5 -20
  65. package/src/consumers/gridLayout/addVideosGrid.engine.ts +13 -0
  66. package/src/consumers/signalNewConsumerTransport.ts +7 -25
  67. package/src/consumers/switchUserAudio.ts +18 -5
  68. package/src/consumers/transportRecovery.ts +170 -0
  69. package/src/index.ts +2 -0
  70. package/src/methods/stream/clickAudio.ts +13 -5
  71. package/src/methods/stream/switchAudio.ts +10 -1
  72. package/src/methods/utils/headless/virtualBackground.ts +21 -13
  73. package/src/methods/utils/virtualBackgroundFrameLoop.ts +69 -0
  74. package/src/types/shared-base-types.ts +3 -0
  75. package/dist/getParticipantMedia-AwwtMCTz.cjs.map +0 -1
  76. package/dist/getParticipantMedia-CyaOk2oD.js.map +0 -1
  77. package/dist/joinRoomOnMediaSFU-CC8RVJgr.cjs.map +0 -1
  78. package/dist/joinRoomOnMediaSFU-y6vJ1OBo.js.map +0 -1
  79. package/dist/translationConsumerSwitch-C20MfNNq.cjs.map +0 -1
  80. package/dist/translationConsumerSwitch-zKuS5wgH.js.map +0 -1
  81. package/dist/updateParticipantAudioDecibels-CnEXJBmc.js.map +0 -1
  82. package/dist/updateParticipantAudioDecibels-QZyahisU.cjs.map +0 -1
  83. package/dist/validateAlphanumeric-DKn5BsUP.cjs +0 -15
  84. package/dist/validateAlphanumeric-DKn5BsUP.cjs.map +0 -1
  85. package/dist/validateAlphanumeric-Dk1JB80W.js +0 -16
  86. 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.`
@@ -886,6 +886,184 @@ async function disconnectSocket({ socket }) {
886
886
  }
887
887
  return true;
888
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
+ }
889
1067
  const signalNewConsumerTransport = async ({
890
1068
  remoteProducerId,
891
1069
  islevel,
@@ -932,23 +1110,13 @@ const signalNewConsumerTransport = async ({
932
1110
  }
933
1111
  }
934
1112
  );
935
- consumerTransport.on("connectionstatechange", async (state) => {
936
- switch (state) {
937
- case "connecting":
938
- break;
939
- case "connected":
940
- break;
941
- case "failed":
942
- consumerTransport.close();
943
- if (lock_screen) {
944
- await reorderStreams2({ add: true, parameters });
945
- } else {
946
- await reorderStreams2({ add: false, parameters });
947
- }
948
- break;
949
- default:
950
- break;
951
- }
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
+ });
952
1120
  });
953
1121
  await connectRecvTransport2({
954
1122
  consumerTransport,
@@ -1885,12 +2053,7 @@ const createLocalSendTransport = async ({
1885
2053
  }
1886
2054
  }
1887
2055
  );
1888
- createdLocalTransport.on("connectionstatechange", (state) => {
1889
- if (state === "failed") {
1890
- console.error("Local transport connection failed.");
1891
- createdLocalTransport.close();
1892
- }
1893
- });
2056
+ attachTransportRecovery(createdLocalTransport, localSocket, () => clearFailedSendState(parameters, createdLocalTransport, true));
1894
2057
  localTransportCreated = true;
1895
2058
  updateLocalTransportCreated?.(localTransportCreated);
1896
2059
  await connectSendTransport2({
@@ -1981,20 +2144,7 @@ const createSendTransport = async ({
1981
2144
  }
1982
2145
  }
1983
2146
  );
1984
- createdProducerTransport.on("connectionstatechange", async (state) => {
1985
- switch (state) {
1986
- case "connecting":
1987
- break;
1988
- case "connected":
1989
- break;
1990
- case "failed":
1991
- console.log("Transport connection failed.");
1992
- createdProducerTransport.close();
1993
- break;
1994
- default:
1995
- break;
1996
- }
1997
- });
2147
+ attachTransportRecovery(createdProducerTransport, socket, () => clearFailedSendState(parameters, createdProducerTransport));
1998
2148
  transportCreated = true;
1999
2149
  parameters = parameters.getCurrentParams?.() ?? parameters;
2000
2150
  await connectSendTransport2({
@@ -4210,7 +4360,7 @@ const streamSuccessVideo = async ({
4210
4360
  }
4211
4361
  }
4212
4362
  };
4213
- async function switchUserAudio({ audioPreference, parameters }) {
4363
+ async function switchUserAudio({ audioPreference, parameters, audioProcessing }) {
4214
4364
  const {
4215
4365
  mediaDevices,
4216
4366
  prevAudioInputDevice,
@@ -4236,12 +4386,19 @@ async function switchUserAudio({ audioPreference, parameters }) {
4236
4386
  }
4237
4387
  }
4238
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
+ }
4239
4397
  const mediaConstraints = {
4240
4398
  audio: {
4241
4399
  deviceId: { exact: audioPreference },
4242
- echoCancellation: false,
4243
- noiseSuppression: false,
4244
- autoGainControl: false
4400
+ ...processing,
4401
+ ...audioProcessingConstraints(audioProcessing)
4245
4402
  },
4246
4403
  video: false
4247
4404
  };
@@ -5501,4 +5658,4 @@ export {
5501
5658
  processConsumerTransportsAudio as y,
5502
5659
  readjust as z
5503
5660
  };
5504
- //# sourceMappingURL=updateParticipantAudioDecibels-CnEXJBmc.js.map
5661
+ //# sourceMappingURL=updateParticipantAudioDecibels-DiJ_LFfH.js.map