使用 ffmpeg 裁切视频尺寸

之前我们介绍过用 shotcut 来裁切视频尺寸,这个方法还算简便,不过也有一些缺点, 比如对裁切范围的控制不是特别精确,这次我们再介绍一种更为极客的方法: 使用 ffmpeg 进行裁切

开始之前

关于裁切视频尺寸,我有两篇文章,推荐给不同需求的读者:

  1. 使用 shotcut 裁切,适合习惯图形界面操作的用户
  2. 使用 ffmpeg 裁切(本文),适合习惯命令行操作的用户

问题

假设我们有这么一个视频:

KA_SP02.HHP-r-4x.gif

这个视频只有左上一块是有图像的,接下来我们把它裁切一下,只保留有图像的部分

环境

ffmpeg

这个功能对版本的要求应该不会很高,我目前使用的版本是 5.1.2,供大家参考:

Untitled

windows

这个就更不是问题了,我这边是使用 windows 11

提取参考帧

我们可能需要从视频中提取一帧图像来作为参考,来确定裁切框大小, 这个一般视频播放器都会有,可以凭自己习惯操作,不过既然本文是关于 ffmpeg, 那么这里也给一个 ffmpeg 的方式:

ffmpeg -i input.mp4 -vf select=between(n\,120\,120) frame.jpg

其中 input.mp4 是输入文件,select 那段是过滤器, 表示介于 120 到 120 帧(前后都包含)的部分,”,” 是逗号的转义,不要偷懒不写 “\”。

最后解释一下这个 120,这个 120 表示视频的第 120 帧,起始帧是 0,所以较真的话, 这是第 121 帧。如果视频 fps 是 60,那么这个就是第三秒的第一帧。换句话说, 我们要根据当前帧的时间和 fps,算一下我们要提取的位置。

上面这个方法只会输出一个 jpg,所以 ffmpeg 会有一个警告, 希望我们修改输出文件命名为 test%03d.jpg 的格式, 这样我们会得到名为 test001.jpg 的文件,这个对于多数情况可能更有帮助, 我们可能只知道参考帧的大概时间,这样我们可以把这个时间段的所有帧数都提取出来:

ffmpeg -ss 00:16:00 -i "path/to/input.mp4" -frames:v 30 "path/to/output-%03d.jpg"

-ss 指定了提取的起始时间,-frames:v 指定了我们要提取的帧数, 这样我们就可以逐帧找到想要的图像,似乎这样也比较简单。

确定裁切框大小

有了参考帧,我们就可以确定裁切框的大小了,和提取参考帧一样, 一般的绘图软件都可以胜任,自己习惯就好,这里我们使用 gimp:

Untitled

所以我们需要裁切的部分是 (0, 0) 到 (2048, 1120) 的矩形部分。 不过我们要换个表述方式,后面会用到,这是一个左上角为 (0,0),宽 2048, 高 1120 的矩形。

使用 ffmpeg 裁切

准备工作做了这么多,终于可以开始裁切了,不用担心,很简单:

ffmpeg -hwaccel auto -i "path/to/input.mp4" -filter:v "crop=2048:1120:0:0" "path/to/output.mp4"

重头戏的部分我们详细解释一下,我们可以看到四个参数:

-hwaccel auto #自动选择硬件加速
-i "path/to/input.mp4" #输入文件路径
-filter:v "crop=2048:1120:0:0" #截取左上角为 (0,0),宽 2048,高 1120 的矩形
"path/to/output.mp4" #输出文件路径

最重要的是第三个参数,这样输出的文件就是截取后的文件了。

KA_SP02.HHP-r-4x-crop.gif

总结

这次除了确定截取尺寸时,我们使用到了 gimp, 其他时候我们只要命令行和 ffmpeg 就完成了。 这时不免和之前用的 shotcut 互相比较一下,我觉得 shotcut 较为直观,拖动几下, 就可以完成裁切,而命令行较为精确, 我们可以很明确地告诉 ffmpeg 我们要视频的哪部分。 其实这也是图形工具和命令行工具的主要差异,它们都可以完成我们的任务, 至于最终选用哪个,选择权在用户手中。