How to cut at exact frames using ffmpeg?
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.
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.