[mirotalksfu] - added raise hand & turn-off audio-video
هذا الالتزام موجود في:
@@ -116,6 +116,8 @@ access to use this app.
|
|||||||
<button id="chatButton" class="hidden"><i class="fas fa-comments"></i> Chat</button>
|
<button id="chatButton" class="hidden"><i class="fas fa-comments"></i> Chat</button>
|
||||||
<button id="fullScreenButton" class="hidden"><i class="fas fa-expand-alt"></i> Full screen</button>
|
<button id="fullScreenButton" class="hidden"><i class="fas fa-expand-alt"></i> Full screen</button>
|
||||||
<button id="swapCameraButton" class="hidden"><i class="fas fa-sync-alt"></i> Swap Cam</button>
|
<button id="swapCameraButton" class="hidden"><i class="fas fa-sync-alt"></i> Swap Cam</button>
|
||||||
|
<button id="raiseHandButton" class="hidden"><i class="fas fa-hand-rock"></i> Raise hand</button>
|
||||||
|
<button id="lowerHandButton" class="hidden"><i class="fas fa-hand-paper"></i> Lower hand</button>
|
||||||
<button id="startAudioButton" class="hidden"><i class="fas fa-microphone-slash"></i> Start audio</button>
|
<button id="startAudioButton" class="hidden"><i class="fas fa-microphone-slash"></i> Start audio</button>
|
||||||
<button id="stopAudioButton" class="hidden"><i class="fas fa-microphone"></i> Stop audio</button>
|
<button id="stopAudioButton" class="hidden"><i class="fas fa-microphone"></i> Stop audio</button>
|
||||||
<button id="startVideoButton" class="hidden"><i class="fas fa-video-slash"></i> Start video</button>
|
<button id="startVideoButton" class="hidden"><i class="fas fa-video-slash"></i> Start video</button>
|
||||||
|
|||||||
@@ -532,16 +532,6 @@ button:hover {
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#roomParticipants button {
|
|
||||||
background: transparent;
|
|
||||||
color: red;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
#roomParticipants button:hover {
|
|
||||||
color: white;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#roomParticipants table {
|
#roomParticipants table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
ثنائية
public/images/hide.png
Normal file
ثنائية
public/images/hide.png
Normal file
ملف ثنائي غير معروض.
|
بعد العرض: | الارتفاع: | الحجم: 1.8 KiB |
ثنائية
public/images/mute.png
Normal file
ثنائية
public/images/mute.png
Normal file
ملف ثنائي غير معروض.
|
بعد العرض: | الارتفاع: | الحجم: 3.6 KiB |
@@ -4,6 +4,16 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h
|
|||||||
|
|
||||||
const RoomURL = window.location.href;
|
const RoomURL = window.location.href;
|
||||||
|
|
||||||
|
const _PEER = {
|
||||||
|
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>',
|
||||||
|
videoOff: '<i style="color: red;" class="fas fa-video-slash"></i>',
|
||||||
|
raiseHand: '<i style="color: rgb(0, 180, 50);" class="fas fa-hand-paper pulsate"></i>',
|
||||||
|
lowerHand: '',
|
||||||
|
ejectPeer: '<i class="fas fa-times"></i>',
|
||||||
|
};
|
||||||
|
|
||||||
const swalBackground = 'linear-gradient(to left, #1f1e1e, #000000)';
|
const swalBackground = 'linear-gradient(to left, #1f1e1e, #000000)';
|
||||||
const swalImageUrl = '../images/pricing-illustration.svg';
|
const swalImageUrl = '../images/pricing-illustration.svg';
|
||||||
|
|
||||||
@@ -174,6 +184,7 @@ function getPeerInfo() {
|
|||||||
peer_name: peer_name,
|
peer_name: peer_name,
|
||||||
peer_audio: isAudioOn,
|
peer_audio: isAudioOn,
|
||||||
peer_video: isVideoOn,
|
peer_video: isVideoOn,
|
||||||
|
peer_hand: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,6 +400,7 @@ function roomIsReady() {
|
|||||||
show(fullScreenButton);
|
show(fullScreenButton);
|
||||||
}
|
}
|
||||||
show(settingsButton);
|
show(settingsButton);
|
||||||
|
show(raiseHandButton);
|
||||||
if (isAudioAllowed) show(startAudioButton);
|
if (isAudioAllowed) show(startAudioButton);
|
||||||
if (isVideoAllowed) show(startVideoButton);
|
if (isVideoAllowed) show(startVideoButton);
|
||||||
show(participantsButton);
|
show(participantsButton);
|
||||||
@@ -534,6 +546,12 @@ function handleButtons() {
|
|||||||
swapCameraButton.onclick = () => {
|
swapCameraButton.onclick = () => {
|
||||||
rc.closeThenProduce(RoomClient.mediaType.video, null, true);
|
rc.closeThenProduce(RoomClient.mediaType.video, null, true);
|
||||||
};
|
};
|
||||||
|
raiseHandButton.onclick = () => {
|
||||||
|
rc.updatePeerInfo(peer_name, rc.peer_id, 'hand', true);
|
||||||
|
};
|
||||||
|
lowerHandButton.onclick = () => {
|
||||||
|
rc.updatePeerInfo(peer_name, rc.peer_id, 'hand', false);
|
||||||
|
};
|
||||||
startAudioButton.onclick = () => {
|
startAudioButton.onclick = () => {
|
||||||
rc.produce(RoomClient.mediaType.audio, microphoneSelect.value);
|
rc.produce(RoomClient.mediaType.audio, microphoneSelect.value);
|
||||||
// rc.resumeProducer(RoomClient.mediaType.audio);
|
// rc.resumeProducer(RoomClient.mediaType.audio);
|
||||||
@@ -633,6 +651,17 @@ function handleRoomClientEvents() {
|
|||||||
show(startRecButton);
|
show(startRecButton);
|
||||||
stopRecordingTimer();
|
stopRecordingTimer();
|
||||||
});
|
});
|
||||||
|
rc.on(RoomClient.EVENTS.raiseHand, () => {
|
||||||
|
console.log('Room Client raise hand');
|
||||||
|
hide(raiseHandButton);
|
||||||
|
show(lowerHandButton);
|
||||||
|
setColor(lowerHandButton, 'green');
|
||||||
|
});
|
||||||
|
rc.on(RoomClient.EVENTS.lowerHand, () => {
|
||||||
|
console.log('Room Client lower hand');
|
||||||
|
hide(lowerHandButton);
|
||||||
|
show(raiseHandButton);
|
||||||
|
});
|
||||||
rc.on(RoomClient.EVENTS.startAudio, () => {
|
rc.on(RoomClient.EVENTS.startAudio, () => {
|
||||||
console.log('Room Client start audio');
|
console.log('Room Client start audio');
|
||||||
hide(startAudioButton);
|
hide(startAudioButton);
|
||||||
@@ -720,13 +749,13 @@ function closeNav() {
|
|||||||
// SHOW LOG
|
// SHOW LOG
|
||||||
// ####################################################
|
// ####################################################
|
||||||
|
|
||||||
function userLog(icon, message, position) {
|
function userLog(icon, message, position, timer = 3000) {
|
||||||
const Toast = Swal.mixin({
|
const Toast = Swal.mixin({
|
||||||
background: swalBackground,
|
background: swalBackground,
|
||||||
toast: true,
|
toast: true,
|
||||||
position: position,
|
position: position,
|
||||||
showConfirmButton: false,
|
showConfirmButton: false,
|
||||||
timer: 3000,
|
timer: timer,
|
||||||
});
|
});
|
||||||
Toast.fire({
|
Toast.fire({
|
||||||
icon: icon,
|
icon: icon,
|
||||||
@@ -755,26 +784,7 @@ async function sound(name) {
|
|||||||
async function getRoomParticipants() {
|
async function getRoomParticipants() {
|
||||||
let room_info = await rc.getRoomInfo();
|
let room_info = await rc.getRoomInfo();
|
||||||
let peers = new Map(JSON.parse(room_info.peers));
|
let peers = new Map(JSON.parse(room_info.peers));
|
||||||
let table = `<div id="roomParticipants"><table>
|
let table = await getParticipantsTable(peers);
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
<th></th>
|
|
||||||
</tr>`;
|
|
||||||
for (let peer of Array.from(peers.keys())) {
|
|
||||||
let peer_info = peers.get(peer).peer_info;
|
|
||||||
let peer_name = peer_info.peer_name;
|
|
||||||
let peer_id = peer_info.peer_id;
|
|
||||||
rc.peer_id === peer_id
|
|
||||||
? (table += `<tr>
|
|
||||||
<td>👤 ${peer_name} (me)</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>`)
|
|
||||||
: (table += `<tr id='${peer_id}'>
|
|
||||||
<td>👤 ${peer_name}</td>
|
|
||||||
<td><button id='${peer_id}' onclick="rc.peerAction('me',this.id,'eject')">eject</button></td>
|
|
||||||
</tr>`);
|
|
||||||
}
|
|
||||||
table += `</table></div>`;
|
|
||||||
|
|
||||||
sound('open');
|
sound('open');
|
||||||
|
|
||||||
@@ -783,15 +793,66 @@ async function getRoomParticipants() {
|
|||||||
position: 'center',
|
position: 'center',
|
||||||
title: `Participants ${peers.size}`,
|
title: `Participants ${peers.size}`,
|
||||||
html: table,
|
html: table,
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: `Refresh`,
|
||||||
|
cancelButtonText: `Close`,
|
||||||
showClass: {
|
showClass: {
|
||||||
popup: 'animate__animated animate__fadeInDown',
|
popup: 'animate__animated animate__fadeInDown',
|
||||||
},
|
},
|
||||||
hideClass: {
|
hideClass: {
|
||||||
popup: 'animate__animated animate__fadeOutUp',
|
popup: 'animate__animated animate__fadeOutUp',
|
||||||
},
|
},
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
getRoomParticipants();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getParticipantsTable(peers) {
|
||||||
|
let table = `<div id="roomParticipants">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>`;
|
||||||
|
for (let peer of Array.from(peers.keys())) {
|
||||||
|
let peer_info = peers.get(peer).peer_info;
|
||||||
|
let peer_name = '👤 ' + peer_info.peer_name;
|
||||||
|
let peer_audio = peer_info.peer_audio ? _PEER.audioOn : _PEER.audioOff;
|
||||||
|
let peer_video = peer_info.peer_video ? _PEER.videoOn : _PEER.videoOff;
|
||||||
|
let peer_hand = peer_info.peer_hand ? _PEER.raiseHand : _PEER.lowerHand;
|
||||||
|
let peer_eject = _PEER.ejectPeer;
|
||||||
|
let peer_id = peer_info.peer_id;
|
||||||
|
if (rc.peer_id === peer_id) {
|
||||||
|
table += `
|
||||||
|
<tr>
|
||||||
|
<td>${peer_name} (me)</td>
|
||||||
|
<td><button>${peer_audio}</button></td>
|
||||||
|
<td><button>${peer_video}</button></td>
|
||||||
|
<td><button>${peer_hand}</button></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
table += `
|
||||||
|
<tr id='${peer_id}'>
|
||||||
|
<td>${peer_name}</td>
|
||||||
|
<td><button id='${peer_id}__audio' onclick="rc.peerAction('me',this.id,'mute')">${peer_audio}</button></td>
|
||||||
|
<td><button id='${peer_id}__video' onclick="rc.peerAction('me',this.id,'hide')">${peer_video}</button></td>
|
||||||
|
<td><button>${peer_hand}</button></td>
|
||||||
|
<td><button id='${peer_id}__eject' onclick="rc.peerAction('me',this.id,'eject')">${peer_eject}</button></td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
table += `</table></div>`;
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
// ####################################################
|
// ####################################################
|
||||||
// ABOUT
|
// ABOUT
|
||||||
// ####################################################
|
// ####################################################
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ const image = {
|
|||||||
poster: '../images/loader.gif',
|
poster: '../images/loader.gif',
|
||||||
delete: '../images/delete.png',
|
delete: '../images/delete.png',
|
||||||
locked: '../images/locked.png',
|
locked: '../images/locked.png',
|
||||||
|
mute: '../images/mute.png',
|
||||||
|
hide: '../images/hide.png',
|
||||||
};
|
};
|
||||||
|
|
||||||
const mediaType = {
|
const mediaType = {
|
||||||
@@ -28,6 +30,8 @@ const _EVENTS = {
|
|||||||
pauseRec: 'pauseRec',
|
pauseRec: 'pauseRec',
|
||||||
resumeRec: 'resumeRec',
|
resumeRec: 'resumeRec',
|
||||||
stopRec: 'stopRec',
|
stopRec: 'stopRec',
|
||||||
|
raiseHand: 'raiseHand',
|
||||||
|
lowerHand: 'lowerHand',
|
||||||
startVideo: 'startVideo',
|
startVideo: 'startVideo',
|
||||||
pauseVideo: 'pauseVideo',
|
pauseVideo: 'pauseVideo',
|
||||||
resumeVideo: 'resumeVideo',
|
resumeVideo: 'resumeVideo',
|
||||||
@@ -381,6 +385,14 @@ class RoomClient {
|
|||||||
}.bind(this),
|
}.bind(this),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}.bind(this),
|
||||||
|
);
|
||||||
|
|
||||||
this.socket.on(
|
this.socket.on(
|
||||||
'disconnect',
|
'disconnect',
|
||||||
function () {
|
function () {
|
||||||
@@ -606,7 +618,7 @@ class RoomClient {
|
|||||||
let elem, d, p;
|
let elem, d, p;
|
||||||
d = document.createElement('div');
|
d = document.createElement('div');
|
||||||
d.className = 'Camera';
|
d.className = 'Camera';
|
||||||
d.id = id + '_d';
|
d.id = id + '__d';
|
||||||
elem = document.createElement('video');
|
elem = document.createElement('video');
|
||||||
elem.setAttribute('id', id);
|
elem.setAttribute('id', id);
|
||||||
elem.setAttribute('playsinline', true);
|
elem.setAttribute('playsinline', true);
|
||||||
@@ -614,7 +626,7 @@ class RoomClient {
|
|||||||
elem.poster = image.poster;
|
elem.poster = image.poster;
|
||||||
this.isMobileDevice || type === mediaType.screen ? (elem.className = '') : (elem.className = 'mirror');
|
this.isMobileDevice || type === mediaType.screen ? (elem.className = '') : (elem.className = 'mirror');
|
||||||
p = document.createElement('p');
|
p = document.createElement('p');
|
||||||
p.id = id + '_name';
|
p.id = id + '__name';
|
||||||
p.innerHTML = '👤 ' + this.peer_name + ' (me)';
|
p.innerHTML = '👤 ' + this.peer_name + ' (me)';
|
||||||
d.appendChild(elem);
|
d.appendChild(elem);
|
||||||
d.appendChild(p);
|
d.appendChild(p);
|
||||||
@@ -684,11 +696,16 @@ class RoomClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let producer_id = this.producerLabel.get(type);
|
let producer_id = this.producerLabel.get(type);
|
||||||
console.log('Close producer', producer_id);
|
|
||||||
|
|
||||||
this.socket.emit('producerClosed', {
|
let data = {
|
||||||
producer_id,
|
peer_name: this.peer_name,
|
||||||
});
|
producer_id: producer_id,
|
||||||
|
type: type,
|
||||||
|
status: false,
|
||||||
|
};
|
||||||
|
console.log('Close producer', data);
|
||||||
|
|
||||||
|
this.socket.emit('producerClosed', data);
|
||||||
|
|
||||||
this.producers.get(producer_id).close();
|
this.producers.get(producer_id).close();
|
||||||
this.producers.delete(producer_id);
|
this.producers.delete(producer_id);
|
||||||
@@ -696,7 +713,7 @@ class RoomClient {
|
|||||||
|
|
||||||
if (type !== mediaType.audio) {
|
if (type !== mediaType.audio) {
|
||||||
let elem = this.getId(producer_id);
|
let elem = this.getId(producer_id);
|
||||||
let d = this.getId(producer_id + '_d');
|
let d = this.getId(producer_id + '__d');
|
||||||
elem.srcObject.getTracks().forEach(function (track) {
|
elem.srcObject.getTracks().forEach(function (track) {
|
||||||
track.stop();
|
track.stop();
|
||||||
});
|
});
|
||||||
@@ -786,7 +803,7 @@ class RoomClient {
|
|||||||
case mediaType.video:
|
case mediaType.video:
|
||||||
d = document.createElement('div');
|
d = document.createElement('div');
|
||||||
d.className = 'Camera';
|
d.className = 'Camera';
|
||||||
d.id = id + '_d';
|
d.id = id + '__d';
|
||||||
elem = document.createElement('video');
|
elem = document.createElement('video');
|
||||||
elem.setAttribute('id', id);
|
elem.setAttribute('id', id);
|
||||||
elem.setAttribute('playsinline', true);
|
elem.setAttribute('playsinline', true);
|
||||||
@@ -794,7 +811,7 @@ class RoomClient {
|
|||||||
elem.className = '';
|
elem.className = '';
|
||||||
elem.poster = image.poster;
|
elem.poster = image.poster;
|
||||||
p = document.createElement('p');
|
p = document.createElement('p');
|
||||||
p.id = id + '_name';
|
p.id = id + '__name';
|
||||||
p.innerHTML = '👤 ' + peer_name;
|
p.innerHTML = '👤 ' + peer_name;
|
||||||
d.appendChild(elem);
|
d.appendChild(elem);
|
||||||
d.appendChild(p);
|
d.appendChild(p);
|
||||||
@@ -819,7 +836,7 @@ class RoomClient {
|
|||||||
|
|
||||||
removeConsumer(consumer_id) {
|
removeConsumer(consumer_id) {
|
||||||
let elem = this.getId(consumer_id);
|
let elem = this.getId(consumer_id);
|
||||||
let d = this.getId(consumer_id + '_d');
|
let d = this.getId(consumer_id + '__d');
|
||||||
|
|
||||||
elem.srcObject.getTracks().forEach(function (track) {
|
elem.srcObject.getTracks().forEach(function (track) {
|
||||||
track.stop();
|
track.stop();
|
||||||
@@ -980,13 +997,13 @@ class RoomClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
userLog(icon, message, position) {
|
userLog(icon, message, position, timer = 5000) {
|
||||||
const Toast = Swal.mixin({
|
const Toast = Swal.mixin({
|
||||||
background: swalBackground,
|
background: swalBackground,
|
||||||
toast: true,
|
toast: true,
|
||||||
position: position,
|
position: position,
|
||||||
showConfirmButton: false,
|
showConfirmButton: false,
|
||||||
timer: 5000,
|
timer: timer,
|
||||||
});
|
});
|
||||||
Toast.fire({
|
Toast.fire({
|
||||||
icon: icon,
|
icon: icon,
|
||||||
@@ -1436,45 +1453,136 @@ class RoomClient {
|
|||||||
// PEER ACTION
|
// PEER ACTION
|
||||||
// ####################################################
|
// ####################################################
|
||||||
|
|
||||||
peerAction(from_peer_name, peer_id, action, emit = true) {
|
peerAction(from_peer_name, id, action, emit = true, broadcast = false) {
|
||||||
switch (action) {
|
let peer_id = id;
|
||||||
case 'eject':
|
|
||||||
let peer = this.getId(peer_id);
|
|
||||||
if (peer) peer.parentNode.removeChild(peer);
|
|
||||||
if (peer_id === this.peer_id) {
|
|
||||||
this.sound(action);
|
|
||||||
let timerInterval;
|
|
||||||
Swal.fire({
|
|
||||||
allowOutsideClick: false,
|
|
||||||
background: swalBackground,
|
|
||||||
title: from_peer_name,
|
|
||||||
html: 'Will eject you from the room after <b style="color: red;"></b> milliseconds.',
|
|
||||||
timer: 5000,
|
|
||||||
timerProgressBar: true,
|
|
||||||
didOpen: () => {
|
|
||||||
Swal.showLoading();
|
|
||||||
const b = Swal.getHtmlContainer().querySelector('b');
|
|
||||||
timerInterval = setInterval(() => {
|
|
||||||
b.textContent = Swal.getTimerLeft();
|
|
||||||
}, 100);
|
|
||||||
},
|
|
||||||
willClose: () => {
|
|
||||||
clearInterval(timerInterval);
|
|
||||||
},
|
|
||||||
}).then(() => {
|
|
||||||
this.exit();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
if (emit) {
|
if (emit) {
|
||||||
|
const words = peer_id.split('__');
|
||||||
|
peer_id = words[0];
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case 'eject':
|
||||||
|
let peer = this.getId(peer_id);
|
||||||
|
if (peer) peer.parentNode.removeChild(peer);
|
||||||
|
break;
|
||||||
|
case 'mute':
|
||||||
|
let peerAudioButton = this.getId(peer_id + '__audio');
|
||||||
|
if (peerAudioButton) peerAudioButton.innerHTML = _PEER.audioOff;
|
||||||
|
break;
|
||||||
|
case 'hide':
|
||||||
|
let peerVideoButton = this.getId(peer_id + '__video');
|
||||||
|
if (peerVideoButton) peerVideoButton.innerHTML = _PEER.videoOff;
|
||||||
|
}
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
from_peer_name: this.peer_name,
|
from_peer_name: this.peer_name,
|
||||||
peer_id: peer_id,
|
peer_id: peer_id,
|
||||||
action: action,
|
action: action,
|
||||||
|
broadcast: broadcast,
|
||||||
};
|
};
|
||||||
this.socket.emit('peerAction', data);
|
this.socket.emit('peerAction', data);
|
||||||
|
} else {
|
||||||
|
switch (action) {
|
||||||
|
case 'eject':
|
||||||
|
if (peer_id === this.peer_id) {
|
||||||
|
this.sound(action);
|
||||||
|
let timerInterval;
|
||||||
|
Swal.fire({
|
||||||
|
allowOutsideClick: false,
|
||||||
|
background: swalBackground,
|
||||||
|
title: from_peer_name,
|
||||||
|
html: 'Will eject you from the room after <b style="color: red;"></b> milliseconds.',
|
||||||
|
timer: 5000,
|
||||||
|
timerProgressBar: true,
|
||||||
|
didOpen: () => {
|
||||||
|
Swal.showLoading();
|
||||||
|
const b = Swal.getHtmlContainer().querySelector('b');
|
||||||
|
timerInterval = setInterval(() => {
|
||||||
|
b.textContent = Swal.getTimerLeft();
|
||||||
|
}, 100);
|
||||||
|
},
|
||||||
|
willClose: () => {
|
||||||
|
clearInterval(timerInterval);
|
||||||
|
},
|
||||||
|
}).then(() => {
|
||||||
|
this.exit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'mute':
|
||||||
|
if (peer_id === this.peer_id) {
|
||||||
|
this.closeProducer(mediaType.audio);
|
||||||
|
this.userLog(
|
||||||
|
'warning',
|
||||||
|
from_peer_name + ' ' + _PEER.audioOff + ' has closed yours audio',
|
||||||
|
'top-end',
|
||||||
|
10000,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'hide':
|
||||||
|
if (peer_id === this.peer_id) {
|
||||||
|
this.closeProducer(mediaType.video);
|
||||||
|
this.userLog(
|
||||||
|
'warning',
|
||||||
|
from_peer_name + ' ' + _PEER.videoOff + ' has closed yours video',
|
||||||
|
'top-end',
|
||||||
|
10000,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ####################################################
|
||||||
|
// UPDATE PEER INFO
|
||||||
|
// ####################################################
|
||||||
|
|
||||||
|
updatePeerInfo(peer_name, peer_id, type, status, emit = true) {
|
||||||
|
if (emit) {
|
||||||
|
switch (type) {
|
||||||
|
case 'audio':
|
||||||
|
this.peer_info.peer_audio = status;
|
||||||
|
break;
|
||||||
|
case 'video':
|
||||||
|
this.peer_info.peer_video = status;
|
||||||
|
break;
|
||||||
|
case 'hand':
|
||||||
|
this.peer_info.peer_hand = status;
|
||||||
|
if (status) {
|
||||||
|
this.event(_EVENTS.raiseHand);
|
||||||
|
this.sound('raiseHand');
|
||||||
|
} else {
|
||||||
|
this.event(_EVENTS.lowerHand);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let data = {
|
||||||
|
peer_name: peer_name,
|
||||||
|
peer_id: peer_id,
|
||||||
|
type: type,
|
||||||
|
status: status,
|
||||||
|
};
|
||||||
|
this.socket.emit('updatePeerInfo', data);
|
||||||
|
} else {
|
||||||
|
switch (type) {
|
||||||
|
case 'audio':
|
||||||
|
break;
|
||||||
|
case 'video':
|
||||||
|
break;
|
||||||
|
case 'hand':
|
||||||
|
if (status)
|
||||||
|
this.userLog(
|
||||||
|
'warning',
|
||||||
|
peer_name + ' ' + _PEER.raiseHand + ' has raised the hand',
|
||||||
|
'top-end',
|
||||||
|
10000,
|
||||||
|
);
|
||||||
|
this.sound('raiseHand');
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1488,6 +1596,7 @@ class RoomClient {
|
|||||||
'peer_name',
|
'peer_name',
|
||||||
'peer_audio',
|
'peer_audio',
|
||||||
'peer_video',
|
'peer_video',
|
||||||
|
'peer_hand',
|
||||||
'is_mobile_device',
|
'is_mobile_device',
|
||||||
'os_name',
|
'os_name',
|
||||||
'os_version',
|
'os_version',
|
||||||
|
|||||||
ثنائية
public/sounds/raiseHand.wav
Normal file
ثنائية
public/sounds/raiseHand.wav
Normal file
ملف ثنائي غير معروض.
21
src/Peer.js
21
src/Peer.js
@@ -10,11 +10,32 @@ module.exports = class Peer {
|
|||||||
this.peer_name = data.peer_info.peer_name;
|
this.peer_name = data.peer_info.peer_name;
|
||||||
this.peer_audio = data.peer_info.peer_audio;
|
this.peer_audio = data.peer_info.peer_audio;
|
||||||
this.peer_video = data.peer_info.peer_video;
|
this.peer_video = data.peer_info.peer_video;
|
||||||
|
this.peer_hand = data.peer_info.peer_hand;
|
||||||
this.transports = new Map();
|
this.transports = new Map();
|
||||||
this.consumers = new Map();
|
this.consumers = new Map();
|
||||||
this.producers = new Map();
|
this.producers = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ####################################################
|
||||||
|
// UPDATE PEER INFO
|
||||||
|
// ####################################################
|
||||||
|
|
||||||
|
updatePeerInfo(data) {
|
||||||
|
switch (data.type) {
|
||||||
|
case 'audio':
|
||||||
|
case 'audioType':
|
||||||
|
this.peer_info.peer_audio = data.status;
|
||||||
|
break;
|
||||||
|
case 'video':
|
||||||
|
case 'videoType':
|
||||||
|
this.peer_info.peer_video = data.status;
|
||||||
|
break;
|
||||||
|
case 'hand':
|
||||||
|
this.peer_info.peer_hand = data.status;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ####################################################
|
// ####################################################
|
||||||
// TRANSPORT
|
// TRANSPORT
|
||||||
// ####################################################
|
// ####################################################
|
||||||
|
|||||||
@@ -219,7 +219,18 @@ io.on('connection', (socket) => {
|
|||||||
|
|
||||||
socket.on('peerAction', (data) => {
|
socket.on('peerAction', (data) => {
|
||||||
log.debug('Peer action:', data);
|
log.debug('Peer action:', data);
|
||||||
roomList.get(socket.room_id).sendTo(data.peer_id, 'peerAction', data);
|
if (data.broadcast) {
|
||||||
|
roomList.get(socket.room_id).broadCast(data.peer_id, 'peerAction', data);
|
||||||
|
} else {
|
||||||
|
roomList.get(socket.room_id).sendTo(data.peer_id, 'peerAction', data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('updatePeerInfo', (data) => {
|
||||||
|
log.debug('Peer info update:', data);
|
||||||
|
// peer_info hand raise Or lower
|
||||||
|
roomList.get(socket.room_id).getPeers().get(socket.id).updatePeerInfo(data);
|
||||||
|
roomList.get(socket.room_id).broadCast(socket.id, 'updatePeerInfo', data);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('join', (data, cb) => {
|
socket.on('join', (data, cb) => {
|
||||||
@@ -290,16 +301,26 @@ io.on('connection', (socket) => {
|
|||||||
return callback({ error: 'Room not found' });
|
return callback({ error: 'Room not found' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let peer_name = getPeerName(false);
|
||||||
|
|
||||||
let producer_id = await roomList
|
let producer_id = await roomList
|
||||||
.get(socket.room_id)
|
.get(socket.room_id)
|
||||||
.produce(socket.id, producerTransportId, rtpParameters, kind);
|
.produce(socket.id, producerTransportId, rtpParameters, kind);
|
||||||
|
|
||||||
log.debug('Produce', {
|
log.debug('Produce', {
|
||||||
kind: kind,
|
kind: kind,
|
||||||
peer_name: getPeerName(false),
|
peer_name: peer_name,
|
||||||
producer_id: producer_id,
|
producer_id: producer_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// peer_info audio Or video ON
|
||||||
|
let data = {
|
||||||
|
peer_name: peer_name,
|
||||||
|
type: kind,
|
||||||
|
status: true,
|
||||||
|
};
|
||||||
|
roomList.get(socket.room_id).getPeers().get(socket.id).updatePeerInfo(data);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
producer_id,
|
producer_id,
|
||||||
});
|
});
|
||||||
@@ -323,10 +344,12 @@ io.on('connection', (socket) => {
|
|||||||
callback(params);
|
callback(params);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('producerClosed', ({ producer_id }) => {
|
socket.on('producerClosed', (data) => {
|
||||||
log.debug('Producer close', getPeerName());
|
log.debug('Producer close', data);
|
||||||
|
|
||||||
roomList.get(socket.room_id).closeProducer(socket.id, producer_id);
|
// peer_info audio Or video OFF
|
||||||
|
roomList.get(socket.room_id).getPeers().get(socket.id).updatePeerInfo(data);
|
||||||
|
roomList.get(socket.room_id).closeProducer(socket.id, data.producer_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('resume', async (_, callback) => {
|
socket.on('resume', async (_, callback) => {
|
||||||
|
|||||||
المرجع في مشكلة جديدة
حظر مستخدم