subprocess.Popen
を使用して、ビデオファイルの長さを取得するシーケンスを作成しようとしています。私は3日間検索していて、このコードが機能しない理由をオンラインで見つけることができませんが、空白の結果が表示され続けます。
import sys
import os
import subprocess
def main():
the_file = "/Volumes/Footage/Acura/MDX/2001/Crash Test/01 Acura MDX Front Crash.mov"
ffmpeg = subprocess.Popen(['/opt/local/bin/ffmpeg', '-i', the_file], stdout = subprocess.PIPE, )
grep = subprocess.Popen(['grep', 'Duration'], stdin = subprocess.PIPE, stdout = subprocess.PIPE, )
cut = subprocess.Popen(['cut', '-d', ' ', '-f', '4'], stdin = subprocess.PIPE, stdout = subprocess.PIPE, )
sed = subprocess.Popen(['sed', 's/,//'], stdin = subprocess.PIPE, stdout = subprocess.PIPE, )
duration = sed.communicate()
print duration
if __name__ == '__main__':
main()
stderrをstdoutにリダイレクトする必要があります。また、cut/sed
などの他のツールを呼び出す必要はありません。Pythonで文字列を操作します。
import subprocess
....
the_file = "/Volumes/Footage/Acura/MDX/2001/Crash Test/01 Acura MDX Front Crash.mov"
ffmpeg = subprocess.Popen(['/usr/bin/ffmpeg', '-i', the_file], stderr=subprocess.STDOUT,stdout = subprocess.PIPE )
out, err = ffmpeg.communicate()
if "Duration" in out:
print out[out.index("Duration"):].split()[1]
Pythonが必須ではない場合は、シェルを直接使用できます。
the_file="/Volumes/Footage/Acura/MDX/2001/Crash Test/01 Acura MDX Front Crash.mov"
ffmpeg -i "$file" 2>&1 | awk '/Duration/{print $2}'
他の人が指摘しているように、あるプロセスから次のプロセスにPIPEを渡す必要があります。 1つのプロセスからのstdout(PIPE)は、次のタスクのstdinになります。
このようなもの(あなたの例から始めて):
import sys
import os
import subprocess
def main():
the_file = "/Volumes/Footage/Acura/MDX/
2001/Crash Test/01 Acura MDX Front Crash.mov"
ffmpeg = subprocess.Popen(['/opt/local/bin/ffmpeg', '-i', the_file],
stdout = subprocess.PIPE)
grep = subprocess.Popen(['grep', 'Duration'],
stdin = ffmpeg.stdout, stdout = subprocess.PIPE)
cut = subprocess.Popen(['cut', '-d', ' ', '-f', '4'],
stdin = grep.stdout, stdout = subprocess.PIPE)
sed = subprocess.Popen(['sed', 's/,//'],
stdin = cut.stdout, stdout = subprocess.PIPE)
duration = sed.communicate()[0]
print duration
if __name__ == '__main__':
main()
subprocess.PIPE
を使用しても、正しいパイプが魔法のように配線されることはありません。
最初のプロセスの出力パイプを、2番目のプロセスのパラメータstdin
の値として渡す必要があります。 例についてはドキュメントを参照してください 。
Pythonは、この方法で「パイプライン全体を構築」することはできません。タスクをシェルに委任したり、行の前のサブプロセスオブジェクトのstdout
属性を使用してより直接接着したりできますが、実際にはあります。この特定のケースでは、Pythonで非常に簡単にコーディングできるため、その理由はありません。例:
ffmpeg = subprocess.Popen(['/opt/local/bin/ffmpeg', '-i', the_file],
stdout=subprocess.PIPE)
for line in ffmpeg.stdout:
if 'Duration' not in line: continue
fields = line.split()
duration = fields[4].replace(',', '')
break