[mirotalksfu] - update config.template

هذا الالتزام موجود في:
Miroslav Pejic
2025-03-24 18:47:05 +01:00
الأصل 1d9fda7979
التزام 1e6b7e3a5b
4 ملفات معدلة مع 91 إضافات و22 حذوفات

1
.gitignore مباع
عرض الملف

@@ -15,6 +15,7 @@ package-lock.json
.cache .cache
# personal # personal
.env
config.js config.js
docker-compose.yml docker-compose.yml
docker-push.sh docker-push.sh

عرض الملف

@@ -290,7 +290,7 @@ const streams = {}; // Collect all rtmp streams
const webRtcServerActive = config.mediasoup.webRtcServerActive; const webRtcServerActive = config.mediasoup.webRtcServerActive;
// ip (server local IPv4) // ip (server local IPv4)
const IPv4 = webRtcServerActive const IP = webRtcServerActive
? config.mediasoup.webRtcServerOptions.listenInfos[0].ip ? config.mediasoup.webRtcServerOptions.listenInfos[0].ip
: config.mediasoup.webRtcTransport.listenInfos[0].ip; : config.mediasoup.webRtcTransport.listenInfos[0].ip;
@@ -304,7 +304,7 @@ const workers = [];
let nextMediasoupWorkerIdx = 0; let nextMediasoupWorkerIdx = 0;
// Autodetect announcedAddress (https://www.ipify.org) // Autodetect announcedAddress (https://www.ipify.org)
if (!announcedAddress && IPv4 === '0.0.0.0') { if (!announcedAddress && IP === '0.0.0.0') {
http.get( http.get(
{ {
host: 'api.ipify.org', host: 'api.ipify.org',
@@ -1300,6 +1300,18 @@ function startServer() {
email_alerts: config.email?.alert ? config.email : false, email_alerts: config.email?.alert ? config.email : false,
webhook: webhook, webhook: webhook,
// System info
systemInfo: config.systemInfo,
// SFU settings
sfu: {
ip: IP, // Local IPv4 listen on
announcedAddress, // Public IPv4 listen on
numWorker: config.mediasoup?.numWorkers,
rtcMinPort: config.mediasoup?.worker?.rtcMinPort || 40000,
rtcMaxPort: config.mediasoup?.worker?.rtcMaxPort || 40100,
},
// Version Information // Version Information
app_version: packageJson.version, app_version: packageJson.version,
node_version: process.versions.node, node_version: process.versions.node,

عرض الملف

@@ -1,9 +1,13 @@
'use strict'; 'use strict';
const dotenv = require('dotenv').config();
const packageJson = require('../../package.json'); const packageJson = require('../../package.json');
const os = require('os'); const os = require('os');
const https = require('https');
// ############################# // #############################
// HELPERS // HELPERS
// ############################# // #############################
@@ -23,9 +27,24 @@ function getFFmpegPath(platform) {
} }
} }
// https://api.ipify.org function getPublicIPv4(timeout = 5000) {
return new Promise((resolve, reject) => {
const req = https.get('https://api.ipify.org', (res) => {
res.on('data', (ip) => {
resolve(String(ip)); // Resolve with the public IP address
});
});
req.on('error', (err) => {
reject(err);
});
req.setTimeout(timeout, () => {
req.destroy();
reject(new Error('Request timed out'));
});
});
}
function getIPv4() { function getLocalIPv4() {
const ifaces = os.networkInterfaces(); const ifaces = os.networkInterfaces();
for (const interfaceName in ifaces) { for (const interfaceName in ifaces) {
const iface = ifaces[interfaceName]; const iface = ifaces[interfaceName];
@@ -41,14 +60,28 @@ function getIPv4() {
/* /*
IPv4 Configuration Guide: IPv4 Configuration Guide:
1. Localhost Setup: 1. Localhost Setup:
- For local development with Docker, replace `getIPv4()` with '127.0.0.1'. - For local development with Docker, replace `getLocalIPv4()` with '127.0.0.1' if needed.
2. Production Setup: 2. Production Setup:
- Replace `getIPv4()` with the 'Public Static IPv4 Address' of the server hosting this application. - If you leave it empty (''), it will be automatically detected using a service like https://api.ipify.org.
- For AWS EC2 instances, replace `getIPv4()` with the 'Elastic IP' associated with the instance. - Replace `getLocalIPv4()` with the 'Public Static IPv4 Address' of the server hosting this application.
- For AWS EC2 instances, replace `getLocalIPv4()` with the 'Elastic IP' associated with the instance.
This ensures the public IP remains consistent across instance reboots. This ensures the public IP remains consistent across instance reboots.
Note: Always enclose the IP address in single quotes ''. Note: Always enclose the IP address in single quotes ''.
*/ */
const IPv4 = getIPv4(); // Replace with the appropriate IPv4 address for your environment. let IPv4 = process.env.SFU_ANNOUNCED_IP || getLocalIPv4(); // Replace with the appropriate IPv4 address for your environment or leave it empty ('') to be automatically detected on instance startup.
(async () => {
if (IPv4 === '0.0.0.0' || !IPv4) {
try {
IPv4 = await getPublicIPv4();
} catch (err) {
console.error('Failed to determine public IPv4, using local fallback', err);
IPv4 = getLocalIPv4();
}
}
})();
const listenIP = process.env.SFU_LISTEN_IP || '0.0.0.0';
/* /*
Set the port range for WebRTC communication. This range is used for the dynamic allocation of UDP ports for media streams. Set the port range for WebRTC communication. This range is used for the dynamic allocation of UDP ports for media streams.
@@ -58,15 +91,37 @@ const IPv4 = getIPv4(); // Replace with the appropriate IPv4 address for your en
Note: Note:
- When running in Docker, use 'network mode: host' for improved performance. - When running in Docker, use 'network mode: host' for improved performance.
- Alternatively, enable 'webRtcServerActive: true' mode for better scalability. - Alternatively, enable 'webRtcServerActive: true' mode for better scalability.
- Make sure these port ranges are not blocked by the firewall, if they are, add the necessary rules
*/ */
const rtcMinPort = 40000; const rtcMinPort = process.env.SFU_MIN_PORT || 40000;
const rtcMaxPort = 40100; const rtcMaxPort = process.env.SFU_MAX_PORT || 40100;
const numWorkers = require('os').cpus().length; /*
One worker can handle approximately 100 concurrent participants.
The number of workers cannot exceed the number of available CPU cores.
*/
const numCPUs = os.cpus().length;
const numWorkers = Math.min(process.env.SFU_NUM_WORKERS || numCPUs, numCPUs);
const ffmpegPath = getFFmpegPath(platform); // Used 4 RTMP streams
const ffmpegPath = process.env.FFMPEG_PATH || getFFmpegPath(platform);
module.exports = { module.exports = {
systemInfo: {
os: {
type: os.type(),
release: os.release(),
arch: os.arch(),
},
cpu: {
cores: os.cpus().length,
model: os.cpus()[0].model,
speed: os.cpus()[0].speed + ' MHz',
},
memory: {
total: (os.totalmem() / 1024 / 1024 / 1024).toFixed(2) + ' GB',
},
},
console: { console: {
/* /*
timeZone: Time Zone corresponding to timezone identifiers from the IANA Time Zone Database es 'Europe/Rome' default UTC timeZone: Time Zone corresponding to timezone identifiers from the IANA Time Zone Database es 'Europe/Rome' default UTC
@@ -85,8 +140,8 @@ module.exports = {
trustProxy: false, // Enables trust for proxy headers (e.g., X-Forwarded-For) based on the trustProxy setting trustProxy: false, // Enables trust for proxy headers (e.g., X-Forwarded-For) based on the trustProxy setting
ssl: { ssl: {
// ssl/README.md // ssl/README.md
cert: '../ssl/cert.pem', cert: process.env.SSL_CERT || '../ssl/cert.pem',
key: '../ssl/key.pem', key: process.env.SSL_KEY || '../ssl/key.pem',
}, },
cors: { cors: {
/* /*
@@ -704,17 +759,17 @@ module.exports = {
webRtcServerActive: false, webRtcServerActive: false,
webRtcServerOptions: { webRtcServerOptions: {
listenInfos: [ listenInfos: [
// { protocol: 'udp', ip: '0.0.0.0', announcedAddress: IPv4, port: rtcMinPort }, // { protocol: 'udp', ip: listenIP, announcedAddress: IPv4, port: rtcMinPort },
// { protocol: 'tcp', ip: '0.0.0.0', announcedAddress: IPv4, port: rtcMinPort }, // { protocol: 'tcp', ip: listenIP, announcedAddress: IPv4, port: rtcMinPort },
{ {
protocol: 'udp', protocol: 'udp',
ip: '0.0.0.0', ip: listenIP,
announcedAddress: IPv4, announcedAddress: IPv4,
portRange: { min: rtcMinPort, max: rtcMinPort + numWorkers }, portRange: { min: rtcMinPort, max: rtcMinPort + numWorkers },
}, },
{ {
protocol: 'tcp', protocol: 'tcp',
ip: '0.0.0.0', ip: listenIP,
announcedAddress: IPv4, announcedAddress: IPv4,
portRange: { min: rtcMinPort, max: rtcMinPort + numWorkers }, portRange: { min: rtcMinPort, max: rtcMinPort + numWorkers },
}, },
@@ -727,13 +782,13 @@ module.exports = {
// { protocol: 'tcp', ip: IPv4, portRange: { min: rtcMinPort, max: rtcMaxPort } }, // { protocol: 'tcp', ip: IPv4, portRange: { min: rtcMinPort, max: rtcMaxPort } },
{ {
protocol: 'udp', protocol: 'udp',
ip: '0.0.0.0', ip: listenIP,
announcedAddress: IPv4, announcedAddress: IPv4,
portRange: { min: rtcMinPort, max: rtcMaxPort }, portRange: { min: rtcMinPort, max: rtcMaxPort },
}, },
{ {
protocol: 'tcp', protocol: 'tcp',
ip: '0.0.0.0', ip: listenIP,
announcedAddress: IPv4, announcedAddress: IPv4,
portRange: { min: rtcMinPort, max: rtcMaxPort }, portRange: { min: rtcMinPort, max: rtcMaxPort },
}, },

عرض الملف

@@ -1,6 +1,6 @@
{ {
"name": "mirotalksfu", "name": "mirotalksfu",
"version": "1.7.90", "version": "1.7.91",
"description": "WebRTC SFU browser-based video calls", "description": "WebRTC SFU browser-based video calls",
"main": "Server.js", "main": "Server.js",
"scripts": { "scripts": {
@@ -59,7 +59,7 @@
"dependencies": { "dependencies": {
"@mattermost/client": "10.6.0", "@mattermost/client": "10.6.0",
"@ngrok/ngrok": "1.4.1", "@ngrok/ngrok": "1.4.1",
"@sentry/node": "^9.8.0", "@sentry/node": "^9.9.0",
"axios": "^1.8.4", "axios": "^1.8.4",
"chokidar": "^4.0.3", "chokidar": "^4.0.3",
"colors": "1.4.0", "colors": "1.4.0",
@@ -68,6 +68,7 @@
"crypto-js": "4.2.0", "crypto-js": "4.2.0",
"discord.js": "^14.18.0", "discord.js": "^14.18.0",
"dompurify": "^3.2.4", "dompurify": "^3.2.4",
"dotenv": "^16.4.7",
"express": "4.21.2", "express": "4.21.2",
"express-openid-connect": "^2.18.0", "express-openid-connect": "^2.18.0",
"fluent-ffmpeg": "^2.1.3", "fluent-ffmpeg": "^2.1.3",