mediasfu-shared 1.0.1 → 1.0.2

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 (125) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +103 -222
  3. package/dist/index.cjs +7500 -2163
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +4203 -273
  6. package/dist/index.js +7521 -2184
  7. package/dist/index.js.map +1 -1
  8. package/package.json +85 -78
  9. package/src/ProducerClient/producerClientEmits/joinRoomClient.ts +57 -0
  10. package/src/ProducerClient/producerClientEmits/updateRoomParametersClient.ts +401 -0
  11. package/src/consumers/addVideosGrid.ts +3 -2
  12. package/src/consumers/changeVids.ts +111 -41
  13. package/src/consumers/checkPermission.ts +35 -1
  14. package/src/consumers/connectRecvTransport.ts +42 -1
  15. package/src/consumers/consumerResume.ts +2 -2
  16. package/src/consumers/dispStreams.ts +83 -37
  17. package/src/consumers/frameworkConsumerContract.ts +6 -0
  18. package/src/consumers/generatePageContent.ts +24 -10
  19. package/src/consumers/getPipedProducersAlt.ts +112 -16
  20. package/src/consumers/gridLayout/addVideosGrid.engine.ts +42 -0
  21. package/src/consumers/gridLayout/prepopulateUserMedia.engine.ts +444 -0
  22. package/src/consumers/mixStreams.ts +45 -14
  23. package/src/consumers/onScreenChanges.ts +25 -10
  24. package/src/consumers/prepopulateUserMedia.ts +3 -2
  25. package/src/consumers/processConsumerTransports.ts +68 -23
  26. package/src/consumers/processConsumerTransportsAudio.ts +53 -16
  27. package/src/consumers/reUpdateInter.ts +61 -21
  28. package/src/consumers/readjust.ts +30 -14
  29. package/src/consumers/reorderStreams.ts +76 -42
  30. package/src/consumers/resumePauseAudioStreams.ts +66 -17
  31. package/src/consumers/resumePauseStreams.ts +53 -10
  32. package/src/consumers/socketReceiveMethods/joinConsumeRoom.ts +8 -0
  33. package/src/consumers/socketReceiveMethods/newPipeProducer.ts +114 -0
  34. package/src/consumers/socketReceiveMethods/producerClosed.ts +13 -0
  35. package/src/consumers/streamSuccessScreen.ts +2 -2
  36. package/src/consumers/streamSuccessVideo.ts +5 -0
  37. package/src/consumers/translationConsumerSwitch.ts +299 -0
  38. package/src/index.ts +85 -1
  39. package/src/methods/coHostMethods/modifyCoHostSettings.ts +9 -9
  40. package/src/methods/displaySettings/modifyDisplaySettings.ts +5 -0
  41. package/src/methods/index.ts +66 -0
  42. package/src/methods/message/sendMessage.ts +12 -29
  43. package/src/methods/panelists/focusPanelists.ts +83 -0
  44. package/src/methods/panelists/index.ts +3 -0
  45. package/src/methods/panelists/launchPanelists.ts +13 -0
  46. package/src/methods/panelists/updatePanelists.ts +135 -0
  47. package/src/methods/permissions/index.ts +3 -0
  48. package/src/methods/permissions/launchPermissions.ts +13 -0
  49. package/src/methods/permissions/updateParticipantPermission.ts +127 -0
  50. package/src/methods/permissions/updatePermissionConfig.ts +52 -0
  51. package/src/methods/polls/pollUpdated.ts +88 -0
  52. package/src/methods/recording/confirmRecording.ts +15 -12
  53. package/src/methods/recording/recordResumeTimer.ts +2 -2
  54. package/src/methods/recording/recordStartTimer.ts +2 -2
  55. package/src/methods/recording/timeLeftRecording.ts +25 -0
  56. package/src/methods/requests/hostRequestResponse.ts +153 -0
  57. package/src/methods/settings/modifySettings.ts +17 -17
  58. package/src/methods/socketReceive/allMembers.ts +450 -0
  59. package/src/methods/socketReceive/allMembersRest.ts +480 -0
  60. package/src/methods/socketReceive/allWaitingRoomMembers.ts +35 -0
  61. package/src/methods/socketReceive/banParticipant.ts +73 -0
  62. package/src/methods/socketReceive/controlMediaHost.ts +280 -0
  63. package/src/methods/socketReceive/disconnect.ts +40 -0
  64. package/src/methods/socketReceive/disconnectUserSelf.ts +56 -0
  65. package/src/methods/socketReceive/getDomains.ts +112 -0
  66. package/src/methods/socketReceive/meetingEnded.ts +49 -0
  67. package/src/methods/socketReceive/meetingStillThere.ts +26 -0
  68. package/src/methods/socketReceive/panelistReceiveMethods.ts +195 -0
  69. package/src/methods/socketReceive/participantRequested.ts +48 -0
  70. package/src/methods/socketReceive/permissionReceiveMethods.ts +59 -0
  71. package/src/methods/socketReceive/personJoined.ts +35 -0
  72. package/src/methods/socketReceive/producerMediaClosed.ts +223 -0
  73. package/src/methods/socketReceive/producerMediaPaused.ts +267 -0
  74. package/src/methods/socketReceive/producerMediaResumed.ts +157 -0
  75. package/src/methods/socketReceive/reInitiateRecording.ts +53 -0
  76. package/src/methods/socketReceive/receiveMessage.ts +117 -0
  77. package/src/methods/socketReceive/recordingNotice.ts +286 -0
  78. package/src/methods/socketReceive/roomRecordParams.ts +122 -0
  79. package/src/methods/socketReceive/screenProducerId.ts +61 -0
  80. package/src/methods/socketReceive/startRecords.ts +46 -0
  81. package/src/methods/socketReceive/stoppedRecording.ts +44 -0
  82. package/src/methods/socketReceive/translationReceiveMethods.ts +581 -0
  83. package/src/methods/socketReceive/updateConsumingDomains.ts +128 -0
  84. package/src/methods/socketReceive/updateMediaSettings.ts +45 -0
  85. package/src/methods/socketReceive/updatedCoHost.ts +75 -0
  86. package/src/methods/socketReceive/userWaiting.ts +45 -0
  87. package/src/methods/stream/clickAudio.ts +380 -0
  88. package/src/methods/stream/clickChat.ts +36 -0
  89. package/src/methods/stream/clickScreenShare.ts +173 -0
  90. package/src/methods/stream/clickVideo.ts +22 -5
  91. package/src/methods/stream/index.ts +1 -0
  92. package/src/methods/utils/SoundPlayer.ts +31 -0
  93. package/src/methods/utils/checkLimitsAndMakeRequest.ts +156 -2
  94. package/src/methods/utils/createResponseJoinRoom.ts +47 -0
  95. package/src/methods/utils/createRoomOnMediaSFU.ts +160 -0
  96. package/src/methods/utils/formatNumber.ts +42 -0
  97. package/src/methods/utils/generateRandomMessages.ts +70 -0
  98. package/src/methods/utils/generateRandomParticipants.ts +100 -0
  99. package/src/methods/utils/generateRandomPolls.ts +43 -0
  100. package/src/methods/utils/generateRandomRequestList.ts +51 -0
  101. package/src/methods/utils/generateRandomWaitingRoomList.ts +17 -0
  102. package/src/methods/utils/getModalPosition.ts +23 -0
  103. package/src/methods/utils/getOverlayPosition.ts +37 -0
  104. package/src/methods/utils/initialValuesState.ts +405 -0
  105. package/src/methods/utils/joinRoomOnMediaSFU.ts +124 -0
  106. package/src/methods/utils/liveSubtitle.ts +107 -0
  107. package/src/methods/utils/meetingTimeRemaining.ts +33 -0
  108. package/src/methods/utils/meetingTimer/startMeetingProgressTimer.ts +72 -0
  109. package/src/methods/utils/producer/aParams.ts +10 -0
  110. package/src/methods/utils/producer/hParams.ts +26 -0
  111. package/src/methods/utils/producer/screenParams.ts +13 -0
  112. package/src/methods/utils/producer/vParams.ts +26 -0
  113. package/src/methods/utils/producer/videoCaptureConstraints.ts +65 -0
  114. package/src/methods/utils/resolveMediaSFURoomApi.ts +16 -0
  115. package/src/methods/utils/sleep.ts +24 -0
  116. package/src/methods/utils/translationLanguages.ts +308 -0
  117. package/src/methods/utils/webrtc.ts +44 -0
  118. package/src/methods/welcome/handleWelcomeRequest.ts +11 -2
  119. package/src/methods/welcome/index.ts +5 -1
  120. package/src/methods/whiteboard/captureCanvasStream.ts +128 -0
  121. package/src/producers/producerEmits/joinConRoom.ts +2 -2
  122. package/src/producers/producerEmits/joinLocalRoom.ts +240 -0
  123. package/src/producers/producerEmits/joinRoom.ts +129 -0
  124. package/src/types/shared-base-types.ts +14 -3
  125. package/src/types/types.ts +255 -0
