如何使用ffmpeg

时间:2016-12-05 02:46:49

标签: linux windows video ffmpeg duplicates

首先,我在前言中说我对视频处理没有任何帮助, 虽然我多年来一直在摆弄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来提取视频的“切片”以便以后重新组合?

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

  • 用户为重复项指定“阈值持续时间”    (可能仅运行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 个答案:

答案 0 :(得分:1)

我已经就这个问题做了一些工作......并且发现以下工作非常好......

输入视频似乎必须具有"恒定的帧速率"为了使事情正常工作,所以第一个命令是: -

ffmpeg -i test.mp4 ^
       -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" ^
       -vsync cfr test01.mp4

然后我需要查看分数'对于每一帧。这样的清单由以下产生: -

ffmpeg -i test01.mp4 ^
       -vf select="'gte(scene,0)',metadata=print" -f null - 

我会查看所有这些分数......并对它们进行平均(均值) - 有点狡猾,但似乎工作正常。在此示例中,该平均分数为“0.021187”。

然后我必须选择一个“持久性”'价值 - 多久让“重复”'帧运行。如果你强迫它只保留一帧,那么整个视频的运行速度都会太快......所以,我一直用0.2秒作为起点。

所以下一个命令变为: -

ffmpeg -i test01.mp4 ^
       -vf "select='if(gt(scene,0.021187),st(1,t),lte(t-ld(1),0.20))', 
                    setpts=N/FRAME_RATE/TB" output.mp4

之后,结果' output.mp4'视频看起来效果很好。它只是在摆弄“坚持不懈”。在播放流畅的视频和突然改变的场景之间可能需要做出的折衷。

我已经将一些有效的Perl代码放在一起,如果有人对它感兴趣,我会找出如何发布的内容...最终(!)

编辑:这个'抽取'的另一个好处是文件的持续时间较短(显然)并且它们的尺寸较小。例如,运行时间为00:07:14并且大小为22MB的示例视频分别为00:05:35和11MB。