2017-08-29 95 views
0

我想什么做的是这样的:如何将一个程序(ffmpeg)的输出传递给python脚本?

ffmpeg -i udp://224.10.10.10:15004 -qscale:v 2 sttest%04d.jpg 

再经过这个输出图像路径到Python脚本,其分别发生在图像和操纵他们,因为ffmpeg运行(最终我会使用ffmpy来调用ffmpeg而不是使用命令行工具,但是为了测试目的,我从这里开始)。

我想要做到这一点的方法是每次处理图像时查看ffmpeg输出的目录以查看是否有新图像,然后将其加载到python中(使用OpenCV) - - 如果没有新图像要处理,则等待一定的时间间隔。

但是有没有更好的方法来做到这一点,比如直接发送图像的路径到某种类型的队列,python脚本可以逐一处理?

回答

0

对于任何人都好奇,这里是我的解决方案。它使用OpenCV。当我问这个问题时,我并没有意识到这一点,但OpenCV具有在幕后使用ffmpeg的某些功能。由于我的程序已经在使用OpenCV,我只是在提到的问题中提到了这个问题(因为我认为它不重要),使用OpenCV内置的功能来执行我想要的功能并不是很困难。下面是代码:

cap = cv2.VideoCapture("video.mpg") 
count = 0 
frame_q = queue.Queue() 

while cap.grab(): 
    success, frame = cap.read() 

    if count % 5 == 0 and success: 
      frame_alpha = np.insert(frame, 3, 255, axis=2) 
      frame_q.put(frame_alpha) 

    count += 1 

正如你所看到的,我只是把每五帧到帧的Queue。这样做的核心是以下三行:

cap = cv2.VideoCapture("video.mpg") 
while cap.grab(): 
    success, frame = cap.read() 

第一行打开捕捉,而子句检查是否存在使用cap.grab()任何一个以上帧(返回True如果存在下一个帧),然后我读使用cap.read()将帧编码为numpy阵列。success是一个布尔值,指示操作是否成功。后来,我加入一个alpha通道frame,并把它放入frame_q

然后,程序get小号帧的另一个线程的是Queue的。这样,我根本不必处理文件系统 - 就像Marcus说的那样,我将它们直接加入到程序中。

注:cv2.VideoCapture()上班opencv_ffmpeg.dll需要在系统路径或者您正在使用哪个的Python安装的根目录。你可能有其中XYZ是OpenCV版本号减去小数点将其重命名为opencv_ffmpegXYZ.dll。所以对我来说,这是opencv_ffmpeg330.dll因为我有版本3.3.0。它也可能在x64系统上被称为opencv_ffmpeg330_64.dll

opencv_ffmpeg.dll位置取决于你如何安装OpenCV,我只想在OpenCV目录搜索opencv_ffmpeg,看看它出现。在你把它复制到Python目录,一定要检查,如果它已经存在。这可能是,取决于你如何安装OpenCV

1

由于FFmpeg没有输出“我已生成的文件名”的流,所以您唯一的选择是使用您拥有的文件系统。

根据您的操作系统,在目录中接触到新文件时可能会收到通知。我不知道这是否适用于linux,windows,os x,但它值得研究。

事实上,这看起来很简单,你不会做到这一点通过外部调用ffmpeg。 ffmpeg基本上是用于libavcodec的用户前端,该库用于对视频,音频等进行解码和编码。

因此,您可能只是想在应用程序中使用libavcodec。我实际上认为,如果使用实际的媒体流体系结构,你想要做的事会容易得多。 GStreamer可能是您的首选工具,您可以直接从python使用它,但我没有经验,这是多么容易。

您的目标应该是直接在您的python程序中获取框架,而不必绕行写入磁盘。

一个简单的MJPEG(Motion JPEG格式)转换器,简单管道输送到你的程序的stdin可能是最简单的方法,如果你不希望使用任何libav*gstreamer

相关问题