[mirotalksfu] - refactoring

هذا الالتزام موجود في:
Miroslav Pejic
2024-03-07 19:43:00 +01:00
الأصل 0438037918
التزام e469bcae41
8 ملفات معدلة مع 100 إضافات و81 حذوفات

عرض الملف

@@ -93,7 +93,7 @@ module.exports = class Peer {
return this.producers.get(producer_id); return this.producers.get(producer_id);
} }
async createProducer(producerTransportId, rtpParameters, kind, type) { async createProducer(producerTransportId, producer_rtpParameters, producer_kind, producer_type) {
try { try {
if (!producerTransportId) { if (!producerTransportId) {
throw new Error('Invalid producer transport ID'); throw new Error('Invalid producer transport ID');
@@ -105,41 +105,40 @@ module.exports = class Peer {
} }
const producer = await producerTransport.produce({ const producer = await producerTransport.produce({
kind, kind: producer_kind,
rtpParameters, rtpParameters: producer_rtpParameters,
}); });
producer.appData.mediaType = type; const { id, appData, type, rtpParameters } = producer;
this.producers.set(producer.id, producer); appData.mediaType = producer_type;
const producerType = producer.type; this.producers.set(id, producer);
if (['simulcast', 'svc'].includes(producerType)) { if (['simulcast', 'svc'].includes(type)) {
const { scalabilityMode } = producer.rtpParameters.encodings[0]; const { scalabilityMode } = rtpParameters.encodings[0];
const spatialLayer = parseInt(scalabilityMode.substring(1, 2)); // 1/2/3 const spatialLayer = parseInt(scalabilityMode.substring(1, 2)); // 1/2/3
const temporalLayer = parseInt(scalabilityMode.substring(3, 4)); // 1/2/3 const temporalLayer = parseInt(scalabilityMode.substring(3, 4)); // 1/2/3
log.debug(`Producer [${producerType}] created with ID ${producer.id}`, { log.debug(`Producer [${type}] created with ID ${id}`, {
scalabilityMode, scalabilityMode,
spatialLayer, spatialLayer,
temporalLayer, temporalLayer,
}); });
} else { } else {
log.debug(`Producer of type ${producerType} created with ID ${producer.id}`); log.debug(`Producer of type ${type} created with ID ${id}`);
} }
producer.on('transportclose', () => { producer.on('transportclose', () => {
log.debug('Producer transport closed', { log.debug('Producer transport closed', {
peer_name: this.peer_info?.peer_name, peer_name: this.peer_info?.peer_name,
producer_id: producer.id, producer_id: id,
}); });
producer.close(); this.closeProducer(id);
this.producers.delete(producer.id);
}); });
return producer; return producer;
} catch (error) { } catch (error) {
log.error('Error creating producer', error); log.error('Error creating producer', error.message);
return null; return null;
} }
} }
@@ -173,48 +172,48 @@ module.exports = class Peer {
paused: false, paused: false,
}); });
const consumerType = consumer.type; const { id, type, kind, rtpParameters, producerPaused } = consumer;
if (['simulcast', 'svc'].includes(consumerType)) { if (['simulcast', 'svc'].includes(type)) {
const { scalabilityMode } = consumer.rtpParameters.encodings[0]; const { scalabilityMode } = rtpParameters.encodings[0];
const spatialLayer = parseInt(scalabilityMode.substring(1, 2)); // 1/2/3 const spatialLayer = parseInt(scalabilityMode.substring(1, 2)); // 1/2/3
const temporalLayer = parseInt(scalabilityMode.substring(3, 4)); // 1/2/3 const temporalLayer = parseInt(scalabilityMode.substring(3, 4)); // 1/2/3
await consumer.setPreferredLayers({ await consumer.setPreferredLayers({
spatialLayer: spatialLayer, spatialLayer: spatialLayer,
temporalLayer: temporalLayer, temporalLayer: temporalLayer,
}); });
log.debug(`Consumer [${consumerType}] ----->`, { log.debug(`Consumer [${type}] ----->`, {
scalabilityMode, scalabilityMode,
spatialLayer, spatialLayer,
temporalLayer, temporalLayer,
}); });
} else { } else {
log.debug('Consumer ----->', { type: consumerType }); log.debug('Consumer ----->', { type: type });
} }
consumer.on('transportclose', () => { consumer.on('transportclose', () => {
log.debug('Consumer transport close', { log.debug('Consumer transport close', {
peer_name: this.peer_info?.peer_name, peer_name: this.peer_info?.peer_name,
consumer_id: consumer.id, consumer_id: id,
}); });
this.removeConsumer(consumer.id); this.removeConsumer(id);
}); });
this.consumers.set(consumer.id, consumer); this.consumers.set(id, consumer);
return { return {
consumer, consumer,
params: { params: {
producerId: producer_id, producerId: producer_id,
id: consumer.id, id: id,
kind: consumer.kind, kind: kind,
rtpParameters: consumer.rtpParameters, rtpParameters: rtpParameters,
type: consumer.type, type: type,
producerPaused: consumer.producerPaused, producerPaused: producerPaused,
}, },
}; };
} catch (error) { } catch (error) {
log.error('Error creating consumer', error); log.error('Error creating consumer', error.message);
return null; return null;
} }
} }

