Extract the frame (in image format) at exactly every minute (or second) from a video (by ffmpeg)

6,245

The fps filter is designed to smartly drop/duplicate frames to match the output fps based on the input fps. If you ask it to output one frame every minute, it's going to select one frame at the center of the 00:00-01:00 window and drop all the others, thus why you get frames at 00:30, 01:30, etc..

Have you considered making a bat/bash script that does this ?

for i in 0..50
   ffmpeg -ss %i:oo -i input.mp4 -vframes 1 out-%i.png

You can also do the following if you wish to get screenshots at 01:00, 02:00 [..] instead of 00:30, 01:30 [..] :

ffmpeg -ss 00:30 -i input.mp4 -start_number 0 -vf fps=1/60 "B 00-%02d-00.000.png"
Share:
6,245

Related videos on Youtube

midnite
Author by

midnite

Please be constructive. Please be helpful. Please don't just upvote, help solving it together is a lot more appreciated :)

Updated on September 18, 2022

Comments

  • midnite
    midnite almost 2 years

    Motivation: I would like to seek the frame, then take high quality and exact time screenshots (images) from a video.

    The video is length is 00:48:43.71 and 23.98 fps (we can think it is 24 fps, isn't it?).


    With reference from this webpage: Create a thumbnail image every X seconds of the video

    I wrote some commands that grab a frame every hour, every minute, and every second.

    After exterminating the images, the screenshots are in fact taken from the half hour, half minute, and half second. You will understand shortly.

    For example, the command to grab a frame every minute, it is in fact extracting the frame at the half minute, which means the 00:00:30 , 00:01:30 , 00:02:30 , and so on. That is why I name to filename as follow:

    ffmpeg -i "video.mp4" -start_number 0 -vf fps=1/60 "B 00-%02d-30.000.png"
    

    (adding the "B" prefix is to prevent overwriting by different commands.)

    For example, to grab a frame every second from 00:03:00 to 00:04:00, the commend is:

    ffmpeg -i "video.mp4" -start_number 0 -vf fps=1 -ss 00:03:00 -to 00:04:00 "C 00-03-%02d.500.png"
    

    To verify them, we can extract all the frames from 00:03:29 to 00:03:31 :

    ffmpeg -copyts -ss 00:03:29 -i "video.mp4" -start_number 0 -to 00:03:31 "D 00-03-29.%03d.png"
    

    We may check the following image files are identical:

    D 00:03:29.012.png is identical to C 00:03:29.500.png.

    D 00:03:29.024.png is identical to B 00:03:30.000.png.

    D 00:03:29.036.png is identical to C 00:03:30.500.png.


    Those are my findings from trials and errors this morning. Here comes my question:

    Let's take "extract a frame at exactly every minute" as an example, how can we get / what is the command to get the frames 00:00:00.000 , 00:00:01.000, 00:00:02.000 , and so on?

    I have just heard of ffmpeg this morning. I still do not know what -copyts means (after reading the docs) and when I need to put -ss position before -i and when to put it at the output part. So please do correct me if I am using the wrong commands.

  • midnite
    midnite almost 9 years
    Oh the second method is smart. But we still have problems getting the first half of the minute/second/etc. I wonder if there is another command/param, in stead of fps filter, to get to job done nicely? For the first method, as (i think) ffmpeg is processing all the frames, and just dropping the unwanted ones, will the command become very very slow when i reaches the final part of the video? If it is handy, please tell me also what is -copyts and where to put -ss. Or i am ok to ask them in another question threads :)
  • Tallboy
    Tallboy almost 6 years
    @Ely can you put that in your answer? I just spent like an hour trying to figure out why it didnt work and I didn't even notice this comment lol (kill me)