FFmpeg - 如何高精度修剪?

DSa*_*nga 4 ffmpeg

我非常喜欢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
Run Code Online (Sandbox Code Playgroud)

[请注意,Filter Complex内部的所有内容都是关于Overlay,它工作正常]

据我所知,生成的视频应该每隔15秒就有一个Keyframe.现在,我想将视频分为两部分("在第二个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 
Run Code Online (Sandbox Code Playgroud)

如上所述,我期望A.mp4的结束与C.mp4的开头"匹配"(以帧精度),但我获得的结果远非完美.

非常感谢,任何形式的帮助将不胜感激!

Gya*_*yan 5

假设您的最终目标是我希望它在某一秒内停止,请将图像冻结几秒钟(如暂停),然后从同一帧中再次重现.当前的方法,具有多代视频,不必要地浪费.

假设视频为25 FPS,这是在一个命令中执行此操作的方法.

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
Run Code Online (Sandbox Code Playgroud)

这是filtergraph中发生的事情:

首先,视频被分成两个相同的流.然后从第2个开始到第15秒结束修剪第一个流.在环路滤波器中,1从(最后一帧)开始的帧#349循环75帧.然后时间戳被正规化,因为修剪或环路滤波器不会这样做.第二个分割流被修剪为从第16秒开始,其时间戳重置,两个流使用concat联合.如果需要在关节流的顶部叠加某些内容,请overlay在连续后插入过滤器.


Sto*_*ica 0

由于您没有定义帧速率,我认为问题可能是您的关键帧没有准确插入到您想要的位置。无需强制每 15 帧插入一帧,只需插入您需要的两帧即可:

-force_key_frames 00:00:01,00:00:15
Run Code Online (Sandbox Code Playgroud)

或者,如果您只关心分割是否干净而不是分割的确切位置,则可以使用分段复用器:

-f segment -segment_time 14 out%03d.mp4
Run Code Online (Sandbox Code Playgroud)

关于本文档的另一个想法:

-ss位置(输入/输出)
当用作输入选项(在 之前-i)时,在此输入文件中查找位置。请注意,在大多数格式中不可能精确查找,因此 ffmpeg 将查找位置之前最近的查找点。当转码和-accurate_seek启用(默认)时,搜索点和位置之间的额外段将被解码并丢弃。当进行流复制或-noaccurate_seek使用时,它将被保留。

当用作输出选项(在输出文件名之前)时,解码但丢弃输入,直到时间戳到达位置。

因此,移动-ss应该不会有任何区别,但值得一试,特别是对于没有精确搜索的旧版本。