2016-09-22 252 views
0

我需要運行一個ffmpeg命令來創建一個視頻圖像之間的交叉淡入淡出作爲過渡。該命令源自此post。我需要通過Golang os/exec包來運行它。我需要運行的命令是:通過Golang運行FFMPEG命令執行

ffmpeg -loop 1 -t 5 -i img-0.png -loop 1 -t 5 -i img-1.png -loop 1 -t 5 -i img-2.png -filter_complex "[1:v][0:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b1v];[2:v][1:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b2v];[0:v][b1v][1:v][b2v][2:v]concat=n=5:v=1:a=0,format=yuv420p[v]" -map '[v]' -c:v libx264 -pix_fmt yuv420p -r 30 -s 1280x720 -aspect 16:9 -crf 1 -preset ultrafast output.mp4 

如果您直接在終端中運行此命令,它工作得很好。但是,它不通過我的代碼工作。這是我的代碼,需要一個字符串命令,並運行它通過os/exec包:

command := "ffmpeg -loop 1 -t 5 -i img-0.png -loop 1 -t 5 -i img-1.png -loop 1 -t 5 -i img-2.png -filter_complex "[1:v][0:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b1v];[2:v][1:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b2v];[0:v][b1v][1:v][b2v][2:v]concat=n=5:v=1:a=0,format=yuv420p[v]" -map '[v]' -c:v libx264 -pix_fmt yuv420p -r 30 -s 1280x720 -aspect 16:9 -crf 1 -preset ultrafast output.mp4" 

lastQuote := rune(0) 
f := func(c rune) bool { 
    switch { 
    case c == lastQuote: 
     lastQuote = rune(0) 
     return false 
    case lastQuote != rune(0): 
     return false 
    case unicode.In(c, unicode.Quotation_Mark): 
     lastQuote = c 
     return false 
    default: 
     return unicode.IsSpace(c) 
    } 
} 
parts := strings.FieldsFunc(command, f) 

cmd := exec.Command(parts[0], parts[1:]...) 
cmd.Stderr = os.Stderr 
cmd.Stdout = os.Stdout 

err := cmd.Run() 
if err != nil { 
    return err 
} 

當我運行它,我得到的ffmpeg錯誤:沒有這樣的過濾器:「」「,錯誤配置過濾器的,我知道它有事情做與必須在視頻濾鏡的報價,但我想盡一切辦法得到它的工作,我無法弄清楚。

任何幫助,不勝感激!

+0

您的字段func不會刪除封閉的引號。爲什麼不使用正確執行它的包,或者只是將字符串傳遞給一個shell來執行,而不是試圖從shell輸入中獲取內容? – JimB

+0

我試圖運行沒有圍繞過濾器複雜的封閉引號的命令,因爲即使是從終端直接工作,但我得到這個錯誤:缺少')'或'過多的參數'(T' [AVFilterGraph @ 0x3b94ee0 ]錯誤初始化過濾器'混合'與參數'all_expr = A *(if(gte(T' 錯誤配置過濾器。 –

+1

是的我不確定你想要完成這個開關,但我的感覺是,你應該沒有這些,只需傳遞「ffmpeg」作爲第一個參數,然後使用反引號讓你創建字符串文字(在這裏不能這樣做,因爲標記使它成爲代碼片段),所以你可以保留必要的引號在命令中將ffmpeg後面的所有內容作爲一個單獨的字符串傳遞,而不是將它分開,並試圖用'parts [1:] ...'傳播數組。我認爲除非你真的需要,否則你只是做了更多的工作需要微調那些參數。 – evanmcdonnal

回答

2

這實際上確實工作正常:

exec.Command("ffmpeg", "-loop", "1", "-t", "5", "-i", "img-0.png", "-loop", "1", "-t", "5", "-i", "img-1.png", "-loop", "1", "-t", "5", "-i", "img-2.png", "-filter_complex", "[1:v][0:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b1v];[2:v][1:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b2v];[0:v][b1v][1:v][b2v][2:v]concat=n=5:v=1:a=0,format=yuv420p[v]", "-map", "[v]", "-c:v", "libx264", "-pix_fmt", "yuv420p", "-r", "30", "-s", "1280x720", "-aspect", "16:9", "-crf", "1", "-preset", "ultrafast", "output.mp4") 

請注意,我確實刪除了-filter_complex參數中的開始和結束雙引號以及-map參數中的兩個單引號。

雖然手動,但不知道strings函數可以做到這一點自動

+0

謝謝你的幫助。 –