Предотвратить 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