伪代码

伪代码

FFmpeg 可以从视频中捕获图像,这些图像可以用作缩略图来表示视频。最常见的方法是在FFmpeg 维基

但是,我不想在某些间隔内随机挑选帧。我在 FFmpeg 上找到了一些使用过滤器来捕捉场景变化的选项:

该过滤器thumbnail尝试找到视频中最具代表性的帧:

ffmpeg -i input.mp4 -vf  "thumbnail,scale=640:360" -frames:v 1 thumb.png

以下命令仅选择与之前相比变化超过 40% 的帧(因此可能是场景变化)并生成 5 个 PNG 序列。

ffmpeg -i input.mp4 -vf  "select=gt(scene\,0.4),scale=640:360" -frames:v 5 thumb%03d.png

以上命令的信息来源法比奥·索纳蒂。第二个方法似乎更好,因为我可以获取 n 张图片并挑选出最好的一张。我试了一下,它生成了 5 次相同的图像。

进一步的调查让我发现:

ffmpeg -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr  out%02d.png

-vsync vfr确保您获得不同的图像。这仍然总是选择视频的第一帧,在大多数情况下,第一帧是片尾字幕/徽标,没有意义,所以我添加了-ss3 以丢弃视频的前 3 秒。

我的最终命令如下:

ffmpeg -ss 3 -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.jpg

这是我能做的最好的了。我注意到,由于我只挑选了 5 个视频,它们大多都是从视频的开头开始的,可能会错过视频后面发生的重要场景

我希望向您请教是否有其他更好的选择。

答案1

理想情况下,如何在 5 个时间跨度内寻找第一个 >40% 变化的帧,其中时间跨度是视频的第 1、2、3、4 和 5 个 20%。

您也可以将其分成 6 个时间跨度并忽略第一个时间跨度以避免损失信用。

实际上,这意味着在应用场景变化检查和参数来丢弃视频的第一部分时,将 fps 设置为一个较低的数字。

...就像是:

ffmpeg -ss 3 -i input.mp4 -vf "select=gt(scene\,0.4)" -frames:v 5 -vsync vfr -vf fps=fps=1/600 out%02d.jpg

答案2

定义有意义的很难,但如果你想有效地制作跨越整个视频文件的 N 个缩略图,这就是我在制作时使用用户上传的内容生成缩略图的方法。

伪代码

for X in 1..N
  T = integer( (X - 0.5) * D / N )  
  run `ffmpeg -ss <T> -i <movie>
              -vf select="eq(pict_type\,I)" -vframes 1 image<X>.jpg`

在哪里:

  • D -ffmpeg -i <movie>单独读取视频时长,或者ffprobe顺便说一下,具有很好的 JSON 输出编写器
  • N - 您想要的缩略图总数
  • X - 缩略图编号,从 1 到 N
  • T - 缩略图的时间点

简单来说,上面记录了电影每个分区的中心关键帧。例如,如果电影时长 300 秒,而您想要 3 个缩略图,那么在 50 秒、150 秒和 250 秒后需要一个关键帧。对于 5 个缩略图,则分别为 30 秒、90 秒、150 秒、210 秒、270 秒。您可以根据电影时长 D 调整 N,例如,5 分钟的电影将有 3 个缩略图,但超过 1 小时的电影将有 20 个缩略图。

表现

对于~1GB H.264,每次调用上述ffmpeg命令只需几分之一秒(!)。这是因为它会立即跳转到<time>位置(记住-ss之前-i)并获取第一个关键帧,这实际上是完整的 JPEG。渲染电影以匹配精确的时间位置不会浪费时间。

后期处理

您可以将上述方法与scale或任何其他调整大小方法混合使用。您还可以删除纯色框或尝试将其与其他滤镜(如)混合使用thumbnail

答案3

尝试这个

 ffmpeg -i input.mp4 -vf fps= no_of_thumbs_req/total_video_time out%d.png

使用此命令,我可以生成代表整个视频的所需数量的缩略图。

答案4

我曾经做过类似的事情,但我导出了视频的所有帧(以 1 fps 为单位),并将它们与我找到的用于计算图像之间差异的 perl 实用程序进行比较。我将每一帧与之前的缩略图进行比较,如果它与所有缩略图都不同,我会将其添加到缩略图集合中。这样做的好处是,如果您的视频从场景 A 移动到 B,然后又返回到 A,ffmpeg 将导出 A 的 2 帧。

相关内容