ffmpeg - 如何使用 ffmpeg 从 H264 视频中提取最接近给定帧号的关键帧

标签 ffmpeg h.264 keyframe libavcodec ffprobe

如果您知道帧号(如下所示),我知道如何使用 ffmpeg 从视频中提取一组帧作为 jpg 文件

Extracting Frames: [40, 59, 73, 110]
/usr/bin/ffmpeg -y -hide_banner -nostats -loglevel error -i /home/pi/movie.mp4 -vf select='eq(n\,40)+eq(n\,59)+eq(n\,73)+eq(n\,110)',scale=640:-1 -vsync 0 /tmp/%04d.jpg

这会将帧 [40, 59, 73, 110] 提取为文件/tmp/0000.jpg、/tmp/0001.jpg 等。

我还知道如何提取给定时间间隔的所有关键帧:

ffmpeg -ss <start_time> -i video.mp4 -t <duration> -q:v 2 -vf select="eq(pict_type\,PICT_TYPE_I)" -vsync 0 frame%03d.jpg

这将获取从 start_timestart_time+duration 的所有 I 帧。

但是我想做的是给出一个帧号列表,并让 ffmpeg 提取与每个帧号最接近的关键帧。有没有办法用 ffmpeg 来做到这一点,或者我必须在 libavcodec 上编写自己的程序才能做到这一点?

最佳答案

如果速度是主要考虑因素,您可以选择在分离器阶段跳过非关键帧。

ffmpeg -discard nokey -i video.mp4 -q:v 2 -vf select="eq(pict_type\,PICT_TYPE_I)" -vsync 0 frame%03d.jpg

这应该可以提供 20-100 倍的加速。

如果您需要使用丢弃选项提取特定半径内的所有关键帧,请使用

ffmpeg -discard nokey -i video.mp4 -q:v 2 -vf select="eq(pict_type\,PICT_TYPE_I)*(lt(abs(t-14),3)+lt(abs(t-107),3)+lt(abs(t-2113),3))" -vsync 0 frame%03d.jpg

这里,将选择半径为 3 秒时间 t = 14s、107s 和 2113s 的关键帧。

您不能使用 discard 引用 n,因为编号会错误 --> ffmpeg 仅将关键帧发送到过滤器和 n > 表示过滤帧的计数。因此,所有变量和值都以秒为单位。如果您的视频是恒定帧速率,则 t 就是 n/fps

关于ffmpeg - 如何使用 ffmpeg 从 H264 视频中提取最接近给定帧号的关键帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41175085/

相关文章:

c++ - avcodec_encode_video2 在 MinGW32 上崩溃(但在 MinGW64 上没有)

FFMPEG 无法对高速变化的视频进行编码

ffmpeg 为 MJPEG 编码生成更高质量的图像

css - 动画完成后动画文本被隐藏

css - 悬停时反转关键帧动画

video - 如何在视频上从右上到右下垂直滑动水印文字

c++ - 使用 FFMPEG 将每个输入图像转换为 H264 在 MevisLab 中运行的 Visual Studio 中编译时出错

iphone - 我们如何从 iPhone Camera 获取 H.264 编码的视频流?

ffmpeg - VLC播放器如何计算fmp4文件时间线的总长度?

CSS 关键帧手机振动