【问题标题】:FFMPEG: how to take 3000 snapshots faster?FFMPEG:如何更快地拍摄 3000 张快照?
【发布时间】:2021-03-13 14:50:19
【问题描述】:

我有一个长度为 200 分钟的视频。
并且还获得了将要拍摄的每个快照的时间戳。
我尝试使用 ffmpeg 通过以下命令拍摄快照。
但是,它非常慢,每个快照大约需要 10 秒。
有什么办法可以加快速度吗?谢谢。

操作系统:win10; PC:英特尔 NUC8i5

ffmpeg -i 1.mp4 -ss 00:00:04 -vframes 1 000004.jpg
ffmpeg -i 1.mp4 -ss 00:00:08 -vframes 1 000008.jpg
ffmpeg -i 1.mp4 -ss 00:00:12 -vframes 1 000012.jpg
ffmpeg -i 1.mp4 -ss 00:00:16 -vframes 1 000016.jpg
ffmpeg -i 1.mp4 -ss 00:00:17 -vframes 1 000017.jpg
ffmpeg -i 1.mp4 -ss 00:00:20 -vframes 1 000020.jpg
ffmpeg -i 1.mp4 -ss 00:00:24 -vframes 1 000024.jpg
ffmpeg -i 1.mp4 -ss 00:00:26 -vframes 1 000026.jpg
ffmpeg -i 1.mp4 -ss 00:00:28 -vframes 1 000028.jpg
ffmpeg -i 1.mp4 -ss 00:00:32 -vframes 1 000032.jpg
ffmpeg -i 1.mp4 -ss 00:00:36 -vframes 1 000036.jpg
ffmpeg -i 1.mp4 -ss 00:00:38 -vframes 1 000038.jpg
ffmpeg -i 1.mp4 -ss 00:00:43 -vframes 1 000043.jpg

【问题讨论】:

  • 时间戳的间隔不规则。我想出了一种解决方案。谢谢。

标签: ffmpeg


【解决方案1】:

如果时间戳的间隔不规则(从您的示例看来就是这种情况),您可以使用选择过滤器:

ffmpeg -i 1.mp4 -filter:v \
    "select='lt(prev_pts*TB\,4)*gte(pts*TB\,4) \
            +lt(prev_pts*TB\,12)*gte(pts*TB\,12) \
            +lt(prev_pts*TB\,17)*gte(pts*TB\,17) \
            +lt(prev_pts*TB\,28)*gte(pts*TB\,28) \
            +lt(prev_pts*TB\,43)*gte(pts*TB\,43)'" \
    -vsync drop out/%03d.jpg

这将抓取指定时间戳的帧,如果在该精确时间戳处没有帧,它将抓取下一帧。

【讨论】:

    【解决方案2】:

    尝试在200 parts 中分割视频(一段 200 分钟),然后一一加载。将整个视频加载到内存是昂贵的。试试小视频看看效果如何

    【讨论】:

      【解决方案3】:

      我使用 VLC 来解决这个问题。 基本思路是利用VLC的http接口来控制vlc跳转到特定的时间戳并进行快照。 内存消耗极低,速度更快。
      拍摄 3800 张快照大约需要 16 分钟。

      以下代码在自动热键中。

      #Include, VLC_HTTP2.ahk
       
      Loop, read, %A_ScriptDir%\TimeStamps.txt
      {
          VLC_JumpTime:=A_LoopReadLine
          VLCHTTP2_Jumpto(VLC_JumpTime)
          Sleep, 100
          VLCHTTP2_Snapshot()
      }
      return
      
      VLCHTTP2_Jumpto(VLC_JumpToTime)
      {
          VLC_CurrentTime:=VLCHTTP2_TimeSeconds()
          SeekBackwardTime:=VLC_CurrentTime-VLC_JumpToTime
          if SeekBackwardTime >0    
              VLCHTTP2_JumpBackward(SeekBackwardTime) 
          else if SeekBackwardTime <0
          {
              SeekForwardTime:=-SeekBackwardTime
              VLCHTTP2_JumpForward(SeekForwardTime)
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-13
        • 1970-01-01
        • 2013-02-14
        • 2014-12-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多