diff --git a/app/src/Room.js b/app/src/Room.js
index 7c99cd63..ee098fa3 100644
--- a/app/src/Room.js
+++ b/app/src/Room.js
@@ -39,6 +39,7 @@ module.exports = class Room {
};
// ##########################
this._moderator = {
+ video_start_privacy: false,
audio_start_muted: false,
video_start_hidden: false,
audio_cant_unmute: false,
@@ -424,6 +425,9 @@ module.exports = class Room {
updateRoomModerator(data) {
log.debug('Update room moderator', data);
switch (data.type) {
+ case 'video_start_privacy':
+ this._moderator.video_start_privacy = data.status;
+ break;
case 'audio_start_muted':
this._moderator.audio_start_muted = data.status;
break;
diff --git a/app/src/Server.js b/app/src/Server.js
index 6d3fcaf1..5ffe7790 100644
--- a/app/src/Server.js
+++ b/app/src/Server.js
@@ -44,7 +44,7 @@ dependencies: {
* @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
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
- * @version 1.5.26
+ * @version 1.5.27
*
*/
@@ -1827,6 +1827,8 @@ function startServer() {
const peer = room.getPeer(socket.id);
+ if (!peer) return;
+
peer.updatePeerInfo(data);
if (data.broadcast) {
@@ -2590,6 +2592,8 @@ function startServer() {
const peer = room.getPeer(id);
+ if (!peer) return false;
+
const { peer_name } = peer;
return peer_name == name;
diff --git a/package.json b/package.json
index 2f43dc01..18d55d1d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "mirotalksfu",
- "version": "1.5.26",
+ "version": "1.5.27",
"description": "WebRTC SFU browser-based video calls",
"main": "Server.js",
"scripts": {
diff --git a/public/css/Room.css b/public/css/Room.css
index ce458da1..f3541a2a 100644
--- a/public/css/Room.css
+++ b/public/css/Room.css
@@ -608,6 +608,7 @@ th {
width: 65%;
background-color: var(--body-bg);
min-height: 480px;
+ max-height: 680px;
overflow-x: hidden;
overflow-y: auto;
}
@@ -1042,6 +1043,12 @@ th {
# Common
--------------------------------------------------------------*/
+h1,
+h2,
+h3 {
+ color: #c2c2c2;
+}
+
select {
height: 40px;
line-height: 40px;
@@ -1405,7 +1412,8 @@ hr {
}
.wa {
- width: auto;
+ /* width: auto; */
+ width: 320px;
}
.ml-5 {
diff --git a/public/js/LocalStorage.js b/public/js/LocalStorage.js
index 273c140e..0f3294c3 100644
--- a/public/js/LocalStorage.js
+++ b/public/js/LocalStorage.js
@@ -20,6 +20,7 @@ class LocalStorage {
show_chat_on_msg: true, // show chat on new message
transcript_show_on_msg: true, // show transcript on new message
speech_in_msg: false, // speech incoming message
+ moderator_video_start_privacy: false, // Everyone starts video in privacy mode
moderator_audio_start_muted: false, // Everyone starts muted in the room
moderator_video_start_hidden: false, // Everyone starts hidden in the room
moderator_audio_cant_unmute: false, // Everyone can't unmute themselves
diff --git a/public/js/Room.js b/public/js/Room.js
index 79d6b3df..9ab077b4 100644
--- a/public/js/Room.js
+++ b/public/js/Room.js
@@ -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 CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
- * @version 1.5.26
+ * @version 1.5.27
*
*/
@@ -2432,6 +2432,16 @@ function handleSelects() {
toggleCanvasGrid();
};
// room moderator rules
+ switchEveryonePrivacy.onchange = (e) => {
+ const videoStartPrivacy = e.currentTarget.checked;
+ isVideoPrivacyActive = !videoStartPrivacy;
+ rc.toggleVideoPrivacyMode();
+ rc.updateRoomModerator({ type: 'video_start_privacy', status: videoStartPrivacy });
+ rc.roomMessage('video_start_privacy', videoStartPrivacy);
+ localStorageSettings.moderator_video_start_privacy = videoStartPrivacy;
+ lS.setSettings(localStorageSettings);
+ e.target.blur();
+ };
switchEveryoneMute.onchange = (e) => {
const audioStartMuted = e.currentTarget.checked;
rc.updateRoomModerator({ type: 'audio_start_muted', status: audioStartMuted });
@@ -4304,7 +4314,7 @@ function showAbout() {
imageUrl: image.about,
customClass: { image: 'img-about' },
position: 'center',
- title: 'WebRTC SFU v1.5.26',
+ title: 'WebRTC SFU v1.5.27',
html: `
diff --git a/public/js/RoomClient.js b/public/js/RoomClient.js
index 088afbc4..c85bcd24 100644
--- a/public/js/RoomClient.js
+++ b/public/js/RoomClient.js
@@ -9,7 +9,7 @@
* @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
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
- * @version 1.5.26
+ * @version 1.5.27
*
*/
@@ -210,6 +210,7 @@ class RoomClient {
// Moderator
this._moderator = {
+ video_start_privacy: false,
audio_start_muted: false,
video_start_hidden: false,
audio_cant_unmute: false,
@@ -506,6 +507,7 @@ class RoomClient {
if (room.moderator && (!isRulesActive || !isPresenter)) {
console.log('07.2 ----> ROOM MODERATOR', room.moderator);
const {
+ video_start_privacy,
audio_start_muted,
video_start_hidden,
audio_cant_unmute,
@@ -515,6 +517,7 @@ class RoomClient {
chat_cant_chatgpt,
} = room.moderator;
+ this._moderator.video_start_privacy = video_start_privacy;
this._moderator.audio_start_muted = audio_start_muted;
this._moderator.video_start_hidden = video_start_hidden;
this._moderator.audio_cant_unmute = audio_cant_unmute;
@@ -522,7 +525,18 @@ class RoomClient {
this._moderator.screen_cant_share = screen_cant_share;
this._moderator.chat_cant_privately = chat_cant_privately;
this._moderator.chat_cant_chatgpt = chat_cant_chatgpt;
+
//
+ if (this._moderator.video_start_privacy || localStorageSettings.moderator_video_start_privacy) {
+ this.peer_info.peer_video_privacy = true;
+ this.emitCmd({
+ type: 'privacy',
+ peer_id: this.peer_id,
+ active: true,
+ broadcast: true,
+ });
+ this.userLog('warning', 'The Moderator starts video in privacy mode', 'top-end');
+ }
if (this._moderator.audio_start_muted && this._moderator.video_start_hidden) {
this.userLog('warning', 'The Moderator disabled your audio and video', 'top-end');
} else {
@@ -1853,7 +1867,7 @@ class RoomClient {
pn.id = id + '__pin';
pn.className = html.pin;
vp = document.createElement('button');
- vp.id = this.peer_id + +'__vp';
+ vp.id = this.peer_id + '__vp';
vp.className = html.videoPrivacy;
au = document.createElement('button');
au.id = this.peer_id + '__audio';
@@ -1888,7 +1902,7 @@ class RoomClient {
d.appendChild(p);
d.appendChild(vb);
this.videoMediaContainer.appendChild(d);
- this.attachMediaStream(elem, stream, type, 'Producer');
+ await this.attachMediaStream(elem, stream, type, 'Producer');
this.myVideoEl = elem;
this.isVideoPictureInPictureSupported && this.handlePIP(elem.id, pip.id);
this.isVideoFullScreenSupported && this.handleFS(elem.id, fs.id);
@@ -1919,7 +1933,7 @@ class RoomClient {
elem.volume = 0;
this.myAudioEl = elem;
this.localAudioEl.appendChild(elem);
- this.attachMediaStream(elem, stream, type, 'Producer');
+ await this.attachMediaStream(elem, stream, type, 'Producer');
console.log('[addProducer] audio-element-count', this.localAudioEl.childElementCount);
break;
default:
@@ -2194,7 +2208,7 @@ class RoomClient {
};
}
- handleConsumer(id, type, stream, peer_name, peer_info) {
+ async handleConsumer(id, type, stream, peer_name, peer_info) {
let elem, vb, d, p, i, cm, au, pip, fs, ts, sf, sm, sv, gl, ban, ko, pb, pm, pv, pn;
let eDiv, eBtn, eVc; // expand buttons
@@ -2318,7 +2332,7 @@ class RoomClient {
d.appendChild(pm);
d.appendChild(vb);
this.videoMediaContainer.appendChild(d);
- this.attachMediaStream(elem, stream, type, 'Consumer');
+ await this.attachMediaStream(elem, stream, type, 'Consumer');
this.isVideoPictureInPictureSupported && this.handlePIP(elem.id, pip.id);
this.isVideoFullScreenSupported && this.handleFS(elem.id, fs.id);
this.handleDD(elem.id, remotePeerId);
@@ -2363,7 +2377,7 @@ class RoomClient {
elem.autoplay = true;
elem.audio = 1.0;
this.remoteAudioEl.appendChild(elem);
- this.attachMediaStream(elem, stream, type, 'Consumer');
+ await this.attachMediaStream(elem, stream, type, 'Consumer');
let audioConsumerId = remotePeerId + '___pVolume';
this.audioConsumers.set(audioConsumerId, id);
let inputPv = this.getId(audioConsumerId);
@@ -2648,7 +2662,7 @@ class RoomClient {
// HELPERS
// ####################################################
- attachMediaStream(elem, stream, type, who) {
+ async attachMediaStream(elem, stream, type, who) {
let track;
switch (type) {
case mediaType.audio:
@@ -3473,23 +3487,33 @@ class RoomClient {
// ####################################################
handleVP(elemId, vpId) {
+ const startVideoInPrivacyMode =
+ this._moderator.video_start_privacy || localStorageSettings.moderator_video_start_privacy;
let videoPlayer = this.getId(elemId);
let btnVp = this.getId(vpId);
if (btnVp && videoPlayer) {
btnVp.addEventListener('click', () => {
this.sound('click');
- isVideoPrivacyActive = !isVideoPrivacyActive;
- this.setVideoPrivacyStatus(this.peer_id, isVideoPrivacyActive);
- this.emitCmd({
- type: 'privacy',
- peer_id: this.peer_id,
- active: isVideoPrivacyActive,
- broadcast: true,
- });
+ this.toggleVideoPrivacyMode();
});
+
+ if (startVideoInPrivacyMode) {
+ btnVp.click();
+ }
}
}
+ toggleVideoPrivacyMode() {
+ isVideoPrivacyActive = !isVideoPrivacyActive;
+ this.setVideoPrivacyStatus(this.peer_id, isVideoPrivacyActive);
+ this.emitCmd({
+ type: 'privacy',
+ peer_id: this.peer_id,
+ active: isVideoPrivacyActive,
+ broadcast: true,
+ });
+ }
+
setVideoPrivacyStatus(elemName, privacy) {
let videoPlayer = this.getName(elemName)[0];
if (privacy) {
@@ -5807,6 +5831,13 @@ class RoomClient {
'top-end',
);
break;
+ case 'video_start_privacy':
+ this.userLog(
+ 'info',
+ `${icons.moderator} Moderator: everyone starts in privacy mode ${status}`,
+ 'top-end',
+ );
+ break;
case 'audio_start_muted':
this.userLog('info', `${icons.moderator} Moderator: everyone starts muted ${status}`, 'top-end');
break;
diff --git a/public/js/Rules.js b/public/js/Rules.js
index 5d5ce4e1..2302cc47 100644
--- a/public/js/Rules.js
+++ b/public/js/Rules.js
@@ -162,6 +162,7 @@ function handleRules(isPresenter) {
switchHostOnlyRecording.checked = hostOnlyRecording;
rc.roomAction(hostOnlyRecording ? 'hostOnlyRecordingOn' : 'hostOnlyRecordingOff', true, false);
// Room moderator
+ switchEveryonePrivacy.checked = localStorageSettings.moderator_video_start_privacy;
switchEveryoneMute.checked = localStorageSettings.moderator_audio_start_muted;
switchEveryoneHidden.checked = localStorageSettings.moderator_video_start_hidden;
switchEveryoneCantUnmute.checked = localStorageSettings.moderator_audio_cant_unmute;
@@ -173,6 +174,7 @@ function handleRules(isPresenter) {
// Update moderator settings...
const moderatorData = {
+ video_start_privacy: switchEveryonePrivacy.checked,
audio_start_muted: switchEveryoneMute.checked,
video_start_hidden: switchEveryoneHidden.checked,
audio_cant_unmute: switchEveryoneCantUnmute.checked,
diff --git a/public/views/Room.html b/public/views/Room.html
index eb6df9a7..736f9d07 100644
--- a/public/views/Room.html
+++ b/public/views/Room.html
@@ -638,7 +638,27 @@ access to use this app.
+
Moderator options
+
+
+
+
+
+ Everyone starts in privacy mode
+
+ |
+
+
+
+
+ |
+
|
|