2

I'm using FFmpeg to extract images from video, 1 frame every 6 seconds:

Normal command on Dos ( Windows 8 OS) >  ffmpeg -i in.mkv -r 1/6 %4d.png

Takes too much time as speed is very low, around 15-20.

So I used skip_frame nokey

ffmpeg -skip_frame nokey -i "in.mkv" -vsync 0 -frame_pts true -r 1/6 %4d.png

This extracts at higher speed, around 200 (ten times faster).
But the problem is it skips many images, and throws error:

application provided invalid, non monotonically increasing dts to muxer in stream

So I used this command:

ffmpeg -i in.mkv -vf "select='if(not(floor(mod(t,6)))*lt(ld(1),1),st(1,1)+st(2,n)+st(3,t));if(eq(ld(1),1)*lt(n,ld(2)+1),1,if(trunc(t-ld(3)),st(1,0)))'" -vsync 0 %4d.png

(Provided here - How to capture first X frames every X seconds into a PNG with FFmpeg?)

This gives me speed of 25-30.

Is there anyway I can achieve higher speed with -skip_frame?

Cool
  • 41
  • 1
  • 6
  • Edited a bit, last command removed, not working properly. – Cool Sep 25 '19 at 17:35
  • 1
    @ankii, no. just edited my origional post. The link you've given is about timestamp. I'm just insterested in extracting images from video fastest way possible. Thank you. – Cool Sep 25 '19 at 17:38
  • @ankii, loop ?? run what ? command ? – Cool Sep 25 '19 at 17:40
  • You want the speed advantage of using -skip_frame, but you don't want it to "skip many images"? That's what you're telling it to do: skip all frames that are not key frames. On top of that you're applying -r 1/6 which modifies the frame rate. – llogan Sep 25 '19 at 17:41
  • I see. I got that command from somewhere. So according to my understanding -skip_frame skips directly to every 6 seconds and -r 1/6 means 1 frame per 6 seconds. Is there other way to fast seek while extracting images from a video ? – Cool Sep 25 '19 at 17:47
  • I searched a lot. There are two ways to extract image based on time, one is -r and another is -vf fps. – Cool Sep 25 '19 at 17:51
  • The number of key frames depends on the input video. If the video has 60 key frames then you will get an output of 60 images. If you then apply -r then you will drop or duplicate frames depending on your -r value. To find the number and location of key frames see Checking keyframe interval? – llogan Sep 25 '19 at 18:12
  • Found a long list of numbers. So how can use this found key frames in my DOS command ? – Cool Sep 25 '19 at 18:26
  • I get a list of keyframes executing the second command, now I want to use it for faster image extraction. Thats what I mean. – Cool Sep 25 '19 at 18:29
  • Yes, that's what the command does (did you not read any of the context or did you just blindly run the command?). It shows you how many key frames are there and when they occur. It is only to help you determine how many images you'll get and if they occur in an acceptable timestamp. Now you are informed enough to know if you can use -skip_frame nokey or not. – llogan Sep 25 '19 at 18:42
  • Does that mean I can extract image on that keyframe only ? (The list I got.) If yes, then how ? – Cool Sep 25 '19 at 18:45
  • Yes, unless you decide to omit -skip_frame nokey, but then it will be slower. – llogan Sep 25 '19 at 18:46
  • Can you post the exact command that will extract images ? – Cool Sep 25 '19 at 18:47
  • ffmpeg -skip_frame nokey -i input.mkv -vsync 0 %4d.png – llogan Sep 25 '19 at 18:48
  • Ok, got it. Thank you very much. Is there anyway to extract images faster ? The maximum speed I get is only 27. While extracting keyframes with -skip_frame nokey, i get around 130-200. I want 1 frame per 6 seconds (every 144th frame, with video framerate of ~24). The keyframes in my video are random with gape of 5-10 seconds, so using -skip_frame is of no use. – Cool Sep 25 '19 at 19:05

1 Answers1

2

Ok the code I posted above in the original post is the only solution I've found so far for faster image extraction. Sometimes gives me speed upto 50.

ffmpeg -i in.mkv -vf "select='if(not(floor(mod(t,6)))*lt(ld(1),1),st(1,1)+st(2,n)+st(3,t));if(eq(ld(1),1)*lt(n,ld(2)+1),1,if(trunc(t-ld(3)),st(1,0)))'" -vsync 0 %4d.png

If you are interested in random image extraction (based on keyframe) to get higher speed, use -skip_frame nokey.

Cool
  • 41
  • 1
  • 6