[mirotalksfu] - #194 Keep uploaded virtual background images in IndexedDB

هذا الالتزام موجود في:
Miroslav Pejic
2025-02-14 18:10:52 +01:00
الأصل 81d3ae87e4
التزام ac6f9733a5
6 ملفات معدلة مع 232 إضافات و25 حذوفات

عرض الملف

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

عرض الملف

@@ -5011,20 +5011,107 @@ function showImageSelector() {
if (file) {
const reader = new FileReader();
reader.onload = function (e) {
const customImg = document.createElement('img');
customImg.id = `customImage${imageCounter}`; // Assign a unique id
customImg.src = e.target.result;
customImg.alt = 'Custom Background';
customImg.addEventListener('click', async function () {
await applyVirtualBackground(initVideo, initStream, false, e.target.result);
});
imageGrid.appendChild(customImg);
setTippy(customImg.id, 'Custom background', 'top');
const imgData = e.target.result;
saveImageToIndexedDB(imgData);
addImageToUI(imgData);
};
reader.readAsDataURL(file);
}
});
// Load images from IndexedDB
async function loadStoredImages() {
const storedImages = await getImagesFromIndexedDB();
storedImages.forEach((imgData) => addImageToUI(imgData));
}
// Save image to IndexedDB
async function saveImageToIndexedDB(imgData) {
const db = await openDB();
const transaction = db.transaction('images', 'readwrite');
const store = transaction.objectStore('images');
store.add({ imgData });
}
// Open IndexedDB
function openDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open('customImageDB', 1);
request.onupgradeneeded = function (event) {
const db = event.target.result;
if (!db.objectStoreNames.contains('images')) {
db.createObjectStore('images', { keyPath: 'id', autoIncrement: true });
}
};
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
// Get images from IndexedDB
function getImagesFromIndexedDB() {
return new Promise((resolve, reject) => {
const dbRequest = openDB();
dbRequest.then((db) => {
const transaction = db.transaction('images', 'readonly');
const store = transaction.objectStore('images');
const request = store.getAll();
request.onsuccess = () => resolve(request.result.map((item) => item.imgData));
request.onerror = () => reject(request.error);
});
});
}
// Add image to UI
function addImageToUI(imgData) {
const imageContainer = document.createElement('div');
imageContainer.className = 'image-wrapper';
const customImg = document.createElement('img');
customImg.id = `customImageGrid${imageCounter}`;
customImg.src = imgData;
customImg.alt = 'Custom Background';
customImg.addEventListener('click', async function () {
await applyVirtualBackground(initVideo, initStream, false, imgData);
});
// Create delete button
const deleteBtn = createDeleteIcon(imgData, imageContainer);
imageContainer.appendChild(customImg);
imageContainer.appendChild(deleteBtn);
imageGrid.appendChild(imageContainer);
setTippy(customImg.id, 'Custom background', 'top');
imageCounter++;
}
// Create delete icon
function createDeleteIcon(imgData, container) {
const deleteIcon = document.createElement('span');
deleteIcon.className = 'delete-icon fas fa-times';
deleteIcon.addEventListener('click', function (event) {
event.stopPropagation(); // Prevent triggering background change
removeImageFromIndexedDB(imgData);
container.remove();
});
return deleteIcon;
}
// Remove image from IndexedDB
async function removeImageFromIndexedDB(imgData) {
const db = await openDB();
const transaction = db.transaction('images', 'readwrite');
const store = transaction.objectStore('images');
const request = store.getAll();
request.onsuccess = () => {
const items = request.result;
const itemToDelete = items.find((item) => item.imgData === imgData);
if (itemToDelete) store.delete(itemToDelete.id);
};
}
// Append the button to the imageGrid
imageGrid.appendChild(uploadImg);
setTippy(uploadImg.id, 'Upload your custom background', 'top');
@@ -5040,6 +5127,9 @@ function showImageSelector() {
});
imageGrid.appendChild(img);
});
// Load images from IndexedDB on page load
loadStoredImages();
}
async function applyVirtualBackground(videoElement, stream, blurLevel, backgroundImage) {

عرض الملف

@@ -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.36
* @version 1.7.37
*
*/
@@ -1685,7 +1685,7 @@ class RoomClient {
const cleanVbImg = document.createElement('img');
cleanVbImg.id = 'cleanVbImg';
cleanVbImg.src = image.user;
cleanVbImg.alt = 'Clean virtual bacgroundk';
cleanVbImg.alt = 'Clean virtual background';
cleanVbImg.dataset.index = 'cleanVb';
cleanVbImg.addEventListener('click', async function () {
if (!virtualBackgroundBlurLevel && !virtualBackgroundSelectedImage) {
@@ -1726,26 +1726,113 @@ class RoomClient {
fileInput.click();
});
// Load images from IndexedDB
async function loadStoredImages() {
const storedImages = await getImagesFromIndexedDB();
storedImages.forEach((imgData) => addImageToUI(imgData));
}
// Handle image selection
fileInput.addEventListener('change', function () {
const file = this.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function (e) {
const customImg = document.createElement('img');
customImg.id = `customImage${imageCounter}`; // Assign a unique id
customImg.src = e.target.result;
customImg.alt = 'Custom Background';
customImg.addEventListener('click', async function () {
await rc.applyVirtualBackground(false, e.target.result);
});
imageGridVideo.appendChild(customImg);
setTippy(customImg.id, 'Custom background', 'top');
const imgData = e.target.result;
saveImageToIndexedDB(imgData);
addImageToUI(imgData);
};
reader.readAsDataURL(file);
}
});
// Add image with delete button to UI
function addImageToUI(imgData) {
const imageContainer = document.createElement('div');
imageContainer.className = 'image-wrapper';
const customImg = document.createElement('img');
customImg.id = `customImageGrid${imageCounter}`;
customImg.src = imgData;
customImg.alt = 'Custom Background';
customImg.addEventListener('click', async function () {
await rc.applyVirtualBackground(false, imgData);
});
// Create delete button
const deleteBtn = createDeleteIcon(imgData, imageContainer);
imageContainer.appendChild(customImg);
imageContainer.appendChild(deleteBtn);
imageGridVideo.appendChild(imageContainer);
setTippy(customImg.id, 'Custom background', 'top');
imageCounter++;
}
// Create delete icon
function createDeleteIcon(imgData, container) {
const deleteIcon = document.createElement('span');
deleteIcon.className = 'delete-icon fas fa-times';
deleteIcon.addEventListener('click', function (event) {
event.stopPropagation(); // Prevent triggering background change
removeImageFromIndexedDB(imgData);
container.remove();
});
return deleteIcon;
}
// Save image to IndexedDB
async function saveImageToIndexedDB(imgData) {
const db = await openDB();
const transaction = db.transaction('images', 'readwrite');
const store = transaction.objectStore('images');
store.add({ imgData });
}
// Open IndexedDB
function openDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open('customImageDB', 1);
request.onupgradeneeded = function (event) {
const db = event.target.result;
if (!db.objectStoreNames.contains('images')) {
db.createObjectStore('images', { keyPath: 'id', autoIncrement: true });
}
};
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
// Get images from IndexedDB
function getImagesFromIndexedDB() {
return new Promise((resolve, reject) => {
const dbRequest = openDB();
dbRequest.then((db) => {
const transaction = db.transaction('images', 'readonly');
const store = transaction.objectStore('images');
const request = store.getAll();
request.onsuccess = () => resolve(request.result.map((item) => item.imgData));
request.onerror = () => reject(request.error);
});
});
}
// Remove image from IndexedDB
async function removeImageFromIndexedDB(imgData) {
const db = await openDB();
const transaction = db.transaction('images', 'readwrite');
const store = transaction.objectStore('images');
const request = store.getAll();
request.onsuccess = () => {
const items = request.result;
const itemToDelete = items.find((item) => item.imgData === imgData);
if (itemToDelete) store.delete(itemToDelete.id);
};
}
// Append the button to the imageGrid
imageGridVideo.appendChild(uploadImg);
setTippy(uploadImg.id, 'Upload your custom background', 'top');
@@ -1761,6 +1848,9 @@ class RoomClient {
});
imageGridVideo.appendChild(img);
});
// Load images from IndexedDB on page load
loadStoredImages();
}
async applyVirtualBackground(blurLevel, backgroundImage) {