Предотвратить ffmpeg от захвата stdout

Когда я делаю system "ffmpeg -i just-do-it.mp4 -ab 96k -ar 22050 -qscale 6 output.flv" ffmpeg берет на себя процесс ruby, пока работа не будет выполнена, что иногда занимает много времени. Я пытался использовать нити amd fork в Ruby, но безрезультатно system эквивалентные команды, такие как exec%x[] Я также попробовал последние версии Fibers в ruby ​​1.9.2, но не думаю, что использую их правильно.

Мой вопрос, как запустить два процесса ffmpeg из ruby ​​одновременно?

РЕДАКТИРОВАТЬ:

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 ответа

Решение

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

Попробуйте использовать гем подпроцесса - это то, что я сейчас использую, чтобы справиться с разветвлением процессов и найти его намного более простым в использовании.

Например

    work_list.each do |cmd|
        process = Subprocess::Popen.new(cmd)
        process.run
        process.wait
        #puts process.stdout
        #puts process.stderr
        puts process.status
    end
Другие вопросы по тегам