Python的管道和大文件的子处理

Lin*_*äck 7 python subprocess ffmpeg

我正在尝试使用python + ffmpeg + oggenc将任何音频文件转换为ogg.该计划几乎可以运作.但对于大文件(我认为>〜6mb),ffmpeg进程开始在pipe_wait中休眠.我不知道它等待哪个管道.

如果我杀死ffmpeg进程,oggenc进程继续,我得到一个结果ogg文件约有所有声音的2:40.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from subprocess import Popen, PIPE
from sys import argv

ffmpeg = Popen([
    "ffmpeg",
    "-i", argv[1],
    "-vcodec", "null",
    "-acodec", "pcm_s16le",
    "-ac", "2",
    "-ab", "44100",
    "-f", "wav",
    "-"
],stdout = PIPE,stderr = PIPE)

oggenc = Popen([
    "oggenc",
    "-", "--raw",
    "-q", "4",
    "-o", argv[2]
],stdin = ffmpeg.stdout,stderr = PIPE)

oggenc.communicate()
ffmpeg.communicate()
Run Code Online (Sandbox Code Playgroud)

编辑:

以为我可能会补充说这完美无缺:

#!/bin/bash

ffmpeg -i "$1" -vcodec null -acodec pcm_s16le -ac 2 -ab 44100 -f wav - | oggenc - --raw -q 4 -o "$2"
Run Code Online (Sandbox Code Playgroud)

tzo*_*zot 5

你究竟stderr对这两个管道的通道做了什么?

编码器/解码器通常会产生大量的stderr输出,作为状态更新; 此输出通过管道输送到您的进程,缓冲区将变满.也许你应该ffmpeg.stderr.read()在(无用的,我认为).communicate调用之前添加一些虚拟调用,或者甚至更好,stderr=PIPE完全删除参数.

UPDATE

对于>/dev/null等效的,请执行以下操作:

nulfp = open(os.devnull, "w")
…
… = subprocess.Popen(…, stderr=nulfp.fileno())
Run Code Online (Sandbox Code Playgroud)

显然,你可以nulfpstderr你想要忽略的所有人重复使用相同的东西.