الملفات
codepill-sfu/app/src/RtmpFile.js
2024-07-01 22:38:01 +02:00

98 أسطر
3.3 KiB
JavaScript

'use strict';
const config = require('./config');
const ffmpegPath = config.server.rtmp && config.server.rtmp.ffmpeg ? config.server.rtmp.ffmpeg : '/usr/bin/ffmpeg';
const ffmpeg = require('fluent-ffmpeg');
ffmpeg.setFfmpegPath(ffmpegPath);
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) => {
this.ffmpegProcess = null;
if (!err.message.includes('Exiting normally')) {
this.handleError(err.message, stdout, stderr);
}
})
.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, stdout, stderr) {
if (!this.room) return;
this.room.send(this.socketId, 'errorRTMP', { message });
this.room.rtmpFileStreamer = false;
log.error('Error: ' + message, { stdout, stderr });
}
}
module.exports = RtmpFile;