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 want a FFmpeg seeking command that fast and accurate. I found this.

The solution is that we apply -ss for both input (fast seeking) and output (accurate seeking). But: If the input seeking is not accurate, how can we be sure that the seeking position is accurate?

For example: If we wanted to seek to 00:03:00, the command is something like:

ffmpeg -ss 00:02:30 -i <INPUT> ... -ss 00:00:30 <OUTPUT>

The first -ss will seek to somewhere else, not 00:02:30, say 00:02:31. And after applying the second seek, the final result would be 00:03:01- not what we want. Is that correct?

Where does the first -ss seek to? Does it seek to the keyframe that is closest to 00:02:30?

If so, here is my thought—correct me if I'm wrong: after first seeking, we get the timestamp of the result (in this example: 00:02:31), then we apply second seeking with appropriate time, in this case 00:00:29.

Question is: How do we get time stamp of the first seek result?

share|improve this question
up vote 10 down vote accepted

To literally answer your title's question: You can get a list of I-frames with

ffprobe -select_streams v -show_frames <INPUT> 

To see which frame is closest (comes after) a certain timestamp, you'd first need to find out all timestamps of the keyframes, for example with awk.

First, define the time you want to look for, e.g., 2:30m which equals to 150s.

ffprobe -select_streams v -show_frames -v quiet in.mp4 | 
awk -F= ' 
  /pict_type=/ { if (index($2, "I")) { i=1; } else { i=0; } } 
  /pkt_pts_time/ { if (i && ($2 >= 150)) print $2; }  
' | head -n 1

For example, this would return 150.400000.

Now, when using -ss before -i, FFmpeg seeks until that point and then uses the next keyframe it finds. Programmatically it would be a nightmare to implement any other behavior, i.e. returning a keyframe before that.

So, use the above script to find out the PTS of the keyframe after your timestamp, and use that to get more accurate seeking later.

The real question is why that'd all really matter. If you want to be super accurate while seeking, you should probably convert the video to any lossless, intra-only format, where you could cut at any point.

share|improve this answer
thanks, I'm not making a video editor, but i do want to have precise video seeking in which the gap should less than 0,5 seconds. – jackode Feb 20 '13 at 8:41
You can probably juggle around with the PTS from ffprobe. If not, any intermediate format would do, e.g. ProRes 422, DNxHD, which are visually lossless and intra-frame only. Or you use something like HuffYUV, etc. But then you'd lose the "fast" aspect again, of course. – slhck Feb 20 '13 at 8:44
what version of ffprobe did you use for the command, because mine said Unrecognized option 'select_streams' – jackode Feb 22 '13 at 3:55
You were close, the select_streams option was added in October 2012. :) You could do without that but then you'd get information for audio frames as well, mixed in between. – slhck Feb 22 '13 at 8:21
Note you can add this the ffmpeg line to let it only output the necessary 2 fields, instead of a lot of stuff that gets thrown away by awk: -show_entries frame=pkt_pts_time,pict_type – Jannes Feb 28 '15 at 22:24

You must log in to answer this question.

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