Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过FFMPEG平滑FPS更改_Ffmpeg - Fatal编程技术网

通过FFMPEG平滑FPS更改

通过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

我有一个来自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 -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