2016-12-04 73 views
2

用下面的代碼,我可以使用Python,NumPy的和FFmpeg的二進制文件FFMPEG視頻的管框架:管道與Python子進程FFmpeg的凍結

from __future__ import print_function 
import subprocess 
import numpy as np 
import sys 

npshape = [480, 480] 
cmd_out = ['ffmpeg', 
      '-y', # (optional) overwrite output file if it exists 
      '-f', 'rawvideo', 
      '-vcodec','rawvideo', 
      '-s', '%dx%d'%(npshape[1], npshape[0]), # size of one frame 
      '-pix_fmt', 'rgb24', 
      '-r', '24', # frames per second 
      '-i', '-', # The input comes from a pipe 
      '-an', # Tells FFMPEG not to expect any audio 
      '-vcodec', 'mpeg4', 
      'output.mp4'] 

fout = subprocess.Popen(cmd_out, stdin=subprocess.PIPE, stderr=subprocess.PIPE).stdin 

for i in range(24*40): 
    if i%(24)==0: 
     print('%d'%(i/24), end=' ') 
     sys.stdout.flush() 

    fout.write((np.random.random(npshape[0]*npshape[1]*3)*128).astype('uint8').tostring()) 

fout.close() 

,如果我寫的東西少也能正常工作價值超過37秒的框架,但如果我嘗試寫更多東西,代碼就會掛起。這種行爲的根本原因是什麼?我該如何解決它?

+0

要告訴:'STDERR = subprocess.PIPE',則忽略它完全是一個災難。 –

回答

2

一個很可能的罪魁禍首是令人討厭的臭subprocess.Popen線。不僅你忽略了它的返回值 - 你永遠不會這樣做,爲了確保子進程完成某個點和/或檢查它的退出代碼 - 你還使stderr成爲一個管道,但從未讀過 - 所以這個過程必須掛起當它的緩衝區填滿時。

這應該修復它:

p = subprocess.Popen(cmd_out, stdin=subprocess.PIPE) 
fout = p.stdin 

<...> 

fout.close() 
p.wait() 
if p.returncode !=0: raise subprocess.CalledProcessError(p.returncode,cmd_out) 
+1

感謝它的工作!從現在開始,這將是我處理Python管道的標準方式。 –