Practical ffmpeg commands to manipulate a video
ffmpeg is a popular open-source tool to manipulate your video/audio files.
Remove video segments (without audio)
For example, you want to remove 108→157
, 226 → 341
, 404 → 407
(unit: second) segments from your video recording.
Note that the audio is not modified.
ffmpeg \
-i 'screenrecord.mp4' \
-filter_complex \
"[0:v]trim=duration=108[a] \
;[0:v]trim=start=157:end=226,setpts=PTS-STARTPTS[b] \
;[a][b]concat[c]; \
;[0:v]trim=start=341:end=404,setpts=PTS-STARTPTS[d] \
;[c][d]concat[e] \
;[0:v]trim=start=407,setpts=PTS-STARTPTS[f] \
;[e][f]concat[out]" \
-map [out] \
'screenrecord-cropped.mp4'
Explanation:
-i 'screenrecord.mp4'
: specify input source. Note: Multiple files can be specified, for example:-i video1.mp4 -i video2.mp4
.-filter_complex
: start the filter for video trim.[0:v]
: select the first (0
)v
ideo stream as parameters for the next filters.
trim
: specify a video trim filter.=
: set option for the video trim filter.duration=180
,start=157:end=226
,start=407
: option for the trim filter.
,
: the next filter.
setpts
: change the PTS (presentation timestamp) of the frame filter.=
: option for thesetpts
filter.PTS
: The presentation timestamp in input.-
: minus operator.STARTPTS
: The PTS of the first frame.
[a]
: set name to the trimmed segment toa
.;
: start a new filter chain.[c][d]
: specify input parameters.concat
: concat filter.-map [out]
: map user-mapped stream to the output file.'screenrecord-cropped.mp4'
: output file path.
Remove video+audio segments from a stream
ffmpeg \
-i 'screenrecord.mp4' \
-filter_complex \
"[0:v]trim=duration=108[va] \
;[0:a]atrim=duration=108[aa] \
\
;[0:v]trim=start=157:end=226,setpts=PTS-STARTPTS[vb] \
;[0:a]atrim=start=157:end=226,asetpts=PTS-STARTPTS[ab] \
\
;[va][vb]concat[vc]; \
;[aa][ab]concat=v=0:a=1[ac]; \
\
;[0:v]trim=start=341:end=404,setpts=PTS-STARTPTS[vd] \
;[0:a]atrim=start=341:end=404,asetpts=PTS-STARTPTS[ad] \
\
;[vc][vd]concat[ve] \
;[ac][ad]concat=v=0:a=1[ae] \
\
;[0:v]trim=start=407,setpts=PTS-STARTPTS[vf] \
;[0:a]trim=start=407,asetpts=PTS-STARTPTS[af] \
\
;[ve][vf]concat[vout]" \
;[ae][af]concat=v=0:a=1[aout]" \
\
-map [vout] \
-map [aout] \
\
'screenrecord-cropped.mp4'
Similar to the video-only cropping command:
concat=v=0:a=1
: concat audio only.asetpts
: works on audio frames.atrim
: atrim filter for audio frames.
Convert .gif image to .mp4 video
ffmpeg \
-r 30 \
-i input.gif \
-movflags faststart \
-pix_fmt yuv420p \
-c:v libx264 \
-crf 23 \
-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" \
output.mp4
ffmpeg main options reference.
-r
: frame rate video options.-r[:stream_specifier] fps (input/output,per-stream)
.-movflags faststart
: optimize the video format for playing, this flag may slow down the video conversion process a bit (source).-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"
: truncate the video size to be divisible by 2 because the H.264 format requires dimensions to be even numbers.pix_fmt
: set pixel format. To list all available pixel formats, useffmpeg -pix_fmts
. In the sample command, yuv420p is used (-pix_fmt yuv420p
is an alias for-vf format=yuv420p
).
# ffmpeg -pix_fmts
Pixel formats:
I.... = Supported Input format for conversion
.O... = Supported Output format for conversion
..H.. = Hardware accelerated format
...P. = Paletted format
....B = Bitstream format
FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL
-----
IO... yuv420p 3 12
IO... yuyv422 3 16
IO... rgb24 3 24
IO... bgr24 3 24
IO... yuv422p 3 16
IO... yuv444p 3 24
IO... yuv410p 3 9
IO... yuv411p 3 12
IO... gray 1 8
IO..B monow 1 1
IO..B monob 1 1
I..P. pal8 1 8
IO... yuvj420p 3 12
IO... yuvj422p 3 16
IO... yuvj444p 3 24
IO... uyvy422 3 16
..... uyyvyy411 3 12
IO... bgr8 3 8
.O..B bgr4 3 4
IO... bgr4_byte 3 4
IO... rgb8 3 8
.O..B rgb4 3 4
IO... rgb4_byte 3 4
IO... nv12 3 12
IO... nv21 3 12
IO... argb 4 32
IO... rgba 4 32
IO... abgr 4 32
IO... bgra 4 32
IO... gray16be 1 16
IO... gray16le 1 16
IO... yuv440p 3 16
IO... yuvj440p 3 16
IO... yuva420p 4 20
IO... rgb48be 3 48
IO... rgb48le 3 48
IO... rgb565be 3 16
IO... rgb565le 3 16
IO... rgb555be 3 15
IO... rgb555le 3 15
IO... bgr565be 3 16
IO... bgr565le 3 16
IO... bgr555be 3 15
IO... bgr555le 3 15
..H.. vaapi_moco 0 0
..H.. vaapi_idct 0 0
..H.. vaapi_vld 0 0
IO... yuv420p16le 3 24
IO... yuv420p16be 3 24
IO... yuv422p16le 3 32
IO... yuv422p16be 3 32
IO... yuv444p16le 3 48
IO... yuv444p16be 3 48
..H.. dxva2_vld 0 0
IO... rgb444le 3 12
IO... rgb444be 3 12
IO... bgr444le 3 12
IO... bgr444be 3 12
IO... ya8 2 16
IO... bgr48be 3 48
IO... bgr48le 3 48
IO... yuv420p9be 3 13
IO... yuv420p9le 3 13
IO... yuv420p10be 3 15
IO... yuv420p10le 3 15
IO... yuv422p10be 3 20
IO... yuv422p10le 3 20
IO... yuv444p9be 3 27
IO... yuv444p9le 3 27
IO... yuv444p10be 3 30
IO... yuv444p10le 3 30
IO... yuv422p9be 3 18
IO... yuv422p9le 3 18
IO... gbrp 3 24
IO... gbrp9be 3 27
IO... gbrp9le 3 27
IO... gbrp10be 3 30
IO... gbrp10le 3 30
IO... gbrp16be 3 48
IO... gbrp16le 3 48
IO... yuva422p 4 24
IO... yuva444p 4 32
IO... yuva420p9be 4 22
IO... yuva420p9le 4 22
IO... yuva422p9be 4 27
IO... yuva422p9le 4 27
IO... yuva444p9be 4 36
IO... yuva444p9le 4 36
IO... yuva420p10be 4 25
IO... yuva420p10le 4 25
IO... yuva422p10be 4 30
IO... yuva422p10le 4 30
IO... yuva444p10be 4 40
IO... yuva444p10le 4 40
IO... yuva420p16be 4 40
IO... yuva420p16le 4 40
IO... yuva422p16be 4 48
IO... yuva422p16le 4 48
IO... yuva444p16be 4 64
IO... yuva444p16le 4 64
..H.. vdpau 0 0
IO... xyz12le 3 36
IO... xyz12be 3 36
..... nv16 3 16
..... nv20le 3 20
..... nv20be 3 20
IO... rgba64be 4 64
IO... rgba64le 4 64
IO... bgra64be 4 64
IO... bgra64le 4 64
IO... yvyu422 3 16
IO... ya16be 2 32
IO... ya16le 2 32
IO... gbrap 4 32
IO... gbrap16be 4 64
IO... gbrap16le 4 64
..H.. qsv 0 0
..H.. mmal 0 0
..H.. d3d11va_vld 0 0
..H.. cuda 0 0
IO... 0rgb 3 24
IO... rgb0 3 24
IO... 0bgr 3 24
IO... bgr0 3 24
IO... yuv420p12be 3 18
IO... yuv420p12le 3 18
IO... yuv420p14be 3 21
IO... yuv420p14le 3 21
IO... yuv422p12be 3 24
IO... yuv422p12le 3 24
IO... yuv422p14be 3 28
IO... yuv422p14le 3 28
IO... yuv444p12be 3 36
IO... yuv444p12le 3 36
IO... yuv444p14be 3 42
IO... yuv444p14le 3 42
IO... gbrp12be 3 36
IO... gbrp12le 3 36
IO... gbrp14be 3 42
IO... gbrp14le 3 42
IO... yuvj411p 3 12
I.... bayer_bggr8 3 8
I.... bayer_rggb8 3 8
I.... bayer_gbrg8 3 8
I.... bayer_grbg8 3 8
I.... bayer_bggr16le 3 16
I.... bayer_bggr16be 3 16
I.... bayer_rggb16le 3 16
I.... bayer_rggb16be 3 16
I.... bayer_gbrg16le 3 16
I.... bayer_gbrg16be 3 16
I.... bayer_grbg16le 3 16
I.... bayer_grbg16be 3 16
..H.. xvmc 0 0
IO... yuv440p10le 3 20
IO... yuv440p10be 3 20
IO... yuv440p12le 3 24
IO... yuv440p12be 3 24
IO... ayuv64le 4 64
..... ayuv64be 4 64
..H.. videotoolbox_vld 0 0
IO... p010le 3 15
IO... p010be 3 15
IO... gbrap12be 4 48
IO... gbrap12le 4 48
IO... gbrap10be 4 40
IO... gbrap10le 4 40
..H.. mediacodec 0 0
IO... gray12be 1 12
IO... gray12le 1 12
IO... gray10be 1 10
IO... gray10le 1 10
IO... p016le 3 24
IO... p016be 3 24
..H.. d3d11 0 0
IO... gray9be 1 9
IO... gray9le 1 9
IO... gbrpf32be 3 96
IO... gbrpf32le 3 96
IO... gbrapf32be 4 128
IO... gbrapf32le 4 128
..H.. drm_prime 0 0
..H.. opencl 0 0
IO... gray14be 1 14
IO... gray14le 1 14
IO... grayf32be 1 32
IO... grayf32le 1 32
IO... yuva422p12be 4 36
IO... yuva422p12le 4 36
IO... yuva444p12be 4 48
IO... yuva444p12le 4 48
IO... nv24 3 24
IO... nv42 3 24
..H.. vulkan 0 0
..... y210be 3 20
I.... y210le 3 20
-c:v libx264
: encode the video in H.264 format. This option is optional becauseffmpeg
detects and uses H.264 as the default encoding when outputting.mp4
video file. Inc:v
,c
stands forc
odec
,v
means selecting the first video stream.libx264
is the codec name,copy
is a special codec name indicating keeping the source stream unchanged.-crf 23
: constant rate factor, the parameter to set your output video's quality. 0 is lossless, 23 is the default, 51 is the worst quality possible. Source.
Combining multiple images into a gif file can be easily achieved with the imageio package in Python.
from imageio import imsave, mimsave
mimsave('output.gif`, images)
Screen recording
The sample command from ffmpeg docs.
ffmpeg -f x11grab -video_size cif -framerate 25 -i :0.0 output.mpg
Press q
to quit the recording.
cif
is abbreviation for 352x288
.
On my PC, the default display is not :0
and there are multiple monitors, so I use this command.
ffmpeg -f x11grab -video_size 1920x1080 -r 25 -i :1.0+1920,0 output.mpg
To get the display value:
# echo $DISPLAY
:1
Cut video
Cut video input.mp4
from 5min12sec to 10min15sec, output to mp4.
ffmpeg -ss 5:12 -i input.mp4 -t 10:15 -c copy output.mp4
Note that: The order of flags must be -ss
then -i
then -t
. Otherwise, there will be several seconds of black screen (with sound) in the output video file. (source1, source2)
Concatenate two videos
echo "list input1.mp4" > list.txt
echo "list input2.mp4" >> list.txt
ffmpeg -f concat -i list.txt -c copy output.mp4
GUI
If you just want to cut/copy/paste your videos, I highly recommend the lossless-cut
project.