除了使用-ss
和-to
寻找似乎不太准确的参数外,我可以根据给定的帧数剪切视频吗?例如;
ffmpeg -i video.webm -startingframe 80 -endingframe 560 output.webm
[包括第 80 帧和第 560 帧。因此,总共是 (560 - 80 +1) 帧]
经过回答和一番搜索后,我尝试了一些命令。但到目前为止,我找不到可接受的方法。
如果有人想剪切第 250 帧和第 750 帧之间的视频流,可以采用以下方法。它将输出 501 帧:
笔记:movie.mp4 的帧率为 25 fps,音频采样率为 48k
ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm
正如预期的那样,输出正好是 20 秒长。
对音频使用相同的方法:
ffmpeg -i movie.mp4 -vn -af "aselect=between(n\,480\,1440),setpts=PTS-STARTPTS" a_stream.webm
出乎意料的是,这个的准确率很差。它应该给我 960001(960k+1)个样本,相当于 20 秒的音频。但输出却是 20.505 秒长,有 984240 个样本。此外,如果我增加持续时间,误差也会增加。
然后我尝试使用 -ss -to 参数来剪切音频流:
ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm
传统的方法效果更好。输出时长为 20.003 秒,有 960144 个样本。此外,增加持续时间不会增加误差,误差是恒定的,该输入文件始终有 144 个样本剩余。
总结:
select
过滤器在大多数情况下效果很好,但aselect
事实并非如此。经典-ss
参数更适合音频,但样本不准确。此外,不能同时使用-vf select
和-ss
参数,因为-ss
会影响音频和视频流,而我们希望它只影响音频。
因此,为了精确剪切媒体文件,我必须执行以下 3 个步骤:
ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm
ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm
ffmpeg -i v_stream.webm -i a_stream.webm -c:v copy -c:a copy movie-between_10th_and 20th_seconds.webm
这给出了最准确的结果。视频时长 20,000 秒,帧精确音频时长 20.003 秒,有 960144 个样本。与视频流不完全匹配,但还可以。只有 144 个样本剩余。最大的缺点是,每当我想剪切文件时,我必须为一个简单的任务发送 3 个命令,它会创建两个不必要的文件:a_stream.webm
和v_stream.webm
。而且select
过滤器对我尝试过的一些输入文件不起作用。它成功完成了任务(?)但从不停止编码过程,所以我每次都必须关闭命令提示符。
答案1
音频以秒为单位,而不是以帧为单位,因此,如果要剪切视频,则必须计算视频 fps × 20 秒,如下所示:20 秒,23.97 fps = 479.4
帧剪切并不准确,因为您无法在最后一秒获得完整的 fps,因此音频将获得更多秒数或仅半秒或多一点或少一点!也许您应该使用秒而不是帧来获得精确的剪切,您告诉 ffmpeg 为您完成此操作。如果您得到 1 个额外的帧,那么将第 250 和第 750 帧更改为第 250 和第 749 帧怎么样?!在那里使用减 1 始终可以获得您要求的帧数!
答案2
无法根据帧号进行搜索。从特定帧开始的唯一方法是将帧数转换为 ss.ms 语法,或 hh:mm:ss.ms。因此,如果您的视频为 25 fps,并且您希望从 250 帧开始,在 750 帧结束,则需要先计算时间戳:
250/25 = 10
750/25 = 30
您可以使用调整过滤器随着setpts,asetpts 过滤器在精确的位置剪切视频,例如
ffmpeg -i movie.mp4 \
-filter_complex '[0:v]setpts=(PTS-STARTPTS),trim=10:30 \
[0:a]asetpts=(PTS-STARTPTS),atrim=10:30' \
movie-between_10th_and 20th_seconds.webm
请确保在修剪过滤器之前添加setpts=(PTS-STARTPTS)
和,asetpts=(PTS-STARTPTS)
以确保 pts 的计数从 开始0
,以便产生帧精确的输出