عرض الملف

@@ -102,7 +102,7 @@ module.exports = class Room {
audioVolume: audioVolume, audioVolume: audioVolume,
}; };
// Uncomment the following line for debugging // Uncomment the following line for debugging
// log.debug('Sending audio volume:', data); // log.debug('Sending audio volume', data);
this.broadCast(0, 'audioVolume', data); this.broadCast(0, 'audioVolume', data);
} }
}); });
@@ -110,7 +110,7 @@ module.exports = class Room {
} }
} }
} catch (error) { } catch (error) {
log.error('Error sending active speaker volume', error); log.error('Error sending active speaker volume', error.message);
} }
} }
@@ -201,10 +201,11 @@ module.exports = class Room {
const producerList = []; const producerList = [];
this.peers.forEach((peer) => { this.peers.forEach((peer) => {
peer.producers.forEach((producer) => { peer.producers.forEach((producer) => {
const { peer_name, peer_info } = peer;
producerList.push({ producerList.push({
producer_id: producer.id, producer_id: producer.id,
peer_name: peer.peer_name, peer_name: peer_name,
peer_info: peer.peer_info, peer_info: peer_info,
type: producer.appData.mediaType, type: producer.appData.mediaType,
}); });
}); });
@@ -224,7 +225,7 @@ module.exports = class Room {
await this.peers.get(socket_id).connectTransport(transport_id, dtlsParameters); await this.peers.get(socket_id).connectTransport(transport_id, dtlsParameters);
} catch (error) { } catch (error) {
log.error('Error connecting peer transport', error); log.error('Error connecting peer transport', error.message);
} }
} }
@@ -253,34 +254,44 @@ module.exports = class Room {
initialAvailableOutgoingBitrate, initialAvailableOutgoingBitrate,
}); });
const { id, iceParameters, iceCandidates, dtlsParameters } = transport;
if (maxIncomingBitrate) { if (maxIncomingBitrate) {
await transport.setMaxIncomingBitrate(maxIncomingBitrate); try {
await transport.setMaxIncomingBitrate(maxIncomingBitrate);
} catch (error) {
log.error('Transport setMaxIncomingBitrate error', error.message);
}
} }
const peer = this.peers.get(socket_id);
const { peer_name } = peer;
transport.on('dtlsstatechange', (dtlsState) => { transport.on('dtlsstatechange', (dtlsState) => {
if (dtlsState === 'closed') { if (dtlsState === 'closed') {
log.debug('Transport closed', { peer_name: this.peers.get(socket_id)?.peer_name }); log.debug('Transport closed', { peer_name: peer_name });
transport.close(); transport.close();
} }
}); });
transport.on('close', () => { transport.on('close', () => {
log.debug('Transport closed', { peer_name: this.peers.get(socket_id)?.peer_name }); log.debug('Transport closed', { peer_name: peer_name });
}); });
log.debug('Adding transport', { transportId: transport.id }); log.debug('Adding transport', { transportId: id });
this.peers.get(socket_id)?.addTransport(transport); peer.addTransport(transport);
return { return {
params: { params: {
id: transport.id, id: id,
iceParameters: transport.iceParameters, iceParameters: iceParameters,
iceCandidates: transport.iceCandidates, iceCandidates: iceCandidates,
dtlsParameters: transport.dtlsParameters, dtlsParameters: dtlsParameters,
}, },
}; };
} catch (error) { } catch (error) {
log.error('Error creating WebRTC transport', error); log.error('Error creating WebRTC transport', error.message);
return null; return null;
} }
} }
@@ -295,31 +306,35 @@ module.exports = class Room {
throw new Error('Invalid input parameters'); throw new Error('Invalid input parameters');
} }
const producer = await this.peers if (!this.peers.has(socket_id)) {
.get(socket_id) throw new Error(`Invalid socket ID: ${socket_id}`);
?.createProducer(producerTransportId, rtpParameters, kind, type); }
const peer = this.peers.get(socket_id);
const producer = await peer.createProducer(producerTransportId, rtpParameters, kind, type);
if (!producer) { if (!producer) {
throw new Error('Failed to create producer'); throw new Error('Failed to create producer');
} }
const peer = this.peers.get(socket_id); const { id } = producer;
const peerName = peer?.peer_name;
const peerInfo = peer?.peer_info; const { peer_name, peer_info } = peer;
this.broadCast(socket_id, 'newProducers', [ this.broadCast(socket_id, 'newProducers', [
{ {
producer_id: producer.id, producer_id: id,
producer_socket_id: socket_id, producer_socket_id: socket_id,
peer_name: peerName, peer_name: peer_name,
peer_info: peerInfo, peer_info: peer_info,
type: type, type: type,
}, },
]); ]);
return producer.id; return id;
} catch (error) { } catch (error) {
console.error('Error producing', error); console.error('Error producing', error.message);
throw error; throw error.message;
} }
} }
@@ -342,12 +357,15 @@ module.exports = class Room {
return; return;
} }
const peer = this.peers.get(socket_id); if (!this.peers.has(socket_id)) {
if (!peer) { log.warn('Peer not found for socket ID', socket_id);
log.warn('Peer not found for socket ID:', socket_id);
return; return;
} }
const peer = this.peers.get(socket_id);
const { peer_name } = peer;
const result = await peer.createConsumer(consumer_transport_id, producer_id, rtpCapabilities); const result = await peer.createConsumer(consumer_transport_id, producer_id, rtpCapabilities);
if (!result || !result.consumer || !result.params) { if (!result || !result.consumer || !result.params) {
@@ -357,17 +375,19 @@ module.exports = class Room {
const { consumer, params } = result; const { consumer, params } = result;
const { id, kind } = consumer;
consumer.on('producerclose', () => { consumer.on('producerclose', () => {
log.debug('Consumer closed due to producerclose event', { log.debug('Consumer closed due to producerclose event', {
peer_name: this.peers.get(socket_id)?.peer_name, peer_name: peer_name,
consumer_id: consumer.id, consumer_id: id,
}); });
this.peers.get(socket_id)?.removeConsumer(consumer.id); peer.removeConsumer(id);
// Tell client consumer is dead // Tell client consumer is dead
this.io.to(socket_id).emit('consumerClosed', { this.io.to(socket_id).emit('consumerClosed', {
consumer_id: consumer.id, consumer_id: id,
consumer_kind: consumer.kind, consumer_kind: kind,
}); });
}); });
@@ -385,7 +405,7 @@ module.exports = class Room {
} }
this.peers.get(socket_id).closeProducer(producer_id); this.peers.get(socket_id).closeProducer(producer_id);
} catch (error) { } catch (error) {
log.error('Error closing producer:', error); log.error('Error closing producer', error.message);
} }
} }

