RazrFalcon
RazrFalcon

Reputation: 807

Smooth FPS change via FFMPEG

I have a 240FPS video from GoPro and I want to slow down it to 30FPS linearly. For this I'm using:

ffmpeg -i raw.mp4 -filter_complex "[v:0]setpts='lerp(2,8,T/5)*PTS" -r 30 output.mp4

* 5 is video duration in seconds

The problem is that the resulting video stutters pretty heavily. But if I use a fixed setpts, like setpts=8*PTS, then everything is fine.

How to make smooth FPS transition via FFMPEG?

Upvotes: 1

Views: 1412

Answers (1)

ovikoomikko
ovikoomikko

Reputation: 577

For video,

ffmpeg -i raw.mp4 -filter:v "setpts='if(between(T,0,1),PTS,(((T-1)*(1+7*T/4+1-7/4)/2+1)/T)*PTS)'" -an output.mp4

should do that, with the exception of the first second being at a normal frame rate.

Conceptually, I found it easiest to do this graphically. Please see the image, where x axis is time and y axis is PTS.

Concept of method

Where enter image description here

I am using the setpts filter.

The PTS (presentation timestamp) tells when to show the frame, so PTS*1 means to show it at the same time in the output as in the input, where PTS*0.5 tells to show it at 50% of input time etc.

So

setpts='if(between(T,0,1),PTS

means to keep the framerate same for the first second (this mostly due to the fact that one cannot divide with a zero). After which, the Area A1 is 1*1 = 1.

At t1=1s we start to decrease the framerate by telling each frame to come at a later time than in the input. The area A2 is a trapezoid where the area is calculated by the average of the sides times the base. Base is T - 1 and average of sides is ( 1 + ( 7 * T/4 + 1 - 7/4 ) ) / 2 (from creating a function for the line). To get the PTS of any given frame between 1 and 5 seconds, we must add the area of all (one in this case) previous areas and divide by the area of PTS*1, which equals T.

Thus from 1s to 5s, the PTS is calculated by

((T-1)*(1+7*T/4+1-7/4)/2+1)/T)*PTS

Unfortunately using the same method for audio in ffmpeg drops a lot of data and results in badly breaking sound (for speed-up at least). As I can accurately calculate the duration of the video (it is the same as the areas A1+A2), I ended up using audacity to try and fit each variable rate portion manually.

Upvotes: 2

Related Questions