2016-06-20 84 views
0

所以我使用手剎和python根據時間表對視頻進行編碼。我需要監視進度,因爲我用它來估計編碼時間。然後我可以把它放到我的調度程序中。Python監控Handbrake的進度

我有一個問題,從過程中獲取ETA和%完成。這是我到目前爲止

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() 

它不匹配,實際上我不完全確定發生了什麼事情。當我運行我的腳本時,我看到ETA和%完成打印

Encoding: task 1 of 1, 1.19 % (45.57 fps, avg 62.74 fps, ETA 00h08m01s) 

我試過使用stdout,但它也不起作用。

+0

我很確定問題在於Handbrake CLI在每次進程進展一點時都不會輸出新的附加行,而是會修改現有的行。嘗試在'inter for inter..'之後立即打印這行,看看它實際上給了你什麼。 – advance512

+0

不會在for循環結束後給我輸出嗎?所以當這個過程結束時呢?隨着過程的進行,我希望獲得這些信息。 –

+0

首先,你正在迭代stderr,也許你需要迭代stdout。其次,我認爲cp.stderr.readline會從子進程本身返回完整的行,而不是一個重複更新的行。在'handbreak'過程結束後,我會打印最後一行,以查看它的外觀。而且,正如我告訴過你的,我會在for循環中打印每一行,以瞭解我實際收到的內容。迭代stdout的 – advance512

回答

0

您需要從stdout中讀取,而不是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() 

使用進度包裝(使用clint.textui.progress.Bar)和字節讀取字節(爲我的作品):

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 

沒有測試代碼,重寫了它匹配線程初始職位。

希望有所幫助。