通过FFMPEG平滑FPS更改
我有一个来自GoPro的240FPS视频,我想把它线性地降到30FPS。为此,我使用:通过FFMPEG平滑FPS更改,ffmpeg,Ffmpeg,我有一个来自GoPro的240FPS视频,我想把它线性地降到30FPS。为此,我使用: ffmpeg -i raw.mp4 -filter_complex "[v:0]setpts='lerp(2,8,T/5)*PTS" -r 30 output.mp4 *5是以秒为单位的视频持续时间 问题是由此产生的视频口吃相当严重。但是如果我使用一个固定的setpts,比如setpts=8*PTS,那么一切都很好 如何通过FFMPEG实现平滑的FPS转换?对于视频 ffmpeg -i raw.mp4 -f
ffmpeg -i raw.mp4 -filter_complex "[v:0]setpts='lerp(2,8,T/5)*PTS" -r 30 output.mp4
*5是以秒为单位的视频持续时间
问题是由此产生的视频口吃相当严重。但是如果我使用一个固定的setpts
,比如setpts=8*PTS
,那么一切都很好
如何通过FFMPEG实现平滑的FPS转换?对于视频
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
应该这样做,除了第一秒是在正常帧速率
从概念上讲,我发现以图形的方式来做这件事是最容易的。请看图片,其中x轴为时间,y轴为PTS
在哪里
我正在使用setpts过滤器
PTS(表示时间戳)指示何时显示帧,因此PTS*1表示在输出中与在输入中同时显示帧,其中PTS*0.5指示在输入时间的50%显示帧,以此类推
所以
意味着在第一秒钟内保持帧速率不变(这主要是因为不能用零除)。之后,区域A1是1×1=1
在t1=1s时,我们开始降低帧速率,方法是告诉每一帧的出现时间比输入时间晚。面积A2是一个梯形,其中面积由侧面乘以基底的平均值计算。底面为T-1,边的平均值为(1+(7*T/4+1-7/4))/2(通过为线创建函数)。要获得1到5秒之间任何给定帧的PTS,我们必须将所有(本例中为一个)先前区域的面积相加,然后除以PTS*1的面积,等于T
因此,从1s到5s,通过以下公式计算PTS:
((T-1)*(1+7*T/4+1-7/4)/2+1)/T)*PTS
不幸的是,在ffmpeg中对音频使用相同的方法会丢失大量数据并导致严重的声音中断(至少是为了提高速度)。由于我可以准确地计算视频的持续时间(与A1+A2区域相同),我最终使用audacity尝试手动拟合每个可变速率部分
((T-1)*(1+7*T/4+1-7/4)/2+1)/T)*PTS