241

I have a video file of 30 minutes, but I want to extract a video from 00:09:23 to 00:25:33.

I can define the startposition with -ss, but I couldn't find one for the end position. Any help please?

slhck
  • 223,558
  • 70
  • 607
  • 592
x74x61
  • 2,801
  • 4
  • 16
  • 7

6 Answers6

379

Install ffmpeg

Make sure you download a recent version of ffmpeg, and don't use the one that comes with your distribution (e.g. Ubuntu). Packaged versions from various distributions are often outdated and do not behave as expected.

Or compile it yourself. Under macOS, you can use Homebrew and brew install ffmpeg.

How to cut a video, without re-encoding

Use this to cut video from [start] for [duration]:

ffmpeg -ss [start] -i in.mp4 -t [duration] -map 0 -c copy out.mp4

Use this to cut video from [start] to [end]:

ffmpeg -copyts -ss [start] -i in.mp4 -to [end] -map 0 -c copy out.mp4

Explaining the options

The options mean the following:

  • -ss specifies the start time, e.g. 00:01:23.000 or 83 (in seconds)
  • -t specifies the duration of the clip. The format of the time is the same.
  • Instead of -t, you can also use -to, which specifies the end time.
  • -map 0 maps all streams, audio, video and subtitles

You have to understand that normally, -ss resets the timestamps of the input video after the cut point to 0, so by default it does not matter if you use -t or -to. If you want -ss to not reset the timestamp to 0, the -copyts option can be used. This makes -to behave more intuitively.

For example:

ffmpeg -ss 5 -i in.mp4 -t 30 -map 0 -c copy out.mp4

This seeks forward in the input by 5 seconds and generates a 30 second long output file. In other words, you get the input video's part from 5–35 seconds.

Or:

ffmpeg -ss 5 -i in.mp4 -to 30 -map 0 -c copy out.mp4

This achieves the same thing as above, since the timestamps get reset to 0 after seeking 5 seconds in the input. The output will still be 30 seconds long.

If we instead use -copyts, and we want the part from 5–35 seconds, we should use:

ffmpeg -copyts -ss 5 -i in.mp4 -to 35 -map 0 -c copy out.mp4

Finally, we've used the -c copy option. -c copy copies the first video, audio, and subtitle bitstream from the input to the output file without re-encoding them. This won't harm the quality and make the command run within seconds.

For more info on seeking, see https://trac.ffmpeg.org/wiki/Seeking

How to cut a video, with re-encoding

