João Santiago
João Santiago

Reputation: 33

Subtitles in video with NodeJS and FFMpeg Fluent Api

I try to include subtitles (srt) in na vídeo stream with Node JS and FFMpeg... I’m try this away:

 var command = ffmpeg(file.createReadStream())
    .input("C:\\code.srt").videoCodec('copy')
  .videoCodec('libvpx').audioCodec('libvorbis').format('webm')
  .audioBitrate(128)
  .videoBitrate(1024)
    .inputFPS(75)
  .outputOptions([
    '-deadline realtime',
    '-error-resilient 1'
  ])

And I got this error:

[Error: ffmpeg exited with code 1: Encoder (codec none) not found for output stream #0:2

Try this too, with --vf subititles= of documentation of FFMpeg and I’ve got this error:

var command = ffmpeg(file.createReadStream())
      .videoCodec('libvpx').audioCodec('libvorbis').format('webm')
      .audioBitrate(128)
      .videoBitrate(1024)
        .inputFPS(75)
      .outputOptions([
        '-deadline realtime',
        '-vf subtitles=C:\\code.srt',
        '-error-resilient 1'
      ])

Error: ffmpeg exited with code 1: Error opening filters!

Someone knows a away of embed subtitles in vídeo with FFMpeg Fluent Api in Node.JS

Sorry my English, I’m Brazilian! Thank's so much

Upvotes: 2

Views: 5573

Answers (1)

abhi
abhi

Reputation: 131

I solved this by dividing the task into two parts

  1. Add subtitles and save the video locally code:

    var addSubtitles = function(key, callback) {
        console.log("inside addSubtitles");
        ffmpeg('./' + key + '.mp4')
            .videoCodec('libx264')
            .audioCodec('libmp3lame')
            .outputOptions(
                '-vf subtitles=./jellies.srt'
            )
            .on('error', function(err) {
                callback(true, err)
            })
            .save('./moviewithsubtitle.mp4')
            .on('end', function() {
                callback(false, "done");
            })
    }
    
  2. Send the video with subtitle

    var streaming = function(req, res, newpath) {
        var path = './' + newpath + '.mp4';
        var stat = fs.statSync(path);
        var total = stat.size;
        if (req.headers['range']) {
            var range = req.headers.range;
            var parts = range.replace(/bytes=/, "").split("-");
            var partialstart = parts[0];
            var partialend = parts[1];
    
            var start = parseInt(partialstart, 10);
            var end = partialend ? parseInt(partialend, 10) : total - 1;
            var chunksize = (end - start) + 1;
            console.log('RANGE: ' + start + ' - ' + end + ' = ' + chunksize);
    
            var file = fs.createReadStream(path, {
                start: start,
                end: end
            });
            res.writeHead(206, {
                'Content-Range': 'bytes ' + start + '-' + end + '/' + total,
                'Accept-Ranges': 'bytes',
                'Content-Length': chunksize,
                'Content-Type': 'video/mp4'
            });
            file.pipe(res);
        } else {
            console.log('ALL: ' + total);
            res.writeHead(200, {
                'Content-Length': total,
                'Content-Type': 'video/mp4'
            });
            fs.createReadStream(path).pipe(res);
        }
    }
    

So now my whole program becomes

    var ffmpeg = require('fluent-ffmpeg');
    var fs = require('fs');
    var express = require('express');
    var app = express();
    var uuid = require('node-uuid');
    var port = 8000;


    var addSubtitles = function(key, callback) {
        console.log("inside addSubtitles");
        ffmpeg('./' + key + '.mp4')
            .videoCodec('libx264')
            .audioCodec('libmp3lame')
            .outputOptions(
                '-vf subtitles=./jellies.srt'
            )
            .on('error', function(err) {
                callback(true, err)
            })
            .save('./moviewithsubtitle.mp4')
            .on('end', function() {
                callback(false, "done");
            })
    }

    var streaming = function(req, res, newpath) {
        var path = './' + newpath + '.mp4';
        var stat = fs.statSync(path);
        var total = stat.size;
        if (req.headers['range']) {
            var range = req.headers.range;
            var parts = range.replace(/bytes=/, "").split("-");
            var partialstart = parts[0];
            var partialend = parts[1];

            var start = parseInt(partialstart, 10);
            var end = partialend ? parseInt(partialend, 10) : total - 1;
            var chunksize = (end - start) + 1;
            console.log('RANGE: ' + start + ' - ' + end + ' = ' + chunksize);

            var file = fs.createReadStream(path, {
                start: start,
                end: end
            });
            res.writeHead(206, {
                'Content-Range': 'bytes ' + start + '-' + end + '/' + total,
                'Accept-Ranges': 'bytes',
                'Content-Length': chunksize,
                'Content-Type': 'video/mp4'
            });
            file.pipe(res);
        } else {
            console.log('ALL: ' + total);
            res.writeHead(200, {
                'Content-Length': total,
                'Content-Type': 'video/mp4'
            });
            fs.createReadStream(path).pipe(res);
        }
    }



    app.get('/subs', function(req, res) {
        addSubtitles("movie", function(error, newpath) {
            if (error) {
                res.send("error : " + error)
            } else {
                console.log("done");
                res.end();
            }
        })
    })


    app.get('/', function(req, res) {
        streaming(req, res, "moviewithsubtitle");
    })

    app.listen(port);
    console.log("the server is running at port :", port);

Upvotes: 9

Related Questions