To extract keyframe timestamps from a video using FFmpeg, run the command ffmpeg -i input.mp4 -vf select='eq(pict_type\,PICT_TYPE_I)' -vsync vfr -show_frames output.csv. This method isolates only intra-frames (I-frames) and outputs their precise Presentation Timestamps (PTS) in seconds. It is the most reliable way to identify random access points for editing or analysis.
Understanding Keyframes and Their Importance
Video compression relies on three primary frame types: Intra-coded frames (I-frames), Predictive frames (P-frames), and Bidirectional frames (B-frames). I-frames are complete images that do not rely on other frames for decoding. They serve as anchor points in the video stream, allowing players and editors to jump directly to specific moments without processing every preceding frame. For video editors, knowing the exact timestamp of each keyframe is crucial for seamless cuts. If you cut between two keyframes, the player must decode all intermediate P and B frames to display the image, which can cause stuttering or increased CPU load during playback. By identifying these timestamps, you ensure that your edits land precisely on an I-frame, resulting in smoother performance and faster seeking times. This process is distinct from simply listing all frame timestamps. While every frame has a timestamp, only keyframes provide true random access capability. Understanding this distinction helps in optimizing workflows for large video files where processing power is limited. For more advanced filtering techniques, you might explore Utilizing FFmpeg Filter Stream Characteristics for Image and Video Inputs, which expands on how to manipulate stream data effectively.The Command Line Solution
The most efficient way to extract these timestamps is by using FFmpeg’s video filter graph. The following command selects only I-frames and outputs their metadata in a CSV format suitable for further processing.ffmpeg -i input.mp4 -vf "select='eq(pict_type\,PICT_TYPE_I)',showinfo" -f null -
However, this outputs raw text logs. To get clean CSV data, use the -show_frames option combined with the select filter. Here is the optimized command for generating a clean list:
ffmpeg -i input.mp4 -vf select='eq(pict_type\,PICT_TYPE_I)' -vsync vfr -show_entries frame=pts_time -of csv=p=0 output_keyframes.csv
Let’s break down why each part of this command is necessary. The -i input.mp4 specifies the source file. The -vf select='eq(pict_type\,PICT_TYPE_I)' applies a video filter that passes only frames where the picture type equals an I-frame. Without this, FFmpeg would process every single frame, slowing down the operation significantly.
The -vsync vfr flag is critical. Variable Frame Rate (VFR) synchronization ensures that timestamps are preserved accurately relative to the original stream. If you use constant frame rate (cfr), timestamps may be rounded or altered, leading to inaccuracies. Finally, -show_entries frame=pts_time tells FFmpeg to output only the Presentation Timestamp in seconds, and -of csv=p=0 formats the output as comma-separated values without headers.
Alternative Methods for Different Needs
Sometimes, you may need more than just the timestamp. For instance, if you require the frame number or pixel dimensions alongside the timestamp, the previous command needs adjustment. You can modify the-show_entries parameter to include additional fields.
ffmpeg -i input.mp4 -vf select='eq(pict_type\,PICT_TYPE_I)' -vsync vfr -show_entries frame=pts_time,pkt_size,nb_samples -of csv=p=0 output_detailed.csv
Another common requirement is extracting the actual image frames at those keyframe locations. Instead of just logging the time, you can dump the images directly. Use the fps filter in conjunction with select to control output density, though note that this will generate image files rather than a text log.
If you are working with complex streams where standard selection fails, consider examining the stream characteristics more deeply. As discussed in Extracting Specific Frame Index using FFmpeg's Timestamp (PTS), understanding PTS vs DTS (Decoding Timestamp) differences can resolve issues where extracted timestamps appear out of order due to B-frames being decoded before they are displayed.
Handling Edge Cases and Errors
Not all videos behave predictably. Some encoded files may have missing I-frames or irregular intervals. When running the extraction command, monitor the FFmpeg console output for warnings. If you see messages about dropped packets or invalid timestamps, the source file might be corrupted or poorly encoded. In cases where you encounter negative presentation timestamps, it often indicates a discrepancy in how the container handles time bases. This issue is frequently seen when trimming videos incorrectly. For insights into managing timestamp anomalies, refer to Trimming Start of Video Generates Negative Presentation Timestamps with FFmpeg. Additionally, ensure your FFmpeg version is up to date. Older versions may lack support for certain filter expressions or output formats. Upgrading can also improve processing speed and stability. A guide on improving performance through upgrades can be found in Upgrading ffmpeg from 2.6.8 to 5.1.6 while Achieving Fast File Writing. Finally, always verify the output CSV. Open it in a spreadsheet application and check for gaps. If your video is 10 minutes long but you only have 50 keyframes listed, the extraction may have failed silently. Increasing verbosity with-loglevel debug can help diagnose such issues during the initial run.
Frequently Asked Questions
What is the difference between PTS and DTS?
PTS (Presentation Timestamp) determines when a frame should be displayed to the user, while DTS (Decoding Timestamp) determines when it must be decoded. Because B-frames depend on future frames, their DTS is earlier than their PTS. Always use PTS for editing timelines to ensure correct visual placement.Why are my keyframe timestamps not evenly spaced?
Keyframe intervals vary based on scene complexity and encoding settings. Action-heavy scenes may have more frequent keyframes, while static shots may go longer between them. This is normal behavior for modern codecs like H.264 and H.265 to optimize bitrate usage.Can I extract keyframes from a live stream?
Yes, but it requires real-time processing. You can pipe the stream into FFmpeg and apply the sameselect filter. However, buffering delays may affect accuracy. It is generally better to record the stream first and then analyze the saved file for precise timestamps.