使用 FFmpeg 删除每个偶数或奇数帧?

使用 FFmpeg 删除每个偶数或奇数帧?

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

例如:

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

有什么想法如何仅使用 FFmpeg 来实现这一点?

答案1

为了准确工作,首先将视频转换为 RAW YUV 比特流(如果尚未转换):

ffmpeg -i input.mp4 -an -vcodec rawvideo -pix_fmt yuv420p rawbitstream.yuv

下一步: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

为了不产生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

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

ffmpeg -f rawvideo -s:v 1280x720 -pix_fmt yuv420p input.yuv …

答案2

如果你的 ffmpeg 是使用 AviSynth 标志构建的,那么我相信您可以传递一个.avs文件。

您可以通过运行ffmpeg并查找来--enable-avisynth检查配置数据。 --enable-avisynth

如果它在那里,您可以像这样使用它:ffmpeg -i blahEven.avs blahEven.yuv

简单来说就是blahEven.avs

ffvideosource("blah.yuv").SelectEven()

对于奇数帧,使用SelectOdd()

有关更多高级用法,请参阅选择每一个文档。

相关内容