How to Extract Frames from the uploaded video through ffmpeg using node js?

12,219

Solution 1

The Foolish mistake was the ';', i forgot to keep it so it is going in infinite loops

var express = require('express');

var app = express();

var bodyParser = require('body-parser');

var path = require('path');

var multer = require('multer');

var cfenv = require('cfenv');

var watson = require('watson-developer-cloud');

var ffmpeg = require('ffmpeg');

var stat = require('fs').statSync;

var zipFolder = require('zip-folder');


app.use(bodyParser.json());

app.use(bodyParser.urlencoded({"extended": false}));

app.use(express.static(__dirname + '/public'));

var storage = multer.diskStorage({
    destination: function(req, file, callback){
        callback(null, './public/class/'); // set the destination
    },
    filename: function(req, file, callback){
        callback(null,'NotUseful.mp4'); // set the file name and extension
    }
});

var upload = multer({storage: storage});
 
 app.upload = upload;
 
 // get the app environment from Cloud Foundry
 var appEnv = cfenv.getAppEnv();

var VisualRecognitionV3 = require('watson-developer-cloud/visual-recognition/v3');

var fs = require('fs');


var visualRecognition = new VisualRecognitionV3({
  version: '2018-03-19',
  iam_apikey: 'aaIFu-fHWBXgj09eVarEQUFlIaTeH9bpgvRqHIJxu_8N'
});

function tosplit(request)
{
    var value = request;
    valueArray = value.split("\\");
    return valueArray;
}

function extsplit(request)
{
    var value = request;
    nameArray = value.split('.');
    return nameArray;
}

function makeZip(pathname,zipname){
        
        zipFolder(pathname,zipname, function(err) {
            
    if(err) {
        console.log('oh no!', err);
        
    } else {
        
        console.log('Zip Created...');
    }
  });
}

app.post('/upload',app.upload.single('video-upl'),function(req,res){
                
    var video_file = fs.createReadStream(req.file.path); // Storing File path
    var video_String = JSON.stringify(video_file); // Converting Json into String of req.file.path
    var video_res = JSON.parse(video_String); // Parsing req.file.path  
    
    var valueArray = tosplit(video_res.path);  //Splitting Path in values
    
    var filenme = req.file.originalname; // Requesting Original File name
    var filnameStringify = JSON.stringify(filenme); //Stringify file original name
    var filnameParse = JSON.parse(filnameStringify); //Parsing file Original name
    
    var filename = extsplit(filnameParse);  // Spliting File name from path
    
    var finalpath = './public/class/'+valueArray[2]; // Path to Video for Extracting Images
    
    var destpath = './public/class/'+filename[0]+'/'; //Destinaton Path to Store Images
    
    var zipdest = './public/class/'+filename[0]; //Destination of File to be Zip
    
    var articleid = extsplit(valueArray[2]);  //For ArticleId through Video Name
        
    try {
    var process = new ffmpeg(finalpath);
    process.then(function (video) {
        // Callback mode
        video.fnExtractFrameToJPG(destpath, {
            frame_rate: 1,
            number: 50,
            keep_pixel_aspect_ratio : true,
            keep_aspect_ratio: true,
            file_name : filename[0]+'_%s'
        }, function (error,files){
                
            if(!error)
                {   
                    var fileJsonStr = JSON.stringify(files);
                    
                    makeZip(zipdest,'./public/class/'+filename[0]+'.zip');
                    
                    console.log(res);
                    
                    res.send(fileJsonStr).responseJSON;
                }
        });
    }, function (err) {
         console.log('Error: ' + err);
    });
  }
    
    catch (e) {
    console.log(e.code);
    console.log(e.msg);
}
});
app.listen(3000);

Solution 2

If you are using the ffmpeg npm package you can simply use the fnExtractFrameToJPG function with a little tweak :

try {
        var process = new ffmpeg(file);
        process.then(function (video) {
            video.fnExtractFrameToJPG("this/is/a/directory", {
                every_n_frames : 1
            }, myCallbackFunction())
        }, function (err) {
            console.log('Error: ' + err);
        });
    } catch (e) {
        console.log(e.code);
        console.log(e.msg);
    }

The every_n_frames param lets you choose the frame interval you want to extract a frame. Some other parameters are available in the doc.

Solution 3

Here's a code snippet that worked for me to extract a single frame at 1min 30secs of the video. Hope it helps :)

var ffmpeg = require('ffmpeg');

try {
  var process = new ffmpeg('./video.mp4');
  process.then(function (video) {
    video.addCommand('-ss', '00:01:30')
    video.addCommand('-vframes', '1')
    video.save('./test.jpg', function (error, file) {
        if (!error)
          console.log('Video file: ' + file);
      });
  }, function (err) {
    console.log('Error: ' + err);
  });
} catch (e) {
  console.log(e.code);
  console.log(e.msg);
}
Share:
12,219

Related videos on Youtube

Aditya Vyas
Author by

Aditya Vyas

Updated on June 04, 2022

Comments

  • Aditya Vyas
    Aditya Vyas almost 2 years

    I have created application in which user uploads a video , from that video i want to extract 50 images using ffmpeg in nodejs, but i am unable to get that file after uploading it in specific folder. I am uploading video through multer as it stores video in specified folder, after that i read that video using read stream but it is not giving proper information on that particular video

    Code:

    var express = require('express');
    
    var app = express();
    
    var bodyParser = require('body-parser');
    
    var path = require('path');
    
    var multer = require('multer');
    
    var cfenv = require('cfenv');
    
    var watson = require('watson-developer-cloud');
    
    var ffmpeg = require('ffmpeg');
    
    app.use(bodyParser.json());
    
    app.use(bodyParser.urlencoded({"extended": false}));
    
    app.use(express.static(__dirname + '/public'));
    
    var storage = multer.diskStorage({
        destination: function(req, file, callback){
            callback(null, './public/class'); // set the destination
        },
        filename: function(req, file, callback){
            callback(null, 199212+ '.avi'); // set the file name and extension
        }
    });
    
    var upload = multer({storage: storage});
     
     app.upload = upload;
     
     // get the app environment from Cloud Foundry
     var appEnv = cfenv.getAppEnv();
    
    var VisualRecognitionV3 = require('watson-developer-cloud/visual-recognition/v3');
    
    var fs = require('fs');
    
    
    var visualRecognition = new VisualRecognitionV3({
      version: '2018-03-19',
      iam_apikey: 'aaIFu-fHWBXgj09eVarEQUFlIaTeH9bpgvRqHIJxu_8N'
    });
    
    
    app.post('/imgtable',app.upload.single('video-upl'),function(req,res){
                    
        var video_file = fs.createReadStream(req.file.path);
                                        
     try {
        var process = new ffmpeg('./public/class/199212.avi');
        process.then(function (video) {
            // Video metadata
            console.log('******************************');
            console.log(video);
            // FFmpeg configuration
            console.log('*********************************');
            console.log(video.info_configuration);
        }, function (err) {
            console.log('Error: ' + err);
        });
    } catch (e) {
        console.log(e.code);
        console.log(e.msg);
    }
    
        
    })
    
    app.listen(3000);`
    
    • Lucbug
      Lucbug over 5 years
      Bumping into this. Having the same situation. Did you find a solution for this ?
    • Aditya Vyas
      Aditya Vyas over 5 years
      yeah i will posting the solution here thanks