[mirotalksfu] - add RTMP server and multi-source streaming!, update dep
هذا الالتزام موجود في:
97
app/src/RtmpFile.js
Normal file
97
app/src/RtmpFile.js
Normal file
@@ -0,0 +1,97 @@
|
||||
'use strict';
|
||||
|
||||
const ffmpeg = require('fluent-ffmpeg');
|
||||
const ffmpegInstaller = require('@ffmpeg-installer/ffmpeg');
|
||||
ffmpeg.setFfmpegPath(ffmpegInstaller.path);
|
||||
|
||||
const Logger = require('./Logger');
|
||||
const log = new Logger('RtmpFile');
|
||||
|
||||
class RtmpFile {
|
||||
constructor(socket_id = false, room = false) {
|
||||
this.socketId = socket_id;
|
||||
this.room = room;
|
||||
this.rtmpUrl = '';
|
||||
this.ffmpegProcess = null;
|
||||
}
|
||||
|
||||
async start(inputStream, rtmpUrl) {
|
||||
if (this.ffmpegProcess) {
|
||||
log.debug('Streaming is already in progress');
|
||||
return false;
|
||||
}
|
||||
|
||||
this.rtmpUrl = rtmpUrl;
|
||||
|
||||
try {
|
||||
this.ffmpegProcess = ffmpeg(inputStream)
|
||||
.inputOptions(['-re']) // Read input at native frame rate
|
||||
.outputOptions([
|
||||
'-c:v libx264', // Encode video to H.264
|
||||
'-preset veryfast', // Set preset to very fast
|
||||
'-maxrate 3000k', // Max bitrate for the video stream
|
||||
'-bufsize 6000k', // Buffer size
|
||||
'-g 50', // GOP size
|
||||
'-c:a aac', // Encode audio to AAC
|
||||
'-b:a 128k', // Bitrate for the audio stream
|
||||
'-f flv', // Output format
|
||||
])
|
||||
.output(rtmpUrl)
|
||||
.on('start', (commandLine) => log.info('ffmpeg process starting with command:', commandLine))
|
||||
.on('progress', (progress) => {
|
||||
/* log.debug('Processing', progress); */
|
||||
})
|
||||
.on('error', (err, stdout, stderr) => {
|
||||
log.debug('Error: ' + err.message);
|
||||
this.ffmpegProcess = null;
|
||||
if (!err.message.includes('Exiting normally')) {
|
||||
this.handleError(err.message);
|
||||
}
|
||||
})
|
||||
.on('end', () => {
|
||||
log.info('FFmpeg processing finished');
|
||||
this.ffmpegProcess = null;
|
||||
this.handleEnd();
|
||||
})
|
||||
.run();
|
||||
|
||||
log.info('RtmpFile started', rtmpUrl);
|
||||
return true;
|
||||
} catch (error) {
|
||||
log.error('Error starting RtmpFile', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async stop() {
|
||||
if (this.ffmpegProcess && !this.ffmpegProcess.killed) {
|
||||
try {
|
||||
this.ffmpegProcess.kill('SIGTERM');
|
||||
this.ffmpegProcess = null;
|
||||
log.info('RtmpFile stopped');
|
||||
return true;
|
||||
} catch (error) {
|
||||
log.error('Error stopping RtmpFile', error.message);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
log.debug('No RtmpFile process to stop');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
handleEnd() {
|
||||
if (!this.room) return;
|
||||
this.room.send(this.socketId, 'endRTMP', { rtmpUrl: this.rtmpUrl });
|
||||
this.room.rtmpFileStreamer = false;
|
||||
}
|
||||
|
||||
handleError(message) {
|
||||
if (!this.room) return;
|
||||
this.room.send(this.socketId, 'errorRTMP', { message });
|
||||
this.room.rtmpFileStreamer = false;
|
||||
log.error('Error: ' + message);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RtmpFile;
|
||||
المرجع في مشكلة جديدة
حظر مستخدم