在python中正确使用subprocess.PIPE?
我试图使用在python中正确使用subprocess.PIPE?,python,subprocess,Python,Subprocess,我试图使用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([
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()
使用
subprocess.PIPE
不会神奇地为您连接正确的管道
必须将第一个进程的输出管道作为第二个进程的参数stdin
的值传递 Python不能以这种方式“构建一个完整的管道”——它可以将任务委托给shell,或者更直接地使用行中先前子流程对象的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
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不是必须的,那么可以直接使用shell
the_file="/Volumes/Footage/Acura/MDX/2001/Crash Test/01 Acura MDX Front Crash.mov"
ffmpeg -i "$file" 2>&1 | awk '/Duration/{print $2}'
正如其他人指出的,您需要将管道从一个流程传递到下一个流程。 来自一个进程的标准输出(管道)将成为以下任务的标准输入 类似这样的内容(从您的示例开始):
为什么要使用grep、cut和sed来解析输出,而不是使用内置的Python函数?你的敌人是你。我没有意识到我必须重定向<代码> STDRR 。我会认为这是正确的答案,它准确地回答了OP所问的问题,并没有告诉你如何绕过它。现在有一个管道模块:
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()