Merge Multiple Video Segments with FFmpeg Select
This article demonstrates how to use FFmpeg’s select and
aselect filters to extract multiple non-continuous segments
from a video and merge them into a single output file. You will learn
the exact command-line syntax required to define your time ranges,
synchronize the audio, and reconstruct the video timeline to prevent
frozen frames or playback gaps.
To cut and join multiple disjoint segments of a video using the
select filter, you must filter both the video and audio
streams simultaneously and then reset their presentation timestamps
(PTS). If you do not reset the timestamps, the output video will contain
frozen frames or empty gaps where the discarded segments used to be.
The FFmpeg Command
Below is the standard template command to select and merge two segments: from 0 to 10 seconds and from 30 to 40 seconds.
ffmpeg -i input.mp4 -vf "select='between(t,0,10)+between(t,30,40)',setpts=N/FRAME_RATE/TB" -af "aselect='between(t,0,10)+between(t,30,40)',asetpts=N/SR/TB" output.mp4Command Breakdown
-i input.mp4: Specifies the input video file.-vf "...": Applies the video filtergraph.select='between(t,0,10)+between(t,30,40)': This tells FFmpeg to only keep video frames where the timestamptis between 0 and 10 seconds, OR (represented by+) between 30 and 40 seconds.setpts=N/FRAME_RATE/TB: This re-calculates the presentation timestamps for the selected video frames sequentially. It removes the temporal gap between the two segments, ensuring smooth playback.
-af "...": Applies the audio filtergraph.aselect='between(t,0,10)+between(t,30,40)': Selects the audio samples corresponding to the same time segments to keep the audio in sync with the video.asetpts=N/SR/TB: Resets the audio timestamps sequentially based on the sample rate (SR) and timebase (TB), matching the video timeline adjustment.
Adding More Segments
You can add as many segments as you need by appending more
between(t,start,end) statements separated by the
+ operator.
For example, to select three segments (0-10s, 30-40s, and 60-70s), use the following syntax:
ffmpeg -i input.mp4 -vf "select='between(t,0,10)+between(t,30,40)+between(t,60,70)',setpts=N/FRAME_RATE/TB" -af "aselect='between(t,0,10)+between(t,30,40)+between(t,60,70)',asetpts=N/SR/TB" output.mp4