【发布时间】:2011-11-29 18:16:52
【问题描述】:
我已经查看了许多问题,但仍然无法完全弄清楚这一点。我正在使用 PyQt,并希望运行 ffmpeg -i file.mp4 file.avi 并在流式传输时获取输出,以便创建进度条。
我查看了以下问题: Can ffmpeg show a progress bar? catching stdout in realtime from subprocess
我可以看到 rsync 命令的输出,使用以下代码:
import subprocess, time, os, sys
cmd = "rsync -vaz -P source/ dest/"
p, line = True, 'start'
p = subprocess.Popen(cmd,
shell=True,
bufsize=64,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
for line in p.stdout:
print("OUTPUT>>> " + str(line.rstrip()))
p.stdout.flush()
但是当我将命令更改为 ffmpeg -i file.mp4 file.avi 时,我没有收到任何输出。我猜这与标准输出/输出缓冲有关,但我不知道如何读取看起来像
frame= 51 fps= 27 q=31.0 Lsize= 769kB time=2.04 bitrate=3092.8kbits/s
我可以用它来计算进度。
有人可以告诉我一个例子,说明如何使用或不使用 PyQt(如果可能的话)将这些信息从 ffmpeg 获取到 python 中
编辑: 我最终选择了 jlp 的解决方案,我的代码如下所示:
#!/usr/bin/python
import pexpect
cmd = 'ffmpeg -i file.MTS file.avi'
thread = pexpect.spawn(cmd)
print "started %s" % cmd
cpl = thread.compile_pattern_list([
pexpect.EOF,
"frame= *\d+",
'(.+)'
])
while True:
i = thread.expect_list(cpl, timeout=None)
if i == 0: # EOF
print "the sub process exited"
break
elif i == 1:
frame_number = thread.match.group(0)
print frame_number
thread.close
elif i == 2:
#unknown_line = thread.match.group(0)
#print unknown_line
pass
这给出了这个输出:
started ffmpeg -i file.MTS file.avi
frame= 13
frame= 31
frame= 48
frame= 64
frame= 80
frame= 97
frame= 115
frame= 133
frame= 152
frame= 170
frame= 188
frame= 205
frame= 220
frame= 226
the sub process exited
完美!
【问题讨论】:
-
您在 edit 中的代码看起来不正确(并且对我不起作用)...我认为您不想捕获通配符模式并且什么都不做(您只需要捕获您关心的模式),更重要的是 - 您希望
thread.close在 while 循环之外,而不是在您第一次捕获您感兴趣的模式时调用。 @jlp 的代码似乎更正确,一旦适应了 ffmpeg 输出,就可以为我工作。 -
如果是Python3,应该是:
frame_number = thread.match.group(0).decode('utf-8') -
对于捕获的错误,您应该在 while 后面加上:
thread.close()if thread.exitstatus:print(thread.before)else:print('Ok') -
这部分'(.+)'在代码中做了什么?另外,我正在使用的程序,我需要检测输出失败,有没有办法做多种模式?谢谢。
标签: python ffmpeg pyqt subprocess stdout