From 46e6aa6c0f037f0caf4dab605794eadf8b56eaa7 Mon Sep 17 00:00:00 2001 From: Miroslav Pejic Date: Wed, 8 Jan 2025 02:23:03 +0100 Subject: [PATCH] [mirotalksfu] - refactoring --- app/src/Server.js | 2 +- package.json | 4 +- public/js/Room.js | 87 +++++++++++++++++++++-------------------- public/js/RoomClient.js | 41 ++++++++++--------- public/js/VideoGrid.js | 2 +- public/views/Room.html | 1 - 6 files changed, 71 insertions(+), 66 deletions(-) diff --git a/app/src/Server.js b/app/src/Server.js index 06c3c718..48b08cf2 100644 --- a/app/src/Server.js +++ b/app/src/Server.js @@ -55,7 +55,7 @@ dev 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.6.87 + * @version 1.6.88 * */ diff --git a/package.json b/package.json index eb91d27e..76ac19b0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mirotalksfu", - "version": "1.6.87", + "version": "1.6.88", "description": "WebRTC SFU browser-based video calls", "main": "Server.js", "scripts": { @@ -57,7 +57,7 @@ "node": ">=18" }, "dependencies": { - "@mattermost/client": "^10.2.0", + "@mattermost/client": "10.2.0", "@sentry/node": "^8.48.0", "axios": "^1.7.9", "colors": "1.4.0", diff --git a/public/js/Room.js b/public/js/Room.js index e91c8a48..fa0bc9ec 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.6.87 + * @version 1.6.88 * */ @@ -21,7 +21,19 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h console.log('Window Location', window.location); -const socket = io({ transports: ['websocket'] }); +const userAgent = navigator.userAgent.toLowerCase(); +const parser = new UAParser(userAgent); +const parserResult = parser.getResult(); +const isMobileDevice = isMobile(userAgent); +const isTabletDevice = isTablet(userAgent); +const isIPadDevice = isIpad(userAgent); +const isDesktopDevice = isDesktop(); +const thisInfo = getInfo(); + +const socket = io({ + transports: ['websocket'], + reconnection: isDesktopDevice, +}); let survey = { enabled: true, @@ -61,11 +73,6 @@ const initUser = document.getElementById('initUser'); const initVideoContainerClass = document.querySelector('.init-video-container'); const bars = document.querySelectorAll('.volume-bar'); -const userAgent = navigator.userAgent.toLowerCase(); -const isTabletDevice = isTablet(userAgent); -const isIPadDevice = isIpad(userAgent); -const thisInfo = getInfo(); - const Base64Prefix = 'data:application/pdf;base64,'; // Whiteboard @@ -276,7 +283,7 @@ function initClient() { transcription = new Transcription(); transcription.init(); - if (!DetectRTC.isMobileDevice) { + if (!isMobileDevice) { refreshMainButtonsToolTipPlacement(); setTippy('closeEmojiPickerContainer', 'Close', 'bottom'); setTippy('mySettingsCloseBtn', 'Close', 'bottom'); @@ -381,7 +388,7 @@ function initClient() { // #################################################### function refreshMainButtonsToolTipPlacement() { - if (!DetectRTC.isMobileDevice) { + if (!isMobileDevice) { // const position = BtnsBarPosition.options[BtnsBarPosition.selectedIndex].value; const placement = position == 'vertical' ? 'right' : 'top'; @@ -935,26 +942,22 @@ function getPeerInfo() { peer_recording: isRecording, peer_video_privacy: isVideoPrivacyActive, peer_hand: false, - is_desktop_device: !DetectRTC.isMobileDevice && !isTabletDevice && !isIPadDevice, - is_mobile_device: DetectRTC.isMobileDevice, + is_desktop_device: isDesktopDevice, + is_mobile_device: isMobileDevice, is_tablet_device: isTabletDevice, is_ipad_pro_device: isIPadDevice, - os_name: DetectRTC.osName, - os_version: DetectRTC.osVersion, - browser_name: DetectRTC.browser.name, - browser_version: DetectRTC.browser.version, + os_name: parserResult.os.name, + os_version: parserResult.os.version, + browser_name: parserResult.browser.name, + browser_version: parserResult.browser.version, user_agent: userAgent, }; } function getInfo() { - const parser = new UAParser(userAgent); - try { - const parserResult = parser.getResult(); console.log('Info', parserResult); - // Filter out properties with 'Unknown' values const filterUnknown = (obj) => { const filtered = {}; for (const [key, value] of Object.entries(obj)) { @@ -1176,7 +1179,7 @@ async function handleAudioVideo() { hide(initVideoButton); hide(initVideoAudioRefreshButton); } - if (isAudioAllowed && isVideoAllowed && !DetectRTC.isMobileDevice) show(initVideoAudioRefreshButton); + if (isAudioAllowed && isVideoAllowed && !isMobileDevice) show(initVideoAudioRefreshButton); setColor(initAudioVideoButton, isAudioVideoAllowed ? 'white' : 'red'); setColor(initAudioButton, isAudioAllowed ? 'white' : 'red'); setColor(initVideoButton, isVideoAllowed ? 'white' : 'red'); @@ -1294,10 +1297,6 @@ async function shareRoom(useNavigator = false) { // ROOM UTILITY // #################################################### -function isDesktopDevice() { - return !DetectRTC.isMobileDevice && !isTabletDevice && !isIPadDevice; -} - function makeRoomQR() { let qr = new QRious({ element: document.getElementById('qrRoom'), @@ -1374,7 +1373,6 @@ function joinRoom(peer_name, room_id) { if (rc && rc.isConnected()) { console.log('Already connected to a room'); } else { - const isDesktopDevice = !DetectRTC.isMobileDevice && !isTabletDevice && !isIPadDevice; console.log('05 ----> join Room ' + room_id); roomId.innerText = room_id; userName.innerText = peer_name; @@ -1390,7 +1388,6 @@ function joinRoom(peer_name, room_id) { peer_name, peer_uuid, peer_info, - isDesktopDevice, isAudioAllowed, isVideoAllowed, isScreenAllowed, @@ -1443,10 +1440,10 @@ function roomIsReady() { show(chatCleanTextButton); show(chatPasteButton); show(chatSendButton); - if (isDesktopDevice()) { + if (isDesktopDevice) { show(whiteboardGridBtn); } - if (DetectRTC.isMobileDevice) { + if (isMobileDevice) { hide(initVideoAudioRefreshButton); hide(refreshVideoDevices); hide(refreshAudioDevices); @@ -1495,7 +1492,7 @@ function roomIsReady() { show(startRtmpURLButton) && show(streamerRtmpButton); } - if (DetectRTC.browser.name != 'Safari') { + if (!parserResult.browser.name.toLowerCase().includes('safari')) { document.onfullscreenchange = () => { if (!document.fullscreenElement) rc.isDocumentOnFullScreen = false; }; @@ -1512,7 +1509,7 @@ function roomIsReady() { BUTTONS.settings.sendEmailInvitation && show(sendEmailInvitation); if (rc.recording.recSyncServerRecording) show(roomRecordingServer); BUTTONS.main.aboutButton && show(aboutButton); - if (!DetectRTC.isMobileDevice) show(pinUnpinGridDiv); + if (!isMobileDevice) show(pinUnpinGridDiv); if (!isSpeechSynthesisSupported) hide(speechMsgDiv); handleButtons(); handleSelects(); @@ -1727,14 +1724,14 @@ function handleButtons() { sound('ring', true); }; roomId.onclick = () => { - DetectRTC.isMobileDevice ? shareRoom(true) : copyRoomURL(); + isMobileDevice ? shareRoom(true) : copyRoomURL(); }; roomSendEmail.onclick = () => { shareRoomByEmail(); }; chatButton.onclick = () => { rc.toggleChat(); - if (DetectRTC.isMobileDevice) { + if (isMobileDevice) { rc.toggleShowParticipants(); } }; @@ -1918,7 +1915,7 @@ function handleButtons() { }; toggleExtraButton.onclick = () => { toggleExtraButtons(); - if (!DetectRTC.isMobileDevice) { + if (!isMobileDevice) { isToggleExtraBtnClicked = true; setTimeout(() => { isToggleExtraBtnClicked = false; @@ -1926,7 +1923,7 @@ function handleButtons() { } }; toggleExtraButton.onmouseover = () => { - if (isToggleExtraBtnClicked || DetectRTC.isMobileDevice) return; + if (isToggleExtraBtnClicked || isMobileDevice) return; if (control.style.display === 'none') { toggleExtraButtons(); } @@ -2121,7 +2118,7 @@ function handleButtons() { // #################################################### function setButtonsInit() { - if (!DetectRTC.isMobileDevice) { + if (!isMobileDevice) { setTippy('initAudioButton', 'Toggle the audio', 'top'); setTippy('initVideoButton', 'Toggle the video', 'top'); setTippy('initAudioVideoButton', 'Toggle the audio & video', 'top'); @@ -2133,7 +2130,7 @@ function setButtonsInit() { if (!isAudioAllowed) hide(initAudioButton); if (!isVideoAllowed) hide(initVideoButton); if (!isAudioAllowed || !isVideoAllowed) hide(initAudioVideoButton); - if ((!isAudioAllowed && !isVideoAllowed) || DetectRTC.isMobileDevice) hide(initVideoAudioRefreshButton); + if ((!isAudioAllowed && !isVideoAllowed) || isMobileDevice) hide(initVideoAudioRefreshButton); isAudioVideoAllowed = isAudioAllowed && isVideoAllowed; } @@ -2391,7 +2388,7 @@ async function toggleScreenSharing() { } function handleCameraMirror(video) { - if (isDesktopDevice()) { + if (isDesktopDevice) { // Desktop devices... if (!video.classList.contains('mirror')) { video.classList.toggle('mirror'); @@ -2757,7 +2754,7 @@ function handleSelects() { function handleInputs() { chatMessage.onkeyup = (e) => { - if (e.keyCode === 13 && (DetectRTC.isMobileDevice || !e.shiftKey)) { + if (e.keyCode === 13 && (isMobileDevice || !e.shiftKey)) { e.preventDefault(); chatSendButton.click(); } @@ -3340,8 +3337,8 @@ function showButtons() { if ( isButtonsBarOver || isButtonsVisible || - (rc.isMobileDevice && rc.isChatOpen) || - (rc.isMobileDevice && rc.isMySettingsOpen) + (isMobileDevice && rc.isChatOpen) || + (isMobileDevice && rc.isMySettingsOpen) ) return; toggleExtraButton.innerHTML = icons.down; @@ -3454,6 +3451,10 @@ function isIpad(userAgent) { return /macintosh/.test(userAgent) && 'ontouchend' in document; } +function isDesktop() { + return !isMobileDevice && !isTabletDevice && !isIPadDevice; +} + function openURL(url, blank = false) { blank ? window.open(url, '_blank') : (window.location.href = url); } @@ -4393,7 +4394,7 @@ function getParticipantsList(peers) { function setParticipantsTippy(peers) { // - if (!DetectRTC.isMobileDevice) { + if (!isMobileDevice) { setTippy('muteAllButton', 'Mute all participants', 'top'); setTippy('hideAllButton', 'Hide all participants', 'top'); setTippy('stopAllButton', 'Stop screen share to all participants', 'top'); @@ -4686,7 +4687,7 @@ function adaptAspectRatio(participantsCount) { desktop = 1; // (4:3) mobile = 3; // (1:1) } - BtnAspectRatio.selectedIndex = DetectRTC.isMobileDevice ? mobile : desktop; + BtnAspectRatio.selectedIndex = isMobileDevice ? mobile : desktop; setAspectRatio(BtnAspectRatio.selectedIndex); } @@ -4702,7 +4703,7 @@ function showAbout() { imageUrl: image.about, customClass: { image: 'img-about' }, position: 'center', - title: 'WebRTC SFU v1.6.87', + title: 'WebRTC SFU v1.6.88', html: `
diff --git a/public/js/RoomClient.js b/public/js/RoomClient.js index 2caff4a3..7011d063 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.6.87 + * @version 1.6.88 * */ @@ -196,7 +196,6 @@ class RoomClient { peer_name, peer_uuid, peer_info, - isDesktopDevice, isAudioAllowed, isVideoAllowed, isScreenAllowed, @@ -225,9 +224,9 @@ class RoomClient { this.peer_info = peer_info; // Device type - this.isDesktopDevice = isDesktopDevice; - this.isMobileDevice = DetectRTC.isMobileDevice; - this.isMobileSafari = this.isMobileDevice && DetectRTC.browser.name === 'Safari'; + this.isDesktopDevice = peer_info.is_desktop_device; + this.isMobileDevice = peer_info.is_mobile_device; + this.isMobileSafari = this.isMobileDevice && peer_info.browser_name.toLowerCase().includes('safari'); // RTMP selected file name this.selectedRtmpFilename = ''; @@ -932,9 +931,9 @@ class RoomClient { this.handleConnect(); }; - handleSocketDisconnect = () => { - console.log('SocketOn Disconnect'); - this.handleDisconnect(); + handleSocketDisconnect = (reason) => { + console.log(`SocketOn Disconnect Reason: ${reason}`); + this.handleDisconnect(reason); }; handleConsumerClosed = ({ consumer_id, consumer_kind }) => { @@ -1115,7 +1114,7 @@ class RoomClient { this.refreshBrowser(); } - handleDisconnect() { + handleDisconnect(reason) { window.localStorage.isReconnected = true; console.log('Disconnected. Attempting to reconnect...'); @@ -1133,8 +1132,8 @@ class RoomClient { showDenyButton: false, showConfirmButton: false, icon: 'warning', - title: 'Lost connection', - text: 'The server may be under maintenance or your connection may have changed', + title: `Lost connection\n(${reason})`, + text: `The server may be under maintenance or your connection may have changed. Please ${this.isMobileDevice ? 'wait...' : 'check your connection.'}`, showClass: { popup: 'animate__animated animate__fadeInDown' }, hideClass: { popup: 'animate__animated animate__fadeOutUp' }, }); @@ -1173,11 +1172,17 @@ class RoomClient { let serverAwayShown = false; let reconnect; let reconnectTimer; + let waitingTime = this.isMobileDevice ? 30000 : 6000; + + // Clear existing timers if any + const clearTimers = () => { + clearTimeout(reconnect); + clearTimeout(reconnectTimer); + }; // Handle connect_error events this.socket.once('connect_error', () => { - clearTimeout(reconnect); - clearTimeout(reconnectTimer); + clearTimers(); }); this.socket.on('connect_error', () => { if (this.reconnectAttempts < this.maxReconnectAttempts) { @@ -1222,14 +1227,14 @@ class RoomClient { this.socket.once('connect', () => { console.log('Reconnected!'); this.reconnectAttempts = 0; - clearTimeout(reconnectTimer); + clearTimers(); }); - // Start reconnect logic after a brief delay + //Start reconnect logic after a brief delay reconnect = setTimeout(() => { showReconnectAlert(); attemptReconnect(); - }, 6000); + }, waitingTime); } // #################################################### @@ -3017,7 +3022,7 @@ class RoomClient { // #################################################### setTippy(elem, content, placement, allowHTML = false) { - if (DetectRTC.isMobileDevice) return; + if (this.isMobileDevice) return; const element = this.getId(elem); if (element) { if (element._tippy) { @@ -5695,7 +5700,7 @@ class RoomClient { const type = recordedBlobs[0].type.includes('mp4') ? 'mp4' : 'webm'; const blob = new Blob(recordedBlobs, { type: 'video/' + type }); const recFileName = `Rec_${dateTime}.${type}`; - const currentDevice = DetectRTC.isMobileDevice ? 'MOBILE' : 'PC'; + const currentDevice = this.isMobileDevice ? 'MOBILE' : 'PC'; const blobFileSize = bytesToSize(blob.size); const recTime = document.getElementById('recordingStatus'); const recType = 'Locally'; diff --git a/public/js/VideoGrid.js b/public/js/VideoGrid.js index 0f7d7808..15d30d03 100644 --- a/public/js/VideoGrid.js +++ b/public/js/VideoGrid.js @@ -186,7 +186,7 @@ function resizeChatRoom() { function resizeTranscriptionRoom() { if ( - DetectRTC.isMobileDevice || + isMobileDevice || !Boolean(transcription.speechTranscription) || transcription.isHidden || transcription.isPinned diff --git a/public/views/Room.html b/public/views/Room.html index f13e1a4f..ab85d554 100644 --- a/public/views/Room.html +++ b/public/views/Room.html @@ -126,7 +126,6 @@ -