A list of ffmpeg commands that I frequently use or that I spent a long time finding out.

Info

The below commands can be generally combined together. Video filters need to be concatenated with comma if multiple are used together, but order matters, especially if it is complex.1

Here is a list of my combined commands:

  1. For combining time lapse videos, downsampling them and removing duplicate frames:

    ffmpeg -f concat -i input_list.txt -c:v libx264 -crf 23 -vf "format=yuv420p, scale=1920:1080,mpdecimate=hi=64*128:lo=64*48:frac=0.33,setpts=N/FRAME_RATE/TB" output.mp4

Concatenate videos

Generally I concatenate videos with same resolution and codec (h264 generally), so I just following this method:2

$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
    
$ ffmpeg -f concat -i mylist.txt -c copy output.mp4

Downsample videos

Downsampling videos (from 4K) to 1080p:3

ffmpeg -i input.mp4 -c:v libx264 -crf 23 -vf "format=yuv420p, scale=1920:1080" -c:a copy output.mp4

Downsampling videos to 720p:

ffmpeg -i input.mp4 -c:v libx264 -crf 23 -vf format=yuv420p -s hd720 -c:a copy output.mp4

Drop duplicate frames

ffmpeg -i input.mkv -vf "mpdecimate=hi=64*128:lo=64*48:frac=0.33,setpts=N/FRAME_RATE/TB" output.mkv

Useful to drop duplicate frames in time-lapse videos where nothing is going on.4

The tricky part is to estimate the hi & low values.

My way of figuring out the hi value is to save a screenshot of video frame using mpv or vlc. The resolution of the screenshot will be the same. I will estimate the number of pixels that are changing (generally a timestamp) and then use that for the hi value.

The low value is generally half or 1/3 of the hi value. And I keep the frac at 0.33 (or 0.25)

ffmpeg docs on hi, low and frac values:

Values for hi and lo are for 8x8 pixel blocks and represent actual pixel value differences, so a threshold of 64 corresponds to 1 unit of difference for each pixel, or the same spread out differently over the block.

A frame is a candidate for dropping if no 8x8 blocks differ by more than a threshold of hi, and if no more than frac blocks (1 meaning the whole image) differ by more than a threshold of lo.

Default value for hi is 64*12, default value for lo is 64*5, and default value for frac is 0.33.

Trim videos

ffmpeg -i input.avi -ss 00:00:00 -to 00:00:31 -c:v libx264 -crf 23 -vf format=yuv420p output.mp4

Remove frames periodically from videos

This took a loooooong time to figure this out. Finally, used the ffpeg reference5 along with some wrong stackoverflow posts to figure out the following command for picking 1 frame every 100 (n) frames:

ffmpeg -i input.mp4 -filter:v "format=yuv420p,select=not(mod(n+1\,100)),setpts=N/(FRAME_RATE*TB)" -c:v h264_videotoolbox -q:v 65 -an output.mp4

The setpts rebuilts the time base. This works for hevc_videotoolbox as well - picked h264 because it works properly with preview.

Macos specific formats

h264_videotoolbox - produces x264 at really fast rates6
hevc_videotoolbox - produces x265 at really fast rates7

Footnotes

  1. https://superuser.com/questions/1435505/does-it-matter-how-you-order-your-filtergraph-in-ffmpeg

  2. https://stackoverflow.com/questions/7333232/how-to-concatenate-two-mp4-files-using-ffmpeg

  3. https://video.stackexchange.com/questions/14907/how-to-downsample-4k-to-1080p-using-ffmpeg-while-maintaining-the-quality

  4. https://stackoverflow.com/questions/37088517/remove-sequentially-duplicate-frames-when-using-ffmpeg/67322549#67322549

  5. https://ffmpeg.org/ffmpeg-filters.html#Examples-166

  6. https://blog.andyhermann.ch/ffmpeg/macos/2022/01/13/ffmpeg-hardware-accelerated.html

  7. https://stackoverflow.com/questions/64924728/optimally-using-hevc-videotoolbox-and-ffmpeg-on-osx