عرض الملف

@@ -41,7 +41,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.3.85 * @version 1.3.86
* *
*/ */

عرض الملف

@@ -1,6 +1,6 @@
{ {
"name": "mirotalksfu", "name": "mirotalksfu",
"version": "1.3.85", "version": "1.3.86",
"description": "WebRTC SFU browser-based video calls", "description": "WebRTC SFU browser-based video calls",
"main": "Server.js", "main": "Server.js",
"scripts": { "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 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.3.85 * @version 1.3.86
* *
*/ */
@@ -1752,9 +1752,9 @@ async function changeCamera(deviceId) {
checkInitConfig(); checkInitConfig();
handleCameraMirror(initVideo); handleCameraMirror(initVideo);
}) })
.catch((err) => { .catch((error) => {
console.error('[Error] changeCamera', err); console.error('[Error] changeCamera', error);
userLog('error', 'Error while swapping camera' + err, 'top-end'); userLog('error', 'Error while swapping camera' + error.message, 'top-end');
}); });
} }
@@ -1781,8 +1781,8 @@ async function toggleScreenSharing() {
disable(initVideoButton, true); disable(initVideoButton, true);
disable(initAudioVideoButton, true); disable(initAudioVideoButton, true);
}) })
.catch((err) => { .catch((error) => {
console.error('[Error] toggleScreenSharing', err); console.error('[Error] toggleScreenSharing', error);
joinRoomWithScreen = false; joinRoomWithScreen = false;
return checkInitVideo(isVideoAllowed); return checkInitVideo(isVideoAllowed);
}); });
@@ -2246,7 +2246,7 @@ function handleRoomEmojiPicker() {
}; };
function sendEmojiToRoom(data) { function sendEmojiToRoom(data) {
console.log('Selected Emoji:', data.native); console.log('Selected Emoji', data.native);
const cmd = { const cmd = {
type: 'roomEmoji', type: 'roomEmoji',
peer_name: peer_name, peer_name: peer_name,
@@ -2995,8 +2995,8 @@ async function loadPDF(pdfData, pages) {
); );
return canvases.filter((canvas) => canvas !== null); return canvases.filter((canvas) => canvas !== null);
} catch (error) { } catch (error) {
console.error('Error loading PDF:', error); console.error('Error loading PDF', error.message);
throw error; throw error.message;
} }
} }
@@ -3013,8 +3013,8 @@ async function pdfToImage(pdfData, canvas) {
); );
}); });
} catch (error) { } catch (error) {
console.error('Error converting PDF to images:', error); console.error('Error converting PDF to images', error.message);
throw error; throw error.message;
} }
} }

