0

am using ffmpeg with fluent-ffmpeg to get a thumbnail from a video like this

ffmpeg({
  source: `../../uploadedVideo/${filepath}`,
}).takeScreenshots({
  filename: "example.jpg",
  timemarks: [2, 4, 6, 8],
  folder: "../../thumbnail/",
});

but what i wanna do is instead of saving the thumbnail to a folder i wanna send it as an api response , here is the whole code.

const ffmpegPath = require("@ffmpeg-installer/ffmpeg").path;
const ffmpeg = require("fluent-ffmpeg");
ffmpeg.setFfmpegPath(ffmpegPath);

router.post("/upload", (req, res) => {

  const file = req.files.video;
  const filepath = `${uuid()}${path.extname(file.name)}`;
  
  // imagine the file is saved to the server at this point
  
  ffmpeg({
    source: `../../uploadedVideo/${filepath}`,
  }).takeScreenshots({
    filename: "example.jpg",
    timemarks: [2, 4, 6, 8],
    folder: "../../thumbnail/",
  });

  res.send({ msg: "success", thumbnail });

});

Any help or suggestion will be appreciated.

Ghost
  • 81
  • 1
  • 9
  • When you say "send it as an api response" do you want to receive the jpg files as a byte array directly from ffmpeg instead of you reading the thumbnail file? – kesh Mar 22 '22 at 14:27
  • so right now its saving the images to a file in a folder but like you said i wanna receive the jpg files as a byte array directly from ffmpeg and send it as a response. can i use pipe() here? – Ghost Mar 23 '22 at 21:53

1 Answers1

0

In FFmpeg, the following is what you need to run for each screenshot time t:

ffmpeg -ss t -i source.mp4 -f mjpeg -vframe 1 -s wxh -

and subprocess' stdout spits out jpeg data with the frame size of width w by height h. So you need to call this line 4 times, at t = 2, 4, 6, & 8 (and that's actually what fluent-ffmpeg does.

Now, the part I'm not sure is how all this translates to fluent-ffmpeg. You're correct, you need to use pipe(). Here is my rough take (I haven't used JavaScript in years so forgive me if I mess something up)


var outStream = fs.createWriteStream('/path/to/output.mp4');

ffmpeg(`../../uploadedVideo/${filepath}`)
  .format('mjpeg') // -f mjpeg
  .frames(1) // -vframes 1
  .size('320x240') // -s 320x240 : w = 320, h = 240
  .on('error', function(err) {
    console.log('An error occurred: ' + err.message);
  })
  .on('end', function() {
    console.log('Processing finished !');
  })
  .pipe(outStream, { end: true });

I modified an example on fluent-ffmpeg documentation.

kesh
  • 4,515
  • 2
  • 12
  • 20