从视频中获取帧内帧

时间:2017-06-01 14:09:38

标签: video ffmpeg

首先,让我先说明我必须处理大量视频,每个视频甚至1秒钟的剃须非常重要。

我试图提取视频中所有帧内帧的位置。

FFProbe有效,但速度非常慢。

FFMpeg工作得更快,但它仍然很慢。

所以,我的问题是,如果有一个lib,我可以做一些像这样的伪代码:

var frame = first_frame;
do
{
    if (frame.type == intra_frame) log(frame.time);
    frame = frame.next;
} while (frame != null);

并且非常快速地浏览视频,而不是查看帧内的任何内容,而只是查找帧的类型并转到下一帧。

最终目标是尽可能快地生成用于预览的幻灯片。我需要生成48个缩略图,大致均匀地分布在电影中并覆盖整个电影跨度(每端不包括5秒)。我希望通过仅提取帧内帧来加快进程。由于我需要固定数量的缩略图,我只能通过了解帧内的总量来实现这一点。

此方案仅在找到所有帧内索引并提取48个帧内帧的时间少于在一次通过中以规则间隔获取帧数48次时才有效。

<小时/> 编辑:这是我到目前为止找到的解决方案;在这个例子中,我每分钟取一帧

ffmpeg -hide_banner -skip_frame nokey -i _a.mp4 -vf "select='eq(pict_type\,PICT_TYPE_I)*(lt(abs(t\-30)\,2)+lt(abs(t\-90)\,2)+lt(abs(t\-150)\,2)+lt(abs(t\-180)\,2)+lt(abs(t\-240)\,2)+lt(abs(t\-300)\,2)+lt(abs(t\-360)\,2)+lt(abs(t\-420)\,2))',showinfo,scale=640:480,tile=6x8" -vsync 0 frames.jpg

我发现如果我直接指定帧,我就不会有速度差异。

没有通过API,FFMPEG有什么更快的东西吗?

1 个答案:

答案 0 :(得分:0)

一般来说,不,这样的lib不存在。但是,如果您根据处理的特定视频做出假设,则可以估算结果。 FFmpeg不能为你做到这一点,因为它是一个通用的框架。

让我们开始简单:

  • 您的视频是什么容器?
  • 他们使用什么编解码器?

为什么我问这个?某些容器(例如AVI)在索引中标记帧类型,因此您无需对压缩帧执行任何操作即可获取您要求的信息。对于其他容器(例如Matroska / WebM),信息不是容器的严格组成部分,但存在衍生信息。例如,对于非内部的压缩流(例如H.264 / VP9),seekHead实际上是一个关键帧位置列表,其范围与AVI文件中的索引类似。但这不是规范所保证的,它恰好在实践中是正确的。

好的,所以我们假设容器不足以满足您的需要。您需要自己解析视频数据。对于H.264,您可以解析每帧中第一个切片的切片头以获得切片类型。规范保证所有后续切片(对于相同的字段)具有相同的切片类型。这可能是I,B或P.如果是我,那就是帧内帧。对于VP9,标题包含名为keyframe和intraonly的字段,可以执行您要查找的内容。其他压缩标准(MPEG-1/2/4,HEVC,VP8等)是相同的,但您需要自己实现。它并不复杂,但是没有通用的框架可以帮到你,因为它是一个非常明显的用例。