防止ffmpeg接管stdout

时间:2011-02-15 21:37:39

标签: ruby-on-rails ruby multithreading ffmpeg fiber

当我做system "ffmpeg -i just-do-it.mp4 -ab 96k -ar 22050 -qscale 6 output.flv" ffmpeg接管ruby过程直到工作完成,这有时需要很长时间。我已经尝试在Ruby中使用线程amd fork无济于事,system等效命令如exec %x[]我也在ruby 1.9.2中尝试了最新的Fibers,但我没有我认为我正在使用它。

我的问题是如何同时从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

2 个答案:

答案 0 :(得分:3)

fork/exec是正确的解决方案。由于分叉进程继承父进程fopen文件句柄/等,你必须关闭(或重定向)你不希望子进程使用的文件句柄。

例如:

# 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")

答案 1 :(得分:0)

尝试子进程gem - 这就是我现在用来处理进程分叉并发现它更容易使用的东西。

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