How to add additional key frames to video using ffmpeg?
Solution 1
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.
Solution 2
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.
jjulianf
Updated on September 18, 2022Comments
-
jjulianf over 1 year
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?
-
jjulianf over 5 yearsThat 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?
-
jjulianf over 5 yearsBut I could add the previous keyframes by hand afterwards, using
force_key_frame
, right? -
Eugen Rieck over 5 yearsWhy then use
scencut=0
? Let scencut do its magic! -
slhck over 5 years@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 xyproblem.info) Do you need regular intervals for streaming purposes?
-
Gyan over 5 yearsNote: 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. -
jjulianf over 5 yearsThanks, 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!
-
Gyan over 5 years
-force_key_frames source
, as it says, sets the key frames at the exact frames. -
jjulianf over 5 yearsI 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.. :-)
-
jjulianf over 5 yearsYes, 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. -
Gyan over 5 yearsThat's due to your keyint=20. If you set it to a very large value (9999), source KFs will be exactly replicated.