使用 FFmpeg 丢弃每个偶数或奇数帧?

Mar*_*ark 17 video ffmpeg framerate

是否有一种准确的方法来获取原始视频并从中提取仅包含奇数帧或偶数帧(由选择)的新视频?

例如:

我有 400 帧(0-399)的“blah.yuv”。我想创建包含帧 1-399(1,3,5,7...399)的“blahOdd.yuv”和包含帧 0-398(0,2,4,6...398)的“blahEven” )。

任何想法如何只使用 FFmpeg 来做到这一点?

slh*_*hck 12

为了准确工作,首先通过以下方式将视频转换为 RAW YUV 比特流(如果还没有):

ffmpeg -i input.mp4 -an -vcodec rawvideo -pix_fmt yuv420p rawbitstream.yuv
Run Code Online (Sandbox Code Playgroud)

下一步:select过滤器采用表达式,其中n是帧号。

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="mod(n-1\,2)" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="not(mod(n-1\,2))" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an even.yuv
Run Code Online (Sandbox Code Playgroud)

为了ffmpeg不重复帧,您必须强制输入帧率的一半 - 因此您将“2”设置为输入,将“1”设置为输出。不要忘记用剪辑的实际尺寸替换 WxH,因为原始比特流没有携带此信息的标头。

除了上述之外,另一种可能性是添加setpts过滤器来为输出设置新的时间戳。但要小心,因为它不准确地丢帧。这里,25 是你想要的实际输出帧率:

ffmpeg -i input.mp4 -filter:v select="mod(n-1\,2)",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -i input.mp4 -filter:v select="not(mod(n-1\,2))",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an even.yuv
Run Code Online (Sandbox Code Playgroud)

您当然可以选择另一种像素格式(任何一种ffmpeg -pix_fmts)。确保在读取文件时您知道像素大小和像素格式:

ffmpeg -f rawvideo -s:v 1280x720 -pix_fmt yuv420p input.yuv …
Run Code Online (Sandbox Code Playgroud)