[mirotalksfu] - allow screen sharing up to 8k, improvements
هذا الالتزام موجود في:
@@ -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.5.85
|
||||
* @version 1.5.86
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mirotalksfu",
|
||||
"version": "1.5.85",
|
||||
"version": "1.5.86",
|
||||
"description": "WebRTC SFU browser-based video calls",
|
||||
"main": "Server.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -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.5.85
|
||||
* @version 1.5.86
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -2286,6 +2286,9 @@ function handleSelects() {
|
||||
videoQuality.onchange = () => {
|
||||
rc.closeThenProduce(RoomClient.mediaType.video, videoSelect.value);
|
||||
};
|
||||
screenQuality.onchange = () => {
|
||||
rc.closeThenProduce(RoomClient.mediaType.screen);
|
||||
};
|
||||
videoFps.onchange = () => {
|
||||
rc.closeThenProduce(RoomClient.mediaType.video, videoSelect.value);
|
||||
localStorageSettings.video_fps = videoFps.selectedIndex;
|
||||
@@ -4490,7 +4493,7 @@ function showAbout() {
|
||||
imageUrl: image.about,
|
||||
customClass: { image: 'img-about' },
|
||||
position: 'center',
|
||||
title: 'WebRTC SFU v1.5.85',
|
||||
title: 'WebRTC SFU v1.5.86',
|
||||
html: `
|
||||
<br />
|
||||
<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 CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
|
||||
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
|
||||
* @version 1.5.85
|
||||
* @version 1.5.86
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1510,7 +1510,7 @@ class RoomClient {
|
||||
}
|
||||
|
||||
// ####################################################
|
||||
// AUDIO/VIDEO CONSTRAINTS
|
||||
// AUDIO/VIDEO/SCREEN CONSTRAINTS
|
||||
// ####################################################
|
||||
|
||||
getAudioConstraints(deviceId) {
|
||||
@@ -1555,149 +1555,85 @@ class RoomClient {
|
||||
const defaultFrameRate = { ideal: 30 };
|
||||
const selectedValue = this.getSelectedIndexValue(videoFps);
|
||||
const customFrameRate = parseInt(selectedValue, 10);
|
||||
const frameRate = selectedValue == 'max' ? defaultFrameRate : customFrameRate;
|
||||
let videoConstraints = {
|
||||
const frameRate = selectedValue === 'max' ? defaultFrameRate : { ideal: customFrameRate };
|
||||
|
||||
// Base constraints structure with dynamic values for resolution and frame rate
|
||||
const videoBaseConstraints = (width, height, exact = false) => ({
|
||||
audio: false,
|
||||
video: {
|
||||
width: { ideal: 3840 },
|
||||
height: { ideal: 2160 },
|
||||
width: exact ? { exact: width } : { ideal: width },
|
||||
height: exact ? { exact: height } : { ideal: height },
|
||||
deviceId: deviceId,
|
||||
aspectRatio: 1.777, // 16:9
|
||||
aspectRatio: 1.777, // 16:9 aspect ratio
|
||||
frameRate: frameRate,
|
||||
},
|
||||
}; // Init auto detect max cam resolution and fps
|
||||
});
|
||||
|
||||
videoFps.disabled = false;
|
||||
const videoResolutionMap = {
|
||||
qvga: { width: 320, height: 240, exact: true },
|
||||
vga: { width: 640, height: 480, exact: true },
|
||||
hd: { width: 1280, height: 720, exact: true },
|
||||
fhd: { width: 1920, height: 1080, exact: true },
|
||||
'2k': { width: 2560, height: 1440, exact: true },
|
||||
'4k': { width: 3840, height: 2160, exact: true },
|
||||
'6k': { width: 6144, height: 3456, exact: true },
|
||||
'8k': { width: 7680, height: 4320, exact: true },
|
||||
};
|
||||
|
||||
let videoConstraints;
|
||||
|
||||
switch (videoQuality.value) {
|
||||
case 'default':
|
||||
// This will make the browser use HD Video and 30fps as default.
|
||||
videoConstraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
width: { ideal: 1280 },
|
||||
height: { ideal: 720 },
|
||||
deviceId: deviceId,
|
||||
aspectRatio: 1.777,
|
||||
},
|
||||
};
|
||||
// Default ideal HD resolution
|
||||
videoConstraints = videoBaseConstraints(1280, 720);
|
||||
videoFps.selectedIndex = 0;
|
||||
videoFps.disabled = true;
|
||||
break;
|
||||
case 'qvga':
|
||||
videoConstraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
width: { exact: 320 },
|
||||
height: { exact: 240 },
|
||||
deviceId: deviceId,
|
||||
aspectRatio: 1.777,
|
||||
frameRate: frameRate,
|
||||
},
|
||||
}; // video cam constraints low bandwidth
|
||||
break;
|
||||
case 'vga':
|
||||
videoConstraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
width: { exact: 640 },
|
||||
height: { exact: 480 },
|
||||
deviceId: deviceId,
|
||||
aspectRatio: 1.777,
|
||||
frameRate: frameRate,
|
||||
},
|
||||
}; // video cam constraints medium bandwidth
|
||||
break;
|
||||
case 'hd':
|
||||
videoConstraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
width: { exact: 1280 },
|
||||
height: { exact: 720 },
|
||||
deviceId: deviceId,
|
||||
aspectRatio: 1.777,
|
||||
frameRate: frameRate,
|
||||
},
|
||||
}; // video cam constraints high bandwidth
|
||||
break;
|
||||
case 'fhd':
|
||||
videoConstraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
width: { exact: 1920 },
|
||||
height: { exact: 1080 },
|
||||
deviceId: deviceId,
|
||||
aspectRatio: 1.777,
|
||||
frameRate: frameRate,
|
||||
},
|
||||
}; // video cam constraints very high bandwidth
|
||||
break;
|
||||
case '2k':
|
||||
videoConstraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
width: { exact: 2560 },
|
||||
height: { exact: 1440 },
|
||||
deviceId: deviceId,
|
||||
aspectRatio: 1.777,
|
||||
frameRate: frameRate,
|
||||
},
|
||||
}; // video cam constraints ultra high bandwidth
|
||||
break;
|
||||
case '4k':
|
||||
videoConstraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
width: { exact: 3840 },
|
||||
height: { exact: 2160 },
|
||||
deviceId: deviceId,
|
||||
aspectRatio: 1.777,
|
||||
frameRate: frameRate,
|
||||
},
|
||||
}; // video cam constraints ultra high bandwidth
|
||||
break;
|
||||
case '6k':
|
||||
videoConstraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
width: { exact: 6144 },
|
||||
height: { exact: 3456 },
|
||||
deviceId: deviceId,
|
||||
aspectRatio: 1.777,
|
||||
frameRate: frameRate,
|
||||
},
|
||||
}; // video cam constraints Very ultra high bandwidth
|
||||
break;
|
||||
case '8k':
|
||||
videoConstraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
width: { exact: 7680 },
|
||||
height: { exact: 4320 },
|
||||
deviceId: deviceId,
|
||||
aspectRatio: 1.777,
|
||||
frameRate: frameRate,
|
||||
},
|
||||
}; // video cam constraints Very ultra high bandwidth
|
||||
break;
|
||||
default:
|
||||
// Ideal Full HD if no match found in the video resolution map
|
||||
const { width, height, exact } = videoResolutionMap[videoQuality.value] || {
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
};
|
||||
videoConstraints = videoBaseConstraints(width, height, exact);
|
||||
break;
|
||||
}
|
||||
|
||||
this.videoQualitySelectedIndex = videoQuality.selectedIndex;
|
||||
|
||||
return videoConstraints;
|
||||
}
|
||||
|
||||
getScreenConstraints() {
|
||||
const defaultFrameRate = { ideal: 30 };
|
||||
const selectedValue = this.getSelectedIndexValue(screenFps);
|
||||
const frameRate = selectedValue == 'max' ? 30 : parseInt(selectedValue, 10);
|
||||
return {
|
||||
const customFrameRate = parseInt(selectedValue, 10);
|
||||
const frameRate = selectedValue === 'max' ? defaultFrameRate : { ideal: customFrameRate };
|
||||
|
||||
// Base constraints structure with dynamic values for resolution and frame rate
|
||||
const screenBaseConstraints = (width, height) => ({
|
||||
audio: true,
|
||||
video: {
|
||||
width: { ideal: 1920 },
|
||||
height: { ideal: 1080 },
|
||||
width: { ideal: width },
|
||||
height: { ideal: height },
|
||||
aspectRatio: 1.777, // 16:9 aspect ratio
|
||||
frameRate: frameRate,
|
||||
},
|
||||
});
|
||||
|
||||
const screenResolutionMap = {
|
||||
hd: { width: 1280, height: 720 },
|
||||
fhd: { width: 1920, height: 1080 },
|
||||
'2k': { width: 2560, height: 1440 },
|
||||
'4k': { width: 3840, height: 2160 },
|
||||
'6k': { width: 6144, height: 3456 },
|
||||
'8k': { width: 7680, height: 4320 },
|
||||
};
|
||||
|
||||
// Default to Full HD if no match found in the screen resolution map
|
||||
const { width, height } = screenResolutionMap[screenQuality.value] || { width: 1920, height: 1080 };
|
||||
|
||||
return screenBaseConstraints(width, height);
|
||||
}
|
||||
|
||||
// ####################################################
|
||||
|
||||
@@ -399,6 +399,20 @@ access to use this app.
|
||||
<option value="6k">🎥 6k</option>
|
||||
<option value="8k">🎥 8K</option>
|
||||
</select>
|
||||
<br />
|
||||
<div class="title">
|
||||
<i class="fas fa-palette"></i>
|
||||
<p>Screen Quality:</p>
|
||||
</div>
|
||||
<select id="screenQuality" class="form-select text-light bg-dark">
|
||||
<option value="default">🖥 Default</option>
|
||||
<option value="hd">🖥 HD</option>
|
||||
<option value="fhd">🖥 FULL HD</option>
|
||||
<option value="2k">🖥 2k</option>
|
||||
<option value="4k">🖥 4K</option>
|
||||
<option value="6k">🖥 6k</option>
|
||||
<option value="8k">🖥 8K</option>
|
||||
</select>
|
||||
<hr />
|
||||
<div class="title">
|
||||
<i class="fa-solid fa-camera"></i>
|
||||
|
||||
المرجع في مشكلة جديدة
حظر مستخدم