16

I am trying to convert some files into ProRes. One fairly important part of the conversion is:

  • reducing frames from 60 to 30
  • blending every 2 frames into one and achieving a more fluent movement. (a simple sort of motion blur)

I have tried the -blend command, however it was not recognized as a command.

-i source.mp4 -r 30 -vcodec prores_ks -profile:v 0 Output.mov

How do I reduce frames with blending in ffmpeg?

RafaSashi
  • 16,483
  • 8
  • 84
  • 94
user3213418
  • 169
  • 1
  • 3

4 Answers4

6

Simple frame dropping:

ffmpeg -i input.mov -r 30 output.mov

Interpolate frames with the minterpolate filter:

ffmpeg -i input.mov -vf minterpolate=fps=30 output.mov
  • See link above as there are many additional options.

Interpolate frames with the framerate filter:

ffmpeg -i input.mov -vf framerate=fps=30 output.mov
  • See link above as there are many additional options.
Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
llogan
  • 121,796
  • 28
  • 232
  • 243
  • 1
    For me, `framerate` was literally 100x faster than `minterpolate` . – Benjamin H Jun 01 '21 at 21:47
  • It's normal to have such speed increase @BenjaminH. One mathematically models and a function and samples each frames at points of time and other drops the frames to approximate thereof. – tripulse Jan 12 '22 at 12:26
5

Try

ffmpeg -h

or

ffmpeg --help

and you'll have a short help. Please read it. :)

Try

ffmpeg -filters

and you'll have a list of available filters

Try

ffmpeg -help filter=name

and you'll have syntax and parameters for this filter


I already needed to do something like this, reducing framerate. If you do

ffmpeg -i "input" -r outputframerate [video encoding options...] [-y] "output"

Note : Things in brackets [] are optionnal.

You'll have a simple framerate change, with a possible loss of input frames. And, it's especially what you don't want to get.


To have a framerate change without a loss of input frames, you'll have to use a video filter.

The tblend filter blends successive frames. It is the filter to use if source framerate is an integer multiply of destination framerate (eg : 60→30, 75→15, 75→25, ...)

ffmpeg -i "input" -vf tblend=all_mode=average [video encoding options...] -r outputframerate⁽¹⁾ [-y] "output"

⁽¹⁾ If haven't tested this filter myself, and I'm sure the output framerate must be set somewhere. The tblend filter has no fps parameter. Maybe it just blends 2 successive frames ? You should check this point, and make some tries ?


There exists another framerate changer, more adapted to be used with any i/o framerates :

minterpolate : Frame rate conversion using Motion Interpolation.

So, type :

ffmpeg -i "input" -vf minterpolate=fps=outputframerate [video encoding options...] [-y] "output"

The other minterpolate parameters have good enough defaut values, to make sure a good blend. Check them with a

ffmpeg -help filter=minterpolate

If you want to add some parameters in the minterpolate chain, you'll have to use a ':' as parameter separator. Let's say you want to use motion interpolation mode = blend, instead of the default motion compensated interpolation (mci), type :

ffmpeg -i "input" -vf minterpolate=fps=outputframerate:mi_mode=blend [video encoding options...] [-y] "output"

If you want to use many videos filters, you must not chain -vf options. The last one will override the ones before. You must (as ':' for filter parameters) use ',' as filters separator. Ex :

ffmpeg -i "input" -vf minterpolate=fps=outputframerate:mi_mode=blend,filter2=param1=value1:param2=value2[...] [video encoding options...] [-y] "output"

The order of given filters are important.


Things have been done with

ffmpeg version 3.2.14-1~deb9u1 Copyright (c) 2000-2019 the FFmpeg developers

zebulon 1er
  • 75
  • 1
  • 3
  • 1
    ffmpeg -i "input" -vf tblend=all_mode=average [video encoding options...] -r outputframerate⁽¹⁾ [-y] "output" This one actually is really good. Much better than minterpolate. – thirsty93 Sep 05 '21 at 17:22
1

Specifically for blending between frames in a time lapse to give a really high quality almost blur between the frames you can use tblend=average.

This is what I ended up using and provides an incredibly soft, smooth look to my time lapse videos:

ffmpeg -i in_video.mp4 -vf "tblend=average,setpts=0.05*PTS" -r 60 -crf 2 -an out_video.mp4

Or, for your use case:

ffmpeg -i in_video.mp4 -vf "tblend=average,setpts=0.5*PTS" -r 30 -crf 2 -an out_video.mp4
Charles Lohr
  • 695
  • 1
  • 8
  • 23
0

The most generic solution uses tmix:

ffmpeg -i source.mp4 -vf tmix=frames=60/30 -r 30 ...

Where 60 is your input framerate and 30 your output.

Background

The tmix video filter takes every input frame and averages it with its follower. At that point, you have a 60fps blurry stream. The -r 30 subsamples that by selecting every other frame (and making it last twice as long), which leaves you with the desired result.

Nit picking

Technically speaking this only works if your ratio is an integer (e.g. 50/25, 60/20, but not 60/24). If you really want to be precise, you could go from 60->24 (=2.5 source frames per output frame) by e.g. weighting a middle frame at 100% and both its neighbours at 75%, for a total of 2.5:

ffmpeg -i source.mp4 -vf 'tmix=frames=3:weights=75 100 75' -r 25 ...

(Although I'm not sure why you would bother.)

Sources

Thanks to Ian for the link and Max for the answer.

hraban
  • 1,819
  • 1
  • 17
  • 27