@@ -2,6 +2,14 @@ import { Socket } from 'socket.io-client';
2
2
  import { signalNewConsumerTransport } from '../signalNewConsumerTransport';
3
3
  import { ReorderStreamsParameters, ReorderStreamsType, SignalNewConsumerTransportParameters, ConnectRecvTransportParameters, ConnectRecvTransportType, ShowAlert } from '../../types/types';
4
4
  import type { Device } from 'mediasoup-client/lib/types';
5
+
6
+ export interface TranslationMeta {
7
+ speakerId: string;
8
+ speakerName: string;
9
+ language: string;
10
+ originalProducerId?: string;
11
+ isSpeakerControlled?: boolean;
12
+ }
5
13
  export interface NewPipeProducerParameters extends ReorderStreamsParameters, SignalNewConsumerTransportParameters, ConnectRecvTransportParameters {
6
14
 
7
15
  first_round: boolean;
@@ -21,6 +29,15 @@ export interface NewPipeProducerParameters extends ReorderStreamsParameters, Sig
21
29
  connectRecvTransport: ConnectRecvTransportType;
22
30
  reorderStreams: ReorderStreamsType;
23
31
  getUpdatedAllParams: () => NewPipeProducerParameters;
32
+
33
+ startConsumingTranslation?: (producerId: string, speakerId: string, language: string, originalProducerId?: string, nsock?: Socket) => Promise<void>;
34
+ translationSubscriptions?: Map<string, { speakerId: string; language: string }>;
35
+ speakerTranslationStates?: Map<string, { speakerId: string; speakerName: string; inputLanguage: string; outputLanguage: string; originalProducerId: string; enabled: boolean }>;
36
+ listenerTranslationOverrides?: Map<string, { speakerId: string; wantOriginal: boolean; preferredLanguage?: string }>;
37
+ listenerTranslationPreferences?: {
38
+ perSpeaker: Map<string, { speakerId: string; language: string | null; wantOriginal: boolean }>;
39
+ globalLanguage: string | null;
40
+ };
24
41
  [key: string]: any;
25
42
 
26
43
  }
