Using ffmpeg to cut up video

357

158

I am using ffmpeg to cut out a section of a large file like this:

ffmpeg -i input.wmv -ss 60 -t 60 -acodec copy -vcodec copy output.wmv

The -ss part works fine but the -t is ignored. It correctly removes the initial specified seconds specified with -ss but then keeps going to the end of the input with the copy.

Is there a way to use ffmpeg to cut off the end of a video without recoding it?

Neil

Posted 2010-05-06T14:12:17.863

Reputation: 3 699

1this syntax is correct. – jiggunjer – 2015-12-08T07:03:38.933

1http://stackoverflow.com/questions/18444194/cutting-the-videos-based-on-start-and-end-time-using-ffmpeg/40244234#40244234 – Ciro Santilli 新疆改造中心法轮功六四事件 – 2017-01-22T18:30:10.857

Answers

423

You can use the -ss option to specify a start timestamp, and the -t option to specify the encoding duration. The timestamps need to be in HH:MM:SS.xxx format or in seconds (s.msec).

The following would clip the first 30 seconds, and then clip everything that is 10 seconds after that:

ffmpeg -ss 00:00:30.0 -i input.wmv -c copy -t 00:00:10.0 output.wmv
ffmpeg -ss 30 -i input.wmv -c copy -t 10 output.wmv

Note that -t is an output option and always needs to be specified after -i.

Some tips:

  • For older ffmpeg versions, if you use -ss after -i, you get more accurate seeking at the expense of a slower execution altogether. See also: Seeking with FFmpeg
  • You can use -to instead of -t to specify the timestamp to which you want to cut. So, instead of -i <input> -ss 30 -t 10 you could also do -i <input> -ss 30 -to 40 to achieve the same thing.

  • If your ffmpeg does not support -c, or -to, it is likely very outdated. Compile a new version yourself or download a static build from their homepage. It's really not complicated.

user37242

Posted 2010-05-06T14:12:17.863

Reputation:

6+1 I came here to figure out how to ignore everything after the first 35 seconds, thanks: ffmpeg -i input.wmv -c copy -t 35 output.wmv – karlphillip – 2014-09-05T19:20:12.563

2This does not work for me (mp4). It just produces a 5 second black screen: frame= 150 fps=0.0 q=-1.0 Lsize= 264kB time=00:00:09.97 bitrate= 216.6kbits/s – clocksmith – 2015-05-15T18:42:18.037

2This produced 3-4 s black screen in the beginning of my video clip. Chris's modification with omitting -c copy removed the initial black screen, see his answer for details. – joelostblom – 2016-04-16T22:32:34.343

1From the docs, the part you said about -t being only an output option is incorrect: `When used as an input option (before -i), limit the duration of data read from the input file.

When used as an output option (before an output filename), stop writing the output after its duration reaches duration.` – deweydb – 2016-08-30T02:52:50.463

How would I need to change the command if I want to cut the video part from lets say 00:01:22 to 00:05:11 ? – utdev – 2017-02-02T09:06:34.853

4You write "The following would clip the first 30 seconds, and then clip everything that is 10 seconds after that:" <-- What does that mean? By clip do you mean include? 'cos clip can mean clip out. Assuming you mean include. Do you mean Start from 30 seconds in, and include just 10 seconds from there? If so then I suggest you write that it'd be much clearer. – barlop – 2017-12-19T02:21:26.637

There is a way to say "start the cut at 01:02:03" but I see no way to say "stop the cut at 02:03:04". -t and -to seems to be the duration of the cut. What is the option (if it exists) to set the end timestamp (in the original input) of the cut? – Xenos – 2019-08-30T21:20:20.707

1

@Mondain Actually, you get more accuracy putting the -ss after. And slhck mentions this here http://blog.superuser.com/2012/02/24/ffmpeg-the-ultimate-video-and-audio-manipulation-tool/ also in ffmpeg documentation for -ss it mentions a difference between putting it before or after.

– barlop – 2013-10-11T00:38:27.587

105

As other people mentioned, putting -ss before (much faster) or after (more accurate) the -i makes a big difference. The section "Fast And Accurate Seeking" on the ffmpeg seek page tells you how to get both, and I have used it, and it makes a big difference. Basically you put -ss before AND after the -i, just make sure to leave enough time before where you want to start cutting to have another key frame. Example: If you want to make a 1-minute clip, from 9min0sec to 10min 0sec in Video.mp4, you could do it both quickly and accurately using:

ffmpeg -ss 00:08:00 -i Video.mp4 -ss 00:01:00 -t 00:01:00 -c copy VideoClip.mp4

The first -ss seeks fast to (approximately) 8min0sec, and then the second -ss seeks accurately to 9min0sec, and the -t 00:01:00 takes out a 1min0sec clip.

Also note this important point from that page: "If you use -ss with -c:v copy, the resulting bitstream might end up being choppy, not playable, or out of sync with the audio stream, since ffmpeg is forced to only use/split on i-frames."

