Cut and Merge Video Segments with FFmpeg Select
This guide explains how to extract multiple disjoint segments from an
input video and seamlessly combine them into a single output file using
FFmpeg. By leveraging the select video filter and the
aselect audio filter alongside timestamp recalculation, you
can cut and concatenate various parts of your media in a single command
without creating temporary files.
The Basic Syntax
To cut and join multiple segments, define time intervals using the
between(t, start, end) function within both the video and
audio filtergraphs, joined by the addition operator (+),
which acts as a logical OR.
Here is the standard command structure:
ffmpeg -i input.mp4 -vf "select='between(t,10,20)+between(t,45,60)',setpts=N/FRAME_RATE/TB" -af "aselect='between(t,10,20)+between(t,45,60)',asetpts=N/SR/TB" output.mp4In this example, FFmpeg extracts the segment between 10 and 20
seconds, and the segment between 45 and 60 seconds, merging them into
output.mp4.
How the Filters Work
selectandaselect:- The
between(t, start_seconds, end_seconds)expression returns1(true) if the current timestamptfalls within the range, and0(false) otherwise. - Adding multiple
between()expressions with+allows the filter to retain frames from any specified range while dropping frames that fall outside them.
- The
setpts=N/FRAME_RATE/TB:- Dropping frames creates gaps in Presentation Time Stamps (PTS).
- Recalculating the PTS using the frame count (
N), input frame rate (FRAME_RATE), and time base (TB) generates continuous timestamps, preventing video freezing or playback stutter.
asetpts=N/SR/TB:- Functions identically to the video timestamp filter, but for audio.
- It reconstructs continuous audio timestamps based on the audio
sample count (
N), sample rate (SR), and time base (TB) to maintain audio-video synchronization.
Selecting More Than Two Segments
To add more segments, simply chain additional between()
expressions within the single quotes:
ffmpeg -i input.mp4 -vf "select='between(t,5,15)+between(t,30,40)+between(t,75,90)',setpts=N/FRAME_RATE/TB" -af "aselect='between(t,5,15)+between(t,30,40)+between(t,75,90)',asetpts=N/SR/TB" output.mp4Selecting Segments by Frame Numbers
If exact time offsets are difficult to calculate or frame accuracy is
critical, you can replace the time parameter t with the
frame index n (for video only):
ffmpeg -i input.mp4 -vf "select='between(n,100,250)+between(n,500,750)',setpts=N/FRAME_RATE/TB" -af "aselect='between(t,4.17,10.42)+between(t,20.85,31.28)',asetpts=N/SR/TB" output.mp4Note: The audio filter aselect does not support
video frame numbers (n), so audio ranges must still be
specified in seconds or sample counts.