Reputation: 807
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
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.
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