10

I need to speed up video by a factor of 4x, but do not want to drop the frames and instead average them. I.e. each 4 frames are averaged, and produce 1 output frame. Target frame-rate stays the same, so video is now 4 times faster.

Is there a way to do so in ffmpeg?

8
  • 3
    Can you be more specific about how they should be "averaged"? What method do you want to use?
    – llogan
    Oct 5, 2015 at 6:09
  • @LordNeckbeard (f1+f2+f3+f4)/4 - simple averaging. So each resulting frame have faint traces of the movement on all sub-frames. Oct 5, 2015 at 11:32
  • @BarsMonster I doubt ffmpeg can do this. Have you seen this effect done another way? Do you know what it actually looks like?
    – Jim Mack
    Oct 5, 2015 at 15:08
  • @JimMack I currently did that manually in VirtualDub, they have interpolate filter, with 0.5x interpolation it does correctly average 2 frames. Here is the result : youtube.com/watch?v=8zrws5CGWsI One can see that each frame has movement of 2 subframes, so it is slightly smoother. But doing so in a cmdline would be much faster in the future. Oct 5, 2015 at 18:16
  • slowmoVideo may be worth a try, but I don't know if it has a cli. The FFmpeg framerate filter appears to perform interpolation, but it does not seem to fit your needs.
    – llogan
    Oct 5, 2015 at 21:26

2 Answers 2

3

I use these commands:

4x speedup:

ffmpeg" -r 60 -i "inputfile.mp4"  -vf "tmix=frames=4:weights='1',select='not(mod(n\,4))',setpts=0.25*PTS" -c:v libx265 -an -x265-params crf=25 "outputfile.mp4"

16x speedup:

ffmpeg" -r 60 -i "inputfile.mp4"  -vf "tmix=frames=16:weights='1',select='not(mod(n\,16))',setpts=0.0625*PTS" -c:v libx265 -an -x265-params crf=25 "outputfile.mp4"

The "-r 60" parameter is used to specify the source file fps.
The "crf=25" parameter define the encoding quality (lower number = higher quality = higher size)

2
  • Thanks, that is much more robust and universal solution! Jan 2, 2022 at 10:22
  • 1
    I liked the apparent scalability of this answer, but it turns out this is ridiculously inefficient. If you do a 4× speedup for example, it's generating 4 frames (each averaging the previous 4 frames of the input) and then discarding 3 of them, for each frame of the output. I wanted to do a 60× speedup… you can do the maths. I discovered it would take more than twice as long to render (on an 8-core machine) as the runtime of the original video! Gyan's answer on the other hand, while rather inconvenient for large speedups, scales well because it doesn't do any wasted effort.
    – mystery
    Dec 28, 2022 at 11:34
12

ffmpeg with this filterchain does it:

ffmpeg -i input -vf "tblend=average,framestep=2,tblend=average,framestep=2,setpts=0.25*PTS" -r srcfps -{encoding parameters} output

srcfps should be replaced with your input's framerate.

5
  • 3
    Also tried for x16 using "tblend=average,framestep=2,tblend=average,framestep=2,tblend=average,framestep=2,tblend=average,framestep=2,setpts=0.0625*PTS" Oct 15, 2016 at 15:31
  • so the multiplier to PTS is important to increase rate Dec 12, 2020 at 15:53
  • @BarsMonster is there a way to use this to combine every frame in the video into a single image output? The docs seem to suggest (since it will use the longest input) that I can just increase the multiplier, but i'm getting silly results before I even get that far, e.g. at 256x with pts at 1/256*PTS I am getting 0.3fps and only 3 frames out of 72,000 when I would expect 281.
    – Michael
    Feb 22, 2021 at 16:18
  • @BarsMonster In fact, adjusting PTS doesn't seem to change the reported frame rate, even as high as 0.1PTS I'm still seeing 0.3fps.
    – Michael
    Feb 22, 2021 at 16:23
  • If I use setpts=1*PTS, it's still 0.3fps, but it does produce the expected number of output frames.
    – Michael
    Feb 22, 2021 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.