I want to make a clip from a video with FFmpeg with 2-second video every m minutes, where

m = video_length / 5

For example I have a video that is 10 minutes long. The video clip will have 10 seconds total length (5 segments by 2 seconds) and will be composed of these video timestamp ranges:

00:00 - 00:02
02:00 - 02:02
04:00 - 04:02
06:00 - 06:02
08:00 - 08:02

This will produce a sort of trailer from the video.

I know I can achieve that with segment but can't figure out the whole process.


You can do this using the select filter, in one go

ffmpeg -i in.mp4
       -vf select='lt(mod(t,120),2)',setpts=N/FRAME_RATE/TB
       -af aselect='lt(mod(t,120),2)',asetpts=N/SR/TB
  • Seems something missing: [Parsed_select_0 @ 0x7fe018d02440] [Eval @ 0x7fff56fb2460] Missing ')' or too many args in 'mod(t' [Parsed_select_0 @ 0x7fe018d02440] Error while parsing expression 'lt(mod(t' [AVFilterGraph @ 0x7fe018d021a0] Error initializing filter 'select' with args 'lt(mod(t' Error opening filters! – kollo Mar 17 '17 at 8:25
  • 1
    Looks like you need to escape the commas. 'lt(mod(t\,120)\,2)' – Gyan Mar 17 '17 at 8:30
  • Yes better, could you explain a little bit lt(mod and setpts as actually it does not give the excepted result on a 5 mins video. seems 120 is the time in second and should be a var depending on video length ? The 10 mins video was just an example in my question, I may have to correct it. – kollo Mar 17 '17 at 8:39
  • 1
    lt(mod(t,120),2) selects all frames whose timestamp is less than 2 seconds from a multiple of 120 seconds. FFmpeg does not expose stream duration as a variable, so you'll have to run another command beforehand to get duration, divide that by 5 and then substitute it in place of 120. The select filter does not alter the timestamps of the selected frames, so when it selects the first frame from the 3rd minute, the frame retains that timestamp. During playback, there will be two minutes of freeze on the last frame selected from the first minute. To make timestamps contnuous, setpts is used. – Gyan Mar 17 '17 at 8:54
  • Perfect! Sad that that there is no duration var :/ – kollo Mar 17 '17 at 10:02

I know of a method which you might use. It's a bit messy, though.

Extract the clips with a command like this:

ffmpeg -i -ss <time to start> -t <duration> <output clip filename>

What you do is you extract the clips with this format, where -ss is the start of the clip, and -t is the duration of the clip. Once you have those extracted, you can then concatenate them together with:

ffmpeg -i concat:"clip_file1|clip_file2|clip_file3" -c copy <your output file>

Please note that this form of concatenation doesn't work with all video formats, and you may have to throw in some other arguments, such as -bsf:a aac_adtstoasc for MP4 files. But this should get you the video you desire.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.