Checking keyframe interval?
Solution 1
You can display the timestamp for each frame with ffprobe
with awk
to only output key frame info. Works in Linux and macOS.
ffprobe -loglevel error -select_streams v:0 -show_entries packet=pts_time,flags -of csv=print_section=0 input.mp4 | awk -F',' '/K/ {print $1}'
Or a slower method that works on any OS and does not require awk
or similar additional processing tools:
ffprobe -loglevel error -skip_frame nokey -select_streams v:0 -show_entries frame=pkt_pts_time -of csv=print_section=0 input.mp4
Results:
0.000000
2.502000
3.795000
6.131000
10.344000
12.554000
16.266000
17.559000
...
See the ffprobe
documentation for more info.
Solution 2
The following command will give you the offsets of all key Frames in the Video
ffprobe -show_frames -select_streams v:0 \
-print_format csv Video.mov 2> /dev/null |
stdbuf -oL cut -d ',' -f4 |
grep -n 1 |
stdbuf -oL cut -d ':' -f1
Note that the command might respond a little late. Have patience :-)
The ffprobe
command gives you the frame level details in CSV format. Rest is a smart combination of cut
and grep
commands.
cut -d ',' -f4
filters the fourth column - this refers to the 'key_frame' flag.
grep -n 1
filters the key-frames only, and shows their line numbers in the CSV feed.
The
stdbuf -oL
with the cut
command manipulates the buffer of the cut command.
rabotalius
Updated on July 13, 2022Comments
-
rabotalius almost 2 years
How can I check keyframe interval of a video file?
all I can see in ffmpeg output is:
Metadata: metadatacreator : Yet Another Metadata Injector for FLV - Version 1.8 hasKeyframes : true hasVideo : true hasAudio : true hasMetadata : true canSeekToEnd : true datasize : 256600272 videosize : 210054362 audiosize : 45214634 lasttimestamp : 5347 lastkeyframetimestamp: 5347 lastkeyframelocation: 256649267 Duration: 01:29:07.24, start: 0.040000, bitrate: 383 kb/s Stream #0:0: Video: h264 (High), yuv420p, 720x304 [SAR 1:1 DAR 45:19], 312 kb/s, 25 tbr, 1k tbn, 50 tbc Stream #0:1: Audio: mp3, 44100 Hz, mono, s16p, 64 kb/s
-
lucky1928 almost 9 yearsper my understand, select first video stream command should be -select_streams v:0, but not 0:v:0. am I wrong?
-
llogan almost 9 years@lucky1928 You're correct. I fixed the typo (
0:v:0
would be the syntax inffmpeg
). -
voices about 7 yearsIs the keyframe interval included in this output, somewhere? I can't see it.
-
maetthu over 6 yearsIt isn't directly, but you can calculate the keyframe interval from this output. Count the frames from one keyframe (key_frame=1) to the next, this is the interval in frames. If you want the keyframe interval in seconds, multiply it by the framerate. Note that it may not be constant and can be different for each keyframe depending on the encoding parameters. A quick and dirty way to determine the interval for the first two keyframes:
ffprobe -select_streams v:0 -show_frames INPUT.MP4 2>/dev/null | awk -vf=0 '/key_frame=1/ {f=1; ++d} d!=2 && /key_frame/ {print} f && d==2 {exit}' | wc -l
-
Multihunter about 6 yearsDoes it bother anyone else that the
-skip_frame
flag isn't mentioned in the documentation anywhere? How are we supposed to know about it if it's not in the documentation? -
llogan about 6 years@Multihunter It is, but it is buried in ffmpeg-all. See
man ffmpeg-all
or the online ffmpeg-all documentation. Alternatively, refer toffmpeg -h full
. -
tmm1 almost 5 yearsThis command will be very slow as it is decoding every frame. You can use
-show_entries packet=pts,flags
for a much faster result and filter forflags=K
-
llogan almost 5 years@tmm1 Thanks, added.
-
Francois Bertrand over 2 yearsThe Windows/cross-platform command provided did NOT work properly, had to change
frame=pkt_pts_time
toframe=pts_time
, as nothing was showing up. The field may have changed the name since the original post?