How to extract time-accurate video segments with ffmpeg


This is not a particularly new question area around here, but I've tried what's been suggested there without much luck. So, my story:

I've got a hunk of 15 seconds of video out of which I want to extract a specific chunk, which I can identify by start time and stop time, in seconds. I started by trying to do what I'll call a "copy extraction": to get seconds 9 to 12,

ffmpeg -i -vcodec copy -acodec copy -ss 9 -to 12

This was a not-bad start, but there are some black frames at the beginning and end of the clip, which I can't have — it has to be a clean edit from the original. So, I tried recoding the original into a new, trimmed clip:

ffmpeg -i -ss 00:00:09 -t 00:00:03

This is better, but not quite: There are no longer any black frames at the beginning of the clip, but they're still there at the end.

After some more browsing and reading, I then suspected that the problem is that ffmpeg is having trouble finding the proper points because of a lack of keyframes in the original video. So I recoded the original video to (presumably) add keyframes, in a couple of different ways. Since I want to be able to pick video at boundaries of a second ("from 9 seconds to 12 seconds"), I tried, copying various suggestions around the web,

ffmpeg -i -force_key_frames "expr:gte(t, n_forced)" test-forced.mp4


ffmpeg -i -g 1 test-g-inserted.mp4

(I built these as mp4's based on some comments about an mp4 container being needed to support the keyframe search, but I'm honestly just hacking here.) I then tried the extraction as before, but on these new videos that presumably now have keyframes in them. No luck — both seem to be about the same; the start is OK but there are still black frames at the end. (FWIW, both test-forced.mp4 and test-g-inserted.mp4 also have trailing black frames.)

So: I'm still stuck, and would like to not be. Any insights out there as to what I'm doing wrong? I feel like I'm close, but I really need to get rid of those trailing black frames….

Best Solution

Ok, first of all assuming you know the start and stop duration; we will add key-frames at that duration.

ffmpeg -i a.mp4 -force_key_frames 00:00:09,00:00:12 out.mp4

Most of the time you can directly cut the video with perfection but in your case it does not help you; so we have taken care of it by above command. Here be cautious to not add too many key frames as it can be a problem while encoding as per Ffmpeg Docs.

Now you can again try to cut the video from specific time.

ffmpeg -ss 00:00:09 -i out.mp4 -t 00:00:03 -vcodec copy -acodec copy -y final.mp4

This will solve the problem as we have manually added the keyframes at start and end points of the cut . It worked for me.


Related Question