Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a video lasting 10 minutes which I want to cut into five 2-minute segments.

I can use ffmpeg to cut a video to a specific time with the following:

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

Do I first have to obtain the length of the video and then repeat the above command, or is there a simpler way to do this?

share|improve this question
ffmpeg -i input.mp4 -map 0 -c copy -f segment -segment_time 120 -reset_timestamps 1 out%02d.mp4

...will create files along the lines of 'out01.mp4 'out02.mp4', each one being 120 seconds in duration (except the last one, which may be shorter). Note that it has to split up the file on a keyframe, so you won't get 100% accurate splitting. See the segment documentation.

If you're willing to re-encode, you can get accurate splitting using -force_key_frames. To force a key frame every 120 seconds and split using segment:

ffmpeg -i input.mp4 -map 0 -c:v libx264 -preset veryfast -crf 22 -c:a libfdk_aac -vbr 3 \
-force_key_frames expr:gte(t,n_forced*120) -f segment -segment_time 120 -reset_timestamps 1 out%02d.mp4

Alternatively, you can use -g to set the GOP size - this requires you to know the frame rate of your video. If your video has a frame rate of 25 fps, then a GOP of 120*25=3000 would get one keyframe every two minutes; obviously, this is too few! Reducing it to 300 will be more reasonable, and will give you keyframes on the places you need:

ffmpeg -i input.mp4 -map 0 -c:v libx264 -preset veryfast -crf 22 -c:a libfdk_aac -vbr 3 \
-g 300 -f segment -segment_time 120 -reset_timestamps 1 out%02d.mp4

The specific codecs your version of ffmpeg supports may be different to mine (you won't have libfdk_aac unless you compiled from source).

share|improve this answer
while [[ "$?" == "0" ]]; do \
    ((i+=120)) \
    ffmpeg -ss $i -t 120 -i $infile ${infile/.mpg/.$((i/120)).mpg} \
share|improve this answer
Thanks. Any explanatio on this:${infile/.mpg/.$((i/120)).mpg}? – DocWiki Jul 8 '11 at 23:16
Assuming that the infile's extension is .mpg, that should produce output files named infile.0.mpg infile.1.mpg infile.2.mpg ... – blahdiblah Jul 8 '11 at 23:36
Some checking with ffmpeg reveals that the $? condition isn't going to hit anyways because ffmpeg doesn't care if -ss is out of range. Changing the exit condition based on finding the length of the video or that output files aren't empty is left as an exercise for the reader. – blahdiblah Jul 9 '11 at 0:00
Nice exercise! MIN=ffmpeg -i ${1} 2>&1 | grep "Duration" | cut -d ' ' -f 4 | sed s/,// | cut -d ":" -f 2 – DocWiki Jul 9 '11 at 0:36
Here is my code:… Some errors cant be corrected. – DocWiki Jul 9 '11 at 0:53

You must log in to answer this question.

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