7

I want to add key frames on the base of a specific interval (20 frames) to my video.

Therefore I used the following command in ffmpeg:

ffmpeg -i <input> -vcodec libx264 -x264-params keyint=20:scenecut=0 -acodec copy out.mp4

Output is, that I get key frames every 20 frames.

But the original video had a key frame e.g. at frame 1, 12, 89....

Now I have key frames at frame 1, 21, 41....

I don't want to replace the key frames which were already there. I want to add additional key frames, so it looks like this:

frame 1, 12, 21, 41, 89....

How can I do this?

Julian F.
  • 453
  • 2
  • 6
  • 12

2 Answers2

5

force_key_frames has an option to mirror source stream's keyframe cadence (as yet undocumented - on my todo), however this can't be combined with other expressions in f_k_f.

However, what you can use, is

-force_key_frames source -x264-params keyint=20:scenecut=0

This will set a keyframe if the source frame was a keyframe. However keyint is always measured from the last keyframe set, so if your source had KFs at n=0,34,55,64 then result will have KFs at n=0,20,34,54,55,64,84 - note the lack of KFs at 40,60,80. Also note the consecutive KFs at 54,55, so it's best to ignore the source KFs and let scenecut work.

Gyan
  • 34,439
  • 6
  • 56
  • 98
  • Thanks, it's good to know about this option! But it's not exactly what I wanted since I need the key frames at the exact frames. But still, interesting option! – Julian F. Sep 11 '18 at 08:31
  • `-force_key_frames source`, as it says, sets *the key frames at the exact frames.* – Gyan Sep 11 '18 at 08:33
  • Yes, but I mean `n=0, 20, 34, 40, 55, 60, 64, 80...` . But as I said in the upper comment, the video still plays great with my initial solution. – Julian F. Sep 11 '18 at 08:36
  • That's due to your keyint=20. If you set it to a very large value (9999), source KFs will be exactly replicated. – Gyan Sep 11 '18 at 08:37
3

Short answer: You can't

Long answer: When using FFMpeg with reencoding (i.e. any other codec than copy), every single image in the input stream will be decompressed and available as a full bitmap. This implies, that at this point in the pipeline, frames 1, 12 and 89 are no longer "special" - they are images like any other.

When now compressing via libx264, you create a video that has key frames - these will be put at the places you configure, in you case every 20 frames.

Eugen Rieck
  • 19,950
  • 5
  • 51
  • 46
  • That seems to make sense, thanks for your answer! But what happens, when I have a complete scene change between frame 11 and 12 and I only get keyframes at frame 1, 21, ... ? Don't I need a keyframe at frame 12 in that case? – Julian F. Sep 10 '18 at 12:36
  • But I could add the previous keyframes by hand afterwards, using `force_key_frame`, right? – Julian F. Sep 10 '18 at 12:47
  • 2
    Why then use `scencut=0` ? Let scencut do its magic! – Eugen Rieck Sep 10 '18 at 16:46
  • @jjulianf It seems you need to rewrite your question to ask about the *actual* problem you're having, not what you think the solution is. (See http://xyproblem.info/) Do you need regular intervals for streaming purposes? – slhck Sep 11 '18 at 06:01
  • 1
    Note: scenecut value doesn't represent the delta measurement between adjoining frames. `scenecut` also takes into consideration the distance from the last keyframe, so with a low keyint value, scenecut may never be triggered unless the latter is set very high. – Gyan Sep 11 '18 at 06:28
  • I thought that I woul still need the original keyframes. Thought that the video would run stuttery or something like that when a scene completly changes and the original keyframes are not there anymore. But it turned out that it still plays very well somehow.. :-) – Julian F. Sep 11 '18 at 08:33