ffmpeg, a command-line tool, can do this in one command.
Update: New template, first below, is easier to manipulate (and understand)
This is a generalized command template:
ffmpeg -i input -filter_complex "[0:v]select='gte(mod((t\-FS),I),0)*lt(mod((t\-FS),I),D)', setpts=N/TB/FRAME_RATE[v]; [0:a]aselect='gte(mod((t\-FS),I),0)*lt(mod((t\-FS),I),D)', asetpts=N/SR/TB[a]" -c:v libx264 -crf 23 -map "[v]" -map "[a]" -fflags +genpts output.mp4
Alternate method:
ffmpeg -i input.mp4 -filter_complex "[0:v]select=isinf(t\/(mod(D*trunc(1+(t/D))\,Interval))),setpts=N/TB/FRAME_RATE[v];[0:a]aselect=isinf(t\/(mod(D*trunc(1+(t/D))\,Interval))),asetpts=N/SR/TB[a]" -c:v libx264 -crf 23 -map "[v]" -map "[a]" -fflags +genpts output.mp4
This is the first command formatted for full visibility
ffmpeg -i input -filter_complex \
"[0:v]select='gte(mod((t\-FS),I),0)*lt(mod((t\-FS),I),D)', \
setpts=N/TB/FRAME_RATE[v]; \
[0:a]aselect='gte(mod((t\-FS),I),0)*lt(mod((t\-FS),I),D)', \
asetpts=N/SR/TB[a]" \
-c:v libx264 -crf 23 -map "[v]" -map "[a]" -fflags +genpts output.mp4
Basically, replace input
with your source video filename, output.mp4
with your intended output name.
Replace D
with duration of segment, I
for gap between the start of two segments and FS
with start time of first segment . So, for 3-second segments every 45 seconds, starting at 36 seconds, from a file called fullfile.mp4
, the command will be
ffmpeg -i fullfile.mp4 -filter_complex \
"[0:v]select='gte(mod((t\-36),45),0)*lt(mod((t\-36),45),3)', \
setpts=N/TB/FRAME_RATE[v]; \
[0:a]aselect='gte(mod((t\-36),45),0)*lt(mod((t\-36),45),3)', \
asetpts=N/SR/TB[a]" \
-c:v libx264 -crf 23 -map "[v]" -map "[a]" -fflags +genpts output.mp4
These segments will be extracts from seconds 36 to 39, 81 to 84..etc
Download ffmpeg for Windows (32-bit static build) from here.