yahiya
yahiya

Reputation: 45

unable to insert subtitles in ffmpeg i can cornfirm all the pathes are correct

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

Answers (1)

Lyndon Armitage
Lyndon Armitage

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

Related Questions