I am attempting to extract frames with their timestamps from videos using the command line, but I am struggling to relate both the output of the showinfo filter to the actual frames outputted by the command, and the corresponding output file names from the -frame_pts option. I am extracting 1 frame per second using the following command:

ffmpeg -y -i GOPR3427.MP4 -r 1 -vf showinfo -copyts -s 640x480 -frame_pts 1 \
        GOPR3427.MP4-frames/%d.jpg > GOPR3427.MP4-frames/output.txt  2>&1 -hide_banner

This output a series of jpg's from 0 -11, for example, 0.jpg, 1.jpg, 2.jpg etc. According to FFprobe, my video has a duration of 10.581333

My understanding from this superuser answer to the question Extract I-frames to images quickly is that the -frame_pts sets the numeral portion of the output image filename to represent the timestamp based on the frame rate. So in my example, the frame rate is 50/1 and according to the logic in the answer, I should be able to calculate the pts_time as follows 3.jpg would be: 3/50 = 0.06

If I check in the output.txt file I can see a line that reads

[Parsed_showinfo_0 @ 0x563d384a5080] n:3 pts:5400 pts_time:0.06 pos:451041
    fmt:yuvj420p sar:1/1 s:1920x1080 i:P iskey:0 type:P checksum:D56E24BB 
    plane_checksum:[A1E26C9D C6294D84 DB726A8B] mean:[131 145 104 ] stdev:[27.4 23.2 20.8 ]

This corresponds with the calculation above, however, my output.txt contains 528 parsed line entries like the one above, yet my command outputs only 11 files, using the logic above the file named 11.jpg would be a pts_time of 0.22, this doesn’t represent 1 x frame every second.

Can anyone help tie this together for me, at the moment I am struggling to understand the outputs here?

  • The output filename numbers should be interpreted in terms of the output -r value. Input fps is only relevant if no fps transformation has occurred, via -r or fps filter..etc. Since your video is 10.58 seconds and output rate is 1, 11.jpg should correspond to the 11th second, which is correct. – Gyan Nov 19 '19 at 15:48
  • Thanks, @Gyan - sorry just to clarify, I am going to load the images into the browser in a web application, if a user clicks on an image, say image 11 and chooses to delete, I will trim the video using that images corresponding timestamp, in this case, the 11th second. if I am to do any seek to operation in FFMPEG, given that the FFPROBE duration is 10.581333 what timestamp would I use? I'm trying to map the output files to their corresponding timestamp in the input file. – Lee Goodman Nov 19 '19 at 16:16
  • Use ffmpeg -y -i GOPR3427.MP4 select='if(eq(n\,0),1,floor(t)-floor(prev_selected_t))' -vsync 0 -r 1000 -copyts -s 640x480 -frame_pts 1 GOPR3427.MP4-frames/%d.jpg – Gyan Nov 19 '19 at 16:16
  • For complete accuracy, you would use -r 1000000 and %10 in the filename – Gyan Nov 19 '19 at 16:17
  • Thanks very much, @Gyan, I'm receiving an error when running your cmd, possibly a syntax error but I can't seem to figure it out. [NULL @ 0x560db35d1cc0] Unable to find a suitable output format for 'select=if(eq(n\,0),1,floor(t)-floor(prev_selected_t))' select=if(eq(n\,0),1,floor(t)-floor(prev_selected_t)): Invalid argument – Lee Goodman Nov 19 '19 at 16:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.