2016-09-22 250 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

谢谢你的帮助。 –