我看了很多问题,但还是不能完全弄清楚。 我正在使用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
时,我没有收到任何输出。我猜这与stdout / output buffering有关,但是我不知道如何读取看起来像的那一行frame= 51 fps= 27 q=31.0 Lsize= 769kB time=2.04 bitrate=3092.8kbits/s
我希望能够使用它来确定进度。
有人可以向我展示如何将此信息从ffmpeg获取到Python中,无论是否使用PyQt(如果可能)
编辑:最终我采用了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
完美!
thread.close
在 while 循环之外而不是在第一次捕获到你感兴趣的模式时调用。@jlp 的代码似乎更正确,一旦适应 ffmpeg 输出,它对我也有效。 - Anentropicframe_number = thread.match.group(0).decode('utf-8')
。 - o_renthread.close()
if thread.exitstatus:
print(thread.before)
else:
print('Ok')
- Artem