Sometimes, using -c copy leads to output files that some players cannot process (they'll show a black frame or have audio-video sync errors).

If you leave out the -c copy option, ffmpeg will automatically re-encode the output video and audio according to the format you chose. For high quality video and audio, read the x264 Encoding Guide and the AAC Encoding Guide, respectively.

For example:

ffmpeg -ss [start] -i in.mp4 -t [duration] -c:v libx264 -crf 23 -c:a aac -b:a 192k out.mp4

You can change the CRF and audio bitrate parameters to vary the output quality. Lower CRF means better quality, and vice-versa. Sane values are between 18 and 28.

slhck
  • 223,558
  • 70
  • 607
  • 592
  • 1
    On ubuntu 12:10, -c:v and -c:a didn't work. I had to use "-acodec copy and -vcodec copy" instead. – Samuel Lampa Apr 02 '13 at 14:21
  • 1
    @Samuel Then you're using an outdated version, which isn't even real FFmpeg, but the Libav fork. See: http://stackoverflow.com/a/9477756/1109017 – slhck Apr 02 '13 at 14:45
  • 1
    Thanks for this! if you don't specify a duration, will it go to the end? – Jeff Mar 31 '14 at 17:03
  • 1
    @Jeff Yes! (character minimum) – slhck Apr 01 '14 at 05:34
  • thank you! I was using: "ffmpeg -i in.mp4 -vf trim=duration=99 out.mp4" and it was giving me 1:44 output instead of 1:39 output, even when I reduced the duration to 98 and 90 sec, I still got a 1:44 output? Anyway, using your first example above, I got the correct output length. – bee.catt Jul 01 '15 at 18:37
  • Could you explain what frame accuracy means? – Prateek Jul 03 '15 at 06:30
  • 7
    @Prateek When copying the video bitstream (instead of re-encoding), you can only cut at [keyframes](https://en.wikipedia.org/wiki/Video_compression_picture_types#Intra_coded_frames.2Fslices_.28I.E2.80.91frames.2Fslices_or_Key_frames.29). If there are keyframes at seconds 1, 2, and 3, but you want to cut at second 1.5, then ffmpeg will wait until second 2 before it can start cutting. That makes it inaccurate. – slhck Jul 03 '15 at 12:36
  • The accurate method seems to produce exactly the same results as the fast one. I get the first 1-2 seconds as a frozen frame, while the audio plays normally. – Ron Harlev Nov 17 '15 at 18:50
  • Ron Harlev - ffmpeg changed how it works some time ago so that it will be accurate no matter where you put the `-ss`. The fast method is still faster though. – Yay295 Dec 27 '15 at 18:12
  • @Yay295 I revised my answer to clarify that. Thanks for the comment—I'd have forgotten to do that otherwise. – slhck Dec 30 '15 at 10:54
  • I just wanted to comment on how fast the cutting process is - on my Windows 10 Skylake PC, it took pretty much a split second to finish. I thought something went wrong at first, but nope - the new file was written and chopped off perfectly. – Artem Russakovskii Dec 03 '16 at 23:48
  • 1
    I had to put the -ss after the -i in.mp4 `ffmpeg -i in.mp4 -ss 00:01:00 -to 00:02:30 -c copy out.mp4` – technoplato Nov 20 '19 at 18:58
  • @lustig That should make no difference at all when stream copying. – slhck Nov 20 '19 at 20:49
  • Just the messenger here friend. Doing the way above did not work. The video start time I specified was ignored. – technoplato Nov 20 '19 at 20:56
  • @lustig Hm. Completely ignored, or was there an offset to what you specified? I think it depends on whether you hit a a keyframe or not… I just tried and putting `-ss` after the input made it inaccurate. – slhck Nov 21 '19 at 09:02
  • @slhck good question, and one where I'd have to check things out again to tell you. I'm a very novice user of FFmpeg, so mine should not be a canonical exception bur rather an anecdote. – technoplato Nov 22 '19 at 14:22
  • I think you should mention that `-to` starts from `-ss`, not from the beginning of the original input, unless you add the `-copyts` option (cf. [Cutting small sections](https://trac.ffmpeg.org/wiki/Seeking)). – Géry Ogam Mar 03 '20 at 13:42
  • @Maggyero Good suggestion, added. – slhck Mar 03 '20 at 14:10
  • 6
    `-to` does not always "start from" `-ss` even without `-copyts`, @Maggyero I use to move the `-to` option to configure the input instead of the output so it is just another solution. `ffmpeg -ss [start] -to [stop] -i in.mp4 -c copy out.mp4` Like this my stop time is correct despite the start time. I wonder if it is also the reason why @lustig moved `-ss` to the output while they did not know why. The answer does not even mention `-copyts` ! It should, as it is the simplest solution here ! I prefer reordering the arguments, but i guess it is not simpler. – Link-akro Aug 23 '20 at 08:54
  • 1
    @Link-akro thank you so much! That did it! You should add that as the answer. Out of all the things I've tried on here this is the only method that reliably and accurately trims the video. Using latest stable ffmpeg. – gargoylebident Jan 06 '21 at 18:38
  • @stackexchange_account1111 to be fair the present answer links to the Seeking guide, which in turn explains `-copyts` etc. Leaving aside whether i had the rep or boldness to edit, the edit queue is full according to the system when i tried to edit just now. – Link-akro Mar 30 '21 at 20:56
  • It is noted that "if you've used -ss, you have to subtract this from the -to timestamp"...Can you give a concrete example of what things to subtract exactly and how you do that subtraction when milliseconds are involved? – kraftydevil Apr 14 '23 at 12:47
  • 1
    @kraftydevil I updated the answer. It's a bit confusing with the use of `-copyts`, unfortunately. – slhck Apr 14 '23 at 15:25
  • I'm still getting a clip that is of duration length unfortunately. For example, when I try `ffmpeg -copyts -ss 00:00:03.633 -i input.mp4 -to 00:00:04.166 -c:v libx264 -crf 23 -c:a aac -b:a 192k output.mp4` - I get a clip that is 4.166 seconds long and I want the duration to be the difference between 4.166 - 3.633, which is about half a second. In addition the clip is blank, but I'm trying to get the length correct first – kraftydevil Apr 14 '23 at 21:27
  • 1
    @kraftydevil Your command should work, it shouldn't be 4.166 seconds long. How do you determine the length? Where did you play the clip? Maybe post a new question and show the full command line output that your command produces. – slhck Apr 16 '23 at 09:01
  • 1
    @slhck It indeed creates a clip that is 4.166 seconds long. The first part of the generated video is black until it ends with the desired clip. I get the start/end values by manually finding what I want in DaVinci resolve, and then copying the timecode - being sure to convert frames to milliseconds. Playing them with Quicktime. I actually gave up on this method and decided to use '-t'. I ended up calculating the duration separately (endTime - startTime). It worked so I'm done pursuing. Thank you for your work! – kraftydevil Apr 17 '23 at 08:56
49

I think you can use the following command now.

ffmpeg -i inputFile -vcodec copy -acodec copy -ss 00:09:23 -to 00:25:33 outputFile

Have a look also ffmpeg Doc, or this wiki page.

rsalmond
  • 103
  • 3
sflee
  • 591
  • 4
  • 4
  • 15
    `ffmpeg -i inputFile -c copy -ss 00:09:23 -to 00:25:33 outputFile` simpler version – nwgat Nov 20 '16 at 16:37
  • 5
    I had to use `ffmpeg -ss 00:01:00 -i video.mp4 -to 00:02:00 -c copy -copyts cut.mp4` version (with `-copyts`), otherwise it cut incorrectly (with black screen in the beginning). Thanks for the 2nd link though. – Necronomicron Jan 12 '18 at 15:51
  • 2
    This is great, the last thing I wanted was calculating the duration from endpoints. – Tomasz Gandor May 11 '18 at 09:50
  • 2
    The -to option answers the question that was actually asked. The rest of the answers are either impertinent or obsolete. – James Bowery May 15 '18 at 15:35
  • @Necronomicron but timestamps may not be appropriate with that variant. – jarno Apr 02 '20 at 23:33
23

This is odd that no-one suggested the trim filter.

Drop everything except the second minute of input:

ffmpeg -i INPUT -vf trim=60:120

Keep only the first second:

ffmpeg -i INPUT -vf trim=duration=1

Drop everything except from second 13 to second 58:

ffmpeg -i INPUT -vf trim=13:58 OUTPUT
malat
  • 1,223
  • 2
  • 15
  • 36
  • 24
    Yes, good to mention `trim` and `atrim`. I usually use these when filtering, but users should note that **filtering requires re-encoding**. – llogan Apr 07 '15 at 17:28
  • You are my hero. I badly needed a filter that did this. – fahadash Dec 24 '16 at 05:55
  • Is this losless or does this re-encode the video? – fap Dec 08 '21 at 19:10
  • 1
    @fap The comment above yours literally answers this. – Hashim Aziz Jul 22 '22 at 15:44
  • The trim filter also takes named arguments `start` and `end`. Using named arguments lets you omit the others, as in `trim=end=X` (from start to X) and `trim=start=X` (from X to end). If you want a colon in X (e.g., the time 5:39), you need to escape it, as in `trim=end=5\:39` so that it doesn't get interpreted as the field separator. – BallpointBen Jun 22 '23 at 20:31
9

You can use these two methods which work for Windows and Linux.

There are two ways how to split video files by ffmpeg. The first one is good in itself, more than that - it is faster, but sometimes creates output files with certain flaws. So for those cases there is the second way of splitting video files: it is considerably slower, the output files are bigger, but it seems they are always of the same quality level as input files used.

Way 1:

ffmpeg -ss <start> -i in1.avi -t <duration> -c copy out1.avi

Way 2:

ffmpeg -ss <start> -i in1.avi -t <duration> out1.avi
  • <start> – the beginning of the part of a video ffmpeg is to cut out. Format: 00:00:00.0000, meaning hours:minutes:seconds:milliseconds.

  • <duration> – the duration of the part of a video ffmpeg is to cut out. Same format as above.

Examples:

ffmpeg -ss 01:19:00 -i in1.avi -t 00:05:00 -c copy out1.avi
ffmpeg -ss 01:19:00 -i in1.avi -t 00:05:00 out1.avi

ffmpeg cuts out a part of the video file starting from 1 hour 19 minutes 0 seconds. The duration of the video sequence cut out is 5 minutes 0 seconds.

Christian
  • 7,102
  • 1
  • 22
  • 36
  • Ok, thnx. Will check out the docs and give it a try tomorrow. – juGGaKNot Oct 03 '13 at 19:18
  • 3
    [`-sameq` does not mean "same quality"](http://superuser.com/a/478550/110524) and has been removed from ffmpeg. Use `-codec copy` instead. Also, don't forget about the `-to` option. – llogan Oct 03 '13 at 20:47
  • 1
    I corrected the commands in your quote, as they were quite outdated. Please don't copy-paste information without properly quoting it. – slhck Oct 04 '13 at 10:08
-3

I use the following syntax to cut video with ffmpef:

ffmpeg -sameq -ss [start_seconds] -t [duration_seconds] -i [input_file] [outputfile]

-t is used to set the duration in seconds - you can't specify the end time but this should work for you.

  • 1
    Why are you setting FFmpeg to re-encode the file? Note that `-sameq` does not mean "same quality" at all. – slhck Jan 11 '12 at 21:18
-3

You can use this

ffmpeg -sameq -ss clip_start -t duration  -i  original.ogg  clip.ogg

Here you have to give duration of video. ie. 00:25:33-00:09:23

daya
  • 2,571
  • 17
  • 19
  • 1
    As I mentioned on the other answer: With your command, you're re-encoding the file, which is absolutely not necessary and results in reduced quality and increased processing time. – slhck Jan 11 '12 at 21:18