Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Video 从视频中获取帧内帧_Video_Ffmpeg - Fatal编程技术网

Video 从视频中获取帧内帧

Video 从视频中获取帧内帧,video,ffmpeg,Video,Ffmpeg,首先,让我先说一句,我必须处理大量的视频,每一个视频哪怕减少1秒钟都是非常重要的 我试图提取视频中所有帧内帧的位置 FFProbe可以工作,但速度惊人地慢 FFMpeg的工作速度要快得多,但仍然相当慢 所以,我的问题是,是否有一个lib,我可以在其中执行类似以下伪代码的操作: var frame = first_frame; do { if (frame.type == intra_frame) log(frame.time); frame = frame.next; } whi

首先,让我先说一句,我必须处理大量的视频,每一个视频哪怕减少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还有什么更快的吗?

一般来说,没有,这样的库不存在。但是,如果你根据你处理的特定视频做出假设,你可以近似得出结果。FFmpeg不能为您这样做,因为它是一个通用框架

让我们从简单开始:

  • 你的视频是什么容器
  • 他们使用什么编解码器
我为什么要问这个?一些容器(如AVI)在索引中标记帧类型,因此您不需要对压缩帧执行任何操作即可获得所需的信息。对于其他容器(如Matroska/WebM),信息严格来说不是容器的一部分,但存在衍生信息。例如,对于不仅仅是帧内的压缩流(例如H.264/VP9),seekHead实际上是一个关键帧位置列表,其范围类似于AVI文件中的索引。但是规范并不能保证这一点,它只是碰巧在实践中是正确的


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

我们有mp4容器,但不幸的是,由于视频是用户提交的,所以视频之间存在很多差异,这就是为什么我不想直接解析格式的原因。让我编辑这个问题来解释最终目标,也许会弹出其他解决方案。mp4也有关键帧标记,所以应该可以正常工作。请参阅libavformat/mov.c中的“sc->keyframes[]”,以及如何使用它在索引中设置AVINDEX_关键帧。索引是在read_header()期间生成的,因此可以从ffmpeg API访问该索引,而无需编写自己的mp4解析器,并且仍然是编解码器无关的。这非常有趣。我现在正在调查,你可以用启发式的方法来做。读取
stss
框中的条目数。探测媒体的持续时间。计算粗略的KF距离值(以秒为单位)。使用ffmpeg和
-跳过帧nokey
,然后选择filter来提取相距如此之远的帧。添加
-vframes 48
以避免额外的图像。