Reputation: 45
I was trying to add subtitles in node js by -vf filter , and at that time it is giving the error cannot open output path , which was working fine before adding subtitles , which had compilled vedio and autput successfully
here is my code before adding subtitle
shuffleArrayVedios : (array) => {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
},
compile:()=>{
return new Promise(async (resolve, reject) => {
try {
const videosDir = path.join(__dirname, '../public/images'); // Directory containing video files
const outputVideoPath = path.join(__dirname, '../public/videos', 'output.mp4'); // Output video path
const audioFilePath = path.join(__dirname, '../voiceOver', 'voiceover.wav'); // Path to the audio file
const subtitlesFilePath = path.join(__dirname, '../voiceOver', 'subtitles.srt'); // Path to the subtitles file
console.log("Download started");
console.log("Audio file path:", audioFilePath);
console.log("Subtitles file path:", subtitlesFilePath);
// Get the list of video files
let videoFiles = fs.readdirSync(videosDir).filter(file => file.match(/^vid\d+\.mp4$/));
// Shuffle video files
videoFiles =module.exports. shuffleArrayVedios(videoFiles);
// Create a new FFmpeg command
const command = ffmpeg();
// Add video inputs
videoFiles.forEach(video => {
command.input(path.join(videosDir, video));
});
// Add audio input separately
command.input(audioFilePath);
// Add filter_complex for concatenating videos
const filterComplex = [
`concat=n=${videoFiles.length}:v=1:a=0[outv]`, // Concatenate video files
`[${videoFiles.length}:a]atempo=1.25[a]` // Adjust the audio speed; `1.5` means 1.5x speed
];
// Adjust the map options to correctly handle the video and modified audio
command
.complexFilter(filterComplex)
.outputOptions(['-map [outv]', '-map [a]', '-shortest']) // Map adjusted video and audio, and limit to the shortest stream
.output(outputVideoPath)
.on('start', (commandLine) => {
console.log('Spawned FFmpeg with command: ' + commandLine);
})
.on('progress', (progress) => {
console.log('Processing: ' + JSON.stringify(progress) + '% done');
})
.on('end', () => {
console.log('Video compilation finished!');
resolve();
})
.on('error', (err) => {
console.error('Error during video compilation:', err);
reject(err);
})
.run();
} catch (err) {
console.error('Error during processing:', err);
reject(err);
}
});
},
here is my code after adding the subtitles
compile: () => {
return new Promise(async (resolve, reject) => {
try {
const videosDir = path.join(__dirname, '../public/images'); // Directory containing video files
const outputVideoPath = path.join(__dirname, '../public/videos', 'output.mp4'); // Output video path
const audioFilePath = path.join(__dirname, '../voiceOver', 'voiceover.wav'); // Path to the audio file
const subtitlesFilePath = path.join(__dirname, '../voiceOver', 'subtitles.srt'); // Path to the subtitles file
console.log("Download started");
console.log("Audio file path:", audioFilePath);
console.log("Subtitles file path:", subtitlesFilePath);
// Get the list of video files
let videoFiles = fs.readdirSync(videosDir).filter(file => file.match(/^vid\d+\.mp4$/));
// Shuffle video files
videoFiles = module.exports.shuffleArrayVedios(videoFiles);
// Create a new FFmpeg command
const command = ffmpeg();
// Add video inputs
videoFiles.forEach(video => {
command.input(path.join(videosDir, video));
});
// Add audio input separately
command.input(audioFilePath);
// Add filter_complex for concatenating videos
const filterComplex = [
`concat=n=${videoFiles.length}:v=1:a=0[outv]`, // Concatenate video files
`[${videoFiles.length}:a]atempo=1.25[a]` // Adjust the audio speed; `1.25` means 1.25x speed
];
// Adjust the map options to correctly handle the video and modified audio
command
.complexFilter(filterComplex)
.outputOptions(['-map [outv]', '-map [a]', '-shortest']) // Map adjusted video and audio, and limit to the shortest stream
// Add subtitles after concatenation
.outputOptions(`-vf subtitles=${subtitlesFilePath}`) // Apply subtitles to the output video
.output(outputVideoPath)
.on('start', (commandLine) => {
console.log('Spawned FFmpeg with command: ' + commandLine);
})
.on('progress', (progress) => {
console.log('Processing: ' + JSON.stringify(progress) + '% done');
})
.on('end', () => {
console.log('Video compilation finished!');
resolve();
})
.on('error', (err) => {
console.error('Error during video compilation:', err);
reject(err);
})
.run();
} catch (err) {
console.error('Error during processing:', err);
reject(err);
}
});
},
and here is the error Download started Audio file path: D:\programming\ai\voiceOver\voiceover.wav Subtitles file path: D:\programming\ai\voiceOver\subtitles.srt GET / 304 73.273 ms - - GET /stylesheets/style.css 304 3.741 ms - - Spawned FFmpeg with command: ffmpeg -i D:\programming\ai\public\images\vid5.mp4 -i D:\programming\ai\public\images\vid2.mp4 -i D:\programming\ai\public\images\vid6.mp4 -i D:\programming\ai\public\images\vid9.mp4 -i D:\programming\ai\public\images\vid7.mp4 -i D:\programming\ai\public\images\vid8.mp4 -i D:\programming\ai\public\images\vid4.mp4 -i D:\programming\ai\public\images\vid3.mp4 -i D:\programming\ai\public\images\vid13.mp4 -i D:\programming\ai\public\images\vid1.mp4 -i D:\programming\ai\public\images\vid10.mp4 -i D:\programming\ai\public\images\vid11.mp4 -i D:\programming\ai\public\images\vid12.mp4 -i D:\programming\ai\voiceOver\voiceover.wav -y -filter_complex concat=n=13:v=1:a=0[outv];[13:a]atempo=1.25[a] -map [outv] -map [a] -shortest -vf subtitles=D:\programming\ai\voiceOver\subtitles.srt D:\programming\ai\public\videos\output.mp4 Error during video compilation: Error: ffmpeg exited with code 4294967274: Error opening output file D:\programming\ai\public\videos\output.mp4. Error opening output files: Invalid argument
at ChildProcess.<anonymous> (D:\programming\ai\node_modules\fluent-ffmpeg\lib\processor.js:180:22)
at ChildProcess.emit (node:events:519:28)
at ChildProcess._handle.onexit (node:internal/child_process:294:12)
Error: Error: ffmpeg exited with code 4294967274: Error opening output file D:\programming\ai\public\videos\output.mp4. Error opening output files: Invalid argument
at ChildProcess.<anonymous> (D:\programming\ai\node_modules\fluent-ffmpeg\lib\processor.js:180:22)
at ChildProcess.emit (node:events:519:28)
at ChildProcess._handle.onexit (node:internal/child_process:294:12)
Error [ERR_HTTP_HEADERS_SENT]: D:\programming\ai\views\layout.hbs: Cannot set headers after they are sent to the client at ServerResponse.setHeader (node:_http_outgoing:659:11) at ServerResponse.header (D:\programming\ai\node_modules\express\lib\response.js:767:10) at ServerResponse.contentType (D:\programming\ai\node_modules\express\lib\response.js:595:15) at ServerResponse.send (D:\programming\ai\node_modules\express\lib\response.js:145:14) at done (D:\programming\ai\node_modules\express\lib\response.js:1004:10) at D:\programming\ai\node_modules\hbs\lib\hbs.js:106:11 at Object.done (D:\programming\ai\node_modules\hbs\lib\async.js:74:20) at D:\programming\ai\node_modules\hbs\lib\hbs.js:101:20 at D:\programming\ai\node_modules\hbs\lib\hbs.js:82:11 at Object.done (D:\programming\ai\node_modules\hbs\lib\async.js:74:20)
Upvotes: 0
Views: 73
Reputation: 452
Have you tried escaping all the special characters as mentioned in this related answer: Unable to parse option value xxx.srt as image size in ffmpeg ?
Something like: vf "subtitles='D\:\/programming\/ai\/voiceOver\/subtitles.srt'"
Alternatively, using backslashes like so: vf "subtitles='D\:\\programming\\ai\\voiceOver\\subtitles.srt'"
Upvotes: 1