我非常喜欢FFmpeg修剪视频的方式,所以如果有人能帮助我,我会非常感激。 基本上,我想要做的是:我有一个视频序列,我希望它在某一秒内停止,冻结图像几秒钟(如暂停),然后再从同一帧完全再现。我可以说我正在处理三个视频: A.mp4 (视频序列的第一部分),B.mp4(冻结图像)和 C.mp4 (第二部分)部分视频序列)。此外,我还使用filter_complex执行叠加。
从静态图像生成视频的部分不是问题,我主要关注的是找到准确修剪和连接视频的方法。从其他帖子和来源,我发现FFmpeg修剪来自那些可以被强制的关键帧框架。但是,我获得的结果不合适,因为我的视频 A 的结尾与 C 开头不同。
我使用的命令如下:
ffmpeg -y -i VideoSequence.mp4 -c:v libx264 -pix_fmt yuv420p \
-force_key_frames "expr: gte(t,n_forced * 15)" -t 30 VideoOut.mp4
[请注意,Filter Complex中的所有内容都是关于叠加的,这样可以正常工作]
据我所知,生成的视频应该每隔15秒就有一个关键帧。现在,我想将视频分为两部分(#34;第二部分15""第二部分15")
ffmpeg -y -ss 00:00:01 -i VideoOut.mp4 -t 14 -c copy A.mp4
ffmpeg -y -ss 00:00:15 -i VideoOut.mp4 -t 5 -c copy C.mp4
如前所述,我希望A.mp4的结束与#34;匹配"以C.mp4的开头(以帧精度),但我得到的结果远非完美。
非常感谢,任何形式的帮助都将不胜感激!
答案 0 :(得分:5)
假设你的最终目标是我希望它在某一秒内停止,将图像冻结几秒钟(如暂停),然后从相同的确切帧再次重现。,当前的方法多代视频,不必浪费。
这是在一个命令中执行此操作的方法,假设视频为25 FPS。
Mysql
这里是过滤器图中发生的事情:
首先,视频被分成两个相同的流。然后从第2个开始到第15秒结束修剪第一个流。在环路滤波器中,从(最后一帧)#ffmpeg -i original.mp4 -filter_complex
"[0]split[a][b];
[a]trim=1:15,loop=75:1:349,setpts=N/FRAME_RATE/TB[pre];
[b]trim=15,setpts=N/FRAME_RATE/TB[post];
[0]atrim=1:15,asetpts=N/SR/TB[apre];
[0]atrim=15,asetpts=N/SR/TB[apost];
[pre][apre][post][apost]concat=a=1[v][a]"
-map "[v]" -map "[a]" paused.mp4
开始的1
帧循环75帧。然后时间戳被正规化,因为修剪或循环过滤器不会这样做。第二个分割流被修剪为从第16秒开始,其时间戳重置,两个流使用concat联合。如果您需要在联合流的顶部叠加某些内容,请在concat之后插入349
过滤器。
答案 1 :(得分:0)
由于您没有定义帧率,我认为问题可能是您的关键帧没有准确插入到您想要的位置。而不是每15帧强制一个,只需插入你需要的两个:
-force_key_frames 00:00:01,00:00:15
或者如果你只关心拆分是干净的而不是拆分的确切位置,你可以使用段复用器:
-f segment -segment_time 14 out%03d.mp4
有关此documentation的另一个想法:
-ss 位置(输入/输出)
当用作输入选项(-i
之前)时,在此输入文件中寻找位置。请注意,在大多数格式中,无法精确搜索,因此ffmpeg将在位置之前寻找最接近的搜索点。当转码和-accurate_seek
启用(默认值)时,搜索点和位置之间的这个额外段将被解码并丢弃。在进行流复制或使用-noaccurate_seek
时,它将被保留。当用作输出选项(在输出文件名之前)时,解码但丢弃输入,直到时间戳到达位置。
所以移动-ss
不应该有任何区别,但值得一试,特别是对于没有准确搜索的旧版本。