1

Let's say I need to remove everything but the second minute from a video.

I can do this, for example, in the following way:

ffmpeg -copyts -ss <start> -i input.mp4 -to <end> -c:v libx264 -crf 23 -c:a aac -b:a 192k output.mp4

I am interested in whether the -ss should be before or after the -i.

I have read all the answers and comments here and here. From what I read there, it seems that in older versions of FFmpeg, before 2.1, placing -ss before -i was for faster processing, while placing -ss after -i was for more accurate processing, but in newer versions, placing -ss before -i is not only for faster processing, but also for more accurate processing.

But on the other hand, the sections “Input seeking” and “Output seeking” here don't mention this nuance, and after reading them I'm not so sure that putting -ss before -i is "the one and only solution".

Could someone explain this? (What I want from processing is accuracy. I don't care how long it will take.)

6
  • 1
    Fot "seekable" input like MP4, the -ss should be before the -i, because it is faster, and has the same accuracy as after the -i. Without re-encoding should also work: ffmpeg -ss <start> -i input.mp4 -to <end> -c copy output.mp4 (in most cases).
    – Rotem
    Commented Jun 4 at 19:06
  • That looks groovy to me. You could add -preset ultrafast to make it a little faster. (No quality loss)
    – JayCravens
    Commented Jun 4 at 21:23
  • @Rotem 'Fot "seekable" input like MP4, the -ss should be before the -i' - And are there cases in which -ss should be after -i?
    – jsx97
    Commented Jun 8 at 21:06
  • 1
    @jsx97 In cases where -ss before the -i gives an error message, try placing it after the -i. In all other cases, I assume it is recommended placing it before the -i (as far as I know), assuming you FFmpeg version is not too old... Can you please be more specific on you objectives? Is your only objective is cutting a part of a video, or are there other objectives? Do you know how to check if the cutting is accurate?
    – Rotem
    Commented Jun 8 at 21:44
  • 1
    For testing the video, I suggest to start with synthetic video with frame numbers: ffmpeg -y -f lavfi -r 10 -i testsrc=size=192x108:rate=1:duration=500 -vf setpts=N/10/TB -c:v libx264 -pix_fmt yuv420p input.mp4. I don't know how to test the audio cutting accuracy. I suggest you to do some research, and figure out how to test it.
    – Rotem
    Commented Jun 9 at 9:07

1 Answer 1

1
+100

Compressed codecs use keyframes (or intra-frames) at given time-intervals. Only in keyframes is stored a complete image, while intermediate frames store only the difference to the neighboring keyframes. So, any decoding of a stream must always start at a keyframe.

Before version 2.1, ffmpeg's -ss option could not seek accurately when used as an input option (i.e. before the -i parameter). Rather, it would start at the nearest keyframe, so it was not possible to cut exactly at an indicated time. You first needed to decode the whole stream so you could select the exact frame at which to cut, and to that end you needed to use -ss as output option (i.e. after the -i parameter).

Nowadays however, the official documentation states :

-ss position (input/output)

When used as an input option (before -i), seeks in this input file to position. Note that in most formats it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position. When transcoding and -accurate_seek is enabled (the default), this extra segment between the seek point and position will be decoded and discarded. When doing stream copy or when -noaccurate_seek is used, it will be preserved.

When used as an output option (before an output url), decodes but discards input until the timestamps reach position.

So, if you are looking for accuracy, nowadays it does not make any sense to use the -ss parameter as an output option, as you just waste time to decode something which you will discard anyway.

The main use for -ss as output parameter is that it will maintain the original time codes, which might be useful in some cases.

Note that the above implies that you cannot do stream copy and at the same time start encoding at an arbitrary seek point. On the other hand, if the exact starting point is not that important, you might use -ss in combination with stream copy and avoid re-encoding.

3
  • Many thanks, 1NN!
    – jsx97
    Commented Jun 11 at 10:36
  • But if -ss is before -i, the value of the -to parameter is treated less intuitively, right? For example, if I need to trim the video from 10s to 15s, I can use ffmpeg -i input.mov -ss 00:00:10 -to 00:00:15 output1.mov, with -i before -ss. But if I modify this command so that -i will be after -ss, I will need to change the -to value as well, because ffmpeg -ss 00:00:10 -i input.mov -to 00:00:15 output2.mov will trim the video from 10s to 25s, (cont.)
    – jsx97
    Commented Jun 14 at 10:46
  • and to trim the video to 15s, I need to change the -to value of the second command to 00:00:05: ffmpeg -ss 00:00:10 -i input.mov -to 00:00:05 output3.mov. In real-life situations, if I need to cut a part from one hh:mm:ss to another, this seems to be somewhat inconvenient.
    – jsx97
    Commented Jun 14 at 10:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .