The Computer Oracle

How to cut at exact frames using ffmpeg?

--------------------------------------------------
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Game Looping

--

Chapters
00:00 How To Cut At Exact Frames Using Ffmpeg?
00:47 Accepted Answer Score 78
02:21 Answer 2 Score 20
02:40 Answer 3 Score 0
03:51 Answer 4 Score 6
04:04 Thank you

--

Full question
https://superuser.com/questions/459313/h...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#commandline #ffmpeg #videoconversion #videoediting

#avk47



ACCEPTED ANSWER

Score 78


timecode_frame_start does not work like this.

Seeking based on frame numbers is not possible. The only way to start at specific frames is to convert a number of frames to ss.ms syntax, or hh:mm:ss.ms. So, if your video is at 25 fps, and you want to start at 133 frames, you would need to first calculate the timestamp:

133 / 25 = 5.32

Then run:

ffmpeg -ss 5.32 -i input.mp4 -c:v libx264 -c:a aac out.mp4

Note that cutting on exact frames with bitstream copy (-c:v copy) is not possible, since not all frames are intra-coded ("keyframes"). A video must begin with a keyframe to be decoded properly. You will therefore have to re-encode the video, e.g. to H.264 using -c:v libx264 as shown above. You can also choose a lossless codec like -c:v ffv1 which preserves the quality of the input video.

To summarize, -ss will always be frame-accurate when performing re-encoding.

If you further want to encode a specific number of frames, use -frames:v, for example:

ffmpeg -ss 5.32 -i input.mp4 -c:v libx264 -c:a aac -frames:v 60 out.mp4

Note that you you also have the choice to use the select/aselect filters to select frames/audio samples.

ffmpeg -i input.mp4 -vf 'select=gte(n\,100)' -c:v libx264 -c:a aac out.mp4

This, however, is slower than the -ss option shown above, since the entire video will be decoded.




ANSWER 2

Score 20


The option

-vf select="between(n\,start_frame_num\,end_frame_num),setpts=PTS-STARTPTS"

e.g.,

-vf select="between(n\,200\,300),setpts=PTS-STARTPTS"

cuts video from(includes) 200th to(includes) 300th frame, the sequence counting starts from 0.




ANSWER 3

Score 6


LosslessCut is a cross-platform GUI tool that uses FFmpeg as a backend and losslessly cuts your video. You can choose to cut at a keyframe or any frame.




ANSWER 4

Score 0


I have a solution, but I don't know how to do it using current ffmpeg commands (my trials to copy at keyframes didn't come accurate too. I want to know how ffmpeg decides the cutpoints).

I suggested suggest this algorithm, to divide the segment (t1, t2) that we want to copy to 3 parts:

  1. a part (t1-x, t1+y), which is a complete encoded block that should be re-encoded to be able to copy the part (t1, y) precisely.
  2. a part (t2-z, t3+w), which is a complete encoded block that should be re-encoded to be able to copy the part (z, t2) precisely.
  3. a middle part (y, z) which contains complete encoded blocks, where it can be copied as is.
  4. Join the 3 parts resulted from the above steps.

Note that the first two parts are expected to be small (and one of them or both can be zero length), so, the re-encoding process will be fast. This will make us able to have exact cuts with slightly slower operation but still super faster than re-encoding the full video. It can be even faster if we can do multiple cuts with one command, so we traverse the frames once. I hope if someone can apply this, and tell us how, or mention some of the ffmpeg team, or deliver it to them anyhow.