FFmpeg 可以从视频中捕获图像,这些图像可以用作缩略图来表示视频。在FFmpeg Wiki中捕获了最常见的方法。
但是,我不想在某些时间间隔内选择随机帧。我发现了一些在 FFmpeg 上使用过滤器来捕捉场景变化的选项:
过滤器thumbnail试图找到视频中最具代表性的帧:
ffmpeg -i input.mp4 -vf "thumbnail,scale=640:360" -frames:v 1 thumb.png
Run Code Online (Sandbox Code Playgroud)
并且以下命令仅选择与之前相比具有超过 40% 变化的帧(因此可能是场景变化)并生成 5 个 PNG 的序列。
ffmpeg -i input.mp4 -vf "select=gt(scene\,0.4),scale=640:360" -frames:v 5 thumb%03d.png
Run Code Online (Sandbox Code Playgroud)
以上命令的信息归功于Fabio Sonnati。第二个看起来更好,因为我可以得到 n 个图像并选择最好的。我试过了,它生成了 5 次相同的图像。
更多的调查使我:
ffmpeg -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.png
Run Code Online (Sandbox Code Playgroud)
-vsync vfr确保您获得不同的图像。这仍然总是选择视频的第一帧,在大多数情况下,第一帧是署名/标志并且没有意义,所以我添加了一个-ss3 来丢弃视频的前 3 秒。
我的最终命令如下所示:
ffmpeg -ss 3 -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.jpg
Run Code Online (Sandbox Code Playgroud)
这是我能做的最好的事情。我注意到,由于我只挑选了5个视频,所有视频都来自视频的开头,可能会错过视频后面出现的重要场景。
我想为任何其他更好的选择挑选你的大脑。
我的最终目标是从 30 分钟或 1 小时长的视频中获取有意义的快照。“有意义”有点野心,所以我简化了我的要求。
图像应该清晰 - 不模糊。
最初,我认为这意味着获得“关键帧”。由于关键帧很多,我决定选择最接近视频第三分钟的关键帧,这对我来说通常“有意义”。我遵循了以下建议:FFmpeg 命令找到最接近第 3 分钟的关键帧
但问题是这些关键帧通常(并不总是)模糊。一个例子是:

然后我尝试使用 FFmpeg 为视频制作有意义的缩略图,这确实有助于获得更有意义的快照,但我仍然经常(并非总是)得到像上面这样的模糊帧。
您会注意到这种图像本质上是 2 个不同场景的重叠。然而,有时我会得到对我有用的图像 - 像这样:

上图意义不大,但很清晰。
理想情况下,我希望 FFmpeg 不返回模糊帧。或者,我想使用脚本来检测模糊帧并从 5 帧中选择最不模糊的帧。有谁知道如何做到这一点?