1

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.

snips-n-snails
  • 637
  • 5
  • 22
  • add `-c copy -map_metadata 0 -movflags use_metadata_tags` – kesh Sep 14 '22 at 02:37
  • @kesh That doesn't appear to do anything, although I had to remove `-c copy` because it conflicted with the `select` statement (the error said, "filtering and streamcopy cannot be used together"). – snips-n-snails Sep 14 '22 at 05:48
  • @snips-n-snails You say _"`input.mp4` is 30 FPS and after... `output.mp4` is **2 FPS** as expected..."_ Why is 2 suddenly the expected output frame rate from original 30 FPS input? – VC.One Sep 14 '22 at 12:43
  • PS: Is a basic command like this getting close to what you want? (untested): `ffmpeg.exe -skip_frame nokey -i input.mp4 -c copy output.mp4` – VC.One Sep 14 '22 at 12:47
  • @VC.One got the right option. you need to make your demuxer to select frames not your filter to avoid reencoding. Sorry for my brainfart – kesh Sep 14 '22 at 12:58

1 Answers1

3

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
Gyan
  • 85,394
  • 9
  • 169
  • 201