[mirotalksfu] - #194 Add Virtual Background Image from URL

هذا الالتزام موجود في:
Miroslav Pejic
2025-02-14 23:24:09 +01:00
الأصل ac6f9733a5
التزام 9709acb51c
8 ملفات معدلة مع 198 إضافات و4 حذوفات

عرض الملف

@@ -58,7 +58,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.7.37
* @version 1.7.38
*
*/

عرض الملف

@@ -1,6 +1,6 @@
{
"name": "mirotalksfu",
"version": "1.7.37",
"version": "1.7.38",
"description": "WebRTC SFU browser-based video calls",
"main": "Server.js",
"scripts": {

عرض الملف

@@ -269,6 +269,54 @@ body {
color: white;
}
/*--------------------------------------------------------------
# Custom modal to paste image URL
--------------------------------------------------------------*/
.imageUrlModal {
display: none;
position: fixed;
z-index: 9999;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: var(--body-bg);
width: 80%;
max-width: 400px;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
.imageUrlModal-content {
background: var(--body-bg);
padding: 20px;
border-radius: 8px;
text-align: center;
}
.imageUrlModal input {
width: 80%;
padding: 10px;
margin: 10px 0;
border: var(--border);
border-radius: 4px;
}
.imageUrlModal button {
padding: 10px 20px;
border: none;
background: var(--btns-bg-color);
border-radius: 10px;
border-radius: 4px;
cursor: pointer;
margin: 5px;
}
.imageUrlModal button:hover {
background: var(--body-bg) !important;
}
/*--------------------------------------------------------------
# Buttons bar
--------------------------------------------------------------*/

ثنائية
public/images/link.png Normal file

ملف ثنائي غير معروض.

بعد

العرض:  |  الارتفاع:  |  الحجم: 2.4 KiB

عرض الملف

@@ -64,7 +64,7 @@ let BRAND = {
},
about: {
imageUrl: '../images/mirotalk-logo.gif',
title: '<strong>WebRTC SFU v1.7.37</strong>',
title: '<strong>WebRTC SFU v1.7.38</strong>',
html: `
<button
id="support-button"

عرض الملف

@@ -5116,6 +5116,74 @@ function showImageSelector() {
imageGrid.appendChild(uploadImg);
setTippy(uploadImg.id, 'Upload your custom background', 'top');
// Function to fetch image from URL and store it in IndexedDB
async function fetchAndStoreImage(url) {
try {
const response = await fetch(url);
const blob = await response.blob();
const reader = new FileReader();
reader.onload = function (e) {
const imgData = e.target.result;
saveImageToIndexedDB(imgData);
addImageToUI(imgData);
};
reader.readAsDataURL(blob);
} catch (error) {
console.error('Error fetching image:', error);
}
}
saveImageUrlBtn.addEventListener('click', async () => {
elemDisplay(imageUrlModal.id, false);
if (isValidURL(imageUrlInput.value)) {
await fetchAndStoreImage(imageUrlInput.value);
imageUrlInput.value = '';
}
});
cancelImageUrlBtn.addEventListener('click', () => {
elemDisplay(imageUrlModal.id, false);
imageUrlInput.value = '';
});
function askForImageURL() {
elemDisplay(imageUrlModal.id, true);
// Take URL from clipboard ex:
navigator.clipboard
.readText()
.then((clipboardText) => {
if (!clipboardText) return false;
const sanitizedText = filterXSS(clipboardText);
if (isValidURL(sanitizedText) && imageUrlInput) {
imageUrlInput.value = sanitizedText;
}
return false;
})
.catch(() => {
return false;
});
}
// Function to validate URL format
function isValidURL(url) {
return (
url.match(/\.(jpeg|jpg|png|gif|webp|bmp|svg|apng|avif|heif|heic|tiff?|ico|cur|jfif|pjpeg|pjp|raw)$/i) !==
null
);
}
// Create link to upload image
const linkImg = document.createElement('img');
linkImg.id = 'linkImage';
linkImg.src = image.link;
linkImg.alt = 'Link image';
linkImg.addEventListener('click', askForImageURL);
imageGrid.appendChild(linkImg);
setTippy(linkImg.id, 'Upload Image from Url', 'top');
// Loop through virtual background images dynamically
virtualBackgrounds.forEach((imageUrl, index) => {
const img = document.createElement('img');

عرض الملف

@@ -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.7.37
* @version 1.7.38
*
*/
@@ -114,6 +114,7 @@ const image = {
transcription: '../images/transcription.png',
back: '../images/back.png',
blur: '../images/blur.png',
link: '../images/link.png',
upload: '../images/upload.png',
virtualBackground: {
one: '../images/virtual-background/background-1.jpg',
@@ -1837,6 +1838,75 @@ class RoomClient {
imageGridVideo.appendChild(uploadImg);
setTippy(uploadImg.id, 'Upload your custom background', 'top');
// Function to fetch image from URL and store it in IndexedDB
async function fetchAndStoreImage(url) {
try {
const response = await fetch(url);
const blob = await response.blob();
const reader = new FileReader();
reader.onload = function (e) {
const imgData = e.target.result;
saveImageToIndexedDB(imgData);
addImageToUI(imgData);
};
reader.readAsDataURL(blob);
} catch (error) {
console.error('Error fetching image:', error);
}
}
saveImageUrlBtn.addEventListener('click', async () => {
elemDisplay(imageUrlModal.id, false);
if (isValidURL(imageUrlInput.value)) {
await fetchAndStoreImage(imageUrlInput.value);
imageUrlInput.value = '';
}
});
cancelImageUrlBtn.addEventListener('click', () => {
elemDisplay(imageUrlModal.id, false);
imageUrlInput.value = '';
});
function askForImageURL() {
elemDisplay(imageUrlModal.id, true);
// Take URL from clipboard ex:
navigator.clipboard
.readText()
.then((clipboardText) => {
if (!clipboardText) return false;
const sanitizedText = filterXSS(clipboardText);
if (isValidURL(sanitizedText) && imageUrlInput) {
imageUrlInput.value = sanitizedText;
}
return false;
})
.catch(() => {
return false;
});
}
// Function to validate URL format
function isValidURL(url) {
return (
url.match(
/\.(jpeg|jpg|png|gif|webp|bmp|svg|apng|avif|heif|heic|tiff?|ico|cur|jfif|pjpeg|pjp|raw)$/i,
) !== null
);
}
// Create link to upload image
const linkImg = document.createElement('img');
linkImg.id = 'linkImage';
linkImg.src = image.link;
linkImg.alt = 'Link image';
linkImg.addEventListener('click', askForImageURL);
imageGridVideo.appendChild(linkImg);
setTippy(linkImg.id, 'Upload Image from Url', 'top');
// Loop through virtual background images dynamically
virtualBackgrounds.forEach((imageUrl, index) => {
const img = document.createElement('img');

عرض الملف

@@ -175,6 +175,14 @@ access to use this app.
</div>
</div>
<div id="usernameEmoji" class="usernameEmoji fadein center hidden"></div>
<div id="imageUrlModal" class="imageUrlModal">
<div class="imageUrlModal-content fadein">
<h2>Paste Image URL</h2>
<input type="text" id="imageUrlInput" placeholder="Enter the image URL here..." />
<button id="saveImageUrlBtn">Save</button>
<button id="cancelImageUrlBtn">Cancel</button>
</div>
</div>
</section>
<div id="control" class="fadein">