我非常喜欢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的开头"匹配"(以帧精度),但我获得的结果远非完美.
非常感谢,任何形式的帮助将不胜感激!
假设您的最终目标是我希望它在某一秒内停止,请将图像冻结几秒钟(如暂停),然后从同一帧中再次重现.当前的方法,具有多代视频,不必要地浪费.
假设视频为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在连续后插入过滤器.
由于您没有定义帧速率,我认为问题可能是您的关键帧没有准确插入到您想要的位置。无需强制每 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应该不会有任何区别,但值得一试,特别是对于没有精确搜索的旧版本。
| 归档时间: |
|
| 查看次数: |
3878 次 |
| 最近记录: |