我已经研究了许多问题,但仍然不能完全解决这个问题。我正在使用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 /输出缓冲有关,但我不知道如何阅读下面的代码行
frame= 51 fps= 27 q=31.0 Lsize= 769kB time=2.04 bitrate=3092.8kbits/s我可以用它来计算进度。
有没有人可以给我举个例子,说明如何在使用或不使用PyQt的情况下,将这些信息从ffmpeg导入python (如果可能的话)。
jlp编辑:我最终采用了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太棒了!
发布于 2011-10-04 06:02:48
我发现从子进程获得动态反馈/输出的唯一方法是使用类似于pexpect的东西:
#! /usr/bin/python
import pexpect
cmd = "foo.sh"
thread = pexpect.spawn(cmd)
print "started %s" % cmd
cpl = thread.compile_pattern_list([pexpect.EOF,
'waited (\d+)'])
while True:
i = thread.expect_list(cpl, timeout=None)
if i == 0: # EOF
print "the sub process exited"
break
elif i == 1:
waited_time = thread.match.group(1)
print "the sub process waited %d seconds" % int(waited_time)
thread.close()被调用的子进程foo.sh只是在10到20秒之间随机等待一段时间,下面是它的代码:
#! /bin/sh
n=5
while [ $n -gt 0 ]; do
ns=`date +%N`
p=`expr $ns % 10 + 10`
sleep $p
echo waited $p
n=`expr $n - 1`
done您需要使用一些与从ffmpeg获得的输出相匹配的正则表达式,并对其进行某种计算以显示进度条,但这至少会从ffmpeg获得未缓冲的输出。
发布于 2016-02-16 09:50:14
在这个捕获ffmpeg的状态输出的特定情况下(到STDERR),这个SO问题为我解决了它:FFMPEG and Pythons subprocess
诀窍是将universal_newlines=True添加到subprocess.Popen()调用中,因为ffmpeg的输出实际上是无缓冲的,但带有换行符。
cmd = "ffmpeg -i in.mp4 -y out.avi"
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,universal_newlines=True)
for line in process.stdout:
print(line)还要注意,在此代码示例中,STDERR status输出被直接重定向到subprocess.STDOUT
发布于 2011-10-03 17:03:33
stderr而不是stdout提供了部分ffmpeg输出。如果您只想打印输出行,如上面的示例所示,则只需执行以下操作:
import subprocess
cmd = 'ffmpeg -i file.mp4 file.avi'
args = cmd.split()
p = subprocess.Popen(args)请注意,ffmpeg chat的行以\r结尾,因此它将在同一行中被覆盖!我认为这意味着您不能像在p.stderr示例中那样遍历rsync中的行。然后,要构建自己的进度条,您可能需要自己处理读数,这应该可以让您开始:
p = subprocess.Popen(args, stderr=subprocess.PIPE)
while True:
chatter = p.stderr.read(1024)
print("OUTPUT>>> " + chatter.rstrip())https://stackoverflow.com/questions/7632589
复制相似问题