45

I'm trying to use ffmpeg to cut video files at precise times. The ffmpeg help shows an option -timecode_frame_start to specify the starting frame but I am unable to get this command to work. The resulting video always starts at the beginning of the original video. Here's an example of the command I'm running:

ffmpeg -i input.mpg -acodec copy -vcodec copy -timecode_frame_start 200 -vframes 210 -n ouput.mpg

I've moved the timecode_frame_start option before and after the other options with no change in results. Is there an additional option I need to specify? I've tried various file formats, mkv, avi, mp4, and it doesn't appear the problem is codec related. Here is one file I've tried:

http://www.seaotter.com/marine/movies/hermit-long-01.mpg

Am I missing something?

3
  • appears this was answered on the mailing list (and NB that with -vcodec copy you can't "really" get frame specific cutting, since it can only resynchronize on i-frames
    – rogerdpack
    Aug 9 '12 at 11:46
  • @user39364 I asked on the mailing list and it turns out that this option doesn't do what the OP wants. I also learned something new :)
    – slhck
    Aug 9 '12 at 11:46
  • Just wanted to note that I found a method for cutting at exact frames using melt, see Accurately cut video files from command line - Super User
    – sdaau
    Jan 26 '18 at 2:26
68

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.

6
  • 6
    for videos with drop frames (e.g. 29.97fps) that are over 10 minutes; how would you go about accurately calculating the time for a particular frame?
    – GFoley83
    Sep 5 '16 at 20:53
  • 1
    the select=gte(n\,100) method works but the seeking is eating up performance. If you test by encoding just 30 frames at a time, The further into the video I start, the longer ffmpeg takes to complete because of the seeking.
    – Adam Grant
    Jan 29 '17 at 9:32
  • After applying this method to a video file, in my player (VLC), there's some lingering audio that plays after the video frames have stopped playing. I'm thinking I need to somehow apply this same method to "audio frames". Or simply tell ffmpeg to halt adding more audio once the video has stopped. How do I do that?
    – t-mart
    Feb 14 '20 at 23:11
  • 1
    @t-mart Add -shortest to make it stop encoding when the shortest stream is finished (i.e. the video stream in your case).
    – slhck
    Feb 16 '20 at 15:52
  • how can i trim at an exact frame but only re-encode from the starting frame until the first keyframe after that, then copy?
    – Michael
    Oct 7 '20 at 1:47
14

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.

3
  • 1
    bash: syntax error near unexpected token `(' Mar 5 '20 at 17:47
  • 2
    What does setpts=PTS-STARTPTS do?
    – Kingsley
    Jul 17 '20 at 0:23
  • For reference, here's the documentation on ffmpeg filters: ffmpeg.org/ffmpeg-filters.html. In particular, see the section on Multimedia Filters for descriptions of the select and setpts filters (as at 15 Jan 2021 sections 16.14 and 16.16, respectively).
    – SimonTewsi
    Jan 14 at 20:57
1

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.

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.

1
  • I agree with your suggestion (and i virtually had such an idea years ago). Such a feature should be provided with options. Before such a feature exists we might manage to do it with shell scripts but I'd rather avoid the troubles such as shell compatibility. I am concerned that codecs or muxers might not support well a variability in the rate (conversely delay) of key frames near the extremities. I learnt recently about Instantaneous Decode Refresh frames and their opposite whatsoever which may cause troubles like interrupted buffered video streams on internet.
    – Link-akro
    Aug 30 '20 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.