@@ -30,6 +47,8 @@ export interface NewPipeProducerOptions {
30
47
  islevel: string;
31
48
  nsock: Socket;
32
49
  parameters: NewPipeProducerParameters;
50
+ isTranslation?: boolean;
51
+ translationMeta?: TranslationMeta;
33
52
  }
34
53
 
35
54
  // Export the type definition for the function
@@ -96,7 +115,102 @@ export const newPipeProducer = async ({
96
115
  islevel,
97
116
  nsock,
98
117
  parameters,
118
+ isTranslation,
119
+ translationMeta,
99
120
  }: NewPipeProducerOptions): Promise<void> => {
121
+ if (isTranslation && translationMeta) {
122
+ const freshParams = parameters.getUpdatedAllParams ? parameters.getUpdatedAllParams() : parameters;
123
+
124
+ const {
125
+ startConsumingTranslation,
126
+ translationSubscriptions,
127
+ speakerTranslationStates,
128
+ listenerTranslationOverrides,
129
+ listenerTranslationPreferences,
130
+ } = freshParams;
131
+
132
+ const normalizedLang = translationMeta.language?.toLowerCase();
133
+ const isSpeakerControlledFromMeta = translationMeta.isSpeakerControlled === true;
134
+ const speakerState = speakerTranslationStates?.get(translationMeta.speakerId);
135
+ const isSpeakerControlledFromState = speakerState?.enabled
136
+ && speakerState?.outputLanguage?.toLowerCase() === normalizedLang;
137
+ const shouldSkipBecauseWrongLanguage = isSpeakerControlledFromMeta
138
+ && speakerState?.enabled
139
+ && speakerState?.outputLanguage?.toLowerCase() !== normalizedLang;
140
+
141
+ const subscriptionKey = `${translationMeta.speakerId}_${normalizedLang}`;
142
+ const isListenerSubscribed = translationSubscriptions?.has(subscriptionKey)
143
+ || translationSubscriptions?.has(translationMeta.speakerId);
144
+
145
+ let overrideBlocksConsumption = false;
146
+ let shouldConsumeForOverride = false;
147
+ let shouldConsumeForGlobal = false;
148
+
149
+ const perSpeakerPref = listenerTranslationPreferences?.perSpeaker?.get(translationMeta.speakerId);
150
+ const globalPref = listenerTranslationPreferences?.globalLanguage;
151
+ const listenerOverride = listenerTranslationOverrides?.get(translationMeta.speakerId);
152
+
153
+ if (perSpeakerPref) {
154
+ if (perSpeakerPref.wantOriginal) {
155
+ overrideBlocksConsumption = true;
156
+ } else if (perSpeakerPref.language) {
157
+ if (perSpeakerPref.language === normalizedLang) {
158
+ shouldConsumeForOverride = true;
159
+ } else {
160
+ overrideBlocksConsumption = true;
161
+ }
162
+ }
163
+ } else if (globalPref) {
164
+ if (globalPref === normalizedLang) {
165
+ shouldConsumeForGlobal = true;
166
+ } else {
167
+ overrideBlocksConsumption = true;
168
+ }
169
+ } else if (listenerOverride) {
170
+ if (listenerOverride.wantOriginal) {
171
+ overrideBlocksConsumption = true;
172
+ } else if (listenerOverride.preferredLanguage) {
173
+ if (listenerOverride.preferredLanguage.toLowerCase() === normalizedLang) {
174
+ shouldConsumeForOverride = true;
175
+ } else {
176
+ overrideBlocksConsumption = true;
177
+ }
178
+ }
179
+ }
180
+
181
+ const shouldConsumeForSpeakerControlled =
182
+ isSpeakerControlledFromMeta
183
+ && (!speakerState?.enabled || speakerState?.outputLanguage?.toLowerCase() === normalizedLang);
184
+ const hasNoPreference = !perSpeakerPref && !globalPref && !listenerOverride;
185
+ const isListenerInitiated = !isSpeakerControlledFromMeta && !isSpeakerControlledFromState;
186
+ const blockBecauseNotRelevant = hasNoPreference && isListenerInitiated && !isListenerSubscribed;
187
+
188
+ const shouldConsume =
189
+ !overrideBlocksConsumption
190
+ && !shouldSkipBecauseWrongLanguage
191
+ && !blockBecauseNotRelevant
192
+ && (shouldConsumeForOverride
193
+ || shouldConsumeForGlobal
194
+ || shouldConsumeForSpeakerControlled
195
+ || isSpeakerControlledFromState
196
+ || isListenerSubscribed);
197
+
198
+ if (shouldConsume && startConsumingTranslation) {
199
+ try {
200
+ await startConsumingTranslation(
201
+ producerId,
202
+ translationMeta.speakerId,
203
+ translationMeta.language,
204
+ translationMeta.originalProducerId,
205
+ nsock,
206
+ );
207
+ } catch {
208
+ }
209
+ }
210
+
211
+ return;
212
+ }
213
+
100
214
  const {
101
215
  shareScreenStarted,
102
216
  shared,
@@ -63,6 +63,19 @@ export const producerClosed = async ({
63
63
  }: ProducerClosedOptions): Promise<void> => {
64
64
  let { consumerTransports, closeAndResize, screenId, updateConsumerTransports } = parameters;
65
65
 
66
+ const activeTranslationProducerIds = parameters.activeTranslationProducerIds;
67
+ const isTranslationProducer = activeTranslationProducerIds?.has?.(remoteProducerId);
68
+
69
+ if (isTranslationProducer) {
70
+ activeTranslationProducerIds?.delete?.(remoteProducerId);
71
+
72
+ const removeTranslationStream = parameters.removeTranslationStream as ((producerId: string) => void) | undefined;
73
+
74
+ if (removeTranslationStream) {
75
+ removeTranslationStream(remoteProducerId);
76
+ }
77
+ }
78
+
66
79
  // Handle producer closed
67
80
  const producerToClose = consumerTransports.find(
68
81
  (transportData: any) => transportData.producerId === remoteProducerId
@@ -3,11 +3,11 @@
3
3
  import { Socket } from "socket.io-client";
4
4
  import {
5
5
  SleepType, CreateSendTransportType, ConnectSendTransportScreenType, DisconnectSendTransportScreenType, StopShareScreenType, ReorderStreamsType, PrepopulateUserMediaType, RePortType,
6
- ShowAlert, CreateSendTransportParameters, ConnectSendTransportScreenParameters, DisconnectSendTransportScreenParameters, StopShareScreenParameters, ReorderStreamsParameters, PrepopulateUserMediaParameters,
6
+ ShowAlert, CreateSendTransportParameters, ConnectSendTransportScreenParameters, DisconnectSendTransportScreenParameters, StopShareScreenParameters, ReorderStreamsParameters, PrepopulateUserMediaParameters, RePortParameters,
7
7
  EventType
8
8
  } from "../types/types";
9
9
 
10
- export interface StreamSuccessScreenParameters extends CreateSendTransportParameters, ConnectSendTransportScreenParameters, DisconnectSendTransportScreenParameters, StopShareScreenParameters, ReorderStreamsParameters, PrepopulateUserMediaParameters {
10
+ export interface StreamSuccessScreenParameters extends CreateSendTransportParameters, ConnectSendTransportScreenParameters, DisconnectSendTransportScreenParameters, StopShareScreenParameters, ReorderStreamsParameters, PrepopulateUserMediaParameters, RePortParameters {
11
11
  socket: Socket;
12
12
  transportCreated: boolean;
13
13
  localStreamScreen: MediaStream | null;
@@ -30,6 +30,7 @@ export interface StreamSuccessVideoParameters extends CreateSendTransportParamet
30
30
  keepBackground: boolean;
31
31
  appliedBackground: boolean;
32
32
  videoProducer: Producer | null;
33
+ removeSingleVideoEncoding?: boolean;
33
34
 
34
35
  // Update functions
35
36
  updateTransportCreatedVideo: (created: boolean) => void;
@@ -275,6 +276,10 @@ export const streamSuccessVideo = async ({
275
276
  (codec: RtpCodecCapability) => codec.mimeType.toLowerCase() !== "video/vp9" && codec.kind === "video"
276
277
  ) || [];
277
278
 
279
+ if (parameters.removeSingleVideoEncoding && videoParamse.encodings && videoParamse.encodings.length <= 1) {
280
+ delete videoParamse.encodings;
281
+ }
282
+
278
283
  videoParams = {
279
284
  track: localStream.getVideoTracks()[0],
280
285
  ...videoParamse,
@@ -0,0 +1,299 @@
1
+ import { BreakoutParticipant, EventType, Participant, Transport } from '../types/types';
2
+
3
+ export interface TranslationConsumerSwitchParameters {
4
+ consumerTransports: Transport[];
5
+ roomName: string;
6
+ member: string;
7
+ updateConsumerTransports: (transports: Transport[]) => void;
8
+ breakOutRoomStarted?: boolean;
9
+ breakOutRoomEnded?: boolean;
10
+ breakoutRooms?: BreakoutParticipant[][];
11
+ limitedBreakRoom?: BreakoutParticipant[];
12
+ participants?: Participant[];
13
+ ref_participants?: Participant[];
14
+ islevel?: string;
15
+ eventType?: EventType;
16
+ hostNewRoom?: number;
17
+ [key: string]: any;
18
+ }
19
+
20
+ export interface PauseOriginalProducerOptions {
21
+ originalProducerId: string;
22
+ speakerId?: string;
23
+ parameters: TranslationConsumerSwitchParameters;
24
+ }
25
+
26
+ export interface ResumeOriginalProducerOptions {
27
+ originalProducerId: string;
28
+ speakerId?: string;
29
+ parameters: TranslationConsumerSwitchParameters;
30
+ }
31
+
32
+ export type PauseOriginalProducerType = (options: PauseOriginalProducerOptions) => Promise<void>;
33
+ export type ResumeOriginalProducerType = (options: ResumeOriginalProducerOptions) => Promise<void>;
34
+
35
+ export interface StopConsumingTranslationOptions {
36
+ speakerId?: string;
37
+ language: string;
38
+ translationProducerMap: Record<string, Record<string, string>>;
39
+ parameters: TranslationConsumerSwitchParameters;
40
+ }
41
+
42
+ export type StopConsumingTranslationType = (options: StopConsumingTranslationOptions) => Promise<string | null>;
43
+
44
+ export const isSpeakerInMyBreakoutRoom = (
45
+ speakerName: string,
46
+ parameters: TranslationConsumerSwitchParameters
47
+ ): boolean => {
48
+ const {
49
+ breakOutRoomStarted = false,
50
+ breakOutRoomEnded = false,
51
+ limitedBreakRoom = [],
52
+ participants = [],
53
+ islevel = '1',
54
+ eventType = 'conference',
55
+ hostNewRoom = -1,
56
+ breakoutRooms = [],
57
+ member = '',
58
+ } = parameters;
59
+
60
+ if (!breakOutRoomStarted || breakOutRoomEnded) {
61
+ return true;
62
+ }
63
+
64
+ const host = participants.find((p) => p.islevel === '2');
65
+ const speakerIsHost = host?.name === speakerName;
66
+
67
+ if (islevel !== '2') {
68
+ if (eventType === 'webinar' && speakerIsHost) {
69
+ return true;
70
+ }
71
+
72
+ if (eventType === 'conference' && speakerIsHost) {
73
+ const roomMember = breakoutRooms.find((r) =>
74
+ r.find((p) => p.name === member)
75
+ );
76
+ const memberBreakRoom = roomMember ? breakoutRooms.indexOf(roomMember) : -1;
77
+ const inBreakRoom = memberBreakRoom !== -1;
78
+
79
+ if (inBreakRoom) {
80
+ return memberBreakRoom === hostNewRoom;
81
+ }
82
+
83
+ if (hostNewRoom === -1) {
84
+ return true;
85
+ }
86
+
87
+ return hostNewRoom === memberBreakRoom && memberBreakRoom !== -1;
88
+ }
89
+ }
90
+
91
+ return limitedBreakRoom.some((p) => p.name === speakerName);
92
+ };
93
+
94
+ export const pauseOriginalProducer = async ({
95
+ originalProducerId,
96
+ speakerId,
97
+ parameters,
98
+ }: PauseOriginalProducerOptions): Promise<void> => {
99
+ try {
100
+ const { consumerTransports } = parameters;
101
+
102
+ if (speakerId && !isSpeakerInMyBreakoutRoom(speakerId, parameters)) {
103
+ return;
104
+ }
105
+
106
+ const transport = consumerTransports.find(
107
+ (t) => t.producerId === originalProducerId && t.consumer?.kind === 'audio'
108
+ );
109
+
110
+ if (transport && transport.consumer && !transport.consumer.paused) {
111
+ transport.consumer.pause();
112
+
113
+ transport.socket_?.emit(
114
+ 'consumer-pause',
115
+ { serverConsumerId: transport.serverConsumerTransportId },
116
+ async () => {}
117
+ );
118
+ }
119
+ } catch (error) {
120
+ console.error('[TranslationSwitch] Error pausing original producer:', error);
121
+ }
122
+ };
123
+
124
+ export const resumeOriginalProducer = async ({
125
+ originalProducerId,
126
+ speakerId,
127
+ parameters,
128
+ }: ResumeOriginalProducerOptions): Promise<void> => {
129
+ try {
130
+ const { consumerTransports } = parameters;
131
+
132
+ if (speakerId && !isSpeakerInMyBreakoutRoom(speakerId, parameters)) {
133
+ return;
134
+ }
135
+
136
+ const transport = consumerTransports.find(
137
+ (t) => t.producerId === originalProducerId && t.consumer?.kind === 'audio'
138
+ );
139
+
140
+ if (transport && transport.consumer && transport.consumer.paused) {
141
+ transport.socket_?.emit(
142
+ 'consumer-resume',
143
+ { serverConsumerId: transport.serverConsumerTransportId },
144
+ async ({ resumed }: { resumed: boolean }) => {
145
+ if (resumed) {
146
+ transport.consumer.resume();
147
+ }
148
+ }
149
+ );
150
+ }
151
+ } catch (error) {
152
+ console.error('[TranslationSwitch] Error resuming original producer:', error);
153
+ }
154
+ };
155
+
156
+ export const isConsumingTranslationForSpeaker = (
157
+ speakerId: string,
158
+ consumerTransports: Transport[],
159
+ translationProducerMap: Map<string, { translationProducerId: string; originalProducerId: string; language: string }>
160
+ ): { consuming: boolean; language?: string; translationProducerId?: string; originalProducerId?: string } => {
161
+ const translationInfo = translationProducerMap.get(speakerId);
162
+
163
+ if (translationInfo) {
164
+ const hasConsumer = consumerTransports.some(
165
+ (t) => t.producerId === translationInfo.translationProducerId
166
+ );
167
+
168
+ if (hasConsumer) {
169
+ return {
170
+ consuming: true,
171
+ language: translationInfo.language,
172
+ translationProducerId: translationInfo.translationProducerId,
173
+ originalProducerId: translationInfo.originalProducerId,
174
+ };
175
+ }
176
+ }
177
+
178
+ return { consuming: false };
179
+ };
180
+
181
+ export const getActiveTranslationConsumers = (
182
+ translationProducerMap: Map<string, { translationProducerId: string; originalProducerId: string; language: string }>,
183
+ consumerTransports: Transport[]
184
+ ): Array<{ speakerId: string; translationProducerId: string; originalProducerId: string; language: string }> => {
185
+ const results: Array<{ speakerId: string; translationProducerId: string; originalProducerId: string; language: string }> = [];
186
+
187
+ translationProducerMap.forEach((info, speakerId) => {
188
+ const hasConsumer = consumerTransports.some(
189
+ (t) => t.producerId === info.translationProducerId
190
+ );
191
+
192
+ if (hasConsumer) {
193
+ results.push({
194
+ speakerId,
195
+ ...info,
196
+ });
197
+ }
198
+ });
199
+
200
+ return results;
201
+ };
202
+
203
+ export const findOriginalProducerForSpeaker = (
204
+ speakerId: string,
205
+ allAudioStreams: Array<{ producerId: string; name?: string; [key: string]: any }>
206
+ ): string | null => {
207
+ const stream = allAudioStreams.find(
208
+ (s) => s.name === speakerId || s.producerId?.includes(speakerId)
209
+ );
210
+ return stream?.producerId || null;
211
+ };
212
+
213
+ export const stopConsumingTranslation = async (options: StopConsumingTranslationOptions): Promise<string | null> => {
214
+ const { language, translationProducerMap, parameters } = options;
215
+ try {
216
+ const { consumerTransports, updateConsumerTransports } = parameters;
217
+
218
+ let originalProducerId: string | null = null;
219
+ let translationProducerId: string | null = null;
220
+
221
+ for (const [origId, langMap] of Object.entries(translationProducerMap)) {
222
+ if (langMap && langMap[language]) {
223
+ translationProducerId = langMap[language];
224
+ originalProducerId = origId;
225
+ break;
226
+ }
227
+ }
228
+
229
+ if (!translationProducerId) {
230
+ return originalProducerId;
231
+ }
232
+
233
+ const transportIndex = consumerTransports.findIndex(
234
+ (t) => t.producerId === translationProducerId
235
+ );
236
+
237
+ if (transportIndex === -1) {
238
+ return originalProducerId;
239
+ }
240
+
241
+ const transport = consumerTransports[transportIndex];
242
+
243
+ if (transport.socket_ && transport.consumer) {
244
+ transport.socket_.emit(
245
+ 'consumer-close',
246
+ { serverConsumerId: transport.serverConsumerTransportId },
247
+ () => {}
248
+ );
249
+ }
250
+
251
+ if (transport.consumer) {
252
+ transport.consumer.close();
253
+ }
254
+
255
+ const updatedTransports = consumerTransports.filter((_, i) => i !== transportIndex);
256
+ updateConsumerTransports(updatedTransports);
257
+
258
+ return originalProducerId;
259
+ } catch (error) {
260
+ console.error('[TranslationSwitch] Error stopping translation consumer:', error);
261
+ return null;
262
+ }
263
+ };
264
+
265
+ export const syncTranslationStateAfterBreakoutChange = async (
266
+ translationProducerMap: Record<string, Record<string, string>>,
267
+ speakerIdByProducerId: Record<string, string>,
268
+ parameters: TranslationConsumerSwitchParameters
269
+ ): Promise<void> => {
270
+ try {
271
+ const { consumerTransports } = parameters;
272
+
273
+ for (const [originalProducerId, langMap] of Object.entries(translationProducerMap)) {
274
+ const speakerId = speakerIdByProducerId[originalProducerId];
275
+ if (!speakerId) continue;
276
+
277
+ const inMyRoom = isSpeakerInMyBreakoutRoom(speakerId, parameters);
278
+ const hasTranslation = Object.keys(langMap).length > 0;
279
+
280
+ const originalConsumer = consumerTransports.find(
281
+ (t) => t.producerId === originalProducerId && t.consumer?.kind === 'audio'
282
+ );
283
+
284
+ if (!originalConsumer) continue;
285
+
286
+ if (inMyRoom && hasTranslation) {
287
+ if (!originalConsumer.consumer.paused) {
288
+ await pauseOriginalProducer({
289
+ originalProducerId,
290
+ speakerId,
291
+ parameters,
292
+ });
293
+ }
294
+ }
295
+ }
296
+ } catch (error) {
297
+ console.error('[TranslationSwitch] Error syncing translation state:', error);
298
+ }
299
+ };
package/src/index.ts CHANGED
@@ -11,11 +11,14 @@ export * from './consumers/checkScreenShare';
11
11
  export * from './consumers/closeAndResize';
12
12
  export * from './consumers/compareActiveNames';
13
13
  export * from './consumers/compareScreenStates';
14
+ export * from './consumers/gridLayout/addVideosGrid.engine';
15
+ export * from './consumers/gridLayout/prepopulateUserMedia.engine';
14
16
  export * from './consumers/connectIps';
15
17
  export * from './consumers/connectLocalIps';
16
18
  export * from './consumers/connectRecvTransport';
17
19
  export * from './consumers/connectSendTransport';
18
20
  export * from './consumers/connectSendTransportAudio';
21
+ export * from './consumers/consumerResume';
19
22
  export * from './consumers/connectSendTransportScreen';
20
23
  export * from './consumers/connectSendTransportVideo';
21
24
  export * from './consumers/controlMedia';
@@ -56,6 +59,7 @@ export * from './consumers/streamSuccessVideo';
56
59
  export * from './consumers/switchUserAudio';
57
60
  export * from './consumers/switchUserVideo';
58
61
  export * from './consumers/switchUserVideoAlt';
62
+ export * from './consumers/translationConsumerSwitch';
59
63
  export * from './consumers/trigger';
60
64
  export * from './consumers/updateMiniCardsGrid';
61
65
  export * from './consumers/updateParticipantAudioDecibels';
@@ -79,10 +83,17 @@ export * from './methods/participants/launchParticipants';
79
83
  export * from './methods/participants/messageParticipants';
80
84
  export * from './methods/participants/muteParticipants';
81
85
  export * from './methods/participants/removeParticipants';
86
+ export * from './methods/panelists/launchPanelists';
87
+ export * from './methods/panelists/updatePanelists';
88
+ export * from './methods/panelists/focusPanelists';
89
+ export * from './methods/permissions/launchPermissions';
90
+ export * from './methods/permissions/updateParticipantPermission';
91
+ export * from './methods/permissions/updatePermissionConfig';
82
92
  export * from './methods/polls/handleCreatePoll';
83
93
  export * from './methods/polls/handleEndPoll';
84
94
  export * from './methods/polls/handleVotePoll';
85
95
  export * from './methods/polls/launchPoll';
96
+ export * from './methods/polls/pollUpdated';
86
97
  export * from './methods/prejoin/handleCreateRoom';
87
98
  export * from './methods/prejoin/handleJoinRoom';
88
99
  export * from './methods/recording/checkPauseState';
@@ -95,24 +106,97 @@ export * from './methods/recording/recordStartTimer';
95
106
  export * from './methods/recording/recordUpdateTimer';
96
107
  export * from './methods/recording/startRecording';
97
108
  export * from './methods/recording/stopRecording';
109
+ export * from './methods/recording/timeLeftRecording';
98
110
  export * from './methods/recording/updateRecording';
99
111
  export * from './methods/requests/launchRequests';
112
+ export * from './methods/requests/hostRequestResponse';
100
113
  export * from './methods/requests/respondToRequests';
101
114
  export * from './methods/settings/launchSettings';
102
115
  export * from './methods/settings/modifySettings';
103
116
  export * from './methods/stream/switchAudio';
104
117
  export * from './methods/stream/switchVideo';
105
118
  export * from './methods/stream/switchVideoAlt';
119
+ export * from './methods/stream/clickAudio';
120
+ export * from './methods/stream/clickChat';
121
+ export * from './methods/stream/clickScreenShare';
122
+ export * from './methods/utils/liveSubtitle';
123
+ export * from './methods/utils/translationLanguages';
124
+ export * from './methods/utils/SoundPlayer';
125
+ export * from './methods/utils/getOverlayPosition';
126
+ export * from './methods/utils/getModalPosition';
127
+ export * from './methods/utils/sleep';
128
+ export * from './methods/utils/formatNumber';
129
+ export * from './methods/utils/generateRandomMessages';
130
+ export * from './methods/utils/generateRandomParticipants';
131
+ export * from './methods/utils/generateRandomPolls';
132
+ export * from './methods/utils/generateRandomRequestList';
133
+ export * from './methods/utils/generateRandomWaitingRoomList';
134
+ export * from './methods/utils/initialValuesState';
135
+ export * from './methods/utils/webrtc';
136
+ export * from './methods/utils/checkLimitsAndMakeRequest';
137
+ export * from './methods/utils/createResponseJoinRoom';
138
+ export * from './methods/utils/joinRoomOnMediaSFU';
139
+ export * from './methods/utils/createRoomOnMediaSFU';
140
+ export * from './methods/utils/meetingTimer/startMeetingProgressTimer';
141
+ export * from './methods/utils/meetingTimeRemaining';
142
+ export * from './methods/utils/producer/aParams';
143
+ export * from './methods/utils/producer/hParams';
144
+ export * from './methods/utils/producer/vParams';
145
+ export * from './methods/utils/producer/screenParams';
146
+ export * from './methods/utils/producer/videoCaptureConstraints';
147
+ export * from './methods/utils/validateAlphanumeric';
148
+ export * from './methods/socketReceive/allWaitingRoomMembers';
149
+ export * from './methods/socketReceive/allMembers';
150
+ export * from './methods/socketReceive/allMembersRest';
151
+ export * from './methods/socketReceive/banParticipant';
152
+ export * from './methods/socketReceive/controlMediaHost';
153
+ export * from './methods/socketReceive/disconnect';
154
+ export * from './methods/socketReceive/disconnectUserSelf';
155
+ export * from './methods/socketReceive/getDomains';
156
+ export * from './methods/socketReceive/meetingEnded';
157
+ export * from './methods/socketReceive/meetingStillThere';
158
+ export * from './methods/socketReceive/panelistReceiveMethods';
159
+ export * from './methods/socketReceive/participantRequested';
160
+ export * from './methods/socketReceive/permissionReceiveMethods';
161
+ export * from './methods/socketReceive/personJoined';
162
+ export * from './methods/socketReceive/producerMediaClosed';
163
+ export * from './methods/socketReceive/producerMediaPaused';
164
+ export * from './methods/socketReceive/producerMediaResumed';
165
+ export * from './methods/socketReceive/receiveMessage';
166
+ export * from './methods/socketReceive/recordingNotice';
167
+ export * from './methods/socketReceive/reInitiateRecording';
168
+ export * from './methods/socketReceive/roomRecordParams';
169
+ export * from './methods/socketReceive/screenProducerId';
170
+ export * from './methods/socketReceive/startRecords';
171
+ export * from './methods/socketReceive/stoppedRecording';
172
+ export * from './methods/socketReceive/translationReceiveMethods';
173
+ export * from './methods/socketReceive/updateMediaSettings';
174
+ export * from './methods/socketReceive/updateConsumingDomains';
175
+ export * from './methods/socketReceive/updatedCoHost';
176
+ export * from './methods/socketReceive/userWaiting';
106
177
  export * from './methods/waiting/launchWaiting';
107
178
  export * from './methods/waiting/respondToWaiting';
108
- export * from './methods/welcome/handleWelcomeRequest';
179
+ export {
180
+ handleWelcomeRequest,
181
+ validateAlphanumeric as validateWelcomeAlphanumeric,
182
+ validateWelcomeInputs,
183
+ } from './methods/welcome/handleWelcomeRequest';
184
+ export type {
185
+ HandleWelcomeRequestOptions,
186
+ ValidateWelcomeInputsOptions,
187
+ } from './methods/welcome/handleWelcomeRequest';
109
188
  export * from './methods/whiteboard/handleStartWhiteboard';
110
189
  export * from './methods/whiteboard/handleStopWhiteboard';
111
190
  export * from './methods/whiteboard/launchConfigureWhiteboard';
191
+ export * from './methods/whiteboard/captureCanvasStream';
112
192
  // ProducerClient exports
113
193
  export * from './ProducerClient/producerClientEmits/createDeviceClient';
194
+ export * from './ProducerClient/producerClientEmits/joinRoomClient';
195
+ export * from './ProducerClient/producerClientEmits/updateRoomParametersClient';
114
196
  // Producers exports
115
197
  export * from './producers/producerEmits/joinConRoom';
198
+ export * from './producers/producerEmits/joinLocalRoom';
199
+ export * from './producers/producerEmits/joinRoom';
116
200
  // Socket exports
117
201
  export * from './sockets/SocketManager';
118
202
  // Stream method exports (clickVideo)
@@ -51,7 +51,7 @@ export type ModifyCoHostSettingsType = (options: ModifyCoHostSettingsOptions) =>
51
51
  */
52
52
  export const modifyCoHostSettings = async ({
53
53
  roomName,
54
- showAlert,
54
+ // showAlert,
55
55
  selectedParticipant,
56
56
  coHost,
57
57
  coHostResponsibility,
@@ -61,15 +61,15 @@ export const modifyCoHostSettings = async ({
61
61
  socket,
62
62
  }: ModifyCoHostSettingsOptions): Promise<void> => {
63
63
  // Check if the chat room is in demo mode
64
- if (roomName.toLowerCase().startsWith('d')) {
65
- showAlert?.({
66
- message: 'You cannot add co-host in demo mode.',
67
- type: 'danger',
68
- duration: 3000,
69
- });
64
+ // if (roomName.toLowerCase().startsWith('d')) {
65
+ // showAlert?.({
66
+ // message: 'You cannot add co-host in demo mode.',
67
+ // type: 'danger',
68
+ // duration: 3000,
69
+ // });
70
70
 
71
- return;
72
- }
71
+ // return;
72
+ // }
73
73
 
74
74
  let newCoHost = coHost;
75
75