如何使用 ffmpeg 进行精确帧剪切?

如何使用 ffmpeg 进行精确帧剪切?

我正在尝试使用 ffmpeg 在精确的时间剪切视频文件。ffmpeg 帮助显示了一个选项 -timecode_frame_start 来指定起始帧,但我无法让此命令工作。生成的视频总是从原始视频的开头开始。以下是我正在运行的命令的示例:

ffmpeg -i input.mpg -acodec copy -vcodec copy -timecode_frame_start 200 -vframes 210 -n ouput.mpg

我已将 timecode_frame_start 选项移至其他选项之前和之后,结果没有变化。我是否需要指定其他选项?我尝试了各种文件格式,mkv、avi、mp4,但问题似乎与编解码器无关。这是我尝试过的一个文件:

http://www.seaotter.com/marine/movies/hermit-long-01.mpg

我是否遗漏了什么?

答案1

timecode_frame_start不像这样工作。

根据帧号进行搜索是不可能的。从特定帧开始的唯一方法是将帧数转换为ss.ms语法,或hh:mm:ss.ms。因此,如果您的视频为 25 fps,并且您想从 133 帧开始,则需要先计算时间戳:

133/25=5.32

然后运行:

ffmpeg -ss 5.32 -i input.mp4 -c:v libx264 -c:a aac out.mp4

请注意,无法使用比特流复制 ( ) 剪切精确帧-c:v copy,因为并非所有帧都是帧内编码(“关键帧”)。视频必须以关键帧开始才能正确解码。因此,您必须重新编码视频,例如使用如上-c:v libx264所示的 H.264。您还可以选择无损编解码器,这样-c:v ffv1可以保留输入视频的质量。

总而言之,-ss执行重新编码时始终是帧精确的。

如果您还想编码特定数量的帧,请使用-frames:v,例如:

ffmpeg -ss 5.32 -i input.mp4 -c:v libx264 -c:a aac -frames:v 60 out.mp4

请注意,您也可以选择使用select/aselect过滤器选择帧/音频样本。

ffmpeg -i input.mp4 -vf 'select=gte(n\,100)' -c:v libx264 -c:a aac out.mp4

然而,这比上面显示的选项慢-ss,因为整个视频都将被解码。

答案2

选项

-vf select="between(n\,start_frame_num\,end_frame_num),setpts=PTS-STARTPTS"

例如,

-vf select="between(n\,200\,300),setpts=PTS-STARTPTS"

将视频从第 200 帧(含)剪切至第 300 帧(含),序列计数从 0 开始。

答案3

无损剪辑是一款跨平台 GUI 工具,使用 FFmpeg 作为后端,可无损剪切视频。您可以选择在关键帧或任意帧处剪切。

答案4

我有一个解决方案,但我不知道如何使用当前的 ffmpeg 命令来做到这一点(我在关键帧处复制的尝试也不准确。我想知道 ffmpeg 如何决定切点)。

我建议采用这种算法,将我们要复制的段(t1,t2)分为 3 个部分:

  1. 部分 (t1-x, t1+y),这是一个完整的编码块,应该重新编码才能精确复制部分 (t1, y)。
  2. 部分 (t2-z, t3+w),这是一个完整的编码块,应该重新编码才能精确复制部分 (z, t2)。
  3. 中间部分(y,z)包含完整的编码块,可以按原样复制。
  4. 将上述步骤得到的 3 个部分连接起来。

请注意,前两部分预计会很小(其中一个或两个部分的长度可以为零),因此重新编码过程会很快。这将使我们能够以稍慢的操作进行精确的剪切,但仍然比重新编码整个视频快得多。如果我们可以用一个命令进行多次剪切,速度会更快,因此我们只需遍历帧一次。我希望有人可以应用这一点,并告诉我们如何应用,或者提及一些 ffmpeg 团队,或者无论如何将其交给他们。

相关内容