+-
linux – 如何使用ffmpeg从视频中删除重复帧
首先,我通过说我对视频操作没有任何专长来说明这一点,
虽然我多年来一直在摆弄ffmpeg(以相当有限的方式).因此,我并不会因为所有语言经常使用的人而闪过……以及它如何影响我在操作中想要做的事情……但无论如何我都会对此有所了解……

我在这里查了几个链接,例如:
ffmpeg – remove sequentially duplicate frames

…但内容并没有真正帮助我.

我使用ffmpeg和其他类似应用程序在Windows和Linux下创建了数百个视频剪辑.然而,他们在视频中的时间存在一些问题,其中显示器是“静止的”.

例如,假设我们有一些网站将实时视频流式传输到网络浏览器中的Flash视频播放器/插件中.在这种情况下,我们讨论的是交通摄像机视频流.

有一个运行ffmpeg的实例,它将(Windows)桌面的一个区域捕获到一个视频文件中,即: –

ffmpeg -hide_banner -y -f dshow ^
      -i video="screen-capture-recorder" ^
      -vf "setpts=1.00*PTS,crop=448:336:620:360" ^
      -an -r 25 -vcodec libx264 -crf 0 -qp 0 ^
      -preset ultrafast SAMPLE.flv

假设正在捕获的实际“显示”如下所示: –

123456789 XXXXX 1234567 XXXXXXXXXXX 123456789 XXXXXXX
^---a---^ ^-P-^ ^--b--^ ^----Q----^ ^---c---^ ^--R--^ 

…每个字符位置代表一个(序列)帧.由于互联网连接不良,可以长时间显示“单帧”(“X”字符是前一帧的(几乎)精确副本).所以这意味着我们拥有拍摄视频的片段,其中图像根本不会改变(无论如何).

我们如何处理重复的帧?…如果’重复’与ffmpeg不同但看起来或多或少与观众相同,我们的方法如何改变?

如果我们只是移除重复的帧,视频的“节奏”就会丢失,过去需要花费5秒才能显示,现在只需要几分之一秒,会产生非常不稳定,不自然的动作,尽管有视频中没有重复的图像.使用带有’mp_decimate’选项的ffmpeg,这似乎是可以实现的,即: –

     ffmpeg -i SAMPLE.flv ^                      ... (i)
        -r 25 ^
        -vf mpdecimate,setpts=N/FRAME_RATE/TB DEC_SAMPLE.mp4

我引用的那个引用使用一个命令来显示哪个帧’mp_decimate’在它认为它们是’相同’时会删除,即: –

     ffmpeg -i SAMPLE.flv ^                      ... (ii)
        -vf mpdecimate ^
        -loglevel debug -f null -

…但是知道(复杂的格式化)信息,我们如何重新组织视频而不执行多次运行ffmpeg来提取视频的“切片”以便以后重新组合?

在那种情况下,我猜我们必须运行类似的东西: –

> user指定重复项的“阈值持续时间”
   (也许只运行1秒)
>确定&保存主要视频信息(fps等 – 假设
   恒帧率)
>映射(重复项开始的帧/时间) – >否.的
   帧/重复的持续时间
>如果重复的持续时间小于用户阈值,
   不要将此期间视为“一系列重复帧”
   然后继续前进
>提取’非重复’视频片段(a,b& c)
   上图)
>使用原始视频的规格创建“新视频”(空)
>对于每个视频片段
   提取段的最后一帧
   创建一个包含帧重复帧的短视频剪辑
     刚提取(持续时间=用户规格= 1秒)
   将(当前视频片段短片)附加到“新视频”
 并重复

…但在我的情况下,很多拍摄的视频可能长达30分钟并且有数百个10秒长的暂停,因此使用此方法“重建”视频需要很长时间.

这就是为什么我希望有一些“可靠”和“更智能”的使用方式
ffmepg(带/不带’mp_decimate’过滤器)仅在几次传递中执行’decimate’功能……也许有一种方法甚至可以指定所需的段(例如,在文本文件中)并且当ffmpeg运行时它会
在指定的时间/帧号停止/重启它的转码?

除此之外,还有另一个应用程序(用于Windows或Linux)可以执行我正在寻找的内容,而无需手动设置启动/停止点,
手动提取/组合视频片段……?

我一直试图用Win7-SP1下的ffmpeg N-79824-gcaee88d和Puppy Linux Slacko 5.6.4下的(我现在不记得的另一个版本)来做这一切.

感谢一堆线索.

最佳答案
我假设你想要做的是保持帧的运动和最多1秒的重复帧,但丢弃其余的帧.

ffmpeg -i in.mp4 -vf
"select='if(gt(scene,0.01),st(1,t),lte(t-ld(1),1))',setpts=N/FRAME_RATE/TB"
trimmed.mp4

select过滤器表达式的作用是使用if-then-else运算符:

gt(场景,0.01)检查当前帧是否检测到相对于前一帧的运动.与传感器/压缩噪声或帧中的视觉噪声相比,通过查看哪个值准确地捕获实际活动,必须基于手动观察来校准该值.有关如何获取所有场景更改值的列表,请参阅here.

如果帧被评估为具有运动,则then子句计算st(1,t).函数st(val,expr)将expr的值存储在编号为val的变量中,并且还将该表达式值作为结果返回.因此,保留帧的时间戳将继续在该变量中更新,直到遇到静态帧.

else子句检查当前帧时间戳与存储值的时间戳之间的差异.如果差异小于1秒,则保留帧,否则丢弃.

setpts清理所有选定帧的时间戳.

编辑:我用我合成的视频输入测试了我的命令并且它有效.

点击查看更多相关文章

转载注明原文:linux – 如何使用ffmpeg从视频中删除重复帧 - 乐贴网