mediasfu-shared 1.0.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/LICENSE +21 -0
- package/README.md +228 -0
- package/dist/index.cjs +7707 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +7285 -0
- package/dist/index.js +7690 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
- package/src/ProducerClient/producerClientEmits/createDeviceClient.ts +68 -0
- package/src/consumers/addVideosGrid.ts +18 -0
- package/src/consumers/autoAdjust.ts +100 -0
- package/src/consumers/calculateRowsAndColumns.ts +51 -0
- package/src/consumers/changeVids.ts +753 -0
- package/src/consumers/checkGrid.ts +100 -0
- package/src/consumers/checkPermission.ts +89 -0
- package/src/consumers/checkScreenShare.ts +114 -0
- package/src/consumers/closeAndResize.ts +401 -0
- package/src/consumers/compareActiveNames.ts +122 -0
- package/src/consumers/compareScreenStates.ts +117 -0
- package/src/consumers/connectIps.ts +175 -0
- package/src/consumers/connectLocalIps.ts +103 -0
- package/src/consumers/connectRecvTransport.ts +158 -0
- package/src/consumers/connectSendTransport.ts +150 -0
- package/src/consumers/connectSendTransportAudio.ts +161 -0
- package/src/consumers/connectSendTransportScreen.ts +169 -0
- package/src/consumers/connectSendTransportVideo.ts +149 -0
- package/src/consumers/consumerResume.ts +25 -0
- package/src/consumers/controlMedia.ts +118 -0
- package/src/consumers/createSendTransport.ts +312 -0
- package/src/consumers/disconnectSendTransportAudio.ts +170 -0
- package/src/consumers/disconnectSendTransportScreen.ts +130 -0
- package/src/consumers/disconnectSendTransportVideo.ts +161 -0
- package/src/consumers/dispStreams.ts +694 -0
- package/src/consumers/generatePageContent.ts +118 -0
- package/src/consumers/getEstimate.ts +124 -0
- package/src/consumers/getPipedProducersAlt.ts +96 -0
- package/src/consumers/getProducersPiped.ts +89 -0
- package/src/consumers/getVideos.ts +107 -0
- package/src/consumers/mixStreams.ts +97 -0
- package/src/consumers/onScreenChanges.ts +106 -0
- package/src/consumers/prepopulateUserMedia.ts +18 -0
- package/src/consumers/processConsumerTransports.ts +157 -0
- package/src/consumers/processConsumerTransportsAudio.ts +121 -0
- package/src/consumers/rePort.ts +123 -0
- package/src/consumers/reUpdateInter.ts +289 -0
- package/src/consumers/readjust.ts +170 -0
- package/src/consumers/receiveAllPipedTransports.ts +77 -0
- package/src/consumers/receiveRoomMessages.ts +55 -0
- package/src/consumers/reorderStreams.ts +246 -0
- package/src/consumers/requestScreenShare.ts +103 -0
- package/src/consumers/resumePauseAudioStreams.ts +174 -0
- package/src/consumers/resumePauseStreams.ts +110 -0
- package/src/consumers/resumeSendTransportAudio.ts +143 -0
- package/src/consumers/signalNewConsumerTransport.ts +179 -0
- package/src/consumers/socketReceiveMethods/joinConsumeRoom.ts +130 -0
- package/src/consumers/socketReceiveMethods/newPipeProducer.ts +138 -0
- package/src/consumers/socketReceiveMethods/producerClosed.ts +102 -0
- package/src/consumers/startShareScreen.ts +124 -0
- package/src/consumers/stopShareScreen.ts +241 -0
- package/src/consumers/streamSuccessAudio.ts +297 -0
- package/src/consumers/streamSuccessAudioSwitch.ts +315 -0
- package/src/consumers/streamSuccessScreen.ts +255 -0
- package/src/consumers/streamSuccessVideo.ts +373 -0
- package/src/consumers/switchUserAudio.ts +140 -0
- package/src/consumers/switchUserVideo.ts +201 -0
- package/src/consumers/switchUserVideoAlt.ts +331 -0
- package/src/consumers/trigger.ts +250 -0
- package/src/consumers/updateMiniCardsGrid.ts +150 -0
- package/src/consumers/updateParticipantAudioDecibels.ts +56 -0
- package/src/index.ts +119 -0
- package/src/methods/background/launchBackground.ts +16 -0
- package/src/methods/breakoutRooms/breakoutRoomUpdated.ts +161 -0
- package/src/methods/breakoutRooms/handleStartBreakout.ts +96 -0
- package/src/methods/breakoutRooms/handleStopBreakout.ts +72 -0
- package/src/methods/breakoutRooms/index.ts +4 -0
- package/src/methods/breakoutRooms/launchBreakoutRooms.ts +31 -0
- package/src/methods/coHost/launchCoHost.ts +28 -0
- package/src/methods/coHostMethods/index.ts +2 -0
- package/src/methods/coHostMethods/modifyCoHostSettings.ts +94 -0
- package/src/methods/displaySettings/index.ts +1 -0
- package/src/methods/displaySettings/launchDisplaySettings.ts +31 -0
- package/src/methods/displaySettings/modifyDisplaySettings.ts +242 -0
- package/src/methods/exit/confirmExit.ts +60 -0
- package/src/methods/exit/index.ts +2 -0
- package/src/methods/exit/launchConfirmExit.ts +29 -0
- package/src/methods/index.ts +5 -0
- package/src/methods/mediaSettings/launchMediaSettings.ts +61 -0
- package/src/methods/menu/launchMenuModal.ts +28 -0
- package/src/methods/message/index.ts +1 -0
- package/src/methods/message/launchMessages.ts +27 -0
- package/src/methods/message/sendMessage.ts +175 -0
- package/src/methods/participants/index.ts +3 -0
- package/src/methods/participants/launchParticipants.ts +25 -0
- package/src/methods/participants/messageParticipants.ts +78 -0
- package/src/methods/participants/muteParticipants.ts +79 -0
- package/src/methods/participants/removeParticipants.ts +97 -0
- package/src/methods/polls/handleCreatePoll.ts +66 -0
- package/src/methods/polls/handleEndPoll.ts +64 -0
- package/src/methods/polls/handleVotePoll.ts +76 -0
- package/src/methods/polls/index.ts +3 -0
- package/src/methods/polls/launchPoll.ts +25 -0
- package/src/methods/prejoin/handleCreateRoom.ts +441 -0
- package/src/methods/prejoin/handleJoinRoom.ts +153 -0
- package/src/methods/prejoin/index.ts +14 -0
- package/src/methods/recording/checkPauseState.ts +57 -0
- package/src/methods/recording/checkResumeState.ts +42 -0
- package/src/methods/recording/confirmRecording.ts +241 -0
- package/src/methods/recording/launchRecording.ts +114 -0
- package/src/methods/recording/recordPauseTimer.ts +52 -0
- package/src/methods/recording/recordResumeTimer.ts +92 -0
- package/src/methods/recording/recordStartTimer.ts +106 -0
- package/src/methods/recording/recordUpdateTimer.ts +49 -0
- package/src/methods/recording/startRecording.ts +268 -0
- package/src/methods/recording/stopRecording.ts +124 -0
- package/src/methods/recording/updateRecording.ts +245 -0
- package/src/methods/requests/index.ts +1 -0
- package/src/methods/requests/launchRequests.ts +25 -0
- package/src/methods/requests/respondToRequests.ts +108 -0
- package/src/methods/settings/index.ts +2 -0
- package/src/methods/settings/launchSettings.ts +25 -0
- package/src/methods/settings/modifySettings.ts +99 -0
- package/src/methods/stream/clickVideo.ts +337 -0
- package/src/methods/stream/index.ts +3 -0
- package/src/methods/stream/switchAudio.ts +73 -0
- package/src/methods/stream/switchVideo.ts +148 -0
- package/src/methods/stream/switchVideoAlt.ts +152 -0
- package/src/methods/utils/checkLimitsAndMakeRequest.ts +103 -0
- package/src/methods/utils/validateAlphanumeric.ts +41 -0
- package/src/methods/waiting/index.ts +1 -0
- package/src/methods/waiting/launchWaiting.ts +26 -0
- package/src/methods/waiting/respondToWaiting.ts +82 -0
- package/src/methods/welcome/handleWelcomeRequest.ts +189 -0
- package/src/methods/welcome/index.ts +5 -0
- package/src/methods/whiteboard/handleStartWhiteboard.ts +65 -0
- package/src/methods/whiteboard/handleStopWhiteboard.ts +48 -0
- package/src/methods/whiteboard/index.ts +4 -0
- package/src/methods/whiteboard/launchConfigureWhiteboard.ts +29 -0
- package/src/producers/producerEmits/joinConRoom.ts +153 -0
- package/src/sockets/SocketManager.ts +232 -0
- package/src/types/shared-base-types.ts +752 -0
- package/src/types/types.ts +84 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Socket } from "socket.io-client";
|
|
2
|
+
import type { Request, RequestResponse } from "../../types/types";
|
|
3
|
+
|
|
4
|
+
export interface RespondToRequestsOptions {
|
|
5
|
+
socket: Socket;
|
|
6
|
+
request: Request;
|
|
7
|
+
updateRequestList: (newRequestList: Request[]) => void;
|
|
8
|
+
requestList?: Request[];
|
|
9
|
+
action: string;
|
|
10
|
+
roomName: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Export the type definition for the function
|
|
14
|
+
export type RespondToRequestsType = (options: RespondToRequestsOptions) => Promise<void>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Responds to incoming requests by updating the request list and emitting a response to the server.
|
|
18
|
+
*
|
|
19
|
+
* @param {Object} options - The options for responding to requests.
|
|
20
|
+
* @param {Socket} options.socket - The socket instance used to emit the response.
|
|
21
|
+
* @param {Request} options.request - The request object containing details of the request.
|
|
22
|
+
* @param {Function} options.updateRequestList - The function to update the request list.
|
|
23
|
+
* @param {Request[]} options.requestList - The current list of requests.
|
|
24
|
+
* @param {string} options.action - The action to be taken on the request.
|
|
25
|
+
* @param {string} options.roomName - The name of the room to which the response should be emitted.
|
|
26
|
+
*
|
|
27
|
+
* @returns {Promise<void>} A promise that resolves when the response has been emitted.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* respondToRequests({
|
|
32
|
+
* socket,
|
|
33
|
+
* request: { id: "123", name: "John", icon: "fa-microphone" },
|
|
34
|
+
* updateRequestList: setRequestList,
|
|
35
|
+
* requestList: currentRequests,
|
|
36
|
+
* action: "accept",
|
|
37
|
+
* roomName: "mainRoom"
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
export const respondToRequests = async ({
|
|
43
|
+
socket,
|
|
44
|
+
request,
|
|
45
|
+
updateRequestList,
|
|
46
|
+
requestList = [],
|
|
47
|
+
action,
|
|
48
|
+
roomName,
|
|
49
|
+
}: RespondToRequestsOptions): Promise<void> => {
|
|
50
|
+
if (!request || typeof request !== "object") {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!updateRequestList) {
|
|
55
|
+
console.warn("[respondToRequests] Missing updateRequestList handler; aborting emit.");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const currentList = Array.isArray(requestList) ? requestList : [];
|
|
60
|
+
|
|
61
|
+
const requestIdRaw = (request as { id?: string | number }).id;
|
|
62
|
+
const requestIcon = (request as { icon?: string }).icon;
|
|
63
|
+
const requestName = (request as { name?: string }).name;
|
|
64
|
+
|
|
65
|
+
if (requestIdRaw === undefined || requestIcon === undefined || requestName === undefined) {
|
|
66
|
+
console.warn("[respondToRequests] Request payload is missing required fields; aborting emit.", request);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const requestId = String(requestIdRaw);
|
|
71
|
+
|
|
72
|
+
if (!requestId || !requestIcon || !requestName) {
|
|
73
|
+
console.warn("[respondToRequests] Request payload contains empty fields; aborting emit.", request);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Filter out the request from the request list
|
|
78
|
+
const newRequestList = currentList.filter(
|
|
79
|
+
(request_) =>
|
|
80
|
+
!(
|
|
81
|
+
request_ &&
|
|
82
|
+
request_.id === requestId &&
|
|
83
|
+
request_.icon === requestIcon &&
|
|
84
|
+
request_.name === requestName
|
|
85
|
+
)
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
// Update the request list with the filtered list
|
|
89
|
+
updateRequestList(newRequestList);
|
|
90
|
+
|
|
91
|
+
// Prepare the request response
|
|
92
|
+
const requestResponse: RequestResponse = {
|
|
93
|
+
id: requestId,
|
|
94
|
+
name: requestName,
|
|
95
|
+
type: requestIcon,
|
|
96
|
+
action,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// Emit the request response to the server
|
|
100
|
+
const socketReady = socket && typeof (socket as Socket).emit === "function";
|
|
101
|
+
|
|
102
|
+
if (!socketReady) {
|
|
103
|
+
console.warn("[respondToRequests] Socket is not ready; skipping emit.");
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
(socket as Socket).emit("updateUserofRequestStatus", { requestResponse, roomName });
|
|
108
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface LaunchSettingsOptions {
|
|
2
|
+
updateIsSettingsModalVisible: (isVisible: boolean) => void
|
|
3
|
+
isSettingsModalVisible: boolean
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export type LaunchSettingsType = (options: LaunchSettingsOptions) => void
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Toggles the visibility state of the settings modal.
|
|
10
|
+
*
|
|
11
|
+
* @param {LaunchSettingsOptions} options - The options for launching settings.
|
|
12
|
+
* @param {Function} options.updateIsSettingsModalVisible - Function to update the visibility state of the settings modal.
|
|
13
|
+
* @param {boolean} options.isSettingsModalVisible - Current visibility state of the settings modal.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* launchSettings({
|
|
18
|
+
* isSettingsModalVisible: false,
|
|
19
|
+
* updateIsSettingsModalVisible: (visible) => setSettingsModalVisible(visible),
|
|
20
|
+
* })
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export const launchSettings: LaunchSettingsType = ({ updateIsSettingsModalVisible, isSettingsModalVisible }) => {
|
|
24
|
+
updateIsSettingsModalVisible(!isSettingsModalVisible)
|
|
25
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Socket } from 'socket.io-client';
|
|
2
|
+
import type { ShowAlert } from '../../types/types';
|
|
3
|
+
|
|
4
|
+
export interface ModifySettingsOptions {
|
|
5
|
+
showAlert?: ShowAlert;
|
|
6
|
+
roomName: string;
|
|
7
|
+
audioSet: string;
|
|
8
|
+
videoSet: string;
|
|
9
|
+
screenshareSet: string;
|
|
10
|
+
chatSet: string;
|
|
11
|
+
socket: Socket;
|
|
12
|
+
updateAudioSetting: (audioSet: string) => void;
|
|
13
|
+
updateVideoSetting: (videoSet: string) => void;
|
|
14
|
+
updateScreenshareSetting: (screenshareSet: string) => void;
|
|
15
|
+
updateChatSetting: (chatSet: string) => void;
|
|
16
|
+
updateIsSettingsModalVisible: (isVisible: boolean) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Export the type definition for the function
|
|
20
|
+
export type ModifySettingsType = (options: ModifySettingsOptions) => Promise<void>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Modifies the settings for a given room and updates the state accordingly.
|
|
24
|
+
*
|
|
25
|
+
* @param {ModifySettingsOptions} options - The options for modifying settings.
|
|
26
|
+
* @returns {Promise<void>} A promise that resolves when the settings have been modified.
|
|
27
|
+
*
|
|
28
|
+
* @throws Will show an alert if any setting is set to "approval" in demo mode (room name starts with "d").
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* modifySettings({
|
|
33
|
+
* roomName: "d123",
|
|
34
|
+
* audioSet: "allow",
|
|
35
|
+
* videoSet: "allow",
|
|
36
|
+
* screenshareSet: "deny",
|
|
37
|
+
* chatSet: "allow",
|
|
38
|
+
* socket: mySocketInstance,
|
|
39
|
+
* updateAudioSetting: setAudioSetting,
|
|
40
|
+
* updateVideoSetting: setVideoSetting,
|
|
41
|
+
* updateScreenshareSetting: setScreenshareSetting,
|
|
42
|
+
* updateChatSetting: setChatSetting,
|
|
43
|
+
* updateIsSettingsModalVisible: setIsSettingsModalVisible,
|
|
44
|
+
* showAlert: (options) => alertUser(options),
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export async function modifySettings({
|
|
49
|
+
showAlert,
|
|
50
|
+
roomName,
|
|
51
|
+
audioSet,
|
|
52
|
+
videoSet,
|
|
53
|
+
screenshareSet,
|
|
54
|
+
chatSet,
|
|
55
|
+
socket,
|
|
56
|
+
updateAudioSetting,
|
|
57
|
+
updateVideoSetting,
|
|
58
|
+
updateScreenshareSetting,
|
|
59
|
+
updateChatSetting,
|
|
60
|
+
updateIsSettingsModalVisible,
|
|
61
|
+
}: ModifySettingsOptions): Promise<void> {
|
|
62
|
+
if (roomName.toLowerCase().startsWith('d')) {
|
|
63
|
+
// none should be approval
|
|
64
|
+
if (
|
|
65
|
+
audioSet === 'approval' ||
|
|
66
|
+
videoSet === 'approval' ||
|
|
67
|
+
screenshareSet === 'approval' ||
|
|
68
|
+
chatSet === 'approval'
|
|
69
|
+
) {
|
|
70
|
+
showAlert?.({
|
|
71
|
+
message: 'You cannot set approval for demo mode.',
|
|
72
|
+
type: 'danger',
|
|
73
|
+
duration: 3000,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Check and update state variables based on the provided logic
|
|
81
|
+
if (audioSet) {
|
|
82
|
+
updateAudioSetting(audioSet);
|
|
83
|
+
}
|
|
84
|
+
if (videoSet) {
|
|
85
|
+
updateVideoSetting(videoSet);
|
|
86
|
+
}
|
|
87
|
+
if (screenshareSet) {
|
|
88
|
+
updateScreenshareSetting(screenshareSet);
|
|
89
|
+
}
|
|
90
|
+
if (chatSet) {
|
|
91
|
+
updateChatSetting(chatSet);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const settings = [audioSet, videoSet, screenshareSet, chatSet];
|
|
95
|
+
socket.emit('updateSettingsForRequests', { settings, roomName });
|
|
96
|
+
|
|
97
|
+
// Close modal
|
|
98
|
+
updateIsSettingsModalVisible(false);
|
|
99
|
+
}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { Socket } from "socket.io-client";
|
|
2
|
+
import { CheckPermissionType, DisconnectSendTransportVideoParameters, DisconnectSendTransportVideoType, RequestPermissionCameraType, ShowAlert, StreamSuccessVideoParameters, StreamSuccessVideoType, VidCons } from "../../types/types";
|
|
3
|
+
|
|
4
|
+
export interface ClickVideoParameters extends DisconnectSendTransportVideoParameters, StreamSuccessVideoParameters {
|
|
5
|
+
checkMediaPermission: boolean;
|
|
6
|
+
hasCameraPermission: boolean;
|
|
7
|
+
videoAlreadyOn: boolean;
|
|
8
|
+
audioOnlyRoom: boolean;
|
|
9
|
+
recordStarted: boolean;
|
|
10
|
+
recordResumed: boolean;
|
|
11
|
+
recordPaused: boolean;
|
|
12
|
+
recordStopped: boolean;
|
|
13
|
+
recordingMediaOptions: string;
|
|
14
|
+
islevel: string;
|
|
15
|
+
youAreCoHost: boolean;
|
|
16
|
+
adminRestrictSetting: boolean;
|
|
17
|
+
videoRequestState: string | null;
|
|
18
|
+
videoRequestTime: number;
|
|
19
|
+
member: string;
|
|
20
|
+
socket: Socket;
|
|
21
|
+
roomName: string;
|
|
22
|
+
userDefaultVideoInputDevice: string;
|
|
23
|
+
currentFacingMode: string;
|
|
24
|
+
vidCons: VidCons;
|
|
25
|
+
frameRate: number;
|
|
26
|
+
videoAction: boolean;
|
|
27
|
+
localStream: MediaStream | null;
|
|
28
|
+
audioSetting: string;
|
|
29
|
+
videoSetting: string;
|
|
30
|
+
screenshareSetting: string;
|
|
31
|
+
chatSetting: string;
|
|
32
|
+
updateRequestIntervalSeconds: number;
|
|
33
|
+
|
|
34
|
+
showAlert?: ShowAlert;
|
|
35
|
+
updateVideoAlreadyOn: (value: boolean) => void;
|
|
36
|
+
updateVideoRequestState: (state: string) => void;
|
|
37
|
+
updateLocalStream: (stream: MediaStream | null) => void;
|
|
38
|
+
mediaDevices: MediaDevices;
|
|
39
|
+
|
|
40
|
+
streamSuccessVideo: StreamSuccessVideoType;
|
|
41
|
+
disconnectSendTransportVideo: DisconnectSendTransportVideoType;
|
|
42
|
+
requestPermissionCamera: RequestPermissionCameraType;
|
|
43
|
+
checkPermission: CheckPermissionType;
|
|
44
|
+
|
|
45
|
+
getUpdatedAllParams: () => ClickVideoParameters;
|
|
46
|
+
[key: string]: any;
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ClickVideoOptions {
|
|
51
|
+
parameters: ClickVideoParameters;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Export the type definition for the function
|
|
55
|
+
export type ClickVideoType = (options: ClickVideoOptions) => Promise<void>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Handles the click event to toggle the participant's video on/off and manages video permission requests.
|
|
59
|
+
*
|
|
60
|
+
* @param {ClickVideoOptions} options - The function parameters.
|
|
61
|
+
* @returns {Promise<void>}
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* clickVideo({
|
|
66
|
+
* parameters: {
|
|
67
|
+
* checkMediaPermission: true,
|
|
68
|
+
* hasCameraPermission: false,
|
|
69
|
+
* videoAlreadyOn: false,
|
|
70
|
+
* audioOnlyRoom: false,
|
|
71
|
+
* recordStarted: true,
|
|
72
|
+
* recordResumed: false,
|
|
73
|
+
* recordPaused: true,
|
|
74
|
+
* recordStopped: false,
|
|
75
|
+
* recordingMediaOptions: "video",
|
|
76
|
+
* islevel: "1",
|
|
77
|
+
* youAreCoHost: false,
|
|
78
|
+
* adminRestrictSetting: false,
|
|
79
|
+
* videoRequestState: null,
|
|
80
|
+
* videoRequestTime: Date.now(),
|
|
81
|
+
* member: "John Doe",
|
|
82
|
+
* socket: socketInstance,
|
|
83
|
+
* roomName: "room123",
|
|
84
|
+
* userDefaultVideoInputDevice: "default",
|
|
85
|
+
* currentFacingMode: "user",
|
|
86
|
+
* vidCons: { width: 1280, height: 720 },
|
|
87
|
+
* frameRate: 30,
|
|
88
|
+
* videoAction: false,
|
|
89
|
+
* localStream: null,
|
|
90
|
+
* audioSetting: "allow",
|
|
91
|
+
* videoSetting: "allow",
|
|
92
|
+
* screenshareSetting: "allow",
|
|
93
|
+
* chatSetting: "allow",
|
|
94
|
+
* updateRequestIntervalSeconds: 60,
|
|
95
|
+
* showAlert: showAlertFunction,
|
|
96
|
+
* updateVideoAlreadyOn: setVideoAlreadyOn,
|
|
97
|
+
* updateVideoRequestState: setVideoRequestState,
|
|
98
|
+
* updateLocalStream: setLocalStream,
|
|
99
|
+
* mediaDevices: navigator.mediaDevices,
|
|
100
|
+
* streamSuccessVideo: streamSuccessVideoFunction,
|
|
101
|
+
* disconnectSendTransportVideo: disconnectVideoTransportFunction,
|
|
102
|
+
* requestPermissionCamera: requestCameraPermissionFunction,
|
|
103
|
+
* checkPermission: checkPermissionFunction,
|
|
104
|
+
* getUpdatedAllParams: getUpdatedParamsFunction
|
|
105
|
+
* }
|
|
106
|
+
* });
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
export const clickVideo = async ({ parameters }: ClickVideoOptions): Promise<void> => {
|
|
111
|
+
let {
|
|
112
|
+
checkMediaPermission,
|
|
113
|
+
hasCameraPermission,
|
|
114
|
+
videoAlreadyOn,
|
|
115
|
+
audioOnlyRoom,
|
|
116
|
+
recordStarted,
|
|
117
|
+
recordResumed,
|
|
118
|
+
recordPaused,
|
|
119
|
+
recordStopped,
|
|
120
|
+
recordingMediaOptions,
|
|
121
|
+
islevel,
|
|
122
|
+
youAreCoHost,
|
|
123
|
+
adminRestrictSetting,
|
|
124
|
+
videoRequestState,
|
|
125
|
+
videoRequestTime,
|
|
126
|
+
member,
|
|
127
|
+
socket,
|
|
128
|
+
roomName,
|
|
129
|
+
userDefaultVideoInputDevice,
|
|
130
|
+
currentFacingMode,
|
|
131
|
+
vidCons,
|
|
132
|
+
frameRate,
|
|
133
|
+
videoAction,
|
|
134
|
+
localStream,
|
|
135
|
+
audioSetting,
|
|
136
|
+
videoSetting,
|
|
137
|
+
screenshareSetting,
|
|
138
|
+
chatSetting,
|
|
139
|
+
updateRequestIntervalSeconds,
|
|
140
|
+
streamSuccessVideo,
|
|
141
|
+
showAlert,
|
|
142
|
+
updateVideoAlreadyOn,
|
|
143
|
+
updateVideoRequestState,
|
|
144
|
+
updateLocalStream,
|
|
145
|
+
mediaDevices,
|
|
146
|
+
disconnectSendTransportVideo,
|
|
147
|
+
requestPermissionCamera,
|
|
148
|
+
checkPermission,
|
|
149
|
+
} = parameters;
|
|
150
|
+
|
|
151
|
+
if (audioOnlyRoom) {
|
|
152
|
+
showAlert?.({
|
|
153
|
+
message: "You cannot turn on your camera in an audio-only event.",
|
|
154
|
+
type: "danger",
|
|
155
|
+
duration: 3000,
|
|
156
|
+
});
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (videoAlreadyOn) {
|
|
161
|
+
if (islevel === "2" && (recordStarted || recordResumed)) {
|
|
162
|
+
if (!(recordPaused || recordStopped)) {
|
|
163
|
+
if (recordingMediaOptions === "video") {
|
|
164
|
+
showAlert?.({
|
|
165
|
+
message: "You cannot turn off your camera while recording video, please pause or stop recording first.",
|
|
166
|
+
type: "danger",
|
|
167
|
+
duration: 3000,
|
|
168
|
+
});
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
videoAlreadyOn = false;
|
|
175
|
+
updateVideoAlreadyOn(videoAlreadyOn);
|
|
176
|
+
localStream!.getVideoTracks()[0].enabled = false;
|
|
177
|
+
updateLocalStream(localStream);
|
|
178
|
+
await disconnectSendTransportVideo({ parameters });
|
|
179
|
+
} else {
|
|
180
|
+
if (adminRestrictSetting) {
|
|
181
|
+
showAlert?.({
|
|
182
|
+
message: "You cannot turn on your camera. Access denied by host.",
|
|
183
|
+
duration: 3000,
|
|
184
|
+
type: "danger",
|
|
185
|
+
});
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
let response = 2;
|
|
190
|
+
|
|
191
|
+
if (!videoAction && islevel !== "2" && !youAreCoHost) {
|
|
192
|
+
response = await checkPermission({
|
|
193
|
+
permissionType: "videoSetting",
|
|
194
|
+
audioSetting, videoSetting, screenshareSetting, chatSetting,
|
|
195
|
+
});
|
|
196
|
+
} else {
|
|
197
|
+
response = 0;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (response == 1) {
|
|
201
|
+
//approval
|
|
202
|
+
//check if request is pending or not
|
|
203
|
+
if (videoRequestState === "pending") {
|
|
204
|
+
showAlert?.({
|
|
205
|
+
message: "A request is pending. Please wait for the host to respond.",
|
|
206
|
+
type: "danger",
|
|
207
|
+
duration: 3000,
|
|
208
|
+
});
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
// check if rejected and current time is less than videoRequestTime
|
|
212
|
+
if (videoRequestState === "rejected" && Date.now() - videoRequestTime < updateRequestIntervalSeconds) {
|
|
213
|
+
showAlert?.({
|
|
214
|
+
message: `A request was rejected. Please wait for ${updateRequestIntervalSeconds} seconds before sending another request.`,
|
|
215
|
+
type: "danger",
|
|
216
|
+
duration: 3000,
|
|
217
|
+
});
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// send request to host
|
|
222
|
+
showAlert?.({
|
|
223
|
+
message: "Request sent to host.",
|
|
224
|
+
type: "success",
|
|
225
|
+
duration: 3000,
|
|
226
|
+
});
|
|
227
|
+
videoRequestState = "pending";
|
|
228
|
+
updateVideoRequestState(videoRequestState);
|
|
229
|
+
|
|
230
|
+
const userRequest = { id: socket.id, name: member, icon: "fa-video" };
|
|
231
|
+
await socket.emit("participantRequest", { userRequest, roomName });
|
|
232
|
+
} else if (response === 2) {
|
|
233
|
+
//if video permission is set to deny then show alert
|
|
234
|
+
showAlert?.({
|
|
235
|
+
message: "You cannot turn on your camera. Access denied by host.",
|
|
236
|
+
type: "danger",
|
|
237
|
+
duration: 3000,
|
|
238
|
+
});
|
|
239
|
+
} else {
|
|
240
|
+
//if video permission is set to allow then turn on video
|
|
241
|
+
|
|
242
|
+
//first check if permission is granted
|
|
243
|
+
if (!hasCameraPermission) {
|
|
244
|
+
if (checkMediaPermission) {
|
|
245
|
+
const statusCamera = await requestPermissionCamera();
|
|
246
|
+
if (statusCamera !== "granted") {
|
|
247
|
+
showAlert?.({
|
|
248
|
+
message: "Allow access to your camera or check if your camera is not being used by another application.",
|
|
249
|
+
type: "danger",
|
|
250
|
+
duration: 3000,
|
|
251
|
+
});
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
let mediaConstraints = {};
|
|
258
|
+
let altMediaConstraints = {};
|
|
259
|
+
if (userDefaultVideoInputDevice) {
|
|
260
|
+
if (vidCons && vidCons.width && vidCons.height) {
|
|
261
|
+
mediaConstraints = {
|
|
262
|
+
video: {
|
|
263
|
+
deviceId: userDefaultVideoInputDevice,
|
|
264
|
+
facingMode: currentFacingMode,
|
|
265
|
+
...vidCons,
|
|
266
|
+
frameRate: { ideal: frameRate },
|
|
267
|
+
},
|
|
268
|
+
audio: false,
|
|
269
|
+
};
|
|
270
|
+
altMediaConstraints = {
|
|
271
|
+
video: { ...vidCons, frameRate: { ideal: frameRate } },
|
|
272
|
+
audio: false,
|
|
273
|
+
};
|
|
274
|
+
} else {
|
|
275
|
+
mediaConstraints = {
|
|
276
|
+
video: { ...vidCons, frameRate: { ideal: frameRate } },
|
|
277
|
+
audio: false,
|
|
278
|
+
};
|
|
279
|
+
altMediaConstraints = {
|
|
280
|
+
video: { frameRate: { ideal: frameRate } },
|
|
281
|
+
audio: false,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
} else {
|
|
285
|
+
if (vidCons && vidCons.width && vidCons.height) {
|
|
286
|
+
mediaConstraints = {
|
|
287
|
+
video: { ...vidCons, frameRate: { ideal: frameRate } },
|
|
288
|
+
audio: false,
|
|
289
|
+
};
|
|
290
|
+
altMediaConstraints = {
|
|
291
|
+
video: { ...vidCons, frameRate: { ideal: frameRate } },
|
|
292
|
+
audio: false,
|
|
293
|
+
};
|
|
294
|
+
} else {
|
|
295
|
+
mediaConstraints = {
|
|
296
|
+
video: { frameRate: { ideal: frameRate } },
|
|
297
|
+
audio: false,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
await mediaDevices
|
|
303
|
+
.getUserMedia(mediaConstraints)
|
|
304
|
+
.then(async (stream) => {
|
|
305
|
+
await streamSuccessVideo({ stream, parameters });
|
|
306
|
+
})
|
|
307
|
+
.catch(async () => {
|
|
308
|
+
await mediaDevices
|
|
309
|
+
.getUserMedia(altMediaConstraints)
|
|
310
|
+
.then(async (stream) => {
|
|
311
|
+
await streamSuccessVideo({ stream, parameters });
|
|
312
|
+
})
|
|
313
|
+
.catch(async() => {
|
|
314
|
+
//remove frameRate from constraints
|
|
315
|
+
altMediaConstraints = {
|
|
316
|
+
video: { ...vidCons },
|
|
317
|
+
audio: false,
|
|
318
|
+
};
|
|
319
|
+
await mediaDevices
|
|
320
|
+
.getUserMedia(altMediaConstraints)
|
|
321
|
+
.then(async (stream) => {
|
|
322
|
+
await streamSuccessVideo({ stream, parameters });
|
|
323
|
+
}).catch(() => {
|
|
324
|
+
|
|
325
|
+
showAlert?.({
|
|
326
|
+
message:
|
|
327
|
+
"Allow access to your camera or check if your camera is not being used by another application.",
|
|
328
|
+
type: "danger",
|
|
329
|
+
duration: 3000,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { SwitchUserAudioType, SwitchUserAudioParameters } from '../../types/types';
|
|
2
|
+
|
|
3
|
+
export interface SwitchAudioParameters extends SwitchUserAudioParameters {
|
|
4
|
+
defAudioID: string
|
|
5
|
+
userDefaultAudioInputDevice: string
|
|
6
|
+
prevAudioInputDevice: string
|
|
7
|
+
updateUserDefaultAudioInputDevice: (deviceId: string) => void
|
|
8
|
+
updatePrevAudioInputDevice: (deviceId: string) => void
|
|
9
|
+
|
|
10
|
+
// mediasfu functions
|
|
11
|
+
switchUserAudio: SwitchUserAudioType
|
|
12
|
+
|
|
13
|
+
getUpdatedAllParams: () => SwitchAudioParameters
|
|
14
|
+
[key: string]: any
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface SwitchAudioOptions {
|
|
18
|
+
audioPreference: string
|
|
19
|
+
parameters: SwitchAudioParameters
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Export the type definition for the function
|
|
23
|
+
export type SwitchAudioType = (options: SwitchAudioOptions) => Promise<void>
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Switches the audio input device based on user preference.
|
|
27
|
+
*
|
|
28
|
+
* @param {SwitchAudioOptions} options - The function parameters.
|
|
29
|
+
* @returns {Promise<void>}
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* switchAudio({
|
|
34
|
+
* audioPreference: "newAudioDeviceID",
|
|
35
|
+
* parameters: {
|
|
36
|
+
* defAudioID: "defaultAudioDeviceID",
|
|
37
|
+
* userDefaultAudioInputDevice: "currentAudioDeviceID",
|
|
38
|
+
* prevAudioInputDevice: "previousAudioDeviceID",
|
|
39
|
+
* updateUserDefaultAudioInputDevice: (deviceId) => setUserDefaultAudio(deviceId),
|
|
40
|
+
* updatePrevAudioInputDevice: (deviceId) => setPrevAudioDevice(deviceId),
|
|
41
|
+
* switchUserAudio: switchUserAudioFunction,
|
|
42
|
+
* getUpdatedAllParams: getUpdatedParamsFunction
|
|
43
|
+
* }
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
export const switchAudio = async ({
|
|
49
|
+
audioPreference,
|
|
50
|
+
parameters
|
|
51
|
+
}: SwitchAudioOptions): Promise<void> => {
|
|
52
|
+
let {
|
|
53
|
+
defAudioID,
|
|
54
|
+
userDefaultAudioInputDevice,
|
|
55
|
+
prevAudioInputDevice,
|
|
56
|
+
updateUserDefaultAudioInputDevice,
|
|
57
|
+
updatePrevAudioInputDevice,
|
|
58
|
+
|
|
59
|
+
//mediasfu functions
|
|
60
|
+
switchUserAudio
|
|
61
|
+
} = parameters
|
|
62
|
+
|
|
63
|
+
if (audioPreference !== defAudioID) {
|
|
64
|
+
prevAudioInputDevice = userDefaultAudioInputDevice
|
|
65
|
+
updatePrevAudioInputDevice(prevAudioInputDevice)
|
|
66
|
+
userDefaultAudioInputDevice = audioPreference
|
|
67
|
+
updateUserDefaultAudioInputDevice(userDefaultAudioInputDevice)
|
|
68
|
+
|
|
69
|
+
if (defAudioID) {
|
|
70
|
+
await switchUserAudio({ audioPreference, parameters })
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|