FFMPEG multiple screenshots command

760 views Asked by At

iam trying to code a function which creates images from video files using ffmpeg.

But now i want to know how can i make that with ffmpeg commands exactly, because i use wrapper and now i have some limitations, so i must go in the native way.

So, first of all i have decided to use a Wrapper which is called node-fluent-ffmpeg.

And this is my work-around with the Wrapper:

ffmpeg({
        source: `The video file...`,
      })
        .on("filenames", async (filenames) => {
        })
        .on("error", function (err) {
          console.log("Error in filenames section: " + JSON.stringify(err));
        })
        .on("end", function () {
          console.log("Screenshots taken");
        })
        .screenshots({
          count: 60,
          folder: "tmp/",
          filename: "thumbnail-at-%i.png",
          size: "1600x900",
        })
        .on("end", function (stdout, stderr) {
            let newImg = await fs.createReadStream(`/tmp/${img}`);
            destparams = await {
              Bucket: dstBucket,
              Key: "uploaded-" + img,
              Body: newImg,
              ContentType: "image",
            };
           await s3.putObject(destparams).promise();

});

Notes for understanding me better:

  • I still want to make it in node.js

  • Let's assume the file is: "The video file..."

  • I am taking 60 screenshots from the video in a random way, like it does not matter the length of the video it will just take 60 screenshots from start until the end of the video.

  • Every screenshot taken will have a prefixed and ordered number and name for every frame. For example: thumbnail-at-1.png, thumbnail-at-2.png, thumbnail-at-3.png and it continues until it reaches the 60 screenshot limit.

  • Every screenshot will be saved with a 1600x900 resolution.

  • Every screenshot will be saved in the TMP folder.

  • Do not mind reading this: After all I'll upload every screenshot to a s3 bucket.

  • I had search trough a lot of old forums, but it seems that ffmpeg has a poor documentation (I have been stuck, so hard to understand).

So my main goal is:

How i can make exactly that function that i have shown in the code sample and the quick notes, with the FFMPEG commands? (Not with the wrapper)

(Sorry that i'm trying to make it simpler)

I mean, Which commands i must use, with the FFMPEG commands in the following code sample?

By the way: it is node.js,

Do not really know what to do, sorry

spawnSync(
      "/opt/ffmpeg/ffmpeg",
      [
        "-i",
        ``,
        "-f",
        "",
        ``
      ],
      { stdio: "inherit" }
 );

Thanks for your patience!

Enviroment:

  • Node.js 12.x
  • FFMPEG (4.3.1)
1

There are 1 answers

1
Lawrence Cherone On BEST ANSWER

The main problem would be getting the duration of the video, so as long as you have ffprobe you should be able to do this:

Get duration then divide by 60, convert the number to a timestamp.

ffprobe -v quiet -print_format json -show_format -show_streams "<FILENAME>"

Then parse the JSON for format.duration, then divide it by the number of screens you want.

Then loop over 60 times to get a single frame at a specific timestamp by doing dateformat('H:i:s', i * (format.duration / 60)) (pseudo):

ffmpeg -ss 00:00:00 -i "infile.mp4" -t 00:00:01 -r 1 -f mjpeg "thumbnail-at-0.png"
ffmpeg -ss 00:00:10 -i "infile.mp4" -t 00:00:01 -r 1 -f mjpeg "thumbnail-at-1.png"
ffmpeg -ss 00:00:20 -i "infile.mp4" -t 00:00:01 -r 1 -f mjpeg "thumbnail-at-2.png"
...
ffmpeg -ss 00:09:30 -i "infile.mp4" -t 00:00:01 -r 1 -f mjpeg "thumbnail-at-57.png"
ffmpeg -ss 00:09:40 -i "infile.mp4" -t 00:00:01 -r 1 -f mjpeg "thumbnail-at-58.png"
ffmpeg -ss 00:09:50 -i "infile.mp4" -t 00:00:01 -r 1 -f mjpeg "thumbnail-at-59.png"