ffmpegcommand-line-interfacemp4h.264keyframe

Remove all non-keyframes from H.264 (AVC) video without re-encoding


This question is similar to Remove all non key frames from video without re-encoding but this one is specific to H.264 (AVC), not H.265 (HEVC). Also, the accepted answer to that question results in an unplayable 1k file for me.

My command line currently looks like this:

ffmpeg.exe -skip_frame nokey -i input.mp4 -vf "select='eq(pict_type,PICT_TYPE_I)'" -vsync vfr output.mp4

input.mp4 is 30fps and after I run the command line above, output.mp4 is 2fps as expected, but it's composed of not just I-frames (keyframes) but also P-frames and B-frames. Because that command is CPU-intensive, it appears to be re-encoding, and I want NO re-encoding.

Also it removes the exif information and I would like to preserve it in the file. I just want to remove the non-keyframes and keep everything else.


Solution

  • With ffmpeg 5.0 or later, and assuming your input container marks video keyframes (MP4, MKV do), use

    ffmpeg -i input.mp4 -c copy -bsf:v noise=drop=not(key) output.mp4