2014-09-21 332 views
2

我一直在我的程序中納入子進程調用。我曾與子呼籲其他命令沒有任何問題,但我有麻煩在命令行中輸入子進程調用ffmpeg(命令行)

ffmpeg -r 10 -i frame%03d.png -r ntsc movie.mpg 

要將subprocess.call()

我嘗試沒有成功下列內工作:

subprocess.call('ffmpeg -r 10 -i %s frame%03.d.png - r ntsc movie.mpg') 

有什麼想法?我分離出不同的命令,我是否指定字符串,整數等與%s,%d

+1

運行命令,但每個參數列表中分裂出來。如果你把它作爲一個單一的字符串,那麼你將不得不指定'shell = True',你可能不想這麼做。所以,假設你的命令是作爲變量'cmd'構建的,運行'subprocess.call(cmd.split())'並等待魔術。 – sberry 2014-09-21 02:55:42

+0

什麼是錯誤? shell = True可以解決它。 – tdelaney 2014-09-21 02:58:01

+0

謝謝,是的,shell = True可以讓我將這些命令作爲一個大字符串來運行,但是我也很好奇如果使用變量名替換'movie.mpg',它的語法也是如此。 – user3295674 2014-09-21 03:57:56

回答

6

我發現了這個選擇,簡單,答案也工作。

subprocess.call('ffmpeg -r 10 -i frame%03d.png -r ntsc '+str(out_movie), shell=True) 
+0

噢,不錯。但爲什麼'str(out_movie)'?是不是'out_movie'已經是一個字符串? – 2014-09-22 04:47:04

+0

正確,這是多餘的。 :)但這種方法給出了一個乾淨的答案。 – user3295674 2014-09-22 17:36:03

8

當您使用子進程時,您的命令必須是一個與您在命令行中鍵入的內容完全相同的字符串(並且您設置了shell = True),或者每個命令都是列表中的項目並且您將默認shell = False)。無論哪種情況,您都必須處理字符串的可變部分。例如,操作系統不知道「%03d」是什麼,你必須填寫它。

我不能確切地告訴你的問題到底是什麼參數,但讓我們假設你想轉換幀3 ,它看起來像這樣一個字符串:

my_frame = 3 
subprocess.call(
    'ffmpeg -r 10 -i frame%03d.png -r ntsc movie%03d.mpg' % (my_frame, my_frame), 
    shell=True) 

它在這個例子中有點微妙,但這是有風險的。假設這些東西位於名稱中有空格的目錄中(例如./我的電影/恐怖電影)。殼會被這些空間所困惑。

所以,你可以把它變成一個列表,並避免該問題

my_frame = 3 
subprocess.call(['ffmpeg', '-r', '10', '-i', 'frame%03d.png' % my_frame, 
    ['-r', 'ntsc', 'movie%03d.mpg' % my_frame]) 

更打字,但更安全。

+0

謝謝。我有一個問題,對於「框架」部分,我希望它以格式框###。png將目錄中的文件放在一起,而不僅僅是一幀。我應該爲一個名爲'frame * .png'的字符串創建一個變量嗎? – user3295674 2014-09-21 18:21:25

+1

請注意,[ffmpeg](https://www.ffmpeg.org/ffmpeg-formats.html#Examples)本身可以解釋文件名規範中的'%03d'語法。 – 2014-09-21 18:22:06

+0

@ PM2Ring這就是我的想法,但它告訴我'沒有像%03d.png這樣的文件'想法? – user3295674 2014-09-21 18:35:53

0

'ffmpeg -r 10 -i frame%03d.png -r ntsc movie.mpg'應該沒問題。 OTOH,如果你不需要frame%03d.png的力量,frame*.png更簡單一點。

如果你想「看到它的語法,如果我取代‘movie.mpg’用一個變量名」,它看起來是這樣的:

cmd = 'ffmpeg -r 10 -i "frame%%03d.png" -r ntsc "%s"' % moviename

我們需要躲避%與額外的%可以將其隱藏在Python的%替換機器中。我還添加了雙引號",以解決tdelaney提到的問題。

+0

'frame%03d.png'不能有任何空格問題。使用引號在這裏是沒用的。使用'pipes.quote(moviename)'代替'%s''。 – jfs 2014-09-22 07:32:09

+0

@JFSebastian:沒錯,這裏沒有空白問題,我只是把這些引號放在作爲未來參考的一般示例。 OTOH,我同意我所說的關於在我最後的評論中引用tdelaney的帖子的內容沒有幫助;我應該知道比在上午5點發布更好。 :)但是我不知道'pipes.quote',所以非常感謝(雖然我在文檔中看到它已經在Python 3中被棄用了)。 – 2014-09-22 08:01:30

+1

沒有[tag:python-3.x]標記,因此我使用'pipes.quote'而不是'shlex.quote'名稱(它是相同的函數)。 – jfs 2014-09-22 08:08:45

1
import shlex 
import pipes 
from subprocess import check_call 

command = 'ffmpeg -r 10 -i frame%03d.png -r ntsc ' + pipes.quote(out_movie) 
check_call(shlex.split(command))