FFMPEG:如何更快地拍摄 3000 张快照?

问题描述 投票:0回答:4

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

操作系统:win10;电脑:英特尔 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
4个回答
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

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


0
投票

尝试将视频(200 分钟一个)分成200 个部分,然后逐个加载。将整个视频加载到 RAM 的成本很高。尝试用小视频看看它会如何改进


0
投票

我使用VLC来解决这个问题。 基本思想是利用VLC的http接口来控制vlc跳转到特定的时间戳并拍摄快照。 RAM消耗非常低,速度也快很多
拍摄 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)
    }
}

0
投票

我没有代表。对 hb_ 关于选择过滤器的答案进行评论。这正是我一直在寻找的。谢谢你! 我正在构建一个基于 Motionplus、Raspberry Pi 3B+ 的安全摄像头系统,当然它是从 SD 卡运行的。 前端根据视频长度计算出不规则的寻道时间,显示多个缩略图。 我之前已经循环过,类似于这个问题。处理需要少量缩略图的较长捕获需要花费很长时间。 我按照选择过滤器示例进行操作,性能得到了巨大的提高。一分钟的视频需要 70 秒才能处理。使用选择过滤器将其缩短为 12 秒。 我还将快照缩小到缩略图大小。为此,您可以将比例过滤器与选择链接起来。我正在使用 Python3,这是我的命令行,将被输入到 subprocess.Popen()。我之前按照 hb_ 的答案在名为 select 的变量中构建了“select=...”过滤器。

cmd = [ 'ffmpeg',
        '-loglevel', 'error',
        '-i', videoFilePath,
        '-f', 'image2',
        '-filter:v', f'scale=300:-1, {select}',
        '-vsync', 'drop',
         thumbOutDir + '/' + thumbFilePattern]

因此过滤器字符串现在带有前缀:

scale=300:-1,

...制作 filter:v 两个过滤器的链。不要错过逗号分隔符。 我在这里解释这一点是因为解决方案和工作示例很难找到。 FFmpeg 文档非常密集,如果您还不了解的话很难理解。

© www.soinside.com 2019 - 2024. All rights reserved.