FFmpeg – tips and tricks
Over the years, and in particular with preparing videos of a conference for publication on YouTube, I have accumulated a few reminders how to do things with FFmpeg. It is such a fantastic beast full of features, that I will never run out of new things to learn.
(Update 2022-11-30: Found that excellent lengthy intro: FFmpeg – The Ultimate Guide)
So here we go, in some rather random order:
split at time stamps
Basic usage:
ffmpeg -i INPUT -ss STARTTS -to ENDTS -c copy OUTFILE
WARNING: since splitting is only possible at keyframes, this will by default set an “editlist” and start at the previous keyframe, and tell the player to start playing after the required difference.
Now that is a pain, because watermarking (see below) requires
--ignore_editlist 1
and then the audio gets out of sync!!!!
In this case one need to do the splitting already in addition to recoding and resizing so that it splits at the exact time!!!
concat two mp4 files
ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4
see Concatenation of files with same codecs, at concat protcocol
cut out a part from STARTCUT – ENDCUT
This is done by creating two intermediate files by rendering only the initial or end part and at the same time encoding to mpeg-2 transport streams:
ffmpeg -i INPUT -ss 00:00:00 -to STARTCUT -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i INPUT -ss ENDCUT -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4
concat different formats
ffmpeg -i file1.mp4 -i file2.mp4 -i file3.mp4 \
-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4
see here.
watermark
ffmpeg -i INPUT.mp4 -i TUG-33.png -filter_complex "overlay=x=(main_w-overlay_w-30):y=(main_h-overlay_h-30)" OUTPUT.mp4
If there is an error like
Could not find codec parameters for stream 0 ... unspecified pixel format
one needs to add -ignore_editlist 1
which in turn requires proper cutting, see above.
(if necessary, add -analyzeduration 100M -probesize 100M
)
simple scaling
ffmpeg -i input.avi -vf scale=320:240 output.avi
scale and watermark
ffmpeg -ignore_editlist 1 -i INPUT -i TUG-33.png -filter_complex "[0:v]scale=1920:1080 [mnn], [mnn][1:v]overlay=x=(main_w-overlay_w-30):y=(main_h-overlay_h-30)" OUTPUT
You can use the -ss
option to specify a start timestamp, and the -t
option to specify the encoding duration. The timestamps need to be in HH:MM:SS.xxx
format or in seconds (s.msec
).
The following would clip the first 30 seconds, and then clip everything that is 10 seconds after that:
ffmpeg -ss 00:00:30.0 -i input.wmv -c copy -t 00:00:10.0 output.wmv
ffmpeg -ss 30 -i input.wmv -c copy -t 10 output.wmv
Note that -t
is an output option and always needs to be specified after -i
.
Some tips:
For older ffmpeg versions, if you use -ss
after -i
, you get more accurate seeking at the expense of a slower execution altogether. See also: Seeking with FFmpeg. You can use -to
instead of -t
to specify the timestamp to which you want to cut. So, instead of -i -ss 30 -t 10
you could also do -i -ss 30 -to 40
to achieve the same thing.
If your ffmpeg does not support -c
, or -to
, it is likely very outdated. Compile a new version yourself or download a static build from their homepage. It’s really not complicated.
still image (screenshot) from video
Trivial solution would be
ffmpeg -y -ss 00:$i -i $INPUT -frames:v 1 -q:v 2 ${OUTPUT}.jpg
but that does not keep aspect ratio (DAR Display Aspect Ratio). To get correct output:
ffmpeg -y -ss 00:$i -i $INPUT -vf scale='trunc(ih*dar):ih',setsar=1/1 -frames:v 1 -q:v 2 ${OUTPUT}.jpg
Thank you!
The age of WYSIWYG tends to underestimate (or forget) the power of command line tools.
Here are a few more:
“`bash
# extract mp3 from avi:
ffmpeg -i MVI_3826-2.avi -vn -ar 44100 -ac 2 -ab 320k -af volume=4.000000 -f mp3 MVI_3826.mp3`
# Extract audio from mp4
ffmpeg -i foo.mp4 bar.mp3
ffmpeg -i myvideo.mp4 -codec:a libmp3lame audio.mp3
# ffprobe
ffprobe.exe -hide_banner foo.mp4
ffprobe.exe -hide_banner -show_format foo.mp4
ffprobe.exe -hide_banner -show_streams foo.mp4
# Scale down for web:
– keep aspect ratio so that height is adjusted to fit
ffmpeg -y -i file.mp4 -vf scale=640:-2,setsar=1:1 -c:v libx264 -c:a copy file-s.mp4
“`
Probably not for you but for potential onlookers, keep in mind you should often use the likes of -c:a copy to do it without reencoding. It depends a bit on the era, but AVI with divx/xvid and mp3 is rather common.
Just for fun, in case on the contrary you need to _remove_ watermarks (in a rough fashion) I once made this 😄
https://github.com/m3at/video-watermark-removal
Haa, very nice, and cool idea how to compute the watermark. Thanks!
Thanks for sharing some knowledge, much appreciated! It is an amazing piece of software.
Well, I start to be very worried. It’s Jan. 16th, your last post is from late Nov. Are you ok?
Thanks for the worries, but I am fine. Contemplating writing a “final” Debian article, and some other stuff.
OK, phew I’m relieved… 😉