This means you need to re-encode the video, even if you want to just copy it, or risk it being choppy and out of sync. You could try just -c copy first, but if the video sucks you'll need to re-do it.

seriesoftubes

Posted 2010-05-06T14:12:17.863

Reputation: 1 151

the same warning applies to -c:a copy for this way of seeking. – jiggunjer – 2015-12-08T04:10:02.223

1The best answer, this way worked the best for me. – Ondra Žižka – 2016-03-24T11:04:59.423

4

It seems "-ss" is now fast and accurate in ffmpeg 2.1+ without specifying it twice. https://trac.ffmpeg.org/wiki/Seeking

– Conrad Meyer – 2018-09-30T20:35:01.170

If the video is long, trimming without -c copy directly is slow. However, you can do a rough trimming using the copy mode first and then trim the result more precisely with re-encoding. – danijar – 2019-12-16T08:24:24.240

27

I found that -ss combined with -c copy resulted in a half-second chop at the start.

To avoid that, you have to remove the -c copy (which admittedly will do a transcode).

Chris

Posted 2010-05-06T14:12:17.863

Reputation: 1 394

4There is another answer which deals with accuracy. Re-encoding with default option is often NOT what you want to do! – Tomasz Gandor – 2017-10-09T08:30:18.597

Good point @TomaszGandor – Chris – 2017-10-10T09:56:31.940

1I didn't understand @TomaszGandor's reply at all, but removing -c copy fixed it. – Iulian Onofrei – 2018-08-25T16:11:35.943

If you use -c copy it will maintain the original keyframes and their position. The 'lost time' at the start is depending on the spacing between the keyframes. – user1323995 – 2019-10-16T15:44:47.357

13

MANUALLY

Open the file in a media player that will frame by frame advance and play an AVISynth file with data such as:

DirectShowSource(("C:\Downloads\Video\Do you want him.flv"), Pixel_Type="yuy2").Crop(0,0,-0,-0)
Subtitle("C:\Downloads\Video\Do you want him.flv", font="Arial", size=24, text_color=$ff0000, align=3)
ShowFrameNumber(scroll=true, x=336, y=27, font="Arial", size=24, text_color=$ff0000)
ShowTime(x=398, y=44, font="Arial", size=24, text_color=$ff0000)

Then cut with the EXACT time format:

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:05.240 -to 00:00:08.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him1.flv"

and

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:10.240 -to 00:00:14.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him2.flv"

Now make a txt file with the video files with contents like:

file 'C:\Downloads\Video\Do you want him1.flv'
file 'C:\Downloads\Video\Do you want him2.flv'

Run ffmpeg:

ffmpeg -f concat -i FileList.txt -c copy "Path\NewName_joined.flv"

budman1

Posted 2010-05-06T14:12:17.863

Reputation: 180

If you use -c copy it will maintain the original keyframes and their position. Your videos will be cut to those keyframes, so no, the time will not be exact. – user1323995 – 2019-10-16T15:46:10.960

8

For me -t option didn't work, but -vframes worked. I prefer using #frames, since I would rather cut at I-Frames and I found out GOP for video using ffprobe.

The command line that worked for me is:

ffmpeg -ss 60s -i input.wmv -vframes 1800 -acodec copy -vcodec copy output.wmv

By the way, putting -ss in the front of -i makes a big difference in execution time.

Ben

Posted 2010-05-06T14:12:17.863

Reputation: 81

1Actually -vframes (or -frames:v) should come after -i because it's an output option. – slhck – 2013-11-20T12:55:15.400

5

As with user225366, the -t option doesn't work for short videos, but it does for longer videos. For short videos it seems that -frames:v is better. This is what worked for me.

ffmpeg -ss 4 -i input.mp4 -frames:v 200 -vcodec copy output.mp4

-acodec copy needs to added if the video has audio, as the other answers show.

VectorVortec

Posted 2010-05-06T14:12:17.863

Reputation: 181

0

I see not many mention this (I'm no expert so maybe there is a catch), but if your file has other streams like subtitles and other metadata like chapters and so on, it's possible to cut/trim and keep all streams with the following command

ffmpeg -to 60 -i input.mkv -map 0 -c copy output.mkv

With -map 0 you take all the streams in the file, and with -c copy you copy all them as they are.
Using -to omitting the start via -ss will cut the input video from start to second 60.

Fiddling with map is useful also if you want only specific streams to be kept in the cut (maybe you don't need all the audio sources in the file, or only some subtitles).

I use this when I need to split big MKV files that can't be stored in FAT32 storage.

Gruber

Posted 2010-05-06T14:12:17.863

Reputation: 255

0

use this format:

ffmpeg <start time> <input file> <cut duration> <out file>

eg. cut 60 second clip after 1 minute of video

ffmpeg.exe -ss 00:01:00 -i "in file.mp4" -to 00:01:00 -c copy out.mp4

Zimba

Posted 2010-05-06T14:12:17.863

Reputation: 107