如何将一个程序(ffmpeg)的输出传递给python脚本?

时间:2017-08-29 09:01:11

标签: python ffmpeg ipc

我想做的是:

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

然后将此输出图像路径传递给python脚本,当ffmpeg正在运行时,它会单独接收图像并对其进行操作(最终我将使用ffmpy来调用{{1而不是使用命令行工具,但为了现在的测试目的,我从这里开始。)

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

但是有更好的方法吗,比如将图像的路径直接发送到某种队列,然后python脚本可以逐个处理?

2 个答案:

答案 0 :(得分:1)

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

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

事实上,这看起来很简单,你不会通过外部调用ffmpeg来拥有来实现它。 ffmpeg基本上是libavcodec的用户前端,这是一个用于解码和编码视频,音频等的库。

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

你的目标应该是直接在你的python程序中获取帧,而不必绕过将它们写入磁盘。

简单的MJPEG(Motion JPEG)转换器,如果您不想使用stdinlibav*,只需通过管道传输到程序的gstreamer可能是最简单的方式。

答案 1 :(得分: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()

第一行打开捕获,while子句使用cap.grab()检查是否还有帧(如果有下一帧则返回True)然后我将该帧读入{{ 1}}数组使用numpycap.read()是一个布尔值,表示操作是否成功。之后,我向success添加了一个Alpha通道,并将其放入frame

然后,程序frame_q的另一个线程框出get。这样,我根本不需要处理文件系统 - 就像Marcus说的那样,我将它们直接送到程序中。

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

opencv_ffmpeg.dll的位置取决于您安装OpenCV的方式,我只需在OpenCV目录中搜索opencv_ffmpeg并查看其出现位置。在将其复制到Python目录之前,请务必检查它是否已存在。它可能是,取决于您安装OpenCV的方式。