【问题标题】:How to pipe output from ffmpeg using python?如何使用python从ffmpeg管道输出?
【发布时间】:2019-07-26 19:52:17
【问题描述】:

我正在尝试在 Python 中管道输出来自 FFmpeg 的输出。我正在从视频采集卡中读取图像,并且成功地使用 dshow 从命令行将其读取到输出文件中。我正在尝试将图像从卡中抓取到我的 OpenCv 代码中,以便能够进一步使用数据。不幸的是,当我输出图像时,我只得到了视频的显示,如链接所示:

链接:s000.tinyupload.com/?file_id=15940665795196022618。

我使用的代码如下图:

import cv2
import subprocess as sp
import numpy
import sys
import os
old_stdout=sys.stdout
log_file=open("message.log","w")
sys.stdout=log_file

FFMPEG_BIN = "C:/ffmpeg/bin/ffmpeg.exe"
command = [ FFMPEG_BIN, '-y',
            '-f', 'dshow', '-rtbufsize', '100M',
            '-i', 'video=Datapath VisionAV Video 01' ,
             '-video_size', '640x480',
              '-pix_fmt', 'bgr24', '-r','25',  
          '-f', 'image2pipe', '-' ]    
pipe = sp.Popen(command, stdout = sp.PIPE, bufsize=10**8)

while True:
    # Capture frame-by-frame
    raw_image = pipe.stdout.read(640*480*3)
      # transform the byte read into a numpy array
    image =  numpy.frombuffer(raw_image, dtype='uint8')
    print(image)
    image = image.reshape((480,640,3))          
    if image is not None:
        cv2.imshow('Video', image)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    pipe.stdout.flush()
sys.stdout=old_stdout
log_file.close()
cv2.destroyAllWindows()

请为我提供一些解决此问题的建议。非常感谢您的帮助。

【问题讨论】:

  • @Muhammad Furqan 在 ffmpeg 命令中的“-”之前最后添加 -f image2pipe 似乎并没有给我视频。您还有其他建议吗?
  • 尝试修改命令如下[ FFMPEG_BIN, '-y', '-f', 'dshow', '-rtbufsize', '100M', '-i', 'video=Datapath VisionAV Video 01' ,'-f', 'image2pipe', '-video_size', '640x480', '-pix_fmt', 'bgr24', '-r','25', '-' ]

标签: python opencv ffmpeg pipe


【解决方案1】:

您拨打sp.Popen后,您已经与它通信。您可以使用以下代码:

try:    
    pipe = sp.Popen(command, stdout=sp.PIPE, stderr=sp.STDOUT, universal_newlines=True)`

    ffmpeg_output, _ = pipe.communicate()

except  sp.CalledProcessError as err:
     print("FFmpeg stdout output on error:\n" + err.output)

最后,您可以打印输出以确保上述命令有效:

print(ffmpeg_output)

上述语句将显示与进程通信返回的输出。

【讨论】:

  • 我通过在 opencv 读取之前添加这些行来尝试这个。但是我没有在命令行上打印任何内容。该程序旨在从视频采集卡中获取连续流。如果命令行上似乎没有打印任何内容,我不知道这是否是原因..有什么想法吗?
  • 不,我编辑了我的答案。我建议您单独测试脚本中的命令,以确保它正常工作。
  • 这是我得到的:<_io.textiowrapper name="3" encoding="cp1252"> @SenDjasni
  • 我的错,尝试更新,我在终端上测试它并且它有效。
  • @user10890282 另外,将这些命令放在try: except: subprocess.CalledProcessError 中,因为subprocess 调用可能会产生异常。
【解决方案2】:

我在控制台应用程序 FFmpeg 上挣扎了更长时间,最后放弃了。 这个扩展更容易:

pip install ffmpeg-python

Karl Kroening 在这里发布了 FFmpeg 与 Python 的非常好的集成。 有了这些例子,一个解决方案应该是可能的: https://github.com/kkroening/ffmpeg-python

【讨论】:

  • 它不适用于多个 INPUT 命名管道
【解决方案3】:

这对我有用

import subprocess as sp
import json
import os
import numpy
import PIL
from imutils.video import FPS
import cv2 


def video_frames_ffmpeg():
    width = 640
    height = 360
    iterator = 0
    cmd = ['ffmpeg', '-loglevel', 'quiet',
           '-f', 'dshow',
           '-i', 'video=HD USB Camera',
           #'-vf','scale=%d:%d,smartblur'%(width,height),
           '-preset' ,'ultrafast', '-tune', 'zerolatency',
           '-f', 'rawvideo',
           '-pix_fmt','bgr24',
           '-']
    p = sp.Popen(cmd, stdout=sp.PIPE)

    while True:
        arr = numpy.frombuffer(p.stdout.read(width*height*3), dtype=numpy.uint8)
        iterator += 1 
        if len(arr) == 0:
            p.wait()
            print("awaiting")
            #return
        if iterator >= 1000:
            break

        frame = arr.reshape((height, width,3))
        cv2.putText(frame, "frame{}".format(iterator), (75, 70),
                cv2.cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 2)
        im = Image.fromarray(frame)
        im.save("ffmpeg_test/test%d.jpeg" % iterator)

        yield arr


from PIL import Image
from imutils.video import FPS
for i, frame in enumerate(video_frames_ffmpeg()):
    if i == 0:
        fps = FPS().start()
    else: fps.update()
fps.stop()
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
cv2.destroyAllWindows()

【讨论】:

  • 当使用“gray”而不是“bgr24”时,我得到了更多的 fps
  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
【解决方案4】:

试试:

command = [ FFMPEG_BIN,
            '-rtbufsize', '100M',
            '-i', '/dev/video0' , #change to here to your camera device
            '-video_size', '640x480',
            '-pix_fmt', 'bgr24',# '-r','25',
            '-f', 'image2pipe', #'-'
            '-vcodec', 'rawvideo', '-an', '-'
            ]

我不知道'-vcodec', 'rawvideo', '-an', '-' 这有什么帮助, 如果没有它,我的代码将无法工作。

【讨论】:

    猜你喜欢
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2015-11-16
    • 1970-01-01
    • 2020-08-20
    • 2014-07-01
    • 1970-01-01
    相关资源
    最近更新 更多