2017-07-26 156 views
1

我在我的Java程序運行一個命令調用java.lang.Runtime.exec(...)工作(一些FFMPEG命令)簡單地傳遞給我的功能:的Java執行命令不代碼

private static void RunCommand(String command) throws InterruptedException { 
     try { 
      // Execute command 
      Process proc = Runtime.getRuntime().exec(command); 
} 
} 

它適用於簡單的FFMPEG情況,如ffmpeg -i input.avi -c copy output.avi

但是對於其中一個命令,顯然它不運行。當我在命令行中複製/粘貼確切的字符串時,我可以運行它並查看輸出文件。

ffmpeg -i "concat:/home/temp10.avi|/home/p2.avi|/home/temp15.avi" -c copy -y /home/output.avi 

這是下面的代碼:

String c4="ffmpeg -i \"concat:"+dir+temp1+"|"+dir+ad+"|"+dir+temp3+"\" -c copy -y "+dir+output; 

這是怎麼回事?任何猜測爲什麼它不能在代碼中運行?如果"導致問題,爲什麼相應的字符串看起來不錯?!

+1

它在我看來像這個exec函數不會執行shell風格的引用,只是簡單地分割空白,所以你應該能夠通過刪除引號來修復它。如果文件名可能包含空格,則需要傳遞一個String數組來代替exec。 –

+0

你的意思是我應該刪除引號嗎? – Ariana

+0

哇!你是對的。 '''''''解決了這個問題,也許你想描述它,並且我將你標記爲最佳答案? – Ariana

回答

3

怎麼寫,它的命令:當shell中運行

ffmpeg -i "concat:/home/temp10.avi|/home/p2.avi|/home/temp15.avi" -c copy -y /home/output.avi 

作品。引號是shell語法的一部分,而不是ffmpeg語法的一部分。引用是必要的,因爲|字符會導致shell在沒有引用的情況下構建管道。當它被引用時,它只是傳遞給ffmpeg。

你想用java Runtime exec函數完成同樣的事情,但exec不是一個shell。它不會執行管道,重定向,引用或替換。它將字符串拆分爲空白字符串,並將結果字符串數組與unix execvp等效。

由於exec不會對|字符做任何特殊處理,所以不需要引用。你把這個字符串傳給exec來完成同樣的事情,上面的shell命令應該只是

ffmpeg -i concat:/home/temp10.avi|/home/p2.avi|/home/temp15.avi -c copy -y /home/output.avi 

有可能會碰到根據文件名的併發症。假設你的shell命令是這樣的:

ffmpeg -i "concat:/home/temp 10.avi|/home/p2.avi|/home/temp15.avi" -c copy -y /home/output.avi 

(區別:第一個文件名temp 10.avi在它有一個空格)。現在是我們2個目的引用:防止|從創建一個管道,並防止空間分裂論點。如果你試試這個傳遞給exec去掉引號,它不會工作,因爲該字符串將被分割,產生這種陣列的參數:

-i 
concat:/home/temp 
10.avi|/home/p2.avi|/home/temp15.avi 
-c 
copy 
-y 
/home/output.avi 

這不是想要的ffmpeg的;它想要包含完整輸入規範的-i之後的單個字符串。你必須自己做分割字符串的工作,這樣你就可以離開這個空間的說法,這樣的:

Runtime.getRuntime().exec(
    new String[] { 
    "ffmpeg", 
    "-i", 
    "concat:/home/temp 10.avi|/home/p2.avi|/home/temp15.avi", 
    "-c", 
    "copy", 
    "-y", 
    "/home/output.avi" 
    } 
) 

在評論下面的例子看起來像

Runtime.getRuntime().exec(
    new String[] { 
    "ffmpeg", 
    "-i", 
    "sample.mp4", 
    "-i", 
    "ad.mp4", 
    "-filter_complex", 
    "[0:v]trim=0:15,setpts=PTS-STARTPTS[v0]; [1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; [0:v]trim=20:30,setpts=PTS-STARTPTS[v2]; [v0][v1][v2]concat=n=3:v=1:a=0[out]", 
    "-map", 
    "[out]", 
    "output.mp4" 
    } 
) 

-filter_complex之後的字符串是單個參數,因爲它在命令的shell版本中引用。它沒有任何字符在shell中的""之間,而在Java中的""之間沒有特殊字符,所以它可以不加修改地工作。

+0

運行此命令時遇到困難,你能幫我嗎?'ffmpeg -i sample.mp4 -i ad.mp4 - filter_complex「[0:v] trim = 0:15,setpts = PTS-STARTPTS [v0]; [1:V]修剪= 0:5,setpts = PTS-STARTPTS [V1]; [0:V]修剪= 20:30,setpts = PTS-STARTPTS [V2]; [v0] [v1] [v2] concat = n = 3:v = 1:a = 0 [out]「-map」[out]「output.mp4' – Ariana