问题
So I am using handbrake and python to encode videos based on a schedule. I need to monitor the progress because I use it to estimate the encoding time. Then I can fit it to my scheduler.
I am having an issue getting the ETA and % complete from the process. Here is what I have so far
profile = ["HandBrakeCLI","-i",input,"-o","output","-e","x264"]
cp = subprocess.Popen(profile, stderr=subprocess.PIPE, bufsize=1)
for line in iter(cp.stderr.readline, b''):
# regex match for % complete and ETA
matches = re.match( r'.*(\d+\.\d+)\s%.*ETA\s(\d+)h(\d+)m(\d+)s', line.decode('utf-8') )
if matches:
print( matches.group() )
print(line),
cp.stderr.close()
cp.wait()
It does not match, in fact I'm not entirely sure what is going on. When I run my script, I see the ETA and % complete print out
Encoding: task 1 of 1, 1.19 % (45.57 fps, avg 62.74 fps, ETA 00h08m01s)
I've tried using stdout but it doesn't work either.
回答1:
You need to read from stdout, not stderr.
profile = ["HandBrakeCLI","-i",input,"-o","output","-e","x264"]
cp = subprocess.Popen(profile, stderr=subprocess.PIPE, strout=subprocess.PIPE, bufsize=1)
for line in iter(cp.stdout.readline, b''):
# regex match for % complete and ETA
matches = re.match( r'.*(\d+\.\d+)\s%.*ETA\s(\d+)h(\d+)m(\d+)s', line.decode('utf-8') )
if matches:
print( matches.group() )
print(line),
cp.stderr.close()
cp.stdout.close()
cp.wait()
Using a progress wrapper (using clint.textui.progress.Bar) and read byte by byte (works for me):
profile = ["HandBrakeCLI","-i",input,"-o","output","-e","x264"]
cp = subprocess.Popen(profile, stderr=subprocess.PIPE, strout=subprocess.PIPE, close_fds=True)
bar = Bar(label="Encoding %s" % input, width=30, expected_size=10000, every=1)
bar.show(0)
line = ""
c = 0
while True:
nl = cp.stdout.read(1)
if nl == '' and cp.poll() is not None:
break # Aborted, no characters available, process died.
if nl == "\n":
line = ""
elif nl == "\r":
# regex match for % complete and ETA, assuming the regex is ok.
matches = re.match( r'.*(\d+\.\d+)\s%.*ETA\s(\d+)h(\d+)m(\d+)s', line.decode('utf-8') )
if matches:
print( matches.group() )
# do something
line = ""
else:
line += nl
error = cp.stderr.read()
success = "Encode done!" in error
Did not test the code, rewrote it to match the threads initial post.
Hope that helps.
来源:https://stackoverflow.com/questions/37925840/python-monitoring-progress-of-handbrake