عرض الملف

@@ -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.3.85 * @version 1.3.86
* *
*/ */
@@ -2421,7 +2421,7 @@ class RoomClient {
refreshLsDevices(); refreshLsDevices();
}); });
} else { } else {
let error = `Browser seems doesn't support output device selection.`; const error = `Browser seems doesn't support output device selection.`;
console.warn(error); console.warn(error);
this.userLog('error', error, 'top-end', 6000); this.userLog('error', error, 'top-end', 6000);
} }

عرض الملف

@@ -22,7 +22,7 @@ if (statsData) {
window.sessionStorage.setItem(statsDataKey, JSON.stringify(data)); window.sessionStorage.setItem(statsDataKey, JSON.stringify(data));
}) })
.catch((error) => { .catch((error) => {
console.error('Stats fetch error:', error); console.error('Stats fetch error', error);
}); });
} }

عرض الملف

@@ -51,7 +51,7 @@ function resizeVideoMedia() {
let optional = isHideMeActive && videoMediaContainer.childElementCount <= 2 ? 1 : 0; let optional = isHideMeActive && videoMediaContainer.childElementCount <= 2 ? 1 : 0;
let isOneVideoElement = videoMediaContainer.childElementCount - optional == 1 ? true : false; let isOneVideoElement = videoMediaContainer.childElementCount - optional == 1 ? true : false;
// console.log('videoMediaContainer.childElementCount:', { // console.log('videoMediaContainer.childElementCount', {
// isOneVideoElement: isOneVideoElement, // isOneVideoElement: isOneVideoElement,
// children: videoMediaContainer.childElementCount, // children: videoMediaContainer.childElementCount,
// optional: optional, // optional: optional,