[mirotalksfu] - add screen share before join + update dep

هذا الالتزام موجود في:
Miroslav Pejic
2023-03-06 18:14:09 +01:00
الأصل ee5508d946
التزام 1856be737c
6 ملفات معدلة مع 87 إضافات و21 حذوفات

عرض الملف

@@ -38,7 +38,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.0.3 * @version 1.0.4
* *
*/ */

عرض الملف

@@ -1,6 +1,6 @@
{ {
"name": "mirotalksfu", "name": "mirotalksfu",
"version": "1.0.3", "version": "1.0.4",
"description": "WebRTC SFU browser-based video calls", "description": "WebRTC SFU browser-based video calls",
"main": "Server.js", "main": "Server.js",
"scripts": { "scripts": {
@@ -24,8 +24,8 @@
"author": "Miroslav Pejic", "author": "Miroslav Pejic",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"dependencies": { "dependencies": {
"@sentry/integrations": "7.40.0", "@sentry/integrations": "7.41.0",
"@sentry/node": "7.40.0", "@sentry/node": "7.41.0",
"body-parser": "1.20.2", "body-parser": "1.20.2",
"colors": "1.4.0", "colors": "1.4.0",
"compression": "1.7.4", "compression": "1.7.4",
@@ -33,7 +33,7 @@
"crypto-js": "4.1.1", "crypto-js": "4.1.1",
"express": "4.18.2", "express": "4.18.2",
"httpolyglot": "0.1.2", "httpolyglot": "0.1.2",
"mediasoup": "3.11.12", "mediasoup": "3.11.13",
"mediasoup-client": "3.6.82", "mediasoup-client": "3.6.82",
"ngrok": "^3.4.1", "ngrok": "^3.4.1",
"qs": "6.11.0", "qs": "6.11.0",

عرض الملف

@@ -212,7 +212,9 @@ body {
#initAudioButton, #initAudioButton,
#initVideoButton, #initVideoButton,
#initAudioVideoButton { #initAudioVideoButton,
#initStartScreenButton,
#initStopScreenButton {
font-size: 1.2rem; font-size: 1.2rem;
padding: 10px; padding: 10px;
border: var(--border); border: var(--border);

عرض الملف

@@ -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.0.3 * @version 1.0.4
* *
*/ */
@@ -92,6 +92,7 @@ let isVideoControlsOn = false;
let isChatPasteTxt = false; let isChatPasteTxt = false;
let isChatMarkdownOn = false; let isChatMarkdownOn = false;
let joinRoomWithoutAudioVideo = true; let joinRoomWithoutAudioVideo = true;
let joinRoomWithScreen = false;
let initAudioButton = null; let initAudioButton = null;
let initVideoButton = null; let initVideoButton = null;
let initAudioVideoButton = null; let initAudioVideoButton = null;
@@ -231,6 +232,9 @@ async function initEnumerateDevices() {
console.log('01 ----> init Enumerate Devices'); console.log('01 ----> init Enumerate Devices');
await initEnumerateVideoDevices(); await initEnumerateVideoDevices();
await initEnumerateAudioDevices(); await initEnumerateAudioDevices();
if (navigator.getDisplayMedia || navigator.mediaDevices.getDisplayMedia) {
BUTTONS.main.startScreenButton && show(initStartScreenButton);
}
whoAreYou(); whoAreYou();
if (!isVideoAllowed) { if (!isVideoAllowed) {
hide(initVideo); hide(initVideo);
@@ -496,7 +500,7 @@ function whoAreYou() {
peer_name = name; peer_name = name;
}, },
}).then(() => { }).then(() => {
if (initStream) { if (initStream && !joinRoomWithScreen) {
stopTracks(initStream); stopTracks(initStream);
hide(initVideo); hide(initVideo);
} }
@@ -695,6 +699,7 @@ function joinRoom(peer_name, room_id) {
isAudioAllowed, isAudioAllowed,
isVideoAllowed, isVideoAllowed,
isScreenAllowed, isScreenAllowed,
joinRoomWithScreen,
roomIsReady, roomIsReady,
); );
handleRoomClientEvents(); handleRoomClientEvents();
@@ -777,6 +782,10 @@ function show(elem) {
elem.className = ''; elem.className = '';
} }
function disable(elem, disabled) {
elem.disabled = disabled;
}
function setColor(elem, color) { function setColor(elem, color) {
elem.style.color = color; elem.style.color = color;
} }
@@ -1065,9 +1074,11 @@ function handleButtons() {
function setButtonsInit() { function setButtonsInit() {
if (!DetectRTC.isMobileDevice) { if (!DetectRTC.isMobileDevice) {
setTippy('initAudioButton', 'Toggle the audio', 'left'); setTippy('initAudioButton', 'Toggle the audio', 'top');
setTippy('initVideoButton', 'Toggle the video', 'right'); setTippy('initVideoButton', 'Toggle the video', 'top');
setTippy('initAudioVideoButton', 'Toggle the audio & video', 'right'); setTippy('initAudioVideoButton', 'Toggle the audio & video', 'top');
setTippy('initStartScreenButton', 'Toggle screen sharing', 'top');
setTippy('initStopScreenButton', 'Toggle screen sharing', 'top');
} }
initAudioButton = document.getElementById('initAudioButton'); initAudioButton = document.getElementById('initAudioButton');
initVideoButton = document.getElementById('initVideoButton'); initVideoButton = document.getElementById('initVideoButton');
@@ -1139,7 +1150,7 @@ function setSelectsInit() {
if (initVideoSelect.value) changeCamera(initVideoSelect.value); if (initVideoSelect.value) changeCamera(initVideoSelect.value);
} }
function changeCamera(deviceId) { async function changeCamera(deviceId) {
if (initStream) { if (initStream) {
stopTracks(initStream); stopTracks(initStream);
show(initVideo); show(initVideo);
@@ -1150,7 +1161,7 @@ function changeCamera(deviceId) {
initVideo.className = 'mirror'; initVideo.className = 'mirror';
initVideo.srcObject = camStream; initVideo.srcObject = camStream;
initStream = camStream; initStream = camStream;
console.log('04.5 ----> Success attached init video stream'); console.log('04.5 ----> Success attached init cam video stream', initStream);
}) })
.catch((err) => { .catch((err) => {
console.error('[Error] changeCamera', err); console.error('[Error] changeCamera', err);
@@ -1158,6 +1169,39 @@ function changeCamera(deviceId) {
}); });
} }
async function toggleScreenSharing() {
if (initStream) {
stopTracks(initStream);
show(initVideo);
}
joinRoomWithScreen = !joinRoomWithScreen;
if (joinRoomWithScreen) {
navigator.mediaDevices
.getDisplayMedia({ audio: true, video: true })
.then((screenStream) => {
initVideo.srcObject = screenStream;
initStream = screenStream;
console.log('04.6 ----> Success attached init screen video stream', initStream);
show(initStopScreenButton);
hide(initStartScreenButton);
disable(initVideoSelect, true);
disable(initVideoButton, true);
disable(initAudioVideoButton, true);
})
.catch((err) => {
console.error('[Error] toggleScreenSharing', err);
userLog('error', 'Error while toggleScreenSharing' + err.tostring(), 'top-end');
});
} else {
checkInitVideo(isVideoAllowed);
hide(initStopScreenButton);
show(initStartScreenButton);
disable(initVideoSelect, false);
disable(initVideoButton, false);
disable(initAudioVideoButton, false);
}
}
function handleSelects() { function handleSelects() {
// devices options // devices options
videoSelect.onchange = () => { videoSelect.onchange = () => {
@@ -1381,6 +1425,10 @@ function handleRoomClientEvents() {
console.log('Room Client stop screen'); console.log('Room Client stop screen');
hide(stopScreenButton); hide(stopScreenButton);
show(startScreenButton); show(startScreenButton);
if (initStream) {
stopTracks(initStream);
hide(initVideo);
}
}); });
rc.on(RoomClient.EVENTS.roomLock, () => { rc.on(RoomClient.EVENTS.roomLock, () => {
console.log('Room Client lock room'); console.log('Room Client lock room');

عرض الملف

@@ -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.0.3 * @version 1.0.4
* *
*/ */
@@ -110,6 +110,7 @@ class RoomClient {
isAudioAllowed, isAudioAllowed,
isVideoAllowed, isVideoAllowed,
isScreenAllowed, isScreenAllowed,
joinRoomWithScreen,
successCallback, successCallback,
) { ) {
this.localAudioEl = localAudioEl; this.localAudioEl = localAudioEl;
@@ -128,6 +129,7 @@ class RoomClient {
this.isAudioAllowed = isAudioAllowed; this.isAudioAllowed = isAudioAllowed;
this.isVideoAllowed = isVideoAllowed; this.isVideoAllowed = isVideoAllowed;
this.isScreenAllowed = isScreenAllowed; this.isScreenAllowed = isScreenAllowed;
this.joinRoomWithScreen = joinRoomWithScreen;
this.producerTransport = null; this.producerTransport = null;
this.consumerTransport = null; this.consumerTransport = null;
this.device = null; this.device = null;
@@ -284,7 +286,7 @@ class RoomClient {
this.device = await this.loadDevice(data); this.device = await this.loadDevice(data);
console.log('07.1 ----> Get Router Rtp Capabilities codecs: ', this.device.rtpCapabilities.codecs); console.log('07.1 ----> Get Router Rtp Capabilities codecs: ', this.device.rtpCapabilities.codecs);
await this.initTransports(this.device); await this.initTransports(this.device);
this.startLocalMedia(); await this.startLocalMedia();
this.socket.emit('getProducers'); this.socket.emit('getProducers');
} }
@@ -642,7 +644,7 @@ class RoomClient {
// START LOCAL AUDIO VIDEO MEDIA // START LOCAL AUDIO VIDEO MEDIA
// #################################################### // ####################################################
startLocalMedia() { async startLocalMedia() {
console.log('08 ----> Start local media'); console.log('08 ----> Start local media');
if (this.isAudioAllowed) { if (this.isAudioAllowed) {
console.log('09 ----> Start audio media'); console.log('09 ----> Start audio media');
@@ -660,6 +662,10 @@ class RoomClient {
this.setVideoOff(this.peer_info, false); this.setVideoOff(this.peer_info, false);
this.sendVideoOff(); this.sendVideoOff();
} }
if (this.joinRoomWithScreen) {
console.log('08 ----> Start Screen media');
this.produce(mediaType.screen, null, false, true);
}
// if (this.isScreenAllowed) { // if (this.isScreenAllowed) {
// this.shareScreen(); // this.shareScreen();
// } // }
@@ -669,7 +675,7 @@ class RoomClient {
// PRODUCER // PRODUCER
// #################################################### // ####################################################
async produce(type, deviceId = null, swapCamera = false) { async produce(type, deviceId = null, swapCamera = false, init = false) {
let mediaConstraints = {}; let mediaConstraints = {};
let audio = false; let audio = false;
let screen = false; let screen = false;
@@ -708,9 +714,13 @@ class RoomClient {
let stream; let stream;
try { try {
stream = screen if (init) {
? await navigator.mediaDevices.getDisplayMedia(mediaConstraints) stream = initStream;
: await navigator.mediaDevices.getUserMedia(mediaConstraints); } else {
stream = screen
? await navigator.mediaDevices.getDisplayMedia(mediaConstraints)
: await navigator.mediaDevices.getUserMedia(mediaConstraints);
}
console.log('Supported Constraints', navigator.mediaDevices.getSupportedConstraints()); console.log('Supported Constraints', navigator.mediaDevices.getSupportedConstraints());

عرض الملف

@@ -108,13 +108,19 @@ access to use this app.
id="initVideo" id="initVideo"
playsinline="true" playsinline="true"
autoplay="" autoplay=""
poster="../images/loader.gif"
class="mirror" class="mirror"
poster="../images/loader.gif"
style="object-fit: var(--videoObjFit)" style="object-fit: var(--videoObjFit)"
></video> ></video>
<button id="initAudioButton" class="fas fa-microphone" onclick="handleAudio(event)"></button> <button id="initAudioButton" class="fas fa-microphone" onclick="handleAudio(event)"></button>
<button id="initVideoButton" class="fas fa-video" onclick="handleVideo(event)"></button> <button id="initVideoButton" class="fas fa-video" onclick="handleVideo(event)"></button>
<button id="initAudioVideoButton" class="fas fa-eye" onclick="handleAudioVideo(event)"></button> <button id="initAudioVideoButton" class="fas fa-eye" onclick="handleAudioVideo(event)"></button>
<button id="initStartScreenButton" class="" onclick="toggleScreenSharing()">
<i class="fas fa-desktop"></i>
</button>
<button id="initStopScreenButton" class="hidden" onclick="toggleScreenSharing()">
<i class="fas fa-stop-circle"></i>
</button>
<select id="initVideoSelect" class="form-select text-light bg-dark"></select> <select id="initVideoSelect" class="form-select text-light bg-dark"></select>
<select id="initMicrophoneSelect" class="form-select text-light bg-dark"></select> <select id="initMicrophoneSelect" class="form-select text-light bg-dark"></select>
<select id="initSpeakerSelect" class="form-select text-light bg-dark"></select> <select id="initSpeakerSelect" class="form-select text-light bg-dark"></select>