Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I use FFmpeg to extract a keyframe at the 3rd minute. This means that it is the 3*60*25 th frame (assuming 25 FPS). Now, often this frame is not a keyframe.

I want to extract a frame closest to the above frame but ensure that it is a keyframe. This means the frame may occur a few seconds before or after the third minute of the video.

I have looked everywhere without any luck! I am doing this on Linux, so if you are using a FFmpeg with something specially installed or bundled, let me know!

share|improve this question

Using -ss parameter with select filter would work.

Something similar to:

ffmpeg -ss 180 -i yourvideo.mp4 -vf select="eq(pict_type\,I)" -vframes 1 thumbnails.jpeg
share|improve this answer
    
I think it is a fair attempt! Why would you down vote it? agree i missed -vframes 1 – d33pika Jan 17 '13 at 7:43
    
The important part is the concept using -ss and the select filter to pick only I frames. the OP can workout a solution form there. I do not have to spoon feed an answer! – d33pika Jan 17 '13 at 7:46
    
I have tried it. It does generate an image!, the position of -ss before or after -i is indeed a choice one has to make. I think before is faster, I am assuming that OP is ok with finding a Key frame after 3 minutes, that is a big assumption I admit. – d33pika Jan 17 '13 at 8:02
    
Okay, I tested it again with the options placed like that (also changing PICT_TYPE_I to I), and it worked now as expected, +1 anyway (I removed a few obsolete options that don't matter in this case) – slhck Jan 17 '13 at 8:06
1  
Did you look at this: superuser.com/questions/538112/… , I have shared what I use to pick good thumbnails from a video. – d33pika Jan 29 '13 at 5:43

If you assume that the closest I-frame to 00:03:00 appears before that timestamp, you'll have to do some guessing, since the GOP length (the number of frames between each I-frame) isn't the same for each video. If you know your GOP length, e.g. 125 frames, then start 5 seconds before that, at 00:02:55, for example.

Note that this doesn't have to be a fixed length. Good encoders will place an I-frame at scene cuts rather than fixed points to achieve better compression and reliability.

So, let's shift the input by the amount of time we calculated before, using -itsoffset.

We specify the select filter to get us only I-frames, and -vframes to only receive one frame. Finally, write that to a .jpg file.

ffmpeg -itsoffset -00:02:55 -i in.mp4 -filter:v select='eq(pict_type\,I)' -vframes 1 out.jpg

I tested this with a video that originally has a P-frame at 00:03:00, and I received the 13th frame after that, which is the start of a new scene—an I-frame.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .