3

そのため、HandBrakeCLI の出力を Python サブプロセスとしてキャプチャしようとしています。更新ごとにファイルのようなパイプに新しい行が作成されるため、これは stderr の問題ではありません。ただし、stdout を使用すると、HandBrakeCLI はインプレース更新を行い、それらをキャプチャするのに苦労しています。インプレース更新が何と呼ばれているのかさえわからないため、関連するヒントを見つけるのが少し難しい.

これまでに思いついた唯一の解決策は、標準出力を実際のファイルに書き込んでそこから読み取ることですが、私はむしろこれを(メモリ内で)正気の方法で行いたいと考えています。

COMMAND = ['HandBrakeCLI', '-v', '-i', 'in.m4v', '-o', 'out.m4v', '-Z', 'Normal']

outfile = open('output.txt', 'w')

proc = subprocess.Popen(COMMAND, stdout=outfile, stderr=subprocess.PIPE)

infile = open('output.txt', 'r')

while proc.poll() is None:
    print infile.read()
    infile.seek(0)

これは機能しますが、もっと良い方法があるはずです。communicate() または単純な proc.stdout.read() を使用しようとすると、何も得られません。

私は何を間違っていますか?ありがとう!

アップデート

@wimの提案に従って、生の出力HandBrakeCLIが提供するものを確認したところ、次のようになりました。

\rEncoding: task 1 of 1, 0.15 %

\r で始まる標準出力を処理する最良の方法は何ですか?

4

1 に答える 1

5

universal_newlines=True の使用について上記で行ったコメントは機能すると思います。

「inplace_output.py」と呼ばれるインプレース ライターのサンプルを次に示します。

import sys
import time


def main():
    for k in range(5):
        print "{0:03d}\r".format(k),
        sys.stdout.flush()
        time.sleep(1)

if __name__ == "__main__":
    main()

それを実行して、前の出力を上書きするたびに 000、次に 001 などを書き込むのを見ることができます。

上記をサブプロセスとして実行し、その出力を 1 行ずつ読み取るスクリプトを次に示します。

import subprocess


cmd = ['python', 'inplace_output.py']

proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)

while True:
    out = proc.stdout.readline()
    print repr(out)
    if len(out) == 0:
        break

subprocess プログラムが終了したときにすべての出力を一度に収集したい場合は、while ループを次のように置き換えることができます。

out, err = proc.communicate()
lines = out.splitlines()

それらのいずれかがあなたのために働きますか?

于 2012-09-04T03:19:25.280 に答える