[mirotalksfu] - add RTMP server and multi-source streaming!, update dep

هذا الالتزام موجود في:
Miroslav Pejic
2024-06-29 18:49:10 +02:00
الأصل aaf5fe44ed
التزام 3929212631
52 ملفات معدلة مع 3986 إضافات و132 حذوفات

عرض الملف

@@ -0,0 +1,26 @@
# Use a lightweight Node.js image
FROM node:20-slim
# Set working directory
WORKDIR /app
# Copy package.json and install npm dependencies
COPY package.json .
RUN npm install
# Cleanup unnecessary packages and files
RUN npm cache clean --force \
&& rm -rf /tmp/* /var/tmp/* /usr/share/doc/*
# Copy the application code
COPY src src
# Rtmp port
EXPOSE 1935
# Http port
EXPOSE 8081
# Https port
EXPOSE 8043
# Set default command to start the application
CMD ["npm", "start"]

عرض الملف

@@ -0,0 +1,47 @@
# RTMP Streaming
![rtmpStreaming](../rtmpStreaming.jpeg)
For running an `RTMP` (Real-Time Messaging Protocol) server in Node, **[Node-Media-Server](https://github.com/illuspas/Node-Media-Server)** is one of the best options.
## Quick Start
```sh
# Create the config file for the server
$ cp config.template.js config.js
# Install the dependencies
$ npm install
# Start the RTMP Server
$ npm start
```
## Using Docker
```sh
# Create the config file for the server
$ cp config.template.js config.js
# Copy the docker.compose.yml
$ cp docker-compose.template.yml docker-compose.yml
# Pull the official mirotalk rtmp image
$ docker pull mirotalk/nms:latest
# Create and start containers
$ docker-compose up -d
# Check the logs
$ docker logs -f mirotalk-nms
# To stop and remove resources
$ docker-compose down
```
## Dashboard & API
[http://localhost:8081/admin](http://localhost:8081/admin)
[http://localhost:8081/api/server](http://localhost:8081/api/server)
## Custom Configuration
Modify the `config.js` to suit your specific needs.

عرض الملف

@@ -0,0 +1,13 @@
version: '3'
services:
mirotalk-nms:
container_name: mirotalk-nms
image: mirotalk/nms:latest
volumes:
- ./src/config.js/:/app/src/config.js/:ro
ports:
- '1935:1935'
- '8081:8081'
- '8043:8043'
restart: unless-stopped

عرض الملف

@@ -0,0 +1,26 @@
{
"name": "mirotalk-rtmp-nms",
"version": "1.0.0",
"description": "MiroTalk RTMP Node Media Server",
"main": "server.js",
"scripts": {
"start": "node src/server.js",
"start-dev": "nodemon src/server.js"
},
"keywords": [
"rtmp",
"node",
"media",
"server"
],
"author": "Miroslav Pejic",
"license": "AGPLv3",
"dependencies": {
"crypto": "^1.0.1",
"node-media-server": "^2.7.0"
},
"devDependencies": {
"uuid": "10.0.0",
"nodemon": "^3.1.4"
}
}

عرض الملف

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDfzCCAmcCFHLVDcza5/3VZ8U5Vd2LnWRvwME1MA0GCSqGSIb3DQEBCwUAMHsx
CzAJBgNVBAYTAklUMQ4wDAYDVQQIDAVJdGFseTERMA8GA1UECgwITWlyb1RhbGsx
HTAbBgNVBAMMFE1pcm9UYWxrIFJUTVAgU2VydmVyMSowKAYJKoZIhvcNAQkBFhtt
aXJvc2xhdi5wZWppYy44NUBnbWFpbC5jb20wIBcNMjQwNjIwMjE1MDQ4WhgPMjA1
MTExMDUyMTUwNDhaMHsxCzAJBgNVBAYTAklUMQ4wDAYDVQQIDAVJdGFseTERMA8G
A1UECgwITWlyb1RhbGsxHTAbBgNVBAMMFE1pcm9UYWxrIFJUTVAgU2VydmVyMSow
KAYJKoZIhvcNAQkBFhttaXJvc2xhdi5wZWppYy44NUBnbWFpbC5jb20wggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJfFke3Df+0tgei1djU1Af0i4OukeI
UHxWzr3mibVxJ8qtNwukXc0F9XnRXA9kF7WJa+vzuQXQgClH75mrrTNzwV1IWXSZ
nKokogyweHC+XZ/Frdv+yCWyJcC7YrIJVTJNCU+Z4wDBLira35Z2tBTd7UV9gURB
oQZhqeG0b653D1kvb9oEzTJFbmcst5YzEHUfs4CeF6RvOK4q0wD1CXImJYpXrJ02
YbpLyZ8hLZuGq3uDdPOjHXQApxmLhSUgJHnIcHxR/xVFdLyAqP+aTKnozLCS3PZC
yB1lJbuEmPO5WfeQDmL7W3COEtdAdlCNF8VZ09z1AlCKLnp75vi9M04hAgMBAAEw
DQYJKoZIhvcNAQELBQADggEBAHOVKxSt+BGtDFynltp0pfHGyFo1sr5ULUams67s
LQuiOm0Iuw1kXRA9Yf/hAcL12/taEBfNqYxveQXe8xbodwobkOpHmyYYLZ+50a8I
+hP15UkmlJb0iy7OkjoalDqVFFN2WQTJK3OqMg4RdJlTMpzDibNYzZWZ6Xaxl670
FDh3xJO9/MweHO/ScGS5RVIdYIdDbFGzzcYHiWpsbcYgYdvsNVofNsZpotWd37/x
CbYImc1RKhRnBQTcnnK0u+6ugD26Yho3eB5f0nbj2gkikDYueYYZG+7uV2w+9QKI
e+nipac/6/ACwo1ZMsEYR3arjdLN8Rxr39s5PStP63EkGv4=
-----END CERTIFICATE-----

عرض الملف

@@ -0,0 +1,30 @@
'use strict';
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 60,
ping_timeout: 30,
},
http: {
port: 8081,
allow_origin: '*',
},
https: {
port: 8043,
key: __dirname + '/key.pem',
cert: __dirname + '/cert.pem',
},
auth: {
api: true,
api_user: 'mirotalk',
api_pass: 'mirotalkRtmpPassword', // http://localhost:8081/admin
play: false, // Require authentication for playing streams
publish: false, // Require authentication for publishing streams
secret: 'mirotalkRtmpSecret', // Check the sign.js file to generate a valid RTMP URL
},
};
module.exports = config;

عرض الملف

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAyXxZHtw3/tLYHotXY1NQH9IuDrpHiFB8Vs695om1cSfKrTcL
pF3NBfV50VwPZBe1iWvr87kF0IApR++Zq60zc8FdSFl0mZyqJKIMsHhwvl2fxa3b
/sglsiXAu2KyCVUyTQlPmeMAwS4q2t+WdrQU3e1FfYFEQaEGYanhtG+udw9ZL2/a
BM0yRW5nLLeWMxB1H7OAnhekbziuKtMA9QlyJiWKV6ydNmG6S8mfIS2bhqt7g3Tz
ox10AKcZi4UlICR5yHB8Uf8VRXS8gKj/mkyp6Mywktz2QsgdZSW7hJjzuVn3kA5i
+1twjhLXQHZQjRfFWdPc9QJQii56e+b4vTNOIQIDAQABAoIBAQC98pSyGzpO6ccF
RKfl460t0p/JEqRNRlNyIwW0SS7ctn7EPZikJCoc7Acj8H4yBogGPc/7vPpWTfyc
7K0aw/Y1sp2Wj371MlTUpFECLQlc7japzfYQg+/FuwGvpqPhWIhLR/PbR752YGfW
X+MhlTP25LEWWL9Yf83cVKOLz53Sbt9KH/baJhpFhXrrxl/1rcR6U7MhZOLlq1aa
XbYwglzd/l20cED1wbCzbxVwl/M73ZIOgn+2vgSxkNCxkZVpGYvE0Tx9S9b3rmtl
OD9WqTS5beoKABXbMPTMdbyekPAnK2pAUs+WmKD8iJ69djKeMj/lO1vQBZOBJzlL
pxteIS7hAoGBAPvbO27SPnMI76lfXDAECNHCq1YLiVpqhctFvcJlM1aQMbWKqYOX
XVho+drGlh/Mf9JpY3rtfd7VNZKbJQRT/6Wf7j7L7WOldClxIhBXxziqOJ/bemJP
ELRau321q5x2aNLGZbioaDgB9fzEm/aPyjRC8JnIvePyksAzXJNw2mtzAoGBAMzM
9w7nyfa16pG14hAdiYkCtB052jZ71sz+Y9XbA12D36EDLxkQ3l5I6FNrvWvu30N8
snG+SMmk8LSjy3b4bv5DPP1Bnh+HQG/5quoG61uODkRC7aIgLCgdbmnggWrI+gV7
E+YM6HMZFVk3Lvo1GobyxsBCLBRCPdfW15nQ0eMbAoGBAJiXtIOpeFLEOEibUUR6
PUmxs5N3e+m/Hn8RKy6LmDY7ORLwB1KGM/Ur7S3jIfP0OAGo/q/tElUfQs0nmJ7t
sbeMlZGQhqzYAvBU7jmOpVKst5ALLzQ/CTTswCojFu2+RDZoJBtkVXiRn5NdH82c
Qvu1Dwdtu7dPMiCnPdDLEFsHAoGBAJjHhr7N13J+f0C4CK6w+jsFk0wCLnFarQE7
/Uo6GiaXDCrXbzkpxllb1kT1KNft2QxFZ/FGXJJgw1heoJhd+J8hlcvwOX+XrFBc
Vk5DXyxrquTtcMzzZz19xzKg0qrQxwNzr4J8uqOyYKSvcBIjr2hgkDg4pR1v1SbB
FRGgIBNlAoGAeMJrhQy5RU6xCG9l8+jH42PhG4+F9pV5EQI0v421KQ4hklgY+pT6
KrTuZp6tjX7hErYNNd77ELDRLZ3p8VlqxuvF3UI6s+I7rRxpXpjSve3si8USYS4L
aKAp6qDc3Vt1e6uin9NwZS6jtDvH8VOIMOHTQYJwUTnjpSLuYIxOzU0=
-----END RSA PRIVATE KEY-----

عرض الملف

@@ -0,0 +1,81 @@
'use strict';
const NodeMediaServer = require('node-media-server');
const config = require('./config');
console.log('Rtmp Server config', {
config: config,
http: {
admin: 'http://localhost:8081/admin',
stats: 'http://localhost:8081/api/server',
streams: 'http://localhost:8081/api/streams',
},
https: {
admin: 'https://localhost:8043/admin',
stats: 'https://localhost:8043/api/server',
streams: 'http://localhost:8043/api/streams',
},
});
const nms = new NodeMediaServer(config);
nms.run();
nms.on('preConnect', (id, args) => {
console.log('[NodeEvent on preConnect]', `id=${id} args=${JSON.stringify(args)}`);
// let session = nms.getSession(id);
// session.reject();
});
nms.on('postConnect', (id, args) => {
console.log('[NodeEvent on postConnect]', `id=${id} args=${JSON.stringify(args)}`);
});
nms.on('doneConnect', (id, args) => {
console.log('[NodeEvent on doneConnect]', `id=${id} args=${JSON.stringify(args)}`);
});
nms.on('prePublish', (id, StreamPath, args) => {
console.log('[NodeEvent on prePublish]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
// let session = nms.getSession(id);
// session.reject();
});
nms.on('postPublish', (id, StreamPath, args) => {
console.log('[NodeEvent on postPublish]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
nms.on('donePublish', (id, StreamPath, args) => {
console.log('[NodeEvent on donePublish]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
nms.on('prePlay', (id, StreamPath, args) => {
console.log('[NodeEvent on prePlay]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
nms.on('postPlay', (id, StreamPath, args) => {
console.log('[NodeEvent on postPlay]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
// let session = nms.getSession(id);
// session.reject();
});
nms.on('donePlay', (id, StreamPath, args) => {
console.log('[NodeEvent on donePlay]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
nms.on('logMessage', (...args) => {
// custom logger log message handler
});
nms.on('errorMessage', (...args) => {
// custom logger error message handler
});
nms.on('debugMessage', (...args) => {
// custom logger debug message handler
});
nms.on('ffDebugMessage', (...args) => {
// custom logger ffmpeg debug message handler
});

عرض الملف

@@ -0,0 +1,58 @@
'use strict';
const crypto = require('crypto-js');
const { v4: uuidv4 } = require('uuid');
/**
* Generates an RTMP URL with an expiration timestamp and a hash value.
*
* @param {string} baseURL - The base URL of the RTMP server.
* @param {string} streamPath - The path to the stream.
* @param {string} secretKey - The secret key used for generating the hash.
* @param {number} expirationHours - The number of hours until the URL expires.
* @returns {string} - The generated RTMP URL for Node Media Server.
*/
function generateRTMPUrl(baseURL, streamPath, secretKey, expirationHours = 8) {
// Current timestamp in seconds
const currentTime = Math.floor(Date.now() / 1000);
// Expiration time (current time + expirationHours in seconds)
const expirationTime = currentTime + expirationHours * 3600;
// Generate the hash value
const hashValue = crypto.MD5(`${streamPath}-${expirationTime}-${secretKey}`).toString();
// Construct the final request address
const rtmpUrl = `${baseURL}${streamPath}?sign=${expirationTime}-${hashValue}`;
// Print some log
log.debug('generateRTMPUrl', {
currentTime: currentTime,
expirationTime: expirationTime,
hashValue: hashValue,
rtmpUrl: rtmpUrl,
});
return rtmpUrl;
}
// Example usage
const baseURL = 'rtmp://localhost:1935';
const streamKey = uuidv4();
const streamPath = '/live/' + streamKey; // path/stream-key
const secretKey = 'mirotalkRtmpSecret';
const expirationHours = 8;
// Run: node sign.js
const rtmpUrl = generateRTMPUrl(baseURL, streamPath, secretKey, expirationHours);
console.log('Generated RTMP URL:', rtmpUrl);
/*
OBS:
- Server: rtmp://localhost:1935/live
- StreamKey: demo?sign=1719169535-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
FFMPEG:
- ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -maxrate 3000k -bufsize 6000k -vf "scale=-2:720" -g 50 -c:a aac -b:a 128k -f flv "rtmp://localhost:1935/live/demo?sign=1719169535-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
*/