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://<rtsp_source_addr> -vf fps=fps=1/20 -update 1 img.jpg
正如贤林指出的,可能还有其他一些有趣的选项可供使用:
-an :禁用录音。
发现于Audio Options Section-r : 设置帧率
发现于Video Options Section 用作输出选项实际上是fps filter的替代品导致替代版本:
avconv -i rtsp://<rtsp_source_addr> -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 捕获当前帧并覆盖图像输出文件的主要内容,如果未能解决你的问题,请参考以下文章