[mirotalksfu] - add more moderator options, update dep

هذا الالتزام موجود في:
Miroslav Pejic
2023-11-18 22:12:15 +01:00
الأصل 90353bc17f
التزام 3ce1c61010
9 ملفات معدلة مع 237 إضافات و40 حذوفات

عرض الملف

@@ -17,8 +17,11 @@ module.exports = class Room {
this._roomPassword = null; this._roomPassword = null;
this._hostOnlyRecording = false; this._hostOnlyRecording = false;
this._moderator = { this._moderator = {
start_audio_muted: false, audio_start_muted: false,
start_video_hidden: false, video_start_hidden: false,
audio_cant_unmute: false,
video_cant_unhide: false,
screen_cant_share: false,
}; };
this.survey = config.survey; this.survey = config.survey;
this.redirect = config.redirect; this.redirect = config.redirect;
@@ -109,11 +112,19 @@ module.exports = class Room {
updateRoomModerator(data) { updateRoomModerator(data) {
log.debug('Update room moderator', data); log.debug('Update room moderator', data);
switch (data.type) { switch (data.type) {
case 'audio': case 'audio_start_muted':
this._moderator.start_audio_muted = data.status; this._moderator.audio_start_muted = data.status;
break;
case 'video_start_hidden':
this._moderator.video_start_hidden = data.status;
case 'audio_cant_unmute':
this._moderator.audio_cant_unmute = data.status;
break;
case 'video_cant_unhide':
this._moderator.video_cant_unhide = data.status;
case 'screen_cant_share':
this._moderator.screen_cant_share = data.status;
break; break;
case 'video':
this._moderator.start_video_hidden = data.status;
default: default:
break; break;
} }

عرض الملف

@@ -40,7 +40,7 @@ dependencies: {
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com * @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.2.2 * @version 1.2.3
* *
*/ */
@@ -758,6 +758,16 @@ function startServer() {
const room = roomList.get(socket.room_id); const room = roomList.get(socket.room_id);
room.updateRoomModerator(data); room.updateRoomModerator(data);
switch (data.type) {
case 'audio_cant_unmute':
case 'video_cant_unhide':
case 'screen_cant_share':
room.broadCast(socket.id, 'updateRoomModerator', data);
break;
default:
break;
}
}); });
socket.on('fileInfo', (dataObject) => { socket.on('fileInfo', (dataObject) => {

عرض الملف

@@ -1,6 +1,6 @@
{ {
"name": "mirotalksfu", "name": "mirotalksfu",
"version": "1.2.2", "version": "1.2.3",
"description": "WebRTC SFU browser-based video calls", "description": "WebRTC SFU browser-based video calls",
"main": "Server.js", "main": "Server.js",
"scripts": { "scripts": {
@@ -44,10 +44,10 @@
"crypto-js": "4.2.0", "crypto-js": "4.2.0",
"express": "4.18.2", "express": "4.18.2",
"httpolyglot": "0.1.2", "httpolyglot": "0.1.2",
"mediasoup": "3.13.1", "mediasoup": "3.13.2",
"mediasoup-client": "3.7.0", "mediasoup-client": "3.7.0",
"ngrok": "^4.3.3", "ngrok": "^4.3.3",
"openai": "^4.18.0", "openai": "^4.19.0",
"qs": "6.11.2", "qs": "6.11.2",
"socket.io": "4.7.2", "socket.io": "4.7.2",
"swagger-ui-express": "5.0.0", "swagger-ui-express": "5.0.0",

عرض الملف

@@ -881,6 +881,10 @@ button:hover {
transform: var(--btns-hover-scale); transform: var(--btns-hover-scale);
} }
.red {
color: red !important;
}
/*-------------------------------------------------------------- /*--------------------------------------------------------------
# Lobby users list # Lobby users list
--------------------------------------------------------------*/ --------------------------------------------------------------*/

عرض الملف

@@ -20,8 +20,11 @@ class LocalStorage {
show_chat_on_msg: true, // show chat on new message show_chat_on_msg: true, // show chat on new message
show_transcript_on_msg: true, // show transcript on new message show_transcript_on_msg: true, // show transcript on new message
speech_in_msg: false, // speech incoming message speech_in_msg: false, // speech incoming message
moderator_audio_muted: false, // Everyone starts muted in the room moderator_audio_start_muted: false, // Everyone starts muted in the room
moderator_video_hidden: false, // Everyone starts hidden in the room moderator_video_start_hidden: false, // Everyone starts hidden in the room
moderator_audio_cant_unmute: false, // Everyone can't unmute themselves
moderator_video_cant_unhide: false, // Everyone can't unhide themselves
moderator_screen_cant_share: false, // Everyone can't share screen
mic_auto_gain_control: false, mic_auto_gain_control: false,
mic_echo_cancellations: true, mic_echo_cancellations: true,
mic_noise_suppression: true, mic_noise_suppression: true,

عرض الملف

@@ -11,7 +11,7 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com * @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.2.2 * @version 1.2.3
* *
*/ */
@@ -1299,6 +1299,10 @@ function handleButtons() {
rc.updatePeerInfo(peer_name, socket.id, 'hand', false); rc.updatePeerInfo(peer_name, socket.id, 'hand', false);
}; };
startAudioButton.onclick = () => { startAudioButton.onclick = () => {
const moderator = rc.getModerator();
if (moderator.audio_cant_unmute) {
return userLog('warning', 'The moderator does not allow you to unmute', 'top-end', 6000);
}
if (isPushToTalkActive) return; if (isPushToTalkActive) return;
setAudioButtonsDisabled(true); setAudioButtonsDisabled(true);
if (!isEnumerateAudioDevices) initEnumerateAudioDevices(); if (!isEnumerateAudioDevices) initEnumerateAudioDevices();
@@ -1314,6 +1318,10 @@ function handleButtons() {
// rc.pauseProducer(RoomClient.mediaType.audio); // rc.pauseProducer(RoomClient.mediaType.audio);
}; };
startVideoButton.onclick = () => { startVideoButton.onclick = () => {
const moderator = rc.getModerator();
if (moderator.video_cant_unhide) {
return userLog('warning', 'The moderator does not allow you to unhide', 'top-end', 6000);
}
setVideoButtonsDisabled(true); setVideoButtonsDisabled(true);
if (!isEnumerateVideoDevices) initEnumerateVideoDevices(); if (!isEnumerateVideoDevices) initEnumerateVideoDevices();
if (isHideMeActive) rc.handleHideMe(); if (isHideMeActive) rc.handleHideMe();
@@ -1327,6 +1335,10 @@ function handleButtons() {
// rc.pauseProducer(RoomClient.mediaType.video); // rc.pauseProducer(RoomClient.mediaType.video);
}; };
startScreenButton.onclick = () => { startScreenButton.onclick = () => {
const moderator = rc.getModerator();
if (moderator.screen_cant_share) {
return userLog('warning', 'The moderator does not allow you to share the screen', 'top-end', 6000);
}
if (isHideMeActive) rc.handleHideMe(); if (isHideMeActive) rc.handleHideMe();
rc.produce(RoomClient.mediaType.screen); rc.produce(RoomClient.mediaType.screen);
}; };
@@ -1801,18 +1813,42 @@ function handleSelects() {
}; };
// room moderator rules // room moderator rules
switchEveryoneMute.onchange = (e) => { switchEveryoneMute.onchange = (e) => {
const startMuted = e.currentTarget.checked; const audioStartMuted = e.currentTarget.checked;
rc.updateRoomModerator({ type: 'audio', status: startMuted }); rc.updateRoomModerator({ type: 'audio_start_muted', status: audioStartMuted });
rc.roomMessage('mod_audio', startMuted); rc.roomMessage('audio_start_muted', audioStartMuted);
lsSettings.moderator_audio_muted = startMuted; lsSettings.moderator_audio_start_muted = audioStartMuted;
lS.setSettings(lsSettings); lS.setSettings(lsSettings);
e.target.blur(); e.target.blur();
}; };
switchEveryoneHidden.onchange = (e) => { switchEveryoneHidden.onchange = (e) => {
const startHidden = e.currentTarget.checked; const videoStartHidden = e.currentTarget.checked;
rc.updateRoomModerator({ type: 'video', status: startHidden }); rc.updateRoomModerator({ type: 'video_start_hidden', status: videoStartHidden });
rc.roomMessage('mod_video', startHidden); rc.roomMessage('video_start_hidden', videoStartHidden);
lsSettings.moderator_video_hidden = startHidden; lsSettings.moderator_video_start_hidden = videoStartHidden;
lS.setSettings(lsSettings);
e.target.blur();
};
switchEveryoneCantUnmute.onchange = (e) => {
const audioCantUnmute = e.currentTarget.checked;
rc.updateRoomModerator({ type: 'audio_cant_unmute', status: audioCantUnmute });
rc.roomMessage('audio_cant_unmute', audioCantUnmute);
lsSettings.moderator_audio_cant_unmute = audioCantUnmute;
lS.setSettings(lsSettings);
e.target.blur();
};
switchEveryoneCantUnhide.onchange = (e) => {
const videoCantUnhide = e.currentTarget.checked;
rc.updateRoomModerator({ type: 'video_cant_unhide', status: videoCantUnhide });
rc.roomMessage('video_cant_unhide', videoCantUnhide);
lsSettings.moderator_video_cant_unhide = videoCantUnhide;
lS.setSettings(lsSettings);
e.target.blur();
};
switchEveryoneCantShareScreen.onchange = (e) => {
const screenCantShare = e.currentTarget.checked;
rc.updateRoomModerator({ type: 'screen_cant_share', status: screenCantShare });
rc.roomMessage('screen_cant_share', screenCantShare);
lsSettings.moderator_screen_cant_share = screenCantShare;
lS.setSettings(lsSettings); lS.setSettings(lsSettings);
e.target.blur(); e.target.blur();
}; };

عرض الملف

@@ -9,7 +9,7 @@
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com * @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.2.2 * @version 1.2.3
* *
*/ */
@@ -160,8 +160,13 @@ class RoomClient {
this.peer_info = peer_info; this.peer_info = peer_info;
// Moderator // Moderator
this.start_muted = false; this._moderator = {
this.start_hidden = false; audio_start_muted: false,
video_start_hidden: false,
audio_cant_unmute: false,
video_cant_unhide: false,
screen_cant_share: false,
};
this.isAudioAllowed = isAudioAllowed; this.isAudioAllowed = isAudioAllowed;
this.isVideoAllowed = isVideoAllowed; this.isVideoAllowed = isVideoAllowed;
@@ -370,17 +375,21 @@ class RoomClient {
: this.event(_EVENTS.hostOnlyRecordingOff); : this.event(_EVENTS.hostOnlyRecordingOff);
// Handle Room moderator rules // Handle Room moderator rules
if (!isRulesActive || !isPresenter) { if (room.moderator && (!isRulesActive || !isPresenter)) {
console.log('07.2 ----> MODERATOR', room.moderator); console.log('07.2 ----> MODERATOR', room.moderator);
this.start_muted = room.moderator && room.moderator.start_audio_muted; this._moderator.audio_start_muted = room.moderator.audio_start_muted;
this.start_hidden = room.moderator && room.moderator.start_video_hidden; this._moderator.video_start_hidden = room.moderator.video_start_hidden;
if (this.start_muted && this.start_hidden) { this._moderator.audio_cant_unmute = room.moderator.audio_cant_unmute;
this._moderator.video_cant_unhide = room.moderator.video_cant_unhide;
this._moderator.screen_cant_share = room.moderator.screen_cant_share;
//
if (this._moderator.audio_start_muted && this._moderator.video_start_hidden) {
this.userLog('warning', 'The Moderator disabled your audio and video', 'top-end'); this.userLog('warning', 'The Moderator disabled your audio and video', 'top-end');
} }
if (this.start_muted && !this.start_hidden) { if (this._moderator.audio_start_muted && !this._moderator.video_start_hidden) {
this.userLog('warning', 'The Moderator disabled your audio', 'top-end'); this.userLog('warning', 'The Moderator disabled your audio', 'top-end');
} }
if (!this.start_muted && this.start_hidden) { if (!this._moderator.audio_start_muted && this._moderator.video_start_hidden) {
this.userLog('warning', 'The Moderator disabled your video', 'top-end'); this.userLog('warning', 'The Moderator disabled your video', 'top-end');
} }
} }
@@ -740,6 +749,14 @@ class RoomClient {
}.bind(this), }.bind(this),
); );
this.socket.on(
'updateRoomModerator',
function (data) {
console.log('Update room moderator', data);
this.handleUpdateRoomModerator(data);
}.bind(this),
);
this.socket.on( this.socket.on(
'recordingAction', 'recordingAction',
function (data) { function (data) {
@@ -828,7 +845,7 @@ class RoomClient {
async startLocalMedia() { async startLocalMedia() {
console.log('08 ----> Start local media'); console.log('08 ----> Start local media');
if (this.isAudioAllowed && !this.start_muted) { if (this.isAudioAllowed && !this._moderator.audio_start_muted) {
console.log('09 ----> Start audio media'); console.log('09 ----> Start audio media');
this.produce(mediaType.audio, microphoneSelect.value); this.produce(mediaType.audio, microphoneSelect.value);
} else { } else {
@@ -838,7 +855,7 @@ class RoomClient {
this.event(_EVENTS.stopAudio); this.event(_EVENTS.stopAudio);
this.updatePeerInfo(this.peer_name, this.peer_id, 'audio', false); this.updatePeerInfo(this.peer_name, this.peer_id, 'audio', false);
} }
if (this.isVideoAllowed && !this.start_hidden) { if (this.isVideoAllowed && !this._moderator.video_start_hidden) {
console.log('10 ----> Start video media'); console.log('10 ----> Start video media');
this.produce(mediaType.video, videoSelect.value); this.produce(mediaType.video, videoSelect.value);
} else { } else {
@@ -849,7 +866,7 @@ class RoomClient {
this.event(_EVENTS.stopVideo); this.event(_EVENTS.stopVideo);
this.updatePeerInfo(this.peer_name, this.peer_id, 'video', false); this.updatePeerInfo(this.peer_name, this.peer_id, 'video', false);
} }
if (this.joinRoomWithScreen) { if (this.joinRoomWithScreen && !this._moderator.screen_cant_share) {
console.log('08 ----> Start Screen media'); console.log('08 ----> Start Screen media');
this.produce(mediaType.screen, null, false, true); this.produce(mediaType.screen, null, false, true);
} }
@@ -1530,7 +1547,7 @@ class RoomClient {
this.myAudioEl = elem; this.myAudioEl = elem;
this.localAudioEl.appendChild(elem); this.localAudioEl.appendChild(elem);
this.attachMediaStream(elem, stream, type, 'Producer'); this.attachMediaStream(elem, stream, type, 'Producer');
if (this.isAudioAllowed && !this.start_muted && !speakerSelect.disabled) { if (this.isAudioAllowed && !this._moderator.audio_start_muted && !speakerSelect.disabled) {
this.attachSinkId(elem, speakerSelect.value); this.attachSinkId(elem, speakerSelect.value);
} }
console.log('[addProducer] audio-element-count', this.localAudioEl.childElementCount); console.log('[addProducer] audio-element-count', this.localAudioEl.childElementCount);
@@ -4583,12 +4600,33 @@ class RoomClient {
'top-end', 'top-end',
); );
break; break;
case 'mod_audio': case 'audio_start_muted':
this.userLog('info', `${icons.moderator} Moderator: everyone starts muted ${status}`, 'top-end'); this.userLog('info', `${icons.moderator} Moderator: everyone starts muted ${status}`, 'top-end');
break; break;
case 'mod_video': case 'video_start_hidden':
this.userLog('info', `${icons.moderator} Moderator: everyone starts hidden ${status}`, 'top-end'); this.userLog('info', `${icons.moderator} Moderator: everyone starts hidden ${status}`, 'top-end');
break; break;
case 'audio_cant_unmute':
this.userLog(
'info',
`${icons.moderator} Moderator: everyone can't unmute themselves ${status}`,
'top-end',
);
break;
case 'video_cant_unhide':
this.userLog(
'info',
`${icons.moderator} Moderator: everyone can't unhide themselves ${status}`,
'top-end',
);
break;
case 'screen_cant_share':
this.userLog(
'info',
`${icons.moderator} Moderator: everyone can't share the screen ${status}`,
'top-end',
);
break;
default: default:
break; break;
} }
@@ -5395,6 +5433,29 @@ class RoomClient {
} }
} }
handleUpdateRoomModerator(data) {
switch (data.type) {
case 'audio_cant_unmute':
this._moderator.audio_cant_unmute = data.status;
rc.roomMessage('audio_cant_unmute', data.status);
break;
case 'video_cant_unhide':
this._moderator.video_cant_unhide = data.status;
rc.roomMessage('video_cant_unhide', data.status);
case 'screen_cant_share':
this._moderator.screen_cant_share = data.status;
rc.roomMessage('screen_cant_share', data.status);
break;
default:
break;
}
}
getModerator() {
console.log('Get Moderator', this._moderator);
return this._moderator;
}
// #################################################### // ####################################################
// UPDATE PEER INFO // UPDATE PEER INFO
// #################################################### // ####################################################

عرض الملف

@@ -83,6 +83,9 @@ function handleRules(isPresenter) {
console.log('06.1 ----> IsPresenter: ' + isPresenter); console.log('06.1 ----> IsPresenter: ' + isPresenter);
if (!isRulesActive) return; if (!isRulesActive) return;
if (!isPresenter) { if (!isPresenter) {
// ##################################
// GUEST
// ##################################
BUTTONS.participantsList.saveInfoButton = false; BUTTONS.participantsList.saveInfoButton = false;
BUTTONS.settings.lockRoomButton = false; BUTTONS.settings.lockRoomButton = false;
BUTTONS.settings.unlockRoomButton = false; BUTTONS.settings.unlockRoomButton = false;
@@ -97,6 +100,9 @@ function handleRules(isPresenter) {
BUTTONS.whiteboard.whiteboardLockButton = false; BUTTONS.whiteboard.whiteboardLockButton = false;
//... //...
} else { } else {
// ##################################
// PRESENTER
// ##################################
BUTTONS.participantsList.saveInfoButton = true; BUTTONS.participantsList.saveInfoButton = true;
BUTTONS.settings.lockRoomButton = !isRoomLocked; BUTTONS.settings.lockRoomButton = !isRoomLocked;
BUTTONS.settings.unlockRoomButton = isRoomLocked; BUTTONS.settings.unlockRoomButton = isRoomLocked;
@@ -124,10 +130,16 @@ function handleRules(isPresenter) {
switchHostOnlyRecording.checked = hostOnlyRecording; switchHostOnlyRecording.checked = hostOnlyRecording;
rc.roomAction(hostOnlyRecording ? 'hostOnlyRecordingOn' : 'hostOnlyRecordingOff', true, false); rc.roomAction(hostOnlyRecording ? 'hostOnlyRecordingOn' : 'hostOnlyRecordingOff', true, false);
// Room moderator // Room moderator
switchEveryoneMute.checked = lsSettings.moderator_audio_muted; switchEveryoneMute.checked = lsSettings.moderator_audio_start_muted;
switchEveryoneHidden.checked = lsSettings.moderator_video_hidden; switchEveryoneHidden.checked = lsSettings.moderator_video_start_hidden;
rc.updateRoomModerator({ type: 'audio', status: switchEveryoneMute.checked }); switchEveryoneCantUnmute.checked = lsSettings.moderator_audio_cant_unmute;
rc.updateRoomModerator({ type: 'video', status: switchEveryoneHidden.checked }); switchEveryoneCantUnhide.checked = lsSettings.moderator_video_cant_unhide;
switchEveryoneCantShareScreen.checked = lsSettings.moderator_screen_cant_share;
rc.updateRoomModerator({ type: 'audio_start_muted', status: switchEveryoneMute.checked });
rc.updateRoomModerator({ type: 'video_start_hidden', status: switchEveryoneHidden.checked });
rc.updateRoomModerator({ type: 'audio_cant_unmute', status: switchEveryoneCantUnmute.checked });
rc.updateRoomModerator({ type: 'video_cant_unhide', status: switchEveryoneCantUnhide.checked });
rc.updateRoomModerator({ type: 'screen_cant_share', status: switchEveryoneCantShareScreen.checked });
} }
// main. settings... // main. settings...
BUTTONS.settings.lockRoomButton ? show(lockRoomButton) : hide(lockRoomButton); BUTTONS.settings.lockRoomButton ? show(lockRoomButton) : hide(lockRoomButton);

عرض الملف

@@ -593,6 +593,7 @@ access to use this app.
<div id="tabModerator" class="tabcontent"> <div id="tabModerator" class="tabcontent">
<h3 class="mod-title">Moderator options</h3> <h3 class="mod-title">Moderator options</h3>
<hr style="border: 1px solid grey" />
<table class="settingsTable"> <table class="settingsTable">
<tr id="everyoneMuteBtn"> <tr id="everyoneMuteBtn">
<td style="width: auto"> <td style="width: auto">
@@ -625,6 +626,65 @@ access to use this app.
</div> </div>
</td> </td>
</tr> </tr>
<tr>
<td colspan="2">
<hr style="border: 1px solid grey" />
</td>
</tr>
<tr id="everyoneCantUnmuteBtn">
<td style="width: auto">
<div class="title">
<i class="fas fa-microphone red"></i>
<p>Everyone can't unmute themselves</p>
</div>
</td>
<td>
<div class="form-check form-switch form-switch-md">
<input
id="switchEveryoneCantUnmute"
class="form-check-input"
type="checkbox"
checked
/>
</div>
</td>
</tr>
<tr id="everyoneCantUnhideBtn">
<td style="width: auto">
<div class="title">
<i class="fas fa-video red"></i>
<p>Everyone can't unhide themselves</p>
</div>
</td>
<td>
<div class="form-check form-switch form-switch-md">
<input
id="switchEveryoneCantUnhide"
class="form-check-input"
type="checkbox"
checked
/>
</div>
</td>
</tr>
<tr id="everyoneCantShareScreenBtn">
<td style="width: auto">
<div class="title">
<i class="fas fa-display red"></i>
<p>Everyone can't share screen</p>
</div>
</td>
<td>
<div class="form-check form-switch form-switch-md">
<input
id="switchEveryoneCantShareScreen"
class="form-check-input"
type="checkbox"
checked
/>
</div>
</td>
</tr>
</table> </table>
</div> </div>