5

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?

2 Answers 2

9
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).

1
i=-120
infile=<inputfile>
while [[ "$?" == "0" ]]; do \
    ((i+=120)) \
    ffmpeg -ss $i -t 120 -i $infile ${infile/.mpg/.$((i/120)).mpg} \
done
5
  • Thanks. Any explanatio on this:${infile/.mpg/.$((i/120)).mpg}?
    – DocWiki
    Jul 8, 2011 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, 2011 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, 2011 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, 2011 at 0:36
  • Here is my code: stackoverflow.com/questions/6631971/… Some errors cant be corrected.
    – DocWiki
    Jul 9, 2011 at 0:53

You must log in to answer this question.

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