mediasfu-shared 1.2.6 → 1.3.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/CHANGELOG.md +17 -0
- package/HEADLESS_GUIDE.md +12 -0
- package/README.md +14 -2
- package/dist/ProducerClient/producerClientEmits/roomVideoPolicy.d.ts +20 -0
- package/dist/ProducerClient/producerClientEmits/roomVideoPolicy.d.ts.map +1 -0
- package/dist/ProducerClient/producerClientEmits/updateRoomParametersClient.d.ts +11 -1
- package/dist/ProducerClient/producerClientEmits/updateRoomParametersClient.d.ts.map +1 -1
- package/dist/audioProcessing-Ca5wm1nV.js +150 -0
- package/dist/audioProcessing-Ca5wm1nV.js.map +1 -0
- package/dist/audioProcessing-VCbu70Jt.cjs +149 -0
- package/dist/audioProcessing-VCbu70Jt.cjs.map +1 -0
- package/dist/consumers/closeAndResize.d.ts +3 -0
- package/dist/consumers/closeAndResize.d.ts.map +1 -1
- package/dist/consumers/connectIps.d.ts +6 -0
- package/dist/consumers/connectIps.d.ts.map +1 -1
- package/dist/consumers/connectSendTransportScreenAudio.d.ts +65 -0
- package/dist/consumers/connectSendTransportScreenAudio.d.ts.map +1 -0
- package/dist/consumers/consumerBackupPreference.d.ts +14 -0
- package/dist/consumers/consumerBackupPreference.d.ts.map +1 -0
- package/dist/consumers/disconnectSendTransportScreen.d.ts.map +1 -1
- package/dist/consumers/getPipedProducersAlt.d.ts.map +1 -1
- package/dist/consumers/index.cjs +23 -1
- package/dist/consumers/index.cjs.map +1 -1
- package/dist/consumers/index.d.ts +3 -0
- package/dist/consumers/index.d.ts.map +1 -1
- package/dist/consumers/index.js +61 -39
- package/dist/consumers/index.js.map +1 -1
- package/dist/consumers/screenAudio.d.ts +64 -0
- package/dist/consumers/screenAudio.d.ts.map +1 -0
- package/dist/consumers/socketReceiveMethods/producerClosed.d.ts.map +1 -1
- package/dist/consumers/startShareScreen.d.ts +14 -0
- package/dist/consumers/startShareScreen.d.ts.map +1 -1
- package/dist/consumers/streamSuccessScreen.d.ts.map +1 -1
- package/dist/{getParticipantMedia-B6LsMxmS.cjs → getParticipantMedia-1okyF4H7.cjs} +4 -4
- package/dist/{getParticipantMedia-B6LsMxmS.cjs.map → getParticipantMedia-1okyF4H7.cjs.map} +1 -1
- package/dist/{getParticipantMedia-B8MFkrT1.js → getParticipantMedia-DEJwXXhU.js} +4 -4
- package/dist/{getParticipantMedia-B8MFkrT1.js.map → getParticipantMedia-DEJwXXhU.js.map} +1 -1
- package/dist/index.cjs +36 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1523 -1493
- package/dist/index.native.cjs +36 -6
- package/dist/index.native.cjs.map +1 -1
- package/dist/index.native.d.ts +4 -0
- package/dist/index.native.d.ts.map +1 -1
- package/dist/index.native.js +105 -75
- package/dist/{joinLocalRoom-X3NXzGmE.js → joinLocalRoom-DS6_6lJL.js} +26 -23
- package/dist/joinLocalRoom-DS6_6lJL.js.map +1 -0
- package/dist/{joinLocalRoom-XjGmL1_k.cjs → joinLocalRoom-Dsn39SwS.cjs} +26 -23
- package/dist/joinLocalRoom-Dsn39SwS.cjs.map +1 -0
- package/dist/{joinRoomOnMediaSFU-BnAWLciF.js → joinRoomOnMediaSFU-B6tTA0Mx.js} +17 -13
- package/dist/joinRoomOnMediaSFU-B6tTA0Mx.js.map +1 -0
- package/dist/{joinRoomOnMediaSFU-D2C7q1GK.cjs → joinRoomOnMediaSFU-CxwD9fBz.cjs} +17 -13
- package/dist/joinRoomOnMediaSFU-CxwD9fBz.cjs.map +1 -0
- package/dist/methods/index.cjs +12 -8
- package/dist/methods/index.cjs.map +1 -1
- package/dist/methods/index.js +14 -9
- package/dist/methods/index.js.map +1 -1
- package/dist/methods/socketReceive/getDomains.d.ts.map +1 -1
- package/dist/methods/utils/checkLimitsAndMakeRequest.d.ts.map +1 -1
- package/dist/methods/utils/createResponseJoinRoom.d.ts.map +1 -1
- package/dist/methods/welcome/handleWelcomeRequest.d.ts.map +1 -1
- package/dist/sockets/SocketManager.d.ts.map +1 -1
- package/dist/sockets/mediaSocketErrors.d.ts +62 -0
- package/dist/sockets/mediaSocketErrors.d.ts.map +1 -0
- package/dist/types/index.cjs +4 -3
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.js +39 -38
- package/dist/types/shared-base-types.d.ts +8 -0
- package/dist/types/shared-base-types.d.ts.map +1 -1
- package/dist/{updateParticipantAudioDecibels-DiJ_LFfH.js → updateParticipantAudioDecibels-BBfdHWQ0.js} +344 -61
- package/dist/updateParticipantAudioDecibels-BBfdHWQ0.js.map +1 -0
- package/dist/{updateParticipantAudioDecibels-BJ2PxJJD.cjs → updateParticipantAudioDecibels-Dni8i6AY.cjs} +306 -23
- package/dist/updateParticipantAudioDecibels-Dni8i6AY.cjs.map +1 -0
- package/package.json +3 -2
- package/src/ProducerClient/producerClientEmits/roomVideoPolicy.ts +41 -0
- package/src/ProducerClient/producerClientEmits/updateRoomParametersClient.ts +19 -21
- package/src/consumers/closeAndResize.ts +14 -0
- package/src/consumers/connectIps.ts +81 -8
- package/src/consumers/connectSendTransportScreenAudio.ts +184 -0
- package/src/consumers/consumerBackupPreference.ts +43 -0
- package/src/consumers/disconnectSendTransportScreen.ts +8 -0
- package/src/consumers/getPipedProducersAlt.ts +4 -0
- package/src/consumers/index.ts +3 -0
- package/src/consumers/screenAudio.ts +132 -0
- package/src/consumers/socketReceiveMethods/producerClosed.ts +3 -0
- package/src/consumers/startShareScreen.ts +44 -8
- package/src/consumers/streamSuccessScreen.ts +11 -0
- package/src/index.native.ts +4 -0
- package/src/index.ts +4 -0
- package/src/methods/socketReceive/getDomains.ts +4 -0
- package/src/methods/utils/checkLimitsAndMakeRequest.ts +24 -11
- package/src/methods/utils/createResponseJoinRoom.ts +2 -1
- package/src/methods/welcome/handleWelcomeRequest.ts +15 -6
- package/src/sockets/SocketManager.ts +76 -12
- package/src/sockets/mediaSocketErrors.ts +156 -0
- package/src/types/shared-base-types.ts +8 -0
- package/dist/audioProcessing-0z5KlcmO.js +0 -35
- package/dist/audioProcessing-0z5KlcmO.js.map +0 -1
- package/dist/audioProcessing-BpbrdCk-.cjs +0 -34
- package/dist/audioProcessing-BpbrdCk-.cjs.map +0 -1
- package/dist/joinLocalRoom-X3NXzGmE.js.map +0 -1
- package/dist/joinLocalRoom-XjGmL1_k.cjs.map +0 -1
- package/dist/joinRoomOnMediaSFU-BnAWLciF.js.map +0 -1
- package/dist/joinRoomOnMediaSFU-D2C7q1GK.cjs.map +0 -1
- package/dist/updateParticipantAudioDecibels-BJ2PxJJD.cjs.map +0 -1
- package/dist/updateParticipantAudioDecibels-DiJ_LFfH.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updateParticipantAudioDecibels-Dni8i6AY.cjs","sources":["../src/consumers/frameworkConsumerContract.ts","../src/consumers/consumerResume.ts","../src/consumers/changeVids.ts","../src/consumers/checkScreenShare.ts","../src/consumers/closeAndResize.ts","../src/consumers/compareActiveNames.ts","../src/consumers/compareScreenStates.ts","../src/sockets/SocketManager.ts","../src/consumers/transportRecovery.ts","../src/consumers/signalNewConsumerTransport.ts","../src/consumers/socketReceiveMethods/newPipeProducer.ts","../src/consumers/screenAudio.ts","../src/consumers/socketReceiveMethods/producerClosed.ts","../src/producers/producerEmits/joinConRoom.ts","../src/consumers/socketReceiveMethods/joinConsumeRoom.ts","../src/consumers/connectIps.ts","../src/consumers/connectLocalIps.ts","../src/consumers/connectRecvTransport.ts","../src/consumers/connectSendTransport.ts","../src/consumers/connectSendTransportAudio.ts","../src/consumers/connectSendTransportScreen.ts","../src/consumers/connectSendTransportVideo.ts","../src/consumers/createSendTransport.ts","../src/consumers/disconnectSendTransportAudio.ts","../src/consumers/connectSendTransportScreenAudio.ts","../src/consumers/disconnectSendTransportScreen.ts","../src/consumers/disconnectSendTransportVideo.ts","../src/consumers/dispStreams.ts","../src/consumers/generatePageContent.ts","../src/consumers/getVideos.ts","../src/consumers/mixStreams.ts","../src/consumers/onScreenChanges.ts","../src/consumers/processConsumerTransports.ts","../src/consumers/processConsumerTransportsAudio.ts","../src/consumers/readjust.ts","../src/consumers/receiveAllPipedTransports.ts","../src/consumers/reorderStreams.ts","../src/consumers/rePort.ts","../src/consumers/requestScreenShare.ts","../src/consumers/resumePauseAudioStreams.ts","../src/consumers/resumePauseStreams.ts","../src/consumers/reUpdateInter.ts","../src/consumers/startShareScreen.ts","../src/consumers/stopShareScreen.ts","../src/consumers/streamSuccessAudio.ts","../src/consumers/streamSuccessAudioSwitch.ts","../src/consumers/streamSuccessScreen.ts","../src/consumers/streamSuccessVideo.ts","../src/consumers/switchUserAudio.ts","../src/methods/stream/clickVideo.ts","../src/consumers/switchUserVideo.ts","../src/consumers/switchUserVideoAlt.ts","../src/consumers/trigger.ts","../src/consumers/autoAdjust.ts","../src/consumers/calculateRowsAndColumns.ts","../src/consumers/checkGrid.ts","../src/consumers/checkPermission.ts","../src/consumers/controlMedia.ts","../src/consumers/getEstimate.ts","../src/consumers/getPipedProducersAlt.ts","../src/consumers/getProducersPiped.ts","../src/consumers/receiveRoomMessages.ts","../src/consumers/resumeSendTransportAudio.ts","../src/consumers/updateMiniCardsGrid.ts","../src/consumers/updateParticipantAudioDecibels.ts"],"sourcesContent":["export const createFrameworkConsumerContractError = (consumerName: string): Error => {\n return new Error(\n `${consumerName} is a render-coupled consumer helper and has no shared runtime implementation. ` +\n `Inject the framework-specific ${consumerName} implementation instead of calling the shared fallback export.`\n );\n};","// Stub export for consumerResume\n// This is a React component in the original and not needed for the shared package\n\nimport { Socket } from 'socket.io-client';\nimport { createFrameworkConsumerContractError } from './frameworkConsumerContract';\n\nexport interface ConsumerResumeParameters {\n [key: string]: any;\n}\n\nexport interface ConsumerResumeOptions {\n track: MediaStreamTrack;\n kind: string;\n remoteProducerId: string;\n params: any;\n parameters: ConsumerResumeParameters;\n nsock: Socket;\n consumer?: any; // mediasoup Consumer\n}\n\nexport type ConsumerResumeType = (options: ConsumerResumeOptions) => Promise<void>;\n\nexport const consumerResume: ConsumerResumeType = async () => {\n throw createFrameworkConsumerContractError('consumerResume');\n};\n","\n \nimport { Stream, Participant, AudioDecibels, EventType } from \"../types/types\";\n\ninterface ChangeVidsStreamLike {\n producerId?: string | null;\n audioID?: string | null;\n name?: string;\n muted?: boolean | null;\n stream?: unknown;\n}\n\ninterface ChangeVidsParticipantLike {\n name: string;\n islevel?: string | null;\n videoID?: string | null;\n audioID?: string | null;\n muted?: boolean | null;\n breakRoom?: number | null;\n stream?: unknown;\n}\n\ninterface BreakoutParticipantLike {\n name: string;\n breakRoom?: number | null;\n}\n\ninterface AudioDecibelLike {\n name: string;\n averageLoudness?: number | null;\n}\n\ntype BooleanUpdater = (value: boolean) => void;\ntype NumberUpdater = (value: number) => void;\ntype StringListUpdater = (names: string[]) => void;\n\ntype EntryArrayUpdater<TEntry> = {\n bivarianceHack: (entries: TEntry[]) => void;\n}[\"bivarianceHack\"];\n\ntype EntryMatrixUpdater<TEntry> = {\n bivarianceHack: (entries: TEntry[][]) => void;\n}[\"bivarianceHack\"];\n\ntype MixStreamsInvoker<TEntry, TParticipant> = (options: {\n alVideoStreams: TEntry[];\n non_alVideoStreams: TParticipant[];\n ref_participants: TEntry[];\n}) => Promise<TEntry[]>;\n\ntype DispStreamsInvoker = (options: {\n lStreams: any[];\n ind: number;\n auto?: boolean;\n parameters: any;\n breakRoom?: number;\n inBreakRoom?: boolean;\n ChatSkip?: boolean;\n forChatCard?: any;\n forChatID?: any;\n}) => Promise<void>;\n\nexport interface ChangeVidsParameters<\n TStream extends ChangeVidsStreamLike = Stream,\n TParticipant extends ChangeVidsParticipantLike = Participant,\n TBreakoutParticipant extends BreakoutParticipantLike = BreakoutParticipantLike,\n TAudioDecibel extends AudioDecibelLike = AudioDecibels,\n TMediaHandle = unknown,\n> {\n\n allVideoStreams: (TStream | TParticipant)[];\n p_activeNames: string[];\n activeNames: string[];\n dispActiveNames: string[];\n shareScreenStarted: boolean;\n shared: boolean;\n newLimitedStreams: (TStream | TParticipant)[];\n non_alVideoStreams: TParticipant[];\n ref_participants: TParticipant[];\n participants: TParticipant[];\n eventType: EventType;\n islevel: string;\n member: string;\n sortAudioLoudness: boolean;\n audioDecibels: TAudioDecibel[];\n mixed_alVideoStreams: (TStream | TParticipant)[];\n non_alVideoStreams_muted: TParticipant[];\n remoteProducerId?: string;\n localStreamVideo: TMediaHandle | null;\n oldAllStreams: (TStream | TParticipant)[];\n screenPageLimit: number;\n meetingDisplayType: string;\n meetingVideoOptimized: boolean;\n recordingVideoOptimized: boolean;\n recordingDisplayType: \"video\" | \"media\" | \"all\";\n paginatedStreams: (TStream | TParticipant)[][];\n itemPageLimit: number;\n doPaginate: boolean;\n prevDoPaginate: boolean;\n currentUserPage: number;\n breakoutRooms: TBreakoutParticipant[][];\n hostNewRoom: number;\n breakOutRoomStarted: boolean;\n breakOutRoomEnded: boolean;\n virtualStream: TMediaHandle | null;\n mainRoomsLength: number;\n memberRoom: number;\n updateP_activeNames: StringListUpdater;\n updateActiveNames: StringListUpdater;\n updateDispActiveNames: StringListUpdater;\n updateNewLimitedStreams: EntryArrayUpdater<TStream | TParticipant>;\n updateNon_alVideoStreams: EntryArrayUpdater<TParticipant>;\n updateRef_participants: EntryArrayUpdater<TParticipant>;\n updateSortAudioLoudness: BooleanUpdater;\n updateMixed_alVideoStreams: EntryArrayUpdater<TStream | TParticipant>;\n updateNon_alVideoStreams_muted: EntryArrayUpdater<TParticipant>;\n updatePaginatedStreams: EntryMatrixUpdater<TStream | TParticipant>;\n updateDoPaginate: BooleanUpdater;\n updatePrevDoPaginate: BooleanUpdater;\n updateCurrentUserPage: NumberUpdater;\n updateNumberPages: NumberUpdater;\n updateMainRoomsLength: NumberUpdater;\n updateMemberRoom: NumberUpdater;\n\n // mediasfu functions\n mixStreams: MixStreamsInvoker<TStream | TParticipant, TParticipant>;\n dispStreams: DispStreamsInvoker;\n getUpdatedAllParams: () => ChangeVidsParameters<TStream, TParticipant, TBreakoutParticipant, TAudioDecibel, TMediaHandle>;\n [key: string]: any;\n\n}\n\nexport interface ChangeVidsOptions<\n TParameters extends ChangeVidsParameters<any, any, any, any, any> = ChangeVidsParameters,\n> {\n screenChanged?: boolean;\n parameters: TParameters;\n}\n\n// Export the type definition for the function\nexport type ChangeVidsType = <\n TParameters extends ChangeVidsParameters<any, any, any, any, any> = ChangeVidsParameters,\n>(options: ChangeVidsOptions<TParameters>) => Promise<void>;\n\n/**\n * Asynchronously changes the video streams based on the provided options.\n *\n * @function\n * @param {ChangeVidsOptions} options - The options for changing video streams.\n * @param {boolean} [options.screenChanged=false] - Indicates if the screen has changed.\n * @param {ChangeVidsParameters} options.parameters - The parameters for changing video streams.\n * @returns {Promise<void>} A promise that resolves when the video streams have been changed.\n *\n * @typedef {Object} ChangeVidsOptions\n * @property {Function} getUpdatedAllParams - Function to get updated parameters.\n * @property {Array} allVideoStreams - Array of all video streams.\n * @property {Array} p_activeNames - Array of active participant names.\n * @property {Array} activeNames - Array of active names.\n * @property {Array} dispActiveNames - Array of displayed active names.\n * @property {boolean} shareScreenStarted - Indicates if screen sharing has started.\n * @property {boolean} shared - Indicates if the screen is shared.\n * @property {Array} newLimitedStreams - Array of new limited streams.\n * @property {Array} non_alVideoStreams - Array of non-al video streams.\n * @property {Array} ref_participants - Array of reference participants.\n * @property {Array} participants - Array of participants.\n * @property {string} eventType - Type of the event.\n * @property {string} islevel - Level of the participant.\n * @property {string} member - Name of the member.\n * @property {boolean} sortAudioLoudness - Indicates if audio loudness should be sorted.\n * @property {Array} audioDecibels - Array of audio decibels.\n * @property {Array} mixed_alVideoStreams - Array of mixed al video streams.\n * @property {Array} non_alVideoStreams_muted - Array of muted non-al video streams.\n * @property {string} remoteProducerId - ID of the remote producer.\n * @property {Object} localStreamVideo - Local stream video object.\n * @property {Array} oldAllStreams - Array of old all streams.\n * @property {number} screenPageLimit - Limit of streams per screen page.\n * @property {string} meetingDisplayType - Type of meeting display.\n * @property {boolean} meetingVideoOptimized - Indicates if meeting video is optimized.\n * @property {boolean} recordingVideoOptimized - Indicates if recording video is optimized.\n * @property {string} recordingDisplayType - Type of recording display.\n * @property {Array} paginatedStreams - Array of paginated streams.\n * @property {number} itemPageLimit - Limit of items per page.\n * @property {boolean} doPaginate - Indicates if pagination should be done.\n * @property {boolean} prevDoPaginate - Indicates if pagination was previously done.\n * @property {number} currentUserPage - Current user page number.\n * @property {Array} breakoutRooms - Array of breakout rooms.\n * @property {number} hostNewRoom - Index of the new room for the host.\n * @property {boolean} breakOutRoomStarted - Indicates if breakout room has started.\n * @property {boolean} breakOutRoomEnded - Indicates if breakout room has ended.\n * @property {Object} virtualStream - Virtual stream object.\n * @property {number} mainRoomsLength - Length of main rooms.\n * @property {number} memberRoom - Room of the member.\n * @property {Function} updateP_activeNames - Function to update active participant names.\n * @property {Function} updateActiveNames - Function to update active names.\n * @property {Function} updateDispActiveNames - Function to update displayed active names.\n * @property {Function} updateNewLimitedStreams - Function to update new limited streams.\n * @property {Function} updateNon_alVideoStreams - Function to update non-al video streams.\n * @property {Function} updateRef_participants - Function to update reference participants.\n * @property {Function} updateSortAudioLoudness - Function to update audio loudness sorting.\n * @property {Function} updateMixed_alVideoStreams - Function to update mixed al video streams.\n * @property {Function} updateNon_alVideoStreams_muted - Function to update muted non-al video streams.\n * @property {Function} updatePaginatedStreams - Function to update paginated streams.\n * @property {Function} updateDoPaginate - Function to update pagination status.\n * @property {Function} updatePrevDoPaginate - Function to update previous pagination status.\n * @property {Function} updateCurrentUserPage - Function to update current user page.\n * @property {Function} updateNumberPages - Function to update number of pages.\n * @property {Function} updateMainRoomsLength - Function to update main rooms length.\n * @property {Function} updateMemberRoom - Function to update member room.\n * @property {Function} mixStreams - Function to mix streams.\n * @property {Function} dispStreams - Function to display streams.\n * \n * @example\n * const options = {\n * screenChanged: false,\n * parameters: {\n * getUpdatedAllParams: () => updatedParameters,\n * allVideoStreams: allStreams,\n * p_activeNames: activeNames,\n * activeNames: activeNames,\n * dispActiveNames: displayedActiveNames,\n * shareScreenStarted: false,\n * shared: false,\n * newLimitedStreams: limitedStreams,\n * non_alVideoStreams: nonAlStreams,\n * ref_participants: referenceParticipants,\n * participants: participants,\n * eventType: \"conference\",\n * islevel: \"2\",\n * member: \"John Doe\",\n * sortAudioLoudness: true,\n * audioDecibels: audioLevels,\n * mixed_alVideoStreams: mixedStreams,\n * non_alVideoStreams_muted: mutedNonAlStreams,\n * remoteProducerId: \"12345\",\n * localStreamVideo: localStream,\n * oldAllStreams: oldStreams,\n * screenPageLimit: 10,\n * meetingDisplayType: \"video\",\n * meetingVideoOptimized: true,\n * recordingVideoOptimized: false,\n * recordingDisplayType: \"video\",\n * paginatedStreams: paginatedStreams,\n * itemPageLimit: 10,\n * doPaginate: true,\n * prevDoPaginate: false,\n * currentUserPage: 1,\n * breakoutRooms: breakoutRooms,\n * hostNewRoom: 0,\n * breakOutRoomStarted: false,\n * breakOutRoomEnded: false,\n * virtualStream: virtualStream,\n * mainRoomsLength: 2,\n * memberRoom: 0,\n * updateP_activeNames: (names) => updateActiveNames(names),\n * updateActiveNames: (names) => updateActiveNames(names),\n * updateDispActiveNames: (names) => updateDispActiveNames(names),\n * updateNewLimitedStreams: (streams) => updateNewLimitedStreams(streams),\n * updateNon_alVideoStreams: (participants) => updateNon_alVideoStreams(participants),\n * updateRef_participants: (participants) => updateRef_participants(participants),\n * updateSortAudioLoudness: (sort) => updateSortAudioLoudness(sort),\n * updateMixed_alVideoStreams: (streams) => updateMixed_alVideoStreams(streams),\n * updateNon_alVideoStreams_muted: (participants) => updateNon_alVideoStreams_muted(participants),\n * updatePaginatedStreams: (streams) => updatePaginatedStreams(streams),\n * updateDoPaginate: (paginate) => updateDoPaginate(paginate),\n * updatePrevDoPaginate: (paginate) => updatePrevDoPaginate(paginate),\n * updateCurrentUserPage: (page) => updateCurrentUserPage(page),\n * updateNumberPages: (pages) => updateNumberPages(pages),\n * updateMainRoomsLength: (length) => updateMainRoomsLength(length),\n * updateMemberRoom: (room) => updateMemberRoom(room),\n * mixStreams: mixStreams,\n * dispStreams: dispStreams,\n * },\n * };\n * \n * changeVids(options)\n * .then(() => {\n * console.log('Video streams changed successfully');\n * });\n */\n\nexport const changeVids = async <\n TParameters extends ChangeVidsParameters<any, any, any, any, any> = ChangeVidsParameters,\n>({ screenChanged = false, parameters }: ChangeVidsOptions<TParameters>): Promise<void> => {\n const { getUpdatedAllParams } = parameters;\n const updatedParameters = getUpdatedAllParams() as TParameters;\n\n let {\n allVideoStreams,\n p_activeNames,\n activeNames,\n dispActiveNames,\n shareScreenStarted,\n shared,\n newLimitedStreams,\n non_alVideoStreams,\n ref_participants,\n participants,\n eventType,\n islevel,\n member,\n sortAudioLoudness,\n audioDecibels,\n mixed_alVideoStreams,\n non_alVideoStreams_muted,\n remoteProducerId,\n localStreamVideo,\n oldAllStreams,\n screenPageLimit,\n meetingDisplayType,\n meetingVideoOptimized,\n recordingVideoOptimized,\n recordingDisplayType,\n paginatedStreams,\n itemPageLimit,\n doPaginate,\n prevDoPaginate,\n currentUserPage,\n breakoutRooms,\n hostNewRoom,\n breakOutRoomStarted,\n breakOutRoomEnded,\n virtualStream,\n mainRoomsLength,\n memberRoom,\n updateP_activeNames,\n updateActiveNames,\n updateDispActiveNames,\n updateNewLimitedStreams,\n updateNon_alVideoStreams,\n updateRef_participants,\n updateSortAudioLoudness,\n updateMixed_alVideoStreams,\n updateNon_alVideoStreams_muted,\n updatePaginatedStreams,\n updateDoPaginate,\n updatePrevDoPaginate,\n updateCurrentUserPage,\n updateNumberPages,\n updateMainRoomsLength,\n updateMemberRoom,\n mixStreams,\n dispStreams,\n } = updatedParameters;\n\n try {\n let alVideoStreams = [...allVideoStreams];\n p_activeNames = [...activeNames];\n\n let streame;\n\n if (shareScreenStarted || shared) {\n alVideoStreams = [...newLimitedStreams];\n activeNames = [];\n }\n\n activeNames = [];\n dispActiveNames = [];\n ref_participants = participants;\n\n let temp = alVideoStreams;\n\n await Promise.all(\n temp.map(async (stream) => {\n let participant = ref_participants.find(\n (obj) => obj.videoID === stream.producerId\n );\n if (!participant && stream.producerId !== \"youyou\" && stream.producerId !== \"youyouyou\") {\n alVideoStreams = alVideoStreams.filter(\n (obj) => obj.producerId !== stream.producerId\n );\n }\n })\n );\n\n if (eventType === \"broadcast\" || eventType === \"chat\") {\n sortAudioLoudness = false;\n }\n\n if (shareScreenStarted || shared) {\n non_alVideoStreams = [];\n non_alVideoStreams_muted = [];\n mixed_alVideoStreams = [];\n } else {\n if (alVideoStreams.length > screenPageLimit) {\n alVideoStreams = alVideoStreams.filter(\n (obj) => obj.producerId !== \"youyou\" && obj.producerId !== \"youyouyou\"\n );\n\n ref_participants = ref_participants.sort((a, b) => (a.muted ?? false) > (b.muted ?? false) ? 1 : -1\n );\n\n let temp: (Stream | Participant)[] = [];\n await Promise.all(\n ref_participants.map((participant) => {\n let stream = alVideoStreams.find(\n (obj) => obj.producerId === participant.videoID\n );\n if (stream) {\n temp.push(stream);\n }\n })\n );\n\n alVideoStreams = temp;\n\n let youyou = allVideoStreams.find(\n (obj) => obj.producerId === \"youyou\"\n );\n if (!youyou) {\n let youyouyou = allVideoStreams.find(\n (obj) => obj.producerId === \"youyouyou\"\n );\n alVideoStreams.unshift(youyouyou!);\n } else {\n alVideoStreams.unshift(youyou!);\n }\n }\n\n const admin = participants.filter(\n (participant) => participant.islevel === \"2\"\n );\n let adminName = \"\";\n if (admin.length > 0) {\n adminName = admin[0].name || \"\";\n }\n\n non_alVideoStreams = [];\n\n await Promise.all(\n ref_participants.map(async (participant) => {\n let stream = alVideoStreams.find(\n (obj) => obj.producerId === participant.videoID\n );\n if (eventType !== \"chat\" && eventType !== \"conference\") {\n if (!stream && participant.name !== member && !participant.muted && participant.name !== adminName) {\n non_alVideoStreams.push(participant);\n }\n } else {\n if (!stream && participant.name !== member && !participant.muted) {\n non_alVideoStreams.push(participant);\n }\n }\n })\n );\n\n if (sortAudioLoudness) {\n non_alVideoStreams.sort((a, b) => {\n const avgLoudnessA =\n audioDecibels.find((obj) => obj.name === a.name)?.averageLoudness || 127;\n const avgLoudnessB =\n audioDecibels.find((obj) => obj.name === b.name)?.averageLoudness || 127;\n return avgLoudnessB - avgLoudnessA;\n });\n\n if (\n !(meetingDisplayType === \"video\" && meetingVideoOptimized) ||\n !(recordingVideoOptimized && recordingDisplayType === \"video\")\n ) {\n mixed_alVideoStreams = await mixStreams({\n alVideoStreams,\n non_alVideoStreams,\n ref_participants\n });\n }\n }\n\n non_alVideoStreams_muted = [];\n await Promise.all(\n ref_participants.map(async (participant) => {\n let stream = alVideoStreams.find(\n (obj) => obj.producerId === participant.videoID\n );\n if (eventType !== \"chat\" && eventType !== \"conference\") {\n if (!stream && participant.name !== member && participant.muted && participant.name !== adminName) {\n non_alVideoStreams_muted.push(participant);\n }\n } else {\n if (!stream && participant.name !== member && participant.muted) {\n non_alVideoStreams_muted.push(participant);\n }\n }\n })\n );\n }\n\n if (eventType === \"conference\" && islevel !== \"2\") {\n let host = participants.find((obj) => obj.islevel === \"2\");\n if (host) {\n remoteProducerId = host.videoID!;\n if (islevel === \"2\") {\n host.stream = virtualStream || localStreamVideo;\n } else {\n let hostVideo = alVideoStreams.find(\n (obj) => obj.producerId === remoteProducerId\n );\n if (!hostVideo) {\n streame = oldAllStreams.find(\n (streame) => streame.producerId === remoteProducerId\n );\n if (streame) {\n alVideoStreams = alVideoStreams.filter(\n (obj) => obj.producerId !== host.videoID\n );\n non_alVideoStreams = non_alVideoStreams.filter(\n (obj) => obj.name !== host.name\n );\n non_alVideoStreams_muted = non_alVideoStreams_muted.filter(\n (obj) => obj.name !== host.name\n );\n if (sortAudioLoudness) {\n mixed_alVideoStreams = mixed_alVideoStreams.filter(\n (obj) => obj.name !== host.name\n );\n non_alVideoStreams_muted = non_alVideoStreams_muted.filter(\n (obj) => obj.name !== host.name\n );\n if (meetingDisplayType == \"video\" && meetingVideoOptimized) {\n alVideoStreams.unshift(streame);\n } else {\n mixed_alVideoStreams.unshift(streame);\n }\n } else {\n alVideoStreams.unshift(streame);\n }\n } else {\n await Promise.all(\n ref_participants.map(async (participant) => {\n let stream = alVideoStreams.find(\n (obj) =>\n obj.producerId == participant.videoID &&\n participant.name == host.name\n );\n if (stream) {\n if (sortAudioLoudness) {\n mixed_alVideoStreams = mixed_alVideoStreams.filter(\n (obj) => obj.name !== host.name\n );\n non_alVideoStreams_muted =\n non_alVideoStreams_muted.filter(\n (obj) => obj.name !== host.name\n );\n mixed_alVideoStreams.unshift(participant);\n } else {\n non_alVideoStreams = non_alVideoStreams.filter(\n (obj) => obj.name !== host.name\n );\n non_alVideoStreams.unshift(participant);\n return;\n }\n }\n })\n );\n }\n }\n }\n }\n }\n\n let allStreamsPaged: (Stream | Participant)[] = [];\n if (sortAudioLoudness) {\n if (meetingDisplayType === \"video\") {\n if (meetingVideoOptimized) {\n allStreamsPaged = [...alVideoStreams];\n } else {\n allStreamsPaged = [...mixed_alVideoStreams];\n }\n } else if (meetingDisplayType === \"media\") {\n allStreamsPaged = [...mixed_alVideoStreams];\n } else if (meetingDisplayType === \"all\") {\n allStreamsPaged = [...mixed_alVideoStreams, ...non_alVideoStreams_muted];\n }\n } else {\n if (meetingDisplayType === \"video\") {\n allStreamsPaged = [...alVideoStreams];\n } else if (meetingDisplayType === \"media\") {\n allStreamsPaged = [...alVideoStreams, ...non_alVideoStreams];\n } else if (meetingDisplayType === \"all\") {\n allStreamsPaged = [\n ...alVideoStreams,\n ...non_alVideoStreams,\n ...non_alVideoStreams_muted,\n ];\n }\n }\n\n paginatedStreams = [];\n let limit = itemPageLimit;\n\n if (shareScreenStarted || shared) {\n limit = screenPageLimit;\n }\n\n let firstPage: (Stream | Participant)[] = [];\n let page: (Stream | Participant)[] = [];\n let limit_ = limit + 1;\n\n if (eventType === \"conference\" && !shared && !shareScreenStarted) {\n limit_ = limit_ - 1;\n }\n\n // Create pagination\n let memberInRoom = false;\n let filterHost = false;\n if (breakOutRoomStarted && !breakOutRoomEnded) {\n let tempBreakoutRooms = JSON.parse(JSON.stringify(breakoutRooms));\n let host = participants.find((obj) => obj.islevel == \"2\");\n for (let room of tempBreakoutRooms) {\n try {\n let currentStreams: (Stream | Participant)[] = [];\n const roomIndex = tempBreakoutRooms.indexOf(room);\n if (hostNewRoom != -1 && roomIndex == hostNewRoom) {\n if (host) {\n if (!room.map((obj: any) => obj.name).includes(host.name)) {\n room = [...room, { name: host.name, breakRoom: roomIndex }];\n filterHost = true;\n }\n }\n }\n for (let participant of room) {\n if (participant.name == member && !memberInRoom) {\n memberInRoom = true;\n memberRoom = participant.breakRoom;\n updateMemberRoom(memberRoom);\n }\n let streams = allStreamsPaged.filter((stream) => {\n if ((Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") ||\n (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream['audioID'] != null &&\n stream['audioID'] !== \"\")) {\n let producerId = stream.producerId || stream['audioID'];\n let matchingParticipant = ref_participants.find(\n (obj) => obj['audioID'] === producerId ||\n obj.videoID === producerId ||\n ((producerId == \"youyou\" || producerId == \"youyouyou\") &&\n member == participant.name)\n );\n return (\n (matchingParticipant &&\n matchingParticipant.name === participant.name) ||\n (participant.name == member &&\n (producerId == \"youyou\" || producerId == \"youyouyou\"))\n );\n } else {\n return (\n Object.prototype.hasOwnProperty.call(stream, \"name\") &&\n stream.name == participant.name\n );\n }\n });\n for (let stream of streams) {\n if (currentStreams.length < limit_) {\n currentStreams.push(stream);\n }\n }\n }\n paginatedStreams.push(currentStreams);\n } catch {\n // handle error\n }\n }\n\n let remainingStreams = allStreamsPaged.filter((stream) => {\n if ((Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") ||\n (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream['audioID'] != null &&\n stream['audioID'] !== \"\")) {\n let producerId = stream.producerId || stream['audioID'];\n let matchingParticipant = ref_participants.find(\n (obj) => obj['audioID'] === producerId ||\n obj.videoID === producerId ||\n ((producerId == \"youyou\" || producerId == \"youyouyou\") &&\n member == obj.name)\n );\n return (\n matchingParticipant &&\n !breakoutRooms!\n .flat()\n .map((obj) => obj.name)\n .includes(matchingParticipant.name) &&\n (!filterHost || matchingParticipant.name != host!.name)\n );\n } else {\n return (\n !breakoutRooms!\n .flat()\n .map((obj) => obj.name)\n .includes(stream.name ?? '') &&\n (!filterHost || stream.name != host!.name)\n );\n }\n });\n\n if (memberInRoom) {\n let memberStream = allStreamsPaged.find((stream) => {\n if (Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") {\n return (\n stream.producerId == \"youyou\" || stream.producerId == \"youyouyou\"\n );\n }\n return false; // Add a return statement here\n });\n if (memberStream && !remainingStreams.includes(memberStream)) {\n remainingStreams.unshift(memberStream);\n }\n }\n let remainingPaginatedStreams: (Stream | Participant)[][] = [];\n\n if (remainingStreams.length > 0) {\n firstPage = remainingStreams.slice(0, limit_);\n remainingPaginatedStreams.push(firstPage);\n for (let i = limit_; i < remainingStreams.length; i += limit) {\n page = remainingStreams.slice(i, i + limit);\n remainingPaginatedStreams.push(page);\n }\n }\n\n mainRoomsLength = remainingPaginatedStreams.length;\n updateMainRoomsLength(mainRoomsLength);\n // Add the remaining streams to the beginning of the paginatedStreams\n for (let i = remainingPaginatedStreams.length - 1; i >= 0; i--) {\n paginatedStreams.unshift(remainingPaginatedStreams[i]);\n }\n } else {\n firstPage = allStreamsPaged.slice(0, limit_);\n paginatedStreams.push(firstPage);\n\n for (let i = limit_; i < allStreamsPaged.length; i += limit) {\n page = allStreamsPaged.slice(i, i + limit);\n paginatedStreams.push(page);\n }\n }\n\n // State updates\n updateP_activeNames(p_activeNames);\n updateActiveNames(activeNames);\n updateDispActiveNames(dispActiveNames);\n updateNewLimitedStreams(newLimitedStreams);\n updateNon_alVideoStreams(non_alVideoStreams);\n updateRef_participants(ref_participants);\n updateSortAudioLoudness(sortAudioLoudness);\n updateMixed_alVideoStreams(mixed_alVideoStreams);\n updateNon_alVideoStreams_muted(non_alVideoStreams_muted);\n updatePaginatedStreams(paginatedStreams);\n\n prevDoPaginate = doPaginate;\n doPaginate = false;\n updatePrevDoPaginate(prevDoPaginate);\n updateDoPaginate(doPaginate);\n\n let isActive = false;\n\n if (paginatedStreams.length > 1) {\n if (!shareScreenStarted && !shared) {\n doPaginate = true;\n }\n updateDoPaginate(doPaginate);\n\n if (currentUserPage > paginatedStreams.length - 1) {\n if (breakOutRoomStarted && !breakOutRoomEnded) {\n currentUserPage = 0;\n } else {\n currentUserPage = paginatedStreams.length - 1;\n }\n } else if (currentUserPage == 0) {\n isActive = true;\n }\n updateCurrentUserPage(currentUserPage);\n updateNumberPages(paginatedStreams.length - 1);\n\n if (screenChanged) {\n await dispStreams({\n lStreams: paginatedStreams[0],\n ind: 0,\n parameters,\n });\n } else {\n await dispStreams({\n lStreams: paginatedStreams[0],\n ind: 0,\n auto: true,\n parameters,\n });\n }\n\n if (!isActive) {\n const currentPageBreak = currentUserPage - mainRoomsLength;\n await dispStreams({\n lStreams: paginatedStreams[currentUserPage],\n ind: currentUserPage,\n parameters,\n breakRoom: currentPageBreak,\n inBreakRoom: currentPageBreak >= 0,\n });\n }\n } else {\n currentUserPage = 0;\n updateCurrentUserPage(currentUserPage);\n\n if (screenChanged) {\n await dispStreams({\n lStreams: paginatedStreams[0],\n ind: 0,\n parameters,\n });\n } else {\n await dispStreams({\n lStreams: paginatedStreams[0],\n ind: 0,\n auto: true,\n parameters,\n });\n }\n }\n } catch (error) {\n console.log(\"changeVids error\", error);\n }\n};\n","import { StopShareScreenType, StopShareScreenParameters, RequestScreenShareType, RequestScreenShareParameters, ShowAlert } from \"../types/types\";\nexport interface CheckScreenShareParameters extends StopShareScreenParameters, RequestScreenShareParameters {\n shared: boolean;\n whiteboardStarted: boolean;\n whiteboardEnded: boolean;\n breakOutRoomStarted: boolean;\n breakOutRoomEnded: boolean;\n showAlert?: ShowAlert;\n\n // Mediasfu functions\n stopShareScreen: StopShareScreenType;\n requestScreenShare: RequestScreenShareType;\n \n getUpdatedAllParams : () => CheckScreenShareParameters;\n [key: string]: any;\n}\n\nexport interface CheckScreenShareOptions {\n parameters: CheckScreenShareParameters;\n}\n\n// Export the type definition for the function\nexport type CheckScreenShareType = (options: CheckScreenShareOptions) => Promise<void>;\n\n/**\n * Checks the current screen sharing status and either stops or requests screen sharing based on the provided parameters.\n * \n * @param {CheckScreenShareOptions} options - The options for checking screen share.\n * @param {Object} options.parameters - The parameters for screen sharing.\n * @param {boolean} options.parameters.shared - Indicates if the screen is currently being shared.\n * @param {Function} [options.parameters.showAlert] - Function to show alerts.\n * @param {boolean} options.parameters.whiteboardStarted - Indicates if the whiteboard session has started.\n * @param {boolean} options.parameters.whiteboardEnded - Indicates if the whiteboard session has ended.\n * @param {boolean} options.parameters.breakOutRoomStarted - Indicates if the breakout room session has started.\n * @param {boolean} options.parameters.breakOutRoomEnded - Indicates if the breakout room session has ended.\n * @param {Function} options.parameters.stopShareScreen - Function to stop screen sharing.\n * @param {Function} options.parameters.requestScreenShare - Function to request screen sharing.\n * \n * @returns {Promise<void>} A promise that resolves when the screen sharing status has been checked and the appropriate action has been taken.\n * \n * @throws Will log an error message if an error occurs during the process.\n * \n * @example\n * const options = {\n * parameters: {\n * shared: false,\n * showAlert: showAlertFunction,\n * whiteboardStarted: false,\n * whiteboardEnded: false,\n * breakOutRoomStarted: false,\n * breakOutRoomEnded: false,\n * stopShareScreen: stopShareScreenFunction,\n * requestScreenShare: requestScreenShareFunction,\n * },\n * };\n * \n * checkScreenShare(options)\n * .then(() => {\n * console.log('Screen share checked successfully');\n * })\n * .catch((error) => {\n * console.error('Error checking screen share:', error);\n * });\n */\n\nexport async function checkScreenShare({ parameters }: CheckScreenShareOptions): Promise<void> {\n try {\n const {\n shared,\n showAlert,\n whiteboardStarted,\n whiteboardEnded,\n breakOutRoomStarted,\n breakOutRoomEnded,\n\n //mediasfu functions\n stopShareScreen,\n requestScreenShare,\n } = parameters;\n\n // Stop screen share if already shared or request screen share if not shared\n if (shared) {\n if (whiteboardStarted && !whiteboardEnded) {\n showAlert?.({\n message: \"Screen share is not allowed when whiteboard is active\",\n type: \"danger\",\n });\n return;\n }\n await stopShareScreen({ parameters });\n } else {\n // Can't share if breakout room is active\n if (breakOutRoomStarted && !breakOutRoomEnded) {\n showAlert?.({\n message: \"Screen share is not allowed when breakout room is active\",\n type: \"danger\",\n });\n return;\n }\n\n if (whiteboardStarted && !whiteboardEnded) {\n showAlert?.({\n message: \"Screen share is not allowed when whiteboard is active\",\n type: \"danger\",\n });\n return;\n }\n await requestScreenShare({ parameters });\n }\n } catch (error) {\n console.log(\"checkScreenShare error\", error);\n // throw error;\n }\n}\n","import {\n Stream, Participant, ReorderStreamsType, ReorderStreamsParameters, PrepopulateUserMediaParameters,\n PrepopulateUserMediaType, GetVideosType, RePortType, RePortParameters, EventType\n} from '../types/types';\n\n\n \n\nexport interface CloseAndResizeParameters extends ReorderStreamsParameters, PrepopulateUserMediaParameters, RePortParameters {\n allAudioStreams: (Stream | Participant)[];\n /** Rendered audio-only players (React elements, Vue/Angular component descriptors). */\n audioOnlyStreams?: any[];\n allVideoStreams: (Stream | Participant)[];\n activeNames: string[];\n participants: Participant[];\n streamNames: Stream[];\n recordingDisplayType: \"video\" | \"media\" | \"all\";\n recordingVideoOptimized: boolean;\n adminIDStream?: string;\n newLimitedStreams: (Stream | Participant)[];\n newLimitedStreamsIDs: string[];\n oldAllStreams: (Stream | Participant)[];\n shareScreenStarted: boolean;\n shared: boolean;\n meetingDisplayType: string;\n defer_receive: boolean;\n lock_screen: boolean;\n firstAll: boolean;\n first_round: boolean;\n gotAllVids: boolean;\n eventType: EventType;\n hostLabel: string;\n shareEnded: boolean;\n updateMainWindow: boolean;\n updateActiveNames: (activeNames: string[]) => void;\n updateAllAudioStreams: (allAudioStreams: (Stream | Participant)[]) => void;\n updateAudioOnlyStreams?: (audioOnlyStreams: any[]) => void;\n updateShareScreenStarted: (shareScreenStarted: boolean) => void;\n updateUpdateMainWindow: (updateMainWindow: boolean) => void;\n updateNewLimitedStreams: (newLimitedStreams: (Stream | Participant)[]) => void;\n updateOldAllStreams: (oldAllStreams: (Stream | Participant)[]) => void;\n updateDefer_receive: (defer_receive: boolean) => void;\n updateMainHeightWidth: (heightWidth: number) => void;\n updateShareEnded: (shareEnded: boolean) => void;\n updateLock_screen: (lock_screen: boolean) => void;\n updateFirstAll: (firstAll: boolean) => void;\n updateFirst_round: (first_round: boolean) => void;\n\n // mediasfu functions\n reorderStreams: ReorderStreamsType;\n prepopulateUserMedia: PrepopulateUserMediaType;\n getVideos: GetVideosType;\n rePort: RePortType;\n getUpdatedAllParams: () => CloseAndResizeParameters;\n [key: string]: any;\n}\n\nexport interface CloseAndResizeOptions {\n producerId: string;\n kind: string;\n parameters: CloseAndResizeParameters;\n}\n\n// Export the type definition for the function\nexport type CloseAndResizeType = (options: CloseAndResizeOptions) => Promise<void>;\n\n\n/**\n * Closes and resizes the video and audio elements based on the provided options.\n *\n * @param {CloseAndResizeOptions} options - The options for closing and resizing.\n * @param {string} options.producerId - The ID of the producer.\n * @param {string} options.kind - The kind of media (audio, video, screenshare, or screen).\n * @param {object} options.parameters - The parameters for the operation.\n * @param {function} options.parameters.getUpdatedAllParams - Function to get updated parameters.\n * @param {Array} options.parameters.allAudioStreams - Array of all audio streams.\n * @param {Array} options.parameters.allVideoStreams - Array of all video streams.\n * @param {Array} options.parameters.activeNames - Array of active participant names.\n * @param {Array} options.parameters.participants - Array of participants.\n * @param {Array} options.parameters.streamNames - Array of stream names.\n * @param {string} options.parameters.recordingDisplayType - Type of recording display.\n * @param {boolean} options.parameters.recordingVideoOptimized - Whether recording is video optimized.\n * @param {string} options.parameters.adminIDStream - ID of the admin stream.\n * @param {Array} options.parameters.newLimitedStreams - Array of new limited streams.\n * @param {Array} options.parameters.newLimitedStreamsIDs - Array of new limited stream IDs.\n * @param {Array} options.parameters.oldAllStreams - Array of old all streams.\n * @param {boolean} options.parameters.shareScreenStarted - Whether screen sharing has started.\n * @param {boolean} options.parameters.shared - Whether sharing is active.\n * @param {string} options.parameters.meetingDisplayType - Type of meeting display.\n * @param {boolean} options.parameters.defer_receive - Whether to defer receiving.\n * @param {boolean} options.parameters.lock_screen - Whether the screen is locked.\n * @param {boolean} options.parameters.firstAll - Whether it is the first all.\n * @param {boolean} options.parameters.first_round - Whether it is the first round.\n * @param {boolean} options.parameters.gotAllVids - Whether all videos are received.\n * @param {string} options.parameters.eventType - Type of event.\n * @param {string} options.parameters.hostLabel - Label of the host.\n * @param {boolean} options.parameters.shareEnded - Whether sharing has ended.\n * @param {boolean} options.parameters.updateMainWindow - Whether to update the main window.\n * @param {function} options.parameters.updateActiveNames - Function to update active names.\n * @param {function} options.parameters.updateAllAudioStreams - Function to update all audio streams.\n * @param {function} options.parameters.updateAllVideoStreams - Function to update all video streams.\n * @param {function} options.parameters.updateShareScreenStarted - Function to update share screen started status.\n * @param {function} options.parameters.updateUpdateMainWindow - Function to update main window status.\n * @param {function} options.parameters.updateNewLimitedStreams - Function to update new limited streams.\n * @param {function} options.parameters.updateOldAllStreams - Function to update old all streams.\n * @param {function} options.parameters.updateDefer_receive - Function to update defer receive status.\n * @param {function} options.parameters.updateMainHeightWidth - Function to update main height and width.\n * @param {function} options.parameters.updateShareEnded - Function to update share ended status.\n * @param {function} options.parameters.updateLock_screen - Function to update lock screen status.\n * @param {function} options.parameters.updateFirstAll - Function to update first all status.\n * @param {function} options.parameters.updateFirst_round - Function to update first round status.\n * @param {function} options.parameters.reorderStreams - Function to reorder streams.\n * @param {function} options.parameters.prepopulateUserMedia - Function to prepopulate user media.\n * @param {function} options.parameters.getVideos - Function to get videos.\n * @param {function} options.parameters.rePort - Function to report.\n *\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n * \n * @example\n * const options = {\n * producerId: 'producerId',\n * kind: 'video',\n * parameters: {\n * getUpdatedAllParams: getUpdatedAllParamsFunction,\n * allAudioStreams: [],\n * allVideoStreams: [],\n * activeNames: [],\n * participants: [],\n * streamNames: [],\n * recordingDisplayType: 'video',\n * recordingVideoOptimized: true,\n * adminIDStream: 'adminId',\n * newLimitedStreams: [],\n * newLimitedStreamsIDs: [],\n * oldAllStreams: [],\n * shareScreenStarted: false,\n * shared: false,\n * meetingDisplayType: 'video',\n * defer_receive: false,\n * lock_screen: false,\n * firstAll: false,\n * first_round: false,\n * gotAllVids: false,\n * eventType: 'conference',\n * hostLabel: 'host',\n * shareEnded: false,\n * updateMainWindow: true,\n * updateActiveNames: updateActiveNamesFunction,\n * updateAllAudioStreams: updateAllAudioStreamsFunction,\n * updateAllVideoStreams: updateAllVideoStreamsFunction,\n * updateShareScreenStarted: updateShareScreenStartedFunction,\n * updateUpdateMainWindow: updateUpdateMainWindowFunction,\n * updateNewLimitedStreams: updateNewLimitedStreamsFunction,\n * updateOldAllStreams: updateOldAllStreamsFunction,\n * updateDefer_receive: updateDefer_receiveFunction,\n * updateMainHeightWidth: updateMainHeightWidthFunction,\n * updateShareEnded: updateShareEndedFunction,\n * updateLock_screen: updateLock_screenFunction,\n * updateFirstAll: updateFirstAllFunction,\n * updateFirst_round: updateFirst_roundFunction,\n * reorderStreams: reorderStreamsFunction,\n * prepopulateUserMedia: prepopulateUserMediaFunction,\n * getVideos: getVideosFunction,\n * rePort: rePortFunction,\n * },\n * };\n * \n * closeAndResize(options)\n * .then(() => {\n * console.log('Closed and resized successfully');\n * });\n */\n\n\nexport const closeAndResize = async ({ producerId, kind, parameters }: CloseAndResizeOptions): Promise<void> => {\n\n let { getUpdatedAllParams } = parameters;\n parameters = getUpdatedAllParams();\n\n let {\n allAudioStreams,\n audioOnlyStreams = [],\n allVideoStreams,\n activeNames,\n participants,\n streamNames,\n recordingDisplayType,\n recordingVideoOptimized,\n adminIDStream,\n newLimitedStreams,\n newLimitedStreamsIDs,\n oldAllStreams,\n shareScreenStarted,\n shared,\n meetingDisplayType,\n defer_receive,\n lock_screen,\n firstAll,\n first_round,\n gotAllVids,\n eventType,\n\n hostLabel,\n shareEnded,\n updateMainWindow,\n updateActiveNames,\n updateAllAudioStreams,\n updateAudioOnlyStreams,\n updateAllVideoStreams,\n\n updateShareScreenStarted,\n updateUpdateMainWindow,\n updateNewLimitedStreams,\n updateOldAllStreams,\n updateDefer_receive,\n updateMainHeightWidth,\n updateShareEnded,\n updateLock_screen,\n updateFirstAll,\n updateFirst_round,\n\n //mediasfu functions\n reorderStreams,\n prepopulateUserMedia,\n getVideos,\n rePort,\n } = parameters;\n\n //function to close and resize the video and audio elements\n\n let participant: Participant | undefined;\n\n if (kind === \"audio\") {\n //stop the audio by removing the miniAudio with id = producerId\n\n //remove the audio from the allAudioStreams array\n allAudioStreams = allAudioStreams.filter(function (audioStream) {\n return audioStream.producerId !== producerId;\n });\n\n updateAllAudioStreams(allAudioStreams);\n\n // Audio-only players (mic and screen audio) are stored separately from allAudioStreams. Leaving one mounted after\n // its producer closes means a rejoin adds a second player, heard as echo or duplicate speech.\n const playerProducerId = (element: any): string =>\n String(element?.props?.remoteProducerId ?? element?.inputs?.remoteProducerId ?? element?.key ?? '');\n if (audioOnlyStreams.some((element: any) => playerProducerId(element) === producerId)) {\n audioOnlyStreams = audioOnlyStreams.filter((element: any) => playerProducerId(element) !== producerId);\n updateAudioOnlyStreams?.(audioOnlyStreams);\n }\n\n if (recordingDisplayType == \"video\" && recordingVideoOptimized == true) {\n // optimize the video display\n } else {\n //get the name of the participant with the producerId\n participant = participants.find(\n (obj) => obj.audioID === producerId\n );\n\n if (participant) {\n //check if the participants videoID is not null or \"\"\n if (participant.videoID !== null && participant.videoID !== \"\") {\n // found a participant with the producerId\n } else {\n //remove the participant from the activeNames array\n activeNames = activeNames.filter(function (name) {\n return name !== participant!.name;\n });\n updateActiveNames(activeNames);\n }\n }\n }\n\n let checker = false;\n let alt_checker = false;\n\n if (meetingDisplayType == \"video\") {\n checker =\n participant![0].videoID != null &&\n participant![0].videoID != \"\" &&\n participant![0].videoID != undefined;\n } else {\n checker = true;\n alt_checker = true;\n }\n\n if (checker) {\n if (shareScreenStarted || shared) {\n if (!alt_checker) {\n await reorderStreams({ parameters });\n }\n } else {\n if (alt_checker && meetingDisplayType != \"video\") {\n await reorderStreams({ add: false, screenChanged: true, parameters });\n }\n }\n }\n } else if (kind === \"video\") {\n //update the video elements by removing the miniVideo with id = producerId\n //remove the video from the allVideoStreams array\n\n //check if producerId == adminidstream\n if (producerId == adminIDStream) {\n updateMainWindow = true;\n updateUpdateMainWindow(updateMainWindow);\n }\n\n try {\n allVideoStreams = allVideoStreams.filter(function (videoStream) {\n return videoStream.producerId !== producerId;\n });\n\n updateAllVideoStreams(allVideoStreams);\n\n try {\n //try remove it from oldVideoStreams\n oldAllStreams = oldAllStreams.filter(function (videoStream) {\n return videoStream.producerId !== producerId;\n });\n\n updateOldAllStreams(oldAllStreams);\n } catch { // Handle error\n }\n\n try {\n //try remove it from newLimitedStreams\n newLimitedStreams = newLimitedStreams.filter(function (\n videoStream\n ) {\n return videoStream.producerId !== producerId;\n });\n\n updateNewLimitedStreams(newLimitedStreams);\n } catch {\n // Handle error\n }\n } catch {\n try {\n //try remove it from oldVideoStreams\n oldAllStreams = oldAllStreams.filter(function (videoStream) {\n return videoStream.producerId !== producerId;\n });\n updateOldAllStreams(oldAllStreams);\n } catch {\n // Handle error\n }\n }\n\n try {\n //remove the participant from activeNames\n activeNames = activeNames.filter(function (name) {\n //get the participant with the producerId\n let participant = streamNames.find(\n (obj) => obj.producerId === producerId\n );\n\n return name !== participant!['name'];\n });\n\n updateActiveNames(activeNames);\n } catch {\n // Handle error\n }\n\n if (lock_screen) {\n defer_receive = true;\n // check if the video is the one being displayed (i.e. (newLimitedStreamsIDs))\n if (newLimitedStreamsIDs.includes(producerId)) {\n await prepopulateUserMedia({ name: hostLabel, parameters });\n await reorderStreams({ add: false, screenChanged: true, parameters });\n }\n } else {\n await prepopulateUserMedia({ name: hostLabel, parameters });\n await reorderStreams({ add: false, screenChanged: true, parameters });\n }\n } else if (kind === \"screenshare\" || kind === \"screen\") {\n //update the video elements by removing the mainVideo with id = producerId\n updateMainWindow = true;\n\n //screenshare stuff\n shareScreenStarted = false;\n shareEnded = true;\n\n lock_screen = false;\n firstAll = false;\n first_round = false;\n\n updateUpdateMainWindow(updateMainWindow);\n updateShareScreenStarted(shareScreenStarted);\n updateShareEnded(shareEnded);\n updateLock_screen(lock_screen);\n updateFirstAll(firstAll);\n updateFirst_round(first_round);\n\n if (!gotAllVids || defer_receive) {\n defer_receive = false;\n updateDefer_receive(defer_receive);\n await getVideos({\n participants,\n allVideoStreams,\n oldAllStreams,\n updateAllVideoStreams,\n updateOldAllStreams,\n });\n await rePort({ parameters });\n }\n\n if (eventType == \"conference\") {\n updateMainHeightWidth(0);\n }\n\n await prepopulateUserMedia({ name: hostLabel, parameters });\n await reorderStreams({ add: false, screenChanged: true, parameters });\n }\n}","import { TriggerType, TriggerParameters } from '../types/types';\n\nexport interface CompareActiveNamesParameters extends TriggerParameters {\n activeNames: string[];\n prevActiveNames: string[];\n updateActiveNames: (activeNames: string[]) => void;\n updatePrevActiveNames: (prevActiveNames: string[]) => void;\n\n // mediasfu functions\n trigger: TriggerType;\n getUpdatedAllParams: () => CompareActiveNamesParameters;\n [key: string]: any;\n}\n\nexport interface CompareActiveNamesOptions {\n restart?: boolean;\n parameters: CompareActiveNamesParameters;\n}\n\n// Export the type definition for the function\nexport type CompareActiveNamesType = (options: CompareActiveNamesOptions) => Promise<void>;\n\n/**\n * Compares the current active names with the previous active names and triggers an action if there are changes.\n *\n * @param {CompareActiveNamesOptions} options - The options for comparing active names.\n * @param {boolean} [options.restart=false] - Whether to restart the comparison.\n * @param {CompareActiveNamesParameters} options.parameters - The parameters for the comparison.\n * @param {Function} options.parameters.getUpdatedAllParams - Function to get updated parameters.\n * @param {string[]} options.parameters.activeNames - The current active names.\n * @param {string[]} options.parameters.prevActiveNames - The previous active names.\n * @param {Function} options.parameters.updatePrevActiveNames - Function to update the previous active names.\n * @param {Function} options.parameters.trigger - Function to trigger an action when names change.\n *\n * @returns {Promise<void>} A promise that resolves when the comparison is complete.\n *\n * @throws Will log an error message if an error occurs during the comparison.\n * \n * @example\n * const options = {\n * restart: false,\n * parameters: {\n * getUpdatedAllParams: getUpdatedAllParamsFunction,\n * activeNames: ['name1', 'name2'],\n * prevActiveNames: ['name1'],\n * updatePrevActiveNames: updatePrevActiveNamesFunction,\n * trigger: triggerFunction,\n * },\n * };\n * \n * compareActiveNames(options)\n * .then(() => {\n * console.log('Active names compared successfully');\n * });\n */\n\nexport async function compareActiveNames({\n restart = false,\n parameters,\n}: CompareActiveNamesOptions): Promise<void> {\n try {\n const { getUpdatedAllParams } = parameters;\n parameters = getUpdatedAllParams();\n\n const {\n activeNames,\n prevActiveNames,\n updatePrevActiveNames,\n\n //mediasfu functions\n trigger,\n } = parameters;\n\n // Restart the comparison if needed\n if (restart) {\n await trigger({ ref_ActiveNames: activeNames, parameters });\n return;\n }\n\n // Array to track changes in activeNames\n const nameChanged: boolean[] = [];\n\n // Compare each name in activeNames\n for (let i = 0; i < activeNames.length; i++) {\n const currentName = activeNames[i];\n\n // Check if the name is present in prevActiveNames\n const hasNameChanged = !prevActiveNames.includes(currentName);\n\n if (hasNameChanged) {\n nameChanged.push(true);\n await trigger({ ref_ActiveNames: activeNames, parameters });\n break;\n }\n }\n\n // Count the number of `true` in nameChanged\n const count = nameChanged.filter((value) => value === true).length;\n\n if (count < 1) {\n // Check for new names in prevActiveNames\n for (let i = 0; i < prevActiveNames.length; i++) {\n const currentName = prevActiveNames[i];\n\n // Check if the name is present in activeNames\n const hasNameChanged = !activeNames.includes(currentName);\n\n // Signal change if the name is new\n if (hasNameChanged) {\n await trigger({ ref_ActiveNames: activeNames, parameters });\n break;\n }\n }\n }\n\n // Update prevActiveNames with current activeNames\n updatePrevActiveNames([...activeNames]);\n } catch (error) {\n console.log(\"compareActiveNames error\", error);\n // throw error; (Optional: Keep or remove depending on your error handling strategy)\n }\n}\n","import { ScreenState, TriggerType, TriggerParameters } from '../types/types';\n\nexport interface CompareScreenStatesParameters extends TriggerParameters {\n recordingDisplayType: 'video' | 'media' | 'all';\n recordingVideoOptimized: boolean;\n screenStates: ScreenState[];\n prevScreenStates: ScreenState[];\n activeNames: string[];\n\n // mediasfu functions\n trigger: TriggerType;\n getUpdatedAllParams: () => CompareScreenStatesParameters;\n [key: string]: any;\n}\n\nexport interface CompareScreenStatesOptions {\n restart?: boolean;\n parameters: CompareScreenStatesParameters;\n}\n\n// Export the type definition for the function\nexport type CompareScreenStatesType = (options: CompareScreenStatesOptions) => Promise<void>;\n\n/**\n * Compares the current screen states with the previous screen states and triggers actions based on changes.\n *\n * @param {CompareScreenStatesOptions} options - The options for comparing screen states.\n * @param {boolean} [options.restart=false] - Whether to restart the comparison process.\n * @param {CompareScreenStatesParameters} options.parameters - The parameters for the comparison.\n * @param {Function} options.parameters.getUpdatedAllParams - Function to get updated parameters.\n * @param {string} options.parameters.recordingDisplayType - The type of display being recorded.\n * @param {boolean} options.parameters.recordingVideoOptimized - Whether the recording is optimized for video.\n * @param {Array<ScreenState>} options.parameters.screenStates - The current screen states.\n * @param {Array<ScreenState>} options.parameters.prevScreenStates - The previous screen states.\n * @param {Array<string>} options.parameters.activeNames - The active names in the current context.\n * @param {Function} options.parameters.trigger - Function to trigger actions based on changes.\n *\n * @returns {Promise<void>} A promise that resolves when the comparison and any triggered actions are complete.\n *\n * @throws Will log an error message if an error occurs during the comparison process.\n * \n * @example\n * const options = {\n * restart: false,\n * parameters: {\n * getUpdatedAllParams: getUpdatedAllParamsFunction,\n * recordingDisplayType: 'video',\n * recordingVideoOptimized: true,\n * screenStates: [{ key1: 'value1' }, { key2: 'value2' }],\n * prevScreenStates: [{ key1: 'value1' }, { key2: 'value2' }],\n * activeNames: ['name1', 'name2'],\n * trigger: triggerFunction,\n * },\n * };\n * \n * compareScreenStates(options)\n * .then(() => {\n * console.log('Screen states compared successfully');\n * });\n */\n\nexport async function compareScreenStates({\n restart = false,\n parameters,\n}: CompareScreenStatesOptions): Promise<void> {\n try {\n const { getUpdatedAllParams } = parameters;\n parameters = getUpdatedAllParams();\n\n const {\n recordingDisplayType,\n recordingVideoOptimized,\n screenStates,\n prevScreenStates,\n activeNames,\n\n //mediasfu functions\n trigger,\n } = parameters;\n\n // Restart the comparison if needed\n if (restart) {\n // Perform necessary actions on restart\n return;\n }\n\n // Compare each key-value pair in the screenStates objects\n for (let i = 0; i < screenStates.length; i++) {\n const currentScreenState = screenStates[i];\n const prevScreenState = prevScreenStates[i];\n\n // Check if any value has changed\n const hasChanged = (Object.keys(currentScreenState) as (keyof ScreenState)[]).some(\n (key) => currentScreenState[key] !== prevScreenState[key]\n );\n\n // Signal change if any value has changed\n if (hasChanged) {\n // Perform actions or trigger events based on the change\n if (recordingDisplayType === 'video') {\n if (recordingVideoOptimized) {\n await trigger({\n ref_ActiveNames: activeNames,\n parameters,\n });\n break;\n }\n }\n await trigger({ ref_ActiveNames: activeNames, parameters });\n break;\n }\n }\n } catch (error) {\n console.log('compareScreenStates error', error);\n // Optionally re-throw the error for further handling\n }\n}\n","\n// Socket manager for media socket.\nimport { MeetingRoomParams, RecordingParams } from '../types/types';\nimport io, { Socket } from 'socket.io-client'; // Importing socket type\nimport {\n MediaSocketConnectError,\n MediaSocketConnectPhase,\n MediaConnectionRejectionReason,\n currentOnlineState,\n normalizeRejectionReason,\n} from './mediaSocketErrors';\n\n/**\n * Validates the provided API key or token.\n * @param {string} value - The API key or token to validate.\n * @returns {Promise<Boolean>} - True if the API key or token is valid, false otherwise.\n */\nasync function validateApiKeyToken(value: string): Promise<boolean> {\n // API key or token must be alphanumeric and length 64\n if (!/^[a-z0-9]{64}$/i.test(value)) {\n throw new Error('Invalid API key or token.');\n }\n return true;\n}\n\nexport interface ResponseLocalConnection {\n socket?: Socket;\n data?: ResponseLocalConnectionData;\n}\n\nexport interface ResponseLocalConnectionData {\n socketId: string;\n mode: string;\n apiUserName?: string;\n apiKey?: string;\n allowRecord: boolean;\n meetingRoomParams_: MeetingRoomParams;\n recordingParams_: RecordingParams;\n}\n\nexport interface ConnectLocalSocketOptions {\n link: string;\n}\n\nexport interface ConnectSocketOptions {\n apiUserName: string;\n apiKey?: string;\n apiToken?: string;\n link: string;\n}\n\nexport interface DisconnectSocketOptions {\n socket: Socket;\n}\n\n// Export the type definition for the function\nexport type ConnectSocketType = (options: ConnectSocketOptions) => Promise<Socket>;\nexport type DisconnectSocketType = (options: DisconnectSocketOptions) => Promise<boolean>;\nexport type ConnectLocalSocketType = (options: ConnectLocalSocketOptions) => Promise<ResponseLocalConnection>;\n\n\n/**\n * Connects to a media socket using the provided connection options.\n *\n * @param {ConnectSocketOptions} options - The connection options.\n * @param {string} options.apiUserName - The API username.\n * @param {string} [options.apiKey] - The API key (optional if apiToken is provided).\n * @param {string} [options.apiToken] - The API token (optional if apiKey is provided).\n * @param {string} options.link - The socket link.\n *\n * @returns {Promise<Socket>} A promise that resolves to the connected socket.\n * @throws {MediaSocketConnectError} When the connection fails. `phase` says where (`before-open`, `after-open`,\n * `rejected`, `timeout`), `reason`/`stage` carry the server's `connection-rejected` verdict, `elapsedMs` and `online`\n * help tell a device/network problem from a refusal, and `retryable` is false for rejections that cannot succeed\n * with the same credentials. `describeMediaSocketError(error)` turns it into a user-facing sentence.\n *\n * @example\n * ```typescript\n * const options = {\n * apiUserName: 'user123',\n * apiKey: 'yourApiKeyHere',\n * link: 'https://socketlink.com',\n * };\n *\n * try {\n * const socket = await connectSocket(options);\n * console.log('Connected to socket:', socket);\n * } catch (error) {\n * console.error('Failed to connect to socket:', error);\n * }\n * ```\n */\n\n/** How long to wait for `connection-success` before giving up. */\nconst CONNECT_TIMEOUT_MS = 12000;\n\nasync function connectSocket(\n { apiUserName, apiKey, apiToken, link }: ConnectSocketOptions,\n): Promise<Socket> {\n // Validate inputs\n if (!apiUserName) {\n throw new Error('API username required.');\n }\n if (!(apiKey || apiToken)) {\n throw new Error('API key or token required.');\n }\n if (!link) {\n throw new Error('Socket link required.');\n }\n\n // Validate the API key or token\n let useKey = false;\n try {\n if (apiKey && apiKey.length === 64) {\n await validateApiKeyToken(apiKey);\n useKey = true;\n } else if (apiToken && apiToken.length === 64) {\n await validateApiKeyToken(apiToken);\n useKey = false;\n } else {\n throw new Error('Invalid API key or token format.');\n }\n } catch {\n throw new Error('Invalid API key or token.');\n }\n\n let socket: Socket;\n\n return new Promise((resolve, reject) => {\n // Connect to socket using the link provided\n if (useKey) {\n socket = io(`${link}/media`, {\n transports: ['websocket'],\n query: {\n apiUserName: apiUserName,\n apiKey: apiKey!,\n },\n });\n } else {\n socket = io(`${link}/media`, {\n transports: ['websocket'],\n query: {\n apiUserName: apiUserName,\n apiToken: apiToken!,\n },\n });\n }\n\n // Every path below runs at most once, clears handshake listeners/timers,\n // and closes failed clients so Socket.IO cannot keep reconnecting an\n // orphan that the room lifecycle never received.\n let settled = false;\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n const startedAt = Date.now();\n let transportOpened = false;\n let rejection: { reason: MediaConnectionRejectionReason; stage?: string } | null = null;\n const cleanupHandshake = () => {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n socket.off('connection-success', handleConnectionSuccess);\n socket.off('connect_error', handleConnectError);\n socket.off('disconnect', handleDisconnectBeforeReady);\n socket.off('connect', handleTransportOpen);\n socket.off('connection-rejected', handleConnectionRejected);\n };\n const failure = (phase: MediaSocketConnectPhase, transportError?: string) =>\n new MediaSocketConnectError({\n phase: rejection ? 'rejected' : phase,\n reason: rejection?.reason,\n stage: rejection?.stage,\n elapsedMs: Date.now() - startedAt,\n online: currentOnlineState(),\n transportError,\n link,\n });\n const settle = (action: () => void) => {\n if (settled) return;\n settled = true;\n cleanupHandshake();\n action();\n };\n\n // Handle socket connection events\n const handleConnectionSuccess = ({ socketId }: { socketId: string }) => {\n //check if link contains mediasfu.com and contains more than one c\n let conn = 'media';\n try {\n if (link.includes('mediasfu.com') && (link.match(/c/g)?.length ?? 0) > 1) {\n conn = 'consume';\n }\n } catch {\n // do nothing\n }\n\n console.log(`Connected to ${conn} socket with ID: ${socketId}`);\n settle(() => resolve(socket));\n };\n\n const handleConnectError = (error: Error) => {\n settle(() => {\n socket.disconnect();\n reject(failure(transportOpened ? 'after-open' : 'before-open', error?.message));\n });\n };\n\n const handleTransportOpen = () => {\n transportOpened = true;\n };\n\n // Media admission v2: the node says why before it closes the handshake. Socket.IO's own reconnection never\n // retries a server-side close, and settling here stops this attempt from being retried as a network error.\n const handleConnectionRejected = (payload?: { reason?: string; stage?: string }) => {\n rejection = {\n reason: normalizeRejectionReason(payload?.reason),\n stage: typeof payload?.stage === 'string' ? payload.stage : undefined,\n };\n settle(() => {\n try {\n socket.disconnect();\n } catch {\n // Already closing.\n }\n reject(failure('rejected'));\n });\n };\n\n // The transport can connect and then be dropped by the server before it\n // ever sends `connection-success` — a rejected room, an expired token, a\n // bad handshake. Without this the promise stayed pending forever, so the\n // caller's loading modal never came down and no error was ever surfaced.\n const handleDisconnectBeforeReady = (reason: string) => {\n settle(() => reject(failure('after-open', reason)));\n };\n\n socket.on('connection-success', handleConnectionSuccess);\n socket.on('connect_error', handleConnectError);\n socket.on('disconnect', handleDisconnectBeforeReady);\n socket.on('connect', handleTransportOpen);\n socket.on('connection-rejected', handleConnectionRejected);\n\n // Last resort, for the case where the socket neither connects, errors nor\n // disconnects. Nothing above guarantees a settle on its own.\n timeoutHandle = setTimeout(() => {\n settle(() => {\n try {\n socket.disconnect();\n } catch {\n // Nothing useful to do here.\n }\n reject(failure('timeout'));\n });\n }, CONNECT_TIMEOUT_MS);\n });\n}\n\n\n/**\n * Connects to a local media socket using the provided connection options.\n *\n * @param {ConnectLocalSocketOptions} options - The connection options.\n * @param {string} options.link - The socket link.\n *\n * @returns {Promise<ResponseLocalConnection>} A promise that resolves to the connected socket and data.\n *\n * @example\n * ```typescript\n * const options = {\n * link: 'http://localhost:3000',\n * };\n *\n * try {\n * const { socket, data } = await connectLocalSocket(options);\n * console.log('Connected to socket:', socket, data);\n * } catch (error) {\n * console.error('Failed to connect to socket:', error);\n * }\n * ```\n */\n\nasync function connectLocalSocket({ link }: ConnectLocalSocketOptions): Promise<ResponseLocalConnection> {\n if (!link) {\n throw new Error('Socket link required.');\n }\n\n let socket: Socket;\n\n return new Promise((resolve, reject) => {\n // Connect to socket using the link provided\n socket = io(`${link}/media`, {\n transports: ['websocket'],\n });\n const startedAt = Date.now();\n let transportOpened = false;\n socket.on('connect', () => {\n transportOpened = true;\n });\n\n\n // Handle socket connection events\n socket.on('connection-success', (data: ResponseLocalConnectionData) => {\n resolve({ socket, data });\n });\n\n socket.on('connect_error', (error: Error) => {\n reject(\n new MediaSocketConnectError({\n phase: transportOpened ? 'after-open' : 'before-open',\n elapsedMs: Date.now() - startedAt,\n online: currentOnlineState(),\n transportError: error?.message,\n link,\n })\n );\n });\n });\n}\n\n/**\n * Disconnects from the socket.\n *\n * @param {Socket} socket - The socket instance to disconnect.\n * @returns {Promise<boolean>} - A promise that resolves once the socket is disconnected.\n *\n * @example\n * ```typescript\n * const options = { socket: socketInstance };\n *\n * try {\n * const isDisconnected = await disconnectSocket(options);\n * console.log('Disconnected:', isDisconnected);\n * } catch (error) {\n * console.error('Failed to disconnect:', error);\n * }\n * ```\n */\n\nasync function disconnectSocket({ socket }: DisconnectSocketOptions): Promise<boolean> {\n if (socket) {\n socket.disconnect();\n }\n return true;\n}\n\nexport { connectSocket, disconnectSocket, connectLocalSocket };\n","/**\n * Bounded ICE recovery shared by sending and receiving transports.\n * Keeps tracks/producers alive while ICE is restarted on both endpoints.\n */\nexport function attachTransportRecovery(transport: any, socket: any, onFailure: () => void) {\n let timer: ReturnType<typeof setTimeout> | undefined;\n let disposed = false;\n let recovering = false;\n let attempts = 0;\n const socketId = socket.id;\n const listeners: Array<() => void> = [];\n const report = (state: string) => {\n transport.appData = { ...transport.appData, recoveryState: state };\n transport.observer?.emit('recoverychange', state);\n };\n const clearTimer = () => { if (timer) clearTimeout(timer); timer = undefined; };\n const current = () => !disposed && !transport.closed && socket.connected !== false && socket.id === socketId;\n const dispose = () => {\n disposed = true;\n clearTimer();\n listeners.splice(0).forEach(cancel => cancel());\n socket.off?.('disconnect', dispose);\n transport.off?.('connectionstatechange', changed);\n transport.observer?.off?.('close', dispose);\n };\n const failed = () => {\n if (disposed) return;\n report('failed');\n try { onFailure(); } catch (_) { /* UI callbacks must not prevent teardown. */ }\n try { transport.close(); } finally { dispose(); }\n };\n const waitConnected = () => new Promise<void>((resolve, reject) => {\n let settled = false;\n const finish = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(deadline);\n transport.off?.('connectionstatechange', connected);\n const i = listeners.indexOf(cancel);\n if (i >= 0) listeners.splice(i, 1);\n error ? reject(error) : resolve();\n };\n const connected = (state: string) => { if (state === 'connected') finish(); };\n const cancel = () => finish(new Error('Recovery cancelled'));\n const deadline = setTimeout(() => finish(new Error('ICE recovery timed out')), 10000);\n listeners.push(cancel);\n transport.on('connectionstatechange', connected);\n if (transport.connectionState === 'connected') finish();\n });\n const restart = async () => {\n if (!current() || recovering) return;\n recovering = true;\n report('recovering');\n try {\n while (current() && attempts < 2) {\n attempts++;\n try {\n const iceParameters = await new Promise<any>((resolve, reject) => {\n let settled = false;\n const finish = (error?: Error, value?: any) => {\n if (settled) return;\n settled = true;\n clearTimeout(deadline);\n const i = listeners.indexOf(cancel);\n if (i >= 0) listeners.splice(i, 1);\n error ? reject(error) : resolve(value);\n };\n const cancel = () => finish(new Error('Recovery cancelled'));\n const deadline = setTimeout(() => finish(new Error('ICE restart acknowledgement timed out')), 8000);\n listeners.push(cancel);\n socket.emit('transport-restart-ice', { transportId: transport.id }, (response: any) => {\n if (!response?.iceParameters || response.error) finish(new Error(response?.error || 'Invalid ICE response'));\n else finish(undefined, response.iceParameters);\n });\n });\n if (!current()) return;\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n const finish = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(deadline);\n const i = listeners.indexOf(cancel);\n if (i >= 0) listeners.splice(i, 1);\n error ? reject(error) : resolve();\n };\n const cancel = () => finish(new Error('Recovery cancelled'));\n const deadline = setTimeout(() => finish(new Error('Local ICE restart timed out')), 8000);\n listeners.push(cancel);\n Promise.resolve().then(() => {\n if (!current()) throw new Error('Recovery cancelled');\n return transport.restartIce({ iceParameters });\n }).then(() => finish(), error => finish(error));\n });\n if (!current()) return;\n await waitConnected();\n if (!current()) return;\n attempts = 0;\n report('connected');\n return;\n } catch (_) {\n if (!current()) return;\n if (transport.connectionState === 'connected') {\n attempts = 0;\n report('connected');\n return;\n }\n if (attempts < 2) {\n // Respect the server's two-second restart throttle, including\n // immediate acknowledgement failures. Teardown cancels the wait.\n await new Promise<void>(resolve => {\n const cancel = () => {\n clearTimeout(delay);\n const i = listeners.indexOf(cancel);\n if (i >= 0) listeners.splice(i, 1);\n resolve();\n };\n const delay = setTimeout(cancel, 2100);\n listeners.push(cancel);\n });\n }\n }\n }\n if (current()) failed();\n } finally {\n recovering = false;\n }\n };\n const changed = (state: string) => {\n if (disposed) return;\n if (state === 'connected') {\n clearTimer();\n if (!recovering) { attempts = 0; report('connected'); }\n } else if (state === 'disconnected') {\n if (recovering || timer) return;\n report('waiting');\n timer = setTimeout(() => { timer = undefined; void restart(); }, 3000);\n } else if (state === 'failed') {\n clearTimer();\n void restart();\n } else if (state === 'closed') dispose();\n };\n socket.on?.('disconnect', dispose);\n transport.on('connectionstatechange', changed);\n transport.observer?.once('close', dispose);\n return dispose;\n}\n\n/** Clear publishing indicators only if this is still the active transport. */\nexport function clearFailedSendState(parameters: any, transport: any, local = false) {\n const live = parameters.getCurrentParams?.() ?? parameters.getUpdatedAllParams?.() ?? parameters;\n if ((local ? live.localProducerTransport : live.producerTransport) !== transport) return;\n if (local) {\n live.updateLocalProducerTransport?.(null);\n live.updateLocalTransportCreated?.(false);\n return;\n }\n for (const kind of ['Audio', 'Video', 'Screen']) {\n const key = kind.toLowerCase();\n live['update' + kind + 'Producer']?.(null);\n live['updateTransportCreated' + kind]?.(false);\n live['update' + kind + 'AlreadyOn']?.(false);\n // Notify room membership using the existing pause protocol, preserving\n // users' local tracks for an explicit retry.\n live.socket?.emit('pauseProducerMedia', { mediaTag: key, roomName: live.roomName });\n }\n live.updateProducerTransport?.(null);\n live.updateTransportCreated?.(false);\n live.showAlert?.({ message: 'Media connection could not recover. Rejoin the room to restore audio and video.', type: 'danger', duration: 10000 });\n}\n","import { Socket } from \"socket.io-client\";\nimport { attachTransportRecovery } from './transportRecovery';\nimport { ReorderStreamsParameters, ReorderStreamsType, ConnectRecvTransportType,\n ConnectRecvTransportParameters, CreateWebRTCTransportResponse } from \"../types/types\";\nimport type { Device, DtlsParameters } from 'mediasoup-client/types';\n\nexport interface SignalNewConsumerTransportParameters extends ReorderStreamsParameters, ConnectRecvTransportParameters {\n device: Device | null;\n consumingTransports: string[];\n lock_screen: boolean;\n updateConsumingTransports: (transports: string[]) => void;\n connectRecvTransport: ConnectRecvTransportType;\n reorderStreams: ReorderStreamsType;\n getUpdatedAllParams: () => SignalNewConsumerTransportParameters;\n [key: string]: any;\n}\n\nexport interface SignalNewConsumerTransportOptions {\n remoteProducerId: string;\n islevel: string;\n nsock: Socket;\n parameters: SignalNewConsumerTransportParameters;\n}\n\n// Export the type definition for the function\nexport type SignalNewConsumerTransportType = (options: SignalNewConsumerTransportOptions) => Promise<string[] | void>;\n\n/**\n * Signals the creation of a new consumer transport.\n * \n * @param {SignalNewConsumerTransportOptions} options - The options for signaling a new consumer transport.\n * @param {string} options.remoteProducerId - The ID of the remote producer.\n * @param {string} options.islevel - Indicates the level of the consumer.\n * @param {Socket} options.nsock - The socket instance for communication.\n * @param {SignalNewConsumerTransportParameters} options.parameters - The parameters for the transport.\n * \n * @returns {Promise<string[] | void>} A promise that resolves to an array of consuming transports or void.\n * \n * @throws Will throw an error if the signaling process fails.\n * \n * @example\n * const options = {\n * remoteProducerId: 'producer-id',\n * islevel: '1',\n * nsock: socketInstance,\n * parameters: {\n * device: mediaDevice,\n * consumingTransports: [],\n * lock_screen: false,\n * updateConsumingTransports: updateFunction,\n * connectRecvTransport: connectFunction,\n * reorderStreams: reorderFunction,\n * getUpdatedAllParams: getUpdatedParamsFunction,\n * },\n * };\n * \n * signalNewConsumerTransport(options)\n * .then(consumingTransports => {\n * console.log('Consuming Transports:', consumingTransports);\n * })\n * .catch(error => {\n * console.error('Error signaling new consumer transport:', error);\n * });\n */\n\nexport const signalNewConsumerTransport = async ({\n remoteProducerId,\n islevel,\n nsock,\n parameters,\n}: SignalNewConsumerTransportOptions): Promise<string[] | void> => {\n try {\n let {\n device,\n consumingTransports,\n lock_screen,\n updateConsumingTransports,\n connectRecvTransport,\n reorderStreams,\n } = parameters;\n\n // Get updated parameters\n const updatedParams = parameters.getUpdatedAllParams();\n device = updatedParams.device;\n consumingTransports = updatedParams.consumingTransports;\n\n // Check if already consuming\n if (consumingTransports.includes(remoteProducerId)) {\n return consumingTransports;\n }\n\n // Add remote producer ID to consumingTransports array\n consumingTransports.push(remoteProducerId);\n updateConsumingTransports(consumingTransports);\n\n // Emit createWebRtcTransport event to signal a new consumer\n nsock.emit(\n \"createWebRtcTransport\",\n { consumer: true, islevel },\n async ({ params }: { params: CreateWebRTCTransportResponse }) => {\n if (params.error) {\n // Handle error\n return;\n }\n\n try {\n // Create a new receiving transport using the received parameters\n const consumerTransport = device!.createRecvTransport({ ...params });\n\n // Handle 'connect' event for the consumer transport\n consumerTransport.on(\n \"connect\",\n async (\n { dtlsParameters }: { dtlsParameters: DtlsParameters },\n callback: () => void,\n errback: (error: any) => void\n ) => {\n try {\n // Emit transport-recv-connect event to signal connection\n nsock.emit(\"transport-recv-connect\", {\n dtlsParameters,\n serverConsumerTransportId: params.id,\n });\n callback();\n } catch (error) {\n errback(error);\n }\n }\n );\n\n // Listen for connection state change\n attachTransportRecovery(consumerTransport, nsock, () => {\n const live: any = parameters.getCurrentParams?.() ?? parameters.getUpdatedAllParams?.() ?? parameters;\n live.updateConsumingTransports?.((live.consumingTransports || []).filter((id: string) => id !== remoteProducerId));\n live.updateConsumerTransports?.((live.consumerTransports || []).filter((entry: any) => entry.consumerTransport !== consumerTransport));\n live.showAlert?.({ message: 'A remote media connection could not recover. Rejoin to restore it.', type: 'danger', duration: 10000 });\n void Promise.resolve(reorderStreams({ add: Boolean(lock_screen), parameters })).catch(() => {});\n });\n\n // Connect the receiving transport\n await connectRecvTransport({\n consumerTransport,\n remoteProducerId,\n serverConsumerTransportId: params.id,\n nsock,\n parameters,\n });\n } catch (error) {\n console.log(error, \"createRecvTransport error\");\n // Handle error\n return;\n }\n }\n );\n } catch (error) {\n console.log(error, \"signalNewConsumerTransport error\");\n // Handle error\n return;\n }\n};\n","import { Socket } from 'socket.io-client';\nimport { signalNewConsumerTransport } from '../signalNewConsumerTransport';\nimport { ReorderStreamsParameters, ReorderStreamsType, SignalNewConsumerTransportParameters, ConnectRecvTransportParameters, ConnectRecvTransportType, ShowAlert } from '../../types/types';\nimport type { Device } from 'mediasoup-client/types';\n\nexport interface TranslationMeta {\n speakerId: string;\n speakerName: string;\n language: string;\n originalProducerId?: string;\n isSpeakerControlled?: boolean;\n}\nexport interface NewPipeProducerParameters extends ReorderStreamsParameters, SignalNewConsumerTransportParameters, ConnectRecvTransportParameters {\n\n first_round: boolean;\n shareScreenStarted: boolean;\n shared: boolean;\n landScaped: boolean;\n showAlert?: ShowAlert;\n isWideScreen: boolean;\n updateFirst_round: (firstRound: boolean) => void;\n updateLandScaped: (landScaped: boolean) => void;\n device: Device | null;\n consumingTransports: string[];\n lock_screen: boolean;\n updateConsumingTransports: (transports: string[]) => void;\n\n // mediasfu functions\n connectRecvTransport: ConnectRecvTransportType;\n reorderStreams: ReorderStreamsType;\n getUpdatedAllParams: () => NewPipeProducerParameters;\n\n startConsumingTranslation?: (producerId: string, speakerId: string, language: string, originalProducerId?: string, nsock?: Socket) => Promise<void>;\n translationSubscriptions?: Map<string, { speakerId: string; language: string }>;\n speakerTranslationStates?: Map<string, { speakerId: string; speakerName: string; inputLanguage: string; outputLanguage: string; originalProducerId: string; enabled: boolean }>;\n listenerTranslationOverrides?: Map<string, { speakerId: string; wantOriginal: boolean; preferredLanguage?: string }>;\n listenerTranslationPreferences?: {\n perSpeaker: Map<string, { speakerId: string; language: string | null; wantOriginal: boolean }>;\n globalLanguage: string | null;\n };\n [key: string]: any;\n\n}\n\nexport interface NewPipeProducerOptions {\n producerId: string;\n islevel: string;\n nsock: Socket;\n parameters: NewPipeProducerParameters;\n isTranslation?: boolean;\n translationMeta?: TranslationMeta;\n}\n\n// Export the type definition for the function\nexport type NewPipeProducerType = (options: NewPipeProducerOptions) => Promise<void>;\n\n\n/**\n * Handles the creation of a new pipe producer by signaling for a new consumer transport and updating the necessary parameters.\n *\n * @function\n * @async\n * @param {NewPipeProducerOptions} options - The options for the new pipe producer.\n * @param {string} options.producerId - The ID of the producer to be consumed.\n * @param {string} options.islevel - The level status of the participant.\n * @param {Socket} options.nsock - The socket instance for real-time communication.\n * @param {NewPipeProducerParameters} options.parameters - Additional parameters required for the producer.\n * @param {boolean} options.parameters.shareScreenStarted - Indicates if screen sharing has started.\n * @param {boolean} options.parameters.shared - Indicates if sharing is active.\n * @param {boolean} options.parameters.landScaped - Indicates if the device is in landscape mode.\n * @param {ShowAlert} options.parameters.showAlert - Function to show alerts to the user.\n * @param {boolean} options.parameters.isWideScreen - Indicates if the device is a widescreen.\n * @param {Function} options.parameters.updateFirst_round - Function to update the first round status.\n * @param {Function} options.parameters.updateLandScaped - Function to update the landscape status.\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n * @throws {Error} Will throw an error if the operation fails to signal the new consumer transport.\n *\n * @example\n * import { newPipeProducer } from 'mediasfu-reactjs';\n * import { io } from 'socket.io-client';\n * \n * const parameters = {\n * shareScreenStarted: true,\n * shared: true,\n * landScaped: false,\n * showAlert: (alert) => console.log(alert.message),\n * isWideScreen: false,\n * updateFirst_round: (firstRound) => console.log('First round updated:', firstRound),\n * updateLandScaped: (landScaped) => console.log('Landscape status updated:', landScaped),\n * };\n * \n * const producerId = 'producer-123';\n * const islevel = '2';\n * const nsock = io(\"http://localhost:3000\");\n * \n * async function init() {\n * try {\n * await newPipeProducer({\n * producerId,\n * islevel,\n * nsock,\n * parameters,\n * });\n * console.log('New pipe producer created successfully');\n * } catch (error) {\n * console.error('Error creating new pipe producer:', error);\n * }\n * }\n * \n * init();\n */\n\nexport const newPipeProducer = async ({\n producerId,\n islevel,\n nsock,\n parameters,\n isTranslation,\n translationMeta,\n}: NewPipeProducerOptions): Promise<void> => {\n if (isTranslation && translationMeta) {\n const freshParams = parameters.getUpdatedAllParams ? parameters.getUpdatedAllParams() : parameters;\n\n const {\n startConsumingTranslation,\n translationSubscriptions,\n speakerTranslationStates,\n listenerTranslationOverrides,\n listenerTranslationPreferences,\n } = freshParams;\n\n const normalizedLang = translationMeta.language?.toLowerCase();\n const isSpeakerControlledFromMeta = translationMeta.isSpeakerControlled === true;\n const speakerState = speakerTranslationStates?.get(translationMeta.speakerId);\n const isSpeakerControlledFromState = speakerState?.enabled\n && speakerState?.outputLanguage?.toLowerCase() === normalizedLang;\n const shouldSkipBecauseWrongLanguage = isSpeakerControlledFromMeta\n && speakerState?.enabled\n && speakerState?.outputLanguage?.toLowerCase() !== normalizedLang;\n\n const subscriptionKey = `${translationMeta.speakerId}_${normalizedLang}`;\n const isListenerSubscribed = translationSubscriptions?.has(subscriptionKey)\n || translationSubscriptions?.has(translationMeta.speakerId);\n\n let overrideBlocksConsumption = false;\n let shouldConsumeForOverride = false;\n let shouldConsumeForGlobal = false;\n\n const perSpeakerPref = listenerTranslationPreferences?.perSpeaker?.get(translationMeta.speakerId);\n const globalPref = listenerTranslationPreferences?.globalLanguage;\n const listenerOverride = listenerTranslationOverrides?.get(translationMeta.speakerId);\n\n if (perSpeakerPref) {\n if (perSpeakerPref.wantOriginal) {\n overrideBlocksConsumption = true;\n } else if (perSpeakerPref.language) {\n if (perSpeakerPref.language === normalizedLang) {\n shouldConsumeForOverride = true;\n } else {\n overrideBlocksConsumption = true;\n }\n }\n } else if (globalPref) {\n if (globalPref === normalizedLang) {\n shouldConsumeForGlobal = true;\n } else {\n overrideBlocksConsumption = true;\n }\n } else if (listenerOverride) {\n if (listenerOverride.wantOriginal) {\n overrideBlocksConsumption = true;\n } else if (listenerOverride.preferredLanguage) {\n if (listenerOverride.preferredLanguage.toLowerCase() === normalizedLang) {\n shouldConsumeForOverride = true;\n } else {\n overrideBlocksConsumption = true;\n }\n }\n }\n\n const shouldConsumeForSpeakerControlled =\n isSpeakerControlledFromMeta\n && (!speakerState?.enabled || speakerState?.outputLanguage?.toLowerCase() === normalizedLang);\n const hasNoPreference = !perSpeakerPref && !globalPref && !listenerOverride;\n const isListenerInitiated = !isSpeakerControlledFromMeta && !isSpeakerControlledFromState;\n const blockBecauseNotRelevant = hasNoPreference && isListenerInitiated && !isListenerSubscribed;\n\n const shouldConsume =\n !overrideBlocksConsumption\n && !shouldSkipBecauseWrongLanguage\n && !blockBecauseNotRelevant\n && (shouldConsumeForOverride\n || shouldConsumeForGlobal\n || shouldConsumeForSpeakerControlled\n || isSpeakerControlledFromState\n || isListenerSubscribed);\n\n if (shouldConsume && startConsumingTranslation) {\n try {\n await startConsumingTranslation(\n producerId,\n translationMeta.speakerId,\n translationMeta.language,\n translationMeta.originalProducerId,\n nsock,\n );\n } catch {\n }\n }\n\n return;\n }\n\n const {\n shareScreenStarted,\n shared,\n landScaped,\n showAlert,\n isWideScreen,\n updateFirst_round,\n updateLandScaped,\n } = parameters;\n\n // Signal new consumer transport\n await signalNewConsumerTransport({\n remoteProducerId: producerId,\n islevel,\n nsock,\n parameters\n });\n\n // Modify first_round and landscape status\n let updatedFirstRound = false;\n\n if (shareScreenStarted || shared) {\n if (!isWideScreen) {\n if (!landScaped) {\n if (showAlert) {\n showAlert({\n message: 'Please rotate your device to landscape mode for better experience',\n type: 'success',\n duration: 3000,\n });\n }\n updateLandScaped(true);\n }\n }\n\n updatedFirstRound = true;\n updateFirst_round(updatedFirstRound);\n }\n};\n","import type { Producer } from \"mediasoup-client/types\";\nimport { Participant } from \"../types/types\";\n\n/**\n * Screen audio: the audio of a shared tab, window or screen, published as its own producer tagged\n * `appData.mediaTag === \"screen-audio\"`. It belongs to the screen share (starts, pauses, resumes and stops with it),\n * never to the sharer's microphone, so it never marks the sharer as speaking.\n *\n * A client only publishes it when the media server says so in the join response (`supportsScreenAudio`), so new\n * clients keep today's video-only screen share on older servers.\n */\nexport const SCREEN_AUDIO_MEDIA_TAG = \"screen-audio\";\n\n/** Opus settings for shared media (music, video soundtracks) rather than voice. */\nexport const SCREEN_AUDIO_CODEC_OPTIONS = {\n opusStereo: true,\n opusDtx: false,\n opusFec: true,\n opusMaxAverageBitrate: 128000,\n};\n\n// Producer ids are globally unique, so one registry serves every room instance on the page.\nconst screenAudioProducerIds = new Set<string>();\n\n/** Records a producer announced by the server as screen audio (`mediaTag: \"screen-audio\"`). */\nexport const markScreenAudioProducer = (producerId?: string | null, mediaTag?: string | null): void => {\n if (producerId && mediaTag === SCREEN_AUDIO_MEDIA_TAG) screenAudioProducerIds.add(producerId);\n};\n\nexport const forgetScreenAudioProducer = (producerId?: string | null): void => {\n if (producerId) screenAudioProducerIds.delete(producerId);\n};\n\nexport interface IsScreenAudioProducerOptions {\n producerId: string;\n participants?: Participant[];\n appData?: Record<string, unknown> | null;\n}\n\n/** True when the producer is screen audio, by server tag, consumer appData or the sharer's `ScreenAudioID`. */\nexport const isScreenAudioProducer = ({ producerId, participants = [], appData }: IsScreenAudioProducerOptions): boolean => {\n if (!producerId) return false;\n if (screenAudioProducerIds.has(producerId)) return true;\n if (appData?.mediaTag === SCREEN_AUDIO_MEDIA_TAG) return true;\n return participants.some((participant) => participant?.ScreenAudioID === producerId);\n};\n\n/**\n * How a screen share treats audio: `ask` (default) shows a choice before the browser's picker, `always` requests audio\n * without asking, `never` shares video only.\n */\nexport type ScreenAudioMode = \"ask\" | \"always\" | \"never\";\n\nexport interface ScreenAudioSettings {\n supportsScreenAudio?: boolean;\n screenAudioEnabled?: boolean;\n screenAudioMode?: ScreenAudioMode;\n}\n\n/** Screen audio is requested only when the server supports it and the app has not turned it off. */\nexport const shouldShareScreenAudio = ({ supportsScreenAudio, screenAudioEnabled, screenAudioMode }: ScreenAudioSettings): boolean =>\n supportsScreenAudio === true && screenAudioEnabled !== false && screenAudioMode !== \"never\";\n\n/**\n * Whether this browser can capture the audio of a shared tab or screen. Chromium desktop browsers (Chrome, Edge,\n * Opera, Brave) can; Firefox, Safari and mobile browsers return video only.\n */\nexport const canCaptureDisplayAudio = (nav: Partial<Navigator> | undefined = typeof navigator !== \"undefined\" ? navigator : undefined): boolean => {\n if (!nav) return false;\n const ua = String(nav.userAgent || \"\");\n if (/Mobi|Android|iPhone|iPad|iPod/i.test(ua)) return false;\n const brands: string[] = ((nav as any).userAgentData?.brands || []).map((entry: { brand?: string }) => String(entry?.brand || \"\"));\n if (brands.some((brand) => /Chromium|Google Chrome|Microsoft Edge|Opera|Brave/i.test(brand))) return true;\n return /(Chrome|Chromium|Edg)\\//.test(ua) && !/Firefox|FxiOS|OPiOS/.test(ua);\n};\n\n/** The user's answer to \"share audio too?\": `audio`, `video` (screen only) or `null` (cancelled). */\nexport type ScreenAudioChoice = \"audio\" | \"video\" | null;\n\n/** Mutes or unmutes the sharer's screen audio without stopping the screen share. Returns the new paused state. */\nexport const setScreenAudioPaused = (producer: Producer | null | undefined, paused: boolean): boolean => {\n if (!producer || producer.closed) return false;\n if (paused && !producer.paused) producer.pause();\n if (!paused && producer.paused) producer.resume();\n return producer.paused;\n};\n\nexport interface DisplayMediaOptionsInput {\n targetWidth: number;\n targetHeight: number;\n withAudio: boolean;\n}\n\n/**\n * Options for `getDisplayMedia`. With audio, the browser's picker shows its own \"share audio\" choice, which is the\n * user's consent; browsers that cannot capture display audio (Firefox, Safari) return a video-only stream.\n */\nexport const buildDisplayMediaOptions = ({ targetWidth, targetHeight, withAudio }: DisplayMediaOptionsInput) => {\n const options: Record<string, unknown> = {\n video: { width: targetWidth, height: targetHeight, frameRate: 30 },\n audio: withAudio\n ? { echoCancellation: false, noiseSuppression: false, autoGainControl: false }\n : false,\n };\n if (withAudio) {\n // Chromium hints; other browsers ignore unknown members.\n options.systemAudio = \"include\";\n options.suppressLocalAudioPlayback = false;\n }\n return options as DisplayMediaStreamOptions;\n};\n\n// Fallback holder for apps whose parameters have no `screenAudioProducer` state.\nconst producersBySocket = new WeakMap<object, Producer>();\n\nexport const rememberScreenAudioProducer = (socket: object | null | undefined, producer: Producer | null): void => {\n if (!socket) return;\n if (producer) producersBySocket.set(socket, producer);\n else producersBySocket.delete(socket);\n};\n\nexport const recallScreenAudioProducer = (socket: object | null | undefined): Producer | null =>\n (socket && producersBySocket.get(socket)) || null;\n\n/** Sets the listening volume (0..1) of every screen-audio player on the page. */\nexport const setScreenAudioVolume = (volume: number, root: ParentNode | null = typeof document !== \"undefined\" ? document : null): void => {\n if (!root) return;\n const value = Math.min(1, Math.max(0, Number.isFinite(volume) ? volume : 1));\n root.querySelectorAll<HTMLAudioElement>('audio[data-screen-audio=\"true\"]').forEach((element) => {\n element.volume = value;\n });\n};\n","import { Transport, CloseAndResizeParameters, CloseAndResizeType } from '../../types/types';\nimport { forgetScreenAudioProducer } from '../screenAudio';\n\nexport interface ProducerClosedParameters extends CloseAndResizeParameters {\n consumerTransports: Transport[];\n screenId?: string;\n updateConsumerTransports: (transports: Transport[]) => void;\n\n // mediasfu functions\n closeAndResize: CloseAndResizeType;\n getUpdatedAllParams: () => ProducerClosedParameters;\n [key: string]: any;\n\n}\n\nexport interface ProducerClosedOptions {\n remoteProducerId: string;\n parameters: ProducerClosedParameters;\n}\n\n// Export the type definition for the function\nexport type ProducerClosedType = (options: ProducerClosedOptions) => Promise<void>;\n\n/**\n * Handles the closure of a producer identified by its remote producer ID.\n * This function will clean up the consumer transports and resize the video outputs.\n *\n * @function\n * @async\n * @param {ProducerClosedOptions} options - The options for closing the producer.\n * @param {string} options.remoteProducerId - The ID of the remote producer to close.\n * @param {ProducerClosedParameters} options.parameters - Additional parameters for the operation.\n * @param {Transport[]} options.parameters.consumerTransports - The list of consumer transports associated with the producer.\n * @param {Function} options.parameters.closeAndResize - Function to handle the closing and resizing of video streams.\n * @param {string} [options.parameters.screenId] - The ID of the screen producer (if applicable).\n * @param {Function} options.parameters.updateConsumerTransports - Function to update the state of consumer transports.\n * @returns {Promise<void>} A promise that resolves when the producer has been successfully closed.\n * @throws Will throw an error if there is an issue closing the consumer transport or the producer.\n *\n * @example\n * import { producerClosed } from 'mediasfu-reactjs';\n * \n * const options = {\n * remoteProducerId: 'producerId',\n * parameters: {\n * consumerTransports: [], // Array of consumer transports\n * closeAndResize: (params) => console.log('Close and resize called', params),\n * screenId: 'screenId',\n * updateConsumerTransports: (transports) => console.log('Updated transports:', transports),\n * },\n * };\n * \n * producerClosed(options)\n * .then(() => {\n * console.log('Producer closed successfully');\n * })\n * .catch((error) => {\n * console.error('Error closing producer:', error);\n * });\n */\nexport const producerClosed = async ({\n remoteProducerId,\n parameters,\n}: ProducerClosedOptions): Promise<void> => {\n let { consumerTransports, closeAndResize, screenId, updateConsumerTransports } = parameters;\n\n forgetScreenAudioProducer(remoteProducerId);\n\n const activeTranslationProducerIds = parameters.activeTranslationProducerIds;\n const isTranslationProducer = activeTranslationProducerIds?.has?.(remoteProducerId);\n\n if (isTranslationProducer) {\n activeTranslationProducerIds?.delete?.(remoteProducerId);\n\n const removeTranslationStream = parameters.removeTranslationStream as ((producerId: string) => void) | undefined;\n\n if (removeTranslationStream) {\n removeTranslationStream(remoteProducerId);\n }\n }\n\n // Handle producer closed\n const producerToClose = consumerTransports.find(\n (transportData: any) => transportData.producerId === remoteProducerId\n );\n\n if (!producerToClose) {\n return;\n }\n\n // Check if the ID of the producer to close is the same as the screenId\n let kind: string = producerToClose.consumer.kind;\n\n if (producerToClose.producerId === screenId) {\n kind = 'screenshare';\n }\n\n try {\n await producerToClose.consumerTransport.close();\n } catch (error) {\n console.error('Error closing consumer transport:', error);\n }\n\n try {\n producerToClose.consumer.close();\n } catch (error) {\n console.error('Error closing consumer:', error);\n }\n\n // Filter out the closed producer\n consumerTransports = consumerTransports.filter(\n (transportData: any) => transportData.producerId !== remoteProducerId\n );\n updateConsumerTransports(consumerTransports);\n\n // Close and resize the videos\n await closeAndResize({ producerId: remoteProducerId, kind, parameters });\n};\n","import { Socket } from \"socket.io-client\";\nimport { validateAlphanumeric } from \"../../methods/utils/validateAlphanumeric\"; // Import the validateAlphanumeric function from the validateAlphanumeric file\nimport type { RtpCapabilities } from \"mediasoup-client/types\";\n\nexport interface JoinConRoomOptions {\n socket: Socket;\n roomName: string;\n islevel: string;\n member: string;\n sec: string;\n apiUserName: string;\n}\n\nexport interface JoinConRoomResponse {\n success: boolean;\n rtpCapabilities: RtpCapabilities | null;\n reason?: string;\n banned?: boolean;\n suspended?: boolean;\n noAdmin?: boolean;\n [key: string]: any;\n}\n\n\n// Export the type definition for the function\nexport type JoinConRoomType = (options: JoinConRoomOptions) => Promise<JoinConRoomResponse>;\n\n/**\n * Joins a conference room using the provided options.\n *\n * @param {JoinConRoomOptions} options - The options for joining the conference room.\n * @param {Socket} options.socket - The socket instance to use for communication.\n * @param {string} options.roomName - The name of the room to join.\n * @param {string} options.islevel - The level of the user.\n * @param {string} options.member - The member identifier.\n * @param {string} options.sec - The security token.\n * @param {string} options.apiUserName - The API username.\n * \n * @returns {Promise<JoinConRoomResponse>} A promise that resolves with the response of the join operation.\n *\n * @example\n * ```typescript\n * const options = {\n * socket: socketInstance,\n * roomName: \"s12345678\",\n * islevel: \"1\",\n * member: \"user123\",\n * sec: \"64CharacterLongSecretHere\",\n * apiUserName: \"user123\",\n * };\n *\n * try {\n * const response = await joinConRoom(options);\n * console.log(\"Room joined:\", response);\n * } catch (error) {\n * console.error(\"Failed to join room:\", error);\n * }\n * ```\n */\n\nexport async function joinConRoom(\n { socket, roomName, islevel, member, sec, apiUserName }: JoinConRoomOptions\n): Promise<JoinConRoomResponse> {\n return new Promise((resolve, reject) => {\n // Validate inputs\n if (!(sec && roomName && islevel && apiUserName && member)) {\n const validationError: JoinConRoomResponse = {\n success: false,\n rtpCapabilities: null,\n reason: \"Missing required parameters\",\n };\n reject(validationError);\n return;\n }\n\n // Validate alphanumeric for roomName, apiUserName, and member\n try {\n validateAlphanumeric({ str: roomName });\n validateAlphanumeric({ str: apiUserName });\n validateAlphanumeric({ str: member });\n } catch {\n const validationError: JoinConRoomResponse = {\n success: false,\n rtpCapabilities: null,\n reason: \"Invalid roomName or apiUserName or member\",\n };\n reject(validationError);\n return;\n }\n\n // Validate roomName starts with 's' or 'p'\n if (!(roomName.startsWith(\"s\") || roomName.startsWith(\"p\") || roomName.startsWith(\"d\"))) {\n const validationError: JoinConRoomResponse = {\n success: false,\n rtpCapabilities: null,\n reason: \"Invalid roomName, must start with s or p or d\",\n };\n reject(validationError);\n return;\n }\n\n // Validate other conditions for sec, roomName, islevel, apiUserName\n if (\n !(\n sec.length === 64 &&\n roomName.length >= 8 &&\n islevel.length === 1 &&\n apiUserName.length >= 6 &&\n (islevel == \"0\" || islevel == \"1\" || islevel == \"2\")\n )\n ) {\n const validationError: JoinConRoomResponse = {\n success: false,\n rtpCapabilities: null,\n reason: \"Invalid roomName or islevel or apiUserName or secret\",\n };\n reject(validationError);\n return;\n }\n\n socket.emit(\n \"joinConRoom\",\n { roomName, islevel, member, sec, apiUserName },\n async (data: JoinConRoomResponse) => {\n try {\n // Check if rtpCapabilities is null\n if (data.rtpCapabilities == null) {\n // Check if banned, suspended, or noAdmin\n if (data.banned) {\n throw new Error(\"User is banned.\");\n }\n if (data.suspended) {\n throw new Error(\"User is suspended.\");\n }\n if (data.noAdmin) {\n throw new Error(\"Host has not joined the room yet.\");\n }\n\n // Resolve with the data received from the 'joinConRoom' event\n resolve(data);\n } else {\n // Handle other cases or perform additional actions\n resolve(data);\n }\n } catch (error) {\n // Handle errors during the joinConRoom process\n console.log(\"Error joining room:\", error);\n reject(error);\n }\n }\n );\n });\n}\n","import { joinConRoom } from '../../producers/producerEmits/joinConRoom';\nimport type { Device, RtpCapabilities } from 'mediasoup-client/types';\nimport { Socket } from 'socket.io-client';\nimport { ReceiveAllPipedTransportsParameters, ReceiveAllPipedTransportsType, CreateDeviceClientType } from '../../types/types';\n\n\nexport interface JoinConsumeRoomParameters extends ReceiveAllPipedTransportsParameters {\n roomName: string;\n islevel: string;\n member: string;\n device: Device | null;\n updateDevice: (device: Device | null) => void;\n\n // Mediasfu functions\n receiveAllPipedTransports: ReceiveAllPipedTransportsType;\n createDeviceClient: CreateDeviceClientType;\n getUpdatedAllParams: () => JoinConsumeRoomParameters;\n [key: string]: any;\n}\nexport interface JoinConsumeRoomOptions {\n remote_sock: Socket;\n apiToken: string;\n apiUserName: string;\n parameters: JoinConsumeRoomParameters;\n}\n\ninterface JoinConsumeRoomResponse {\n success: boolean;\n rtpCapabilities?: RtpCapabilities | null;\n}\n\n// Export the type definition for the function\nexport type JoinConsumeRoomType = (options: JoinConsumeRoomOptions) => Promise<JoinConsumeRoomResponse>;\n\n/**\n * Joins a consumption room by sending a request to the server, handling device setup, and managing piped transports.\n * \n * @function\n * @async\n * @param {Object} options - The configuration options.\n * @param {Socket} options.remote_sock - The remote socket for communication.\n * @param {string} options.apiToken - The API token for authentication.\n * @param {string} options.apiUserName - The API username for authentication.\n * @param {JoinConsumeRoomParameters} options.parameters - Additional parameters including room details and Mediasoup configurations.\n * @returns {Promise<JoinConsumeRoomResponse>} - An object indicating the success of joining the room and optional RTP capabilities.\n * @throws {Error} Throws an error if joining the room or setup fails.\n *\n * @example\n * import { joinConsumeRoom } from 'mediasfu-reactjs';\n * import { io } from 'socket.io-client';\n * \n * const apiToken = 'your-api-token';\n * const apiUserName = 'your-api-username';\n * const remote_sock = io(\"http://localhost:3000\");\n * \n * const parameters = {\n * roomName: 'room-name',\n * islevel: '2',\n * member: 'user-id',\n * device: null,\n * updateDevice: (device) => console.log('Device updated:', device),\n * receiveAllPipedTransports: (params) => console.log('Receiving all piped transports:', params),\n * createDeviceClient: async (params) => { // Device client setup logic },\n * getUpdatedAllParams: () => console.log('Getting updated parameters'),\n * };\n * \n * async function init() {\n * try {\n * const data = await joinConsumeRoom({\n * remote_sock,\n * apiToken,\n * apiUserName,\n * parameters,\n * });\n * console.log('Joined room:', data);\n * } catch (error) {\n * console.error('Error joining room:', error);\n * }\n * }\n * init();\n * // Expected output: { success: true, rtpCapabilities: { ... } }\n */\n\n\nexport const joinConsumeRoom = async ({\n remote_sock,\n apiToken,\n apiUserName,\n parameters,\n}: JoinConsumeRoomOptions): Promise<JoinConsumeRoomResponse> => {\n const {\n roomName,\n islevel,\n member,\n device,\n updateDevice,\n\n // Mediasfu functions\n receiveAllPipedTransports,\n createDeviceClient,\n } = parameters;\n\n try {\n // Join the consumption room\n const data: JoinConsumeRoomResponse = await joinConRoom({ socket: remote_sock, roomName, islevel, member, sec: apiToken, apiUserName });\n\n if (data && data.success) {\n // Setup media device if not already set\n if (!device) {\n if (data.rtpCapabilities) {\n const device_: Device | null = await createDeviceClient({\n rtpCapabilities: data.rtpCapabilities,\n });\n\n if (device_) {\n updateDevice(device_);\n }\n }\n }\n\n // Receive all piped transports\n await receiveAllPipedTransports({ nsock: remote_sock, parameters });\n\n setTimeout(async () => {\n try {\n await receiveAllPipedTransports({ nsock: remote_sock, parameters });\n } catch (error) {\n console.log('[joinConsumeRoom] Retry receiveAllPipedTransports failed:', error);\n }\n }, 30000);\n }\n\n return data;\n } catch (error) {\n console.error('Error in joinConsumeRoom:', error);\n throw new Error('Failed to join the consumption room or set up necessary components.');\n }\n};\n"," \nimport { connectSocket } from \"../sockets/SocketManager\";\nimport { newPipeProducer } from \"./socketReceiveMethods/newPipeProducer\";\nimport { producerClosed } from \"./socketReceiveMethods/producerClosed\";\nimport { joinConsumeRoom } from \"./socketReceiveMethods/joinConsumeRoom\";\nimport { markScreenAudioProducer } from \"./screenAudio\";\nimport { consumerBackupPreferDelay } from \"./consumerBackupPreference\";\nimport { isMediaSocketConnectError } from \"../sockets/mediaSocketErrors\";\nimport type { Device } from 'mediasoup-client/types';\nimport {\n ReorderStreamsParameters, ReorderStreamsType, NewPipeProducerParameters, NewPipeProducerType, ProducerClosedType,\n ProducerClosedParameters, JoinConsumeRoomType, JoinConsumeRoomParameters, ConsumeSocket\n} from '../types/types';\n\nexport interface ConnectIpsParameters extends ReorderStreamsParameters, JoinConsumeRoomParameters, ProducerClosedParameters, NewPipeProducerParameters {\n device: Device | null;\n roomRecvIPs: string[];\n updateRoomRecvIPs: (roomRecvIPs: string[]) => void;\n updateConsume_sockets: (consume_sockets: ConsumeSocket[]) => void;\n\n // mediasfu functions\n reorderStreams: ReorderStreamsType;\n getUpdatedAllParams: () => ConnectIpsParameters;\n [key: string]: any;\n}\n\nexport interface ConnectIpsOptions {\n consume_sockets: ConsumeSocket[];\n remIP: string[];\n apiUserName: string;\n apiKey?: string;\n apiToken: string;\n newProducerMethod?: NewPipeProducerType;\n closedProducerMethod?: ProducerClosedType;\n joinConsumeRoomMethod?: JoinConsumeRoomType;\n parameters: ConnectIpsParameters;\n}\n\n// Export the type definition for the function\nexport type ConnectIpsType = (options: ConnectIpsOptions) => Promise<[Record<string, any>[], string[]]>;\n\n// Scope pending connections to the caller's socket collection. This prevents\n// overlapping room/domain updates from opening the same consume endpoint more\n// than once without sharing sockets between independent room engines.\nconst pendingConsumeConnections = new WeakMap<\n object,\n Map<string, Promise<boolean>>\n>();\n\nconst normalizeConsumeEndpoint = (ip: string): string =>\n ip.trim().toLowerCase().replace(/\\.$/, \"\");\n\n/**\n * Consume endpoints that refused these credentials (`connection-rejected` with a permanent reason). Domain updates call\n * connectIps again and again; without this every update would retry the same refusal. Keyed by the caller's socket\n * collection so another room (new credentials) starts clean.\n */\nexport const CONSUME_REJECTION_COOLDOWN_MS = 60000;\nconst rejectedConsumeEndpoints = new WeakMap<object, Map<string, number>>();\n\nconst consumeEndpointRecentlyRejected = (owner: object, endpoint: string): boolean => {\n const at = rejectedConsumeEndpoints.get(owner)?.get(endpoint);\n return at !== undefined && Date.now() - at < CONSUME_REJECTION_COOLDOWN_MS;\n};\n\nconst rememberConsumeEndpointRejection = (owner: object, endpoint: string): void => {\n let byEndpoint = rejectedConsumeEndpoints.get(owner);\n if (!byEndpoint) {\n byEndpoint = new Map<string, number>();\n rejectedConsumeEndpoints.set(owner, byEndpoint);\n }\n byEndpoint.set(endpoint, Date.now());\n};\n\nconst hasConsumeEndpoint = (\n consumeSockets: ConsumeSocket[],\n endpoint: string\n): boolean => {\n for (let index = consumeSockets.length - 1; index >= 0; index -= 1) {\n const socketObj = consumeSockets[index];\n const ip = Object.keys(socketObj)[0];\n if (!ip || normalizeConsumeEndpoint(ip) !== endpoint) continue;\n\n const socket = socketObj[ip];\n if (socket?.connected && socket.id) return true;\n\n // A dead entry must not suppress the next room's connection attempt.\n socket?.removeAllListeners?.();\n socket?.disconnect?.();\n consumeSockets.splice(index, 1);\n }\n\n return false;\n};\n\nasync function reserveConsumeEndpoint(\n consumeSockets: ConsumeSocket[],\n ip: string,\n reservationOwner: object = consumeSockets\n): Promise<((connected?: boolean) => void) | null> {\n const endpoint = normalizeConsumeEndpoint(ip);\n if (!endpoint || endpoint === \"none\") return null;\n\n let pendingForSockets = pendingConsumeConnections.get(reservationOwner);\n if (!pendingForSockets) {\n pendingForSockets = new Map<string, Promise<boolean>>();\n pendingConsumeConnections.set(reservationOwner, pendingForSockets);\n }\n\n while (true) {\n if (hasConsumeEndpoint(consumeSockets, endpoint)) return null;\n\n const pending = pendingForSockets.get(endpoint);\n if (pending) {\n if (await pending) return null;\n continue;\n }\n\n let resolvePending!: (connected: boolean) => void;\n const reservation = new Promise<boolean>((resolve) => {\n resolvePending = resolve;\n });\n pendingForSockets.set(endpoint, reservation);\n\n return (didConnect = false) => {\n if (pendingForSockets?.get(endpoint) === reservation) {\n pendingForSockets.delete(endpoint);\n if (pendingForSockets.size === 0) {\n pendingConsumeConnections.delete(reservationOwner);\n }\n }\n resolvePending(didConnect === true);\n };\n }\n}\n\n/**\n * Connects to remote IPs and manages socket connections.\n *\n * @param {ConnectIpsOptions} options - The options for connecting IPs.\n * @param {Record<string, any>[]} options.consume_sockets - The array of current socket connections.\n * @param {string[]} options.remIP - The list of remote IPs to connect to.\n * @param {string} options.apiUserName - The API username for authentication.\n * @param {string} [options.apiKey] - The API key for authentication.\n * @param {string} [options.apiToken] - The API token for authentication.\n * @param {Function} [options.newProducerMethod=newPipeProducer] - The method to handle new pipe producer events.\n * @param {Function} [options.closedProducerMethod=producerClosed] - The method to handle producer closed events.\n * @param {Function} [options.joinConsumeRoomMethod=joinConsumeRoom] - The method to handle joining a consuming room.\n * @param {ConnectIpsParameters} options.parameters - Additional parameters.\n * @param {string[]} options.parameters.roomRecvIPs - The list of IPs that have been received in the room.\n * @param {Function} options.parameters.updateRoomRecvIPs - The function to update the room received IPs.\n * @param {Function} options.parameters.updateConsume_sockets - The function to update the consume sockets.\n *\n * @returns {Promise<[Record<string, any>[], string[]]>} A promise that resolves to an array containing the updated consume sockets and room received IPs.\n *\n * @throws Will throw an error if required parameters are missing or if there is an issue connecting to a remote IP.\n * \n * @example\n * const options = {\n * consume_sockets: [],\n * remIP: ['ip1', 'ip2'],\n * apiUserName: 'username',\n * apiKey: 'apikey',\n * apiToken: 'token',\n * parameters: {\n * roomRecvIPs: [],\n * updateRoomRecvIPs: updateRoomRecvIPsFunction,\n * updateConsume_sockets: updateConsumeSocketsFunction,\n * },\n * };\n * \n * connectIps(options)\n * .then(([consume_sockets, roomRecvIPs]) => {\n * console.log('Connected IPs:', consume_sockets);\n * console.log('Room received IPs:', roomRecvIPs);\n * });\n */\n\nexport const connectIps = async ({\n consume_sockets,\n remIP,\n apiUserName,\n apiKey,\n apiToken,\n\n // mediasfu methods\n newProducerMethod = newPipeProducer,\n closedProducerMethod = producerClosed,\n joinConsumeRoomMethod = joinConsumeRoom,\n parameters,\n}: ConnectIpsOptions): Promise<[Record<string, any>[], string[]]> => {\n try {\n const { roomRecvIPs, updateRoomRecvIPs, updateConsume_sockets } = parameters;\n\n if (!consume_sockets || !remIP || !apiUserName || (!apiKey && !apiToken)) {\n console.log(\"Missing required parameters\", {\n consume_sockets,\n remIP,\n apiUserName,\n apiToken,\n });\n return [consume_sockets, roomRecvIPs];\n }\n\n const rejectionOwner: object = parameters?.socket || consume_sockets;\n for (const ip of remIP) {\n if (consumeEndpointRecentlyRejected(rejectionOwner, normalizeConsumeEndpoint(ip))) continue;\n const releaseReservation = await reserveConsumeEndpoint(\n consume_sockets,\n ip,\n parameters?.socket || consume_sockets\n );\n if (!releaseReservation) continue;\n\n let connected = false;\n let remote_sock: Awaited<ReturnType<typeof connectSocket>> | null = null;\n try {\n // Connect to the remote socket using socket.io-client\n remote_sock = await connectSocket({ apiUserName, apiKey, apiToken, link: `https://${ip}.mediasfu.com` });\n\n if (remote_sock.id) {\n let consumeRoomReady = false;\n const pendingProducers: Array<{\n producerId: string;\n islevel: string;\n isTranslation?: boolean;\n translationMeta?: {\n speakerId: string;\n speakerName: string;\n language: string;\n originalProducerId?: string;\n isSpeakerControlled?: boolean;\n };\n }> = [];\n\n // Check if the IP is in the roomRecvIPs, if not, add it\n if (!roomRecvIPs.includes(ip)) {\n roomRecvIPs.push(ip);\n updateRoomRecvIPs(roomRecvIPs);\n }\n\n // Handle new pipe producer event\n const consumeProducer = async ({ producerId, islevel, isTranslation, translationMeta, mediaTag }: { producerId: string; islevel: string; isTranslation?: boolean; translationMeta?: { speakerId: string; speakerName: string; language: string; originalProducerId?: string; isSpeakerControlled?: boolean }; mediaTag?: string }) => {\n // Screen-share audio is tagged by the server; remember it before the consumer resumes.\n markScreenAudioProducer(producerId, mediaTag);\n if (!consumeRoomReady) {\n pendingProducers.push({ producerId, islevel, isTranslation, translationMeta });\n return;\n }\n // A busy node with a connected backup: give the backup's announcement a moment to win (same producer id).\n const preferDelay = isTranslation ? 0 : consumerBackupPreferDelay(\n ip,\n (parameters.getUpdatedAllParams?.() as any)?.consume_sockets as any\n );\n if (preferDelay > 0) {\n await new Promise((resolve) => setTimeout(resolve, preferDelay));\n }\n if (newProducerMethod) {\n await newProducerMethod({\n producerId,\n islevel,\n nsock: remote_sock!,\n parameters,\n isTranslation,\n translationMeta,\n });\n }\n };\n remote_sock.on(\"new-pipe-producer\", consumeProducer);\n\n // Handle producer closed event\n remote_sock.on(\"producer-closed\", async ({ remoteProducerId }: { remoteProducerId: string }) => {\n if (closedProducerMethod) {\n await closedProducerMethod({ remoteProducerId, parameters });\n }\n });\n\n // Handle new consuming room by joining the room\n if (joinConsumeRoomMethod) {\n let data = await joinConsumeRoomMethod({\n remote_sock,\n apiToken,\n apiUserName,\n parameters,\n });\n if (!data.rtpCapabilities) {\n throw new Error(`Consume room ${ip} did not return RTP capabilities.`);\n }\n }\n\n // Events can arrive after the socket connects but before it has\n // joined the consuming room. Emitting transport requests during that\n // window receives no acknowledgement and poisons global de-duplication.\n // The join's producer sweep covers current producers; flushing the\n // queue closes the event/sweep gap, and signal-level de-duplication\n // makes overlap harmless.\n const queuedProducers = pendingProducers.splice(0);\n consumeRoomReady = true;\n for (const producer of queuedProducers) {\n await consumeProducer(producer);\n }\n\n // Add the remote socket to the consume_sockets array\n consume_sockets.push({ [ip]: remote_sock });\n updateConsume_sockets(consume_sockets);\n connected = true;\n\n remote_sock.on(\"disconnect\", () => {\n const socketIndex = consume_sockets.findIndex(\n (socketObj) => socketObj[ip] === remote_sock\n );\n if (socketIndex >= 0) {\n consume_sockets.splice(socketIndex, 1);\n updateConsume_sockets(consume_sockets);\n }\n\n const recvIndex = roomRecvIPs.indexOf(ip);\n if (recvIndex >= 0) {\n roomRecvIPs.splice(recvIndex, 1);\n updateRoomRecvIPs(roomRecvIPs);\n }\n\n remote_sock?.removeAllListeners?.();\n remote_sock?.disconnect();\n });\n }\n } catch (error) {\n if (isMediaSocketConnectError(error) && !error.retryable) {\n rememberConsumeEndpointRejection(rejectionOwner, normalizeConsumeEndpoint(ip));\n console.warn(`connectIps: ${ip} refused this room (${error.reason}); not retrying for ${CONSUME_REJECTION_COOLDOWN_MS / 1000} s.`, error.message);\n } else {\n console.log(\"connectIps error\", error);\n }\n } finally {\n if (!connected && remote_sock) {\n remote_sock.removeAllListeners?.();\n remote_sock.disconnect();\n }\n releaseReservation(connected);\n }\n }\n\n return [consume_sockets, roomRecvIPs];\n } catch (error) {\n // Handle the error\n console.log(\"connectIps error\", error);\n return [consume_sockets, parameters.roomRecvIPs];\n }\n};\n","\nimport { newPipeProducer } from \"./socketReceiveMethods/newPipeProducer\";\nimport { producerClosed } from \"./socketReceiveMethods/producerClosed\";\nimport {\n ReorderStreamsParameters, ReorderStreamsType, NewPipeProducerParameters, NewPipeProducerType, ProducerClosedType,\n ProducerClosedParameters, \n ReceiveAllPipedTransportsParameters,\n ReceiveAllPipedTransportsType} from '../types/types';\nimport { Socket } from \"socket.io-client\";\n\nexport interface ConnectLocalIpsParameters extends ReorderStreamsParameters, ProducerClosedParameters, NewPipeProducerParameters,\nReceiveAllPipedTransportsParameters {\n socket: Socket;\n\n // mediasfu functions\n reorderStreams: ReorderStreamsType;\n receiveAllPipedTransports: ReceiveAllPipedTransportsType;\n getUpdatedAllParams: () => ConnectLocalIpsParameters;\n [key: string]: any;\n}\n\nexport interface ConnectLocalIpsOptions {\n socket: Socket;\n newProducerMethod?: NewPipeProducerType;\n closedProducerMethod?: ProducerClosedType;\n parameters: ConnectLocalIpsParameters;\n}\n\n// Export the type definition for the function\nexport type ConnectLocalIpsType = (options: ConnectLocalIpsOptions) => Promise<void>;\n\n/**\n * Connects to remote IPs and manages socket connections.\n * \n * @param {ConnectLocalIpsOptions} options - The options for connecting IPs.\n * @param {Socket} options.socket - The socket to connect to.\n * @param {Function} [options.newProducerMethod=newPipeProducer] - The method to handle new pipe producer events.\n * @param {Function} [options.closedProducerMethod=producerClosed] - The method to handle producer closed events.\n * @param {ConnectLocalIpsParameters} options.parameters - Additional parameters.\n * @param {Function} options.parameters.reorderStreams - The function to reorder streams.\n * @param {Function} options.parameters.getUpdatedAllParams - The function to get updated parameters.\n * @param {Socket} options.parameters.socket - The socket to connect to.\n * \n * @returns {Promise<void>} A promise that resolves when the connection is established.\n * \n * @throws Will throw an error if required parameters are missing or if there is an issue connecting to a remote IP.\n * \n * @example\n * ```typescript\n * const options = {\n * socket,\n * newProducerMethod: newPipeProducer,\n * closedProducerMethod: producerClosed,\n * parameters: connectLocalIpsParameters,\n * };\n * \n * connectLocalIps(options)\n * .then(() => {\n * console.log('Connected to local IPs');\n * })\n * .catch(error => {\n * console.error('Error connecting to local IPs:', error);\n * });\n * ```\n */ \n\nexport const connectLocalIps = async ({\n socket,\n\n // mediasfu methods\n newProducerMethod = newPipeProducer,\n closedProducerMethod = producerClosed,\n parameters,\n}: ConnectLocalIpsOptions): Promise<void> => {\n try {\n\n // Connect to the remote socket using socket.io-client\n // Handle new pipe producer event\n socket.on(\"new-producer\", async ({ producerId, islevel, isTranslation, translationMeta }: { producerId: string; islevel: string; isTranslation?: boolean; translationMeta?: { speakerId: string; speakerName: string; language: string; originalProducerId?: string } }) => {\n if (newProducerMethod) {\n await newProducerMethod({\n producerId,\n islevel,\n nsock: socket,\n parameters,\n isTranslation,\n translationMeta,\n });\n }\n });\n\n // Handle producer closed event\n socket.on(\"producer-closed\", async ({ remoteProducerId }: { remoteProducerId: string }) => {\n if (closedProducerMethod) {\n await closedProducerMethod({ remoteProducerId, parameters });\n }\n });\n\n await parameters.receiveAllPipedTransports({ nsock: socket, community: true, parameters });\n\n } catch (error) {\n // Handle the error\n console.log(\"ConnectLocalIps error\", error);\n }\n};\n","import { Socket } from \"socket.io-client\";\nimport { ConsumerResumeType, ConsumerResumeParameters, Transport as TransportType, Participant } from \"../types/types\";\nimport type { Consumer, Device, Transport } from \"mediasoup-client/types\";\n\ninterface SpeakerTranslationState {\n speakerId: string;\n speakerName: string;\n inputLanguage: string;\n outputLanguage: string;\n originalProducerId: string;\n enabled: boolean;\n}\n\nconst getSpeakerNameForProducerId = (\n producerId: string,\n parameters: Record<string, any>,\n): string | undefined => {\n const participants = parameters.participants as Participant[] | undefined;\n const participant = participants?.find((candidate) => candidate.audioID === producerId);\n\n if (participant?.name) {\n return participant.name;\n }\n\n const audStreamName = (parameters.audStreamNames as Array<{ producerId?: string; name?: string }> | undefined)\n ?.find((stream) => stream.producerId === producerId && typeof stream.name === 'string');\n if (audStreamName?.name) {\n return audStreamName.name;\n }\n\n return (parameters.allAudioStreams as Array<{ producerId?: string; name?: string }> | undefined)\n ?.find((stream) => stream.producerId === producerId && typeof stream.name === 'string')\n ?.name;\n};\n\nconst isOriginalAudioSuppressedByTranslation = (\n producerId: string,\n parameters: Record<string, any>,\n): boolean => {\n const activeTranslationProducerIds = parameters.activeTranslationProducerIds as Set<string> | undefined;\n if (activeTranslationProducerIds?.has(producerId)) {\n return false;\n }\n\n const speakerTranslationStates = parameters.speakerTranslationStates as\n | Map<string, SpeakerTranslationState>\n | undefined;\n\n if (!speakerTranslationStates?.size) {\n return false;\n }\n\n const speakerName = getSpeakerNameForProducerId(producerId, parameters);\n\n if (speakerName) {\n const speakerState = speakerTranslationStates.get(speakerName);\n if (speakerState?.enabled) {\n return true;\n }\n }\n\n return Array.from(speakerTranslationStates.values()).some((speakerState) => {\n if (!speakerState?.enabled) {\n return false;\n }\n\n if (speakerState.originalProducerId === producerId) {\n return true;\n }\n\n if (!speakerName) {\n return false;\n }\n\n return (\n speakerState.speakerId === speakerName ||\n speakerState.speakerName === speakerName\n );\n });\n};\n\ninterface Params {\n id: string;\n producerId: string;\n kind: string;\n rtpParameters: any;\n serverConsumerId: string;\n error?: string;\n}\n\nexport interface ConnectRecvTransportParameters extends ConsumerResumeParameters {\n device: Device | null;\n consumerTransports: TransportType[];\n updateConsumerTransports: (transports: TransportType[]) => void;\n speakerTranslationStates?: Map<string, SpeakerTranslationState>;\n\n // mediasfu functions\n consumerResume: ConsumerResumeType;\n getUpdatedAllParams: () => ConnectRecvTransportParameters;\n [key: string]: any; // Extendable for additional parameters\n}\nexport interface ConnectRecvTransportOptions {\n consumerTransport: Transport;\n remoteProducerId: string;\n serverConsumerTransportId: string;\n nsock: Socket;\n parameters: ConnectRecvTransportParameters;\n}\n\n// Export the type definition for the function\nexport type ConnectRecvTransportType = (options: ConnectRecvTransportOptions) => Promise<void>;\n\n/**\n * Connects the receiving transport to consume media from a remote producer.\n *\n * @param {ConnectRecvTransportOptions} options - The options for connecting the receiving transport.\n * @param {Transport} options.consumerTransport - The transport used for consuming media.\n * @param {string} options.remoteProducerId - The ID of the remote producer.\n * @param {string} options.serverConsumerTransportId - The ID of the server consumer transport.\n * @param {Socket} options.nsock - The socket used for communication.\n * @param {ConnectRecvTransportParameters} options.parameters - The parameters for the connection.\n *\n * @returns {Promise<void>} A promise that resolves when the connection is established.\n *\n * @throws Will throw an error if the connection or consumption fails.\n *\n * @example\n * ```typescript\n * const options = {\n * consumerTransport,\n * remoteProducerId: 'producer-id',\n * serverConsumerTransportId: 'transport-id',\n * nsock: socket,\n * parameters: connectRecvTransportOptions,\n * };\n * \n * connectRecvTransport(options)\n * .then(() => {\n * console.log('Transport connected and consuming media');\n * })\n * .catch((error) => {\n * console.error('Error connecting transport:', error);\n * });\n * ```\n */\n\nexport const connectRecvTransport = async ({\n consumerTransport,\n remoteProducerId,\n serverConsumerTransportId,\n nsock,\n parameters,\n}: ConnectRecvTransportOptions): Promise<void> => {\n parameters = parameters.getUpdatedAllParams();\n\n const {\n device,\n consumerTransports,\n updateConsumerTransports,\n consumerResume,\n } = parameters;\n\n try {\n // Emit 'consume' event to signal consumption initiation\n nsock.emit(\n \"consume\",\n {\n rtpCapabilities: device!.rtpCapabilities,\n remoteProducerId,\n serverConsumerTransportId,\n },\n async ({ params }: { params: Params }) => {\n if (params.error) {\n // Handle error\n console.log(\"consume error\", params.error);\n return;\n }\n\n try {\n // Consume media using received parameters\n const consumer: Consumer = await consumerTransport.consume({\n id: params.id,\n producerId: params.producerId,\n kind: params.kind as \"audio\" | \"video\",\n rtpParameters: params.rtpParameters,\n });\n\n // Update consumerTransports array with the new consumer\n consumerTransports.push({\n consumerTransport,\n serverConsumerTransportId: params.id,\n producerId: remoteProducerId,\n consumer,\n socket_: nsock,\n });\n\n updateConsumerTransports(consumerTransports);\n\n // Extract track from the consumer\n const { track } = consumer;\n\n // Emit 'consumer-resume' event to signal consumer resumption\n nsock.emit(\n \"consumer-resume\",\n { serverConsumerId: params.serverConsumerId },\n async ({ resumed }: { resumed: boolean }) => {\n if (resumed) {\n // Consumer resumed and ready to be used\n try {\n await consumerResume({\n track,\n kind: params.kind,\n remoteProducerId,\n params,\n parameters,\n nsock,\n consumer,\n });\n\n if (params.kind === 'audio') {\n try {\n const updatedParams = parameters.getUpdatedAllParams();\n if (isOriginalAudioSuppressedByTranslation(remoteProducerId, updatedParams)) {\n consumer.pause();\n nsock.emit(\n 'consumer-pause',\n { serverConsumerId: params.serverConsumerId },\n () => {},\n );\n return;\n }\n } catch {\n }\n }\n } catch (error) {\n // Handle error\n console.log(\"consumerResume error\", error);\n }\n }\n }\n );\n } catch (error) {\n // Handle error\n console.log(\"consume error\", error);\n return;\n }\n }\n );\n } catch (error) {\n // Handle error\n console.log(\"connectRecvTransport error\", error);\n }\n};\n","import type { ProducerOptions } from 'mediasoup-client/types';\nimport { ConnectSendTransportAudioType, ConnectSendTransportVideoType, ConnectSendTransportScreenType, ConnectSendTransportAudioParameters, ConnectSendTransportVideoParameters, ConnectSendTransportScreenParameters } from '../types/types';\nexport interface ConnectSendTransportParameters extends ConnectSendTransportAudioParameters, ConnectSendTransportVideoParameters, ConnectSendTransportScreenParameters {\n audioParams: ProducerOptions \n videoParams: ProducerOptions;\n localStreamScreen: MediaStream | null;\n canvasStream: MediaStream | null;\n whiteboardStarted: boolean;\n whiteboardEnded: boolean;\n shared: boolean;\n islevel: string;\n\n //mediasfu functions\n connectSendTransportAudio: ConnectSendTransportAudioType;\n connectSendTransportVideo: ConnectSendTransportVideoType;\n connectSendTransportScreen: ConnectSendTransportScreenType;\n\n getUpdatedAllParams: () => ConnectSendTransportParameters;\n [key: string]: any;\n}\n\nexport interface ConnectSendTransportOptions {\n option: 'audio' | 'video' | 'screen' | 'all';\n targetOption?: 'local' | 'remote' | 'all';\n parameters: ConnectSendTransportParameters;\n}\n\n// Export the type definition for the function\nexport type ConnectSendTransportType = (options: ConnectSendTransportOptions) => Promise<void>;\n\n/**\n * Connects the send transport based on the specified option.\n *\n * @param {ConnectSendTransportOptions} options - The options for connecting the send transport.\n * @param {string} options.option - The type of transport to connect (\"audio\", \"video\", \"screen\", or \"all\").\n * @param {boolean} options.targetOption - The target option to connect (\"local\", \"remote\", or \"all\").\n * @param {ConnectSendTransportParameters} options.parameters - The parameters required for connecting the transport.\n * @param {ProducerOptions} options.parameters.audioParams - The audio parameters.\n * @param {ProducerOptions} options.parameters.videoParams - The video parameters.\n * @param {MediaStream} options.parameters.localStreamScreen - The local screen stream.\n * @param {MediaStream} options.parameters.canvasStream - The canvas stream.\n * @param {boolean} options.parameters.whiteboardStarted - Indicates if the whiteboard has started.\n * @param {boolean} options.parameters.whiteboardEnded - Indicates if the whiteboard has ended.\n * @param {boolean} options.parameters.shared - Indicates if the screen is shared.\n * @param {string} options.parameters.islevel - The level of the screen sharing.\n * @param {Function} options.parameters.connectSendTransportAudio - Function to connect the audio send transport.\n * @param {Function} options.parameters.connectSendTransportVideo - Function to connect the video send transport.\n * @param {Function} options.parameters.connectSendTransportScreen - Function to connect the screen send transport.\n *\n * @returns {Promise<void>} A promise that resolves when the transport is connected.\n *\n * @throws Will throw an error if the connection fails.\n *\n * @example\n * const options = {\n * option: 'audio',\n * targetOption: 'local',\n * parameters: {\n * audioParams: audioProducerOptions,\n * videoParams: videoProducerOptions,\n * localStreamScreen: localStream,\n * canvasStream: canvasStream,\n * whiteboardStarted: false,\n * whiteboardEnded: false,\n * shared: false,\n * islevel: '1',\n * connectSendTransportAudio: connectAudioFunction,\n * connectSendTransportVideo: connectVideoFunction,\n * connectSendTransportScreen: connectScreenFunction,\n * },\n * };\n * \n * connectSendTransport(options)\n * .then(() => {\n * console.log('Transport connected successfully');\n * })\n * .catch((error) => {\n * console.error('Error connecting transport:', error);\n * });\n */\n\nexport const connectSendTransport = async ({ option, targetOption = \"all\", parameters }: ConnectSendTransportOptions): Promise<void> => {\n try {\n let {\n audioParams,\n videoParams,\n localStreamScreen,\n canvasStream,\n whiteboardStarted,\n whiteboardEnded,\n shared,\n islevel,\n\n //media functions\n connectSendTransportAudio,\n connectSendTransportVideo,\n connectSendTransportScreen,\n } = parameters;\n\n // Connect send transport based on the specified option\n if (option === \"audio\") {\n await connectSendTransportAudio({\n targetOption,\n audioParams,\n parameters,\n });\n } else if (option === \"video\") {\n await connectSendTransportVideo({\n targetOption,\n videoParams,\n parameters,\n });\n } else if (option === \"screen\") {\n if (\n whiteboardStarted &&\n !whiteboardEnded &&\n canvasStream &&\n islevel === \"2\" &&\n !shared\n ) {\n await connectSendTransportScreen({\n targetOption,\n stream: canvasStream,\n parameters,\n });\n } else {\n await connectSendTransportScreen({\n targetOption,\n stream: localStreamScreen!,\n parameters,\n });\n }\n } else {\n // Connect both audio and video send transports\n await connectSendTransportAudio({\n targetOption,\n audioParams,\n parameters,\n });\n await connectSendTransportVideo({\n targetOption,\n videoParams,\n parameters,\n });\n }\n } catch (error) {\n console.log(\"connectSendTransport error\", error);\n // throw error;\n }\n};\n","import type { Transport, Producer, ProducerOptions } from 'mediasoup-client/types';\n\nexport interface ConnectSendTransportAudioParameters {\n audioProducer: Producer | null;\n producerTransport: Transport | null;\n localAudioProducer?: Producer | null;\n localProducerTransport?: Transport | null;\n updateAudioProducer: (producer: Producer | null) => void;\n updateProducerTransport: (transport: Transport | null) => void;\n updateLocalAudioProducer?: (localProducer: Producer | null) => void;\n updateLocalProducerTransport?: (localTransport: Transport | null) => void;\n updateAudioLevel: (level: number) => void;\n\n // Function to get all parameters\n getUpdatedAllParams: () => ConnectSendTransportAudioParameters;\n [key: string]: any; // Extendable for additional parameters\n\n}\n\nexport interface ConnectSendTransportAudioOptions {\n audioParams: ProducerOptions;\n parameters: ConnectSendTransportAudioParameters;\n targetOption?: 'all' | 'local' | 'remote';\n}\n\n// Export the type definition for the function\nexport type ConnectSendTransportAudioType = (options: ConnectSendTransportAudioOptions) => Promise<void>;\n\nconst connectLocalSendTransportAudio = async ({\n parameters,\n audioParams\n}: ConnectSendTransportAudioOptions): Promise<void> => {\n try {\n let {\n localAudioProducer,\n localProducerTransport,\n updateLocalAudioProducer,\n updateLocalProducerTransport,\n } = parameters;\n\n if (localProducerTransport) {\n localAudioProducer = await localProducerTransport.produce(audioParams);\n\n updateLocalAudioProducer?.(localAudioProducer);\n updateLocalProducerTransport?.(localProducerTransport);\n }\n } catch (error) {\n console.error(\"Error connecting local audio transport:\", error);\n throw error; // Re-throw to let the parent handle it\n }\n};\n\nexport const updateMicLevel = async (audioProducer: Producer, updateAudioLevel: (level: number) => void) => {\n try {\n setInterval(() => {\n const sender = audioProducer!.rtpSender;\n\n sender?.getStats().then((stats) => {\n stats.forEach((report) => {\n\n if (report.type === \"media-source\" && report.kind === \"audio\" && report.audioLevel !== undefined) {\n const newLevel = 127.5 + (report.audioLevel * 127.5);\n updateAudioLevel(newLevel);\n }\n\n });\n });\n }, 1000);\n } catch {\n // Handle error\n }\n}\n\n\n/**\n * Connects the send transport for audio by producing audio data and updating the audio producer and producer transport objects.\n *\n * If the primary connection fails, it attempts to connect using the local transport via a separate function.\n *\n * @param {ConnectSendTransportAudioOptions} options - The options for connecting the send transport.\n * @param {ProducerOptions} options.audioParams - The audio parameters.\n * @param {ConnectSendTransportAudioParameters} options.parameters - The parameters required for connecting the transport.\n * @param {Producer | null} options.parameters.audioProducer - The audio producer object.\n * @param {Transport | null} options.parameters.producerTransport - The producer transport object.\n * @param {Producer | null} [options.parameters.localAudioProducer] - The local audio producer object.\n * @param {Transport | null} [options.parameters.localProducerTransport] - The local producer transport object.\n * @param {(producer: Producer | null) => void} options.parameters.updateAudioProducer - The function to update the audio producer object.\n * @param {(transport: Transport | null) => void} options.parameters.updateProducerTransport - The function to update the producer transport object.\n * @param {(localProducer: Producer | null) => void} [options.parameters.updateLocalAudioProducer] - The function to update the local audio producer object.\n * @param {(localTransport: Transport | null) => void} [options.parameters.updateLocalProducerTransport] - The function to update the local producer transport object.\n * @param {(level: number) => void} [options.parameters.updateAudioLevel] - The function to update the audio level.\n * @returns {Promise<void>} A promise that resolves when the connection is established.\n *\n * @example\n * const options = {\n * audioParams: { codec: \"opus\", maxBitrate: 128000 },\n * parameters: {\n * audioProducer: null,\n * producerTransport: transport,\n * localAudioProducer: null,\n * localProducerTransport: localTransport,\n * updateAudioProducer: (producer) => console.log(\"Updated producer:\", producer),\n * updateProducerTransport: (transport) => console.log(\"Updated transport:\", transport),\n * updateLocalAudioProducer: (localProducer) => console.log(\"Updated local producer:\", localProducer),\n * updateLocalProducerTransport: (localTransport) => console.log(\"Updated local transport:\", localTransport),\n * updateAudioLevel: (level) => console.log(\"Updated audio level:\", level),\n * },\n * };\n *\n * connectSendTransportAudio(options)\n * .then(() => console.log(\"Audio transport connected successfully\"))\n * .catch((error) => console.error(\"Error connecting audio transport:\", error));\n */\n\nexport const connectSendTransportAudio: ConnectSendTransportAudioType = async ({\n parameters,\n audioParams,\n targetOption = \"all\",\n}: ConnectSendTransportAudioOptions): Promise<void> => {\n try {\n let {\n audioProducer,\n producerTransport,\n updateAudioProducer,\n updateProducerTransport,\n } = parameters;\n\n // Attempt to connect the primary send transport\n if (targetOption === \"all\" || targetOption === \"remote\") {\n audioProducer = await producerTransport!.produce(audioParams);\n\n // Update the audio level\n updateMicLevel(audioProducer, parameters.updateAudioLevel);\n\n // Update state with the new producer and transport\n updateAudioProducer(audioProducer);\n updateProducerTransport(producerTransport);\n }\n\n // Attempt to connect the local send transport\n if (targetOption === \"all\" || targetOption === \"local\") {\n try {\n await connectLocalSendTransportAudio({ parameters, audioParams });\n\n // Update the audio level\n if (targetOption === \"local\" && parameters.updateAudioLevel) {\n if (!parameters.localAudioProducer) {\n parameters = parameters.getUpdatedAllParams();\n }\n updateMicLevel(parameters.localAudioProducer!, parameters.updateAudioLevel);\n }\n } catch (localError) {\n console.error(\"Local audio transport connection failed:\", localError);\n }\n }\n\n } catch (primaryError) {\n console.error(\"audio transport connection failed:\", primaryError);\n throw new Error(\"Failed to connect to audio transport.\");\n }\n};\n","import type { Transport, Producer, Device, ProducerOptions } from 'mediasoup-client/types';\n\nexport interface ConnectSendTransportScreenParameters {\n screenProducer: Producer | null;\n localScreenProducer?: Producer | null;\n device: Device | null;\n screenParams: ProducerOptions;\n producerTransport: Transport | null;\n localProducerTransport?: Transport | null;\n params: ProducerOptions;\n updateScreenProducer: (producer: Producer | null) => void;\n updateLocalScreenProducer?: (localProducer: Producer | null) => void;\n updateProducerTransport: (transport: Transport | null) => void;\n updateLocalProducerTransport?: (localTransport: Transport | null) => void;\n\n getUpdatedAllParams: () => ConnectSendTransportScreenParameters;\n getCurrentParams?: () => any;\n [key: string]: any; // Extendable for additional parameters\n}\n\nexport interface ConnectSendTransportScreenOptions {\n stream: MediaStream;\n parameters: ConnectSendTransportScreenParameters;\n targetOption?: \"all\" | \"local\" | \"remote\";\n}\n\n// Export the type definition for the function\nexport type ConnectSendTransportScreenType = (options: ConnectSendTransportScreenOptions) => Promise<void>;\n\nconst connectLocalSendTransportScreen = async ({\n stream,\n parameters,\n}: ConnectSendTransportScreenOptions): Promise<void> => {\n try {\n let {\n localScreenProducer,\n localProducerTransport,\n updateLocalScreenProducer,\n updateLocalProducerTransport,\n device,\n } = parameters;\n\n // Find VP9 codec for local screen share\n const codec = device?.rtpCapabilities?.codecs?.find(\n (codec: { mimeType: string }) =>\n codec.mimeType.toLowerCase() === \"video/vp9\"\n );\n\n // Produce local screen share data\n if (localProducerTransport) {\n localScreenProducer = await localProducerTransport.produce({\n track: stream.getVideoTracks()[0],\n codec,\n appData: { mediaTag: \"screen-video\" },\n });\n\n // Update the local producer and transport objects\n updateLocalScreenProducer?.(localScreenProducer);\n updateLocalProducerTransport?.(localProducerTransport);\n } \n } catch (error) {\n console.error(\"Error connecting local screen transport:\", error);\n throw error; // Re-throw to propagate the error\n }\n};\n\n/**\n * Sets up and connects a screen sharing transport for sending video streams.\n *\n * This function supports both a primary and a local screen producer, delegating local handling to a separate function.\n *\n * @param {ConnectSendTransportScreenOptions} options - The configuration options for setting up the screen transport.\n * @param {\"all\" | \"local\" | \"remote\"} [options.targetOption] - The target option for connecting the transport.\n * @param {MediaStream} options.stream - The screen stream to be shared.\n * @param {ConnectSendTransportScreenParameters} options.parameters - The parameters required for setting up the screen transport.\n * @param {Producer | null} options.parameters.screenProducer - The screen producer object to be updated.\n * @param {Device | null} options.parameters.device - The device object for media capabilities.\n * @param {ProducerOptions} options.parameters.screenParams - The parameters for the screen producer.\n * @param {Transport | null} options.parameters.producerTransport - The producer transport object.\n * @param {ProducerOptions} options.parameters.params - The parameters for the producer.\n * @param {Function} options.parameters.updateScreenProducer - The function to update the screen producer object.\n * @param {Function} options.parameters.updateProducerTransport - The function to update the producer transport object.\n * @param {Function} [options.parameters.updateLocalScreenProducer] - The function to update the local screen producer object.\n * @param {Function} [options.parameters.updateLocalProducerTransport] - The function to update the local producer transport object.\n * @param {Function} options.parameters.getUpdatedAllParams - The function to get updated parameters.\n * @param {Object} [options.parameters.*] - Additional parameters for future use.\n * \n * @returns {Promise<void>} - A promise that resolves once the screen transport is successfully connected and set up.\n *\n * @throws Will throw an error if there is an issue with the connection or setup process.\n *\n * @example\n * ```typescript\n * await connectSendTransportScreen({\n * stream: screenStream,\n * targetOption: \"all\",\n * parameters: {\n * screenProducer: null,\n * localScreenProducer: null,\n * device: mediaDevice,\n * screenParams: { encodings: [{ maxBitrate: 1500000 }] },\n * producerTransport: sendTransport,\n * localProducerTransport: localSendTransport,\n * params: { track: screenStream.getVideoTracks()[0] },\n * updateScreenProducer: setScreenProducer,\n * updateLocalScreenProducer: setLocalScreenProducer,\n * updateProducerTransport: setProducerTransport,\n * updateLocalProducerTransport: setLocalProducerTransport,\n * getUpdatedAllParams: getParams,\n * },\n * });\n * ```\n */\n\nexport const connectSendTransportScreen: ConnectSendTransportScreenType = async ({\n stream,\n parameters,\n targetOption = \"all\",\n}: ConnectSendTransportScreenOptions): Promise<void> => {\n try {\n let {\n screenProducer,\n device,\n screenParams,\n producerTransport,\n params,\n updateScreenProducer,\n updateProducerTransport,\n } = parameters;\n\n // Fetch updated device information\n device = parameters.getCurrentParams\n ? parameters.getCurrentParams().device\n : parameters.device;\n\n // Retrieve screen share parameters\n params = screenParams;\n\n // Find VP9 codec for screen share\n const codec = device?.rtpCapabilities?.codecs?.find(\n (codec: { mimeType: string }) =>\n codec.mimeType.toLowerCase() === \"video/vp9\"\n );\n\n // Produce screen share data using the producer transport\n if (targetOption === \"remote\" || targetOption === \"all\") {\n screenProducer = await producerTransport!.produce({\n track: stream.getVideoTracks()[0],\n ...params,\n codec,\n appData: { mediaTag: \"screen-video\" },\n });\n\n // Update the screen producer and producer transport objects\n updateScreenProducer(screenProducer);\n updateProducerTransport(producerTransport);\n }\n\n // Produce screen share data using the local producer transport\n if (targetOption === \"local\" || targetOption === \"all\") {\n try {\n await connectLocalSendTransportScreen({ stream, parameters });\n } catch (localError) {\n console.log(\"Error connecting local screen transport:\", localError);\n }\n }\n\n } catch (error) {\n console.log(\"connectSendTransportScreen error\", error);\n throw error;\n }\n};\n","import type { Device, Producer, ProducerOptions, Transport } from 'mediasoup-client/types';\n\nexport interface ConnectSendTransportVideoParameters {\n videoProducer: Producer | null;\n localVideoProducer?: Producer | null;\n device: Device | null;\n producerTransport: Transport | null;\n localProducerTransport?: Transport | null;\n islevel: string;\n updateMainWindow: boolean;\n updateVideoProducer: (producer: Producer | null) => void;\n updateLocalVideoProducer?: (localProducer: Producer | null) => void;\n updateProducerTransport: (transport: Transport | null) => void;\n updateLocalProducerTransport?: (localTransport: Transport | null) => void;\n updateUpdateMainWindow: (state: boolean) => void;\n [key: string]: any; // Extendable for additional parameters\n}\n\nexport interface ConnectSendTransportVideoOptions {\n videoParams: ProducerOptions;\n parameters: ConnectSendTransportVideoParameters;\n targetOption?: \"all\" | \"local\" | \"remote\";\n}\n\n// Export the type definition for the function\nexport type ConnectSendTransportVideoType = (options: ConnectSendTransportVideoOptions) => Promise<void>;\n\nconst connectLocalSendTransportVideo = async ({\n videoParams,\n parameters,\n}: ConnectSendTransportVideoOptions): Promise<void> => {\n try {\n let {\n localVideoProducer,\n localProducerTransport,\n updateLocalVideoProducer,\n updateLocalProducerTransport,\n } = parameters;\n\n // Produce local video data if transport exists\n if (localProducerTransport) {\n localVideoProducer = await localProducerTransport.produce(videoParams);\n\n // Update local producer and transport\n updateLocalVideoProducer?.(localVideoProducer);\n updateLocalProducerTransport?.(localProducerTransport);\n }\n } catch (error) {\n console.error(\"Error connecting local video transport:\", error);\n throw error; // Re-throw to propagate the error\n }\n};\n\n/**\n * Connects the send transport for video by producing video data and updates the relevant states.\n *\n * This function supports both a primary and a local video producer, delegating local handling to a separate function.\n *\n * @param {ConnectSendTransportVideoOptions} options - The options for connecting the send transport for video.\n * @param {ProducerOptions} options.videoParams - The parameters for the video producer.\n * @param {\"all\" | \"local\" | \"remote\"} [options.targetOption] - The target option for the video transport connection.\n * @param {ConnectSendTransportVideoParameters} options.parameters - The parameters for the video transport connection.\n * @param {Producer | null} options.parameters.videoProducer - The primary video producer.\n * @param {Producer | null} [options.parameters.localVideoProducer] - The local video producer.\n * @param {Device | null} options.parameters.device - The device information.\n * @param {Transport | null} options.parameters.producerTransport - The primary producer transport.\n * @param {Transport | null} [options.parameters.localProducerTransport] - The local producer transport.\n * @param {string} options.parameters.islevel - The connection level for the video transport.\n * @param {boolean} options.parameters.updateMainWindow - The flag to update the main window state.\n * @param {(producer: Producer | null) => void} options.parameters.updateVideoProducer - The function to update the video producer state.\n * @param {(localProducer: Producer | null) => void} [options.parameters.updateLocalVideoProducer] - The function to update the local video producer state.\n * @param {(transport: Transport | null) => void} options.parameters.updateProducerTransport - The function to update the producer transport state.\n * @param {(localTransport: Transport | null) => void} [options.parameters.updateLocalProducerTransport] - The function to update the local producer transport state.\n * @param {(state: boolean) => void} options.parameters.updateUpdateMainWindow - The function to update the main window state.\n * @param {any} [options.parameters] - Additional parameters for future use.\n * @returns {Promise<void>} A promise that resolves when the send transport for video is connected.\n *\n * @throws Will throw an error if the connection fails.\n *\n * @example\n * const options = {\n * videoParams: {\n * // video producer options (e.g., codec, bitrate)\n * },\n * targetOption: \"all\",\n * parameters: {\n * videoProducer: null,\n * localVideoProducer: null,\n * producerTransport: transport,\n * localProducerTransport: localTransport,\n * islevel: '2',\n * updateMainWindow: false,\n * updateVideoProducer: (producer) => console.log(\"Updated producer\"),\n * updateLocalVideoProducer: (localProducer) => console.log(\"Updated local producer\"),\n * updateProducerTransport: (transport) => console.log(\"Updated transport\"),\n * updateLocalProducerTransport: (localTransport) => console.log(\"Updated local transport\"),\n * updateUpdateMainWindow: (state) => console.log(\"Updated main window:\", state),\n * },\n * };\n *\n * connectSendTransportVideo(options)\n * .then(() => console.log(\"Video transport connected successfully\"))\n * .catch((error) => console.error(\"Error connecting video transport:\", error));\n */\n\nexport const connectSendTransportVideo: ConnectSendTransportVideoType = async ({\n videoParams,\n parameters,\n targetOption = \"all\",\n}: ConnectSendTransportVideoOptions): Promise<void> => {\n try {\n let {\n videoProducer,\n producerTransport,\n islevel,\n updateMainWindow,\n updateVideoProducer,\n updateProducerTransport,\n updateUpdateMainWindow,\n } = parameters;\n\n // Produce video data using the primary transport\n if (targetOption === \"all\" || targetOption === \"remote\"){\n videoProducer = await producerTransport!.produce(videoParams);\n\n // Update main window state based on the video connection level\n if (islevel === \"2\") {\n updateMainWindow = true;\n }\n\n // Update video producer, transport, and UI state\n updateVideoProducer(videoProducer);\n updateProducerTransport(producerTransport);\n updateUpdateMainWindow(updateMainWindow);\n }\n\n // Handle local video transport regardless of primary success or \n if (targetOption === \"all\" || targetOption === \"local\") {\n try {\n await connectLocalSendTransportVideo({ videoParams, parameters });\n } catch (localError) {\n console.log(\"Error connecting local video transport:\", localError);\n }\n }\n } catch (error) {\n console.log(\"connectSendTransportVideo error\", error);\n throw error;\n }\n};\n","import type { Device, Transport, DtlsParameters } from 'mediasoup-client/types';\nimport { attachTransportRecovery, clearFailedSendState } from './transportRecovery';\nimport { Socket } from \"socket.io-client\";\nimport {\n ConnectSendTransportParameters,\n ConnectSendTransportType,\n} from \"../types/types\";\n\nexport interface CreateSendTransportParameters extends ConnectSendTransportParameters {\n islevel: string;\n member: string;\n socket: Socket;\n localSocket?: Socket;\n device: Device | null;\n producerTransport: Transport | null;\n localProducerTransport?: Transport | null;\n transportCreated: boolean;\n localTransportCreated?: boolean;\n updateProducerTransport: (producerTransport: Transport | null) => void;\n updateLocalProducerTransport?: (localTransport: Transport | null) => void;\n updateTransportCreated: (transportCreated: boolean) => void;\n updateLocalTransportCreated?: (localTransportCreated: boolean) => void;\n\n // mediasfu functions\n connectSendTransport: ConnectSendTransportType;\n getUpdatedAllParams: () => CreateSendTransportParameters;\n getCurrentParams?: () => any;\n [key: string]: any;\n}\n\nexport interface CreateSendTransportOptions {\n option: \"audio\" | \"video\" | \"screen\" | \"all\";\n parameters: CreateSendTransportParameters;\n}\n\n// Export the type definition for the function\nexport type CreateSendTransportType = (options: CreateSendTransportOptions) => Promise<void>;\n\nconst waitForReadyDevice = async (\n parameters: CreateSendTransportParameters,\n attempts = 20,\n delayMs = 100,\n): Promise<Device | null> => {\n const readDevice = () => parameters.getCurrentParams\n ? parameters.getCurrentParams().device\n : parameters.device;\n let resolvedDevice = readDevice();\n\n for (let attempt = 0; !resolvedDevice && attempt < attempts; attempt += 1) {\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n resolvedDevice = readDevice();\n }\n\n return resolvedDevice;\n};\n\nconst notifyDeviceNotReady = (parameters: CreateSendTransportParameters): void => {\n parameters.showAlert?.({\n message: 'Media device is still initializing. Please try screen sharing again in a moment.',\n type: 'danger',\n duration: 3000,\n });\n};\n\nconst createLocalSendTransport = async ({\n option,\n parameters,\n}: CreateSendTransportOptions): Promise<void> => {\n try {\n let {\n islevel,\n member,\n socket,\n localSocket,\n device,\n localTransportCreated,\n updateLocalProducerTransport,\n updateLocalTransportCreated,\n\n connectSendTransport,\n } = parameters;\n\n const updatedParams = parameters.getCurrentParams?.() ?? parameters;\n device = updatedParams.device;\n socket = updatedParams.socket ?? socket;\n localSocket = updatedParams.localSocket ?? localSocket;\n\n\n if (!localSocket || !localSocket.id || socket.id === localSocket.id) {\n return;\n }\n\n localSocket.emit(\n \"createWebRtcTransport\",\n { consumer: false, islevel },\n async ({ params }: { params: any }) => {\n if (params && params.error) {\n console.error(\"Error in local createWebRtcTransport:\", params.error);\n return;\n }\n\n const resolvedDevice: Device | null = parameters.getCurrentParams\n ? (parameters.getCurrentParams().device as Device | null)\n : (device ?? null);\n if (!resolvedDevice) {\n // The acknowledgement may arrive after teardown. At that point the\n // current bag deliberately has no device; silently abandon it.\n return;\n }\n\n // Create local send transport\n const createdLocalTransport = await resolvedDevice.createSendTransport(params);\n if (updateLocalProducerTransport) {\n updateLocalProducerTransport(createdLocalTransport);\n }\n\n // Handle local transport events\n createdLocalTransport.on(\n \"connect\",\n async ({ dtlsParameters }: { dtlsParameters: DtlsParameters }, callback: () => void, errback: (error: Error) => void) => {\n try {\n localSocket.emit(\"transport-connect\", { dtlsParameters });\n callback();\n } catch (error) {\n errback(error as Error);\n }\n }\n );\n\n createdLocalTransport.on(\n \"produce\",\n async (\n parameters: { kind: string; rtpParameters: any; appData: any },\n callback: (response: { id: string }) => void,\n errback: (error: Error) => void\n ) => {\n try {\n localSocket.emit(\n \"transport-produce\",\n {\n kind: parameters.kind,\n rtpParameters: parameters.rtpParameters,\n appData: parameters.appData,\n islevel,\n name: member,\n },\n ({ id }: { id: string }) => callback({ id })\n );\n } catch (error) {\n errback(error as Error);\n }\n }\n );\n\n attachTransportRecovery(createdLocalTransport, localSocket, () =>\n clearFailedSendState(parameters, createdLocalTransport, true));\n\n // Mark local transport as created\n localTransportCreated = true;\n updateLocalTransportCreated?.(localTransportCreated);\n\n // connect local transport\n await connectSendTransport({\n targetOption: \"local\",\n option,\n parameters: { ...parameters, localProducerTransport: createdLocalTransport },\n });\n }\n );\n } catch (error) {\n console.error(\"Error creating local send transport:\", error);\n }\n};\n\n/**\n * Creates a WebRTC send transport and sets up event handlers for the transport.\n *\n * Supports both primary and local transports with modular handling.\n *\n * @param {CreateSendTransportOptions} options - The options for creating the send transport.\n * @param {string} options.option - The type of transport to create.\n * @param {CreateSendTransportParameters} options.parameters - The parameters required for creating the transport.\n * @param {string} options.parameters.islevel - The level of the transport.\n * @param {string} options.parameters.member - The member name for the transport.\n * @param {Socket} options.parameters.socket - The primary socket instance.\n * @param {Device} options.parameters.device - The device instance.\n * @param {Transport | null} options.parameters.producerTransport - The primary producer transport object.\n * @param {boolean} options.parameters.transportCreated - The state of the primary transport creation.\n * @param {(transport: Transport | null) => void} options.parameters.updateProducerTransport - The function to update the primary transport object.\n * @param {(state: boolean) => void} options.parameters.updateTransportCreated - The function to update the primary transport creation state.\n * @param {Function} options.parameters.connectSendTransport - The function to connect the send transport.\n * @param {Function} options.parameters.getUpdatedAllParams - The function to get updated parameters.\n * @param {Socket} [options.parameters.localSocket] - The local socket instance.\n * @param {Transport | null} [options.parameters.localProducerTransport] - The local producer transport object.\n * @param {boolean} [options.parameters.localTransportCreated] - The state of the local transport creation.\n * @param {(localTransport: Transport | null) => void} [options.parameters.updateLocalProducerTransport] - The function to update the local transport object.\n * @param {(state: boolean) => void} [options.parameters.updateLocalTransportCreated] - The function to update the local transport creation state.\n* @returns {Promise<void>} A promise that resolves when the send transport is created and configured.\n *\n * @throws Will throw an error if there is an issue creating the send transport.\n *\n * @example\n * const options = {\n * option: 'video',\n * parameters: {\n * islevel: '1',\n * member: 'John Doe',\n * socket: socketInstance,\n * localSocket: localSocketInstance,\n * device: deviceInstance,\n * producerTransport: null,\n * localProducerTransport: null,\n * transportCreated: false,\n * localTransportCreated: false,\n * updateProducerTransport: (transport) => console.log('Primary transport updated:', transport),\n * updateLocalProducerTransport: (transport) => console.log('Local transport updated:', transport),\n * updateTransportCreated: (state) => console.log('Primary transport created:', state),\n * updateLocalTransportCreated: (state) => console.log('Local transport created:', state),\n * },\n * };\n *\n * createSendTransport(options)\n * .then(() => console.log('Send transport created successfully'))\n * .catch((error) => console.error('Error creating send transport:', error));\n */\n\nexport const createSendTransport: CreateSendTransportType = async ({\n option,\n parameters,\n}: CreateSendTransportOptions): Promise<void> => {\n try {\n // Destructure parameters\n let {\n islevel,\n member,\n socket,\n device,\n transportCreated,\n updateProducerTransport,\n updateTransportCreated,\n connectSendTransport,\n } = parameters;\n\n // Get updated device and socket parameters\n const updatedParams = parameters.getCurrentParams?.() ?? parameters;\n device = updatedParams.device;\n socket = updatedParams.socket;\n\n if (!device) {\n device = await waitForReadyDevice(parameters);\n }\n\n if (!device) {\n notifyDeviceNotReady(parameters);\n return;\n }\n\n try {\n // Handle local transport creation first\n await createLocalSendTransport({option, parameters});\n } catch (error) {\n console.log(\"Error creating local send transport:\", error);\n }\n\n // Emit createWebRtcTransport event to the server\n socket.emit(\n \"createWebRtcTransport\",\n { consumer: false, islevel: islevel },\n async ({ params }: { params: any }) => {\n // Check if there is an error in the response\n if (params && params.error) {\n console.error(\"Error in createWebRtcTransport:\", params.error);\n return;\n }\n\n const resolvedDevice: Device | null = parameters.getCurrentParams\n ? (parameters.getCurrentParams().device as Device | null)\n : (device ?? null);\n if (!resolvedDevice) {\n // Late acknowledgement after teardown; no transport should survive it.\n return;\n }\n\n // Create a WebRTC send transport\n const createdProducerTransport = await resolvedDevice.createSendTransport(params);\n updateProducerTransport(createdProducerTransport);\n\n // Handle 'connect' event\n createdProducerTransport.on(\n \"connect\",\n async ({ dtlsParameters }: { dtlsParameters: DtlsParameters }, callback: () => void, errback: (error: Error) => void) => {\n try {\n socket.emit(\"transport-connect\", { dtlsParameters });\n callback();\n } catch (error) {\n errback(error as Error);\n }\n }\n );\n\n // Handle 'produce' event\n createdProducerTransport.on(\n \"produce\",\n async (\n parameters: { kind: string; rtpParameters: any; appData: any },\n callback: (response: { id: string }) => void,\n errback: (error: Error) => void\n ) => {\n try {\n socket.emit(\n \"transport-produce\",\n {\n kind: parameters.kind,\n rtpParameters: parameters.rtpParameters,\n appData: parameters.appData,\n islevel: islevel,\n name: member,\n },\n async ({ id }: { id: string }) => {\n callback({ id });\n }\n );\n } catch (error) {\n errback(error as Error);\n }\n }\n );\n\n // Handle 'connectionstatechange' event\n attachTransportRecovery(createdProducerTransport, socket, () =>\n clearFailedSendState(parameters, createdProducerTransport));\n\n // Update transport creation state\n transportCreated = true;\n parameters = parameters.getCurrentParams?.() ?? parameters;\n await connectSendTransport({\n targetOption: \"remote\",\n option,\n parameters: {\n ...parameters,\n producerTransport: createdProducerTransport,\n },\n });\n updateTransportCreated(transportCreated);\n }\n );\n\n } catch (error) {\n console.log(\"Error creating send transport:\", error);\n }\n};\n","import { Socket } from \"socket.io-client\";\nimport { PrepopulateUserMediaType, PrepopulateUserMediaParameters } from \"../types/types\";\nimport type { Producer } from 'mediasoup-client/types';\n\nexport interface DisconnectSendTransportAudioParameters extends PrepopulateUserMediaParameters {\n audioProducer: Producer | null;\n localAudioProducer?: Producer | null;\n socket: Socket;\n localSocket?: Socket;\n videoAlreadyOn: boolean;\n islevel: string;\n lock_screen: boolean;\n shared: boolean;\n updateMainWindow: boolean;\n hostLabel: string;\n roomName: string;\n updateAudioProducer: (audioProducer: Producer | null) => void;\n updateLocalAudioProducer?: (localAudioProducer: Producer | null) => void;\n updateUpdateMainWindow: (updateMainWindow: boolean) => void;\n\n // mediasfu functions\n prepopulateUserMedia: PrepopulateUserMediaType;\n [key: string]: any;\n}\n\nexport interface DisconnectSendTransportAudioOptions {\n parameters: DisconnectSendTransportAudioParameters;\n}\n\n// Export the type definition for the function\nexport type DisconnectSendTransportAudioType = (options: DisconnectSendTransportAudioOptions) => Promise<void>;\n\nconst disconnectLocalSendTransportAudio = async ({\n parameters,\n}: DisconnectSendTransportAudioOptions): Promise<void> => {\n try {\n const {\n localAudioProducer,\n localSocket,\n roomName,\n updateLocalAudioProducer,\n } = parameters;\n\n if (localSocket && localSocket.id) {\n // Close the local audio producer and notify the server\n if (localAudioProducer) {\n localAudioProducer.close(); // Actual logic: pause instead of close for MediaSFU preference\n updateLocalAudioProducer?.(null);\n }\n\n localSocket.emit(\"pauseProducerMedia\", { mediaTag: \"audio\", roomName: roomName });\n } else {\n return;\n }\n } catch (error) {\n console.log(\"Error disconnecting local audio send transport:\", error);\n throw error; // Re-throw to propagate the error\n }\n};\n\n/**\n * Disconnects the send transport for audio by pausing the audio producer and updating the UI accordingly.\n *\n * This function supports both a primary and a local audio producer, delegating local handling to a separate function.\n *\n * @param {DisconnectSendTransportAudioOptions} options - The options for disconnecting the send transport for audio.\n * @param {DisconnectSendTransportAudioParameters} options.parameters - The parameters for disconnecting the send transport for audio.\n * @param {Producer} options.parameters.audioProducer - The primary audio producer to disconnect.\n * @param {Producer} [options.parameters.localAudioProducer] - The local audio producer to disconnect.\n * @param {Socket} options.parameters.socket - The socket instance to use for communication.\n * @param {Socket} [options.parameters.localSocket] - The local socket instance to use for communication.\n * @param {boolean} options.parameters.videoAlreadyOn - Flag indicating if video is already on.\n * @param {string} options.parameters.islevel - The level of the user.\n * @param {boolean} options.parameters.lock_screen - Flag indicating if the screen is locked.\n * @param {boolean} options.parameters.shared - Flag indicating if the screen is shared.\n * @param {boolean} options.parameters.updateMainWindow - Flag to update the main window.\n * @param {string} options.parameters.hostLabel - The label for the host user.\n * @param {string} options.parameters.roomName - The name of the room.\n * @param {function} options.parameters.updateAudioProducer - Function to update the audio producer.\n * @param {function} [options.parameters.updateLocalAudioProducer] - Function to update the local audio producer (optional).\n * @param {function} options.parameters.updateUpdateMainWindow - Function to update the main window state.\n * @param {function} options.parameters.prepopulateUserMedia - Function to prepopulate user media.\n * @param {object} options.parameters - The parameters required for disconnecting the send transport for audio.\n * @returns {Promise<void>} A promise that resolves when the send transport for audio is disconnected.\n *\n * @throws Will throw an error if the operation fails.\n *\n * @example\n * const options = {\n * parameters: {\n * audioProducer: audioProducerInstance,\n * localAudioProducer: localAudioProducerInstance,\n * socket: socketInstance,\n * localSocket: localSocketInstance,\n * videoAlreadyOn: false,\n * islevel: '1',\n * lock_screen: false,\n * shared: false,\n * updateMainWindow: true,\n * hostLabel: 'Host',\n * roomName: 'Room 1',\n * updateAudioProducer: (producer) => console.log('Updated audio producer:', producer),\n * updateLocalAudioProducer: (producer) => console.log('Updated local audio producer:', producer),\n * updateUpdateMainWindow: (state) => console.log('Main window state updated:', state),\n * prepopulateUserMedia: async ({ name, parameters }) => console.log('Prepopulating user media for', name),\n * },\n * };\n *\n * disconnectSendTransportAudio(options)\n * .then(() => console.log(\"Audio send transport disconnected successfully\"))\n * .catch((error) => console.log(\"Error disconnecting audio send transport:\", error));\n */\n\nexport const disconnectSendTransportAudio: DisconnectSendTransportAudioType = async ({\n parameters,\n}: DisconnectSendTransportAudioOptions): Promise<void> => {\n try {\n // Destructure parameters\n let {\n audioProducer,\n socket,\n videoAlreadyOn,\n islevel,\n lock_screen,\n shared,\n updateMainWindow,\n hostLabel,\n roomName,\n updateAudioProducer,\n updateUpdateMainWindow,\n\n //mediasfu functions\n prepopulateUserMedia,\n } = parameters;\n\n // Pause the primary audio producer\n if (audioProducer) {\n audioProducer.pause(); // Actual logic: pause instead of close for MediaSFU preference\n updateAudioProducer(audioProducer);\n }\n\n // Update the UI\n if (!videoAlreadyOn && islevel === \"2\") {\n if (!lock_screen && !shared) {\n updateMainWindow = true;\n updateUpdateMainWindow(updateMainWindow);\n\n await prepopulateUserMedia({ name: hostLabel, parameters });\n\n updateMainWindow = false;\n updateUpdateMainWindow(updateMainWindow);\n }\n }\n\n // Notify the server about pausing audio producer\n socket.emit(\"pauseProducerMedia\", {\n mediaTag: \"audio\",\n roomName: roomName,\n });\n\n // Handle local audio transport\n try {\n await disconnectLocalSendTransportAudio({ parameters });\n } catch (localError) {\n console.log(\"Error disconnecting local audio send transport:\", localError);\n }\n } catch (error) {\n console.log(\"Error disconnecting primary audio send transport:\", error);\n }\n};\n","import type { Producer, Transport } from \"mediasoup-client/types\";\nimport { Socket } from \"socket.io-client\";\nimport {\n SCREEN_AUDIO_CODEC_OPTIONS,\n SCREEN_AUDIO_MEDIA_TAG,\n recallScreenAudioProducer,\n rememberScreenAudioProducer,\n shouldShareScreenAudio,\n} from \"./screenAudio\";\n\nexport interface ScreenAudioParameters {\n socket: Socket;\n producerTransport: Transport | null;\n screenProducer?: Producer | null;\n screenAudioProducer?: Producer | null;\n supportsScreenAudio?: boolean;\n screenAudioEnabled?: boolean;\n updateScreenAudioProducer?: (producer: Producer | null) => void;\n getUpdatedAllParams: () => ScreenAudioParameters;\n [key: string]: any;\n}\n\nexport interface ConnectSendTransportScreenAudioOptions {\n stream: MediaStream;\n parameters: ScreenAudioParameters;\n /** Wait before the single retry when the server has not registered the screen share yet. */\n retryDelayMs?: number;\n}\n\nexport type ConnectSendTransportScreenAudioType = (\n options: ConnectSendTransportScreenAudioOptions\n) => Promise<Producer | null>;\n\nexport interface DisconnectSendTransportScreenAudioOptions {\n parameters: ScreenAudioParameters;\n /** Also tell the server (the screen share continues). Not needed when the whole screen share stops. */\n notifyServer?: boolean;\n}\n\nexport type DisconnectSendTransportScreenAudioType = (\n options: DisconnectSendTransportScreenAudioOptions\n) => Promise<void>;\n\nconst currentScreenAudioProducer = (parameters: ScreenAudioParameters): Producer | null =>\n parameters.screenAudioProducer || recallScreenAudioProducer(parameters.socket);\n\nconst storeScreenAudioProducer = (parameters: ScreenAudioParameters, producer: Producer | null) => {\n rememberScreenAudioProducer(parameters.socket, producer);\n parameters.updateScreenAudioProducer?.(producer);\n};\n\n/**\n * Closes the screen-audio producer, if any. Safe to call when none exists.\n *\n * @example\n * ```typescript\n * await disconnectSendTransportScreenAudio({ parameters, notifyServer: true });\n * ```\n */\nexport const disconnectSendTransportScreenAudio: DisconnectSendTransportScreenAudioType = async ({\n parameters,\n notifyServer = false,\n}) => {\n const params = parameters.getUpdatedAllParams ? parameters.getUpdatedAllParams() : parameters;\n const producer = currentScreenAudioProducer(params);\n if (!producer) return;\n try {\n if (!producer.closed) producer.close();\n } catch {\n // already closed\n }\n storeScreenAudioProducer(params, null);\n if (notifyServer) {\n try {\n params.socket?.emit(\"closeScreenAudioProducer\");\n } catch {\n // the server also closes it with the screen share\n }\n }\n};\n\nexport interface ToggleScreenAudioOptions {\n parameters: ScreenAudioParameters;\n /** Force a state; omitted = toggle. */\n paused?: boolean;\n}\n\n/**\n * Mutes or unmutes the sharer's screen audio without stopping the screen share (listeners hear silence while muted).\n * Returns the new muted state, or null when no screen audio is being shared.\n *\n * @example\n * ```typescript\n * const muted = toggleScreenAudio({ parameters });\n * ```\n */\nexport const toggleScreenAudio = ({ parameters, paused }: ToggleScreenAudioOptions): boolean | null => {\n const params = parameters.getUpdatedAllParams ? parameters.getUpdatedAllParams() : parameters;\n const producer = currentScreenAudioProducer(params);\n if (!producer || producer.closed) return null;\n const next = paused ?? !producer.paused;\n if (next && !producer.paused) producer.pause();\n if (!next && producer.paused) producer.resume();\n params.updateScreenAudioProducer?.(producer);\n return producer.paused;\n};\n\nconst produceOnce = async (transport: Transport, track: MediaStreamTrack): Promise<Producer | null> => {\n const producer = await transport.produce({\n track,\n codecOptions: SCREEN_AUDIO_CODEC_OPTIONS,\n appData: { mediaTag: SCREEN_AUDIO_MEDIA_TAG },\n // The track belongs to the screen share stream, which stops it with the share.\n stopTracks: false,\n });\n // A rejected produce resolves without a server id: drop the local sender.\n if (!producer?.id) {\n try { producer?.close(); } catch { /* nothing to close */ }\n return null;\n }\n return producer;\n};\n\n/**\n * Publishes the audio track of a screen-share stream as a \"screen-audio\" producer on the existing send transport.\n * Call it after the screen video producer exists. It returns null (and the screen share continues without audio)\n * when the stream has no audio, the server does not support screen audio, or the app turned it off.\n *\n * The producer mirrors the screen producer: it pauses, resumes and closes with it, and it closes alone (telling the\n * server) when its own track ends.\n *\n * @example\n * ```typescript\n * const producer = await connectSendTransportScreenAudio({ stream: screenStream, parameters });\n * ```\n */\nexport const connectSendTransportScreenAudio: ConnectSendTransportScreenAudioType = async ({\n stream,\n parameters,\n retryDelayMs = 600,\n}) => {\n const params = parameters.getUpdatedAllParams ? parameters.getUpdatedAllParams() : parameters;\n const track = stream?.getAudioTracks?.()[0];\n if (!track || track.readyState === \"ended\") return null;\n if (!shouldShareScreenAudio(params)) return null;\n const transport = params.producerTransport;\n if (!transport || transport.closed) return null;\n\n const existing = currentScreenAudioProducer(params);\n if (existing && !existing.closed) return existing;\n\n try {\n let producer = await produceOnce(transport, track);\n // The track may have ended while the first attempt was in flight.\n const trackEnded = () => (track.readyState as MediaStreamTrackState) === \"ended\";\n if (!producer && retryDelayMs > 0 && !trackEnded()) {\n await new Promise((resolve) => setTimeout(resolve, retryDelayMs));\n producer = await produceOnce(transport, track);\n }\n if (!producer) return null;\n\n storeScreenAudioProducer(params, producer);\n\n const screenProducer = params.screenProducer;\n if (screenProducer?.paused) producer.pause();\n screenProducer?.observer?.on(\"pause\", () => {\n if (!producer!.closed) producer!.pause();\n });\n screenProducer?.observer?.on(\"resume\", () => {\n if (!producer!.closed) producer!.resume();\n });\n screenProducer?.observer?.on(\"close\", () => {\n void disconnectSendTransportScreenAudio({ parameters: params });\n });\n\n track.addEventListener(\"ended\", () => {\n void disconnectSendTransportScreenAudio({ parameters: params, notifyServer: true });\n });\n return producer;\n } catch (error) {\n console.log(\"connectSendTransportScreenAudio error\", error);\n return null;\n }\n};\n","import type { Producer } from 'mediasoup-client/types';\nimport { Socket } from \"socket.io-client\";\nimport { disconnectSendTransportScreenAudio } from \"./connectSendTransportScreenAudio\";\n\nexport interface DisconnectSendTransportScreenParameters {\n screenProducer: Producer | null;\n socket: Socket;\n localSocket?: Socket;\n roomName: string;\n updateScreenProducer: (screenProducer: Producer | null) => void;\n updateLocalScreenProducer?: (localScreenProducer: Producer | null) => void;\n\n getUpdatedAllParams: () => DisconnectSendTransportScreenParameters;\n [key: string]: any;\n}\nexport interface DisconnectSendTransportScreenOptions {\n parameters: DisconnectSendTransportScreenParameters;\n}\n\n// Export the type definition for the function\nexport type DisconnectSendTransportScreenType = (options: DisconnectSendTransportScreenOptions) => Promise<void>;\n\nconst disconnectLocalSendTransportScreen = async ({ parameters }: DisconnectSendTransportScreenOptions) : Promise<void> => {\n\n try {\n // Destructure parameters\n let {\n localScreenProducer,\n localSocket,\n roomName,\n updateLocalScreenProducer,\n } = parameters;\n\n if (localSocket && localSocket.id) {\n localScreenProducer!.close();\n updateLocalScreenProducer!(localScreenProducer);\n\n // Notify the server about closing the screen producer and pausing screen sharing\n localSocket.emit('closeScreenProducer');\n localSocket.emit('pauseProducerMedia', { mediaTag: 'screen', roomName: roomName });\n }\n } catch {\n console.log('Error disconnecting local send transport for screen');\n }\n\n}\n\n\n/**\n * Disconnects the send transport for screen sharing.\n *\n * This function closes the screen producer, updates the state, and notifies the server\n * about the closure and pausing of screen sharing.\n *\n * @param {DisconnectSendTransportScreenOptions} options - The options for disconnecting the send transport.\n * @param {Object} options.parameters - The parameters required for disconnection.\n * @param {Function} options.parameters.getUpdatedAllParams - Function to get updated parameters.\n * @param {Producer | null} options.parameters.screenProducer - The screen producer to be closed.\n * @param {Socket} options.parameters.socket - The socket connection to notify the server.\n * @param {Socket} [options.parameters.localSocket] - The local socket connection for communication.\n * @param {string} options.parameters.roomName - The name of the room.\n * @param {Function} options.parameters.updateScreenProducer - Function to update the screen producer state.\n * @param {Function} [options.parameters.updateLocalScreenProducer] - Function to update the local screen producer state.\n * @returns {Promise<void>} A promise that resolves when the disconnection process is complete.\n * @throws {Error} If an error occurs during the disconnection process.\n *\n * @example\n * const options = {\n * parameters: {\n * screenProducer: screenProducerInstance,\n * socket: socketInstance,\n * localSocket: localSocketInstance,\n * roomName: 'Room 1',\n * updateScreenProducer: (producer) => console.log('Updated screen producer:', producer),\n * updateLocalScreenProducer: (localProducer) => console.log('Updated local screen producer:', localProducer),\n * getUpdatedAllParams: () => ({\n * screenProducer: screenProducerInstance,\n * socket: socketInstance,\n * roomName: 'Room 1',\n * }),\n * },\n * };\n *\n * disconnectSendTransportScreen(options)\n * .then(() => {\n * console.log('Screen send transport disconnected successfully');\n * })\n * .catch((error) => {\n * console.error('Error disconnecting screen send transport:', error);\n * });\n */\n\nexport const disconnectSendTransportScreen = async ({ parameters }: DisconnectSendTransportScreenOptions) : Promise<void> => {\n\n let { getUpdatedAllParams } = parameters;\n parameters = getUpdatedAllParams()\n\n try {\n // Screen audio stops with the screen share (the server closes its side on closeScreenProducer).\n await disconnectSendTransportScreenAudio({ parameters: parameters as any });\n } catch {\n // nothing to close\n }\n\n try {\n // Destructure parameters\n let {\n screenProducer,\n socket,\n roomName,\n updateScreenProducer,\n } = parameters;\n\n // Close the screen producer and update the state\n screenProducer!.close();\n updateScreenProducer(screenProducer);\n\n // Notify the server about closing the screen producer and pausing screen sharing\n socket.emit('closeScreenProducer');\n socket.emit('pauseProducerMedia', { mediaTag: 'screen', roomName: roomName });\n\n } catch (error) {\n\n // Handle errors during the disconnection process\n if (error instanceof Error) {\n console.log('Error disconnecting send transport for screen:', error.message);\n } else {\n console.log('Error disconnecting send transport for screen:', error);\n }\n }\n\n try {\n // Disconnect the local screen producer\n await disconnectLocalSendTransportScreen({ parameters }); \n } catch {\n // Handle errors during the disconnection process\n }\n};\n","import type { Producer } from 'mediasoup-client/types';\nimport { Socket } from 'socket.io-client';\nimport { ReorderStreamsType, ReorderStreamsParameters } from '../types/types';\n\nexport interface DisconnectSendTransportVideoParameters extends ReorderStreamsParameters {\n videoProducer: Producer | null;\n localVideoProducer?: Producer | null;\n socket: Socket;\n localSocket?: Socket;\n islevel: string;\n roomName: string;\n lock_screen: boolean;\n updateMainWindow: boolean;\n updateUpdateMainWindow: (state: boolean) => void;\n updateVideoProducer: (producer: Producer | null) => void;\n updateLocalVideoProducer?: (producer: Producer | null) => void;\n\n // mediasfu functions\n reorderStreams: ReorderStreamsType;\n [key: string]: any;\n}\n\nexport interface DisconnectSendTransportVideoOptions {\n parameters: DisconnectSendTransportVideoParameters;\n}\n\n// Export the type definition for the function\nexport type DisconnectSendTransportVideoType = (options: DisconnectSendTransportVideoOptions) => Promise<void>;\n\nconst disconnectLocalSendTransportVideo = async ({\n parameters,\n}: DisconnectSendTransportVideoOptions): Promise<void> => {\n try {\n const {\n localVideoProducer,\n localSocket,\n roomName,\n updateLocalVideoProducer,\n } = parameters;\n\n if (localSocket && localSocket.id) {\n // continue\n }else {\n return \n }\n\n // Close the local video producer and notify the server\n if (localVideoProducer) {\n localVideoProducer.close();\n updateLocalVideoProducer?.(null);\n }\n\n \n localSocket.emit('pauseProducerMedia', { mediaTag: 'video', roomName: roomName });\n \n } catch (error) {\n console.error('Error disconnecting local video send transport:', error);\n throw error; // Re-throw to propagate the error\n }\n};\n\n/**\n * Disconnects the send transport for video, closes the video producer, and updates the state.\n *\n * This function supports both a primary and a local video producer, delegating local handling to a separate function.\n *\n * @param {DisconnectSendTransportVideoOptions} options - The options for disconnecting the send transport.\n * @param {DisconnectSendTransportVideoParameters} options.parameters - The parameters required for disconnecting the send transport.\n * @param {Producer | null} options.parameters.videoProducer - The primary video producer object.\n * @param {Producer | null} [options.parameters.localVideoProducer] - The local video producer object (optional).\n * @param {Socket} options.parameters.socket - The primary socket object.\n * @param {Socket} [options.parameters.localSocket] - The local socket object (optional).\n * @param {string} options.parameters.islevel - The participant's level.\n * @param {string} options.parameters.roomName - The name of the room.\n * @param {boolean} options.parameters.updateMainWindow - The flag to update the main window.\n * @param {boolean} options.parameters.lock_screen - The flag to lock the screen.\n * @param {Function} options.parameters.updateUpdateMainWindow - The function to update the main window state.\n * @param {Function} options.parameters.updateVideoProducer - The function to update the video producer state.\n * @param {Function} [options.parameters.updateLocalVideoProducer] - The function to update the local video producer state (optional).\n * @param {ReorderStreamsType} options.parameters.reorderStreams - The function to reorder streams.\n * @param {Function} [options.parameters.updateLocalProducerTransport] - The function to update the local producer transport state (optional).\n * @param {Function} [options.parameters.updateProducerTransport] - The function to update the producer transport state (optional).\n * \n * @returns {Promise<void>} A promise that resolves when the disconnection process is complete.\n * \n * @throws {Error} Throws an error if the disconnection process fails.\n *\n * @example\n * const options = {\n * parameters: {\n * videoProducer: videoProducerInstance,\n * localVideoProducer: localVideoProducerInstance,\n * socket: socketInstance,\n * localSocket: localSocketInstance,\n * islevel: '2',\n * roomName: 'Room A',\n * updateMainWindow: false,\n * lock_screen: false,\n * updateUpdateMainWindow: (state) => console.log('Main window updated:', state),\n * updateVideoProducer: (producer) => console.log('Video producer updated:', producer),\n * updateLocalVideoProducer: (producer) => console.log('Local video producer updated:', producer),\n * reorderStreams: reorderStreamsFunction,\n * },\n * };\n *\n * disconnectSendTransportVideo(options)\n * .then(() => console.log('Video send transport disconnected successfully'))\n * .catch((error) => console.error('Error disconnecting video send transport:', error));\n */\n\nexport const disconnectSendTransportVideo: DisconnectSendTransportVideoType = async ({\n parameters,\n}: DisconnectSendTransportVideoOptions): Promise<void> => {\n try {\n let {\n videoProducer,\n socket,\n islevel,\n roomName,\n updateMainWindow,\n lock_screen,\n updateUpdateMainWindow,\n updateVideoProducer,\n reorderStreams,\n } = parameters;\n\n // Close the primary video producer and notify the server\n if (videoProducer) {\n videoProducer.close();\n updateVideoProducer(null);\n }\n\n socket.emit('pauseProducerMedia', { mediaTag: 'video', roomName: roomName });\n\n // Update the UI based on the participant's level and screen lock status\n if (islevel === '2') {\n updateMainWindow = true;\n updateUpdateMainWindow(updateMainWindow);\n }\n\n if (lock_screen) {\n await reorderStreams({ add: true, screenChanged: true, parameters });\n } else {\n await reorderStreams({ add: false, screenChanged: true, parameters });\n }\n\n // Handle local video transport regardless of primary success or failure\n try {\n await disconnectLocalSendTransportVideo({ parameters });\n } catch (localError) {\n console.error('Error disconnecting local video send transport:', localError);\n }\n } catch (error) {\n // Handle errors during the disconnection process\n if (error instanceof Error) {\n console.log('Error disconnecting send transport for video:', error.message);\n } else {\n console.log('Error disconnecting send transport for video:', error);\n }\n }\n};\n","import {\n Stream, Participant, Transport,\n EventType\n} from \"../types/types\";\n\ninterface DispStreamEntryLike<TMediaStream = MediaStream> {\n producerId?: string | null;\n audioID?: string | null;\n id?: string | null;\n name?: string | null;\n muted?: boolean | null;\n stream?: TMediaStream | null;\n}\n\ninterface DispParticipantLike<TMediaStream = MediaStream> extends DispStreamEntryLike<TMediaStream> {\n name: string;\n islevel?: string | null;\n videoID?: string | null;\n}\n\ntype StreamCollectionUpdater<TEntry> = {\n bivarianceHack: (streams: TEntry[]) => void;\n}[\"bivarianceHack\"];\n\ntype OpaqueAsyncInvoker = {\n bivarianceHack: (options: any) => Promise<any>;\n}[\"bivarianceHack\"];\n\ntype EstimateResult = [unknown, number, number, ...unknown[]];\n\ntype OpaqueEstimateInvoker = {\n bivarianceHack: (options: any) => EstimateResult;\n}[\"bivarianceHack\"];\n\ntype OpaqueCheckGridInvoker = {\n bivarianceHack: (options: any) => Promise<any> | any;\n}[\"bivarianceHack\"];\n\nexport interface DispStreamsParameters<\n TStream extends DispStreamEntryLike<any> = Stream,\n TParticipant extends DispParticipantLike<any> = Participant,\n TTransport = Transport,\n TMediaStream = MediaStream,\n> {\n consumerTransports: TTransport[];\n streamNames: TStream[];\n audStreamNames: TStream[];\n participants: TParticipant[];\n ref_participants: TParticipant[];\n recordingDisplayType: 'video' | 'media' | 'all';\n recordingVideoOptimized: boolean;\n meetingDisplayType: string;\n meetingVideoOptimized: boolean;\n currentUserPage: number;\n hostLabel: string;\n mainHeightWidth: number;\n prevMainHeightWidth: number;\n prevDoPaginate: boolean;\n doPaginate: boolean;\n firstAll: boolean;\n shared: boolean;\n shareScreenStarted: boolean;\n shareEnded: boolean;\n oldAllStreams: (TStream | TParticipant)[];\n updateMainWindow: boolean;\n remoteProducerId?: string;\n activeNames: string[];\n dispActiveNames: string[];\n p_dispActiveNames: string[];\n nForReadjustRecord: number;\n first_round: boolean;\n lock_screen: boolean;\n chatRefStreams: (TStream | TParticipant)[];\n eventType: EventType;\n islevel: string;\n localStreamVideo: TMediaStream | null;\n\n breakOutRoomStarted: boolean;\n breakOutRoomEnded: boolean;\n keepBackground: boolean;\n virtualStream: TMediaStream | null;\n\n updateActiveNames: (names: string[]) => void;\n updateDispActiveNames: (names: string[]) => void;\n updateLStreams: StreamCollectionUpdater<TStream | TParticipant>;\n updateChatRefStreams: StreamCollectionUpdater<TStream | TParticipant>;\n updateNForReadjustRecord: (n: number) => void;\n updateUpdateMainWindow: (value: boolean) => void;\n updateShowMiniView: (value: boolean) => void;\n\n // mediasfu functions\n prepopulateUserMedia: OpaqueAsyncInvoker;\n rePort: OpaqueAsyncInvoker;\n processConsumerTransports: OpaqueAsyncInvoker;\n resumePauseStreams: OpaqueAsyncInvoker;\n readjust: OpaqueAsyncInvoker;\n addVideosGrid: OpaqueAsyncInvoker;\n getEstimate: OpaqueEstimateInvoker;\n checkGrid: OpaqueCheckGridInvoker;\n resumePauseAudioStreams: OpaqueAsyncInvoker;\n\n getUpdatedAllParams: () => DispStreamsParameters<TStream, TParticipant, TTransport, TMediaStream>;\n [key: string]: any;\n}\n\nexport interface DispStreamsOptions<\n TParameters extends DispStreamsParameters<any, any, any, any> = DispStreamsParameters,\n> {\n lStreams: TParameters extends DispStreamsParameters<infer TStream, infer TParticipant, any, any>\n ? (TStream | TParticipant)[]\n : (Stream | Participant)[];\n ind: number;\n auto?: boolean;\n ChatSkip?: boolean;\n forChatCard?: any;\n forChatID?: any;\n parameters: TParameters;\n breakRoom?: number;\n inBreakRoom?: boolean;\n}\n\n// Export the type definition for the function\nexport type DispStreamsType = <\n TParameters extends DispStreamsParameters<any, any, any, any> = DispStreamsParameters,\n>(options: DispStreamsOptions<TParameters>) => Promise<void>;\n\n/**\n * Function to display streams based on various parameters and conditions.\n *\n * @param {DispStreamsOptions} options - The options object.\n * @param {Array} options.lStreams - List of streams to display.\n * @param {number} options.ind - Index of the current stream.\n * @param {boolean} [options.auto=false] - Flag to indicate if the function should run automatically.\n * @param {boolean} [options.ChatSkip=false] - Flag to indicate if chat should be skipped.\n * @param {string|null} [options.forChatID=null] - ID for chat reference.\n * @param {DispStreamsParameters} options.parameters - Parameters object containing various settings and functions.\n * @param {number} [options.breakRoom=-1] - Break room number.\n * @param {boolean} [options.inBreakRoom=false] - Flag to indicate if in break room.\n *\n * @returns {Promise<void>} A promise that resolves when the function completes.\n *\n * @throws Will log an error if an issue occurs during the display of streams.\n *\n * @example\n * const options = {\n * lStreams: [stream1, stream2],\n * ind: 0,\n * auto: true,\n * ChatSkip: false,\n * forChatID: 'chat123',\n * parameters: {\n * consumerTransports: [],\n * streamNames: [],\n * audStreamNames: [],\n * participants: [],\n * ref_participants: [],\n * recordingDisplayType: 'video',\n * recordingVideoOptimized: false,\n * meetingDisplayType: 'video',\n * meetingVideoOptimized: false,\n * currentUserPage: 1,\n * hostLabel: 'Host',\n * mainHeightWidth: 800,\n * prevMainHeightWidth: 600,\n * prevDoPaginate: false,\n * doPaginate: true,\n * firstAll: true,\n * shared: false,\n * shareScreenStarted: false,\n * shareEnded: false,\n * oldAllStreams: [],\n * updateMainWindow: true,\n * remoteProducerId: null,\n * activeNames: [],\n * dispActiveNames: [],\n * p_dispActiveNames: [],\n * nForReadjustRecord: 0,\n * first_round: false,\n * lock_screen: false,\n * chatRefStreams: [],\n * eventType: 'meeting',\n * islevel: '1',\n * localStreamVideo: null,\n * breakOutRoomStarted: false,\n * breakOutRoomEnded: false,\n * keepBackground: false,\n * virtualStream: null,\n * updateActiveNames: (names) => console.log('Updated active names:', names),\n * updateDispActiveNames: (names) => console.log('Updated displayed active names:', names),\n * updateLStreams: (streams) => console.log('Updated limited streams:', streams),\n * updateChatRefStreams: (streams) => console.log('Updated chat reference streams:', streams),\n * updateNForReadjustRecord: (n) => console.log('Updated n for readjustment:', n),\n * updateUpdateMainWindow: (state) => console.log('Main window updated:', state),\n * updateShowMiniView: (value) => console.log('Mini view updated:', value),\n * prepopulateUserMedia: async () => { console.log('your logic')},\n * rePort: async () => { console.log('your logic')},\n * processConsumerTransports: async () => { console.log('your logic')},\n * resumePauseStreams: async () => { console.log('your logic')},\n * readjust: async () => { console.log('your logic')},\n * addVideosGrid: async () => { console.log('your logic')},\n * getEstimate: async () => { console.log('your logic')},\n * checkGrid: async () => { console.log('your logic')},\n * resumePauseAudioStreams: async () => { console.log('your logic')},\n * getUpdatedAllParams: () => { console.log('your logic')},\n * },\n * breakRoom: 1,\n * inBreakRoom: false,\n * };\n * \n * dispStreams(options)\n * .then(() => {\n * console.log('Streams displayed successfully');\n * })\n * .catch((error) => {\n * console.error('Error displaying streams:', error);\n * });\n */\n\nexport async function dispStreams<\n TParameters extends DispStreamsParameters<any, any, any, any> = DispStreamsParameters,\n>({\n lStreams,\n ind,\n auto = false,\n ChatSkip = false,\n forChatID = null,\n parameters,\n breakRoom = -1,\n inBreakRoom = false,\n}: DispStreamsOptions<TParameters>): Promise<void> {\n // Function to display streams\n\n const { getUpdatedAllParams } = parameters;\n const updatedParameters = getUpdatedAllParams() as TParameters;\n parameters = updatedParameters;\n\n let {\n consumerTransports,\n streamNames,\n audStreamNames,\n participants,\n ref_participants,\n recordingDisplayType,\n recordingVideoOptimized,\n meetingDisplayType,\n meetingVideoOptimized,\n currentUserPage,\n hostLabel,\n mainHeightWidth,\n prevMainHeightWidth,\n prevDoPaginate,\n doPaginate,\n firstAll,\n shared,\n shareScreenStarted,\n shareEnded,\n oldAllStreams,\n updateMainWindow,\n remoteProducerId,\n activeNames,\n dispActiveNames,\n p_dispActiveNames,\n nForReadjustRecord,\n first_round,\n lock_screen,\n chatRefStreams,\n eventType,\n islevel,\n localStreamVideo,\n\n breakOutRoomStarted,\n breakOutRoomEnded,\n keepBackground,\n virtualStream,\n\n updateActiveNames,\n updateDispActiveNames,\n updateLStreams,\n updateChatRefStreams,\n updateNForReadjustRecord,\n updateUpdateMainWindow,\n updateShowMiniView,\n\n prepopulateUserMedia,\n rePort,\n processConsumerTransports,\n resumePauseStreams,\n readjust,\n addVideosGrid,\n checkGrid,\n getEstimate,\n resumePauseAudioStreams,\n } = parameters;\n\n let proceed = true;\n\n let lStreams_ = lStreams.filter((stream) => stream.producerId !== \"youyou\" && stream.producerId !== \"youyouyou\");\n\n lStreams_ = lStreams_.filter((stream) => stream.id !== \"youyou\" && stream.id !== \"youyouyou\" && stream.name !== \"youyou\" && stream.name !== \"youyouyou\");\n\n if (eventType === \"chat\") {\n proceed = true;\n } else if (ind === 0 || (islevel !== \"2\" && currentUserPage === ind)) {\n proceed = false;\n\n //get the name of every participant in lStreams if stream !null and assign it to activeNames\n lStreams_.forEach((stream) => {\n let checker = false;\n let check_level = 0;\n\n if (recordingDisplayType === \"video\") {\n if (recordingVideoOptimized) {\n if (Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") {\n checker = true;\n check_level = 0;\n }\n } else {\n if ((Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") ||\n (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream.audioID != null &&\n stream.audioID !== \"\")) {\n checker = true;\n check_level = 1;\n }\n }\n } else if (recordingDisplayType === \"media\") {\n if ((Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") ||\n (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream.audioID != null &&\n stream.audioID !== \"\")) {\n checker = true;\n check_level = 1;\n }\n } else {\n if ((Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") ||\n (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream.audioID != null &&\n stream.audioID !== \"\") ||\n (Object.prototype.hasOwnProperty.call(stream, \"name\") &&\n stream.name !== null &&\n stream.name != \"\")) {\n checker = true;\n check_level = 2;\n }\n }\n\n let participant;\n\n if (checker) {\n // find the participant with the same videoID as the stream\n if (check_level == 0) {\n if (Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") {\n participant = streamNames.find(\n (obj) => obj.producerId === stream.producerId\n );\n }\n } else if (check_level == 1) {\n // find for either producerId or name\n if (Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") {\n participant = streamNames.find(\n (obj) => obj.producerId === stream.producerId\n );\n }\n if (!participant) {\n if (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream.audioID != null &&\n stream.audioID !== \"\") {\n participant = audStreamNames.find(\n (obj) => obj.producerId === stream.audioID\n );\n if (!participant) {\n participant = ref_participants.find(\n (obj) => obj.audioID === stream.audioID\n );\n }\n }\n }\n } else if (check_level == 2) {\n if (Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") {\n participant = streamNames.find(\n (obj) => obj.producerId === stream.producerId\n );\n }\n if (!participant) {\n if (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream.audioID != null &&\n stream.audioID !== \"\") {\n participant = audStreamNames.find(\n (obj) => obj.producerId === stream.audioID\n );\n if (!participant) {\n participant = ref_participants.find(\n (obj) => obj.audioID === stream.audioID\n );\n }\n }\n }\n if (!participant) {\n if (Object.prototype.hasOwnProperty.call(stream, \"name\") &&\n stream.name !== null &&\n stream.name != \"\") {\n participant = ref_participants.find(\n (obj) => obj.name === stream.name\n );\n }\n }\n }\n\n // push the name of the participant to activeNames\n if (participant) {\n // if activeNames does not include the name of the participant, push it\n if (participant.name && !activeNames.includes(participant.name)) {\n activeNames.push(participant.name);\n }\n }\n }\n });\n\n updateActiveNames(activeNames);\n\n lStreams_.forEach((stream) => {\n let disp_checker = false;\n let disp_check_level = 0;\n\n if (meetingDisplayType == \"video\") {\n if (meetingVideoOptimized) {\n if (Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") {\n disp_checker = true;\n disp_check_level = 0;\n }\n } else {\n if ((Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") ||\n (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream.audioID != null &&\n stream.audioID !== \"\")) {\n disp_checker = true;\n disp_check_level = 1;\n }\n }\n } else if (meetingDisplayType == \"media\") {\n if ((Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") ||\n (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream.audioID != null &&\n stream.audioID !== \"\")) {\n disp_checker = true;\n disp_check_level = 1;\n }\n } else {\n if ((Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") ||\n (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream.audioID != null &&\n stream.audioID !== \"\") ||\n (Object.prototype.hasOwnProperty.call(stream, \"name\") &&\n stream.name !== null &&\n stream.name != \"\")) {\n disp_checker = true;\n disp_check_level = 2;\n }\n }\n\n let participant_;\n\n if (disp_checker) {\n if (disp_check_level == 0) {\n if (Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") {\n participant_ = streamNames.find(\n (obj) => obj.producerId === stream.producerId\n );\n }\n } else if (disp_check_level == 1) {\n // find for either producerId or name\n if (Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") {\n participant_ = streamNames.find(\n (obj) => obj.producerId === stream.producerId\n );\n }\n if (!participant_) {\n if (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream.audioID != null &&\n stream.audioID !== \"\") {\n participant_ = audStreamNames.find(\n (obj) => obj.producerId === stream.audioID\n );\n if (!participant_) {\n participant_ = ref_participants.find(\n (obj) => obj.audioID === stream.audioID\n );\n }\n }\n }\n } else if (disp_check_level == 2) {\n if (Object.prototype.hasOwnProperty.call(stream, \"producerId\") &&\n stream.producerId != null &&\n stream.producerId !== \"\") {\n participant_ = streamNames.find(\n (obj) => obj.producerId === stream.producerId\n );\n }\n if (!participant_) {\n if (Object.prototype.hasOwnProperty.call(stream, \"audioID\") &&\n stream.audioID != null &&\n stream.audioID !== \"\") {\n participant_ = audStreamNames.find(\n (obj) => obj.producerId === stream.audioID\n );\n if (!participant_) {\n participant_ = ref_participants.find(\n (obj) => obj.audioID === stream.audioID\n );\n }\n }\n }\n if (!participant_) {\n if (Object.prototype.hasOwnProperty.call(stream, \"name\") &&\n stream.name !== null &&\n stream.name != \"\") {\n participant_ = ref_participants.find(\n (obj) => obj.name === stream.name\n );\n }\n }\n }\n }\n\n // push the name of the participant to activeNames\n if (participant_) {\n // if dispActiveNames does not include the name of the participant, push it\n if (participant_.name && !dispActiveNames.includes(participant_.name)) {\n dispActiveNames.push(participant_.name);\n if (!p_dispActiveNames.includes(participant_.name)) {\n proceed = true;\n }\n }\n }\n });\n\n updateDispActiveNames(dispActiveNames);\n\n if (lStreams_.length < 1 && (shareScreenStarted || shared || !firstAll)) {\n proceed = true;\n }\n\n if (shareScreenStarted || shared) {\n // Additional logic\n } else {\n if (prevMainHeightWidth !== mainHeightWidth) {\n updateMainWindow = true;\n updateUpdateMainWindow(updateMainWindow);\n }\n }\n\n nForReadjustRecord = activeNames.length;\n updateNForReadjustRecord(nForReadjustRecord);\n }\n\n if (!proceed && auto) {\n if (updateMainWindow && !lock_screen && !shared) {\n await prepopulateUserMedia({ name: hostLabel, parameters });\n } else if (!first_round) {\n await prepopulateUserMedia({ name: hostLabel, parameters });\n }\n\n if (ind === 0 && eventType !== \"chat\") {\n await rePort({ parameters });\n }\n return;\n }\n\n if (eventType == \"broadcast\") {\n lStreams = lStreams_ as typeof lStreams;\n updateLStreams(lStreams);\n } else if (eventType == \"chat\") {\n if (forChatID != null) {\n lStreams = chatRefStreams as typeof lStreams;\n updateLStreams(lStreams);\n } else {\n updateShowMiniView(false);\n\n if (islevel != \"2\") {\n let host = participants.find((obj) => {\n return obj.islevel === \"2\";\n });\n\n if (host) {\n let streame;\n\n remoteProducerId = host.videoID as string;\n // get the stream from allvideostream with the same id as remoteProducerId\n\n if (islevel == \"2\") {\n host.stream =\n keepBackground && virtualStream\n ? virtualStream\n : localStreamVideo;\n } else {\n streame = oldAllStreams.find(\n (streame) => streame.producerId == remoteProducerId\n );\n // add streame to lStreams\n if (streame) {\n //remove any stream with name of host.name\n lStreams = lStreams.filter((stream) => {\n return stream.name != host.name;\n }) as typeof lStreams;\n\n lStreams.push(streame);\n }\n }\n }\n }\n\n //remove youyou and youyouyou from lStreams and then put it at the end\n let youyou = lStreams.find((obj) => {\n return obj.producerId === \"youyou\" || obj.producerId === \"youyouyou\";\n });\n\n lStreams = lStreams.filter((stream) => {\n return (\n stream.producerId != \"youyou\" && stream.producerId != \"youyouyou\"\n );\n }) as typeof lStreams;\n\n if (youyou) {\n lStreams.push(youyou);\n }\n\n chatRefStreams = lStreams;\n\n updateLStreams(lStreams);\n updateChatRefStreams(chatRefStreams);\n }\n }\n\n let refLength = lStreams.length;\n\n const [, rows, cols] = getEstimate({ n: refLength, parameters });\n let result = await checkGrid({ rows, cols, actives: refLength }) || [false, 0, 0, 0, 0, 0, 0];\n let [removeAltGrid, numtoaddd, numRows, numCols, , actualRows, lastrowcols] = result;\n\n if (ChatSkip && eventType === \"chat\") {\n numRows = 1;\n numCols = 1;\n actualRows = 1;\n }\n\n await readjust({ n: lStreams.length, state: ind, parameters });\n\n let mainGridStreams = lStreams.slice(0, numtoaddd);\n let altGridStreams = lStreams.slice(numtoaddd);\n\n if (doPaginate || prevDoPaginate !== doPaginate || shared || shareScreenStarted || shareEnded) {\n let lStreams_alt = lStreams_;\n await processConsumerTransports({ consumerTransports, lStreams_: lStreams_alt, parameters });\n\n\n try {\n if (breakOutRoomStarted && !breakOutRoomEnded) {\n await resumePauseAudioStreams({ inBreakRoom, breakRoom, parameters });\n } else {\n await resumePauseStreams({ parameters });\n }\n } catch {\n // console.log('Error in resumePauseAudioStreams:', error);\n }\n\n try {\n if (!breakOutRoomStarted || (breakOutRoomStarted && breakOutRoomEnded)) {\n await resumePauseStreams({ parameters });\n }\n } catch { \n // console.log('Error in resumePauseStreams:', error\n }\n\n if (shareEnded) {\n shareEnded = false;\n }\n }\n\n if (ChatSkip && eventType === \"chat\") {\n await addVideosGrid({\n mainGridStreams,\n altGridStreams,\n numtoadd: numtoaddd - 1,\n numRows,\n numCols,\n actualRows,\n lastrowcols,\n removeAltGrid,\n parameters,\n });\n } else {\n await addVideosGrid({\n mainGridStreams,\n altGridStreams,\n numtoadd: numtoaddd,\n numRows,\n numCols,\n actualRows,\n lastrowcols,\n removeAltGrid,\n parameters,\n });\n }\n\n if (updateMainWindow && !lock_screen && !shared) {\n await prepopulateUserMedia({ name: hostLabel, parameters });\n } else if (!first_round) {\n await prepopulateUserMedia({ name: hostLabel, parameters });\n }\n\n if (ind === 0 && eventType !== \"chat\") {\n await rePort({ parameters });\n }\n}\n","import { Participant, Stream, DispStreamsParameters } from '../types/types';\n\ntype OpaqueDispStreamsInvoker = {\n bivarianceHack: (options: any) => Promise<void>;\n}['bivarianceHack'];\n\nexport interface GeneratePageContentParameters<\n TStream extends Stream = Stream,\n TParticipant extends Participant = Participant,\n TDispParameters extends DispStreamsParameters<any, any, any, any> = DispStreamsParameters<TStream, TParticipant>,\n> extends DispStreamsParameters<TStream, TParticipant> {\n paginatedStreams: (TParticipant | TStream)[][];\n currentUserPage: number;\n updateMainWindow: boolean;\n updateCurrentUserPage: (page: number) => void;\n updateUpdateMainWindow: (flag: boolean) => void;\n\n // mediasfu functions\n dispStreams: OpaqueDispStreamsInvoker;\n getUpdatedAllParams: () => GeneratePageContentParameters<TStream, TParticipant, TDispParameters>;\n [key: string]: any;\n}\n\nexport interface GeneratePageContentOptions<\n TParameters extends GeneratePageContentParameters<any, any, any> = GeneratePageContentParameters,\n> {\n page: number | string;\n parameters: TParameters;\n breakRoom?: number;\n inBreakRoom?: boolean;\n}\n\n// Export the type definition for the function\nexport type GeneratePageContentType = <\n TParameters extends GeneratePageContentParameters<any, any, any> = GeneratePageContentParameters,\n>(options: GeneratePageContentOptions<TParameters>) => Promise<void>;\n\n/**\n * Generates the content for a specific page.\n *\n * @param {GeneratePageContentOptions} options - The options for generating page content.\n * @param {number | string} options.page - The page number to generate content for.\n * @param {GeneratePageContentParameters} options.parameters - The parameters required for generating content.\n * @param {Array} options.parameters.paginatedStreams - The streams to be paginated.\n * @param {number} options.parameters.currentUserPage - The current page of the user.\n * @param {Function} options.parameters.updateMainWindow - Function to update the main window flag.\n * @param {Function} options.parameters.updateCurrentUserPage - Function to update the current user page.\n * @param {Function} options.parameters.updateUpdateMainWindow - Function to update the main window update flag.\n * @param {Function} options.parameters.dispStreams - Function to display streams for the specified page.\n * @param {number} [options.breakRoom=-1] - The break room identifier.\n * @param {boolean} [options.inBreakRoom=false] - Flag indicating if the user is in a break room.\n * \n * @returns {Promise<void>} A promise that resolves when the content generation is complete.\n * \n * @throws {Error} Throws an error if content generation fails.\n * \n * @example\n * const options = {\n * page: 1,\n * parameters: {\n * paginatedStreams: [[stream1, stream2], [stream3, stream4]], // Example paginated streams\n * currentUserPage: 0,\n * updateMainWindow: true,\n * updateCurrentUserPage: (page) => console.log('Current user page updated to:', page),\n * updateUpdateMainWindow: (flag) => console.log('Main window update flag:', flag),\n * dispStreams: async ({ lStreams, ind }) => {\n * console.log(`Displaying streams for page ${ind}:`, lStreams);\n * },\n * },\n * breakRoom: 1,\n * inBreakRoom: false,\n * };\n * \n * generatePageContent(options)\n * .then(() => {\n * console.log('Page content generated successfully');\n * })\n * .catch((error) => {\n * console.error('Error generating page content:', error);\n * });\n */\n\nexport async function generatePageContent<\n TParameters extends GeneratePageContentParameters<any, any, any> = GeneratePageContentParameters,\n>({\n page,\n parameters,\n breakRoom = -1,\n inBreakRoom = false,\n}: GeneratePageContentOptions<TParameters>): Promise<void> {\n try {\n // Destructure parameters\n let {\n paginatedStreams,\n currentUserPage,\n updateMainWindow,\n\n updateCurrentUserPage,\n updateUpdateMainWindow,\n\n //mediasfu functions\n dispStreams,\n } = parameters;\n\n // Convert page to an integer\n page = typeof page === \"string\" ? parseInt(page) : page;\n\n // Update current user page\n currentUserPage = page;\n updateCurrentUserPage(currentUserPage);\n\n // Update main window flag\n updateMainWindow = true;\n updateUpdateMainWindow(updateMainWindow);\n\n // Display streams for the specified page\n await dispStreams({\n lStreams: paginatedStreams[page],\n ind: page,\n parameters,\n breakRoom,\n inBreakRoom,\n });\n } catch (error) {\n // Handle errors during content generation\n if (error instanceof Error) {\n console.log(\"Error generating page content:\", error.message);\n } else {\n console.log(\"Error generating page content:\", error);\n }\n }\n}\n","import { Stream, Participant } from \"../types/types\";\nexport interface GetVideosOptions {\n participants: Participant[];\n allVideoStreams: (Stream | Participant)[];\n oldAllStreams: (Stream | Participant)[];\n adminVidID?: string;\n updateAllVideoStreams: (streams: (Stream | Participant)[]) => void;\n updateOldAllStreams: (streams: (Stream | Participant)[]) => void;\n}\n\n// Export the type definition for the function\nexport type GetVideosType = (options: GetVideosOptions) => Promise<void>;\n\n\n/**\n * Asynchronously processes and updates video streams by filtering out the admin's video stream.\n *\n * @param {GetVideosOptions} options - The options for getting videos.\n * @param {Participant[]} options.participants - The list of participants.\n * @param {(Stream | Participant)[]} options.allVideoStreams - The list of all video streams.\n * @param {(Stream | Participant)[]} options.oldAllStreams - The list of old video streams.\n * @param {string} [options.adminVidID] - The ID of the admin's video stream.\n * @param {Function} options.updateAllVideoStreams - Function to update the state variable for all video streams.\n * @param {Function} options.updateOldAllStreams - Function to update the state variable for old video streams.\n *\n * @returns {Promise<void>} A promise that resolves when the video streams have been processed and updated.\n *\n * @throws {Error} Throws an error if an issue occurs while processing the streams.\n *\n * @example\n * const options = {\n * participants: participantList,\n * allVideoStreams: allStreams,\n * oldAllStreams: oldStreams,\n * adminVidID: 'admin-video-id',\n * updateAllVideoStreams: (streams) => {\n * console.log('All video streams updated:', streams);\n * },\n * updateOldAllStreams: (streams) => {\n * console.log('Old video streams updated:', streams);\n * },\n * };\n *\n * getVideos(options)\n * .then(() => {\n * console.log('Video streams processed successfully');\n * })\n * .catch((error) => {\n * console.error('Error processing video streams:', error);\n * });\n */\n\nexport async function getVideos({\n participants,\n allVideoStreams,\n oldAllStreams,\n adminVidID,\n updateAllVideoStreams,\n updateOldAllStreams,\n}: GetVideosOptions): Promise<void> {\n\n try {\n\n // Filter out the admin's video stream and update state variables\n let admin = participants.filter(\n (participant) => participant.islevel === \"2\"\n );\n\n if (admin.length > 0) {\n adminVidID = admin[0].videoID;\n\n if (adminVidID != null && adminVidID !== \"\") {\n let oldAllStreams_: (Stream | Participant)[] = [];\n\n // Check if the length of oldAllStreams is greater than 0\n if (oldAllStreams.length > 0) {\n oldAllStreams_ = oldAllStreams;\n }\n\n // Filter out admin's video stream from oldAllStreams\n oldAllStreams = allVideoStreams.filter(\n (streame) => streame.producerId === adminVidID\n );\n\n // If no admin's video stream found, revert to the previous state\n if (oldAllStreams.length < 1) {\n oldAllStreams = oldAllStreams_;\n }\n\n // Update the state variable for old video streams\n updateOldAllStreams(oldAllStreams);\n\n // Filter out admin's video stream from allVideoStreams\n allVideoStreams = allVideoStreams.filter(\n (streame) => streame.producerId !== adminVidID\n );\n\n // Update the state variable for all video streams\n updateAllVideoStreams(allVideoStreams);\n }\n }\n } catch (error) {\n // Handle errors during the process of updating video streams\n console.log(\"Error updating video streams:\", (error as Error).message);\n // throw error;\n }\n}\n","import { Stream, Participant } from \"../types/types\";\n\ninterface MixStreamLike {\n producerId?: string | null;\n muted?: boolean | null;\n}\n\ninterface MixParticipantLike {\n videoID?: string | null;\n muted?: boolean | null;\n}\n\nconst getProducerId = (value: unknown): string | null | undefined => {\n return (value as MixStreamLike | null | undefined)?.producerId;\n};\n\nconst getVideoId = (value: unknown): string | null | undefined => {\n return (value as MixParticipantLike | null | undefined)?.videoID;\n};\n\nconst getMuted = (value: unknown): boolean | null | undefined => {\n return (value as (MixStreamLike & MixParticipantLike) | null | undefined)?.muted;\n};\n\nexport interface MixStreamsOptions<\n TStream extends MixStreamLike = Stream,\n TParticipant extends MixParticipantLike = Participant,\n> {\n alVideoStreams: (TStream | TParticipant)[];\n non_alVideoStreams: TParticipant[];\n ref_participants: (TStream | TParticipant)[];\n}\n\n// Export the type definition for the function\nexport type MixStreamsType = <\n TStream extends MixStreamLike = Stream,\n TParticipant extends MixParticipantLike = Participant,\n>(options: MixStreamsOptions<TStream, TParticipant>) => Promise<(TStream | TParticipant)[]>;\n\n/**\n * Mixes video and audio streams and participants based on specified parameters.\n *\n * @param {MixStreamsOptions} options - The options for mixing streams.\n * @param {Array} options.alVideoStreams - The list of audio and video streams to mix.\n * @param {Array} options.non_alVideoStreams - The list of non-audio and video streams to mix.\n * @param {Array} options.ref_participants - The list of reference participants to mix.\n * @returns {Promise<Array>} A promise that resolves with the mixed streams.\n * @throws Will throw an error if there is an issue mixing the streams.\n * @example\n * ```typescript\n * const mixedStreams = await mixStreams({\n * alVideoStreams: [stream1, stream2],\n * non_alVideoStreams: [participant1, participant2],\n * ref_participants: [participant1, participant2],\n * });\n * console.log('Mixed streams:', mixedStreams);\n * ```\n */\n\n\nexport async function mixStreams<\n TStream extends MixStreamLike = Stream,\n TParticipant extends MixParticipantLike = Participant,\n>({\n alVideoStreams,\n non_alVideoStreams,\n ref_participants,\n}: MixStreamsOptions<TStream, TParticipant>): Promise<(TStream | TParticipant)[]> {\n try {\n\n const mixedStreams: (TStream | TParticipant)[] = [];\n\n // Find \"youyou\" or \"youyouyou\" stream\n const youyouStream = alVideoStreams.find(\n (obj) => getProducerId(obj) === \"youyou\" || getProducerId(obj) === \"youyouyou\"\n );\n\n let remainingAlVideoStreams = alVideoStreams.filter(\n (obj) => getProducerId(obj) !== \"youyou\" && getProducerId(obj) !== \"youyouyou\"\n );\n\n // Separate unmuted and muted streams\n const unmutedAlVideoStreams = remainingAlVideoStreams.filter((obj) => {\n const participant = ref_participants.find(\n (p) => getVideoId(p) === getProducerId(obj)\n );\n return !getMuted(obj) && participant && getMuted(participant) === false;\n });\n\n const mutedAlVideoStreams = remainingAlVideoStreams.filter((obj) => {\n const participant = ref_participants.find(\n (p) => getVideoId(p) === getProducerId(obj)\n );\n return !!getMuted(obj) || (participant && getMuted(participant) === true);\n });\n\n const nonAlVideoStreams = [...non_alVideoStreams]; // Create a copy of non_alVideoStreams\n\n // Add unmutedAlVideoStreams to mixedStreams\n mixedStreams.push(...unmutedAlVideoStreams);\n\n // Interleave the mutedAlVideoStreams and nonAlVideoStreams\n let nonAlIndex = 0;\n for (let i = 0; i < mutedAlVideoStreams.length; i++) {\n if (nonAlIndex < nonAlVideoStreams.length) {\n mixedStreams.push(nonAlVideoStreams[nonAlIndex]);\n nonAlIndex++;\n }\n mixedStreams.push(mutedAlVideoStreams[i]);\n }\n\n // Handle remaining nonAlVideoStreams (if any)\n for (let i = nonAlIndex; i < nonAlVideoStreams.length; i++) {\n mixedStreams.push(nonAlVideoStreams[i]);\n }\n\n // Unshift 'youyou' or 'youyouyou' stream to mixedStreams\n if (youyouStream) {\n mixedStreams.unshift(youyouStream);\n }\n\n return mixedStreams;\n } catch (error) {\n // Handle errors during the process of mixing streams\n console.log(\"Error mixing streams:\", (error as Error).message);\n throw error;\n }\n}\n","import { ReorderStreamsParameters, EventType } from \"../types/types\";\n\ntype OpaqueReorderStreamsInvoker = {\n bivarianceHack: (options: any) => Promise<void>;\n}[\"bivarianceHack\"];\n\nexport interface OnScreenChangesParameters extends ReorderStreamsParameters<any, any, any> {\n eventType: EventType;\n shareScreenStarted: boolean;\n shared: boolean;\n addForBasic: boolean;\n updateAddForBasic: (value: boolean) => void;\n itemPageLimit: number;\n updateItemPageLimit: (value: number) => void;\n updateMainHeightWidth: (value: number) => void;\n\n // mediasfu functions\n reorderStreams: OpaqueReorderStreamsInvoker;\n [key: string]: any;\n}\n\nexport interface OnScreenChangesOptions<\n TParameters extends OnScreenChangesParameters = OnScreenChangesParameters,\n> {\n changed?: boolean;\n parameters: TParameters;\n}\n\n// Export the type definition for the function\nexport type OnScreenChangesType = <\n TParameters extends OnScreenChangesParameters = OnScreenChangesParameters,\n>(options: OnScreenChangesOptions<TParameters>) => Promise<void>;\n\n/**\n * Handles changes in screen events such as broadcast, chat, and conference.\n * \n * @param {OnScreenChangesOptions} options - The options for handling screen changes.\n * @param {boolean} options.changed - Indicates if the screen has changed.\n * @param {object} options.parameters - The parameters for handling screen changes.\n * @param {string} options.parameters.eventType - The type of event (e.g., \"broadcast\", \"chat\", \"conference\").\n * @param {boolean} options.parameters.shareScreenStarted - Indicates if screen sharing has started.\n * @param {boolean} options.parameters.shared - Indicates if the screen is shared.\n * @param {boolean} options.parameters.addForBasic - Flag to add basic controls.\n * @param {function} options.parameters.updateMainHeightWidth - Function to update the main height and width.\n * @param {function} options.parameters.updateAddForBasic - Function to update the addForBasic flag.\n * @param {number} options.parameters.itemPageLimit - The limit for item pages.\n * @param {function} options.parameters.updateItemPageLimit - Function to update the item page limit.\n * @param {function} options.parameters.reorderStreams - Function to reorder streams.\n * \n * @returns {Promise<void>} A promise that resolves when the screen changes have been handled.\n * \n * @throws {Error} Throws an error if there is an issue handling screen changes.\n * \n * @example\n * ```typescript\n * await onScreenChanges({\n * changed: true,\n * parameters: {\n * eventType: 'conference',\n * shareScreenStarted: false,\n * shared: false,\n * addForBasic: false,\n * updateMainHeightWidth: (height) => console.log('Updated height:', height),\n * updateAddForBasic: (value) => console.log('Updated addForBasic:', value),\n * itemPageLimit: 2,\n * updateItemPageLimit: (limit) => console.log('Updated item page limit:', limit),\n * reorderStreams: async (options) => console.log('Reordered streams with options:', options),\n * },\n * });\n * ```\n */ \n\nexport async function onScreenChanges<\n TParameters extends OnScreenChangesParameters = OnScreenChangesParameters,\n>({ changed, parameters }: OnScreenChangesOptions<TParameters>): Promise<void> {\n try {\n // Destructure parameters\n let {\n eventType,\n shareScreenStarted,\n shared,\n whiteboardStarted,\n whiteboardEnded,\n addForBasic,\n updateMainHeightWidth,\n updateAddForBasic,\n itemPageLimit,\n updateItemPageLimit,\n\n //mediasfu functions\n reorderStreams,\n } = parameters;\n const screenFlowActive = shareScreenStarted || shared || (whiteboardStarted && !whiteboardEnded);\n\n // Remove element with id 'controlButtons'\n addForBasic = false;\n updateAddForBasic(addForBasic);\n\n if (eventType === \"broadcast\" || eventType === \"chat\") {\n addForBasic = true;\n updateAddForBasic(addForBasic);\n\n itemPageLimit = eventType === \"broadcast\" ? 1 : 2;\n updateItemPageLimit(itemPageLimit);\n updateMainHeightWidth(screenFlowActive ? 84 : eventType === \"broadcast\" ? 100 : 0);\n } else if (screenFlowActive) {\n updateMainHeightWidth(84);\n } else {\n if (eventType === \"conference\") {\n updateMainHeightWidth(0);\n }\n }\n\n // Update the mini cards grid\n await reorderStreams({ add: false, screenChanged: changed, parameters });\n } catch (error) {\n // Handle errors during the process of handling screen changes\n console.log(\"Error handling screen changes:\", (error as Error).message);\n // throw error;\n }\n}\n","import { Stream, Participant, Transport, SleepType } from \"../types/types\";\n\ninterface ProducerIdCarrier {\n producerId?: string | null;\n}\n\nconst getProducerId = (value: unknown): string | null | undefined => {\n return (value as ProducerIdCarrier | null | undefined)?.producerId;\n};\n\ninterface ConsumerLike {\n paused?: boolean;\n kind?: string;\n pause: () => unknown;\n resume: () => unknown;\n}\n\ninterface SocketLike {\n emit: (\n event: string,\n payload: { serverConsumerId: string },\n callback?: ((payload?: { resumed: boolean }) => void | Promise<unknown>)\n ) => void;\n}\n\ninterface TransportLike {\n producerId?: string | null;\n consumer?: ConsumerLike;\n socket_: SocketLike;\n serverConsumerTransportId: string;\n}\n\nexport interface ProcessConsumerTransportsParameters<\n TStreamEntry = Stream,\n TMediaEntry = Stream | Participant,\n> {\n remoteScreenStream: TStreamEntry[];\n oldAllStreams: TMediaEntry[];\n newLimitedStreams: TMediaEntry[];\n\n // mediasfu functions\n sleep: SleepType;\n getUpdatedAllParams: () => ProcessConsumerTransportsParameters<TStreamEntry, TMediaEntry>;\n [key: string]: any;\n}\n\nexport interface ProcessConsumerTransportsOptions<\n TTransport extends TransportLike = Transport,\n TStreamEntry = Stream,\n TMediaEntry = Stream | Participant,\n> {\n consumerTransports: TTransport[];\n lStreams_: TMediaEntry[];\n parameters: ProcessConsumerTransportsParameters<TStreamEntry, TMediaEntry>;\n}\n\n// Export the type definition for the function\nexport type ProcessConsumerTransportsType = <\n TTransport extends TransportLike = Transport,\n TStreamEntry = Stream,\n TMediaEntry = Stream | Participant,\n>(options: ProcessConsumerTransportsOptions<TTransport, TStreamEntry, TMediaEntry>) => Promise<void>;\n\n/**\n * Processes consumer transports by pausing and resuming them based on certain conditions.\n *\n * @param {Object} options - The options for processing consumer transports.\n * @param {Array} options.consumerTransports - The list of consumer transports to process.\n * @param {Array} options.lStreams_ - The list of local streams.\n * @param {Object} options.parameters - The parameters object containing various stream arrays and utility functions.\n *\n * @returns {Promise<void>} - A promise that resolves when the processing is complete.\n *\n * @throws {Error} - Throws an error if there is an issue processing consumer transports.\n *\n * The function performs the following steps:\n * 1. Destructures and updates the parameters.\n * 2. Defines a helper function to check if a producerId is valid in given stream arrays.\n * 3. Filters consumer transports to resume based on certain conditions.\n * 4. Filters consumer transports to pause based on certain conditions.\n * 5. Pauses consumer transports after a short delay.\n * 6. Emits `consumer-pause` event for each filtered transport (not audio).\n * 7. Emits `consumer-resume` event for each filtered transport (not audio).\n *\n * @example\n * ```typescript\n * await processConsumerTransports({\n * consumerTransports: [transport1, transport2],\n * lStreams_: [stream1, stream2],\n * parameters: {\n * remoteScreenStream: [],\n * oldAllStreams: [],\n * newLimitedStreams: [],\n * sleep: sleepFunction,\n * getUpdatedAllParams: () => parameters,\n * },\n * });\n * ```\n */\n\nexport async function processConsumerTransports<\n TTransport extends TransportLike = Transport,\n TStreamEntry = Stream,\n TMediaEntry = Stream | Participant,\n>({\n consumerTransports,\n lStreams_,\n parameters,\n}: ProcessConsumerTransportsOptions<TTransport, TStreamEntry, TMediaEntry>): Promise<void> {\n try {\n // Destructure parameters and get updated values\n parameters = parameters.getUpdatedAllParams();\n\n const {\n remoteScreenStream,\n oldAllStreams,\n newLimitedStreams,\n sleep,\n } = parameters;\n\n // Function to check if the producerId is valid in the given stream arrays\n function isValidProducerId(producerId: string | null | undefined, ...streamArrays: unknown[][]): boolean {\n return (\n producerId !== null &&\n producerId !== \"\" &&\n streamArrays.some((streamArray) => {\n return (\n streamArray.length > 0 &&\n streamArray.some((stream) => getProducerId(stream) === producerId)\n );\n })\n );\n }\n\n // Get paused consumer transports that are not audio\n const consumerTransportsToResume = consumerTransports.filter(\n (transport) =>\n isValidProducerId(\n transport.producerId,\n lStreams_,\n remoteScreenStream,\n oldAllStreams,\n newLimitedStreams\n ) &&\n transport.consumer?.paused === true &&\n transport.consumer?.kind !== \"audio\"\n );\n\n // Get unpaused consumer transports that are not audio\n const consumerTransportsToPause = consumerTransports.filter(\n (transport) =>\n transport.producerId &&\n transport.producerId !== null &&\n transport.producerId !== \"\" &&\n !lStreams_.some(\n (stream) => getProducerId(stream) === transport.producerId\n ) &&\n transport.consumer &&\n transport.consumer?.kind &&\n transport.consumer.paused !== true &&\n transport.consumer.kind !== \"audio\" &&\n !remoteScreenStream.some((stream) => getProducerId(stream) === transport.producerId) &&\n !oldAllStreams.some((stream) => getProducerId(stream) === transport.producerId) &&\n !newLimitedStreams.some((stream) => getProducerId(stream) === transport.producerId)\n );\n\n // Pause consumer transports after a short delay\n await sleep({ ms: 100 });\n\n // Emit consumer.pause() for each filtered transport (not audio)\n for (const transport of consumerTransportsToPause) {\n transport.consumer?.pause();\n transport.socket_.emit(\n \"consumer-pause\",\n { serverConsumerId: transport.serverConsumerTransportId },\n async () => {\n // Handle the response if needed\n }\n );\n }\n\n // Emit consumer.resume() for each filtered transport (not audio)\n for (const transport of consumerTransportsToResume) {\n transport.socket_.emit(\n \"consumer-resume\",\n { serverConsumerId: transport.serverConsumerTransportId },\n async ({ resumed }: { resumed: boolean } = { resumed: false }) => {\n if (resumed) {\n transport.consumer?.resume();\n }\n }\n );\n }\n } catch (error) {\n if (error instanceof Error) {\n console.error(`Error processing consumer transports: ${error.message}`);\n } else {\n console.error('Error processing consumer transports:', error);\n }\n // throw new Error(`Error processing consumer transports: ${error.message}`);\n }\n}\n","import { Stream, Transport, Participant, SleepType } from \"../types/types\";\n\ninterface ProducerIdCarrier {\n producerId?: string | null;\n}\n\ninterface SpeakerTranslationStateLike {\n enabled?: boolean;\n speakerId?: string;\n speakerName?: string;\n originalProducerId?: string;\n}\n\ninterface ParticipantLike {\n name?: string | null;\n audioID?: string | null;\n}\n\nconst getProducerId = (value: unknown): string | null | undefined => {\n return (value as ProducerIdCarrier | null | undefined)?.producerId;\n};\n\ninterface ConsumerLike {\n paused?: boolean;\n kind?: string;\n pause: () => unknown;\n resume: () => unknown;\n}\n\ninterface SocketLike {\n emit: (\n event: string,\n payload: { serverConsumerId: string },\n callback?: ((payload?: { resumed: boolean }) => void | Promise<unknown>)\n ) => void;\n}\n\ninterface TransportLike {\n producerId?: string | null;\n consumer?: ConsumerLike;\n socket_: SocketLike;\n serverConsumerTransportId: string;\n}\n\nconst getSpeakerNameForProducerId = (\n producerId: string,\n parameters: Record<string, any>,\n): string | undefined => {\n const participants = parameters.participants as ParticipantLike[] | undefined;\n const participant = participants?.find((candidate) => candidate.audioID === producerId);\n\n if (participant?.name) {\n return participant.name;\n }\n\n const audStreamName = (parameters.audStreamNames as Array<{ producerId?: string; name?: string }> | undefined)\n ?.find((stream) => stream.producerId === producerId && typeof stream.name === 'string');\n if (audStreamName?.name) {\n return audStreamName.name;\n }\n\n return (parameters.allAudioStreams as Array<{ producerId?: string; name?: string }> | undefined)\n ?.find((stream) => stream.producerId === producerId && typeof stream.name === 'string')\n ?.name;\n};\n\nconst isOriginalAudioSuppressedByTranslation = (\n producerId: string | null | undefined,\n parameters: Record<string, any>,\n): boolean => {\n if (!producerId) {\n return false;\n }\n\n const activeTranslationProducerIds = parameters.activeTranslationProducerIds as Set<string> | undefined;\n if (activeTranslationProducerIds?.has(producerId)) {\n return false;\n }\n\n const speakerTranslationStates = parameters.speakerTranslationStates as\n | Map<string, SpeakerTranslationStateLike>\n | undefined;\n\n if (!speakerTranslationStates?.size) {\n return false;\n }\n\n const speakerName = getSpeakerNameForProducerId(producerId, parameters);\n\n if (speakerName) {\n const speakerState = speakerTranslationStates.get(speakerName);\n if (speakerState?.enabled) {\n return true;\n }\n }\n\n return Array.from(speakerTranslationStates.values()).some((speakerState) => {\n if (!speakerState?.enabled) {\n return false;\n }\n\n if (speakerState.originalProducerId === producerId) {\n return true;\n }\n\n if (!speakerName) {\n return false;\n }\n\n return (\n speakerState.speakerId === speakerName ||\n speakerState.speakerName === speakerName\n );\n });\n};\n\nexport interface ProcessConsumerTransportsAudioParameters {\n\n // mediasfu functions\n sleep: SleepType;\n [key: string]: any;\n}\n\nexport interface ProcessConsumerTransportsAudioOptions<\n TTransport extends TransportLike = Transport,\n TMediaEntry = Stream | Participant,\n> {\n consumerTransports: TTransport[];\n lStreams: TMediaEntry[];\n parameters: ProcessConsumerTransportsAudioParameters;\n}\n\n// Export the type definition for the function\nexport type ProcessConsumerTransportsAudioType = <\n TTransport extends TransportLike = Transport,\n TMediaEntry = Stream | Participant,\n>(options: ProcessConsumerTransportsAudioOptions<TTransport, TMediaEntry>) => Promise<void>;\n\n/**\n * Processes consumer transports for audio streams by pausing and resuming them based on their current state and the provided streams.\n *\n * @param {Object} options - The options for processing consumer transports.\n * @param {Array} options.consumerTransports - The list of consumer transports to process.\n * @param {Array} options.lStreams - The list of local streams to check against.\n * @param {Object} options.parameters - Additional parameters for processing.\n * @param {Function} options.parameters.sleep - A function to pause execution for a specified duration.\n *\n * @returns {Promise<void>} A promise that resolves when the processing is complete.\n *\n * @throws Will throw an error if there is an issue processing the consumer transports.\n *\n * @example\n * ```typescript\n * await processConsumerTransportsAudio({\n * consumerTransports: [transport1, transport2],\n * lStreams: [stream1, stream2],\n * parameters: {\n * sleep: sleepFunction,\n * },\n * });\n * ```\n */\n\nexport const processConsumerTransportsAudio = async <\n TTransport extends TransportLike = Transport,\n TMediaEntry = Stream | Participant,\n>({\n consumerTransports,\n lStreams,\n parameters,\n}: ProcessConsumerTransportsAudioOptions<TTransport, TMediaEntry>): Promise<void> => {\n try {\n const { sleep } = parameters;\n\n // Function to check if the producerId is valid in the given stream arrays\n const isValidProducerId = (producerId: string | null | undefined, ...streamArrays: unknown[][]): boolean => {\n return (\n producerId !== null &&\n producerId !== \"\" &&\n streamArrays.some((streamArray) => {\n return (\n streamArray.length > 0 &&\n streamArray.some((stream) => getProducerId(stream) === producerId)\n );\n })\n );\n };\n\n // Get paused consumer transports that are audio\n const consumerTransportsToResume = consumerTransports.filter(\n (transport) =>\n isValidProducerId(transport.producerId, lStreams) &&\n !isOriginalAudioSuppressedByTranslation(transport.producerId, parameters) &&\n transport.consumer?.paused === true &&\n transport.consumer?.kind === \"audio\"\n );\n\n // Get unpaused consumer transports that are audio\n const consumerTransportsToPause = consumerTransports.filter(\n (transport) =>\n transport.producerId &&\n transport.producerId !== null &&\n transport.producerId !== \"\" &&\n (\n isOriginalAudioSuppressedByTranslation(transport.producerId, parameters) ||\n !lStreams.some(\n (stream) => getProducerId(stream) === transport.producerId\n )\n ) &&\n transport.consumer &&\n transport.consumer?.kind &&\n transport.consumer.paused !== true &&\n transport.consumer.kind === \"audio\"\n );\n\n await sleep({ms:100});\n\n // Emit consumer.pause() for each transport to pause\n for (const transport of consumerTransportsToPause) {\n transport.consumer?.pause();\n transport.socket_.emit(\n \"consumer-pause\",\n { serverConsumerId: transport.serverConsumerTransportId },\n async () => {\n // Handle the response if needed\n }\n );\n }\n\n // Emit consumer.resume() for each transport to resume\n for (const transport of consumerTransportsToResume) {\n if (isOriginalAudioSuppressedByTranslation(transport.producerId, parameters)) {\n continue;\n }\n\n transport.socket_.emit(\n \"consumer-resume\",\n { serverConsumerId: transport.serverConsumerTransportId },\n async ({ resumed }: { resumed: boolean } = { resumed: false }) => {\n if (resumed) {\n transport.consumer?.resume();\n }\n }\n );\n }\n } catch (error) {\n console.error(\"Error in processConsumerTransportsAudio:\", error);\n }\n};\n\n","\n \nimport { PrepopulateUserMediaParameters, PrepopulateUserMediaOptions, EventType } from '../types/types';\n\ntype PrepopulateUserMediaInvoker = {\n bivarianceHack: (options: PrepopulateUserMediaOptions) => Promise<unknown>;\n}['bivarianceHack'];\n\nexport interface ReadjustParameters extends PrepopulateUserMediaParameters {\n eventType: EventType;\n shareScreenStarted: boolean;\n shared: boolean;\n mainHeightWidth: number;\n prevMainHeightWidth: number;\n hostLabel: string;\n first_round: boolean;\n lock_screen: boolean;\n updateMainHeightWidth: (value: number) => void;\n\n // mediasfu functions\n prepopulateUserMedia: PrepopulateUserMediaInvoker;\n getUpdatedAllParams: () => ReadjustParameters;\n [key: string]: any;\n}\n\nexport interface ReadjustOptions<TParameters extends ReadjustParameters = ReadjustParameters> {\n n: number;\n state: number;\n parameters: TParameters;\n}\n\n// Export the type definition for the function\nexport type ReadjustType = <TParameters extends ReadjustParameters = ReadjustParameters>(\n options: ReadjustOptions<TParameters>\n) => Promise<void>;\n\n/**\n * Adjusts the layout parameters based on the provided options.\n *\n * @param {ReadjustOptions} options - The options for readjusting the layout.\n * @param {number} options.n - The number of participants or elements.\n * @param {number} options.state - The current state of the layout.\n * @param {object} options.parameters - The parameters for the layout adjustment.\n * @param {function} options.parameters.getUpdatedAllParams - Function to get updated parameters.\n * @param {string} options.parameters.eventType - The type of event (e.g., \"broadcast\", \"chat\", \"conference\").\n * @param {boolean} options.parameters.shareScreenStarted - Indicates if screen sharing has started.\n * @param {boolean} options.parameters.shared - Indicates if content is being shared.\n * @param {number} options.parameters.mainHeightWidth - The main height and width value.\n * @param {number} options.parameters.prevMainHeightWidth - The previous main height and width value.\n * @param {string} options.parameters.hostLabel - The label for the host.\n * @param {boolean} options.parameters.first_round - Indicates if it is the first round.\n * @param {boolean} options.parameters.lock_screen - Indicates if the screen is locked.\n * @param {function} options.parameters.updateMainHeightWidth - Function to update the main height and width.\n * @param {function} options.parameters.prepopulateUserMedia - Function to prepopulate user media.\n * @returns {Promise<void>} A promise that resolves when the layout adjustment is complete.\n * @throws {Error} Throws an error if there is an issue updating the grid sizes.\n *\n * @example\n * ```typescript\n * await readjust({\n * n: 5,\n * state: 1,\n * parameters: {\n * eventType: 'conference',\n * shareScreenStarted: false,\n * shared: false,\n * mainHeightWidth: 100,\n * prevMainHeightWidth: 80,\n * hostLabel: 'Host Name',\n * first_round: false,\n * lock_screen: false,\n * updateMainHeightWidth: updateMainHeightWidthFunction,\n * getUpdatedAllParams: getUpdatedAllParamsFunction,\n * },\n * });\n * ```\n */\n\nexport async function readjust<TParameters extends ReadjustParameters = ReadjustParameters>({\n n,\n state,\n parameters,\n}: ReadjustOptions<TParameters>): Promise<void> {\n const { getUpdatedAllParams } = parameters;\n const updatedParameters = getUpdatedAllParams() as TParameters;\n\n try {\n // Destructure parameters\n let {\n eventType,\n shareScreenStarted,\n shared,\n whiteboardStarted,\n whiteboardEnded,\n mainHeightWidth,\n prevMainHeightWidth,\n hostLabel,\n first_round,\n lock_screen,\n updateMainHeightWidth,\n prepopulateUserMedia,\n } = updatedParameters;\n const screenFlowActive = shareScreenStarted || shared || (whiteboardStarted && !whiteboardEnded);\n\n if (state === 0) {\n prevMainHeightWidth = mainHeightWidth;\n }\n\n let val1 = 6;\n let val2 = 12 - val1;\n let cal1 = Math.floor((val1 / 12) * 100);\n let cal2 = 100 - cal1;\n\n if (eventType === \"broadcast\") {\n val1 = 0;\n val2 = 12 - val1;\n\n if (n === 0) {\n val1 = 0;\n val2 = 12 - val1;\n }\n } else if (\n eventType === \"chat\" ||\n (eventType === \"conference\" && !screenFlowActive)\n ) {\n val1 = 12;\n val2 = 12 - val1;\n } else {\n if (screenFlowActive) {\n val2 = 10;\n val1 = 12 - val2;\n } else {\n if (n === 0) {\n val1 = 1;\n val2 = 12 - val1;\n } else if (n >= 1 && n < 4) {\n val1 = 4;\n val2 = 12 - val1;\n } else if (n >= 4 && n < 6) {\n val1 = 6;\n val2 = 12 - val1;\n } else if (n >= 6 && n < 9) {\n val1 = 6;\n val2 = 12 - val1;\n } else if (n >= 9 && n < 12) {\n val1 = 6;\n val2 = 12 - val1;\n } else if (n >= 12 && n < 20) {\n val1 = 8;\n val2 = 12 - val1;\n } else if (n >= 20 && n < 50) {\n val1 = 8;\n val2 = 12 - val1;\n } else {\n val1 = 10;\n val2 = 12 - val1;\n }\n }\n }\n\n if (state === 0) {\n mainHeightWidth = val2;\n }\n\n cal1 = Math.floor((val1 / 12) * 100);\n cal2 = 100 - cal1;\n\n if (mainHeightWidth !== cal2) {\n updateMainHeightWidth(cal2);\n }\n\n if (prevMainHeightWidth !== mainHeightWidth) {\n if (!lock_screen && !shared) {\n await prepopulateUserMedia({ name: hostLabel, parameters: updatedParameters });\n } else if (!first_round) {\n await prepopulateUserMedia({ name: hostLabel, parameters: updatedParameters });\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n console.log(\"Error updating grid sizes:\", error.message);\n } else {\n console.log(\"Error updating grid sizes:\", error);\n }\n }\n}\n","\nimport { Socket } from \"socket.io-client\";\nimport { GetPipedProducersAltType, GetPipedProducersAltParameters } from \"../types/types\";\n\nexport interface ReceiveAllPipedTransportsParameters extends GetPipedProducersAltParameters {\n roomName: string;\n member: string;\n\n // mediasfu functions\n getPipedProducersAlt: GetPipedProducersAltType;\n [key: string]: any;\n}\n\nexport interface ReceiveAllPipedTransportsOptions {\n nsock: Socket;\n community?: boolean;\n parameters: ReceiveAllPipedTransportsParameters;\n}\n\n// Export the type definition for the function\nexport type ReceiveAllPipedTransportsType = (options: ReceiveAllPipedTransportsOptions) => Promise<void>;\n\n/**\n * Receives all piped transports by emitting an event to the server and processing the response.\n *\n * @param {ReceiveAllPipedTransportsOptions} options - The options for receiving all piped transports.\n * @param {Socket} options.nsock - The socket instance used for communication.\n * @param {boolean} options.community - Whether the room is a community edition room.\n * @param {ReceiveAllPipedTransportsParameters} options.parameters - The parameters for the operation.\n * @param {string} options.parameters.roomName - The name of the room.\n * @param {string} options.parameters.member - The member identifier.\n * @param {Function} options.parameters.getPipedProducersAlt - The function to get piped producers for a given level.\n *\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n *\n * @throws Will log an error message if the operation fails.\n *\n * @example\n * ```typescript\n * await receiveAllPipedTransports({\n * nsock: socketInstance,\n * community: false,\n * parameters: {\n * roomName: 'Room1',\n * member: 'Member1',\n * getPipedProducersAlt: getPipedProducersAltFunction,\n * },\n * });\n * ```\n */\n\nexport const receiveAllPipedTransports = async ({ nsock, community=false, parameters }: ReceiveAllPipedTransportsOptions): Promise<void> => {\n try {\n // Destructure parameters\n const { roomName, member, getPipedProducersAlt } = parameters;\n const emitName = community ? \"createReceiveAllTransports\" : \"createReceiveAllTransportsPiped\";\n const emitData = community ? { islevel:'0' } : { roomName, member };\n // Emit createReceiveAllTransportsPiped event to the server\n await nsock.emit(\n emitName,\n emitData,\n async ({ producersExist }: { producersExist: boolean }) => {\n // Array of options representing different levels\n const options = [\"0\", \"1\", \"2\"];\n\n // If producers exist, loop through each level and get producers\n if (producersExist) {\n for (const islevel of options) {\n await getPipedProducersAlt({ nsock, community, islevel, parameters });\n }\n }\n }\n );\n } catch (error) {\n console.log(\"receiveAllPipedTransports error\", error);\n }\n};\n"," \nimport { Participant, Stream } from \"../types/types\";\n\ninterface ReorderStreamLike {\n producerId?: string | null;\n}\n\ninterface ReorderParticipantLike {\n name: string;\n islevel?: string | null;\n videoID?: string | null;\n ScreenID?: string | null;\n}\n\ntype ChangeVidsInvoker = (options: {\n screenChanged?: boolean;\n parameters: any;\n}) => Promise<void>;\n\ntype StreamCollectionUpdater<TEntry> = {\n bivarianceHack: (streams: TEntry[]) => void;\n}[\"bivarianceHack\"];\n\nconst getProducerId = (value: unknown): string | null | undefined => {\n return (value as ReorderStreamLike | null | undefined)?.producerId;\n};\n\nexport interface ReorderStreamsParameters<\n TStream extends ReorderStreamLike = Stream,\n TParticipant extends ReorderParticipantLike = Participant,\n TChangeVidsParameters = unknown,\n> {\n allVideoStreams: (TStream | TParticipant)[];\n participants: TParticipant[];\n oldAllStreams: (TStream | TParticipant)[];\n screenId?: string;\n adminVidID?: string;\n newLimitedStreams: (TStream | TParticipant)[];\n newLimitedStreamsIDs: string[];\n activeSounds: string[];\n screenShareIDStream?: string;\n screenShareNameStream?: string;\n adminIDStream?: string;\n adminNameStream?: string;\n updateNewLimitedStreams: StreamCollectionUpdater<TStream | TParticipant>;\n updateNewLimitedStreamsIDs: (ids: string[]) => void;\n updateActiveSounds: (sounds: string[]) => void;\n updateScreenShareIDStream: (id: string) => void;\n updateScreenShareNameStream: (name: string) => void;\n updateAdminIDStream: (id: string) => void;\n updateAdminNameStream: (name: string) => void;\n updateYouYouStream: StreamCollectionUpdater<TStream | TParticipant>;\n\n // mediasfu functions\n changeVids: ChangeVidsInvoker;\n getUpdatedAllParams: () => ReorderStreamsParameters<TStream, TParticipant, TChangeVidsParameters>;\n [key: string]: any;\n}\n\nexport interface ReorderStreamsOptions<\n TParameters extends ReorderStreamsParameters<any, any, any> = ReorderStreamsParameters,\n> {\n add?: boolean;\n screenChanged?: boolean;\n parameters: TParameters;\n}\n\n\nexport type ReorderStreamsType = <\n TParameters extends ReorderStreamsParameters<any, any, any> = ReorderStreamsParameters,\n>(options: ReorderStreamsOptions<TParameters>) => Promise<void>;\n\n/**\n * Reorders the video streams based on the provided options and updates the UI accordingly.\n *\n * @param {ReorderStreamsOptions} options - The options for reordering streams.\n * @param {boolean} [options.add=false] - Whether to add new streams or not.\n * @param {boolean} [options.screenChanged=false] - Whether the screen has changed or not.\n * @param {Object} options.parameters - The parameters required for reordering streams.\n * @param {Function} options.parameters.getUpdatedAllParams - Function to get updated parameters.\n * @param {Array} options.parameters.allVideoStreams - Array of all video streams.\n * @param {Array} options.parameters.participants - Array of participants.\n * @param {Array} options.parameters.oldAllStreams - Array of old streams.\n * @param {string} options.parameters.screenId - ID of the screen.\n * @param {string} options.parameters.adminVidID - ID of the admin video.\n * @param {Array} options.parameters.newLimitedStreams - Array of new limited streams.\n * @param {Array} options.parameters.newLimitedStreamsIDs - Array of new limited stream IDs.\n * @param {Array} options.parameters.activeSounds - Array of active sounds.\n * @param {string} options.parameters.screenShareIDStream - ID of the screen share stream.\n * @param {string} options.parameters.screenShareNameStream - Name of the screen share stream.\n * @param {string} options.parameters.adminIDStream - ID of the admin stream.\n * @param {string} options.parameters.adminNameStream - Name of the admin stream.\n * @param {Function} options.parameters.updateNewLimitedStreams - Function to update new limited streams.\n * @param {Function} options.parameters.updateNewLimitedStreamsIDs - Function to update new limited stream IDs.\n * @param {Function} options.parameters.updateActiveSounds - Function to update active sounds.\n * @param {Function} options.parameters.updateScreenShareIDStream - Function to update screen share ID stream.\n * @param {Function} options.parameters.updateScreenShareNameStream - Function to update screen share name stream.\n * @param {Function} options.parameters.updateAdminIDStream - Function to update admin ID stream.\n * @param {Function} options.parameters.updateAdminNameStream - Function to update admin name stream.\n * @param {Function} options.parameters.updateYouYouStream - Function to update YouYou stream.\n * @param {Function} options.parameters.changeVids - Function to reflect changes on the UI.\n *\n * @returns {Promise<void>} A promise that resolves when the reordering is complete.\n *\n * @throws {Error} Throws an error if there is an issue updating the streams.\n *\n * @example\n * ```typescript\n * await reorderStreams({\n * add: true,\n * screenChanged: false,\n * parameters: {\n * allVideoStreams: [...],\n * participants: [...],\n * // additional parameters...\n * },\n * });\n * ```\n */\n\nexport const reorderStreams = async <\n TParameters extends ReorderStreamsParameters<any, any, any> = ReorderStreamsParameters,\n>({\n add = false,\n screenChanged = false,\n parameters,\n}: ReorderStreamsOptions<TParameters>): Promise<void> => {\n const { getUpdatedAllParams } = parameters;\n const updatedParameters = getUpdatedAllParams() as TParameters;\n\n let {\n allVideoStreams,\n participants,\n oldAllStreams,\n screenId,\n adminVidID,\n newLimitedStreams,\n newLimitedStreamsIDs,\n activeSounds,\n screenShareIDStream,\n screenShareNameStream,\n adminIDStream,\n adminNameStream,\n updateNewLimitedStreams,\n updateNewLimitedStreamsIDs,\n updateActiveSounds,\n updateScreenShareIDStream,\n updateScreenShareNameStream,\n updateAdminIDStream,\n updateAdminNameStream,\n updateYouYouStream,\n\n //mediasfu functions\n changeVids,\n } = updatedParameters;\n\n // function to reorder streams on the ui\n if (!add) {\n newLimitedStreams = [];\n newLimitedStreamsIDs = [];\n activeSounds = [];\n }\n\n const youyou = allVideoStreams.filter((stream) => getProducerId(stream) === \"youyou\");\n const admin = participants.filter((participant) => participant.islevel === \"2\");\n\n if (admin.length > 0) {\n adminVidID = admin[0].videoID ?? undefined;\n } else {\n adminVidID = \"\";\n }\n\n if (adminVidID) {\n const adminStream = allVideoStreams.find((stream) => getProducerId(stream) === adminVidID);\n\n if (!add) {\n newLimitedStreams = [...newLimitedStreams, ...youyou];\n newLimitedStreamsIDs = [...newLimitedStreamsIDs, ...youyou.map((stream) => getProducerId(stream) ?? \"\")];\n } else {\n const youyouStream = newLimitedStreams.find((stream) => getProducerId(stream) === \"youyou\");\n\n if (!youyouStream) {\n newLimitedStreams = [...newLimitedStreams, ...youyou];\n newLimitedStreamsIDs = [...newLimitedStreamsIDs, ...youyou.map((stream) => getProducerId(stream) ?? \"\")];\n }\n }\n\n if (adminStream) {\n adminIDStream = adminVidID;\n\n if (!add) {\n newLimitedStreams = [...newLimitedStreams, adminStream];\n newLimitedStreamsIDs = [...newLimitedStreamsIDs, getProducerId(adminStream) ?? \"\"];\n } else {\n const adminStreamer = newLimitedStreams.find((stream) => getProducerId(stream) === adminVidID);\n\n if (!adminStreamer) {\n newLimitedStreams = [...newLimitedStreams, adminStream];\n newLimitedStreamsIDs = [...newLimitedStreamsIDs, getProducerId(adminStream) ?? \"\"];\n }\n }\n } else {\n const oldAdminStream = oldAllStreams.find((stream) => getProducerId(stream) === adminVidID);\n\n if (oldAdminStream) {\n //add it to the allVideoStream\n\n adminIDStream = adminVidID;\n adminNameStream = admin[0].name;\n\n if (!add) {\n newLimitedStreams = [...newLimitedStreams, oldAdminStream];\n newLimitedStreamsIDs = [...newLimitedStreamsIDs, getProducerId(oldAdminStream) ?? \"\"];\n } else {\n const adminStreamer = newLimitedStreams.find((stream) => getProducerId(stream) === adminVidID);\n\n if (!adminStreamer) {\n newLimitedStreams = [...newLimitedStreams, oldAdminStream];\n newLimitedStreamsIDs = [...newLimitedStreamsIDs, getProducerId(oldAdminStream) ?? \"\"];\n }\n }\n }\n }\n\n const screenParticipant = participants.filter((participant) => participant.ScreenID === screenId);\n\n if (screenParticipant.length > 0) {\n const screenParticipantVidID = screenParticipant[0].videoID ?? undefined;\n const screenParticipantVidID_ = newLimitedStreams.filter((stream) => getProducerId(stream) === screenParticipantVidID);\n\n if (screenParticipantVidID_?.length < 1 && screenParticipantVidID) {\n screenShareIDStream = screenParticipantVidID;\n screenShareNameStream = screenParticipant[0].name;\n const screenParticipantVidID__ = allVideoStreams.filter((stream) => getProducerId(stream) === screenParticipantVidID);\n newLimitedStreams = [...newLimitedStreams, ...screenParticipantVidID__];\n newLimitedStreamsIDs = [...newLimitedStreamsIDs, ...screenParticipantVidID__.map((stream) => getProducerId(stream) ?? \"\")];\n }\n }\n } else {\n if (!add) {\n newLimitedStreams = [...newLimitedStreams, ...youyou];\n newLimitedStreamsIDs = [...newLimitedStreamsIDs, ...youyou.map((stream) => getProducerId(stream) ?? \"\")];\n } else {\n const youyouStream = newLimitedStreams.find((stream) => getProducerId(stream) === \"youyou\");\n\n if (!youyouStream) {\n newLimitedStreams = [...newLimitedStreams, ...youyou];\n newLimitedStreamsIDs = [...newLimitedStreamsIDs, ...youyou.map((stream) => getProducerId(stream) ?? \"\")];\n }\n }\n\n const screenParticipant = participants.filter((participant) => participant.ScreenID === screenId);\n\n if (screenParticipant.length > 0) {\n const screenParticipantVidID = screenParticipant[0].videoID ?? undefined;\n const screenParticipantVidID_ = newLimitedStreams.filter((stream) => getProducerId(stream) === screenParticipantVidID);\n\n if (screenParticipantVidID_?.length < 1 && screenParticipantVidID) {\n screenShareIDStream = screenParticipantVidID;\n screenShareNameStream = screenParticipant[0].name;\n const screenParticipantVidID__ = allVideoStreams.filter((stream) => getProducerId(stream) === screenParticipantVidID);\n newLimitedStreams = [...newLimitedStreams, ...screenParticipantVidID__];\n newLimitedStreamsIDs = [...newLimitedStreamsIDs, ...screenParticipantVidID__.map((stream) => getProducerId(stream) ?? \"\")];\n }\n }\n }\n\n updateNewLimitedStreams(newLimitedStreams);\n updateNewLimitedStreamsIDs(newLimitedStreamsIDs);\n updateActiveSounds(activeSounds);\n updateScreenShareIDStream(screenShareIDStream!);\n updateScreenShareNameStream(screenShareNameStream!);\n updateAdminIDStream(adminIDStream!);\n updateAdminNameStream(adminNameStream!);\n updateYouYouStream(youyou);\n\n //reflect the changes on the ui\n await changeVids({ screenChanged, parameters: updatedParameters });\n};\n\n","import { ScreenState, CompareScreenStatesParameters, CompareScreenStatesType, CompareActiveNamesParameters, CompareActiveNamesType } from '../types/types';\n\n\nexport interface RePortParameters extends CompareScreenStatesParameters, CompareActiveNamesParameters {\n islevel: string;\n mainScreenPerson: string;\n adminOnMainScreen: boolean;\n mainScreenFilled: boolean;\n recordStarted: boolean;\n recordStopped: boolean;\n recordPaused: boolean;\n recordResumed: boolean;\n screenStates: ScreenState[];\n prevScreenStates: ScreenState[];\n updateScreenStates: (states: ScreenState[]) => void;\n updatePrevScreenStates: (states: ScreenState[]) => void;\n\n // mediasfu functions\n compareActiveNames: CompareActiveNamesType;\n compareScreenStates: CompareScreenStatesType;\n\n getUpdatedAllParams: () => RePortParameters;\n [key: string]: any;\n}\n\nexport interface RePortOptions {\n restart?: boolean;\n parameters: RePortParameters;\n}\n\n\n// Export the type definition for the function\nexport type RePortType = (options: RePortOptions) => Promise<void>;\n\n/**\n * RePort function that handles the reporting logic based on the provided parameters.\n *\n * @param {RePortOptions} options - The options for the rePort function.\n * @param {boolean} [options.restart=false] - Flag indicating whether to restart the process.\n * @param {Object} options.parameters - The parameters object containing various states and functions.\n * @param {Function} options.parameters.getUpdatedAllParams - Function to get updated parameters.\n * @param {string} options.parameters.islevel - The current level of the process.\n * @param {string} options.parameters.mainScreenPerson - The person on the main screen.\n * @param {boolean} options.parameters.adminOnMainScreen - Flag indicating if admin is on the main screen.\n * @param {boolean} options.parameters.mainScreenFilled - Flag indicating if the main screen is filled.\n * @param {boolean} options.parameters.recordStarted - Flag indicating if recording has started.\n * @param {boolean} options.parameters.recordStopped - Flag indicating if recording has stopped.\n * @param {boolean} options.parameters.recordPaused - Flag indicating if recording is paused.\n * @param {boolean} options.parameters.recordResumed - Flag indicating if recording has resumed.\n * @param {Array} options.parameters.screenStates - Array of current screen states.\n * @param {Function} options.parameters.updateScreenStates - Function to update the current screen states.\n * @param {Function} options.parameters.updatePrevScreenStates - Function to update the previous screen states.\n * @param {Function} options.parameters.compareActiveNames - Function to compare active names.\n * @param {Function} options.parameters.compareScreenStates - Function to compare screen states.\n *\n * @returns {Promise<void>} A promise that resolves when the reporting process is complete.\n *\n * @throws {Error} Throws an error if there is an issue during the reporting process.\n *\n * @example\n * ```typescript\n * await rePort({\n * restart: false,\n * parameters: {\n * islevel: \"2\",\n * mainScreenPerson: \"John Doe\",\n * // other parameters...\n * },\n * });\n * ```\n */\n\nexport async function rePort({ restart = false, parameters }: RePortOptions): Promise<void> {\n const { getUpdatedAllParams } = parameters;\n parameters = getUpdatedAllParams();\n\n try {\n // Destructure parameters\n const {\n islevel,\n mainScreenPerson,\n adminOnMainScreen,\n mainScreenFilled,\n recordStarted,\n recordStopped,\n recordPaused,\n recordResumed,\n screenStates,\n updateScreenStates,\n updatePrevScreenStates,\n compareActiveNames,\n compareScreenStates,\n } = parameters;\n\n if (recordStarted || recordResumed) {\n if (recordStopped || recordPaused) {\n // Recording stopped or paused, do nothing\n } else {\n if (islevel === \"2\") {\n const previousScreenStates = [...screenStates];\n updatePrevScreenStates(previousScreenStates);\n\n const currentScreenStates = [\n { mainScreenPerson, adminOnMainScreen, mainScreenFilled },\n ];\n updateScreenStates(currentScreenStates);\n\n\n if (restart) {\n await compareActiveNames({ restart, parameters });\n return;\n }\n await compareActiveNames({ restart, parameters });\n await compareScreenStates({ restart, parameters });\n }\n }\n }\n } catch (error) {\n console.log(\"Error during rePorting: \", error);\n // throw new Error(`Error during rePorting: ${error.message}`);\n }\n}\n\n","import { Socket } from \"socket.io-client\";\nimport { ShowAlert, StartShareScreenType, StartShareScreenParameters } from \"../types/types\";\n\nexport interface RequestScreenShareParameters extends StartShareScreenParameters {\n socket: Socket;\n showAlert?: ShowAlert\n localUIMode: boolean;\n targetResolution?: string;\n targetResolutionHost?: string;\n \n\n // mediasfu functions\n startShareScreen: StartShareScreenType;\n getUpdatedAllParams : () => RequestScreenShareParameters;\n [key: string]: any;\n}\n\nexport interface RequestScreenShareOptions {\n parameters: RequestScreenShareParameters;\n}\n\n// Export the type definition for the function\nexport type RequestScreenShareType = (options: RequestScreenShareOptions) => Promise<void>;\n\n/**\n * Requests to start screen sharing.\n *\n * @param {RequestScreenShareOptions} options - The options for requesting screen share.\n * @param {Object} options.parameters - The parameters for the screen share request.\n * @param {Socket} options.parameters.socket - The socket instance to communicate with the server.\n * @param {Function} [options.parameters.showAlert] - Optional function to show alerts to the user.\n * @param {boolean} options.parameters.localUIMode - Indicates if the user is in local UI mode.\n * @param {string} [options.parameters.targetResolution] - The target resolution for screen sharing.\n * @param {string} [options.parameters.targetResolutionHost] - The target resolution for screen sharing for the host.\n * @param {Function} options.parameters.startShareScreen - Function to start screen sharing.\n *\n * @returns {Promise<void>} A promise that resolves when the screen share request is processed.\n *\n * @throws {Error} Throws an error if there is an issue during the screen share request process.\n *\n * @example\n * ```typescript\n * await requestScreenShare({\n * parameters: {\n * socket: socketInstance,\n * localUIMode: false,\n * targetResolution: 'fhd',\n * startShareScreen: startShareScreenFunction,\n * // other parameters...\n * },\n * });\n * ```\n */\n\nexport async function requestScreenShare({ parameters }: RequestScreenShareOptions): Promise<void> {\n try {\n // Destructure parameters\n let {\n socket,\n showAlert,\n localUIMode,\n targetResolution = 'hd',\n targetResolutionHost = 'hd',\n\n //mediasfu functions\n startShareScreen,\n } = parameters;\n\n let targetWidth = 1280\n let targetHeight = 720\n\n if (targetResolution == 'qhd' || targetResolutionHost == 'qhd') {\n targetWidth = 2560\n targetHeight = 1440\n } else if (targetResolution == 'fhd' || targetResolutionHost == 'fhd') {\n targetWidth = 1920\n targetHeight = 1080\n } \n\n // Check if the user is in local UI mode\n if (localUIMode === true) {\n await startShareScreen({ parameters });\n return;\n }\n\n socket.emit(\"requestScreenShare\", async ({ allowScreenShare }: { allowScreenShare: boolean; }) => {\n if (!allowScreenShare) {\n // Send an alert to the user\n showAlert?.({\n message: \"You are not allowed to share screen\",\n type: \"danger\",\n duration: 3000,\n });\n } else {\n await startShareScreen({ parameters: { ...parameters, targetWidth, targetHeight } });\n }\n });\n } catch (error) {\n // Handle errors during the process of requesting screen share\n // throw new Error(`Error during requesting screen share: ${error.message}`);\n console.log(\"Error during requesting screen share: \", error);\n }\n}\n","import { Participant, Stream, ProcessConsumerTransportsAudioParameters, Transport, EventType } from '../types/types';\n\ninterface BreakoutParticipantLike {\n name: string;\n breakRoom?: number | null;\n}\n\ninterface ParticipantLike {\n name: string;\n islevel?: string | null;\n audioID?: string | null;\n producerId?: string | null;\n breakRoom?: number | null;\n}\n\ninterface MediaEntryLike {\n producerId?: string | null;\n audioID?: string | null;\n}\n\ninterface AudioTransportLike {\n producerId?: string | null;\n consumer?: {\n paused?: boolean;\n kind?: string;\n pause: () => unknown;\n resume: () => unknown;\n };\n socket_: {\n emit: (\n event: string,\n payload: { serverConsumerId: string },\n callback?: ((payload?: { resumed: boolean }) => void | Promise<unknown>)\n ) => void;\n };\n serverConsumerTransportId: string;\n}\n\nexport interface ResumePauseAudioStreamsParameters<\n TTransport extends AudioTransportLike = Transport,\n TMediaEntry extends MediaEntryLike | ParticipantLike = Stream | Participant,\n> extends ProcessConsumerTransportsAudioParameters {\n breakoutRooms: BreakoutParticipantLike[][];\n ref_participants: ParticipantLike[];\n allAudioStreams: TMediaEntry[];\n participants: ParticipantLike[];\n islevel: string;\n eventType: EventType;\n consumerTransports: TTransport[];\n limitedBreakRoom: BreakoutParticipantLike[];\n hostNewRoom: number;\n member: string;\n updateLimitedBreakRoom: (limitedBreakRoom: BreakoutParticipantLike[]) => void;\n\n // mediasfu functions\n processConsumerTransportsAudio: (options: {\n consumerTransports: TTransport[];\n lStreams: TMediaEntry[];\n parameters: ProcessConsumerTransportsAudioParameters;\n }) => Promise<void>;\n getUpdatedAllParams: () => ResumePauseAudioStreamsParameters<TTransport, TMediaEntry>;\n [key: string]: any;\n}\n\nexport interface ResumePauseAudioStreamsOptions<\n TTransport extends AudioTransportLike = Transport,\n TMediaEntry extends MediaEntryLike | ParticipantLike = Stream | Participant,\n> {\n breakRoom?: number;\n inBreakRoom?: boolean;\n parameters: ResumePauseAudioStreamsParameters<TTransport, TMediaEntry>;\n}\n\n// Export the type definition for the function\nexport type ResumePauseAudioStreamsType = (\n options: ResumePauseAudioStreamsOptions\n) => Promise<void>;\n\n/**\n * Resumes or pauses audio streams based on the provided options.\n *\n * @param {ResumePauseAudioStreamsOptions} options - The options for resuming or pausing audio streams.\n * @param {number} [options.breakRoom=-1] - The ID of the break room.\n * @param {boolean} [options.inBreakRoom=false] - Indicates if the participant is in a break room.\n * @param {ResumePauseAudioStreamsParameters} options.parameters - The parameters required for processing audio streams.\n *\n * @returns {Promise<void>} A promise that resolves when the audio streams have been processed.\n *\n * @throws Will log an error message if there is an issue processing the audio streams.\n *\n * @example\n * ```typescript\n * await resumePauseAudioStreams({\n * breakRoom: 1,\n * inBreakRoom: true,\n * parameters: {\n * // ...parameters here\n * },\n * });\n * ```\n */\n\nexport const resumePauseAudioStreams = async <\n TTransport extends AudioTransportLike = Transport,\n TMediaEntry extends MediaEntryLike | ParticipantLike = Stream | Participant,\n>({\n breakRoom = -1,\n inBreakRoom = false,\n parameters,\n}: ResumePauseAudioStreamsOptions<TTransport, TMediaEntry>): Promise<void> => {\n const { getUpdatedAllParams } = parameters;\n parameters = getUpdatedAllParams();\n\n const {\n breakoutRooms,\n ref_participants,\n allAudioStreams,\n participants,\n islevel,\n eventType,\n consumerTransports,\n hostNewRoom,\n member,\n updateLimitedBreakRoom,\n processConsumerTransportsAudio,\n } = parameters;\n\n let room: BreakoutParticipantLike[] = [];\n let currentStreams: TMediaEntry[] = [];\n // Determine the room based on breakout status\n if (inBreakRoom && breakRoom !== -1) {\n room = breakoutRooms[breakRoom];\n } else {\n room = ref_participants\n .filter((participant) =>\n !breakoutRooms\n .flat()\n .map((obj) => obj.name)\n .includes(participant!.name)\n )\n .map(({ name, breakRoom }) => ({ name, breakRoom }));\n \n }\n\n updateLimitedBreakRoom(room);\n\n try {\n let addHostAudio = false;\n\n if (islevel !== \"2\" && eventType === \"conference\") {\n const roomMember = breakoutRooms.find((r) =>\n r.find((p) => p.name === member)\n );\n let memberBreakRoom = -1;\n if (roomMember) {\n memberBreakRoom = breakoutRooms.indexOf(roomMember);\n }\n\n if (\n (inBreakRoom && breakRoom !== hostNewRoom) ||\n (!inBreakRoom && hostNewRoom !== -1 && hostNewRoom !== memberBreakRoom)\n ) {\n const host = participants.find((obj) => obj.islevel === \"2\");\n // Remove the host from the room\n room = room.filter((participant) => participant.name !== host?.name);\n } else {\n if (\n (inBreakRoom && breakRoom === hostNewRoom) ||\n (!inBreakRoom && hostNewRoom === -1) ||\n (!inBreakRoom &&\n hostNewRoom === memberBreakRoom &&\n memberBreakRoom !== -1)\n ) {\n addHostAudio = true;\n }\n }\n }\n\n for (let participant of room) {\n let streams = allAudioStreams.filter((stream) => {\n if (\n (Object.prototype.hasOwnProperty.call(stream, \"producerId\") && stream.producerId) ||\n (Object.prototype.hasOwnProperty.call(stream, \"audioID\") && stream.audioID)\n ) {\n let producerId = stream.producerId || stream.audioID;\n let matchingParticipant = ref_participants.find(\n (obj) => obj.audioID == producerId\n );\n return (\n matchingParticipant && matchingParticipant.name == participant.name\n );\n }\n // Return false if the stream doesn't meet the criteria\n return false;\n });\n\n currentStreams.push(...streams);\n }\n\n // If webinar, add the host audio stream if it is not in the currentStreams\n if (islevel !== \"2\" && (eventType === \"webinar\" || addHostAudio)) {\n const host = participants.find((obj) => obj.islevel === \"2\");\n const hostStream = allAudioStreams.find(\n (obj) => obj.producerId === host?.audioID\n );\n if (hostStream && !currentStreams.includes(hostStream)) {\n currentStreams.push(hostStream);\n if (!room.map((obj) => obj.name).includes(host?.name ?? \"\")) {\n room.push({ name: host?.name || \"\", breakRoom: -1 });\n }\n updateLimitedBreakRoom(room);\n }\n }\n\n await processConsumerTransportsAudio({\n consumerTransports,\n lStreams: currentStreams,\n parameters,\n });\n } catch (error) {\n console.log('Error in resumePauseAudioStreams:', error);\n }\n};\n","import { Participant, Transport, Stream } from \"../types/types\";\n\ninterface ParticipantLike {\n name: string;\n islevel?: string | null;\n videoID?: string | null;\n}\n\ninterface ConsumerLike {\n kind?: string;\n resume: () => unknown;\n}\n\ninterface SocketLike {\n emit: (\n event: string,\n payload: { serverConsumerId: string },\n callback?: ((payload: { resumed: boolean }) => void | Promise<unknown>)\n ) => void;\n}\n\ninterface TransportLike {\n producerId?: string | null;\n consumer: ConsumerLike;\n socket_: SocketLike;\n serverConsumerTransportId: string;\n}\n\nexport interface ResumePauseStreamsParameters<\n TParticipant extends ParticipantLike = Participant,\n TTransport extends TransportLike = Transport,\n TStream = Stream,\n> {\n participants: TParticipant[];\n dispActiveNames: string[];\n remoteScreenStream: TStream[];\n consumerTransports: TTransport[];\n screenId?: string;\n islevel: string;\n\n // mediasfu functions\n getUpdatedAllParams: () => ResumePauseStreamsParameters<TParticipant, TTransport, TStream>;\n [key: string]: any;\n}\n\nexport interface ResumePauseStreamsOptions<\n TParticipant extends ParticipantLike = Participant,\n TTransport extends TransportLike = Transport,\n TStream = Stream,\n> {\n parameters: ResumePauseStreamsParameters<TParticipant, TTransport, TStream>;\n}\n\n// Export the type definition for the function\nexport type ResumePauseStreamsType = <\n TParticipant extends ParticipantLike = Participant,\n TTransport extends TransportLike = Transport,\n TStream = Stream,\n>(options: ResumePauseStreamsOptions<TParticipant, TTransport, TStream>) => Promise<void>;\n\n/**\n * Resumes or pauses streams based on the provided parameters.\n *\n * @param {ResumePauseStreamsOptions} options - The options for resuming or pausing streams.\n * @param {Object} options.parameters - The parameters for the function.\n * @param {Array} options.parameters.participants - The list of participants.\n * @param {Array} options.parameters.dispActiveNames - The list of active display names.\n * @param {Array} options.parameters.consumerTransports - The list of consumer transports.\n * @param {string} [options.parameters.screenId] - The screen producer ID.\n * @param {string} options.parameters.islevel - The level of the user.\n *\n * @returns {Promise<void>} A promise that resolves when the streams have been resumed or paused.\n *\n * @throws Will throw an error if there is an issue during the process of resuming or pausing streams.\n *\n * @example\n * ```typescript\n * await resumePauseStreams({\n * parameters: {\n * participants: participantArray,\n * dispActiveNames: ['user1', 'user2'],\n * consumerTransports: transportArray,\n * screenId: 'screen-123',\n * islevel: '1',\n * },\n * });\n * ```\n */\n\nexport async function resumePauseStreams<\n TParticipant extends ParticipantLike = Participant,\n TTransport extends TransportLike = Transport,\n TStream = Stream,\n>({\n parameters,\n}: ResumePauseStreamsOptions<TParticipant, TTransport, TStream>): Promise<void> {\n try {\n // Destructure parameters\n const { participants, dispActiveNames, consumerTransports, screenId, islevel } = parameters;\n\n // Get the videoID of the host (islevel=2)\n const host = participants.find((obj) => obj.islevel === \"2\");\n const hostVideoID = host ? host.videoID : null;\n\n // Get videoIDs of participants in dispActiveNames and screenproducerId\n const videosIDs = dispActiveNames.map((name) => {\n const participant = participants.find((obj) => obj.name === name);\n return participant ? participant.videoID : null;\n });\n\n // Add screenproducerId to allVideoIDs if it's not null or empty\n if (screenId) {\n videosIDs.push(screenId);\n }\n\n // Add hostVideoID to allVideoIDs if it's not null or empty (only if the user is not the host)\n if (islevel !== \"2\" && hostVideoID) {\n videosIDs.push(hostVideoID);\n }\n\n // Remove null or empty videoIDs\n const allVideoIDs = videosIDs.filter(\n (videoID): videoID is string => videoID !== null && videoID !== \"\"\n );\n\n if (allVideoIDs.length > 0) {\n // Get consumer transports with producerId in allVideoIDs\n const consumerTransportsToResume = consumerTransports.filter(\n (transport) =>\n transport.producerId &&\n allVideoIDs.includes(transport.producerId) &&\n transport.consumer.kind !== \"audio\"\n );\n\n // Resume all consumerTransportsToResume\n for (const transport of consumerTransportsToResume) {\n transport.socket_.emit(\n \"consumer-resume\",\n { serverConsumerId: transport.serverConsumerTransportId },\n async ({ resumed }: { resumed: boolean }) => {\n if (resumed) {\n transport.consumer.resume();\n }\n }\n );\n }\n }\n } catch (error) {\n console.log(\"Error during resuming or pausing streams: \", error);\n // Handle errors during the process of resuming or pausing streams\n }\n}\n\n"," \nimport { Participant, Stream, EventType } from \"../types/types\";\n\ninterface ReUpdateInterStreamLike {\n producerId?: string | null;\n}\n\ninterface ReUpdateInterParticipantLike {\n name: string;\n videoID?: string | null;\n muted?: boolean | null;\n}\n\ntype BooleanUpdater = (value: boolean) => void;\ntype NumberUpdater = (value: number) => void;\ntype StringListUpdater = (ids: string[]) => void;\n\ntype OnScreenChangesInvoker = (options: {\n changed?: boolean;\n parameters: any;\n}) => Promise<void>;\n\ntype ReorderStreamsInvoker = (options: {\n add?: boolean;\n screenChanged?: boolean;\n parameters: any;\n}) => Promise<void>;\n\ntype ChangeVidsInvoker = (options: {\n screenChanged?: boolean;\n parameters: any;\n}) => Promise<void>;\n\nexport interface ReUpdateInterParameters<\n TStream extends ReUpdateInterStreamLike = Stream,\n TParticipant extends ReUpdateInterParticipantLike = Participant,\n> {\n screenPageLimit: number;\n itemPageLimit: number;\n reorderInterval: number;\n fastReorderInterval: number;\n eventType: EventType;\n participants: TParticipant[];\n allVideoStreams: (TParticipant | TStream)[];\n shared: boolean;\n shareScreenStarted: boolean;\n adminNameStream?: string;\n screenShareNameStream?: string;\n updateMainWindow: boolean;\n sortAudioLoudness: boolean;\n lastReorderTime: number;\n newLimitedStreams: (TParticipant | TStream)[];\n newLimitedStreamsIDs: string[];\n oldSoundIds: string[];\n updateUpdateMainWindow: BooleanUpdater;\n updateSortAudioLoudness: BooleanUpdater;\n updateLastReorderTime: NumberUpdater;\n updateNewLimitedStreams: (streams: (TParticipant | TStream)[]) => void;\n updateNewLimitedStreamsIDs: StringListUpdater;\n updateOldSoundIds: StringListUpdater;\n\n // mediasfu functions\n onScreenChanges: OnScreenChangesInvoker;\n reorderStreams: ReorderStreamsInvoker;\n changeVids: ChangeVidsInvoker;\n\n getUpdatedAllParams: () => ReUpdateInterParameters<TStream, TParticipant>;\n [key: string]: any;\n}\n\nexport interface ReUpdateInterOptions<\n TParameters extends ReUpdateInterParameters<any, any> = ReUpdateInterParameters,\n> {\n name: string;\n add?: boolean;\n force?: boolean;\n average?: number;\n parameters: TParameters;\n}\n\n// Export the type definition for the function\nexport type ReUpdateInterType = <\n TParameters extends ReUpdateInterParameters<any, any> = ReUpdateInterParameters,\n>(options: ReUpdateInterOptions<TParameters>) => Promise<void>;\n\n/**\n * Updates the interaction state based on the provided options and parameters.\n * \n * @param {ReUpdateInterOptions} options - The options for updating the interaction.\n * @param {string} options.name - The name of the participant.\n * @param {boolean} [options.add=false] - Whether to add the participant to the interaction.\n * @param {boolean} [options.force=false] - Whether to force the update.\n * @param {number} [options.average=127] - The average value used for determining reorder intervals.\n * @param {Object} options.parameters - The parameters for updating the interaction.\n * @param {number} options.parameters.screenPageLimit - The screen page limit.\n * @param {number} options.parameters.itemPageLimit - The item page limit.\n * @param {number} options.parameters.reorderInterval - The reorder interval.\n * @param {number} options.parameters.fastReorderInterval - The fast reorder interval.\n * @param {string} options.parameters.eventType - The type of event.\n * @param {Array} options.parameters.participants - The list of participants.\n * @param {Array} options.parameters.allVideoStreams - The list of all video streams.\n * @param {boolean} options.parameters.shared - Whether the screen is shared.\n * @param {boolean} options.parameters.shareScreenStarted - Whether screen sharing has started.\n * @param {string} options.parameters.adminNameStream - The admin name stream.\n * @param {string} options.parameters.screenShareNameStream - The screen share name stream.\n * @param {boolean} options.parameters.updateMainWindow - Whether to update the main window.\n * @param {boolean} options.parameters.sortAudioLoudness - Whether to sort audio by loudness.\n * @param {number} options.parameters.lastReorderTime - The last reorder time.\n * @param {Array} options.parameters.newLimitedStreams - The list of new limited streams.\n * @param {Array} options.parameters.newLimitedStreamsIDs - The list of new limited stream IDs.\n * @param {Array} options.parameters.oldSoundIds - The list of old sound IDs.\n * @param {Function} options.parameters.updateUpdateMainWindow - Function to update the main window.\n * @param {Function} options.parameters.updateSortAudioLoudness - Function to update the audio loudness sorting.\n * @param {Function} options.parameters.updateLastReorderTime - Function to update the last reorder time.\n * @param {Function} options.parameters.updateNewLimitedStreams - Function to update the new limited streams.\n * @param {Function} options.parameters.updateNewLimitedStreamsIDs - Function to update the new limited stream IDs.\n * @param {Function} options.parameters.updateOldSoundIds - Function to update the old sound IDs.\n * @param {Function} options.parameters.onScreenChanges - Function to handle screen changes.\n * @param {Function} options.parameters.reorderStreams - Function to reorder streams.\n * @param {Function} options.parameters.changeVids - Function to change videos.\n * \n * @returns {Promise<void>} A promise that resolves when the interaction update is complete.\n *\n * @throws {Error} Throws an error if there is an issue during the updating process.\n *\n * @example\n * ```typescript\n * await reUpdateInter({\n * name: 'participant1',\n * add: true,\n * parameters: {\n * screenPageLimit: 4,\n * itemPageLimit: 2,\n * reorderInterval: 500,\n * fastReorderInterval: 200,\n * eventType: 'conference',\n * participants: [...],\n * allVideoStreams: [...],\n * shared: false,\n * shareScreenStarted: false,\n * adminNameStream: 'Admin',\n * screenShareNameStream: 'Screen Share',\n * updateMainWindow: true,\n * sortAudioLoudness: false,\n * lastReorderTime: Date.now(),\n * newLimitedStreams: [],\n * newLimitedStreamsIDs: [],\n * oldSoundIds: [],\n * updateUpdateMainWindow: (value) => { console.log('your logic') },\n * updateSortAudioLoudness: (value) => { console.log('your logic') },\n * updateLastReorderTime: (value) => { console.log('your logic') },\n * updateNewLimitedStreams: (streams) => { console.log('your logic') },\n * updateNewLimitedStreamsIDs: (ids) => { console.log('your logic') },\n * updateOldSoundIds: (ids) => { console.log('your logic') },\n * onScreenChanges: async (options) => { console.log('your logic') },\n * reorderStreams: async (options) => { console.log('your logic') },\n * changeVids: async (options) => { console.log('your logic') },\n * },\n * });\n * ```\n */\n\n\nexport async function reUpdateInter<\n TParameters extends ReUpdateInterParameters<any, any> = ReUpdateInterParameters,\n>({\n name,\n add = false,\n force = false,\n average = 127,\n parameters,\n}: ReUpdateInterOptions<TParameters>): Promise<void> {\n let {\n screenPageLimit,\n itemPageLimit,\n reorderInterval,\n fastReorderInterval,\n eventType,\n participants,\n allVideoStreams,\n shared,\n shareScreenStarted,\n adminNameStream,\n screenShareNameStream,\n updateMainWindow,\n sortAudioLoudness,\n lastReorderTime,\n newLimitedStreams,\n newLimitedStreamsIDs,\n oldSoundIds,\n updateUpdateMainWindow,\n updateSortAudioLoudness,\n updateLastReorderTime,\n updateNewLimitedStreams,\n updateNewLimitedStreamsIDs,\n updateOldSoundIds,\n\n //mediasfu functions\n onScreenChanges,\n reorderStreams,\n changeVids,\n } = parameters as TParameters;\n\n if (eventType === \"broadcast\" || eventType === \"chat\") {\n return;\n }\n\n let refLimit = screenPageLimit - 1;\n\n if (!(shareScreenStarted || shared)) {\n refLimit = itemPageLimit - 1;\n\n if (add) {\n const currentTime = Date.now();\n if (\n (currentTime - lastReorderTime >= reorderInterval && average > 128.5) ||\n (average > 130 && currentTime - lastReorderTime >= fastReorderInterval)\n ) {\n lastReorderTime = currentTime;\n sortAudioLoudness = true;\n if (eventType === \"conference\") {\n await onScreenChanges({ changed: true, parameters });\n } else {\n await reorderStreams({ add: false, screenChanged: true, parameters });\n }\n sortAudioLoudness = false;\n\n updateSortAudioLoudness(sortAudioLoudness);\n updateUpdateMainWindow(updateMainWindow);\n updateLastReorderTime(lastReorderTime);\n\n return;\n }\n }\n }\n\n let videoID: string | null = null;\n if (shareScreenStarted || shared) {\n if (add) {\n const participant = participants.find((p) => p.name === name);\n videoID = participant?.videoID ?? null;\n\n if (!videoID) {\n return;\n }\n\n if (!newLimitedStreamsIDs.includes(videoID)) {\n //first check length of newLimitedStreams to not exceed refLimit, if so remove oldSoundID from newLimitedStreams\n if (newLimitedStreams.length > refLimit) {\n let oldoldSounds = [...oldSoundIds];\n for (let i = 0; i < oldSoundIds.length; i++) {\n if (newLimitedStreams.length > refLimit) {\n // remove stream from newLimitedStreams\n if (newLimitedStreams.length < screenPageLimit) {\n return;\n }\n const currentId = oldSoundIds[i];\n if (\n currentId !== screenShareNameStream &&\n currentId !== adminNameStream\n ) {\n newLimitedStreams = newLimitedStreams.filter(\n (stream) => stream.producerId !== currentId\n );\n newLimitedStreamsIDs = newLimitedStreamsIDs.filter(\n (id) => id !== currentId\n );\n oldoldSounds = oldoldSounds.filter((id) => id !== currentId);\n }\n }\n }\n oldSoundIds = [...oldoldSounds];\n }\n\n const stream = allVideoStreams.find(\n (s) => s.producerId === videoID\n );\n if (stream && newLimitedStreams.length < screenPageLimit) {\n newLimitedStreams.push(stream);\n newLimitedStreamsIDs.push(videoID);\n if (!oldSoundIds.includes(name)) {\n oldSoundIds.push(name);\n }\n await changeVids({ screenChanged: true, parameters });\n }\n }\n } else {\n if (!force) {\n try {\n // remove stream from newLimitedStreams\n if (newLimitedStreams.length < screenPageLimit) {\n return;\n }\n newLimitedStreams = newLimitedStreams.filter(\n (stream) => stream.producerId != videoID\n );\n newLimitedStreamsIDs = newLimitedStreamsIDs.filter(\n (id) => id !== videoID\n );\n oldSoundIds = oldSoundIds.filter((id) => id !== name);\n await changeVids({ parameters });\n } catch {\n // do nothing\n }\n } else {\n const participant = participants.find((p) => p.name === name);\n if (participant?.muted) {\n try {\n newLimitedStreams = newLimitedStreams.filter(\n (stream) => stream.producerId !== videoID\n );\n newLimitedStreamsIDs = newLimitedStreamsIDs.filter(\n (id) => id !== videoID\n );\n oldSoundIds = oldSoundIds.filter((id) => id !== name);\n await changeVids({ parameters });\n } catch { \n // do nothing\n }\n }\n }\n }\n\n updateNewLimitedStreams(newLimitedStreams);\n updateNewLimitedStreamsIDs(newLimitedStreamsIDs);\n updateOldSoundIds(oldSoundIds);\n }\n}\n\n","\nimport { StreamSuccessScreenType, StreamSuccessScreenParameters, ShowAlert } from \"../types/types\";\nimport {\n buildDisplayMediaOptions,\n canCaptureDisplayAudio,\n shouldShareScreenAudio,\n ScreenAudioChoice,\n ScreenAudioMode,\n} from \"./screenAudio\";\nexport interface StartShareScreenParameters extends StreamSuccessScreenParameters {\n shared: boolean;\n showAlert?: ShowAlert;\n updateShared: (shared: boolean) => void;\n mediaDevices: MediaDevices;\n onWeb: boolean;\n targetWidth?: number;\n targetHeight?: number;\n /** Set from the join response: the media server accepts screen audio. */\n supportsScreenAudio?: boolean;\n /** Ask the browser for the screen's audio too (default true; the browser's picker still lets the user decide). */\n screenAudioEnabled?: boolean;\n /** `ask` (default): offer \"Screen + audio\" / \"Screen only\" first; `always`: request audio; `never`: video only. */\n screenAudioMode?: ScreenAudioMode;\n /**\n * The \"share audio too?\" dialog: resolve `audio`, `video` or `null` (cancel). Each UI SDK supplies its own. Without\n * one, `ask` requests audio and leaves the choice to the browser picker's own \"share audio\" checkbox.\n */\n screenAudioPrompt?: () => Promise<ScreenAudioChoice>;\n /** Override browser detection of display-audio capture (Chromium desktop by default). */\n displayAudioCapable?: boolean;\n\n // mediasfu functions\n streamSuccessScreen: StreamSuccessScreenType;\n [key: string]: any;\n}\n\nexport interface StartShareScreenOptions {\n parameters: StartShareScreenParameters;\n}\n\n// Export the type definition for the function\nexport type StartShareScreenType = (options: StartShareScreenOptions) => Promise<void>;\n\n/**\n * Starts the screen sharing process.\n *\n * @param {StartShareScreenOptions} options - The options for starting screen sharing.\n * @param {Object} options.parameters - The parameters for screen sharing.\n * @param {boolean} options.parameters.shared - Indicates if the screen is currently being shared.\n * @param {Function} options.parameters.showAlert - Function to show alert messages.\n * @param {Function} options.parameters.updateShared - Function to update the shared state.\n * @param {MediaDevices} options.parameters.mediaDevices - The media devices available for screen sharing.\n * @param {boolean} options.parameters.onWeb - Indicates if the application is running on a web platform.\n * @param {number} [options.parameters.targetWidth] - The target width for screen sharing.\n * @param {number} [options.parameters.targetHeight] - The target height for screen sharing.\n * @param {Function} options.parameters.streamSuccessScreen - Function to handle successful screen sharing.\n * \n * @returns {Promise<void>} A promise that resolves when the screen sharing process is complete.\n * \n * @throws Will log an error message if there is an issue starting the screen share.\n *\n * @example\n * const options = {\n * parameters: {\n * shared: false,\n * showAlert: showAlertFunction,\n * updateShared: updateSharedFunction,\n * mediaDevices: navigator.mediaDevices,\n * onWeb: true,\n * targetWidth: 1280,\n * targetHeight: 720,\n * streamSuccessScreen: streamSuccessFunction,\n * },\n * };\n * \n * startShareScreen(options)\n * .then(() => {\n * console.log('Screen sharing started successfully');\n * })\n * .catch(error => {\n * console.error('Error starting screen share:', error);\n * });\n */\n\nexport async function startShareScreen({ parameters }: StartShareScreenOptions): Promise<void> {\n let {\n shared,\n showAlert,\n updateShared,\n mediaDevices,\n onWeb,\n targetWidth = 1280,\n targetHeight = 720,\n supportsScreenAudio,\n screenAudioEnabled,\n screenAudioMode = \"ask\",\n screenAudioPrompt,\n displayAudioCapable,\n\n streamSuccessScreen,\n } = parameters;\n\n try {\n if (!onWeb) {\n showAlert?.({\n message: \"You cannot share screen while on mobile\",\n type: \"danger\",\n duration: 3000,\n });\n return;\n }\n\n if (mediaDevices && mediaDevices.getDisplayMedia) {\n // Screen audio needs a server that accepts it and a browser that can capture it (Chromium desktop).\n let withAudio =\n shouldShareScreenAudio({ supportsScreenAudio, screenAudioEnabled, screenAudioMode }) &&\n (displayAudioCapable ?? canCaptureDisplayAudio());\n if (withAudio && screenAudioMode === \"ask\" && screenAudioPrompt) {\n const choice = await screenAudioPrompt();\n if (choice === null) {\n updateShared(false);\n return;\n }\n withAudio = choice === \"audio\";\n }\n shared = true;\n await mediaDevices\n .getDisplayMedia(\n buildDisplayMediaOptions({\n targetWidth,\n targetHeight,\n withAudio,\n })\n )\n .then(async (stream: MediaStream) => {\n await streamSuccessScreen({ stream, parameters });\n })\n .catch(async () => {\n shared = false;\n showAlert?.({\n message: \"Could not share screen, check and retry\",\n type: \"danger\",\n duration: 3000,\n });\n });\n } else {\n showAlert?.({\n message: \"Could not share screen, check and retry\",\n type: \"danger\",\n duration: 3000,\n });\n }\n\n // Update the shared variable\n updateShared(shared);\n } catch (error) {\n console.log(\"Error starting screen share\", error);\n }\n}\n\n","import { DisconnectSendTransportScreenType, PrepopulateUserMediaType, ReorderStreamsType, GetVideosType, DisconnectSendTransportScreenParameters, PrepopulateUserMediaParameters, ReorderStreamsParameters, EventType } from '../types/types';\nexport interface StopShareScreenParameters extends DisconnectSendTransportScreenParameters, PrepopulateUserMediaParameters, ReorderStreamsParameters {\n shared: boolean;\n shareScreenStarted: boolean;\n shareEnded: boolean;\n updateMainWindow: boolean;\n defer_receive: boolean;\n hostLabel: string;\n lock_screen: boolean;\n forceFullDisplay: boolean;\n firstAll: boolean;\n first_round: boolean;\n localStreamScreen: MediaStream | null;\n eventType: EventType;\n prevForceFullDisplay: boolean;\n annotateScreenStream: boolean;\n\n updateShared: (shared: boolean) => void;\n updateShareScreenStarted: (shareScreenStarted: boolean) => void;\n updateShareEnded: (shareEnded: boolean) => void;\n updateUpdateMainWindow: (updateMainWindow: boolean) => void;\n updateDefer_receive: (defer_receive: boolean) => void;\n updateLock_screen: (lock_screen: boolean) => void;\n updateForceFullDisplay: (forceFullDisplay: boolean) => void;\n updateFirstAll: (firstAll: boolean) => void;\n updateFirst_round: (first_round: boolean) => void;\n updateLocalStreamScreen: (localStreamScreen: MediaStream | null) => void;\n updateMainHeightWidth: (mainHeightWidth: number) => void;\n updateAnnotateScreenStream: (annotateScreenStream: boolean) => void;\n updateIsScreenboardModalVisible: (isVisible: boolean) => void;\n\n // mediasfu functions\n disconnectSendTransportScreen: DisconnectSendTransportScreenType;\n prepopulateUserMedia: PrepopulateUserMediaType;\n reorderStreams: ReorderStreamsType;\n getVideos: GetVideosType;\n\n getUpdatedAllParams: () => StopShareScreenParameters;\n [key: string]: any;\n}\n\nexport interface StopShareScreenOptions {\n parameters: StopShareScreenParameters;\n}\n\n// Export the type definition for the function\nexport type StopShareScreenType = (options: StopShareScreenOptions) => Promise<void>;\n\n/**\n * Stops the screen sharing process and updates the relevant parameters and states.\n * \n * @param {StopShareScreenOptions} options - The options for stopping the screen share.\n * @param {Object} options.parameters - The parameters required for stopping the screen share.\n * @param {Function} options.parameters.getUpdatedAllParams - Function to get updated parameters.\n * @param {boolean} options.parameters.shared - Indicates if the screen is currently shared.\n * @param {boolean} options.parameters.shareScreenStarted - Indicates if the screen sharing has started.\n * @param {boolean} options.parameters.shareEnded - Indicates if the screen sharing has ended.\n * @param {boolean} options.parameters.updateMainWindow - Indicates if the main window needs to be updated.\n * @param {boolean} options.parameters.defer_receive - Indicates if receiving is deferred.\n * @param {string} options.parameters.hostLabel - The label of the host.\n * @param {boolean} options.parameters.lock_screen - Indicates if the screen is locked.\n * @param {boolean} options.parameters.forceFullDisplay - Indicates if full display is forced.\n * @param {boolean} options.parameters.firstAll - Indicates if it is the first all.\n * @param {boolean} options.parameters.first_round - Indicates if it is the first round.\n * @param {MediaStream} options.parameters.localStreamScreen - The local screen stream.\n * @param {string} options.parameters.eventType - The type of event.\n * @param {boolean} options.parameters.prevForceFullDisplay - Indicates if full display was previously forced.\n * @param {boolean} options.parameters.annotateScreenStream - Indicates if the screen stream is annotated.\n * @param {Function} options.parameters.updateShared - Function to update the shared state.\n * @param {Function} options.parameters.updateShareScreenStarted - Function to update the share screen started state.\n * @param {Function} options.parameters.updateShareEnded - Function to update the share ended state.\n * @param {Function} options.parameters.updateUpdateMainWindow - Function to update the main window state.\n * @param {Function} options.parameters.updateDefer_receive - Function to update the defer receive state.\n * @param {Function} options.parameters.updateLock_screen - Function to update the lock screen state.\n * @param {Function} options.parameters.updateForceFullDisplay - Function to update the force full display state.\n * @param {Function} options.parameters.updateFirstAll - Function to update the first all state.\n * @param {Function} options.parameters.updateFirst_round - Function to update the first round state.\n * @param {Function} options.parameters.updateLocalStreamScreen - Function to update the local screen stream.\n * @param {Function} options.parameters.updateMainHeightWidth - Function to update the main height and width.\n * @param {Function} options.parameters.updateAnnotateScreenStream - Function to update the annotate screen stream state.\n * @param {Function} options.parameters.updateIsScreenboardModalVisible - Function to update the screenboard modal visibility.\n * @param {Function} options.parameters.disconnectSendTransportScreen - Function to disconnect the send transport screen.\n * @param {Function} options.parameters.prepopulateUserMedia - Function to prepopulate user media.\n * @param {Function} options.parameters.reorderStreams - Function to reorder streams.\n * @param {Function} options.parameters.getVideos - Function to get videos.\n * \n * @returns {Promise<void>} A promise that resolves when the screen sharing process is stopped.\n *\n * @example\n * const options = {\n * parameters: {\n * shared: true,\n * shareScreenStarted: true,\n * shareEnded: false,\n * updateMainWindow: true,\n * defer_receive: false,\n * hostLabel: \"Host\",\n * lock_screen: false,\n * forceFullDisplay: false,\n * firstAll: false,\n * first_round: false,\n * localStreamScreen: localStream, // MediaStream object\n * eventType: \"conference\",\n * prevForceFullDisplay: false,\n * annotateScreenStream: false,\n * updateShared: updateSharedFunction,\n * updateShareScreenStarted: updateShareScreenStartedFunction,\n * updateShareEnded: updateShareEndedFunction,\n * updateUpdateMainWindow: updateUpdateMainWindowFunction,\n * updateDefer_receive: updateDefer_receiveFunction,\n * updateLock_screen: updateLock_screenFunction,\n * updateForceFullDisplay: updateForceFullDisplayFunction,\n * updateFirstAll: updateFirstAllFunction,\n * updateFirst_round: updateFirst_roundFunction,\n * updateLocalStreamScreen: updateLocalStreamScreenFunction,\n * updateMainHeightWidth: updateMainHeightWidthFunction,\n * updateAnnotateScreenStream: updateAnnotateScreenStreamFunction,\n * updateIsScreenboardModalVisible: updateIsScreenboardModalVisibleFunction,\n * disconnectSendTransportScreen: disconnectSendTransportScreenFunction,\n * prepopulateUserMedia: prepopulateUserMediaFunction,\n * reorderStreams: reorderStreamsFunction,\n * getVideos: getVideosFunction,\n * },\n * };\n * \n * stopShareScreen(options)\n * .then(() => {\n * console.log('Screen sharing stopped successfully');\n * })\n * .catch(error => {\n * console.error('Error stopping screen share:', error);\n * });\n */\n\nexport async function stopShareScreen({ parameters }: StopShareScreenOptions): Promise<void> {\n let { getUpdatedAllParams } = parameters;\n parameters = getUpdatedAllParams();\n\n let {\n shared,\n shareScreenStarted,\n shareEnded,\n updateMainWindow,\n defer_receive,\n hostLabel,\n lock_screen,\n forceFullDisplay,\n firstAll,\n first_round,\n localStreamScreen,\n eventType,\n prevForceFullDisplay,\n annotateScreenStream,\n\n updateShared,\n updateShareScreenStarted,\n updateShareEnded,\n updateUpdateMainWindow,\n updateDefer_receive,\n updateLock_screen,\n updateForceFullDisplay,\n updateFirstAll,\n updateFirst_round,\n updateLocalStreamScreen,\n updateMainHeightWidth,\n updateAnnotateScreenStream,\n updateIsScreenboardModalVisible,\n\n disconnectSendTransportScreen,\n prepopulateUserMedia,\n reorderStreams,\n getVideos,\n } = parameters;\n\n shared = false;\n updateShared(shared);\n shareScreenStarted = false;\n updateShareScreenStarted(shareScreenStarted);\n shareEnded = true;\n updateShareEnded(shareEnded);\n updateMainWindow = true;\n updateUpdateMainWindow(updateMainWindow);\n\n if (defer_receive) {\n defer_receive = false;\n updateDefer_receive(defer_receive);\n await getVideos({ \n participants: parameters.participants,\n allVideoStreams: parameters.allVideoStreams,\n oldAllStreams: parameters.oldAllStreams,\n adminVidID: parameters.adminVidID,\n updateAllVideoStreams: parameters.updateAllVideoStreams,\n updateOldAllStreams: parameters.updateOldAllStreams\n });\n }\n try {\n localStreamScreen!.getTracks().forEach(track => track.stop());\n } catch {\n // Do nothing\n }\n updateLocalStreamScreen(null);\n await disconnectSendTransportScreen({ parameters });\n\n try {\n if (annotateScreenStream) {\n annotateScreenStream = false;\n updateAnnotateScreenStream(annotateScreenStream);\n updateIsScreenboardModalVisible(true);\n await new Promise(resolve => setTimeout(resolve, 500));\n updateIsScreenboardModalVisible(false);\n }\n } catch (error) {\n console.log('Error handling screen annotation:', error);\n }\n\n if (eventType === 'conference') {\n updateMainHeightWidth(0);\n }\n\n try {\n await prepopulateUserMedia({ name: hostLabel, parameters });\n } catch (error) {\n console.log(\"Error in prepopulateUserMedia\", error);\n }\n\n try {\n await reorderStreams({ add: false, screenChanged: true, parameters });\n } catch (error) {\n console.log(\"Error in reorderStreams\", error);\n }\n\n lock_screen = false;\n updateLock_screen(lock_screen);\n forceFullDisplay = prevForceFullDisplay;\n updateForceFullDisplay(forceFullDisplay);\n firstAll = false;\n updateFirstAll(firstAll);\n first_round = false;\n updateFirst_round(first_round);\n}\n\n"," \n\nimport { Socket } from \"socket.io-client\";\nimport type { ProducerOptions } from 'mediasoup-client/types';\nimport { Participant, PrepopulateUserMediaParameters, ShowAlert, CreateSendTransportParameters, ConnectSendTransportAudioParameters, ResumeSendTransportAudioParameters, PrepopulateUserMediaType, CreateSendTransportType, ConnectSendTransportAudioType, ResumeSendTransportAudioType } from \"../types/types\";\nexport interface StreamSuccessAudioParameters extends CreateSendTransportParameters, ConnectSendTransportAudioParameters, ResumeSendTransportAudioParameters, PrepopulateUserMediaParameters {\n socket: Socket;\n participants: Participant[];\n localStream: MediaStream | null;\n transportCreated: boolean;\n transportCreatedAudio: boolean;\n audioAlreadyOn: boolean;\n micAction: boolean;\n audioParams: ProducerOptions;\n localStreamAudio: MediaStream | null;\n defAudioID: string;\n userDefaultAudioInputDevice: string;\n params: ProducerOptions;\n audioParamse?: ProducerOptions;\n aParams: ProducerOptions;\n hostLabel: string;\n islevel: string;\n member: string;\n updateMainWindow: boolean;\n lock_screen: boolean;\n shared: boolean;\n videoAlreadyOn: boolean;\n showAlert?: ShowAlert;\n\n updateParticipants: (participants: Participant[]) => void;\n updateTransportCreated: (transportCreated: boolean) => void;\n updateTransportCreatedAudio: (transportCreatedAudio: boolean) => void;\n updateAudioAlreadyOn: (audioAlreadyOn: boolean) => void;\n updateMicAction: (micAction: boolean) => void;\n updateAudioParams: (audioParams: ProducerOptions) => void;\n updateLocalStream: (localStream: MediaStream | null) => void;\n updateLocalStreamAudio: (localStreamAudio: MediaStream | null) => void;\n updateDefAudioID: (defAudioID: string) => void;\n updateUserDefaultAudioInputDevice: (userDefaultAudioInputDevice: string) => void;\n updateUpdateMainWindow: (updateMainWindow: boolean) => void;\n\n // mediasfu functions\n createSendTransport: CreateSendTransportType;\n connectSendTransportAudio: ConnectSendTransportAudioType;\n resumeSendTransportAudio: ResumeSendTransportAudioType;\n prepopulateUserMedia: PrepopulateUserMediaType;\n \n getUpdatedAllParams: () => StreamSuccessAudioParameters;\n [key: string]: any;\n}\n\nexport interface StreamSuccessAudioOptions {\n stream: MediaStream;\n parameters: StreamSuccessAudioParameters;\n}\n\n// Export the type definition for the function\nexport type StreamSuccessAudioType = (options: StreamSuccessAudioOptions) => Promise<void>;\n\n/**\n * Handles the successful streaming of audio by setting up the necessary transports and updating the relevant states.\n *\n * @param {StreamSuccessAudioOptions} options - The options for streaming success audio.\n * @param {MediaStream} options.stream - The media stream containing the audio track.\n * @param {Object} options.parameters - The parameters required for setting up the audio stream.\n * @param {Socket} options.parameters.socket - The socket connection for communication.\n * @param {Array<Participant>} options.parameters.participants - The list of participants.\n * @param {MediaStream | null} options.parameters.localStream - The local media stream.\n * @param {boolean} options.parameters.transportCreated - Flag indicating if the transport is created.\n * @param {boolean} options.parameters.transportCreatedAudio - Flag indicating if the audio transport is created.\n * @param {boolean} options.parameters.audioAlreadyOn - Flag indicating if the audio is already on.\n * @param {boolean} options.parameters.micAction - Flag indicating the microphone action.\n * @param {ProducerOptions} options.parameters.audioParams - The audio parameters.\n * @param {MediaStream | null} options.parameters.localStreamAudio - The local audio stream.\n * @param {string} options.parameters.defAudioID - The default audio device ID.\n * @param {string} options.parameters.userDefaultAudioInputDevice - The user default audio input device.\n * @param {ProducerOptions} options.parameters.params - Additional parameters.\n * @param {ProducerOptions} options.parameters.audioParamse - Additional audio parameters.\n * @param {ProducerOptions} options.parameters.aParams - Additional parameters for audio.\n * @param {string} options.parameters.hostLabel - The label of the host.\n * @param {string} options.parameters.islevel - The level of the user.\n * @param {string} options.parameters.member - The member name.\n * @param {boolean} options.parameters.updateMainWindow - Flag indicating if the main window should be updated.\n * @param {boolean} options.parameters.lock_screen - Flag indicating if the screen is locked.\n * @param {boolean} options.parameters.shared - Flag indicating if the screen is shared.\n * @param {boolean} options.parameters.videoAlreadyOn - Flag indicating if the video is already on.\n * @param {Function} options.parameters.showAlert - Function to show alert messages.\n * @param {Function} options.parameters.updateParticipants - Function to update participants.\n * @param {Function} options.parameters.updateTransportCreated - Function to update transport created flag.\n * @param {Function} options.parameters.updateTransportCreatedAudio - Function to update audio transport created flag.\n * @param {Function} options.parameters.updateAudioAlreadyOn - Function to update audio already on flag.\n * @param {Function} options.parameters.updateMicAction - Function to update microphone action flag.\n * @param {Function} options.parameters.updateAudioParams - Function to update audio parameters.\n * @param {Function} options.parameters.updateLocalStream - Function to update local stream.\n * @param {Function} options.parameters.updateLocalStreamAudio - Function to update local audio stream.\n * @param {Function} options.parameters.updateDefAudioID - Function to update default audio device ID.\n * @param {Function} options.parameters.updateUserDefaultAudioInputDevice - Function to update user default audio input device.\n * @param {Function} options.parameters.updateUpdateMainWindow - Function to update main window flag.\n * @param {Function} options.parameters.createSendTransport - Function to create send transport.\n * @param {Function} options.parameters.connectSendTransportAudio - Function to connect send transport audio.\n * @param {Function} options.parameters.resumeSendTransportAudio - Function to resume send transport audio.\n * @param {Function} options.parameters.prepopulateUserMedia - Function to prepopulate user media.\n *\n * @returns {Promise<void>} A promise that resolves when the audio streaming setup is complete.\n *\n * @example\n * const options = {\n * stream: localStream, // MediaStream object containing the audio track\n * parameters: {\n * socket: socketInstance,\n * participants: participantList,\n * localStream: null,\n * transportCreated: false,\n * transportCreatedAudio: false,\n * audioAlreadyOn: false,\n * micAction: false,\n * audioParams: {},\n * localStreamAudio: null,\n * defAudioID: \"\",\n * userDefaultAudioInputDevice: \"\",\n * params: {},\n * audioParamse: {},\n * aParams: {},\n * hostLabel: \"Host\",\n * islevel: \"1\",\n * member: \"user1\",\n * updateMainWindow: true,\n * lock_screen: false,\n * shared: false,\n * videoAlreadyOn: false,\n * showAlert: alertFunction,\n * updateParticipants: updateParticipantsFunction,\n * updateTransportCreated: updateTransportCreatedFunction,\n * updateTransportCreatedAudio: updateTransportCreatedAudioFunction,\n * updateAudioAlreadyOn: updateAudioAlreadyOnFunction,\n * updateMicAction: updateMicActionFunction,\n * updateAudioParams: updateAudioParamsFunction,\n * updateLocalStream: updateLocalStreamFunction,\n * updateLocalStreamAudio: updateLocalStreamAudioFunction,\n * updateDefAudioID: updateDefAudioIDFunction,\n * updateUserDefaultAudioInputDevice: updateUserDefaultAudioInputDeviceFunction,\n * updateUpdateMainWindow: updateUpdateMainWindowFunction,\n * createSendTransport: createSendTransportFunction,\n * connectSendTransportAudio: connectSendTransportAudioFunction,\n * resumeSendTransportAudio: resumeSendTransportAudioFunction,\n * prepopulateUserMedia: prepopulateUserMediaFunction,\n * },\n * };\n * \n * streamSuccessAudio(options)\n * .then(() => {\n * console.log('Audio streaming setup successfully');\n * })\n * .catch(error => {\n * console.error('Error setting up audio streaming:', error);\n * });\n */\n\nexport const streamSuccessAudio = async ({\n stream,\n parameters,\n}: StreamSuccessAudioOptions): Promise<void> => {\n let {\n socket,\n participants,\n localStream,\n transportCreated,\n transportCreatedAudio,\n audioAlreadyOn,\n micAction,\n audioParams,\n localStreamAudio,\n defAudioID,\n userDefaultAudioInputDevice,\n params,\n audioParamse,\n aParams,\n hostLabel,\n islevel,\n member,\n updateMainWindow,\n lock_screen,\n shared,\n videoAlreadyOn,\n showAlert,\n\n //update functions\n updateParticipants,\n updateTransportCreated,\n updateTransportCreatedAudio,\n updateAudioAlreadyOn,\n updateMicAction,\n updateAudioParams,\n updateLocalStream,\n updateLocalStreamAudio,\n updateDefAudioID,\n updateUserDefaultAudioInputDevice,\n updateUpdateMainWindow,\n\n //mediasfu functions\n createSendTransport,\n connectSendTransportAudio,\n resumeSendTransportAudio,\n prepopulateUserMedia,\n } = parameters;\n\n localStreamAudio = stream;\n updateLocalStreamAudio(localStreamAudio);\n\n if (localStream == null) {\n localStream = new MediaStream([localStreamAudio.getAudioTracks()[0]]);\n updateLocalStream(localStream);\n } else {\n localStream.addTrack(localStreamAudio.getAudioTracks()[0]);\n updateLocalStream(localStream);\n }\n\n const audioTracked = localStream.getAudioTracks()[0];\n defAudioID = audioTracked.getSettings().deviceId || \"\";\n userDefaultAudioInputDevice = defAudioID;\n\n updateDefAudioID(defAudioID);\n updateUserDefaultAudioInputDevice(userDefaultAudioInputDevice);\n\n try {\n params = aParams;\n audioParamse = { ...params };\n\n audioParams = {\n track: localStream.getAudioTracks()[0],\n ...audioParamse,\n };\n updateAudioParams(audioParams);\n\n if (!transportCreated) {\n try {\n await createSendTransport({\n parameters: {\n ...parameters,\n audioParams: audioParams,\n },\n option: \"audio\",\n });\n } catch (error) {\n console.error(\"Error creating transport:\", error);\n }\n } else {\n if (!transportCreatedAudio) {\n await connectSendTransportAudio({\n audioParams,\n parameters,\n });\n } else {\n await resumeSendTransportAudio({ parameters });\n }\n }\n } catch (error: any) {\n if (showAlert) {\n showAlert({\n message: error.message,\n type: \"danger\",\n duration: 3000,\n });\n }\n }\n\n audioAlreadyOn = true;\n updateAudioAlreadyOn(audioAlreadyOn);\n\n if (micAction === true) {\n micAction = false;\n updateMicAction(micAction);\n }\n\n participants.forEach((participant) => {\n if (participant.socketId === socket.id && participant.name === member) {\n participant.muted = false;\n }\n });\n updateParticipants(participants);\n\n transportCreated = true;\n transportCreatedAudio = true;\n updateTransportCreated(transportCreated);\n updateTransportCreatedAudio(transportCreatedAudio);\n\n if (!videoAlreadyOn && islevel === \"2\") {\n if (!lock_screen && !shared) {\n updateMainWindow = true;\n updateUpdateMainWindow(updateMainWindow);\n await prepopulateUserMedia({ name: hostLabel, parameters });\n updateMainWindow = false;\n updateUpdateMainWindow(updateMainWindow);\n }\n }\n};\n","\n\nimport type { Producer, ProducerCodecOptions, ProducerOptions } from 'mediasoup-client/types';\nimport { Socket } from \"socket.io-client\";\nimport { PrepopulateUserMediaParameters, PrepopulateUserMediaType, CreateSendTransportParameters, CreateSendTransportType, ConnectSendTransportAudioParameters, ConnectSendTransportAudioType, SleepType } from \"../types/types\";\n\nexport interface StreamSuccessAudioSwitchParameters extends PrepopulateUserMediaParameters, CreateSendTransportParameters, ConnectSendTransportAudioParameters {\n audioProducer: Producer | null;\n localAudioProducer?: Producer | null;\n socket: Socket;\n localSocket?: Socket;\n roomName: string;\n localStream: MediaStream | null;\n localStreamAudio: MediaStream | null;\n audioParams: ProducerOptions;\n audioPaused: boolean;\n audioAlreadyOn: boolean;\n transportCreated: boolean;\n localTransportCreated?: boolean;\n audioParamse?: ProducerCodecOptions;\n defAudioID: string;\n userDefaultAudioInputDevice: string;\n hostLabel: string;\n updateMainWindow: boolean;\n videoAlreadyOn: boolean;\n islevel: string;\n lock_screen: boolean;\n shared: boolean;\n\n updateAudioProducer: (audioProducer: Producer | null) => void;\n updateLocalAudioProducer?: (localAudioProducer: Producer | null) => void;\n updateLocalStream: (localStream: MediaStream | null) => void;\n updateAudioParams: (audioParams: ProducerOptions) => void;\n updateDefAudioID: (defAudioID: string) => void;\n updateUserDefaultAudioInputDevice: (userDefaultAudioInputDevice: string) => void;\n updateUpdateMainWindow: (updateMainWindow: boolean) => void;\n\n // mediasfu functions\n sleep: SleepType;\n prepopulateUserMedia: PrepopulateUserMediaType;\n createSendTransport: CreateSendTransportType;\n connectSendTransportAudio: ConnectSendTransportAudioType;\n\n getUpdatedAllParams: () => StreamSuccessAudioSwitchParameters;\n [key: string]: any;\n}\n\nexport interface StreamSuccessAudioSwitchOptions {\n stream: MediaStream;\n parameters: StreamSuccessAudioSwitchParameters;\n}\n\n// Export the type definition for the function\nexport type StreamSuccessAudioSwitchType = (options: StreamSuccessAudioSwitchOptions) => Promise<void>;\n\n/**\n * Handles the switching of the audio stream upon successful stream connection.\n *\n * @param {StreamSuccessAudioSwitchOptions} options - The options for the audio stream success switch.\n * @param {MediaStream} options.stream - The new media stream containing the audio track.\n * @param {Object} options.parameters - The parameters required for setting up the audio stream.\n * @param {Producer} options.parameters.audioProducer - The current audio producer.\n * @param {Producer} options.parameters.localAudioProducer - The local audio producer.\n * @param {Socket} options.parameters.socket - The socket connection for communication.\n * @param {Socket} options.parameters.localSocket - The local socket connection for communication.\n * @param {string} options.parameters.roomName - The name of the room.\n * @param {MediaStream | null} options.parameters.localStream - The local media stream.\n * @param {MediaStream | null} options.parameters.localStreamAudio - The local audio stream.\n * @param {ProducerOptions} options.parameters.audioParams - The audio parameters.\n * @param {boolean} options.parameters.audioPaused - Indicates if the audio is paused.\n * @param {boolean} options.parameters.audioAlreadyOn - Indicates if the audio is already on.\n * @param {boolean} options.parameters.transportCreated - Indicates if the transport is created.\n * @param {ProducerCodecOptions} options.parameters.audioParamse - Additional audio parameters.\n * @param {string} options.parameters.defAudioID - The default audio device ID.\n * @param {string} options.parameters.userDefaultAudioInputDevice - The user default audio input device.\n * @param {string} options.parameters.hostLabel - The label of the host.\n * @param {boolean} options.parameters.updateMainWindow - Indicates if the main window should be updated.\n * @param {boolean} options.parameters.videoAlreadyOn - Indicates if the video is already on.\n * @param {string} options.parameters.islevel - The level of the participant.\n * @param {boolean} options.parameters.lock_screen - Indicates if the screen is locked.\n * @param {boolean} options.parameters.shared - Indicates if the screen is shared.\n * @param {Function} options.parameters.updateAudioProducer - Function to update the audio producer.\n * @param {Function} options.parameters.updateLocalAudioProducer - Function to update the local audio producer.\n * @param {Function} options.parameters.updateLocalStream - Function to update the local stream.\n * @param {Function} options.parameters.updateAudioParams - Function to update the audio parameters.\n * @param {Function} options.parameters.updateDefAudioID - Function to update the default audio device ID.\n * @param {Function} options.parameters.updateUserDefaultAudioInputDevice - Function to update the user default audio input device.\n * @param {Function} options.parameters.updateUpdateMainWindow - Function to update the main window.\n * @param {Function} options.parameters.sleep - Function to pause execution for a specified time.\n * @param {Function} options.parameters.prepopulateUserMedia - Function to prepopulate user media.\n * @param {Function} options.parameters.createSendTransport - Function to create a send transport.\n * @param {Function} options.parameters.connectSendTransportAudio - Function to connect the send transport for audio.\n *\n * @returns {Promise<void>} A promise that resolves when the audio stream switch is complete.\n * \n * @example\n * const options = {\n * stream: newAudioStream, // MediaStream object containing the new audio track\n * parameters: {\n * audioProducer: currentAudioProducer,\n * localAudioProducer: localAudioProducerInstance,\n * localSocket: localSocketInstance, \n * socket: socketInstance,\n * roomName: \"Room1\",\n * localStream: null,\n * localStreamAudio: null,\n * audioParams: audioProducerOptions,\n * audioPaused: false,\n * audioAlreadyOn: true,\n * transportCreated: false,\n * audioParamse: additionalAudioParams,\n * defAudioID: \"default-audio-device-id\",\n * userDefaultAudioInputDevice: \"user-input-device-id\",\n * hostLabel: \"Host\",\n * islevel: \"1\",\n * videoAlreadyOn: false,\n * lock_screen: false,\n * shared: false,\n * updateAudioProducer: updateAudioProducerFunction,\n * updateLocalAudioProducer: updateLocalAudioProducerFunction,\n * updateLocalStream: updateLocalStreamFunction,\n * updateAudioParams: updateAudioParamsFunction,\n * updateDefAudioID: updateDefAudioIDFunction,\n * updateUserDefaultAudioInputDevice: updateUserDefaultAudioInputDeviceFunction,\n * updateUpdateMainWindow: updateMainWindowFunction,\n * sleep: sleepFunction,\n * prepopulateUserMedia: prepopulateUserMediaFunction,\n * createSendTransport: createSendTransportFunction,\n * connectSendTransportAudio: connectSendTransportAudioFunction,\n * },\n * };\n * \n * streamSuccessAudioSwitch(options)\n * .then(() => {\n * console.log('Audio stream switched successfully');\n * })\n * .catch(error => {\n * console.error('Error switching audio stream:', error);\n * });\n */\n\nexport const streamSuccessAudioSwitch = async ({\n stream,\n parameters,\n}: StreamSuccessAudioSwitchOptions): Promise<void> => {\n\n let {\n audioProducer,\n localAudioProducer,\n socket,\n localSocket,\n roomName,\n localStream,\n localStreamAudio,\n audioParams,\n audioPaused,\n audioAlreadyOn,\n transportCreated,\n audioParamse,\n defAudioID,\n userDefaultAudioInputDevice,\n hostLabel,\n updateMainWindow,\n videoAlreadyOn,\n islevel,\n lock_screen,\n shared,\n\n updateAudioProducer,\n updateLocalAudioProducer,\n updateLocalStream,\n updateAudioParams,\n updateDefAudioID,\n updateUserDefaultAudioInputDevice,\n updateUpdateMainWindow,\n\n //mediasfu functions\n sleep,\n prepopulateUserMedia,\n createSendTransport,\n connectSendTransportAudio,\n } = parameters;\n\n // Get the new default audio device ID\n let newDefAudioID = stream.getAudioTracks()[0].getSettings().deviceId;\n\n // Check if the audio device has changed\n if (newDefAudioID !== defAudioID) {\n // Close the current audioProducer\n if (audioProducer) {\n audioProducer.close();\n updateAudioProducer(audioProducer);\n }\n\n // Emit a pauseProducerMedia event to pause the audio media\n socket.emit(\"pauseProducerMedia\", {\n mediaTag: \"audio\",\n roomName: roomName,\n force: true,\n });\n\n try {\n if (localSocket && localSocket.id) {\n if (localAudioProducer) {\n localAudioProducer.close();\n if (updateLocalAudioProducer){\n updateLocalAudioProducer(localAudioProducer);\n }\n }\n localSocket.emit(\"pauseProducerMedia\", {\n mediaTag: \"audio\",\n roomName: roomName,\n force: true,\n });\n }\n } catch {\n // Do nothing\n }\n\n // Update the localStreamAudio with the new audio tracks\n localStreamAudio = stream;\n\n // If localStream is null, create a new MediaStream with the new audio track\n if (localStream == null) {\n localStream = new MediaStream([\n localStreamAudio.getAudioTracks()[0],\n ]);\n } else {\n // Remove all existing audio tracks from localStream and add the new audio track\n localStream.getAudioTracks().forEach((track) => {\n localStream!.removeTrack(track);\n });\n localStream.addTrack(localStreamAudio.getAudioTracks()[0]);\n }\n\n // Update localStream\n updateLocalStream(localStream);\n\n // Get the new default audio device ID from the new audio track\n const audioTracked = localStream.getAudioTracks()[0];\n defAudioID = audioTracked.getSettings().deviceId || \"\";\n updateDefAudioID(defAudioID);\n\n // Update userDefaultAudioInputDevice\n userDefaultAudioInputDevice = defAudioID;\n updateUserDefaultAudioInputDevice(userDefaultAudioInputDevice);\n\n // Update audioParams with the new audio track\n audioParams = {\n track: localStream.getAudioTracks()[0],\n ...audioParamse,\n };\n updateAudioParams(audioParams);\n\n // Sleep for 500 milliseconds\n await sleep({ ms: 500 });\n\n // Create a new send transport if not created, otherwise, connect the existing transport\n if (!transportCreated) {\n try {\n await createSendTransport({\n parameters: {\n ...parameters,\n audioParams: audioParams,\n },\n option: \"audio\",\n });\n } catch (error) {\n console.error(\"Error creating send transport:\", error);\n }\n } else {\n await connectSendTransportAudio({\n audioParams,\n parameters,\n });\n }\n\n // If audio is paused and not already on, pause the audioProducer and emit a pauseProducerMedia event\n if (audioPaused === true && !audioAlreadyOn) {\n audioProducer!.pause();\n updateAudioProducer(audioProducer);\n socket.emit(\"pauseProducerMedia\", {\n mediaTag: \"audio\",\n roomName: roomName,\n });\n\n try {\n if (localSocket && localSocket.id) {\n localAudioProducer!.pause();\n if (updateLocalAudioProducer){\n updateLocalAudioProducer(localAudioProducer!);\n }\n localSocket.emit(\"pauseProducerMedia\", {\n mediaTag: \"audio\",\n roomName: roomName,\n });\n }\n } catch {\n // Do nothing\n }\n }\n }\n\n // Update the UI based on the participant's level and screen lock status\n if (!videoAlreadyOn && islevel === \"2\") {\n if (!lock_screen && !shared) {\n updateMainWindow = true;\n updateUpdateMainWindow(updateMainWindow);\n await prepopulateUserMedia({ name: hostLabel, parameters });\n updateMainWindow = false;\n updateUpdateMainWindow(updateMainWindow);\n }\n }\n};\n"," \n\nimport { Socket } from \"socket.io-client\";\nimport { connectSendTransportScreenAudio } from \"./connectSendTransportScreenAudio\";\nimport {\n SleepType, CreateSendTransportType, ConnectSendTransportScreenType, DisconnectSendTransportScreenType, StopShareScreenType, ReorderStreamsType, PrepopulateUserMediaType, RePortType,\n ShowAlert, CreateSendTransportParameters, ConnectSendTransportScreenParameters, DisconnectSendTransportScreenParameters, StopShareScreenParameters, ReorderStreamsParameters, PrepopulateUserMediaParameters, RePortParameters,\n EventType\n} from \"../types/types\";\n\nexport interface StreamSuccessScreenParameters extends CreateSendTransportParameters, ConnectSendTransportScreenParameters, DisconnectSendTransportScreenParameters, StopShareScreenParameters, ReorderStreamsParameters, PrepopulateUserMediaParameters, RePortParameters {\n socket: Socket;\n transportCreated: boolean;\n localStreamScreen: MediaStream | null;\n screenAlreadyOn: boolean;\n screenAction: boolean;\n transportCreatedScreen: boolean;\n hostLabel: string;\n eventType: EventType;\n showAlert?: ShowAlert;\n annotateScreenStream: boolean;\n shared: boolean;\n\n updateTransportCreatedScreen: (transportCreatedScreen: boolean) => void;\n updateScreenAlreadyOn: (screenAlreadyOn: boolean) => void;\n updateScreenAction: (screenAction: boolean) => void;\n updateTransportCreated: (transportCreated: boolean) => void;\n updateLocalStreamScreen: (localStreamScreen: MediaStream | null) => void;\n updateShared: (shared: boolean) => void;\n updateIsScreenboardModalVisible: (isVisible: boolean) => void;\n\n // mediasfu functions\n sleep: SleepType;\n createSendTransport: CreateSendTransportType;\n connectSendTransportScreen: ConnectSendTransportScreenType;\n disconnectSendTransportScreen: DisconnectSendTransportScreenType;\n stopShareScreen: StopShareScreenType;\n reorderStreams: ReorderStreamsType;\n prepopulateUserMedia: PrepopulateUserMediaType;\n rePort: RePortType;\n\n getUpdatedAllParams: () => StreamSuccessScreenParameters;\n [key: string]: any;\n}\n\nexport interface StreamSuccessScreenOptions {\n stream: MediaStream;\n parameters: StreamSuccessScreenParameters;\n}\n\n// Export the type definition for the function\nexport type StreamSuccessScreenType = (options: StreamSuccessScreenOptions) => Promise<void>;\n\n/**\n * Handles the successful initiation of screen sharing.\n *\n * @param {StreamSuccessScreenOptions} options - The options for the screen sharing success handler.\n * @param {MediaStream} options.stream - The media stream to be shared.\n * @param {Object} options.parameters - The parameters required for screen sharing.\n * @param {Socket} options.parameters.socket - The socket instance for communication.\n * @param {boolean} options.parameters.transportCreated - Flag indicating if the transport is already created.\n * @param {MediaStream | null} options.parameters.localStreamScreen - The local screen media stream.\n * @param {boolean} options.parameters.screenAlreadyOn - Flag indicating if the screen is already being shared.\n * @param {boolean} options.parameters.screenAction - Flag indicating if the screen share action is requested.\n * @param {boolean} options.parameters.transportCreatedScreen - Flag indicating if the screen transport is created.\n * @param {string} options.parameters.hostLabel - The label of the host.\n * @param {string} options.parameters.eventType - The type of the event (e.g., conference).\n * @param {Function} options.parameters.showAlert - Function to show alerts.\n * @param {boolean} options.parameters.annotateScreenStream - Flag indicating if screen annotation is enabled.\n * @param {Function} options.parameters.updateTransportCreatedScreen - Function to update the screen transport creation state.\n * @param {Function} options.parameters.updateScreenAlreadyOn - Function to update the screen sharing state.\n * @param {Function} options.parameters.updateScreenAction - Function to update the screen action state.\n * @param {Function} options.parameters.updateTransportCreated - Function to update the transport creation state.\n * @param {Function} options.parameters.updateLocalStreamScreen - Function to update the local screen stream.\n * @param {Function} options.parameters.updateShared - Function to update the shared state.\n * @param {Function} options.parameters.updateIsScreenboardModalVisible - Function to update the screenboard modal visibility.\n * @param {Function} options.parameters.sleep - Function to pause execution for a specified duration.\n * @param {Function} options.parameters.createSendTransport - Function to create a send transport.\n * @param {Function} options.parameters.connectSendTransportScreen - Function to connect the send transport for screen sharing.\n * @param {Function} options.parameters.disconnectSendTransportScreen - Function to disconnect the send transport for screen sharing.\n * @param {Function} options.parameters.stopShareScreen - Function to stop screen sharing.\n * @param {Function} options.parameters.reorderStreams - Function to reorder streams.\n * @param {Function} options.parameters.prepopulateUserMedia - Function to prepopulate user media.\n * @param {Function} options.parameters.rePort - Function to reinitialize ports.\n *\n * @returns {Promise<void>} A promise that resolves when the screen sharing setup is complete.\n * \n * @throws Will throw an error if there is an issue with screen sharing.\n * \n * @example\n * ```typescript\n * await streamSuccessScreen({\n * stream: mediaStream,\n * parameters: {\n * socket,\n * transportCreated,\n * localStreamScreen: null,\n * screenAlreadyOn: false,\n * screenAction: true,\n * transportCreatedScreen: false,\n * hostLabel: \"Host\",\n * eventType: \"conference\",\n * showAlert,\n * annotateScreenStream: false,\n * updateTransportCreatedScreen,\n * updateScreenAlreadyOn,\n * updateScreenAction,\n * updateTransportCreated,\n * updateLocalStreamScreen,\n * updateShared,\n * updateIsScreenboardModalVisible,\n * sleep,\n * createSendTransport,\n * connectSendTransportScreen,\n * disconnectSendTransportScreen,\n * stopShareScreen,\n * reorderStreams,\n * prepopulateUserMedia,\n * rePort,\n * },\n * });\n * ```\n */\n\nexport const streamSuccessScreen = async ({\n stream,\n parameters,\n}: StreamSuccessScreenOptions): Promise<void> => {\n let { getUpdatedAllParams } = parameters;\n parameters = getUpdatedAllParams();\n\n let {\n socket,\n transportCreated,\n localStreamScreen,\n screenAlreadyOn,\n screenAction,\n transportCreatedScreen,\n hostLabel,\n eventType,\n showAlert,\n annotateScreenStream,\n\n updateTransportCreatedScreen,\n updateScreenAlreadyOn,\n updateScreenAction,\n updateTransportCreated,\n updateLocalStreamScreen,\n updateShared,\n updateIsScreenboardModalVisible,\n sleep,\n\n // mediasfu functions\n createSendTransport,\n connectSendTransportScreen,\n disconnectSendTransportScreen,\n stopShareScreen,\n reorderStreams,\n prepopulateUserMedia,\n rePort,\n } = parameters;\n\n // Share screen on success\n localStreamScreen = stream;\n updateLocalStreamScreen(localStreamScreen);\n\n try {\n // Create transport if not created else connect transport\n if (!transportCreated) {\n await createSendTransport({\n option: \"screen\",\n parameters: { ...parameters, localStreamScreen },\n });\n } else {\n await connectSendTransportScreen({\n stream: localStreamScreen,\n parameters: { ...parameters, localStreamScreen },\n });\n }\n\n // Alert the socket that you are sharing the screen\n socket.emit(\"startScreenShare\");\n\n // Share the screen's audio too, when the browser captured it and the server supports it.\n try {\n await connectSendTransportScreenAudio({\n stream: localStreamScreen,\n parameters: getUpdatedAllParams() as any,\n });\n } catch (error) {\n console.log(\"Screen audio not shared:\", error);\n }\n } catch (error: any) {\n showAlert?.({\n message: error.message,\n type: \"danger\",\n duration: 3000,\n });\n }\n\n // Re-update the screen display\n try {\n updateShared(true);\n await prepopulateUserMedia({\n name: hostLabel,\n parameters: { ...parameters, localStreamScreen, shared: true },\n });\n } catch (error) {\n console.error(\"Error updating shared screen UI:\", error);\n }\n\n // Update the screen sharing state\n screenAlreadyOn = true;\n updateScreenAlreadyOn(screenAlreadyOn);\n\n // Reorder streams if required\n try {\n if (eventType === \"conference\") {\n await reorderStreams({ add: false, screenChanged: true, parameters });\n await prepopulateUserMedia({ name: hostLabel, parameters });\n } else {\n await reorderStreams({ parameters });\n }\n } catch {\n try {\n await rePort({ parameters });\n } catch {\n // console.error(\"Error reordering streams:\", error);\n\n }\n }\n\n // Handle screen share end\n localStreamScreen.getVideoTracks()[0].onended = async function () {\n // Supports both manual and automatic screen share end\n await disconnectSendTransportScreen({ parameters });\n await stopShareScreen({ parameters });\n };\n\n // If user requested to share screen, update the screenAction state\n if (screenAction === true) {\n screenAction = false;\n }\n updateScreenAction(screenAction);\n\n // Update the transport created state\n transportCreatedScreen = true;\n updateTransportCreatedScreen(transportCreatedScreen);\n transportCreated = true;\n updateTransportCreated(transportCreated);\n\n // Handle screen annotation modal\n try {\n if (annotateScreenStream) {\n annotateScreenStream = false;\n updateIsScreenboardModalVisible(true);\n await sleep({ ms: 500 });\n updateIsScreenboardModalVisible(false);\n }\n } catch (error) {\n console.error(\"Error handling screen annotation:\", error);\n }\n\n\n};\n\n","import type { Device, Producer, ProducerOptions, RtpCodecCapability } from 'mediasoup-client/types';\nimport { Socket } from \"socket.io-client\";\nimport { ConnectSendTransportVideoParameters, Participant, ShowAlert, CreateSendTransportParameters, ReorderStreamsParameters, SleepType, CreateSendTransportType, ConnectSendTransportVideoType, ReorderStreamsType, HParamsType, VParamsType } from \"../types/types\";\n\nexport interface StreamSuccessVideoParameters extends CreateSendTransportParameters, ConnectSendTransportVideoParameters, ReorderStreamsParameters {\n socket: Socket;\n participants: Participant[];\n localStream: MediaStream | null;\n transportCreated: boolean;\n transportCreatedVideo: boolean;\n videoAlreadyOn: boolean;\n videoAction: boolean;\n videoParams: ProducerOptions;\n localStreamVideo: MediaStream | null;\n defVideoID: string;\n userDefaultVideoInputDevice: string;\n params: ProducerOptions;\n videoParamse?: ProducerOptions;\n islevel: string;\n member: string;\n updateMainWindow: boolean;\n lock_screen: boolean;\n shared: boolean;\n shareScreenStarted: boolean;\n vParams: VParamsType;\n hParams: HParamsType;\n allowed: boolean;\n currentFacingMode: string;\n device: Device | null;\n keepBackground: boolean;\n appliedBackground: boolean;\n videoProducer: Producer | null;\n removeSingleVideoEncoding?: boolean;\n useNativeCodecSelection?: boolean;\n\n // Update functions\n updateTransportCreatedVideo: (created: boolean) => void;\n updateVideoAlreadyOn: (videoOn: boolean) => void;\n updateVideoAction: (videoAction: boolean) => void;\n updateLocalStream: (stream: MediaStream | null) => void;\n updateLocalStreamVideo: (stream: MediaStream | null) => void;\n updateUserDefaultVideoInputDevice: (device: string) => void;\n updateCurrentFacingMode: (mode: string) => void;\n updateDefVideoID: (id: string) => void;\n updateAllowed: (allowed: boolean) => void;\n updateUpdateMainWindow: (updateMainWindow: boolean) => void;\n updateParticipants: (participants: Participant[]) => void;\n updateVideoParams: (params: ProducerOptions) => void;\n updateIsBackgroundModalVisible: (isVisible: boolean) => void;\n updateAutoClickBackground: (autoClick: boolean) => void;\n\n showAlert?: ShowAlert;\n\n // Media functions\n createSendTransport: CreateSendTransportType;\n connectSendTransportVideo: ConnectSendTransportVideoType;\n reorderStreams: ReorderStreamsType;\n sleep: SleepType;\n\n getUpdatedAllParams: () => StreamSuccessVideoParameters;\n [key: string]: any;\n}\n\nexport interface StreamSuccessVideoOptions {\n stream: MediaStream;\n parameters: StreamSuccessVideoParameters;\n}\n\n// Export the type definition for the function\nexport type StreamSuccessVideoType = (options: StreamSuccessVideoOptions) => Promise<void>;\n\nconst auxiliaryVideoCodecs = new Set([\n 'video/rtx',\n 'video/red',\n 'video/ulpfec',\n 'video/flexfec-03',\n]);\n\nexport function selectVideoProducerCodec({\n device,\n useNativeCodecSelection = false,\n}: {\n device: Pick<Device, 'rtpCapabilities'> | null;\n useNativeCodecSelection?: boolean;\n}): RtpCodecCapability | undefined {\n if (useNativeCodecSelection) return undefined;\n\n return device?.rtpCapabilities?.codecs?.find((codec: RtpCodecCapability) => {\n const mimeType = codec.mimeType.toLowerCase();\n return codec.kind === 'video' &&\n mimeType !== 'video/vp9' &&\n !auxiliaryVideoCodecs.has(mimeType);\n });\n}\n\n\n/**\n * Handles the successful streaming of video by managing the local stream, updating parameters, and handling video transport.\n *\n * @param {StreamSuccessVideoOptions} options - The options for streaming the video.\n * @param {MediaStream} options.stream - The media stream to be used for the video.\n * @param {Object} options.parameters - The parameters required for streaming the video.\n * @param {Socket} options.parameters.socket - The socket connection for communication.\n * @param {Array<Participant>} options.parameters.participants - The list of participants in the room.\n * @param {MediaStream | null} options.parameters.localStream - The local media stream.\n * @param {MediaStream | null} options.parameters.localStreamVideo - The local video stream.\n * @param {boolean} options.parameters.transportCreated - Indicates if the transport has been created.\n * @param {boolean} options.parameters.transportCreatedVideo - Indicates if the video transport has been created.\n * @param {boolean} options.parameters.videoAlreadyOn - Indicates if the video is already on.\n * @param {boolean} options.parameters.videoAction - Indicates the action state of the video.\n * @param {ProducerOptions} options.parameters.videoParams - The video parameters for the producer.\n * @param {string} options.parameters.defVideoID - The default video device ID.\n * @param {string} options.parameters.userDefaultVideoInputDevice - The user default video input device.\n * @param {string} options.parameters.hostLabel - The label of the host.\n * @param {string} options.parameters.islevel - The level of the participant.\n * @param {string} options.parameters.member - The name of the participant.\n * @param {boolean} options.parameters.updateMainWindow - Indicates if the main window should be updated.\n * @param {boolean} options.parameters.lock_screen - Indicates if the screen is locked.\n * @param {boolean} options.parameters.shared - Indicates if the screen is shared.\n * @param {boolean} options.parameters.shareScreenStarted - Indicates if screen sharing has started.\n * @param {VParamsType} options.parameters.vParams - Video parameters.\n * @param {HParamsType} options.parameters.hParams - Horizontal parameters.\n * @param {boolean} options.parameters.allowed - Indicates if the action is allowed.\n * @param {string} options.parameters.currentFacingMode - The current facing mode of the camera.\n * @param {Device | null} options.parameters.device - The device being used for streaming.\n * @param {boolean} options.parameters.keepBackground - Indicates if the background should be kept.\n * @param {boolean} options.parameters.appliedBackground - Indicates if the background has been applied.\n * @param {Producer | null} options.parameters.videoProducer - The video producer instance.\n * @param {Function} options.parameters.updateTransportCreatedVideo - Function to update the transport created state for video.\n * @param {Function} options.parameters.updateVideoAlreadyOn - Function to update the video already on state.\n * @param {Function} options.parameters.updateVideoAction - Function to update the video action state.\n * @param {Function} options.parameters.updateLocalStream - Function to update the local stream.\n * @param {Function} options.parameters.updateLocalStreamVideo - Function to update the local video stream.\n * @param {Function} options.parameters.updateUserDefaultVideoInputDevice - Function to update the user default video input device.\n * @param {Function} options.parameters.updateCurrentFacingMode - Function to update the current facing mode.\n * @param {Function} options.parameters.updateDefVideoID - Function to update the default video device ID.\n * @param {Function} options.parameters.updateAllowed - Function to update the allowed state.\n * @param {Function} options.parameters.updateUpdateMainWindow - Function to update the main window state.\n * @param {Function} options.parameters.createSendTransport - Function to create a send transport.\n * @param {Function} options.parameters.connectSendTransportVideo - Function to connect the send transport for video.\n * @param {Function} options.parameters.showAlert - Function to display alert messages to the user.\n *\n * @returns {Promise<void>} A promise that resolves when the video streaming setup is complete.\n * \n * @throws Will throw an error if there is an issue with streaming the video.\n * \n * @example\n * ```typescript\n * await streamSuccessVideo({\n * stream: mediaStream,\n * parameters: {\n * socket,\n * participants,\n * localStream: null,\n * localStreamVideo: null,\n * transportCreated: false,\n * transportCreatedVideo: false,\n * videoAlreadyOn: false,\n * videoAction: false,\n * videoParams: producerOptions,\n * defVideoID: \"default-video-id\",\n * userDefaultVideoInputDevice: \"user-device-id\",\n * hostLabel: \"Host\",\n * islevel: \"1\",\n * member: \"Participant1\",\n * lock_screen: false,\n * shared: false,\n * shareScreenStarted: false,\n * vParams,\n * hParams,\n * allowed: true,\n * currentFacingMode: \"user\",\n * device: mediaDevice,\n * updateTransportCreatedVideo,\n * updateVideoAlreadyOn,\n * updateVideoAction,\n * updateLocalStream,\n * updateLocalStreamVideo,\n * updateUserDefaultVideoInputDevice,\n * updateCurrentFacingMode,\n * updateDefVideoID,\n * updateAllowed,\n * updateUpdateMainWindow,\n * createSendTransport,\n * connectSendTransportVideo,\n * showAlert,\n * },\n * });\n * ```\n */\n\n\nexport const streamSuccessVideo = async ({\n stream,\n parameters,\n}: StreamSuccessVideoOptions): Promise<void> => {\n\n let { getUpdatedAllParams } = parameters;\n parameters = getUpdatedAllParams();\n\n try {\n let {\n socket,\n participants,\n localStream,\n transportCreated,\n transportCreatedVideo,\n videoAlreadyOn,\n videoAction,\n videoParams,\n localStreamVideo,\n defVideoID,\n userDefaultVideoInputDevice,\n params,\n videoParamse,\n islevel,\n member,\n updateMainWindow,\n lock_screen,\n shared,\n shareScreenStarted,\n vParams,\n hParams,\n allowed,\n currentFacingMode,\n device,\n\n keepBackground,\n appliedBackground,\n videoProducer,\n\n updateTransportCreatedVideo,\n updateVideoAlreadyOn,\n updateVideoAction,\n updateLocalStream,\n updateLocalStreamVideo,\n updateUserDefaultVideoInputDevice,\n updateCurrentFacingMode,\n updateDefVideoID,\n updateAllowed,\n updateUpdateMainWindow,\n updateParticipants,\n updateVideoParams,\n updateIsBackgroundModalVisible,\n updateAutoClickBackground,\n\n //mediasfu functions\n createSendTransport,\n connectSendTransportVideo,\n showAlert,\n reorderStreams,\n sleep,\n } = parameters;\n\n localStreamVideo = stream;\n updateLocalStreamVideo(localStreamVideo);\n\n if (localStream == null) {\n localStream = new MediaStream([\n localStreamVideo.getVideoTracks()[0],\n ]);\n updateLocalStream(localStream);\n } else {\n // remove all video tracks that are currently in the localStream\n localStream.getVideoTracks().forEach((track) => {\n localStream!.removeTrack(track);\n });\n // add the new video track to the localStream\n localStream.addTrack(localStreamVideo.getVideoTracks()[0]);\n updateLocalStream(localStream);\n }\n\n const videoTracked = localStream.getVideoTracks()[0];\n defVideoID = videoTracked.getSettings().deviceId || '';\n userDefaultVideoInputDevice = defVideoID;\n currentFacingMode = videoTracked.getSettings().facingMode || 'user';\n\n if (defVideoID) {\n updateDefVideoID(defVideoID);\n }\n if (userDefaultVideoInputDevice) {\n updateUserDefaultVideoInputDevice(userDefaultVideoInputDevice);\n }\n if (currentFacingMode) {\n updateCurrentFacingMode(currentFacingMode);\n }\n\n allowed = true;\n updateAllowed(allowed);\n\n try {\n if (islevel === \"2\") {\n params = shared || shareScreenStarted ? vParams : hParams;\n videoParamse = { ...params };\n } else {\n params = vParams;\n videoParamse = { ...params };\n }\n\n const useNativeCodecSelection =\n parameters.useNativeCodecSelection ??\n parameters.removeSingleVideoEncoding ??\n false;\n const codec = selectVideoProducerCodec({\n device,\n useNativeCodecSelection,\n });\n\n if (parameters.removeSingleVideoEncoding && videoParamse.encodings && videoParamse.encodings.length <= 1) {\n delete videoParamse.encodings;\n }\n\n videoParams = {\n track: localStream.getVideoTracks()[0],\n ...videoParamse,\n ...(codec ? { codec } : {}),\n };\n updateVideoParams(videoParams);\n\n if (keepBackground && appliedBackground) {\n videoAlreadyOn = true;\n updateVideoAlreadyOn(videoAlreadyOn);\n\n updateAutoClickBackground(true);\n updateIsBackgroundModalVisible(true);\n await sleep({ ms: 500 });\n updateIsBackgroundModalVisible(false);\n updateAutoClickBackground(false);\n } else {\n if (!transportCreated) {\n try {\n await createSendTransport({\n parameters: { ...parameters, videoParams },\n option: \"video\",\n });\n } catch { /* Handle error */}\n } else {\n try {\n videoProducer!.close();\n await sleep({ ms: 500 });\n } catch { /* Handle error */}\n await connectSendTransportVideo({\n parameters,\n videoParams,\n });\n }\n }\n } catch (error) {\n showAlert?.({\n message: (error as Error).message,\n type: \"danger\",\n duration: 3000,\n });\n }\n\n videoAlreadyOn = true;\n updateVideoAlreadyOn(videoAlreadyOn);\n\n if (videoAction === true) {\n videoAction = false;\n updateVideoAction(videoAction);\n }\n\n if (islevel === \"2\") {\n updateMainWindow = true;\n updateUpdateMainWindow(updateMainWindow);\n }\n\n //update the participants array to reflect the change\n participants.forEach((participant) => {\n if (participant.socketId == socket.id && participant.name == member) {\n participant.videoOn = true;\n }\n });\n updateParticipants(participants);\n\n transportCreatedVideo = true;\n updateTransportCreatedVideo(transportCreatedVideo);\n\n //reupdate the screen display\n if (lock_screen) {\n await reorderStreams({\n add: true,\n screenChanged: true,\n parameters: { ...parameters, videoAlreadyOn },\n });\n } else {\n try {\n await reorderStreams({\n add: false,\n screenChanged: true,\n parameters: { ...parameters, videoAlreadyOn },\n });\n } catch { /* Handle error */}\n }\n } catch (error) {\n try {\n let { showAlert } = parameters;\n\n showAlert?.({\n message: (error as Error).message,\n type: \"danger\",\n duration: 3000,\n });\n } catch { /* Handle error */}\n }\n};\n","import { ShowAlert, StreamSuccessAudioSwitchType, RequestPermissionAudioType, StreamSuccessAudioSwitchParameters } from \"../types/types\";\n\n\nexport interface SwitchUserAudioParameters extends StreamSuccessAudioSwitchParameters {\n mediaDevices: MediaDevices;\n userDefaultAudioInputDevice: string;\n prevAudioInputDevice: string;\n showAlert?: ShowAlert;\n hasAudioPermission: boolean;\n updateUserDefaultAudioInputDevice: (deviceId: string) => void;\n\n // mediasfu functions\n streamSuccessAudioSwitch: StreamSuccessAudioSwitchType;\n requestPermissionAudio: RequestPermissionAudioType;\n checkMediaPermission: boolean;\n\n [key: string]: any;\n}\n\nimport { AudioProcessingOptions, audioProcessingConstraints } from './audioProcessing';\n\nexport interface SwitchUserAudioOptions {\n audioProcessing?: AudioProcessingOptions;\n audioPreference: string;\n parameters: SwitchUserAudioParameters;\n}\n\n// Export the type definition for the function\nexport type SwitchUserAudioType = (options: SwitchUserAudioOptions) => Promise<void>;\n\n/**\n * Switches the user's audio input device based on the provided audio preference.\n * \n * @param {SwitchUserAudioOptions} options - The options for switching the user's audio input device.\n * @param {string} options.audioPreference - The preferred audio input device ID.\n * @param {Object} options.parameters - Additional parameters required for switching the audio input device.\n * @param {MediaDevices} options.parameters.mediaDevices - The media devices interface for accessing user media.\n * @param {string} options.parameters.prevAudioInputDevice - The previous audio input device ID.\n * @param {Function} options.parameters.showAlert - Function to show alert messages.\n * @param {boolean} options.parameters.hasAudioPermission - Flag indicating if the user has granted audio permission.\n * @param {Function} options.parameters.updateUserDefaultAudioInputDevice - Function to update the user's default audio input device.\n * @param {Function} options.parameters.streamSuccessAudioSwitch - Function to handle successful audio stream switch.\n * @param {Function} options.parameters.requestPermissionAudio - Function to request audio permission from the user.\n * @param {Function} options.parameters.checkMediaPermission - Function to check if media permission is granted.\n * \n * @returns {Promise<void>} A promise that resolves when the audio input device has been successfully switched.\n * \n * @throws Will throw an error if the audio input device cannot be accessed or if there is an unexpected error.\n * \n * @example\n * ```typescript\n * await switchUserAudio({\n * audioPreference: 'audio-device-id',\n * parameters: {\n * mediaDevices,\n * prevAudioInputDevice: 'prev-audio-device-id',\n * showAlert,\n * hasAudioPermission,\n * updateUserDefaultAudioInputDevice,\n * streamSuccessAudioSwitch,\n * requestPermissionAudio,\n * checkMediaPermission,\n * },\n * });\n * ```\n */\n\n\nexport async function switchUserAudio({ audioPreference, parameters, audioProcessing }: SwitchUserAudioOptions): Promise<void> {\n const {\n mediaDevices,\n prevAudioInputDevice,\n showAlert,\n hasAudioPermission,\n updateUserDefaultAudioInputDevice,\n\n // Media functions\n streamSuccessAudioSwitch,\n requestPermissionAudio,\n checkMediaPermission,\n } = parameters;\n\n try {\n // Check if audio permission is granted\n if (!hasAudioPermission) {\n if (checkMediaPermission) {\n const statusMic = await requestPermissionAudio();\n if (statusMic !== \"granted\") {\n showAlert?.({\n message:\n \"Allow access to your microphone or check if your microphone is not being used by another application.\",\n type: \"danger\",\n duration: 3000,\n });\n return;\n }\n }\n }\n\n // Preserve the microphone's processing policy, not its old deviceId.\n // Omit unknown values so the browser retains its normal defaults.\n const track = parameters.localStreamAudio?.getAudioTracks?.()[0]\n ?? parameters.localStream?.getAudioTracks?.()[0]\n ?? parameters.audioProducer?.track;\n const previousConstraints = track?.getConstraints?.() ?? {};\n const previousSettings = track?.getSettings?.() ?? {};\n const processing: MediaTrackConstraints = {};\n for (const key of ['echoCancellation', 'noiseSuppression', 'autoGainControl'] as const) {\n const value = previousConstraints[key] ?? previousSettings[key];\n if (value !== undefined) processing[key] = value;\n }\n const mediaConstraints: MediaStreamConstraints = {\n audio: {\n deviceId: { exact: audioPreference },\n ...processing,\n ...audioProcessingConstraints(audioProcessing),\n },\n video: false,\n };\n\n // Get user media with the defined audio constraints\n await mediaDevices\n .getUserMedia(mediaConstraints)\n .then(async (stream) => {\n await streamSuccessAudioSwitch({ stream, parameters });\n })\n .catch((error) => {\n console.log(\"Error switching audio A\", error);\n // Handle errors and revert to the previous audio input device\n updateUserDefaultAudioInputDevice(prevAudioInputDevice);\n\n\n showAlert?.({\n message: \"Error switching; the specified microphone could not be accessed.\",\n type: \"danger\",\n duration: 3000,\n });\n\n });\n } catch (error) {\n console.log(\"Error switching audio\", error);\n // Handle unexpected errors and revert to the previous audio input device\n updateUserDefaultAudioInputDevice(prevAudioInputDevice);\n\n\n showAlert?.({\n message: \"Error switching; the specified microphone could not be accessed.\",\n type: \"danger\",\n duration: 3000,\n });\n\n }\n}\n","import { Socket } from \"socket.io-client\";\nimport { CheckPermissionType, DisconnectSendTransportVideoParameters, DisconnectSendTransportVideoType, RequestPermissionCameraType, ShowAlert, StreamSuccessVideoParameters, StreamSuccessVideoType, VidCons } from \"../../types/types\";\n\nexport interface ClickVideoParameters extends DisconnectSendTransportVideoParameters, StreamSuccessVideoParameters {\n checkMediaPermission: boolean;\n hasCameraPermission: boolean;\n videoAlreadyOn: boolean;\n audioOnlyRoom: boolean;\n recordStarted: boolean;\n recordResumed: boolean;\n recordPaused: boolean;\n recordStopped: boolean;\n recordingMediaOptions: string;\n islevel: string;\n youAreCoHost: boolean;\n adminRestrictSetting: boolean;\n videoRequestState: string | null;\n videoRequestTime: number;\n member: string;\n socket: Socket;\n roomName: string;\n userDefaultVideoInputDevice: string;\n currentFacingMode: string;\n vidCons: VidCons;\n frameRate: number;\n videoAction: boolean;\n localStream: MediaStream | null;\n audioSetting: string;\n videoSetting: string;\n screenshareSetting: string;\n chatSetting: string;\n updateRequestIntervalSeconds: number;\n\n showAlert?: ShowAlert;\n updateVideoAlreadyOn: (value: boolean) => void;\n updateVideoRequestState: (state: string) => void;\n updateLocalStream: (stream: MediaStream | null) => void;\n mediaDevices: MediaDevices;\n\n streamSuccessVideo: StreamSuccessVideoType;\n disconnectSendTransportVideo: DisconnectSendTransportVideoType;\n requestPermissionCamera: RequestPermissionCameraType;\n checkPermission: CheckPermissionType;\n\n getUpdatedAllParams: () => ClickVideoParameters;\n [key: string]: any;\n\n}\n\nexport interface ClickVideoOptions {\n parameters: ClickVideoParameters;\n}\n\n// Export the type definition for the function\nexport type ClickVideoType = (options: ClickVideoOptions) => Promise<void>;\n\n/**\n * Handles the click event to toggle the participant's video on/off and manages video permission requests.\n *\n * @param {ClickVideoOptions} options - The function parameters.\n * @returns {Promise<void>}\n *\n * @example\n * ```typescript\n * clickVideo({\n * parameters: {\n * checkMediaPermission: true,\n * hasCameraPermission: false,\n * videoAlreadyOn: false,\n * audioOnlyRoom: false,\n * recordStarted: true,\n * recordResumed: false,\n * recordPaused: true,\n * recordStopped: false,\n * recordingMediaOptions: \"video\",\n * islevel: \"1\",\n * youAreCoHost: false,\n * adminRestrictSetting: false,\n * videoRequestState: null,\n * videoRequestTime: Date.now(),\n * member: \"John Doe\",\n * socket: socketInstance,\n * roomName: \"room123\",\n * userDefaultVideoInputDevice: \"default\",\n * currentFacingMode: \"user\",\n * vidCons: { width: 1280, height: 720 },\n * frameRate: 30,\n * videoAction: false,\n * localStream: null,\n * audioSetting: \"allow\",\n * videoSetting: \"allow\",\n * screenshareSetting: \"allow\",\n * chatSetting: \"allow\",\n * updateRequestIntervalSeconds: 60,\n * showAlert: showAlertFunction,\n * updateVideoAlreadyOn: setVideoAlreadyOn,\n * updateVideoRequestState: setVideoRequestState,\n * updateLocalStream: setLocalStream,\n * mediaDevices: navigator.mediaDevices,\n * streamSuccessVideo: streamSuccessVideoFunction,\n * disconnectSendTransportVideo: disconnectVideoTransportFunction,\n * requestPermissionCamera: requestCameraPermissionFunction,\n * checkPermission: checkPermissionFunction,\n * getUpdatedAllParams: getUpdatedParamsFunction\n * }\n * });\n * ```\n */\n\nexport const clickVideo = async ({ parameters }: ClickVideoOptions): Promise<void> => {\n let {\n checkMediaPermission,\n hasCameraPermission,\n videoAlreadyOn,\n audioOnlyRoom,\n recordStarted,\n recordResumed,\n recordPaused,\n recordStopped,\n recordingMediaOptions,\n islevel,\n youAreCoHost,\n adminRestrictSetting,\n videoRequestState,\n videoRequestTime,\n member,\n socket,\n roomName,\n userDefaultVideoInputDevice,\n currentFacingMode,\n vidCons,\n frameRate,\n videoAction,\n localStream,\n audioSetting,\n videoSetting,\n screenshareSetting,\n chatSetting,\n updateRequestIntervalSeconds,\n streamSuccessVideo,\n showAlert,\n updateVideoAlreadyOn,\n updateVideoRequestState,\n updateLocalStream,\n mediaDevices,\n disconnectSendTransportVideo,\n requestPermissionCamera,\n checkPermission,\n } = parameters;\n\n const resolvedMediaDevices =\n typeof mediaDevices?.getUserMedia === \"function\"\n ? mediaDevices\n : globalThis.navigator?.mediaDevices;\n\n if (typeof resolvedMediaDevices?.getUserMedia !== \"function\") {\n showAlert?.({\n message:\n \"Camera access is unavailable in this browser session. Please refresh and try again.\",\n type: \"danger\",\n duration: 3000,\n });\n return;\n }\n\n if (audioOnlyRoom) {\n showAlert?.({\n message: \"You cannot turn on your camera in an audio-only event.\",\n type: \"danger\",\n duration: 3000,\n });\n return;\n }\n\n if (videoAlreadyOn) {\n if (islevel === \"2\" && (recordStarted || recordResumed)) {\n if (!(recordPaused || recordStopped)) {\n if (recordingMediaOptions === \"video\") {\n showAlert?.({\n message: \"You cannot turn off your camera while recording video, please pause or stop recording first.\",\n type: \"danger\",\n duration: 3000,\n });\n return;\n }\n }\n }\n\n videoAlreadyOn = false;\n updateVideoAlreadyOn(videoAlreadyOn);\n if (localStream && localStream.getVideoTracks().length > 0) {\n localStream.getVideoTracks()[0].enabled = false;\n updateLocalStream(localStream);\n }\n await disconnectSendTransportVideo({ parameters });\n } else {\n if (adminRestrictSetting) {\n showAlert?.({\n message: \"You cannot turn on your camera. Access denied by host.\",\n duration: 3000,\n type: \"danger\",\n });\n return;\n }\n\n let response = 2;\n\n if (!videoAction && islevel !== \"2\" && !youAreCoHost) {\n response = await checkPermission({\n permissionType: \"videoSetting\",\n audioSetting,\n videoSetting,\n screenshareSetting,\n chatSetting,\n permissionConfig: parameters.permissionConfig,\n participantLevel: islevel,\n });\n } else {\n response = 0;\n }\n\n if (response == 1) {\n //approval\n //check if request is pending or not\n if (videoRequestState === \"pending\") {\n showAlert?.({\n message: \"A request is pending. Please wait for the host to respond.\",\n type: \"danger\",\n duration: 3000,\n });\n return;\n }\n // check if rejected and current time is less than videoRequestTime\n if (videoRequestState === \"rejected\" && Date.now() - videoRequestTime < updateRequestIntervalSeconds) {\n showAlert?.({\n message: `A request was rejected. Please wait for ${updateRequestIntervalSeconds} seconds before sending another request.`,\n type: \"danger\",\n duration: 3000,\n });\n return;\n }\n\n // send request to host\n showAlert?.({\n message: \"Request sent to host.\",\n type: \"success\",\n duration: 3000,\n });\n videoRequestState = \"pending\";\n updateVideoRequestState(videoRequestState);\n\n const userRequest = { id: socket.id, name: member, icon: \"fa-video\" };\n await socket.emit(\"participantRequest\", { userRequest, roomName });\n } else if (response === 2) {\n //if video permission is set to deny then show alert\n showAlert?.({\n message: \"You cannot turn on your camera. Access denied by host.\",\n type: \"danger\",\n duration: 3000,\n });\n } else {\n //if video permission is set to allow then turn on video\n\n //first check if permission is granted\n if (!hasCameraPermission) {\n if (checkMediaPermission) {\n const statusCamera = await requestPermissionCamera();\n if (statusCamera !== \"granted\") {\n showAlert?.({\n message: \"Allow access to your camera or check if your camera is not being used by another application.\",\n type: \"danger\",\n duration: 3000,\n });\n return;\n }\n }\n }\n\n let mediaConstraints = {};\n let altMediaConstraints = {};\n if (userDefaultVideoInputDevice) {\n if (vidCons && vidCons.width && vidCons.height) {\n mediaConstraints = {\n video: {\n deviceId: userDefaultVideoInputDevice,\n facingMode: currentFacingMode,\n ...vidCons,\n frameRate: { ideal: frameRate },\n },\n audio: false,\n };\n altMediaConstraints = {\n video: { ...vidCons, frameRate: { ideal: frameRate } },\n audio: false,\n };\n } else {\n mediaConstraints = {\n video: { ...vidCons, frameRate: { ideal: frameRate } },\n audio: false,\n };\n altMediaConstraints = {\n video: { frameRate: { ideal: frameRate } },\n audio: false,\n };\n }\n } else {\n if (vidCons && vidCons.width && vidCons.height) {\n mediaConstraints = {\n video: { ...vidCons, frameRate: { ideal: frameRate } },\n audio: false,\n };\n altMediaConstraints = {\n video: { ...vidCons, frameRate: { ideal: frameRate } },\n audio: false,\n };\n } else {\n mediaConstraints = {\n video: { frameRate: { ideal: frameRate } },\n audio: false,\n };\n }\n }\n\n await resolvedMediaDevices\n .getUserMedia(mediaConstraints)\n .then(async (stream) => {\n await streamSuccessVideo({ stream, parameters });\n })\n .catch(async () => {\n await resolvedMediaDevices\n .getUserMedia(altMediaConstraints)\n .then(async (stream) => {\n await streamSuccessVideo({ stream, parameters });\n })\n .catch(async() => {\n //remove frameRate from constraints\n altMediaConstraints = {\n video: { ...vidCons },\n audio: false,\n };\n await resolvedMediaDevices\n .getUserMedia(altMediaConstraints)\n .then(async (stream) => {\n await streamSuccessVideo({ stream, parameters });\n }).catch(() => {\n\n showAlert?.({\n message:\n \"Allow access to your camera or check if your camera is not being used by another application.\",\n type: \"danger\",\n duration: 3000,\n });\n\n });\n });\n });\n }\n }\n};\n","import { clickVideo, ClickVideoParameters } from \"../methods/stream/clickVideo\";\nimport { ShowAlert, VidCons, RequestPermissionCameraType, StreamSuccessVideoType, SleepType, StreamSuccessVideoParameters } from \"../types/types\";\n\nexport interface SwitchUserVideoParameters extends StreamSuccessVideoParameters, ClickVideoParameters {\n audioOnlyRoom: boolean;\n frameRate: number;\n vidCons: VidCons;\n prevVideoInputDevice: string;\n userDefaultVideoInputDevice: string;\n showAlert?: ShowAlert;\n mediaDevices: MediaDevices;\n hasCameraPermission: boolean;\n updateVideoSwitching: (state: boolean) => void;\n updateUserDefaultVideoInputDevice: (deviceId: string) => void;\n\n // media functions\n requestPermissionCamera: RequestPermissionCameraType;\n streamSuccessVideo: StreamSuccessVideoType;\n sleep: SleepType;\n checkMediaPermission: boolean;\n \n getUpdatedAllParams: () => SwitchUserVideoParameters;\n [key: string]: any;\n}\n\nexport interface SwitchUserVideoOptions {\n videoPreference: string;\n checkoff: boolean;\n parameters: SwitchUserVideoParameters;\n}\n\n// Export the type definition for the function\nexport type SwitchUserVideoType = (options: SwitchUserVideoOptions) => Promise<void>;\n\n/**\n * Switches the user's video input device based on the provided options.\n *\n * @param {SwitchUserVideoOptions} options - The options for switching the user's video.\n * @param {string} options.videoPreference - The preferred video input device ID.\n * @param {boolean} options.checkoff - Flag indicating whether to turn off the video.\n * @param {Object} options.parameters - Additional parameters required for switching the video.\n * @param {boolean} options.parameters.audioOnlyRoom - Indicates if the room is audio-only.\n * @param {number} options.parameters.frameRate - The desired frame rate for the video.\n * @param {Object} options.parameters.vidCons - Video constraints such as width and height.\n * @param {string} options.parameters.prevVideoInputDevice - The previous video input device ID.\n * @param {Function} options.parameters.showAlert - Function to show alerts to the user.\n * @param {Object} options.parameters.mediaDevices - Media devices object to access user media.\n * @param {boolean} options.parameters.hasCameraPermission - Indicates if the user has camera permission.\n * @param {Function} options.parameters.updateVideoSwitching - Function to update video switching state.\n * @param {Function} options.parameters.updateUserDefaultVideoInputDevice - Function to update the default video input device.\n * @param {Function} options.parameters.requestPermissionCamera - Function to request camera permission.\n * @param {Function} options.parameters.streamSuccessVideo - Function to handle successful video stream.\n * @param {Function} options.parameters.sleep - Function to pause execution for a specified duration.\n * @param {Function} options.parameters.checkMediaPermission - Function to check media permissions.\n *\n * @returns {Promise<void>} A promise that resolves when the video input device has been successfully switched.\n *\n * @throws Will throw an error if the audio input device cannot be accessed or if there is an unexpected error.\n *\n * @example\n * ```typescript\n * await switchUserVideo({\n * videoPreference: 'video-device-id',\n * checkoff: false,\n * parameters: {\n * audioOnlyRoom: false,\n * frameRate: 30,\n * vidCons: { width: 640, height: 480 },\n * prevVideoInputDevice: 'prev-video-device-id',\n * showAlert: showAlertFunction,\n * mediaDevices: navigator.mediaDevices,\n * hasCameraPermission: true,\n * updateVideoSwitching: updateVideoSwitchingFunction,\n * updateUserDefaultVideoInputDevice: updateUserDefaultVideoInputDeviceFunction,\n * requestPermissionCamera: requestPermissionCameraFunction,\n * streamSuccessVideo: streamSuccessVideoFunction,\n * sleep: sleepFunction,\n * checkMediaPermission: true,\n * getUpdatedAllParams: getUpdatedAllParamsFunction,\n * },\n * });\n * ```\n */\n\nexport async function switchUserVideo({\n videoPreference,\n checkoff,\n parameters,\n}: SwitchUserVideoOptions): Promise<void> {\n const {\n audioOnlyRoom,\n frameRate,\n vidCons,\n prevVideoInputDevice,\n showAlert,\n mediaDevices,\n hasCameraPermission,\n updateVideoSwitching,\n updateUserDefaultVideoInputDevice,\n\n //mediasfu functions\n requestPermissionCamera,\n streamSuccessVideo,\n sleep,\n checkMediaPermission,\n } = parameters;\n\n try {\n // Check if it's an audio-only room\n if (audioOnlyRoom) {\n\n showAlert?.({\n message: \"You cannot turn on your camera in an audio-only event.\",\n type: \"danger\",\n duration: 3000,\n });\n\n return;\n }\n\n // If checkoff is not true, trigger a click on the video button to turn off the video\n if (!checkoff) {\n await clickVideo({ parameters });\n updateVideoSwitching(true);\n await sleep({ ms: 500 });\n updateVideoSwitching(false);\n }\n\n // Check camera permission\n if (!hasCameraPermission) {\n if (checkMediaPermission) {\n const statusCamera = await requestPermissionCamera();\n if (statusCamera !== \"granted\") {\n\n showAlert?.({\n message:\n \"Allow access to your camera or check if your camera is not being used by another application.\",\n type: \"danger\",\n duration: 3000,\n });\n\n return;\n }\n }\n }\n\n let mediaConstraints: MediaStreamConstraints;\n\n if (vidCons && vidCons.width && vidCons.height) {\n mediaConstraints = {\n video: {\n deviceId: { exact: videoPreference },\n ...vidCons,\n frameRate: { ideal: frameRate },\n },\n audio: false,\n };\n } else {\n mediaConstraints = {\n video: {\n deviceId: { exact: videoPreference },\n frameRate: { ideal: frameRate },\n },\n audio: false,\n };\n }\n\n // Get user media with the defined constraints\n await mediaDevices\n .getUserMedia(mediaConstraints)\n .then(async (stream) => {\n await streamSuccessVideo({ stream, parameters });\n })\n .catch(async () => {\n // Handle errors and revert to the previous video input device\n updateUserDefaultVideoInputDevice(prevVideoInputDevice);\n\n\n showAlert?.({\n message:\n \"Error switching; not accessible, might need to turn off your video and turn it back on after switching.\",\n type: \"danger\",\n duration: 3000,\n });\n\n });\n } catch {\n // Handle unexpected errors and revert to the previous video input device\n updateUserDefaultVideoInputDevice(prevVideoInputDevice);\n\n\n showAlert?.({\n message:\n \"Error switching; not accessible, might need to turn off your video and turn it back on after switching.\",\n type: \"danger\",\n duration: 3000,\n });\n\n }\n}\n\n","import { clickVideo, ClickVideoParameters } from \"../methods/stream/clickVideo\";\nimport { ShowAlert, VidCons, RequestPermissionCameraType, StreamSuccessVideoType, SleepType, StreamSuccessVideoParameters } from \"../types/types\";\n\n\nexport interface SwitchUserVideoAltParameters extends StreamSuccessVideoParameters, ClickVideoParameters {\n audioOnlyRoom: boolean;\n frameRate: number;\n vidCons: VidCons;\n showAlert?: ShowAlert;\n mediaDevices: MediaDevices;\n hasCameraPermission: boolean;\n updateVideoSwitching: (state: boolean) => void;\n updateCurrentFacingMode: (mode: string) => void;\n\n // mediasfu functions\n requestPermissionCamera: RequestPermissionCameraType;\n streamSuccessVideo: StreamSuccessVideoType;\n sleep: SleepType;\n checkMediaPermission: boolean;\n getUpdatedAllParams: () => SwitchUserVideoAltParameters;\n\n [key: string]: any;\n}\n\nexport interface SwitchUserVideoAltOptions {\n videoPreference: string;\n checkoff: boolean;\n parameters: SwitchUserVideoAltParameters;\n}\n\n// Export the type definition for the function\nexport type SwitchUserVideoAltType = (options: SwitchUserVideoAltOptions) => Promise<void>;\n\n/**\n * Switches the user's video stream based on the provided video preference and other parameters.\n * \n * @param {SwitchUserVideoAltOptions} options - The options for switching the user's video.\n * @param {string} options.videoPreference - The preferred video facing mode (e.g., \"user\" or \"environment\").\n * @param {boolean} options.checkoff - A flag indicating whether to turn off the video before switching.\n * @param {SwitchUserVideoAltParameters} options.parameters - The parameters required for switching the video.\n * \n * @returns {Promise<void>} A promise that resolves when the video switching is complete.\n * \n * @throws Will throw an error if there is an issue with switching the video.\n * \n * @example\n * ```typescript\n * const options = {\n * videoPreference: \"user\",\n * checkoff: false,\n * parameters: {\n * audioOnlyRoom: false,\n * frameRate: 30,\n * vidCons: { width: 640, height: 480 },\n * showAlert: showNotification,\n * mediaDevices: navigator.mediaDevices,\n * hasCameraPermission: true,\n * updateVideoSwitching: updateVideoSwitchingState,\n * updateCurrentFacingMode: updateCurrentFacingMode,\n * requestPermissionCamera: requestCameraPermission,\n * streamSuccessVideo: streamSuccessVideoFunction,\n * sleep: sleepFunction,\n * checkMediaPermission: true,\n * getUpdatedAllParams: getUpdatedAllParamsFunction,\n * },\n * };\n * \n * switchUserVideoAlt(options)\n * .then(() => {\n * console.log(\"Video switched successfully\");\n * })\n * .catch((error) => {\n * console.error(\"Error switching video:\", error);\n * });\n * ```\n */\n\nexport async function switchUserVideoAlt({\n videoPreference,\n checkoff,\n parameters,\n}: SwitchUserVideoAltOptions): Promise<void> {\n const updatedParameters = parameters.getUpdatedAllParams();\n\n const {\n audioOnlyRoom,\n frameRate,\n vidCons,\n showAlert,\n mediaDevices,\n hasCameraPermission,\n updateVideoSwitching,\n updateCurrentFacingMode,\n\n //mediasfu functions\n requestPermissionCamera,\n streamSuccessVideo,\n sleep,\n checkMediaPermission,\n } = parameters;\n\n let { currentFacingMode, prevFacingMode } = updatedParameters;\n\n try {\n if (audioOnlyRoom) {\n showAlert?.({\n message: \"You cannot turn on your camera in an audio-only event.\",\n type: \"danger\",\n duration: 3000,\n });\n return;\n }\n\n // If checkoff is not true, trigger a click on the video button to turn off the video\n if (!checkoff) {\n await clickVideo({ parameters });\n updateVideoSwitching(true);\n await sleep({ ms: 500 });\n updateVideoSwitching(false);\n }\n\n // Check camera permission\n if (!hasCameraPermission && checkMediaPermission) {\n const statusCamera = await requestPermissionCamera();\n if (statusCamera !== \"granted\") {\n showAlert?.({\n message:\n \"Allow access to your camera or check if your camera is not being used by another application.\",\n type: \"danger\",\n duration: 3000,\n });\n return;\n }\n }\n\n // Enumerate video devices\n const videoDevices = await mediaDevices.enumerateDevices();\n\n // Define media constraints based on preferences and options\n let mediaConstraints = {};\n\n if (vidCons && vidCons.width && vidCons.height) {\n mediaConstraints = {\n video: {\n facingMode: { exact: videoPreference },\n ...vidCons,\n frameRate: { ideal: frameRate },\n },\n audio: false,\n };\n } else {\n mediaConstraints = {\n video: {\n facingMode: { exact: videoPreference },\n frameRate: { ideal: frameRate },\n },\n audio: false,\n };\n }\n\n // Get user media with the defined constraints\n await mediaDevices\n .getUserMedia(mediaConstraints)\n .then(async (stream) => {\n await streamSuccessVideo({ stream, parameters });\n })\n .catch(async () => {\n let videoDevicesFront: MediaDeviceInfo[] = [];\n\n // Filter video devices based on the preferred facing mode\n if (videoPreference === \"user\") {\n videoDevicesFront = videoDevices.filter(\n (device) =>\n device.label.includes(\"front\") && device.kind === \"videoinput\"\n );\n } else {\n videoDevicesFront = videoDevices.filter(\n (device) =>\n device.label.includes(\"back\") && device.kind === \"videoinput\"\n );\n }\n\n if (videoDevicesFront.length > 0) {\n videoDevicesFront.forEach((device) => {\n if (device.kind === \"videoinput\") {\n let videoDeviceId = device.deviceId;\n\n // Update media constraints with the specific video device\n if (vidCons && vidCons.width && vidCons.height) {\n mediaConstraints = {\n video: {\n deviceId: { exact: videoDeviceId },\n ...vidCons,\n frameRate: { ideal: frameRate },\n },\n audio: false,\n };\n } else {\n mediaConstraints = {\n video: {\n deviceId: { exact: videoDeviceId },\n frameRate: { ideal: frameRate },\n },\n audio: false,\n };\n }\n\n // Try to get user media with the new constraints\n mediaDevices\n .getUserMedia(mediaConstraints)\n .then(async (stream) => {\n await streamSuccessVideo({ stream, parameters });\n })\n .catch(() => {\n // If the current video device is the last one in the list, show the error; otherwise, try the next device\n if (\n videoDeviceId ===\n videoDevicesFront[videoDevicesFront.length - 1].deviceId\n ) {\n currentFacingMode = prevFacingMode;\n updateCurrentFacingMode(currentFacingMode);\n\n showAlert?.({\n message:\n \"Error switching; not accessible, might need to turn off your video and turn it back on after switching.\",\n type: \"danger\",\n duration: 3000,\n });\n\n }\n });\n }\n });\n } else {\n // Show error if no compatible video devices are found\n currentFacingMode = prevFacingMode;\n updateCurrentFacingMode(currentFacingMode);\n\n\n showAlert?.({\n message:\n \"Error switching; not accessible, might need to turn off your video and turn it back on after switching.\",\n type: \"danger\",\n duration: 3000,\n });\n\n }\n });\n } catch {\n // Handle any unexpected errors\n\n const videoDevices = await mediaDevices.enumerateDevices();\n // Handle any unexpected errors\n let videoDevicesFront: MediaDeviceInfo[] = [];\n if (videoPreference === \"user\") {\n videoDevicesFront = videoDevices.filter(\n (device) =>\n device.label.includes(\"front\") && device.kind === \"videoinput\"\n );\n } else {\n videoDevicesFront = videoDevices.filter(\n (device) =>\n device.label.includes(\"back\") && device.kind === \"videoinput\"\n );\n }\n\n let mediaConstraints = {};\n\n if (videoDevicesFront.length > 0) {\n videoDevicesFront.forEach((device) => {\n if (device.kind === \"videoinput\") {\n let videoDeviceId = device.deviceId;\n\n if (vidCons && vidCons.width && vidCons.height) {\n mediaConstraints = {\n video: {\n deviceId: { exact: videoDeviceId },\n ...vidCons,\n frameRate: { ideal: frameRate },\n },\n audio: false,\n };\n } else {\n mediaConstraints = {\n video: {\n deviceId: { exact: videoDeviceId },\n frameRate: { ideal: frameRate },\n },\n audio: false,\n };\n }\n\n mediaDevices\n .getUserMedia(mediaConstraints)\n .then(async (stream) => {\n await streamSuccessVideo({ stream, parameters });\n })\n .catch(() => {\n if (\n videoDeviceId ===\n videoDevicesFront[videoDevicesFront.length - 1].deviceId\n ) {\n currentFacingMode = prevFacingMode;\n updateCurrentFacingMode(currentFacingMode);\n\n showAlert?.({\n message:\n \"Error switching; not accessible, might need to turn off your video and turn it back on after switching.\",\n type: \"danger\",\n duration: 3000,\n });\n\n }\n });\n }\n });\n } else {\n currentFacingMode = prevFacingMode;\n updateCurrentFacingMode(currentFacingMode);\n\n\n showAlert?.({\n message:\n \"Error switching; not accessible, might need to turn off your video and turn it back on after switching.\",\n type: \"danger\",\n duration: 3000,\n });\n\n }\n }\n}\n","import { Socket } from \"socket.io-client\";\nimport { Participant, AutoAdjustType, ScreenState, EventType } from \"../types/types\";\n\nexport interface TriggerParameters {\n socket: Socket;\n localSocket?: Socket;\n roomName: string;\n screenStates: ScreenState[];\n participants: Participant[];\n updateDateState?: number | null;\n lastUpdate: number | null;\n nForReadjust: number | null;\n eventType: EventType;\n shared: boolean;\n shareScreenStarted: boolean;\n whiteboardStarted: boolean;\n whiteboardEnded: boolean;\n updateUpdateDateState: (timestamp: number | null) => void;\n updateLastUpdate: (lastUpdate: number | null) => void;\n updateNForReadjust: (nForReadjust: number) => void;\n\n\n // mediasfu functions\n autoAdjust: AutoAdjustType;\n\n getUpdatedAllParams: () => TriggerParameters;\n [key: string]: any;\n}\n\nexport interface TriggerOptions {\n ref_ActiveNames: string[];\n parameters: TriggerParameters;\n}\n\n// Export the type definition for the function\nexport type TriggerType = (options: TriggerOptions) => Promise<void>;\n\n/**\n * Triggers an update to the screen client based on the provided parameters.\n *\n * @param {TriggerOptions} options - The options for triggering the update.\n * @param {string[]} options.ref_ActiveNames - Reference to the active names.\n * @param {TriggerParameters} options.parameters - The parameters for the trigger.\n * \n * @returns {Promise<void>} A promise that resolves when the trigger is complete.\n *\n * @throws Will throw an error if the updateScreenClient operation fails.\n *\n * @remarks\n * This function handles various conditions to determine the main screen person,\n * adjusts the screen states, and emits an update to the screen client via socket.\n *\n * @example\n * ```typescript\n * await trigger({\n * ref_ActiveNames: [\"user1\", \"user2\"],\n * parameters: {\n * socket: socketInstance,\n * localSocket: localSocketInstance,\n * roomName: \"room1\",\n * screenStates: [{ mainScreenPerson: \"user1\", mainScreenFilled: true, adminOnMainScreen: false }],\n * participants: [{ name: \"admin\", islevel: \"2\" }],\n * updateDateState: 0,\n * lastUpdate: null,\n * nForReadjust: 0,\n * eventType: \"conference\",\n * shared: false,\n * shareScreenStarted: false,\n * whiteboardStarted: false,\n * whiteboardEnded: false,\n * updateUpdateDateState: (date) => {},\n * updateLastUpdate: (date) => {},\n * updateNForReadjust: (n) => {},\n * autoAdjust: async ({ n, parameters }) => [n, 0],\n * },\n * });\n * ```\n */\n\nexport async function trigger({\n ref_ActiveNames,\n parameters,\n}: TriggerOptions): Promise<void> {\n try {\n parameters = parameters.getUpdatedAllParams();\n\n let {\n socket,\n localSocket,\n roomName,\n screenStates,\n participants,\n updateDateState,\n lastUpdate,\n nForReadjust,\n eventType,\n shared,\n shareScreenStarted,\n whiteboardStarted,\n whiteboardEnded,\n updateUpdateDateState,\n updateLastUpdate,\n updateNForReadjust,\n\n //mediasfu functions\n autoAdjust,\n } = parameters;\n\n let socketRef = socket;\n if (localSocket && localSocket.id) {\n socketRef = localSocket;\n }\n\n let personOnMainScreen = screenStates[0].mainScreenPerson;\n let adminName = \"\";\n const admin = participants.filter(\n (participant) => participant.islevel == \"2\"\n );\n if (admin.length > 0) {\n adminName = admin[0].name || \"\";\n }\n\n if (personOnMainScreen === \"WhiteboardActive\") {\n personOnMainScreen = adminName;\n }\n\n let mainfilled = screenStates[0].mainScreenFilled;\n let adminOnMain = screenStates[0].adminOnMainScreen;\n let nForReadjust_: number;\n let val1: number;\n\n let noww = new Date().getTime();\n //get now in seconds\n let timestamp = Math.floor(noww / 1000);\n\n let eventPass = false;\n\n if (eventType == \"conference\" && !(shared || shareScreenStarted)) {\n eventPass = true;\n personOnMainScreen = adminName;\n\n if (!ref_ActiveNames.includes(adminName)) {\n ref_ActiveNames.unshift(adminName);\n }\n }\n\n if ((mainfilled && personOnMainScreen != null && adminOnMain) || eventPass) {\n if (eventType == \"conference\") {\n nForReadjust = nForReadjust! + 1;\n updateNForReadjust(nForReadjust);\n }\n\n if (!ref_ActiveNames.includes(adminName) && whiteboardStarted && !whiteboardEnded) {\n ref_ActiveNames.unshift(adminName);\n }\n\n nForReadjust_ = ref_ActiveNames.length;\n\n if (nForReadjust_ == 0 && eventType == \"webinar\") {\n val1 = 0;\n } else {\n const [val11, ] = await autoAdjust({\n n: nForReadjust_,\n eventType,\n shared,\n shareScreenStarted,\n });\n val1 = val11;\n }\n\n let calc1 = Math.floor((val1 / 12) * 100);\n let calc2 = (100) - calc1;\n\n //check if lastUpdate is not null and at least same seconds\n if (lastUpdate == null || updateDateState != timestamp) {\n let now = new Date();\n\n socketRef.emit(\n \"updateScreenClient\",\n {\n roomName,\n names: ref_ActiveNames,\n mainPercent: calc2,\n mainScreenPerson: personOnMainScreen,\n viewType: eventType,\n },\n ({ success, reason }: { success: boolean; reason: string; }) => {\n updateDateState = timestamp;\n updateUpdateDateState(updateDateState);\n lastUpdate = Math.floor(now.getTime() / 1000);\n updateLastUpdate(lastUpdate);\n if (!success) {\n console.log(reason, \"updateScreenClient failed\");\n }\n }\n );\n }\n } else if (mainfilled && personOnMainScreen != null && !adminOnMain) {\n //check if the person on main screen is still in the room\n // ss = true\n\n nForReadjust_ = ref_ActiveNames.length;\n\n if (!ref_ActiveNames.includes(adminName)) {\n ref_ActiveNames.unshift(adminName);\n }\n\n const [val11, ] = await autoAdjust({\n n: nForReadjust_,\n eventType,\n shared,\n shareScreenStarted,\n });\n val1 = val11;\n\n const calc1 = Math.floor((val1 / 12) * 100);\n const calc2 = 100 - calc1;\n\n if (lastUpdate == null || updateDateState !== timestamp) {\n let now = new Date();\n\n socketRef.emit(\n \"updateScreenClient\",\n {\n roomName,\n names: ref_ActiveNames,\n mainPercent: calc2,\n mainScreenPerson: personOnMainScreen,\n viewType: eventType,\n },\n ({ success, reason }: { success: boolean; reason: string; }) => {\n updateDateState = timestamp;\n updateUpdateDateState(updateDateState);\n lastUpdate = Math.floor(now.getTime() / 1000);\n updateLastUpdate(lastUpdate);\n if (!success) {\n console.log(reason, \"updateScreenClient failed\");\n }\n }\n );\n }\n } else {\n //stop recording\n console.log(\"trigger stopRecording\");\n }\n } catch (error) {\n console.log(\"Error triggering updateScreen:\", error);\n }\n}\n\n","import { EventType } from '../types/types';\n\nexport interface AutoAdjustOptions {\n n: number;\n eventType: EventType;\n shareScreenStarted: boolean;\n shared: boolean; \n}\n\nexport type AutoAdjustType = (options: AutoAdjustOptions) => Promise<number[]>;\n\n\n/**\n * Adjusts values based on the provided options and the number of participants.\n *\n * @function\n * @async\n * @param {AutoAdjustOptions} options - The options for auto adjustment.\n * @param {number} options.n - The number of participants.\n * @param {string} options.eventType - The type of event (e.g., 'broadcast', 'chat', 'conference').\n * @param {boolean} options.shareScreenStarted - Indicates if screen sharing has started.\n * @param {boolean} options.shared - Indicates if something is shared.\n * \n * @returns {Promise<number[]>} A promise that resolves to an array containing the adjusted values.\n * \n * @example\n * import { autoAdjust } from 'mediasfu-reactjs';\n *\n * const options = {\n * n: 10,\n * eventType: 'conference',\n * shareScreenStarted: false,\n * shared: false,\n * };\n * \n * autoAdjust(options)\n * .then(values => {\n * console.log('Adjusted values:', values);\n * })\n * .catch(error => {\n * console.error('Error adjusting values:', error);\n * });\n */\n\nexport async function autoAdjust({\n n,\n eventType, shareScreenStarted, shared\n}: AutoAdjustOptions): Promise<number[]> {\n\n // Default values\n let val1 = 6;\n let val2 = 12 - val1;\n\n // Adjust values based on eventType and other conditions\n if (eventType === 'broadcast') {\n val1 = 0;\n val2 = 12 - val1;\n } else if (\n eventType === 'chat' ||\n (eventType === 'conference' && !(shareScreenStarted || shared))\n ) {\n val1 = 12;\n val2 = 12 - val1;\n } else {\n if (shareScreenStarted || shared) {\n val2 = 10;\n val1 = 12 - val2;\n } else {\n // Adjust values based on the number of participants (n)\n if (n === 0) {\n val1 = 1;\n val2 = 12 - val1;\n } else if (n >= 1 && n < 4) {\n val1 = 4;\n val2 = 12 - val1;\n } else if (n >= 4 && n < 6) {\n val1 = 6;\n val2 = 12 - val1;\n } else if (n >= 6 && n < 9) {\n val1 = 6;\n val2 = 12 - val1;\n } else if (n >= 9 && n < 12) {\n val1 = 6;\n val2 = 12 - val1;\n } else if (n >= 12 && n < 20) {\n val1 = 8;\n val2 = 12 - val1;\n } else if (n >= 20 && n < 50) {\n val1 = 8;\n val2 = 12 - val1;\n } else {\n val1 = 10;\n val2 = 12 - val1;\n }\n }\n }\n\n // Return an array with adjusted values\n return [val1, val2];\n}\n","export interface CalculateRowsAndColumnsOptions {\n n: number;\n}\n\n// Export the type definition for the function\nexport type CalculateRowsAndColumnsType = (options: CalculateRowsAndColumnsOptions) => [number, number];\n\n/**\n * Calculates the number of rows and columns needed to display a given number of items in a grid.\n *\n * @function\n * @param {CalculateRowsAndColumnsOptions} options - The options for calculating rows and columns.\n * @param {number} options.n - The number of items to display.\n * @returns {[number, number]} A tuple containing the number of rows and columns.\n * \n * @example\n * import { calculateRowsAndColumns } from 'mediasfu-reactjs';\n *\n * const options = {\n * n: 10,\n * };\n * \n * const [rows, cols] = calculateRowsAndColumns(options);\n * console.log(`Rows: ${rows}, Columns: ${cols}`); // Outputs: Rows: 4, Columns: 3\n */\nexport function calculateRowsAndColumns({ n }: CalculateRowsAndColumnsOptions): [number, number] {\n // Calculate the square root of n\n const sqrt = Math.sqrt(n);\n\n // Initialize columns based on the floor of the square root\n let cols = Math.floor(sqrt);\n\n // Calculate the number of rows needed to display n videos\n let rows = Math.ceil(n / cols);\n\n // Calculate the product of rows and columns\n let prod = rows * cols;\n\n // Adjust rows and columns until the product is greater than or equal to n\n while (prod < n) {\n if (cols < rows) {\n cols++;\n } else {\n rows++;\n }\n prod = rows * cols;\n }\n\n // Return an array with the calculated number of rows and columns\n return [rows, cols];\n}\n","export interface CheckGridOptions {\n rows: number;\n cols: number;\n actives: number;\n}\n\nexport type CheckGridType = (options: CheckGridOptions) => Promise<[boolean, number, number, number, number, number, number] | void>;\n\n/**\n * Checks the grid configuration and calculates various parameters based on the number of rows, columns, and active elements.\n *\n * @param {CheckGridOptions} options - The options for checking the grid.\n * @param {number} options.rows - The number of rows in the grid.\n * @param {number} options.cols - The number of columns in the grid.\n * @param {number} options.actives - The number of active elements in the grid.\n * @returns {Promise<[boolean, number, number, number, number, number, number] | void>} A promise that resolves to a tuple containing:\n * - `removeAltGrid` (boolean): Indicates whether to remove the alternate grid.\n * - `numtoadd` (number): The number of elements to add.\n * - `numRows` (number): The number of rows.\n * - `numCols` (number): The number of columns.\n * - `remainingVideos` (number): The number of remaining videos.\n * - `actualRows` (number): The actual number of rows.\n * - `lastrowcols` (number): The number of columns in the last row.\n * \n * If an error occurs, it logs the error to the console.\n *\n * @example\n * const options = {\n * rows: 3,\n * cols: 4,\n * actives: 10,\n * };\n * \n * checkGrid(options)\n * .then(result => {\n * console.log('Grid check result:', result);\n * // Example output: [true, 2, 3, 4, 2, 3, 4]\n * })\n * .catch(error => {\n * console.error('Error checking grid:', error);\n * });\n */\n\nexport async function checkGrid({ rows, cols, actives }: CheckGridOptions): Promise<[boolean, number, number, number, number, number, number] | void> {\n try {\n let numRows = 0;\n let numCols = 0;\n let lastrow = 0;\n let lastrowcols = 0;\n let remainingVideos = 0;\n let numtoadd = 0;\n let actualRows = 0;\n let removeAltGrid = false;\n\n if (rows * cols !== actives) {\n if (rows * cols > actives) {\n const res = actives - (rows - 1) * cols;\n if (cols * 0.5 < res) {\n lastrow = rows;\n lastrowcols = res;\n remainingVideos = lastrowcols;\n } else {\n lastrowcols = res + cols;\n lastrow = rows - 1;\n remainingVideos = lastrowcols;\n }\n\n numRows = lastrow - 1;\n numCols = cols;\n numtoadd = (lastrow - 1) * numCols;\n actualRows = lastrow;\n\n removeAltGrid = false;\n }\n } else {\n // Perfect fit\n numCols = cols;\n numRows = rows;\n lastrow = rows;\n lastrowcols = cols;\n remainingVideos = 0;\n numtoadd = lastrow * numCols;\n actualRows = lastrow;\n removeAltGrid = true;\n }\n\n return [\n removeAltGrid,\n numtoadd,\n numRows,\n numCols,\n remainingVideos,\n actualRows,\n lastrowcols,\n ];\n } catch (error) {\n console.log(\"checkGrid error\", error);\n // throw error;\n }\n}\n","import { PermissionConfig } from '../methods/permissions/updatePermissionConfig';\n\nexport interface CheckPermissionOptions {\n audioSetting: string;\n videoSetting: string;\n screenshareSetting: string;\n chatSetting: string;\n permissionType: 'audioSetting' | 'videoSetting' | 'screenshareSetting' | 'chatSetting';\n permissionConfig?: PermissionConfig | null;\n participantLevel?: string;\n}\n\n// Export the type definition for the function\nexport type CheckPermissionType = (options: CheckPermissionOptions) => Promise<number>;\n\n/**\n * Checks the permission based on the provided settings.\n *\n * @param {CheckPermissionOptions} options - The options for checking permissions.\n * @param {string} options.permissionType - The type of permission to check. Can be \"audioSetting\", \"videoSetting\", \"screenshareSetting\", or \"chatSetting\".\n * @param {string} options.audioSetting - The setting for audio permission. Can be \"allow\", \"approval\", or other.\n * @param {string} options.videoSetting - The setting for video permission. Can be \"allow\", \"approval\", or other.\n * @param {string} options.screenshareSetting - The setting for screenshare permission. Can be \"allow\", \"approval\", or other.\n * @param {string} options.chatSetting - The setting for chat permission. Can be \"allow\", \"approval\", or other.\n * @returns {Promise<number>} - Returns 0 if the setting is \"allow\", 1 if the setting is \"approval\", and 2 for other settings or invalid permission types.\n * @throws Will throw an error if an unexpected error occurs during the permission check.\n *\n * @example\n * const options = {\n * permissionType: 'audioSetting',\n * audioSetting: 'allow',\n * videoSetting: 'approval',\n * screenshareSetting: 'approval',\n * chatSetting: 'allow',\n * };\n * \n * checkPermission(options)\n * .then(result => {\n * console.log('Permission result:', result);\n * })\n * .catch(error => {\n * console.error('Error checking permission:', error);\n * });\n */\n\nexport async function checkPermission({\n permissionType,\n audioSetting,\n videoSetting,\n screenshareSetting,\n chatSetting,\n permissionConfig,\n participantLevel,\n}: CheckPermissionOptions) {\n try {\n\n const permissionTypeToCapability: Record<string, keyof import('../methods/permissions/updatePermissionConfig').PermissionCapabilities> = {\n audioSetting: 'useMic',\n videoSetting: 'useCamera',\n screenshareSetting: 'useScreen',\n chatSetting: 'useChat',\n };\n\n if (permissionConfig && participantLevel && participantLevel !== '2') {\n const levelKey = `level${participantLevel}` as 'level0' | 'level1';\n const levelConfig = permissionConfig[levelKey];\n\n if (levelConfig) {\n const capability = permissionTypeToCapability[permissionType];\n if (capability) {\n const configValue = levelConfig[capability];\n if (configValue === 'allow') return 0;\n if (configValue === 'approval') return 1;\n return 2;\n }\n }\n }\n\n // PermissionType is audioSetting, videoSetting, screenshareSetting, chatSetting\n // Perform a switch case to check for the permissionType and return the response\n switch (permissionType) {\n case \"audioSetting\":\n if (audioSetting === \"allow\") {\n return 0;\n } else if (audioSetting === \"approval\") {\n return 1;\n } else {\n return 2;\n }\n case \"videoSetting\":\n if (videoSetting === \"allow\") {\n return 0;\n } else if (videoSetting === \"approval\") {\n return 1;\n } else {\n return 2;\n }\n case \"screenshareSetting\":\n if (screenshareSetting === \"allow\") {\n return 0;\n } else if (screenshareSetting === \"approval\") {\n return 1;\n } else {\n return 2;\n }\n case \"chatSetting\":\n if (chatSetting === \"allow\") {\n return 0;\n } else if (chatSetting === \"approval\") {\n return 1;\n } else {\n return 2;\n }\n default:\n // throw new Error(`Invalid permissionType: ${permissionType}`);\n return 2;\n }\n } catch {\n // console.log('checkPermission error', error);\n // throw error;\n return 2;\n }\n}\n"," \nimport { Socket } from \"socket.io-client\";\nimport { CoHostResponsibility, Participant, ShowAlert } from \"../types/types\";\n\nexport interface ControlMediaOptions {\n participantId: string;\n participantName: string;\n type: 'audio' | 'video' | 'screenshare' | 'all';\n socket: Socket;\n coHostResponsibility: CoHostResponsibility[];\n participants: Participant[];\n member: string;\n islevel: string;\n showAlert?: ShowAlert;\n coHost: string;\n roomName: string;\n}\n// Export the type definition for the function\nexport type ControlMediaType = (options: ControlMediaOptions) => Promise<void>;\n\n/**\n * Controls the media of a participant in a media session if certain conditions are met.\n *\n * @param {ControlMediaOptions} options - The options for controlling media.\n * @param {string} options.participantId - The ID of the participant to control.\n * @param {string} options.participantName - The name of the participant to control.\n * @param {'audio' | 'video' | 'screenshare' | 'all'} options.type - The type of media to control.\n * @param {Socket} options.socket - The socket instance for communication.\n * @param {Array<CoHostResponsibility>} options.coHostResponsibility - List of co-host responsibilities.\n * @param {Array<Participant>} options.participants - List of participants in the session.\n * @param {string} options.member - The current member attempting to control media.\n * @param {string} options.islevel - The level of the current member.\n * @param {Function} [options.showAlert] - Optional function to show alerts.\n * @param {string} options.coHost - The co-host information.\n * @param {string} options.roomName - The name of the room.\n *\n * @returns {Promise<void>} A promise that resolves when the media control operation is complete.\n *\n * @throws Will log an error message if there are issues controlling the media or if participant is not found.\n *\n * @example\n * const options = {\n * participantId: '1234',\n * participantName: 'John Doe',\n * type: 'audio',\n * socket: socketInstance,\n * coHostResponsibility: [{ name: 'media', value: true }],\n * participants: participantList,\n * member: 'Admin',\n * islevel: '1',\n * showAlert: (alert) => console.log(alert.message),\n * coHost: 'CoHostName',\n * roomName: 'Room 1',\n * };\n * \n * controlMedia(options)\n * .then(() => {\n * console.log('Media control operation completed successfully.');\n * })\n * .catch((error) => {\n * console.error('Error controlling media:', error);\n * });\n */\n\nexport async function controlMedia({\n participantId,\n participantName,\n type,\n socket,\n coHostResponsibility,\n participants,\n member,\n islevel,\n showAlert,\n coHost,\n roomName,\n}: ControlMediaOptions): Promise<void> {\n try {\n let mediaValue = false;\n\n try {\n mediaValue = coHostResponsibility.find((item) => item.name === \"media\")?.value ?? false;\n } catch (error) {\n console.log(\"Error retrieving media control value\", error);\n }\n\n const participant = participants.find((obj) => obj.name === participantName);\n\n if (!participant) {\n console.log(\"Participant not found\");\n return;\n }\n\n if (islevel === \"2\" || (coHost === member && mediaValue === true)) {\n if (\n (!participant.muted && participant.islevel !== \"2\" && type === \"audio\") ||\n (participant.islevel !== \"2\" && type === \"video\" && participant.videoOn)\n ) {\n socket.emit(\"controlMedia\", {\n participantId,\n participantName,\n type,\n roomName,\n });\n }\n } else {\n if (showAlert) {\n showAlert({\n message: \"You are not allowed to control media for other participants.\",\n type: \"danger\",\n duration: 3000,\n });\n }\n }\n } catch (error) {\n console.log(\"controlMedia error\", error);\n }\n}\n","import { CalculateRowsAndColumnsType, EventType } from \"../types/types\";\n\nexport interface GetEstimateParameters {\n fixedPageLimit: number;\n screenPageLimit: number;\n shareScreenStarted: boolean;\n shared?: boolean;\n eventType: EventType;\n removeAltGrid: boolean;\n isWideScreen: boolean;\n isMediumScreen: boolean;\n updateRemoveAltGrid: (value: boolean) => void;\n\n // mediaSfu functions\n calculateRowsAndColumns: CalculateRowsAndColumnsType;\n\n [key: string]: any;\n}\n\nexport interface GetEstimateOptions {\n n: number;\n parameters: GetEstimateParameters;\n}\n\n// Export the type definition for the function\nexport type GetEstimateType = (options: GetEstimateOptions) => [number, number, number];\n\n/**\n * Estimates the number of rows and columns for a given set of parameters.\n *\n * @param {GetEstimateOptions} options - The options for the estimation.\n * @param {number} options.n - The number of items to estimate for.\n * @param {GetEstimateParameters} options.parameters - The parameters for the estimation.\n * @param {number} options.parameters.fixedPageLimit - The fixed page limit.\n * @param {number} options.parameters.screenPageLimit - The screen page limit.\n * @param {boolean} options.parameters.shareScreenStarted - Indicates if screen sharing has started.\n * @param {boolean} [options.parameters.shared] - Indicates if sharing is active.\n * @param {string} options.parameters.eventType - The type of event (e.g., \"chat\", \"conference\").\n * @param {boolean} options.parameters.removeAltGrid - Indicates if the alternate grid should be removed.\n * @param {boolean} options.parameters.isWideScreen - Indicates if the screen is wide.\n * @param {boolean} options.parameters.isMediumScreen - Indicates if the screen is medium-sized.\n * @param {Function} options.parameters.updateRemoveAltGrid - Function to update the removeAltGrid parameter.\n * @param {Function} options.parameters.calculateRowsAndColumns - Function to calculate rows and columns.\n *\n * @returns {[number, number, number]} An array containing the estimated number of items, rows, and columns.\n *\n * @throws Will log an error message if an error occurs during estimation.\n *\n * @example\n * const options = {\n * n: 10,\n * parameters: {\n * fixedPageLimit: 5,\n * screenPageLimit: 8,\n * shareScreenStarted: false,\n * shared: false,\n * eventType: 'conference',\n * removeAltGrid: false,\n * isWideScreen: true,\n * isMediumScreen: false,\n * updateRemoveAltGrid: (value) => console.log('Remove Alt Grid:', value),\n * calculateRowsAndColumns: ({ n }) => [3, 4], // Example implementation\n * },\n * };\n * \n * const estimate = getEstimate(options);\n * console.log('Estimated:', estimate); // Output: Estimated: [10, 3, 4]\n */\n\nexport function getEstimate({ n, parameters }: GetEstimateOptions): [number, number, number] {\n try {\n // Destructure parameters\n let {\n fixedPageLimit,\n screenPageLimit,\n shareScreenStarted,\n shared,\n eventType,\n removeAltGrid,\n isWideScreen,\n isMediumScreen,\n updateRemoveAltGrid,\n\n //mediaSfu functions\n calculateRowsAndColumns,\n } = parameters;\n\n // Calculate rows and columns\n const [rows, cols] = calculateRowsAndColumns({ n });\n\n // Check conditions for removing alt grid\n if (\n n < fixedPageLimit ||\n ((shareScreenStarted || shared) && n < screenPageLimit + 1)\n ) {\n removeAltGrid = true;\n updateRemoveAltGrid(removeAltGrid);\n\n // Return estimated values based on screen width\n if (!(isMediumScreen || isWideScreen)) {\n return eventType === \"chat\" ||\n (eventType === \"conference\" && !(shareScreenStarted || shared))\n ? [n, n, 1]\n : [n, 1, n];\n } else {\n return eventType === \"chat\" ||\n (eventType === \"conference\" && !(shareScreenStarted || shared))\n ? [n, 1, n]\n : [n, n, 1];\n }\n }\n\n return [rows * cols, rows, cols];\n } catch (error) {\n // Handle errors during estimation\n if (error instanceof Error) {\n console.log(\"Error estimating rows and columns:\", error.message);\n } else {\n console.log(\"Error estimating rows and columns:\", error);\n }\n return [0, 0, 0];\n // throw error;\n }\n}\n","import { Socket } from \"socket.io-client\";\nimport { SignalNewConsumerTransportParameters, SignalNewConsumerTransportType } from '../types/types';\nimport { markScreenAudioProducer } from './screenAudio';\n\ninterface TranslationMeta {\n speakerId: string;\n speakerName: string;\n language: string;\n originalProducerId?: string;\n isSpeakerControlled?: boolean;\n}\n\ninterface ProducerInfo {\n id: string;\n translationMeta?: TranslationMeta | null;\n /** \"screen-audio\" for audio shared with a screen share. */\n mediaTag?: string;\n}\n\nexport interface GetPipedProducersAltParameters extends Omit<SignalNewConsumerTransportParameters, 'getUpdatedAllParams'> {\n member: string;\n\n listenerTranslationPreferences?: {\n perSpeaker: Map<string, { speakerId: string; language: string | null; wantOriginal: boolean }>;\n globalLanguage: string | null;\n };\n\n // mediasfu functions\n signalNewConsumerTransport: SignalNewConsumerTransportType;\n startConsumingTranslation?: (\n producerId: string,\n speakerId: string,\n language: string,\n originalProducerId?: string,\n nsock?: Socket\n ) => Promise<void>;\n getUpdatedAllParams?: () => GetPipedProducersAltParameters;\n [key: string]: any;\n}\n\nexport interface GetPipedProducersAltOptions {\n community?: boolean;\n nsock: Socket;\n islevel: string;\n parameters: GetPipedProducersAltParameters;\n}\n\n// Export the type definition for the function\nexport type GetPipedProducersAltType = (options: GetPipedProducersAltOptions) => Promise<void>;\n\nconst shouldConsumeTranslationProducer = (\n translationMeta: TranslationMeta,\n listenerTranslationPreferences?: {\n perSpeaker: Map<string, { speakerId: string; language: string | null; wantOriginal: boolean }>;\n globalLanguage: string | null;\n }\n): boolean => {\n const normalizedLang = translationMeta.language?.toLowerCase();\n const speakerId = translationMeta.speakerId;\n const isSpeakerControlled = translationMeta.isSpeakerControlled === true;\n\n if (listenerTranslationPreferences) {\n const perSpeakerPref = listenerTranslationPreferences.perSpeaker?.get(speakerId);\n if (perSpeakerPref) {\n if (perSpeakerPref.wantOriginal) {\n return false;\n }\n if (perSpeakerPref.language) {\n return perSpeakerPref.language.toLowerCase() === normalizedLang;\n }\n }\n\n const globalPref = listenerTranslationPreferences.globalLanguage;\n if (globalPref) {\n return globalPref.toLowerCase() === normalizedLang;\n }\n }\n\n if (isSpeakerControlled) {\n return true;\n }\n\n return false;\n};\n\n/**\n * Retrieves piped producers and signals new consumer transport for each retrieved producer.\n *\n * @param {GetPipedProducersAltOptions} options - The options for retrieving piped producers.\n * @param {boolean} options.community - A flag indicating if the room is a community edition room.\n * @param {Socket} options.nsock - The WebSocket instance used for communication.\n * @param {string} options.islevel - A flag indicating the level of the request.\n * @param {GetPipedProducersAltParameters} options.parameters - Additional parameters for the request.\n * @param {string} options.parameters.member - The member identifier.\n * @param {Function} options.parameters.signalNewConsumerTransport - A function to signal new consumer transport.\n *\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n *\n * @throws {Error} If an error occurs during the process of retrieving producers.\n *\n * @example\n * const options = {\n * community: false,\n * nsock: socketInstance,\n * islevel: '1',\n * parameters: {\n * member: 'memberId',\n * signalNewConsumerTransport: async ({ nsock, remoteProducerId, islevel, parameters }) => {\n * // Implementation for signaling new consumer transport\n * },\n * },\n * };\n *\n * getPipedProducersAlt(options)\n * .then(() => {\n * console.log('Successfully retrieved piped producers');\n * })\n * .catch((error) => {\n * console.error('Error retrieving piped producers:', error);\n * });\n */\n\nexport const getPipedProducersAlt = async ({\n community = false,\n nsock,\n islevel,\n parameters,\n}: GetPipedProducersAltOptions): Promise<void> => {\n try {\n const freshParams = parameters.getUpdatedAllParams ? parameters.getUpdatedAllParams() : parameters;\n\n const {\n member,\n signalNewConsumerTransport,\n startConsumingTranslation,\n listenerTranslationPreferences,\n } = freshParams;\n\n const emitName = community ? \"getProducersAlt\" : \"getProducersPipedAlt\";\n\n // Emit request to get piped producers using WebSocket\n await nsock.emit(\n emitName,\n { islevel, member },\n async (producers: (string | ProducerInfo)[]) => {\n // Check if producers are retrieved\n if (producers.length > 0) {\n for (const producer of producers) {\n let producerId: string;\n let translationMeta: TranslationMeta | null = null;\n\n if (typeof producer === 'string') {\n producerId = producer;\n } else {\n producerId = producer.id;\n translationMeta = producer.translationMeta || null;\n markScreenAudioProducer(producerId, producer.mediaTag);\n }\n\n if (translationMeta) {\n const shouldConsume = shouldConsumeTranslationProducer(\n translationMeta,\n listenerTranslationPreferences,\n );\n\n if (!shouldConsume) {\n continue;\n }\n\n if (startConsumingTranslation) {\n await startConsumingTranslation(\n producerId,\n translationMeta.speakerId,\n translationMeta.language,\n translationMeta.originalProducerId,\n nsock,\n );\n continue;\n }\n }\n\n await signalNewConsumerTransport({\n nsock,\n remoteProducerId: producerId,\n islevel,\n parameters: freshParams as unknown as SignalNewConsumerTransportParameters,\n });\n }\n }\n }\n );\n } catch (error) {\n // Handle errors during the process of retrieving producers\n console.log(\"Error getting piped producers:\", (error as Error).message);\n }\n};\n","import { Socket } from \"socket.io-client\";\nimport { SignalNewConsumerTransportParameters, SignalNewConsumerTransportType } from \"../types/types\";\nexport interface GetProducersPipedParameters extends SignalNewConsumerTransportParameters {\n member: string;\n\n // mediasfu functions\n signalNewConsumerTransport: SignalNewConsumerTransportType,\n [key: string]: any;\n}\n\nexport interface GetProducersPipedOptions {\n nsock: Socket;\n islevel: string;\n parameters: GetProducersPipedParameters;\n}\n\n// Export the type definition for the function\nexport type GetProducersPipedType = (options: GetProducersPipedOptions) => Promise<void>;\n\n/**\n * Retrieves piped producers and signals new consumer transport for each retrieved producer.\n *\n * @param {GetProducersPipedOptions} options - The options for getting piped producers.\n * @param {Socket} options.nsock - The WebSocket instance used for communication.\n * @param {string} options.islevel - A flag indicating the level of the operation.\n * @param {GetProducersPipedParameters} options.parameters - Additional parameters for the operation.\n * @param {string} options.parameters.member - The member identifier.\n * @param {Function} options.parameters.signalNewConsumerTransport - The function to signal new consumer transport.\n *\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n *\n * @throws {Error} If an error occurs during the process of retrieving producers.\n *\n * @example\n * const options = {\n * nsock: socketInstance,\n * islevel: '1',\n * parameters: {\n * member: 'memberId',\n * signalNewConsumerTransport: async ({ remoteProducerId, islevel, nsock, parameters }) => {\n * // Implementation for signaling new consumer transport\n * },\n * },\n * };\n *\n * getProducersPiped(options)\n * .then(() => {\n * console.log('Successfully retrieved piped producers');\n * })\n * .catch((error) => {\n * console.error('Error retrieving piped producers:', error);\n * });\n */\n\nexport const getProducersPiped = async ({\n nsock,\n islevel,\n parameters,\n}: GetProducersPipedOptions): Promise<void> => {\n try {\n // Destructure parameters\n const { member, signalNewConsumerTransport } = parameters;\n\n // Emit request to get piped producers using WebSocket\n await nsock.emit(\n \"getProducersPipedAlt\",\n { islevel, member },\n async (producerIds: string[]) => {\n // Check if producers are retrieved\n if (producerIds.length > 0) {\n // Signal new consumer transport for each retrieved producer\n await Promise.all(\n producerIds.map((id) =>\n signalNewConsumerTransport({\n remoteProducerId: id,\n islevel,\n nsock,\n parameters,\n })\n )\n );\n }\n }\n );\n } catch (error) {\n // Handle errors during the process of retrieving producers\n console.log(\"Error getting piped producers:\", (error as Error).message);\n }\n};\n","import { Socket } from \"socket.io-client\";\nimport { Message } from \"../types/types\";\nexport interface ReceiveRoomMessagesOptions {\n socket: Socket;\n roomName: string;\n updateMessages: (messages: Message[]) => void;\n}\n\n// Export the type definition for the function\nexport type ReceiveRoomMessagesType = (options: ReceiveRoomMessagesOptions) => Promise<void>;\n\n/**\n * Retrieves messages from a specified room and updates the message state.\n *\n * @param {ReceiveRoomMessagesOptions} options - The options for receiving room messages.\n * @param {Socket} options.socket - The socket instance used for communication.\n * @param {string} options.roomName - The name of the room from which to retrieve messages.\n * @param {Function} options.updateMessages - Function to update the state with retrieved messages.\n *\n * @returns {Promise<void>} A promise that resolves when the messages have been retrieved and updated.\n *\n * @throws Will log an error message if there is an issue retrieving the messages.\n *\n * @example\n * ```typescript\n * await receiveRoomMessages({\n * socket: socketInstance,\n * roomName: 'Room1',\n * updateMessages: (messages) => console.log(messages),\n * });\n * ```\n */\n\n\nexport async function receiveRoomMessages({ \n socket,\n roomName,\n updateMessages,\n}: ReceiveRoomMessagesOptions): Promise<void> {\n\n try {\n // Retrieve messages from the server\n socket.emit(\"getMessage\", { roomName }, async ({ messages_ }: { messages_: Message[]; }) => {\n updateMessages(messages_);\n });\n } catch (error) {\n // Handle errors if any\n if (error instanceof Error) {\n console.log(\"Error tuning messages:\", error.message);\n } else {\n console.log(\"Error tuning messages:\", error);\n }\n }\n}\n\n","import type { Producer } from 'mediasoup-client/types';\nimport { PrepopulateUserMediaParameters, PrepopulateUserMediaType } from \"../types/types\";\n\nexport interface ResumeSendTransportAudioParameters extends PrepopulateUserMediaParameters {\n audioProducer: Producer | null;\n localAudioProducer?: Producer | null;\n islevel: string;\n hostLabel: string;\n lock_screen: boolean;\n shared: boolean;\n videoAlreadyOn: boolean;\n updateAudioProducer: (audioProducer: Producer | null) => void;\n updateLocalAudioProducer?: (localAudioProducer: Producer | null) => void;\n updateUpdateMainWindow: (updateMainWindow: boolean) => void;\n\n // mediasfu functions\n prepopulateUserMedia: PrepopulateUserMediaType;\n prepopulateLocalUserMedia?: PrepopulateUserMediaType;\n [key: string]: any;\n}\n\nexport interface ResumeSendTransportAudioOptions {\n parameters: ResumeSendTransportAudioParameters;\n}\n\n// Export the type definition for the function\nexport type ResumeSendTransportAudioType = (options: ResumeSendTransportAudioOptions) => Promise<void>;\n\nconst resumeLocalSendTransportAudio = async ({\n parameters,\n}: ResumeSendTransportAudioOptions): Promise<void> => {\n try {\n const {\n localAudioProducer,\n updateLocalAudioProducer,\n } = parameters;\n\n // Resume local audio producer\n if (localAudioProducer) {\n localAudioProducer.resume();\n updateLocalAudioProducer?.(localAudioProducer);\n }\n } catch (error) {\n console.error(\"Error resuming local audio send transport:\", error);\n throw error; // Re-throw to propagate the error\n }\n};\n\n/**\n * Resumes the send transport for audio and updates the UI and audio producer state accordingly.\n *\n * This function supports both a primary and a local audio producer, delegating the local logic to a separate function.\n *\n * @param {ResumeSendTransportAudioOptions} options - The options for resuming the send transport.\n * @param {ResumeSendTransportAudioParameters} options.parameters - The parameters for resuming the send transport.\n * @param {Producer} options.parameters.audioProducer - The primary audio producer to resume.\n * @param {Producer} [options.parameters.localAudioProducer] - The local audio producer to resume.\n * @param {string} options.parameters.islevel - The level of the audio producer.\n * @param {string} options.parameters.hostLabel - The label for the host.\n * @param {boolean} options.parameters.lock_screen - Indicates if the screen is locked.\n * @param {boolean} options.parameters.shared - Indicates if the screen is shared.\n * @param {boolean} options.parameters.videoAlreadyOn - Indicates if the video is already on.\n * @param {Function} options.parameters.updateAudioProducer - Function to update the audio producer state.\n * @param {Function} [options.parameters.updateLocalAudioProducer] - Function to update the local audio producer state.\n * @param {Function} options.parameters.updateUpdateMainWindow - Function to update the main window.\n * @param {Function} options.parameters.prepopulateUserMedia - Function to prepopulate user media.\n * @returns {Promise<void>} A promise that resolves when the send transport is resumed and the UI is updated.\n *\n * @throws {Error} Throws an error if there is an issue during the process of resuming the audio send transport.\n *\n * @example\n * ```typescript\n * await resumeSendTransportAudio({\n * parameters: {\n * audioProducer: producer,\n * localAudioProducer: localProducer,\n * islevel: '1',\n * hostLabel: 'Host',\n * lock_screen: false,\n * shared: false,\n * updateAudioProducer: updateProducerFunction,\n * updateLocalAudioProducer: updateLocalProducerFunction,\n * videoAlreadyOn: false,\n * updateUpdateMainWindow: updateWindowFunction,\n * prepopulateUserMedia: prepopulateFunction,\n * prepopulateLocalUserMedia: prepopulateLocalFunction,\n * },\n * });\n * ```\n */\n\nexport const resumeSendTransportAudio: ResumeSendTransportAudioType = async ({\n parameters,\n}: ResumeSendTransportAudioOptions): Promise<void> => {\n try {\n const {\n audioProducer,\n islevel,\n hostLabel,\n lock_screen,\n shared,\n updateAudioProducer,\n videoAlreadyOn,\n updateUpdateMainWindow,\n\n //mediasfu functions\n prepopulateUserMedia,\n } = parameters;\n\n // Resume send transport for audio\n audioProducer!.resume();\n\n // Update UI for primary producer\n if (!videoAlreadyOn && islevel === \"2\") {\n if (!lock_screen && !shared) {\n let updatedMainWindow = true;\n updateUpdateMainWindow(updatedMainWindow);\n await prepopulateUserMedia({ name: hostLabel, parameters });\n updatedMainWindow = false;\n updateUpdateMainWindow(updatedMainWindow);\n }\n }\n\n // Update audio producer state\n updateAudioProducer(audioProducer);\n\n // Attempt to handle local audio producer if primary fails\n try {\n await resumeLocalSendTransportAudio({ parameters });\n } catch (localError) {\n console.error(\n \"local audio send transport resuming failed:\",\n localError\n );\n }\n } catch (error: any) {\n // Handle errors during the process of resuming the audio send transport\n throw new Error(\n `Error during resuming audio send transport: ${error.message}`\n );\n\n }\n};\n","import { GridSizes, ComponentSizes, EventType } from \"../types/types\";\nexport interface UpdateMiniCardsGridParameters {\n updateGridRows: (rows: number) => void;\n updateGridCols: (cols: number) => void;\n updateAltGridRows: (rows: number) => void;\n updateAltGridCols: (cols: number) => void;\n updateGridSizes: (gridSizes: GridSizes) => void;\n gridSizes: GridSizes;\n paginationDirection: string;\n paginationHeightWidth: number;\n doPaginate: boolean;\n componentSizes: ComponentSizes;\n eventType: EventType;\n\n getUpdatedAllParams: () => UpdateMiniCardsGridParameters;\n [key: string]: any;\n}\n\nexport interface UpdateMiniCardsGridOptions {\n rows: number;\n cols: number;\n defal?: boolean;\n actualRows?: number;\n parameters: UpdateMiniCardsGridParameters;\n}\n\n// Export the type definition for the function\nexport type UpdateMiniCardsGridType = (options: UpdateMiniCardsGridOptions) => Promise<void>;\n\n/**\n * Updates the mini cards grid based on the specified rows and columns.\n *\n * @param {UpdateMiniCardsGridOptions} options - The function parameters.\n * @param {number} options.rows - The number of rows in the grid.\n * @param {number} options.cols - The number of columns in the grid.\n * @param {boolean} [options.defal] - Flag indicating whether to update the default grid or an alternative grid.\n * @param {number} [options.actualRows] - The actual number of rows in the grid.\n * @param {UpdateMiniCardsGridParameters} options.parameters - Additional parameters needed for the function.\n * @returns {Promise<void>} A promise that resolves when the mini cards grid is updated.\n *\n * @throws Will throw an error if the update operation fails.\n *\n * @example\n * ```typescript\n * const options = {\n * rows: 2,\n * cols: 3,\n * defal: true,\n * actualRows: 2,\n * parameters: {\n * updateGridRows: updateGridRowsFunction,\n * updateGridCols: updateGridColsFunction,\n * updateAltGridRows: updateAltGridRowsFunction,\n * updateAltGridCols: updateAltGridColsFunction,\n * updateGridSizes: updateGridSizesFunction,\n * gridSizes: { gridWidth: 100, gridHeight: 100 },\n * paginationDirection: 'horizontal',\n * paginationHeightWidth: 50,\n * doPaginate: true,\n * componentSizes: { otherWidth: 300, otherHeight: 200 },\n * eventType: 'chat',\n * getUpdatedAllParams: getUpdatedAllParamsFunction,\n * },\n * };\n * \n * await updateMiniCardsGrid(options);\n * ```\n */\n\n\nexport async function updateMiniCardsGrid({\n rows,\n cols,\n defal = true,\n actualRows = 2,\n parameters,\n}: UpdateMiniCardsGridOptions): Promise<void> {\n let { getUpdatedAllParams } = parameters;\n\n parameters = getUpdatedAllParams();\n\n let {\n updateGridRows,\n updateGridCols,\n updateAltGridRows,\n updateAltGridCols,\n updateGridSizes,\n\n gridSizes,\n paginationDirection,\n paginationHeightWidth,\n doPaginate,\n componentSizes,\n eventType,\n } = parameters;\n\n let containerWidth = componentSizes.otherWidth;\n let containerHeight = componentSizes.otherHeight;\n\n if (doPaginate) {\n // Adjust container size based on pagination\n if (paginationDirection === \"horizontal\") {\n containerHeight -= paginationHeightWidth;\n } else {\n containerWidth -= paginationHeightWidth;\n }\n }\n\n let cardSpacing = 3; // 3px margin between cards\n if (eventType === \"chat\") {\n cardSpacing = 0;\n }\n\n let totalSpacingHorizontal = (cols - 1) * cardSpacing;\n let totalSpacingVertical = (actualRows - 1) * cardSpacing;\n\n let cardWidth: number;\n let cardHeight: number;\n\n if (cols === 0 || actualRows === 0) {\n cardWidth = 0;\n cardHeight = 0;\n } else {\n cardWidth = Math.floor(\n (containerWidth - totalSpacingHorizontal) / cols\n );\n cardHeight = Math.floor(\n (containerHeight - totalSpacingVertical) / actualRows\n );\n }\n\n if (defal) {\n updateGridRows(rows);\n updateGridCols(cols);\n\n gridSizes = { ...gridSizes, gridWidth: cardWidth, gridHeight: cardHeight };\n updateGridSizes(gridSizes);\n } else {\n updateAltGridRows(rows);\n updateAltGridCols(cols);\n\n gridSizes = {\n ...gridSizes,\n altGridWidth: cardWidth,\n altGridHeight: cardHeight,\n };\n updateGridSizes(gridSizes);\n }\n}\n\n","import { AudioDecibels } from \"../types/types\";\nexport interface UpdateParticipantAudioDecibelsOptions {\n name: string;\n averageLoudness: number;\n audioDecibels: AudioDecibels[];\n updateAudioDecibels: (audioDecibels: AudioDecibels[]) => void;\n}\n\n// Export the type definition for the function\nexport type UpdateParticipantAudioDecibelsType = (options: UpdateParticipantAudioDecibelsOptions) => void;\n\n\n/**\n * Updates the audio decibels for a participant.\n *\n * @param {UpdateParticipantAudioDecibelsOptions} options - The options for updating participant audio decibels.\n * @param {string} options.name - The name of the participant.\n * @param {number} options.averageLoudness - The average loudness of the participant.\n * @param {Array<AudioDecibels>} options.audioDecibels - The array of audio decibels entries.\n * @param {Function} options.updateAudioDecibels - The function to update the audio decibels array.\n *\n * @returns {void}\n * \n * @example\n * const options = {\n * name: 'participant1',\n * averageLoudness: 50,\n * audioDecibels: [{ name: 'participant1', averageLoudness: 50 }],\n * updateAudioDecibels: updateAudioDecibelsFunction,\n * };\n * \n * updateParticipantAudioDecibels(options);\n */\n\nexport function updateParticipantAudioDecibels({\n name,\n averageLoudness,\n audioDecibels, \n updateAudioDecibels,\n}: UpdateParticipantAudioDecibelsOptions): void {\n\n // Function to update the audioDecibels array\n // Check if the entry already exists in audioDecibels\n const existingEntry = audioDecibels.find((entry) => entry.name === name);\n\n if (existingEntry) {\n // Entry exists, update the averageLoudness\n existingEntry.averageLoudness = averageLoudness;\n } else {\n // Entry doesn't exist, add a new entry to audioDecibels\n audioDecibels.push({ name, averageLoudness });\n }\n\n // Update the audioDecibels array\n updateAudioDecibels(audioDecibels);\n}\n"],"names":["mixStreams","dispStreams","temp","streame","stopShareScreen","requestScreenShare","reorderStreams","getVideos","rePort","participant","trigger","MediaSocketConnectError","currentOnlineState","normalizeRejectionReason","connectRecvTransport","closeAndResize","validateAlphanumeric","receiveAllPipedTransports","consumerBackupPreferDelay","isMediaSocketConnectError","getSpeakerNameForProducerId","isOriginalAudioSuppressedByTranslation","consumerResume","connectSendTransportAudio","connectSendTransportVideo","connectSendTransportScreen","codec","connectSendTransport","parameters","processConsumerTransports","resumePauseStreams","readjust","checkGrid","getEstimate","resumePauseAudioStreams","getProducerId","getPipedProducersAlt","changeVids","compareActiveNames","compareScreenStates","startShareScreen","processConsumerTransportsAudio","breakRoom","onScreenChanges","stream","streamSuccessScreen","disconnectSendTransportScreen","createSendTransport","resumeSendTransportAudio","audioProcessing","streamSuccessAudioSwitch","audioProcessingConstraints","streamSuccessVideo","disconnectSendTransportVideo","checkPermission","autoAdjust","calculateRowsAndColumns","signalNewConsumerTransport"],"mappings":"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"}
|