【问题标题】:Receiving multiple files from ffmpeg via subprocesses.PIPE通过 subprocess.PIPE 从 ffmpeg 接收多个文件
【发布时间】:2014-10-12 20:07:32
【问题描述】:

我正在使用 ffmpeg 将视频转换为图像。这些图像然后由我的 Python 程序处理。本来我是用ffmpeg先把图片保存到磁盘,然后用Python一一读取。

这很好用,但为了加快程序速度,我试图跳过存储步骤,只处理内存中的图像。

我使用以下 ffmpeg 和 Python subproccesses 命令将输出从 ffmpeg 通过管道传输到 Python:

command = "ffmpeg.exe -i ADD\\sg1-original.mp4 -r 1 -f image2pipe pipe:1"
pipe = subprocess.Popen(ffmpeg-command, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
image = Image.new(pipe.communicate()[0])

然后我的程序可以使用图像变量。问题是,如果我从 ffmpeg 发送超过 1 个图像,所有数据都存储在这个变量中。我需要一种分离图像的方法。我能想到的唯一方法是在文件末尾(0xff,0xd9)上分割 jpeg 标记。这有效,但不可靠。

关于带有子进程的管道文件,我错过了什么。有没有办法从管道中一次只读取一个文件?

【问题讨论】:

    标签: python ffmpeg subprocess pipe


    【解决方案1】:

    对此的一种解决方案是使用 ppm 格式,它具有可预测的大小:

    ffmpeg -i movie.mp4 -r 1 -f image2pipe -vcodec ppm pipe:1
    

    这里指定格式:http://netpbm.sourceforge.net/doc/ppm.html

    看起来像这样:

    P6      # magic number
    640 480 # width height
    255     # colors per channel
    <data>
    

    其中正好是 640 * 480 * 3 字节(假设每个通道有 255 种或更少的颜色)。

    请注意,此一种未压缩格式,因此如果您一次读取所有内容,它可能会占用相当多的内存。您可以考虑将您的算法转换为:

    pipe = subprocess.Popen(ffmpeg_command, stdout=subprocess.PIPE, stderr=sys.stderr)
    while True:
       chunk = pipe.stdout.read(4096)
       if not chunk:
           break
       # ... process chunk of data ...
    

    注意子进程'stderr设置为当前进程'stderr;这很重要,因为如果我们不这样做,stderr 缓冲区可能会填满(因为没有任何东西在读取它)并导致死锁。

    【讨论】:

    • 谢谢。这似乎是拆分它的最佳方式。通过缩小图像,我能够将它们缩小到可管理的大小。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 2019-04-28
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多