2011-02-15 44 views
0

当我做system "ffmpeg -i just-do-it.mp4 -ab 96k -ar 22050 -qscale 6 output.flv" ffmpeg接管了ruby进程直到完成作业,这有时需要很长时间。我试过使用线程和红宝石叉无济于事,也system等效命令,如exec%x[]我也尝试了红宝石1.9.2最新的光纤,但我不认为我正确使用它。防止ffmpeg接管stdout

我的问题是如何从ruby同时运行两个ffmpeg进程?

编辑:

fork do 
    fork do 
    system "ffmpeg -i you-know.mp4 -ab 96k -ar 22050 -qscale 6 #{Time.now.sec}.flv" 
    end        

    fork do 
    system "ffmpeg -i bangbang.mp4 -ab 96k -ar 22050 -qscale 6 #{Time.now.sec}.flv" 
    end 
end 

回答

3

fork/exec是正确的解决方案。由于分叉进程会继承父进程fopen文件句柄/ etc,因此您必须关闭(或重定向)您不想让子进程使用的文件句柄。

例如:

# this will print nothing, but yes is running as a forked process 
# you'll want to `killall yes` after running this script. 
fork do 
    [$stdout, $stderr].each { |fh| fh.reopen File.open("/dev/null", "w") } 
    exec "yes" 
end 

好吧,你贴在代码一些意见。外面的fork是毫无意义的。只需从主进程中分离出两个ffmpeg进程即可。也许写这样一个辅助函数:

def ffmpeg(mp4) 
    fork do 
    [$stdout, $stderr].each { ... } 
    exec "ffmpeg -i #{mp4} ..." 
    end 
end 

ffmpeg("you-know.mp4") 
ffmpeg("bangbang.mp4") 
+0

我添加了上面的fork代码,但那不起作用,显然我错过了一些东西,你能帮忙吗?谢谢! –

+0

@Senthil,不要使用'system'(这只是分支/放弃/等待),使用'exec'。请记住重定向STDOUT/STDERR /等。请参阅上面的示例代码片段。 – cam

+0

非常感谢!尽管“是”似乎已经失去了动力,并且正在使用96%的cpu进程。也许我没有正确关闭它,但ffmpeg现在正在运行,所以这很好。 –

0

尝试子宝石 - 这就是我现在使用与过程分叉处理,并发现它更容易使用的东西。

E.g.

work_list.each do |cmd| 
     process = Subprocess::Popen.new(cmd) 
     process.run 
     process.wait 
     #puts process.stdout 
     #puts process.stderr 
     puts process.status 
    end