5

我需要使用网络摄像头捕获视频,并为捕获的每个视频帧输出一个图像。

我曾尝试将 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 等文件,然后再次解码?

有没有人有任何想法或建议?请记住,我需要能够在代码中执行此操作,而不是使用诸如 Adob​​e Premiere 之类的应用程序。

谢谢!

4

3 回答 3

5

您可以像这样简单地在其中添加一个队列:

gst-launch v4l2src device=/dev/video1 ! video/x-raw-yuv,framerate=30/1 ! queue ! ffmpegcolorspace ! pngenc ! multifilesink location="frame%d.png"

这应该确保允许视频捕获以 30 fps 的速度运行,然后可以按照自己的速度将其写入磁盘。请注意,如果您离开此设置太久,队列将变得非常大。

于 2013-06-26T21:40:20.600 回答
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"
于 2014-12-25T08:22:56.337 回答
2

我必须提供的解决方案不使用 gstreamer,而是使用 ffmpeg。我希望这对你也很好。

本论坛帖子中所述,您可以使用以下内容:

ffmpeg -i movie.avi frame%d.png

为视频的每一帧获取 png/jpg 图像。
但根据您使用的输入文件,您可能必须在运行 ffmpeg 之前将其转换为 MPEG vid。

注意:
如果您想在图像文件名中使用前导零,请%05d改用(对于 5 位数字,如 C's 中printf()):

ffmpeg -i movie.avi frame%05d.png

输出文件格式取决于文件扩展名,因此您可以使用.jpg, .bmp, ... 而不是.png.

于 2013-03-26T13:21:51.177 回答