Hi community, i am newby related all the things related with video and audio containers, and I am trying to develop a multi party voice call app for things related with security so everything should be record, no matter which peer is the one who started the recording.
What I want to achieve is every time someone creates the room, start recording everything that happens there.
The feature of the voice call application room is working great using mediasoup.
When I try to do the recording following the demo shared in the documentation, I was only able to record only one peer. It is like ffmpeg process is consuming only one of the plain transports I am configuring.
My question is:
Is there any way for doing a single container file with all the producers of that room?
Thanks in advance, any help will be well received this is driving me crazy?
I have also same problem same as you ,
but i record each user individually
but you can know which peer is related to a specific room
i have a question if you know please help me
i record a peer video but after on/off the camera the new video streams come into the video but the old. video part are losing , my expectation is to append new video part at continue of the first one not overwrite
thanks for replaying
this is my code
startRecordingFfmpeg(role) {
// Return a Promise that can be awaited
let recResolve;
const promise = new Promise((res, _rej) => {
recResolve = res;
});
const useAudio = this.audioEnabled();
const useVideo = this.videoEnabled();
// const useH264 = h264Enabled();
// const cmdProgram = "ffmpeg"; // Found through $PATH
const cmdProgram = FFmpegStatic; // From package "ffmpeg-static"
let cmdInputPath = `${__dirname}/recording/${this.user_id}.sdp`;
let cmdOutputPath = `${__dirname}/recording/${this.user_id}.webm`;
let cmdCodec = "";
let cmdFormat = "-f webm -flags global_header";
// Check if the output file already exists
const outputFileExists = fs.existsSync(cmdOutputPath);
// Update the cmdFormat for concatenation
if (outputFileExists) {
cmdOutputPath = -movflags +faststart -flags global_header ${cmdOutputPath}
;
}
// Ensure correct FFmpeg version is installed
const ffmpegOut = Process.execSync(cmdProgram + " -version", {
encoding: "utf8",
});
const ffmpegVerMatch = /ffmpeg version (\d+)\.(\d+)\.(\d+)/.exec(ffmpegOut);
let ffmpegOk = false;
if (ffmpegOut.startsWith("ffmpeg version git")) {
// Accept any Git build (it's up to the developer to ensure that a recent
// enough version of the FFmpeg source code has been built)
ffmpegOk = true;
} else if (ffmpegVerMatch) {
const ffmpegVerMajor = parseInt(ffmpegVerMatch[1], 10);
if (ffmpegVerMajor >= 4) {
ffmpegOk = true;
}
}
if (!ffmpegOk) {
console.error("FFmpeg >= 4.0.0 not found in $PATH; please install it");
process.exit(1);
}
if (useAudio) {
cmdCodec += " -map 0:a:0 -c:a copy";
}
if (useVideo) {
cmdCodec += " -map 0:v:0 -c:v copy";
// if (useH264) {
// cmdInputPath = `${__dirname}/recording/input-h264.sdp`;
// cmdOutputPath = `${__dirname}/recording/output-ffmpeg-h264.mp4`;
// // "-strict experimental" is required to allow storing
// // OPUS audio into MP4 container
// cmdFormat = "-f mp4 -strict experimental";
// }
}
// Run process
// Run process
const cmdArgStr = [
“-nostdin”,
“-protocol_whitelist file,rtp,udp”,
“-loglevel debug”,
// “-analyzeduration 5M”,
// “-probesize 5M”,
“-fflags +genpts”,
-i ${cmdInputPath}
,
cmdCodec,
cmdFormat,
“-muxdelay 0.1”, // Adjust the value as needed
${cmdOutputPath}
,
].join(" ").trim();
// console.log(`Run command: ${cmdProgram} ${cmdArgStr}`);
let recProcess = Process.spawn(cmdProgram, cmdArgStr.split(/\s+/));
this.recProcess = recProcess;
recProcess.on("error", (err) => {
console.error("Recording process error:", err);
});
recProcess.on("exit", (code, signal) => {
console.log("Recording process exit, code: %d, signal: %s", code, signal);
this.recProcess = null;
// this.stopMediasoupRtp();
if (!signal || signal === "SIGINT") {
console.log("Recording stopped");
} else {
console.warn(
"Recording process didn't exit cleanly, output file might be corrupt"
);
}
});
// FFmpeg writes its logs to stderr
recProcess.stderr.on("data", (chunk) => {
// console.log("chuck", chunk.toString());
console.log("called","audio:",useAudio,"video:",useVideo);
chunk
.toString()
.split(/\r?\n/g)
.filter(Boolean) // Filter out empty strings
.forEach((line) => {
if (line.startsWith("ffmpeg version")) {
setTimeout(() => {
recResolve();
}, 1000);
}
});
});
return promise;
}