如何在不使用 ffmpeg 保持视频持续时间的情况下重新采样 FPS?

Posted

技术标签:

【中文标题】如何在不使用 ffmpeg 保持视频持续时间的情况下重新采样 FPS?【英文标题】:How to resample FPS without keeping duration of the video using ffmpeg? 【发布时间】:2014-08-31 12:26:27 【问题描述】:

我有一个 50fps 的 avi 视频,但相机以 25fps 的速度拍摄。因此,每隔一帧都是空的。事实上,有时相机不提供​​帧,甚至还有更多的空帧。

我想使用 ffmpeg 删除所有空帧并将 fps 设置为 25。到目前为止我发现的最好的是这个命令:

-i video.avi -c mpeg4 -qscale:v 8 -vf fps=25 -vsync drop output.avi

这在理想情况下是有效的,即每隔一帧是空的。这些帧将被丢弃,fps 设置为 25,并且视频持续时间将保持不变,没有重复的帧。但是如果有更多的空帧,ffmpeg 会制作重复帧以保持持续时间。我需要以某种方式处理视频,任何空帧或重复帧都是不可接受的。另一方面,我不介意视频是否会更短。

【问题讨论】:

probably related 感谢您的提示。不幸的是,这些空框架没有特定的位置,因此我不知道如何选择它们。顺便说一句,我要求使用 ffmpeg 的解决方案,但实际上我一般不知道如何实现目标,即使使用 VirtualDub 或 Avidemux ......我想我现在会欢迎任何解决方案。 【参考方案1】:

有一种简单但占用空间的方式来做你想做的事。但是,它不是 ffmpeg 特定的 - 但您可以使用 ffmpeg 来执行此操作。方法如下。

只需导出帧,使用您喜欢的图像浏览器删除空帧,然后重新导入视频文件。

要将整个视频导出为单独的图像文件,请使用:

ffmpeg -i yourvideofile.avi -f image2 "./to-remove-empty/%5d.png"

要将修剪后的文件重新导入您可以使用的文件中:

ffmpeg -r 25 -i "./empty-removed/*.png" -c:v mpeg4 -qscale:v 8 output.avi

(*.png 中的星号应该会导致它读取帧,而无需事先重新编号整个集合)

如果您之后需要在 NLE 中编辑文件,我建议您单独加载帧(即从文件中),或者将生成的视频编码到像 ProRes HQ (422) 这样的中间编解码器中。为此(即使在 Windows 中),请将编解码器指定为:

        -c:v prores_ks -profile:v 2 -pix_fmt yuv422p10le output.mov

或者,如果您以后需要按原样使用它,我建议根据您的示例使用 x264(h264 的开放版本)而不是直接 mpeg4 - 为此,请使用以下格式规范:

        -c:v libx264 -crf 23 -pix_fmt yuv420p output.mp4

大多数现代视频播放设备(和计算机)都能识别这种文件格式。

(匹配要使用的声音格式/编解码器:pcm_s16le 用于 ProRes (aif) 和 aac 用于 libx264 (m4a))

我还想指出,空(即全黑)帧也可以通过编程方式从文件夹中删除:使用脚本语言(如 php 的 GD2 库)或图像包(如 ImageMagick)。运行命令判断框架是否全黑,如果是则删除文件。

【讨论】:

以上是关于如何在不使用 ffmpeg 保持视频持续时间的情况下重新采样 FPS?的主要内容,如果未能解决你的问题,请参考以下文章

FFMPEG:如何在不拉伸的情况下移动视频?

如何在不创建新文件的情况下使用 ffmpeg/avconv 更改元数据?

如何使用 ffmpeg 从视频中删除特定持续时间

ffmpeg:在不创建新文件的情况下向 mp4 添加字幕

python [Python + FFMPEG]在不影响音高和/或连接多个剪辑的情况下改变视频速度

在 ffmpeg 中从单个图像创建特定持续时间的视频