[mirotalksfu] - add room snapshot button, update dep
هذا الالتزام موجود في:
@@ -43,7 +43,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.5.45
|
* @version 1.5.46
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -359,6 +359,7 @@ module.exports = {
|
|||||||
raiseHandButton: true,
|
raiseHandButton: true,
|
||||||
transcriptionButton: true,
|
transcriptionButton: true,
|
||||||
whiteboardButton: true,
|
whiteboardButton: true,
|
||||||
|
snapshotRoomButton: true,
|
||||||
emojiRoomButton: true,
|
emojiRoomButton: true,
|
||||||
settingsButton: true,
|
settingsButton: true,
|
||||||
aboutButton: true, // Please keep me always visible, thank you!
|
aboutButton: true, // Please keep me always visible, thank you!
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mirotalksfu",
|
"name": "mirotalksfu",
|
||||||
"version": "1.5.45",
|
"version": "1.5.46",
|
||||||
"description": "WebRTC SFU browser-based video calls",
|
"description": "WebRTC SFU browser-based video calls",
|
||||||
"main": "Server.js",
|
"main": "Server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/node": "^8.24.0",
|
"@sentry/node": "^8.25.0",
|
||||||
"axios": "^1.7.3",
|
"axios": "^1.7.3",
|
||||||
"body-parser": "1.20.2",
|
"body-parser": "1.20.2",
|
||||||
"colors": "1.4.0",
|
"colors": "1.4.0",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"mediasoup-client": "3.7.14",
|
"mediasoup-client": "3.7.14",
|
||||||
"ngrok": "^5.0.0-beta.2",
|
"ngrok": "^5.0.0-beta.2",
|
||||||
"nodemailer": "^6.9.14",
|
"nodemailer": "^6.9.14",
|
||||||
"openai": "^4.54.0",
|
"openai": "^4.55.3",
|
||||||
"qs": "6.13.0",
|
"qs": "6.13.0",
|
||||||
"socket.io": "4.7.5",
|
"socket.io": "4.7.5",
|
||||||
"swagger-ui-express": "5.0.1",
|
"swagger-ui-express": "5.0.1",
|
||||||
|
|||||||
@@ -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.5.45
|
* @version 1.5.46
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -377,6 +377,7 @@ function refreshMainButtonsToolTipPlacement() {
|
|||||||
setTippy('pollButton', 'Toggle the poll', placement);
|
setTippy('pollButton', 'Toggle the poll', placement);
|
||||||
setTippy('transcriptionButton', 'Toggle transcription', placement);
|
setTippy('transcriptionButton', 'Toggle transcription', placement);
|
||||||
setTippy('whiteboardButton', 'Toggle the whiteboard', placement);
|
setTippy('whiteboardButton', 'Toggle the whiteboard', placement);
|
||||||
|
setTippy('snapshotRoomButton', 'Snapshot the room', placement);
|
||||||
setTippy('settingsButton', 'Toggle the settings', placement);
|
setTippy('settingsButton', 'Toggle the settings', placement);
|
||||||
setTippy('aboutButton', 'About this project', placement);
|
setTippy('aboutButton', 'About this project', placement);
|
||||||
|
|
||||||
@@ -1337,6 +1338,7 @@ function roomIsReady() {
|
|||||||
show(startScreenButton);
|
show(startScreenButton);
|
||||||
show(ScreenFpsDiv);
|
show(ScreenFpsDiv);
|
||||||
}
|
}
|
||||||
|
BUTTONS.main.snapshotRoomButton && show(snapshotRoomButton);
|
||||||
}
|
}
|
||||||
BUTTONS.chat.chatPinButton && show(chatTogglePin);
|
BUTTONS.chat.chatPinButton && show(chatTogglePin);
|
||||||
BUTTONS.chat.chatMaxButton && show(chatMaxButton);
|
BUTTONS.chat.chatMaxButton && show(chatMaxButton);
|
||||||
@@ -1826,6 +1828,9 @@ function handleButtons() {
|
|||||||
whiteboardButton.onclick = () => {
|
whiteboardButton.onclick = () => {
|
||||||
toggleWhiteboard();
|
toggleWhiteboard();
|
||||||
};
|
};
|
||||||
|
snapshotRoomButton.onclick = () => {
|
||||||
|
rc.snapshotRoom();
|
||||||
|
};
|
||||||
whiteboardPencilBtn.onclick = () => {
|
whiteboardPencilBtn.onclick = () => {
|
||||||
whiteboardIsDrawingMode(true);
|
whiteboardIsDrawingMode(true);
|
||||||
};
|
};
|
||||||
@@ -4335,7 +4340,7 @@ function showAbout() {
|
|||||||
imageUrl: image.about,
|
imageUrl: image.about,
|
||||||
customClass: { image: 'img-about' },
|
customClass: { image: 'img-about' },
|
||||||
position: 'center',
|
position: 'center',
|
||||||
title: 'WebRTC SFU v1.5.45',
|
title: 'WebRTC SFU v1.5.46',
|
||||||
html: `
|
html: `
|
||||||
<br />
|
<br />
|
||||||
<div id="about">
|
<div id="about">
|
||||||
|
|||||||
@@ -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.5.45
|
* @version 1.5.46
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -8280,6 +8280,55 @@ class RoomClient {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ####################################################
|
||||||
|
// ROOM SNAPSHOT WINDOW/SCREEN/TAB
|
||||||
|
// ####################################################
|
||||||
|
|
||||||
|
async snapshotRoom() {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
const video = document.createElement('video');
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.sound('snapshot');
|
||||||
|
const captureStream = await navigator.mediaDevices.getDisplayMedia({
|
||||||
|
video: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
video.srcObject = captureStream;
|
||||||
|
video.onloadedmetadata = () => {
|
||||||
|
video.play();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wait for the video to start playing
|
||||||
|
video.onplay = async () => {
|
||||||
|
// Sleep some ms
|
||||||
|
await this.sleep(1000);
|
||||||
|
|
||||||
|
canvas.width = video.videoWidth;
|
||||||
|
canvas.height = video.videoHeight;
|
||||||
|
context.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
// Create a link element to download the image
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = canvas.toDataURL('image/png');
|
||||||
|
link.download = 'Room_' + this.room_id + '_' + getDataTimeString() + '_snapshot.png';
|
||||||
|
link.click();
|
||||||
|
|
||||||
|
// Stop all video tracks to release the capture stream
|
||||||
|
captureStream.getTracks().forEach((track) => track.stop());
|
||||||
|
|
||||||
|
// Clean up: remove references to avoid memory leaks
|
||||||
|
video.srcObject = null;
|
||||||
|
canvas.width = 0;
|
||||||
|
canvas.height = 0;
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error: ' + err);
|
||||||
|
this.userLog('error', 'Snapshot room error ' + err.message, 'top-end', 6000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
toggleVideoMirror() {
|
toggleVideoMirror() {
|
||||||
const peerVideo = this.getName(this.peer_id)[0];
|
const peerVideo = this.getName(this.peer_id)[0];
|
||||||
if (peerVideo) peerVideo.classList.toggle('mirror');
|
if (peerVideo) peerVideo.classList.toggle('mirror');
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ let BUTTONS = {
|
|||||||
raiseHandButton: true,
|
raiseHandButton: true,
|
||||||
transcriptionButton: true,
|
transcriptionButton: true,
|
||||||
whiteboardButton: true,
|
whiteboardButton: true,
|
||||||
|
snapshotRoomButton: true,
|
||||||
emojiRoomButton: true,
|
emojiRoomButton: true,
|
||||||
settingsButton: true,
|
settingsButton: true,
|
||||||
aboutButton: true, // Please keep me always visible, thank you!
|
aboutButton: true, // Please keep me always visible, thank you!
|
||||||
@@ -228,6 +229,7 @@ function handleRulesBroadcasting() {
|
|||||||
BUTTONS.main.swapCameraButton = false;
|
BUTTONS.main.swapCameraButton = false;
|
||||||
//BUTTONS.main.raiseHandButton = false;
|
//BUTTONS.main.raiseHandButton = false;
|
||||||
BUTTONS.main.whiteboardButton = false;
|
BUTTONS.main.whiteboardButton = false;
|
||||||
|
//BUTTONS.main.snapshotRoomButton = false;
|
||||||
//BUTTONS.main.emojiRoomButton = false,
|
//BUTTONS.main.emojiRoomButton = false,
|
||||||
//BUTTONS.main.pollButton = false;
|
//BUTTONS.main.pollButton = false;
|
||||||
BUTTONS.main.transcriptionButton = false;
|
BUTTONS.main.transcriptionButton = false;
|
||||||
@@ -262,6 +264,7 @@ function handleRulesBroadcasting() {
|
|||||||
elemDisplay('swapCameraButton', false);
|
elemDisplay('swapCameraButton', false);
|
||||||
//elemDisplay('raiseHandButton', false);
|
//elemDisplay('raiseHandButton', false);
|
||||||
elemDisplay('whiteboardButton', false);
|
elemDisplay('whiteboardButton', false);
|
||||||
|
//elemDisplay('snapshotRoomButton', false);
|
||||||
//elemDisplay('emojiRoomButton', false);
|
//elemDisplay('emojiRoomButton', false);
|
||||||
//elemDisplay('pollButton', false);
|
//elemDisplay('pollButton', false);
|
||||||
elemDisplay('transcriptionButton', false);
|
elemDisplay('transcriptionButton', false);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ const commands = {
|
|||||||
toggleTr: 'toggle transcription',
|
toggleTr: 'toggle transcription',
|
||||||
whiteboardOn: 'open the whiteboard',
|
whiteboardOn: 'open the whiteboard',
|
||||||
whiteboardOff: 'close the whiteboard',
|
whiteboardOff: 'close the whiteboard',
|
||||||
|
snapshotRoom: 'Snapshot room',
|
||||||
recordingOn: 'start the recording',
|
recordingOn: 'start the recording',
|
||||||
recordingPause: 'pause the recording',
|
recordingPause: 'pause the recording',
|
||||||
recordingResume: 'resume the recording',
|
recordingResume: 'resume the recording',
|
||||||
@@ -215,6 +216,10 @@ function execVoiceCommands(transcript) {
|
|||||||
printCommand(commands.whiteboardOff);
|
printCommand(commands.whiteboardOff);
|
||||||
whiteboardCloseBtn.click();
|
whiteboardCloseBtn.click();
|
||||||
break;
|
break;
|
||||||
|
case commands.snapshotRoom:
|
||||||
|
printCommand(commands.snapshotRoom);
|
||||||
|
snapshotRoomButton.click();
|
||||||
|
break;
|
||||||
case commands.recordingOn:
|
case commands.recordingOn:
|
||||||
printCommand(commands.recordingOn);
|
printCommand(commands.recordingOn);
|
||||||
startRecButton.click();
|
startRecButton.click();
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ access to use this app.
|
|||||||
<button id="pollButton" class="hidden"><i class="fas fa-square-poll-horizontal"></i></button>
|
<button id="pollButton" class="hidden"><i class="fas fa-square-poll-horizontal"></i></button>
|
||||||
<button id="transcriptionButton" class="hidden"><i class="fas fa-closed-captioning"></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>
|
<button id="whiteboardButton" class="hidden"><i class="fas fa-chalkboard-teacher"></i></button>
|
||||||
|
<button id="snapshotRoomButton" class="hidden"><i class="fas fas fa-camera-retro"></i></button>
|
||||||
<button id="settingsButton" class="hidden"><i class="fas fa-cogs"></i></button>
|
<button id="settingsButton" class="hidden"><i class="fas fa-cogs"></i></button>
|
||||||
<button id="aboutButton" class="hidden"><i class="fas fa-question"></i></button>
|
<button id="aboutButton" class="hidden"><i class="fas fa-question"></i></button>
|
||||||
<!-- <button id="restartICE" class="hidden"><i class="fas fa-satellite-dish"></i></button> -->
|
<!-- <button id="restartICE" class="hidden"><i class="fas fa-satellite-dish"></i></button> -->
|
||||||
|
|||||||
المرجع في مشكلة جديدة
حظر مستخدم