2011-09-10 52 views
3

我有以下命令:轉換複雜的命令到蟒子

$ ffmpeg -i http://url/1video.mp4 2>&1 | perl -lane 'print $1 if /(\d+x\d+)/' 
640x360 

我想這個命令的輸出設置成Python變量。以下是我迄今爲止:

>>> from subprocess import Popen, PIPE 
>>> p1 = Popen(['ffmpeg', '-i', 'http://url/1video.mp4', '2>&1'], stdout=PIPE) 
>>> p2=Popen(['perl','-lane','print $1 if /(\d+x\d+)/'], stdin=p1.stdout, stdout=PIPE) 
>>> dimensions = p2.communicate()[0] 
'' 

我在做什麼錯誤在這裏,我怎麼會得到維度正確的價值?

+0

我不知道Perl,但我敢打賭,你也可以在Python中做到這一點,而不會產生perl解釋器。對於一個解決方案,嘗試刪除'2>&1' – utdemir

回答

3

一般情況下,你可以用這個模式replace a shell pipeline

p1 = Popen(["dmesg"], stdout=PIPE) 
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) 
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. 
output = p2.communicate()[0] 

然而,在這種情況下,沒有管道是必要的:

import subprocess 
import shlex 
import re 
url='http://url/1video.mp4' 
proc=subprocess.Popen(shlex.split('ffmpeg -i {f}'.format(f=url)), 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE) 
dimensions=None 
for line in proc.stderr: 
    match=re.search(r'(\d+x\d+)',line) 
    if match: 
     dimensions=match.group(1) 
     break 
print(dimensions) 
+1

好!也許添加一個鏈接到[docs.python.org](http://docs.python.org/library/subprocess.html#using-the-subprocess-module)描述shlex-trick的地方? –

+0

非常好,謝謝。 – David542

3

無需調用perl從蟒之內。

如果從ffmpeg的一個變量的輸出,你可以做這樣的事情:

print re.search(r'(\d+x\d+)', str).group() 
0

注「殼」的說法來subprocess.Popen:此指定是否要通過命令被解析該殼或不。 「2> & 1」是需要由shell解析的那些東西之一,否則FFmpeg(像大多數程序)會嘗試將它視爲文件名或選項值。

最接近地模擬原來的很可能是

Python的序列更像

P1 = subprocess.Popen( 「FFMPEG -i http://url/1video.mp4 2> & 1」,殼=真,標準輸出= subprocess.PIPE)
p2 = subprocess.Popen(r「perl -lane'print $ 1 if /(\ d + x \ d +)/'」,shell = True,stdin = p1.stdout,stdout = subprocess.PIPE)
dimensions = p2 .communicate()[0]