我需要使用网络摄像头捕获视频,并为捕获的每个视频帧输出单个图像。
我尝试过使用gstreamer和multifilesink,例如:
gst-launch v4l2src device=/dev/video1 ! video/x-raw-yuv,framerate=30/1 ! ffmpegcolorspace ! pngenc ! multifilesink location="frame%d.png"
然而,实际上并没有输出每一帧,这意味着如果我以30 fps录制2秒,我就不会得到60张图像。我假设这是因为编码不能那么快,所以我需要另一种方法。
我认为如果我有一个管道捕获视频,并且一个单独的管道将该视频转换为帧,它可能会工作,但我对编解码器知之甚少。我是否需要将视频编码为h264或mp4等文件,然后再对其进行解码?
有没有人有任何想法或建议?请记住,我需要能够在代码中执行此操作,而不是使用Adobe Premiere之类的应用程序。
谢谢!
答案 0 :(得分:3)
您可以像这样添加一个队列:
gst-launch v4l2src device=/dev/video1 ! video/x-raw-yuv,framerate=30/1 ! queue ! ffmpegcolorspace ! pngenc ! multifilesink location="frame%d.png"
这应该确保允许视频捕获以30 fps运行,然后将其写入 磁盘可以按照自己的节奏发生。请注意,队列将变得非常大 如果您将此设置保留太长时间。
答案 1 :(得分:2)
我提供的解决方案不使用gstreamer而是使用ffmpeg。我希望你也没关系。
如this forum post所述,您可以使用以下内容:
ffmpeg -i movie.avi frame%d.png
获取视频每帧的png / jpg图像 但是根据您使用的输入文件,您可能必须在运行ffmpeg之前将其转换为MPEG vid。
注意:
如果您想在图像文件名中使用前导零,请改用%05d
(对于5位数字,如C的printf()
):
ffmpeg -i movie.avi frame%05d.png
输出文件格式取决于文件扩展名,因此您可以使用.jpg
,.bmp
,...代替.png
。
答案 2 :(得分:2)
我最后分两部分来做这件事。
将视频写入文件。
gst-launch v4l2src device=/dev/video2 ! video/x-raw-yuv,framerate=30/1 ! xvidenc ! queue ! avimux ! filesink location=test.avi
发布过程。
gst-launch-1.0 --gst-debug-level=3 filesrc location=test.avi ! decodebin ! queue ! autovideoconvert ! pngenc ! multifilesink location="frame%d.png"