ffmpeg 捕获当前帧并覆盖图像输出文件

Posted

技术标签:

【中文标题】ffmpeg 捕获当前帧并覆盖图像输出文件【英文标题】:ffmpeg capture current frame and overwrite the image output file 【发布时间】:2014-10-11 04:46:45 【问题描述】:

我正在尝试每秒(也可能每 1 分钟)从 RTSP 流 url 中提取图像文件并覆盖此图像文件。

我下面的代码有效,但它输出到多个图像 jpg 文件:img1.jpg, img2.jpg, img3.jpg...

ffmpeg -i rtsp://IP_ADDRESS/live.sdp -f image2 -r 1 img%01d.jpg

如何在 Linux 中使用 ffmpeg 或 bash 脚本覆盖相同的图像文件,同时以不高的频率(比如 1 分钟或 10 秒)连续提取图像?

【问题讨论】:

image2 有一个“updatefirst”选项,IIRC,请记住,如果您在 Windows 上,它会在您尝试读取文件时覆盖文件,这可能会导致冲突/冲突 【参考方案1】:

以下命令行应该适合您。

ffmpeg -i rtsp://IP_ADDRESS/live.sdp -f image2 -updatefirst 1 img.jpg

【讨论】:

这对我有用,我添加了“-r 1/5”选项以使其每 5 秒捕获一次。 @pragnesh 如何将每个屏幕截图保存在不同的文件中? 看来updatefirst 已经在ffmpeg 4.X 版中被移除了? 正如所指出的,-updatefirst 选项已被删除,不再起作用。请改用-y 选项。【参考方案2】:

从pragnesh 中详细说明已经accepted answer,

FFmpeg

如ffmpeg documentation 中所述: ffmpeg 命令行选项指定为

ffmpeg [global_options] [input_options] -i input_file ... [output_options] output_file ...

所以

ffmpeg -i rtsp://<rtsp_source_addr> -f image2 -update 1 img.jpg

使用 output option -f image2 ,强制输出格式为 image2 格式,作为 muxer 阶段的一部分。

请注意,在 ffmpeg 中,如果输出文件名指定了图像格式,则默认使用 image2 muxer,因此该命令可以缩短为:

ffmpeg -i rtsp://<rtsp_source_addr> -update 1 img.jpg

image2 format muxer 需要一个文件名模式,例如img%01d.jpg,以生成一系列按顺序编号的文件。如果 update option 设置为 1,文件名将被解释为只是一个文件名,而不是一个模式,从而覆盖同一个文件。

使用 -r ,设置帧速率,video option 可以工作,但产生了很多丢帧消息,这让我很烦恼。

感谢another answer on the same topic,我发现fps Video Filter 做得更好。

所以我的工作命令版本是

ffmpeg -i rtsp://<rtsp_source_addr> -vf fps=fps=1/20 -update 1 img.jpg

出于某种原因,我仍然不知道从我的提要中可以达到的最低帧速率是 1/20 或 0.05。

还有视频过滤器缩略图,它从一系列帧中选择一个图像,但这是处理密集型的,因此我不推荐它。

我在FFMpeg Online Documentation 上找到了大部分内容和更多内容

AVconv

对于那些使用 avconv 的人来说,它非常相似。毕竟,它们是曾经是一个公共图书馆的分支。 AVconv image2 documentation is found here。

avconv -i rtsp://&lt;rtsp_source_addr&gt; -vf fps=fps=1/20 -update 1 img.jpg

正如贤林指出的,可能还有其他一些有趣的选项可供使用:

-an :禁用录音。

发现于Audio Options Section

-r : 设置帧率

发现于Video Options Section 用作输出选项实际上是fps filter的替代品

导致替代版本:

avconv -i rtsp://&lt;rtsp_source_addr&gt; -r 1/20 -an -update 1 img.jpg

希望它有助于理解可能的进一步调整;)

【讨论】:

使用 avconv 代替 ffmpeg,avconv -i rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov -r 1/20 -an -y -update 1 test.jpg 根据 -r Video Options docs,-r 选项实际上会导致插入 fps 过滤器。所以 -vf fps=fps=1/20 也应该这样做。但是使用 -r 会更短:) 另外我认为您不需要 -y ( Overwrite output files without ask) 选项作为 -update 1 已经知道它应该覆盖。 -an 加法是一个有趣的加法,它可以减少过程猜测。感谢您的评论,我将使用 avconv 选项更新答案。【参考方案3】:

我无法使用 -update 选项来覆盖 .jpg。做一些实验得到了一个可行的解决方案(至少对我来说),最后带有选项 -y (大写字母不起作用)。我还需要 http:// 而不是 rstp:// 这台相机。

ffmpeg -i http://xx:yy@192.168.1.xx:yyy/snapshot.cgi /tmp/Capture2.jpg -y

【讨论】:

【参考方案4】:

每 10 秒从 RTSP 视频流中抓取一次快照。

#!/bin/bash
#fetch-snapshots.sh
url='rtsp://IP_ADDRESS/live.sdp'
avconv -i $url -r 0.1 -vsync 1 -qscale 1 -f image2 images%09d.jpg

-r rate 将帧速率设置为每秒 0.1 帧(这等于每 10 秒 1 帧)。 感谢westonruter,请参阅https://gist.github.com/westonruter/4508842

另外看看FFMPEG: Extracting 20 images from a video of variable length

【讨论】:

所以我将在 60 秒内获得 6 张图像,那么我在 60 秒内只有一张图像被覆盖 6 次如何?这就是我需要的。 您是否尝试过选项“-y(全局)”覆盖输出文件而不询问。

以上是关于ffmpeg 捕获当前帧并覆盖图像输出文件的主要内容,如果未能解决你的问题,请参考以下文章

ffmpeg-python中文文档(三)——API参考

在python中使用vid.stab将ffmpeg的输出文件捕获到一个变量中

ffmpeg常用命令

ffmpeg输出文件名为当前日期

ffmpeg输出文件名为当前日期

处理来自 Mediacodec 输出的帧并在 Android 上更新帧