[mirotalksfu] - #134 WIP add room broadcasting, bug fixing, update dep
هذا الالتزام موجود في:
@@ -12,6 +12,9 @@ module.exports = class Room {
|
||||
this.audioLevelObserver = null;
|
||||
this.audioLevelObserverEnabled = true;
|
||||
this.audioLastUpdateTime = 0;
|
||||
// ##########################
|
||||
this._isBroadcasting = false;
|
||||
// ##########################
|
||||
this._isLocked = false;
|
||||
this._isLobbyEnabled = false;
|
||||
this._roomPassword = null;
|
||||
@@ -109,6 +112,11 @@ module.exports = class Room {
|
||||
// ROOM MODERATOR
|
||||
// ####################################################
|
||||
|
||||
updateRoomModeratorALL(data) {
|
||||
this._moderator = data;
|
||||
log.debug('Update room moderator all data', this._moderator);
|
||||
}
|
||||
|
||||
updateRoomModerator(data) {
|
||||
log.debug('Update room moderator', data);
|
||||
switch (data.type) {
|
||||
@@ -137,6 +145,7 @@ module.exports = class Room {
|
||||
toJson() {
|
||||
return {
|
||||
id: this.id,
|
||||
broadcasting: this._isBroadcasting,
|
||||
config: {
|
||||
isLocked: this._isLocked,
|
||||
isLobbyEnabled: this._isLobbyEnabled,
|
||||
@@ -312,6 +321,10 @@ module.exports = class Room {
|
||||
// ROOM STATUS
|
||||
// ####################################################
|
||||
|
||||
// GET
|
||||
isBroadcasting() {
|
||||
return this._isBroadcasting;
|
||||
}
|
||||
getPassword() {
|
||||
return this._roomPassword;
|
||||
}
|
||||
@@ -324,6 +337,11 @@ module.exports = class Room {
|
||||
isHostOnlyRecording() {
|
||||
return this._hostOnlyRecording;
|
||||
}
|
||||
|
||||
// SET
|
||||
setIsBroadcasting(status) {
|
||||
this._isBroadcasting = status;
|
||||
}
|
||||
setLocked(status, password) {
|
||||
this._isLocked = status;
|
||||
this._roomPassword = password;
|
||||
|
||||
@@ -40,7 +40,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.2.8
|
||||
* @version 1.2.9
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -630,7 +630,7 @@ function startServer() {
|
||||
|
||||
const room = roomList.get(socket.room_id);
|
||||
|
||||
let peerCounts = room.getPeersCount();
|
||||
const peerCounts = room.getPeersCount();
|
||||
|
||||
log.debug('Peer counts', { peerCounts: peerCounts });
|
||||
|
||||
@@ -668,7 +668,13 @@ function startServer() {
|
||||
const room = roomList.get(socket.room_id);
|
||||
|
||||
log.debug('Room action:', data);
|
||||
|
||||
switch (data.action) {
|
||||
case 'broadcasting':
|
||||
if (!isPresenter) return;
|
||||
room.setIsBroadcasting(data.room_broadcasting);
|
||||
room.broadCast(socket.id, 'roomAction', data.action);
|
||||
break;
|
||||
case 'lock':
|
||||
if (!isPresenter) return;
|
||||
if (!room.isLocked()) {
|
||||
@@ -716,6 +722,7 @@ function startServer() {
|
||||
break;
|
||||
}
|
||||
log.debug('Room status', {
|
||||
broadcasting: room.isBroadcasting(),
|
||||
locked: room.isLocked(),
|
||||
lobby: room.isLobbyEnabled(),
|
||||
hostOnlyRecording: room.isHostOnlyRecording(),
|
||||
@@ -780,31 +787,58 @@ function startServer() {
|
||||
|
||||
const room = roomList.get(socket.room_id);
|
||||
|
||||
// update my peer_info status to all in the room
|
||||
room.getPeers().get(socket.id).updatePeerInfo(data);
|
||||
room.broadCast(socket.id, 'updatePeerInfo', data);
|
||||
|
||||
if (data.broadcast) {
|
||||
log.info('updatePeerInfo broadcast data');
|
||||
room.broadCast(socket.id, 'updatePeerInfo', data);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('updateRoomModerator', (dataObject) => {
|
||||
socket.on('updateRoomModerator', async (dataObject) => {
|
||||
if (!roomList.has(socket.room_id)) return;
|
||||
|
||||
const data = checkXSS(dataObject);
|
||||
|
||||
const room = roomList.get(socket.room_id);
|
||||
|
||||
room.updateRoomModerator(data);
|
||||
const isPresenter = await isPeerPresenter(socket.room_id, socket.id, data.peer_name, data.peer_uuid);
|
||||
|
||||
switch (data.type) {
|
||||
if (!isPresenter) return;
|
||||
|
||||
const moderator = data.moderator;
|
||||
|
||||
room.updateRoomModerator(moderator);
|
||||
|
||||
switch (moderator.type) {
|
||||
case 'audio_cant_unmute':
|
||||
case 'video_cant_unhide':
|
||||
case 'screen_cant_share':
|
||||
room.broadCast(socket.id, 'updateRoomModerator', data);
|
||||
room.broadCast(socket.id, 'updateRoomModerator', moderator);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('updateRoomModeratorALL', async (dataObject) => {
|
||||
if (!roomList.has(socket.room_id)) return;
|
||||
|
||||
const data = checkXSS(dataObject);
|
||||
|
||||
const room = roomList.get(socket.room_id);
|
||||
|
||||
const isPresenter = await isPeerPresenter(socket.room_id, socket.id, data.peer_name, data.peer_uuid);
|
||||
|
||||
if (!isPresenter) return;
|
||||
|
||||
const moderator = data.moderator;
|
||||
|
||||
room.updateRoomModeratorALL(moderator);
|
||||
|
||||
room.broadCast(socket.id, 'updateRoomModeratorALL', moderator);
|
||||
});
|
||||
|
||||
socket.on('fileInfo', (dataObject) => {
|
||||
if (!roomList.has(socket.room_id)) return;
|
||||
|
||||
@@ -886,9 +920,10 @@ function startServer() {
|
||||
|
||||
const data = checkXSS(dataObject);
|
||||
|
||||
log.debug('Video off data', data.peer_name);
|
||||
|
||||
const room = roomList.get(socket.room_id);
|
||||
|
||||
log.debug('Video off', getPeerName(room));
|
||||
room.broadCast(socket.id, 'setVideoOff', data);
|
||||
});
|
||||
|
||||
@@ -930,7 +965,7 @@ function startServer() {
|
||||
|
||||
const isPeerValid = isAuthPeer(peer_username, peer_password);
|
||||
|
||||
log.debug('[' + socket.id + '] JOIN ROOM - HOST PROTECTED - USER AUTH check peer', {
|
||||
log.debug('[Join] - HOST PROTECTED - USER AUTH check peer', {
|
||||
ip: peer_ip,
|
||||
peer_username: peer_username,
|
||||
peer_password: peer_password,
|
||||
@@ -953,8 +988,10 @@ function startServer() {
|
||||
|
||||
if (!(socket.room_id in presenters)) presenters[socket.room_id] = {};
|
||||
|
||||
const peer_name = room.getPeers()?.get(socket.id)?.peer_info?.peer_name;
|
||||
const peer_uuid = room.getPeers()?.get(socket.id)?.peer_info?.peer_uuid;
|
||||
const peer = room.getPeers()?.get(socket.id)?.peer_info;
|
||||
const peer_id = peer.peer_id;
|
||||
const peer_name = peer.peer_name;
|
||||
const peer_uuid = peer.peer_uuid;
|
||||
|
||||
// Set the presenters
|
||||
const presenter = {
|
||||
@@ -995,8 +1032,8 @@ function startServer() {
|
||||
'The user is currently waiting to join the room because the lobby is enabled, and they are not a presenter',
|
||||
);
|
||||
room.broadCast(socket.id, 'roomLobby', {
|
||||
peer_id: data.peer_info.peer_id,
|
||||
peer_name: data.peer_info.peer_name,
|
||||
peer_id: peer_id,
|
||||
peer_name: peer_name,
|
||||
lobby_status: 'waiting',
|
||||
});
|
||||
return cb('isLobby');
|
||||
@@ -1235,8 +1272,10 @@ function startServer() {
|
||||
|
||||
const room = roomList.get(socket.room_id);
|
||||
|
||||
const peerName = room.getPeers()?.get(socket.id)?.peer_info?.peer_name || '';
|
||||
const peerUuid = room.getPeers()?.get(socket.id)?.peer_info?.peer_uuid || '';
|
||||
const peer = room.getPeers()?.get(socket.id)?.peer_info;
|
||||
|
||||
const peerName = peer.peer_name || '';
|
||||
const peerUuid = peer.peer_uuid || '';
|
||||
|
||||
const isPresenter = await isPeerPresenter(socket.room_id, socket.id, peerName, peerUuid);
|
||||
|
||||
@@ -1245,12 +1284,7 @@ function startServer() {
|
||||
room.removePeer(socket.id);
|
||||
|
||||
if (room.getPeers().size === 0) {
|
||||
if (room.isLocked()) {
|
||||
room.setLocked(false);
|
||||
}
|
||||
if (room.isLobbyEnabled()) {
|
||||
room.setLobbyEnabled(false);
|
||||
}
|
||||
//
|
||||
roomList.delete(socket.room_id);
|
||||
|
||||
const activeRooms = getActiveRooms();
|
||||
@@ -1275,8 +1309,11 @@ function startServer() {
|
||||
|
||||
const room = roomList.get(socket.room_id);
|
||||
|
||||
const peerName = room.getPeers()?.get(socket.id)?.peer_info?.peer_name || '';
|
||||
const peerUuid = room.getPeers()?.get(socket.id)?.peer_info?.peer_uuid || '';
|
||||
const peer = room.getPeers()?.get(socket.id)?.peer_info;
|
||||
|
||||
const peerName = peer.peer_name || '';
|
||||
const peerUuid = peer.peer_uuid || '';
|
||||
|
||||
const isPresenter = await isPeerPresenter(socket.room_id, socket.id, peerName, peerUuid);
|
||||
|
||||
log.debug('Exit room', peerName);
|
||||
@@ -1287,6 +1324,7 @@ function startServer() {
|
||||
room.broadCast(socket.id, 'removeMe', removeMeData(room, peerName, isPresenter));
|
||||
|
||||
if (room.getPeers().size === 0) {
|
||||
//
|
||||
roomList.delete(socket.room_id);
|
||||
|
||||
delete presenters[socket.room_id];
|
||||
|
||||
@@ -62,7 +62,7 @@ module.exports = {
|
||||
Additional layers can be added to specify valid presenters and co-presenters by setting designated usernames.
|
||||
*/
|
||||
'Miroslav Pejic',
|
||||
'MiroTalk Admin',
|
||||
'MiroTalk SFU',
|
||||
],
|
||||
console: {
|
||||
debug: true,
|
||||
|
||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mirotalksfu",
|
||||
"version": "1.2.8",
|
||||
"version": "1.2.9",
|
||||
"description": "WebRTC SFU browser-based video calls",
|
||||
"main": "Server.js",
|
||||
"scripts": {
|
||||
@@ -34,8 +34,8 @@
|
||||
"author": "Miroslav Pejic",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@sentry/integrations": "7.81.1",
|
||||
"@sentry/node": "7.81.1",
|
||||
"@sentry/integrations": "7.83.0",
|
||||
"@sentry/node": "7.83.0",
|
||||
"axios": "^1.6.2",
|
||||
"body-parser": "1.20.2",
|
||||
"colors": "1.4.0",
|
||||
@@ -44,10 +44,10 @@
|
||||
"crypto-js": "4.2.0",
|
||||
"express": "4.18.2",
|
||||
"httpolyglot": "0.1.2",
|
||||
"mediasoup": "3.13.5",
|
||||
"mediasoup": "3.13.6",
|
||||
"mediasoup-client": "3.7.0",
|
||||
"ngrok": "^4.3.3",
|
||||
"openai": "^4.20.0",
|
||||
"openai": "^4.20.1",
|
||||
"qs": "6.11.2",
|
||||
"socket.io": "4.7.2",
|
||||
"swagger-ui-express": "5.0.0",
|
||||
|
||||
@@ -252,7 +252,7 @@
|
||||
|
||||
.chat .chat-history .other-message {
|
||||
background: var(--left-msg-bg);
|
||||
text-align: right;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.chat .chat-history .other-message:after {
|
||||
|
||||
@@ -35,6 +35,7 @@ class LocalStorage {
|
||||
mic_volume: 100, // %
|
||||
video_fps: 0, // default 1280x768 30fps
|
||||
screen_fps: 0, // max 30fps
|
||||
broadcasting: false, // default false (one to many a/v streaming)
|
||||
lobby: false, // default false
|
||||
pitch_bar: true, // volume indicator
|
||||
sounds: true, // room notify sounds
|
||||
|
||||
@@ -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.2.8
|
||||
* @version 1.2.9
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -34,6 +34,8 @@ let redirect = {
|
||||
};
|
||||
|
||||
const _PEER = {
|
||||
presenter: '<i class="fa-solid fa-user-shield"></i>',
|
||||
guest: '<i class="fa-solid fa-signal"></i>',
|
||||
audioOn: '<i class="fas fa-microphone"></i>',
|
||||
audioOff: '<i style="color: red;" class="fas fa-microphone-slash"></i>',
|
||||
videoOn: '<i class="fas fa-video"></i>',
|
||||
@@ -99,6 +101,7 @@ let isPushToTalkActive = false;
|
||||
let isSpaceDown = false;
|
||||
let isPitchBarEnabled = true;
|
||||
let isSoundEnabled = true;
|
||||
let isBroadcastingEnabled = false;
|
||||
let isLobbyEnabled = false;
|
||||
let isLobbyOpen = false;
|
||||
let hostOnlyRecording = false;
|
||||
@@ -164,6 +167,11 @@ function initClient() {
|
||||
);
|
||||
setTippy('lobbyAcceptAllBtn', 'Accept', 'top');
|
||||
setTippy('lobbyRejectAllBtn', 'Reject', 'top');
|
||||
setTippy(
|
||||
'switchBroadcasting',
|
||||
'Broadcasting is the dissemination of audio or video content to a large audience (one to many)',
|
||||
'right',
|
||||
);
|
||||
setTippy(
|
||||
'switchLobby',
|
||||
'Lobby mode lets you protect your meeting by only allowing people to enter after a formal approval by a moderator',
|
||||
@@ -252,7 +260,7 @@ function refreshMainButtonsToolTipPlacement() {
|
||||
setTippy('stopRecButton', 'Stop recording', placement);
|
||||
setTippy('raiseHandButton', 'Raise your hand', placement);
|
||||
setTippy('lowerHandButton', 'Lower your hand', placement);
|
||||
setTippy('roomEmojiPicker', 'Toggle emoji reaction', placement);
|
||||
setTippy('emojiRoomButton', 'Toggle emoji reaction', placement);
|
||||
setTippy('swapCameraButton', 'Swap the camera', placement);
|
||||
setTippy('chatButton', 'Toggle the chat', placement);
|
||||
setTippy('transcriptionButton', 'Toggle transcription', placement);
|
||||
@@ -345,7 +353,7 @@ async function initEnumerateVideoDevices() {
|
||||
}
|
||||
|
||||
function enumerateVideoDevices(stream) {
|
||||
console.log('03 ----> Get Video Devices');
|
||||
console.log('02 ----> Get Video Devices');
|
||||
navigator.mediaDevices
|
||||
.enumerateDevices()
|
||||
.then((devices) =>
|
||||
@@ -383,7 +391,7 @@ async function initEnumerateAudioDevices() {
|
||||
}
|
||||
|
||||
function enumerateAudioDevices(stream) {
|
||||
console.log('02 ----> Get Audio Devices');
|
||||
console.log('03 ----> Get Audio Devices');
|
||||
navigator.mediaDevices
|
||||
.enumerateDevices()
|
||||
.then((devices) =>
|
||||
@@ -673,7 +681,7 @@ function getPeerInfo() {
|
||||
// ####################################################
|
||||
|
||||
function whoAreYou() {
|
||||
console.log('04 ----> Who are you');
|
||||
console.log('04 ----> Who are you?');
|
||||
|
||||
hide(loadingDiv);
|
||||
document.body.style.background = 'var(--body-bg)';
|
||||
@@ -1001,7 +1009,7 @@ function roomIsReady() {
|
||||
}
|
||||
BUTTONS.main.chatButton && show(chatButton);
|
||||
BUTTONS.main.raiseHandButton && show(raiseHandButton);
|
||||
BUTTONS.main.emojiRoomButton && show(roomEmojiPicker);
|
||||
BUTTONS.main.emojiRoomButton && show(emojiRoomButton);
|
||||
!BUTTONS.chat.chatSaveButton && hide(chatSaveButton);
|
||||
BUTTONS.chat.chatEmojiButton && show(chatEmojiButton);
|
||||
BUTTONS.chat.chatMarkdownButton && show(chatMarkdownButton);
|
||||
@@ -1058,6 +1066,7 @@ function roomIsReady() {
|
||||
isVideoAllowed ? show(stopVideoButton) : BUTTONS.main.startVideoButton && show(startVideoButton);
|
||||
show(fileShareButton);
|
||||
BUTTONS.settings.lockRoomButton && show(lockRoomButton);
|
||||
BUTTONS.settings.broadcastingButton && show(broadcastingButton);
|
||||
BUTTONS.settings.lobbyButton && show(lobbyButton);
|
||||
BUTTONS.settings.host_only_recording && show(roomRecording);
|
||||
BUTTONS.main.aboutButton && show(aboutButton);
|
||||
@@ -1513,7 +1522,7 @@ function handleSelectsInit() {
|
||||
|
||||
function setSelectsInit() {
|
||||
const localStorageDevices = lS.getLocalStorageDevices();
|
||||
console.log('04 ----> Get Local Storage Devices before', localStorageDevices);
|
||||
console.log('04.0 ----> Get Local Storage Devices before', localStorageDevices);
|
||||
if (localStorageDevices) {
|
||||
initMicrophoneSelect.selectedIndex = localStorageDevices.audio.index;
|
||||
initSpeakerSelect.selectedIndex = localStorageDevices.speaker.index;
|
||||
@@ -1703,6 +1712,13 @@ function handleSelects() {
|
||||
}
|
||||
});
|
||||
// room
|
||||
switchBroadcasting.onchange = (e) => {
|
||||
isBroadcastingEnabled = e.currentTarget.checked;
|
||||
rc.roomAction('broadcasting');
|
||||
lsSettings.broadcasting = isBroadcastingEnabled;
|
||||
lS.setSettings(lsSettings);
|
||||
e.target.blur();
|
||||
};
|
||||
switchLobby.onchange = (e) => {
|
||||
isLobbyEnabled = e.currentTarget.checked;
|
||||
rc.roomAction(isLobbyEnabled ? 'lobbyOn' : 'lobbyOff');
|
||||
@@ -1951,10 +1967,16 @@ function handleInputs() {
|
||||
':N': '🥶',
|
||||
':J': '🥴',
|
||||
};
|
||||
for (let i in chatInputEmoji) {
|
||||
let regex = new RegExp(i.replace(/([()[{*+.$^\\|?])/g, '\\$1'), 'gim');
|
||||
this.value = this.value.replace(regex, chatInputEmoji[i]);
|
||||
}
|
||||
// Create a regular expression pattern for all keys in chatInputEmoji
|
||||
const regexPattern = new RegExp(
|
||||
Object.keys(chatInputEmoji)
|
||||
.map((key) => key.replace(/([()[{*+.$^\\|?])/g, '\\$1'))
|
||||
.join('|'),
|
||||
'gim',
|
||||
);
|
||||
// Replace matching patterns with corresponding emojis
|
||||
this.value = this.value.replace(regexPattern, (match) => chatInputEmoji[match]);
|
||||
|
||||
rc.checkLineBreaks();
|
||||
};
|
||||
|
||||
@@ -1992,7 +2014,7 @@ function handleRoomEmojiPicker() {
|
||||
emojiPickerContainer.appendChild(emojiRoomPicker);
|
||||
emojiPickerContainer.style.display = 'none';
|
||||
|
||||
roomEmojiPicker.onclick = () => {
|
||||
emojiRoomButton.onclick = () => {
|
||||
toggleEmojiPicker();
|
||||
};
|
||||
closeEmojiPickerContainer.onclick = () => {
|
||||
@@ -2016,10 +2038,10 @@ function handleRoomEmojiPicker() {
|
||||
function toggleEmojiPicker() {
|
||||
if (emojiPickerContainer.style.display === 'block') {
|
||||
emojiPickerContainer.style.display = 'none';
|
||||
setColor(roomEmojiPicker, 'white');
|
||||
setColor(emojiRoomButton, 'white');
|
||||
} else {
|
||||
emojiPickerContainer.style.display = 'block';
|
||||
setColor(roomEmojiPicker, 'yellow');
|
||||
setColor(emojiRoomButton, 'yellow');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2968,6 +2990,7 @@ async function getRoomParticipants() {
|
||||
participantsList.innerHTML = lists;
|
||||
refreshParticipantsCount(participantsCount, false);
|
||||
setParticipantsTippy(peers);
|
||||
console.log('*** Refresh Chat participant lists ***');
|
||||
}
|
||||
|
||||
async function getParticipantsList(peers) {
|
||||
@@ -3045,6 +3068,7 @@ async function getParticipantsList(peers) {
|
||||
for (const peer of Array.from(peers.keys())) {
|
||||
const peer_info = peers.get(peer).peer_info;
|
||||
const peer_name = peer_info.peer_name;
|
||||
//const peer_presenter = peer_info.peer_presenter ? _PEER.presenter : _PEER.guest;
|
||||
const peer_audio = peer_info.peer_audio ? _PEER.audioOn : _PEER.audioOff;
|
||||
const peer_video = peer_info.peer_video ? _PEER.videoOn : _PEER.videoOff;
|
||||
const peer_screen = peer_info.peer_screen ? _PEER.screenOn : _PEER.screenOff;
|
||||
@@ -3100,6 +3124,9 @@ async function getParticipantsList(peers) {
|
||||
<button class="ml5" id='${peer_id}___pScreen' onclick="rc.peerAction('me',this.id,'stop')">${peer_screen}</button>
|
||||
`;
|
||||
|
||||
// li += `
|
||||
// <button class="ml5" >${peer_presenter}</button>`;
|
||||
|
||||
if (peer_info.peer_hand) {
|
||||
li += `
|
||||
<button class="ml5" >${peer_hand}</button>`;
|
||||
@@ -3127,7 +3154,11 @@ async function getParticipantsList(peers) {
|
||||
<div class="name">${peer_name}</div>
|
||||
<div class="status"> <i class="fa fa-circle online"></i> online <i id="${peer_id}-unread-msg" class="fas fa-comments hidden"></i> </div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// NO ROOM BROADCASTING
|
||||
if (!isBroadcastingEnabled) {
|
||||
li += `
|
||||
<div style="class="dropdown">
|
||||
<button
|
||||
class="dropdown-toggle"
|
||||
@@ -3143,7 +3174,10 @@ async function getParticipantsList(peers) {
|
||||
<li><button class="btn-sm ml5" id="${peer_id}___sendVideoTo" onclick="rc.shareVideo('${peer_id}');">${_PEER.sendVideo} Share Audio/Video</button></li>
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
li += `
|
||||
<br/>
|
||||
|
||||
<div class="about-buttons mt5">
|
||||
@@ -3151,10 +3185,15 @@ async function getParticipantsList(peers) {
|
||||
<button class="ml5" id='${peer_id}___pVideo'>${peer_video}</button>
|
||||
<button class="ml5" id='${peer_id}___pScreen'>${peer_screen}</button>
|
||||
`;
|
||||
|
||||
// li += `
|
||||
// <button class="ml5" >${peer_presenter}</button>`;
|
||||
|
||||
if (peer_info.peer_hand) {
|
||||
li += `
|
||||
<button class="ml5" >${peer_hand}</button>`;
|
||||
}
|
||||
|
||||
li += `
|
||||
</div>
|
||||
</li>
|
||||
@@ -3175,9 +3214,14 @@ function setParticipantsTippy(peers) {
|
||||
for (let peer of Array.from(peers.keys())) {
|
||||
const peer_info = peers.get(peer).peer_info;
|
||||
const peer_id = peer_info.peer_id;
|
||||
setTippy(peer_id + '___pAudio', 'Mute', 'top');
|
||||
setTippy(peer_id + '___pVideo', 'Hide', 'top');
|
||||
setTippy(peer_id + '___pScreen', 'Stop', 'top');
|
||||
|
||||
const peerAudioBtn = rc.getId(peer_id + '___pAudio');
|
||||
const peerVideoBtn = rc.getId(peer_id + '___pVideo');
|
||||
const peerScreenBtn = rc.getId(peer_id + '___pScreen');
|
||||
|
||||
if (peerAudioBtn) setTippy(peerAudioBtn.id, 'Mute', 'top');
|
||||
if (peerVideoBtn) setTippy(peerVideoBtn.id, 'Hide', 'top');
|
||||
if (peerScreenBtn) setTippy(peerScreenBtn.id, 'Stop', 'top');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.2.8
|
||||
* @version 1.2.9
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -42,6 +42,7 @@ const html = {
|
||||
};
|
||||
|
||||
const icons = {
|
||||
room: '<i class="fas fa-home"></i>',
|
||||
chat: '<i class="fas fa-comments"></i>',
|
||||
user: '<i class="fas fa-user"></i>',
|
||||
transcript: '<i class="fas fa-closed-captioning"></i>',
|
||||
@@ -358,7 +359,11 @@ class RoomClient {
|
||||
this.device = await this.loadDevice(data);
|
||||
console.log('07.3 ----> Get Router Rtp Capabilities codecs: ', this.device.rtpCapabilities.codecs);
|
||||
await this.initTransports(this.device);
|
||||
await this.startLocalMedia();
|
||||
if (isBroadcastingEnabled) {
|
||||
isPresenter ? await this.startLocalMedia() : await this.handleRoomBroadcasting();
|
||||
} else {
|
||||
await this.startLocalMedia();
|
||||
}
|
||||
this.socket.emit('getProducers');
|
||||
}
|
||||
|
||||
@@ -369,13 +374,19 @@ class RoomClient {
|
||||
redirect = room.redirect;
|
||||
let peers = new Map(JSON.parse(room.peers));
|
||||
participantsCount = peers.size;
|
||||
// ME
|
||||
for (let peer of Array.from(peers.keys()).filter((id) => id == this.peer_id)) {
|
||||
let my_peer_info = peers.get(peer).peer_info;
|
||||
console.log('07.1 ----> My Peer info', my_peer_info);
|
||||
isPresenter = window.localStorage.isReconnected === 'true' ? isPresenter : my_peer_info.peer_presenter;
|
||||
this.peer_info.peer_presenter = isPresenter;
|
||||
this.getId('isUserPresenter').innerText = isPresenter;
|
||||
window.localStorage.isReconnected = false;
|
||||
handleRules(isPresenter);
|
||||
// ###################################################################################################
|
||||
isBroadcastingEnabled = isPresenter && !room.broadcasting ? isBroadcastingEnabled : room.broadcasting;
|
||||
console.log('07.1 ----> ROOM BROADCASTING', isBroadcastingEnabled);
|
||||
// ###################################################################################################
|
||||
room.config.hostOnlyRecording
|
||||
? (console.log('07.1 ----> WARNING Room Host only recording enabled'),
|
||||
this.event(_EVENTS.hostOnlyRecordingOn))
|
||||
@@ -404,13 +415,17 @@ class RoomClient {
|
||||
this._moderator.video_cant_unhide ? hide(tabVideoDevicesBtn) : show(tabVideoDevicesBtn);
|
||||
}
|
||||
}
|
||||
adaptAspectRatio(participantsCount);
|
||||
// PARTICIPANTS
|
||||
for (let peer of Array.from(peers.keys()).filter((id) => id !== this.peer_id)) {
|
||||
let peer_info = peers.get(peer).peer_info;
|
||||
// console.log('07.1 ----> Remote Peer info', peer_info);
|
||||
if (!peer_info.peer_video) {
|
||||
const canSetVideoOff = !isBroadcastingEnabled || (isBroadcastingEnabled && peer_info.peer_presenter);
|
||||
|
||||
if (!peer_info.peer_video && canSetVideoOff) {
|
||||
console.log('Detected peer video off ' + peer_info.peer_name);
|
||||
await this.setVideoOff(peer_info, true);
|
||||
}
|
||||
|
||||
if (peer_info.peer_recording) {
|
||||
this.handleRecordingAction({
|
||||
peer_id: peer_info.id,
|
||||
@@ -419,8 +434,11 @@ class RoomClient {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.refreshParticipantsCount();
|
||||
|
||||
console.log('07.2 Participants Count ---->', participantsCount);
|
||||
|
||||
// notify && participantsCount == 1 ? shareRoom() : sound('joined');
|
||||
if (notify && participantsCount == 1) {
|
||||
shareRoom();
|
||||
@@ -605,7 +623,7 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'consumerClosed',
|
||||
function ({ consumer_id, consumer_kind }) {
|
||||
console.log('Closing consumer', { consumer_id: consumer_id, consumer_kind: consumer_kind });
|
||||
console.log('SocketOn Closing consumer', { consumer_id: consumer_id, consumer_kind: consumer_kind });
|
||||
this.removeConsumer(consumer_id, consumer_kind);
|
||||
}.bind(this),
|
||||
);
|
||||
@@ -613,19 +631,24 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'setVideoOff',
|
||||
function (data) {
|
||||
console.log('Video off:', data);
|
||||
this.setVideoOff(data, true);
|
||||
if (!isBroadcastingEnabled || (isBroadcastingEnabled && data.peer_presenter)) {
|
||||
console.log('SocketOn setVideoOff', {
|
||||
peer_name: data.peer_name,
|
||||
peer_presenter: data.peer_presenter,
|
||||
});
|
||||
this.setVideoOff(data, true);
|
||||
}
|
||||
}.bind(this),
|
||||
);
|
||||
|
||||
this.socket.on(
|
||||
'removeMe',
|
||||
function (data) {
|
||||
console.log('Remove me:', data);
|
||||
console.log('SocketOn Remove me:', data);
|
||||
this.removeVideoOff(data.peer_id);
|
||||
this.lobbyRemoveMe(data.peer_id);
|
||||
participantsCount = data.peer_counts;
|
||||
adaptAspectRatio(participantsCount);
|
||||
if (!isBroadcastingEnabled) adaptAspectRatio(participantsCount);
|
||||
if (isParticipantsListOpen) getRoomParticipants();
|
||||
}.bind(this),
|
||||
);
|
||||
@@ -633,9 +656,14 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'refreshParticipantsCount',
|
||||
function (data) {
|
||||
console.log('Participants Count:', data);
|
||||
console.log('SocketOn Participants Count:', data);
|
||||
participantsCount = data.peer_counts;
|
||||
adaptAspectRatio(participantsCount);
|
||||
if (isBroadcastingEnabled) {
|
||||
if (isParticipantsListOpen) getRoomParticipants();
|
||||
wbUpdate();
|
||||
} else {
|
||||
adaptAspectRatio(participantsCount);
|
||||
}
|
||||
}.bind(this),
|
||||
);
|
||||
|
||||
@@ -643,7 +671,7 @@ class RoomClient {
|
||||
'newProducers',
|
||||
async function (data) {
|
||||
if (data.length > 0) {
|
||||
console.log('New producers', data);
|
||||
console.log('SocketOn New producers', data);
|
||||
for (let { producer_id, peer_name, peer_info, type } of data) {
|
||||
await this.consume(producer_id, peer_name, peer_info, type);
|
||||
}
|
||||
@@ -654,7 +682,7 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'message',
|
||||
function (data) {
|
||||
console.log('New message:', data);
|
||||
console.log('SocketOn New message:', data);
|
||||
this.showMessage(data);
|
||||
}.bind(this),
|
||||
);
|
||||
@@ -662,7 +690,7 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'roomAction',
|
||||
function (data) {
|
||||
console.log('Room action:', data);
|
||||
console.log('SocketOn Room action:', data);
|
||||
this.roomAction(data, false);
|
||||
}.bind(this),
|
||||
);
|
||||
@@ -670,7 +698,7 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'roomPassword',
|
||||
function (data) {
|
||||
console.log('Room password:', data.password);
|
||||
console.log('SocketOn Room password:', data.password);
|
||||
this.roomPassword(data);
|
||||
}.bind(this),
|
||||
);
|
||||
@@ -678,7 +706,7 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'roomLobby',
|
||||
function (data) {
|
||||
console.log('Room lobby:', data);
|
||||
console.log('SocketOn Room lobby:', data);
|
||||
this.roomLobby(data);
|
||||
}.bind(this),
|
||||
);
|
||||
@@ -686,7 +714,7 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'cmd',
|
||||
function (data) {
|
||||
console.log('Peer cmd:', data);
|
||||
console.log('SocketOn Peer cmd:', data);
|
||||
this.handleCmd(data);
|
||||
}.bind(this),
|
||||
);
|
||||
@@ -694,7 +722,7 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'peerAction',
|
||||
function (data) {
|
||||
console.log('Peer action:', data);
|
||||
console.log('SocketOn Peer action:', data);
|
||||
this.peerAction(data.from_peer_name, data.peer_id, data.action, false, data.broadcast);
|
||||
}.bind(this),
|
||||
);
|
||||
@@ -702,15 +730,15 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'updatePeerInfo',
|
||||
function (data) {
|
||||
console.log('Peer info update:', data);
|
||||
this.updatePeerInfo(data.peer_name, data.peer_id, data.type, data.status, false);
|
||||
console.log('SocketOn Peer info update:', data);
|
||||
this.updatePeerInfo(data.peer_name, data.peer_id, data.type, data.status, false, data.peer_presenter);
|
||||
}.bind(this),
|
||||
);
|
||||
|
||||
this.socket.on(
|
||||
'fileInfo',
|
||||
function (data) {
|
||||
console.log('File info:', data);
|
||||
console.log('SocketOn File info:', data);
|
||||
this.handleFileInfo(data);
|
||||
}.bind(this),
|
||||
);
|
||||
@@ -739,7 +767,7 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'wbCanvasToJson',
|
||||
function (data) {
|
||||
console.log('Received whiteboard canvas JSON');
|
||||
console.log('SocketOn Received whiteboard canvas JSON');
|
||||
JsonToWbCanvas(data);
|
||||
}.bind(this),
|
||||
);
|
||||
@@ -762,15 +790,23 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'updateRoomModerator',
|
||||
function (data) {
|
||||
console.log('Update room moderator', data);
|
||||
console.log('SocketOn Update room moderator', data);
|
||||
this.handleUpdateRoomModerator(data);
|
||||
}.bind(this),
|
||||
);
|
||||
|
||||
this.socket.on(
|
||||
'updateRoomModeratorALL',
|
||||
function (data) {
|
||||
console.log('SocketOn Update room moderator ALL', data);
|
||||
this.handleUpdateRoomModeratorALL(data);
|
||||
}.bind(this),
|
||||
);
|
||||
|
||||
this.socket.on(
|
||||
'recordingAction',
|
||||
function (data) {
|
||||
console.log('Recording action:', data);
|
||||
console.log('SocketOn Recording action:', data);
|
||||
this.handleRecordingAction(data);
|
||||
}.bind(this),
|
||||
);
|
||||
@@ -778,7 +814,7 @@ class RoomClient {
|
||||
this.socket.on(
|
||||
'connect',
|
||||
function () {
|
||||
console.log('Connected to signaling server!');
|
||||
console.log('SocketOn Connected to signaling server!');
|
||||
this._isConnected = true;
|
||||
// location.reload();
|
||||
getPeerName() ? location.reload() : openURL(this.getReconnectDirectJoinURL());
|
||||
@@ -849,6 +885,34 @@ class RoomClient {
|
||||
});
|
||||
}
|
||||
|
||||
// ####################################################
|
||||
// HANDLE ROOM BROADCASTING
|
||||
// ####################################################
|
||||
|
||||
async handleRoomBroadcasting() {
|
||||
console.log('07.4 ----> Room Broadcasting is currently active, and you are not the designated presenter');
|
||||
|
||||
this.peer_info.peer_audio = false;
|
||||
this.peer_info.peer_video = false;
|
||||
this.peer_info.peer_screen = false;
|
||||
|
||||
const mediaTypes = ['audio', 'video', 'screen'];
|
||||
|
||||
mediaTypes.forEach((type) => {
|
||||
const data = {
|
||||
peer_name: this.peer_name,
|
||||
peer_id: this.peer_id,
|
||||
peer_presenter: isPresenter,
|
||||
type: type,
|
||||
status: false,
|
||||
broadcast: true,
|
||||
};
|
||||
this.socket.emit('updatePeerInfo', data);
|
||||
});
|
||||
|
||||
handleRulesBroadcasting();
|
||||
}
|
||||
|
||||
// ####################################################
|
||||
// START LOCAL AUDIO VIDEO MEDIA
|
||||
// ####################################################
|
||||
@@ -1077,7 +1141,7 @@ class RoomClient {
|
||||
this.event(_EVENTS.startScreen);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
this.sound('joined');
|
||||
} catch (err) {
|
||||
@@ -1682,7 +1746,7 @@ class RoomClient {
|
||||
this.event(_EVENTS.stopScreen);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
this.sound('left');
|
||||
@@ -1749,7 +1813,7 @@ class RoomClient {
|
||||
wbUpdate();
|
||||
|
||||
this.getConsumeStream(producer_id, peer_info.peer_id, type).then(
|
||||
function ({ consumer, stream, kind }) {
|
||||
async function ({ consumer, stream, kind }) {
|
||||
console.log('CONSUMER MEDIA TYPE ----> ' + type);
|
||||
console.log('CONSUMER', consumer);
|
||||
|
||||
@@ -1814,12 +1878,12 @@ class RoomClient {
|
||||
|
||||
let remotePeerId = peer_info.peer_id;
|
||||
let remoteIsScreen = type == mediaType.screen;
|
||||
let remotePeerAudio = peer_info.peer_audio;
|
||||
let remotePrivacyOn = peer_info.peer_video_privacy;
|
||||
|
||||
switch (type) {
|
||||
case mediaType.video:
|
||||
case mediaType.screen:
|
||||
let remotePeerAudio = peer_info.peer_audio;
|
||||
this.removeVideoOff(remotePeerId);
|
||||
d = document.createElement('div');
|
||||
d.className = 'Camera';
|
||||
@@ -1939,6 +2003,7 @@ class RoomClient {
|
||||
this.setTippy(pv.id, '🔊 Volume', 'bottom');
|
||||
this.setTippy(ko.id, 'Eject', 'bottom');
|
||||
}
|
||||
this.setPeerAudio(remotePeerId, remotePeerAudio);
|
||||
break;
|
||||
case mediaType.audio:
|
||||
elem = document.createElement('audio');
|
||||
@@ -1952,6 +2017,7 @@ class RoomClient {
|
||||
let inputPv = this.getId(audioConsumerId);
|
||||
if (inputPv) {
|
||||
this.handlePV(id + '___' + audioConsumerId);
|
||||
this.setPeerAudio(remotePeerId, remotePeerAudio);
|
||||
}
|
||||
console.log('[Add audioConsumers]', this.audioConsumers);
|
||||
break;
|
||||
@@ -2016,6 +2082,7 @@ class RoomClient {
|
||||
// ####################################################
|
||||
|
||||
async setVideoOff(peer_info, remotePeer = false) {
|
||||
//console.log('setVideoOff', peer_info);
|
||||
let d, vb, i, h, au, sf, sm, sv, ko, p, pm, pb, pv;
|
||||
let peer_id = peer_info.peer_id;
|
||||
let peer_name = peer_info.peer_name;
|
||||
@@ -2104,6 +2171,8 @@ class RoomClient {
|
||||
this.setTippy(pv.id, '🔊 Volume', 'bottom');
|
||||
this.setTippy(ko.id, 'Eject', 'bottom');
|
||||
}
|
||||
remotePeer ? this.setPeerAudio(peer_id, peer_audio) : this.setIsAudio(peer_id, peer_audio);
|
||||
|
||||
console.log('[setVideoOff] Video-element-count', this.videoMediaContainer.childElementCount);
|
||||
//
|
||||
wbUpdate();
|
||||
@@ -2315,25 +2384,44 @@ class RoomClient {
|
||||
return 'data:image/svg+xml,' + svg.replace(/#/g, '%23').replace(/"/g, "'").replace(/&/g, '&');
|
||||
}
|
||||
|
||||
setPeerAudio(peer_id, status) {
|
||||
if (!isBroadcastingEnabled || (isBroadcastingEnabled && isPresenter)) {
|
||||
console.log('Set peer audio enabled: ' + status);
|
||||
const audioStatus = this.getPeerAudioBtn(peer_id); // producer, consumers
|
||||
const audioVolume = this.getPeerAudioVolumeBtn(peer_id); // consumers
|
||||
if (audioStatus) audioStatus.className = status ? html.audioOn : html.audioOff;
|
||||
if (audioVolume) status ? show(audioVolume) : hide(audioVolume);
|
||||
}
|
||||
}
|
||||
|
||||
setIsAudio(peer_id, status) {
|
||||
this.peer_info.peer_audio = status;
|
||||
let b = this.getPeerAudioBtn(peer_id);
|
||||
if (b) b.className = this.peer_info.peer_audio ? html.audioOn : html.audioOff;
|
||||
if (!isBroadcastingEnabled || (isBroadcastingEnabled && isPresenter)) {
|
||||
console.log('Set audio enabled: ' + status);
|
||||
this.peer_info.peer_audio = status;
|
||||
const audioStatus = this.getPeerAudioBtn(peer_id); // producer, consumers
|
||||
if (audioStatus) audioStatus.className = status ? html.audioOn : html.audioOff;
|
||||
}
|
||||
}
|
||||
|
||||
setIsVideo(status) {
|
||||
this.peer_info.peer_video = status;
|
||||
if (!this.peer_info.peer_video) {
|
||||
this.setVideoOff(this.peer_info, false);
|
||||
this.sendVideoOff();
|
||||
if (!isBroadcastingEnabled || (isBroadcastingEnabled && isPresenter)) {
|
||||
this.peer_info.peer_video = status;
|
||||
if (!this.peer_info.peer_video) {
|
||||
console.log('Set video enabled: ' + status);
|
||||
this.setVideoOff(this.peer_info, false);
|
||||
this.sendVideoOff();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setIsScreen(status) {
|
||||
this.peer_info.peer_screen = status;
|
||||
if (!this.peer_info.peer_screen && !this.peer_info.peer_video) {
|
||||
this.setVideoOff(this.peer_info, false);
|
||||
this.sendVideoOff();
|
||||
if (!isBroadcastingEnabled || (isBroadcastingEnabled && isPresenter)) {
|
||||
this.peer_info.peer_screen = status;
|
||||
if (!this.peer_info.peer_screen && !this.peer_info.peer_video) {
|
||||
console.log('Set screen enabled: ' + status);
|
||||
this.setVideoOff(this.peer_info, false);
|
||||
this.sendVideoOff();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2394,6 +2482,10 @@ class RoomClient {
|
||||
return this.getId(peer_id + '__audio');
|
||||
}
|
||||
|
||||
getPeerAudioVolumeBtn(peer_id) {
|
||||
return this.getId(peer_id + '___pVolume');
|
||||
}
|
||||
|
||||
getPeerHandBtn(peer_id) {
|
||||
return this.getId(peer_id + '__hand');
|
||||
}
|
||||
@@ -4462,7 +4554,8 @@ class RoomClient {
|
||||
// ####################################################
|
||||
|
||||
roomAction(action, emit = true, popup = true) {
|
||||
let data = {
|
||||
const data = {
|
||||
room_broadcasting: isBroadcastingEnabled,
|
||||
room_id: this.room_id,
|
||||
peer_id: this.peer_id,
|
||||
peer_name: this.peer_name,
|
||||
@@ -4472,6 +4565,10 @@ class RoomClient {
|
||||
};
|
||||
if (emit) {
|
||||
switch (action) {
|
||||
case 'broadcasting':
|
||||
this.socket.emit('roomAction', data);
|
||||
if (popup) this.roomStatus(action);
|
||||
break;
|
||||
case 'lock':
|
||||
if (room_password) {
|
||||
this.socket
|
||||
@@ -4481,10 +4578,11 @@ class RoomClient {
|
||||
// Only the presenter can lock the room
|
||||
if (isPresenter || res.peerCounts == 1) {
|
||||
isPresenter = true;
|
||||
this.peer_info.peer_presenter = isPresenter;
|
||||
this.getId('isUserPresenter').innerText = isPresenter;
|
||||
data.password = room_password;
|
||||
this.socket.emit('roomAction', data);
|
||||
this.roomStatus(action);
|
||||
if (popup) this.roomStatus(action);
|
||||
}
|
||||
}.bind(this),
|
||||
)
|
||||
@@ -4519,7 +4617,7 @@ class RoomClient {
|
||||
break;
|
||||
case 'unlock':
|
||||
this.socket.emit('roomAction', data);
|
||||
this.roomStatus(action);
|
||||
if (popup) this.roomStatus(action);
|
||||
break;
|
||||
case 'lobbyOn':
|
||||
this.socket.emit('roomAction', data);
|
||||
@@ -4547,6 +4645,9 @@ class RoomClient {
|
||||
|
||||
roomStatus(action) {
|
||||
switch (action) {
|
||||
case 'broadcasting':
|
||||
this.userLog('info', `${icons.room} BROADCASTING ${isBroadcastingEnabled ? 'On' : 'Off'}`, 'top-end');
|
||||
break;
|
||||
case 'lock':
|
||||
this.sound('locked');
|
||||
this.event(_EVENTS.roomLock);
|
||||
@@ -4666,7 +4767,7 @@ class RoomClient {
|
||||
// ROOM LOBBY
|
||||
// ####################################################
|
||||
|
||||
roomLobby(data) {
|
||||
async roomLobby(data) {
|
||||
console.log('LOBBY--->', data);
|
||||
switch (data.lobby_status) {
|
||||
case 'waiting':
|
||||
@@ -4702,7 +4803,7 @@ class RoomClient {
|
||||
}
|
||||
break;
|
||||
case 'accept':
|
||||
this.joinAllowed(data.room);
|
||||
await this.joinAllowed(data.room);
|
||||
control.style.display = 'flex';
|
||||
this.msgPopup('info', 'Your join meeting was be accepted by moderator');
|
||||
break;
|
||||
@@ -5464,10 +5565,26 @@ class RoomClient {
|
||||
|
||||
updateRoomModerator(data) {
|
||||
if (!isRulesActive || isPresenter) {
|
||||
this.socket.emit('updateRoomModerator', data);
|
||||
const moderator = this.getModeratorData(data);
|
||||
this.socket.emit('updateRoomModerator', moderator);
|
||||
}
|
||||
}
|
||||
|
||||
updateRoomModeratorALL(data) {
|
||||
if (!isRulesActive || isPresenter) {
|
||||
const moderator = this.getModeratorData(data);
|
||||
this.socket.emit('updateRoomModeratorALL', moderator);
|
||||
}
|
||||
}
|
||||
|
||||
getModeratorData(data) {
|
||||
return {
|
||||
peer_name: this.peer_name,
|
||||
peer_uuid: this.peer_uuid,
|
||||
moderator: data,
|
||||
};
|
||||
}
|
||||
|
||||
handleUpdateRoomModerator(data) {
|
||||
switch (data.type) {
|
||||
case 'audio_cant_unmute':
|
||||
@@ -5488,6 +5605,11 @@ class RoomClient {
|
||||
}
|
||||
}
|
||||
|
||||
handleUpdateRoomModeratorALL(data) {
|
||||
this._moderator = data;
|
||||
console.log('Update Room Moderator data all', this._moderator);
|
||||
}
|
||||
|
||||
getModerator() {
|
||||
console.log('Get Moderator', this._moderator);
|
||||
return this._moderator;
|
||||
@@ -5497,7 +5619,7 @@ class RoomClient {
|
||||
// UPDATE PEER INFO
|
||||
// ####################################################
|
||||
|
||||
updatePeerInfo(peer_name, peer_id, type, status, emit = true) {
|
||||
updatePeerInfo(peer_name, peer_id, type, status, emit = true, presenter = false) {
|
||||
if (emit) {
|
||||
switch (type) {
|
||||
case 'audio':
|
||||
@@ -5524,23 +5646,23 @@ class RoomClient {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
let data = {
|
||||
const data = {
|
||||
peer_name: peer_name,
|
||||
peer_id: peer_id,
|
||||
type: type,
|
||||
status: status,
|
||||
broadcast: true,
|
||||
};
|
||||
this.socket.emit('updatePeerInfo', data);
|
||||
} else {
|
||||
const canUpdateMediaStatus = !isBroadcastingEnabled || (isBroadcastingEnabled && presenter);
|
||||
switch (type) {
|
||||
case 'audio':
|
||||
this.setIsAudio(peer_id, status);
|
||||
if (canUpdateMediaStatus) this.setPeerAudio(peer_id, status);
|
||||
break;
|
||||
case 'video':
|
||||
this.setIsVideo(status);
|
||||
break;
|
||||
case 'screen':
|
||||
this.setIsScreen(status);
|
||||
break;
|
||||
case 'hand':
|
||||
let peer_hand = this.getPeerHandBtn(peer_id);
|
||||
|
||||
@@ -28,6 +28,7 @@ const BUTTONS = {
|
||||
settings: {
|
||||
lockRoomButton: true, // presenter
|
||||
unlockRoomButton: true, // presenter
|
||||
broadcastingButton: true, // presenter
|
||||
lobbyButton: true, // presenter
|
||||
micOptionsButton: true, // presenter
|
||||
tabModerator: true, // presenter
|
||||
@@ -80,7 +81,7 @@ const BUTTONS = {
|
||||
};
|
||||
|
||||
function handleRules(isPresenter) {
|
||||
console.log('06.1 ----> IsPresenter: ' + isPresenter);
|
||||
console.log('07.1 ----> IsPresenter: ' + isPresenter);
|
||||
if (!isRulesActive) return;
|
||||
if (!isPresenter) {
|
||||
// ##################################
|
||||
@@ -89,6 +90,7 @@ function handleRules(isPresenter) {
|
||||
BUTTONS.participantsList.saveInfoButton = false;
|
||||
BUTTONS.settings.lockRoomButton = false;
|
||||
BUTTONS.settings.unlockRoomButton = false;
|
||||
BUTTONS.settings.broadcastingButton = false;
|
||||
BUTTONS.settings.lobbyButton = false;
|
||||
BUTTONS.settings.micOptionsButton = false;
|
||||
BUTTONS.settings.tabModerator = false;
|
||||
@@ -106,6 +108,7 @@ function handleRules(isPresenter) {
|
||||
BUTTONS.participantsList.saveInfoButton = true;
|
||||
BUTTONS.settings.lockRoomButton = !isRoomLocked;
|
||||
BUTTONS.settings.unlockRoomButton = isRoomLocked;
|
||||
BUTTONS.settings.broadcastingButton = true;
|
||||
BUTTONS.settings.lobbyButton = true;
|
||||
BUTTONS.settings.micOptionsButton = true;
|
||||
BUTTONS.settings.tabModerator = true;
|
||||
@@ -121,6 +124,10 @@ function handleRules(isPresenter) {
|
||||
// Auto detected rules for presenter
|
||||
// ##################################
|
||||
|
||||
// Room broadcasting
|
||||
isBroadcastingEnabled = lsSettings.broadcasting;
|
||||
switchBroadcasting.checked = isBroadcastingEnabled;
|
||||
rc.roomAction('broadcasting', true, false);
|
||||
// Room lobby
|
||||
isLobbyEnabled = lsSettings.lobby;
|
||||
switchLobby.checked = isLobbyEnabled;
|
||||
@@ -135,15 +142,20 @@ function handleRules(isPresenter) {
|
||||
switchEveryoneCantUnmute.checked = lsSettings.moderator_audio_cant_unmute;
|
||||
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 });
|
||||
// Update moderator settings...
|
||||
const moderatorData = {
|
||||
audio_start_muted: switchEveryoneMute.checked,
|
||||
video_start_hidden: switchEveryoneHidden.checked,
|
||||
audio_cant_unmute: switchEveryoneCantUnmute.checked,
|
||||
video_cant_unhide: switchEveryoneCantUnhide.checked,
|
||||
screen_cant_share: switchEveryoneCantShareScreen.checked,
|
||||
};
|
||||
rc.updateRoomModeratorALL(moderatorData);
|
||||
}
|
||||
// main. settings...
|
||||
BUTTONS.settings.lockRoomButton ? show(lockRoomButton) : hide(lockRoomButton);
|
||||
BUTTONS.settings.unlockRoomButton ? show(unlockRoomButton) : hide(unlockRoomButton);
|
||||
BUTTONS.settings.broadcastingButton ? show(broadcastingButton) : hide(broadcastingButton);
|
||||
BUTTONS.settings.lobbyButton ? show(lobbyButton) : hide(lobbyButton);
|
||||
!BUTTONS.settings.micOptionsButton && hide(micOptionsButton);
|
||||
!BUTTONS.settings.tabModerator && hide(tabModeratorBtn);
|
||||
@@ -153,3 +165,50 @@ function handleRules(isPresenter) {
|
||||
: elemDisplay('whiteboardLockButton', false, 'flex');
|
||||
//...
|
||||
}
|
||||
|
||||
function handleRulesBroadcasting() {
|
||||
console.log('07.2 ----> handleRulesBroadcasting');
|
||||
BUTTONS.main.shareButton = false;
|
||||
BUTTONS.main.hideMeButton = false;
|
||||
BUTTONS.main.startAudioButton = false;
|
||||
BUTTONS.main.startVideoButton = false;
|
||||
BUTTONS.main.startScreenButton = false;
|
||||
BUTTONS.main.swapCameraButton = false;
|
||||
BUTTONS.main.raiseHandButton = false;
|
||||
BUTTONS.main.whiteboardButton = false;
|
||||
//BUTTONS.main.emojiRoomButton = false,
|
||||
BUTTONS.main.transcriptionButton = false;
|
||||
BUTTONS.main.settingsButton = false;
|
||||
BUTTONS.participantsList.saveInfoButton = false;
|
||||
BUTTONS.settings.lockRoomButton = false;
|
||||
BUTTONS.settings.unlockRoomButton = false;
|
||||
BUTTONS.settings.lobbyButton = false;
|
||||
BUTTONS.videoOff.muteAudioButton = false;
|
||||
BUTTONS.videoOff.ejectButton = false;
|
||||
BUTTONS.consumerVideo.sendMessageButton = false;
|
||||
BUTTONS.consumerVideo.sendFileButton = false;
|
||||
BUTTONS.consumerVideo.sendVideoButton = false;
|
||||
BUTTONS.consumerVideo.ejectButton = false;
|
||||
BUTTONS.consumerVideo.muteAudioButton = false;
|
||||
BUTTONS.consumerVideo.muteVideoButton = false;
|
||||
BUTTONS.whiteboard.whiteboardLockButton = false;
|
||||
//...
|
||||
elemDisplay('shareButton', false);
|
||||
elemDisplay('hideMeButton', false);
|
||||
elemDisplay('startAudioButton', false);
|
||||
elemDisplay('stopAudioButton', false);
|
||||
elemDisplay('startVideoButton', false);
|
||||
elemDisplay('stopVideoButton', false);
|
||||
elemDisplay('startScreenButton', false);
|
||||
elemDisplay('stopScreenButton', false);
|
||||
elemDisplay('swapCameraButton', false);
|
||||
elemDisplay('raiseHandButton', false);
|
||||
elemDisplay('whiteboardButton', false);
|
||||
//elemDisplay('emojiRoomButton', false);
|
||||
elemDisplay('transcriptionButton', false);
|
||||
elemDisplay('lockRoomButton', false);
|
||||
elemDisplay('unlockRoomButton', false);
|
||||
elemDisplay('lobbyButton', false);
|
||||
elemDisplay('settingsButton', false);
|
||||
//...
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ access to use this app.
|
||||
<button id="stopRecButton" style="color: red" class="hidden"><i class="fas fa-record-vinyl"></i></button>
|
||||
<button id="raiseHandButton" class="hidden"><i class="fas fa-hand-paper"></i></button>
|
||||
<button id="lowerHandButton" class="hidden"><i id="lowerHandIcon" class="fas fa-hand-paper"></i></button>
|
||||
<button id="roomEmojiPicker" class="hidden"><i class="fas fa-face-smile"></i></button>
|
||||
<button id="emojiRoomButton" class="hidden"><i class="fas fa-face-smile"></i></button>
|
||||
<button id="chatButton" class="hidden"><i class="fas fa-comments"></i></button>
|
||||
<button id="transcriptionButton" class="hidden"><i class="fas fa-closed-captioning"></i></button>
|
||||
<button id="whiteboardButton" class="hidden"><i class="fas fa-chalkboard-teacher"></i></button>
|
||||
@@ -230,6 +230,19 @@ access to use this app.
|
||||
</button>
|
||||
<hr style="border: 1px solid grey" />
|
||||
<table class="settingsTable">
|
||||
<tr id="broadcastingButton" class="hidden">
|
||||
<td class="custom-width">
|
||||
<div class="title">
|
||||
<i class="fa-solid fa-wifi"></i>
|
||||
<p>Broadcast</p>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-check form-switch form-switch-md title">
|
||||
<input id="switchBroadcasting" class="form-check-input" type="checkbox" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="lobbyButton" class="hidden">
|
||||
<td class="custom-width">
|
||||
<div class="title">
|
||||
|
||||
المرجع في مشكلة جديدة
حظر مستخدم