将视频转换为一系列帧图像

6
我需要使用网络摄像头捕获视频并为每个捕获的视频帧输出一张单独的图像。
我尝试使用gstreamer和multifilesink,例如:
gst-launch v4l2src device=/dev/video1 ! video/x-raw-yuv,framerate=30/1 ! ffmpegcolorspace ! pngenc ! multifilesink location="frame%d.png"

然而,这并没有实际输出每一帧,这意味着如果我以30fps录制2秒钟,我不会得到60张图片。我猜这是因为编码速度跟不上,所以我需要另一种方法。
我想,如果我有一个管道捕获视频,另一个管道将该视频转换为帧,那么它可能会起作用,但我对编解码器了解不够。我是否需要将视频编码为像h264或mp4这样的文件,然后再解码它?
有人有什么想法或建议吗?请记住,我需要能够在代码中完成这个操作,而不是使用诸如Adobe Premiere之类的应用程序。
谢谢!
3个回答

5
您可以像这样简单地添加一个队列:
gst-launch v4l2src device=/dev/video1 ! video/x-raw-yuv,framerate=30/1 ! queue ! ffmpegcolorspace ! pngenc ! multifilesink location="frame%d.png"

这个设置可以确保视频捕捉以30帧每秒的速度运行,然后将其写入磁盘的过程可以按自己的节奏进行。但是请注意,如果您长时间保留此设置,则队列会增长到相当大的大小。


1
我把这个过程分成了两个部分。
将视频写入文件。
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"

这是一个笔误还是你在第一条命令中使用了 gst-launch (0.x),而在第二条命令中使用了 gst-launch-1.0? - Adam Plocher

1

我提供的解决方案不使用gstreamer,而是使用ffmpeg。希望这对你来说也可以。

此论坛帖子所述,您可以使用以下类似代码:

ffmpeg -i movie.avi frame%d.png

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

注意:
如果您想要在图像文件名中使用前导零,请改用%05d(例如C语言中的printf()):

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

输出文件格式取决于文件扩展名,因此您可能会使用 .jpg.bmp 等代替 .png


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接