Module: Ffmprb::Util
- Defined in:
- lib/ffmprb/util.rb,
lib/ffmprb/util/thread.rb,
lib/ffmprb/util/proc_vis.rb,
lib/ffmprb/util/threaded_io_buffer.rb
Defined Under Namespace
Modules: ProcVis Classes: BrokenPipeError, Reader, Thread, ThreadedIoBuffer, TimeLimitError
Class Attribute Summary collapse
-
.cmd_timeout ⇒ Object
Returns the value of attribute cmd_timeout.
-
.ffmpeg_cmd ⇒ Object
Returns the value of attribute ffmpeg_cmd.
-
.ffmpeg_inputs_max ⇒ Object
Returns the value of attribute ffmpeg_inputs_max.
-
.ffprobe_cmd ⇒ Object
Returns the value of attribute ffprobe_cmd.
Class Method Summary collapse
- .assert_options_empty!(opts) ⇒ Object
-
.ffmpeg(*args, limit: nil, timeout: cmd_timeout, ignore_broken_pipes: true) ⇒ Object
TODO warn on broken pipes incompatibility with 4.x or something.
- .ffprobe(*args, limit: nil, timeout: cmd_timeout) ⇒ Object
- .sh(*cmd, input: nil, output: :stdout, limit: nil, timeout: cmd_timeout, ignore_broken_pipes: false) ⇒ Object
Class Attribute Details
.cmd_timeout ⇒ Object
Returns the value of attribute cmd_timeout.
15 16 17 |
# File 'lib/ffmprb/util.rb', line 15 def cmd_timeout @cmd_timeout end |
.ffmpeg_cmd ⇒ Object
Returns the value of attribute ffmpeg_cmd.
14 15 16 |
# File 'lib/ffmprb/util.rb', line 14 def ffmpeg_cmd @ffmpeg_cmd end |
.ffmpeg_inputs_max ⇒ Object
Returns the value of attribute ffmpeg_inputs_max.
14 15 16 |
# File 'lib/ffmprb/util.rb', line 14 def ffmpeg_inputs_max @ffmpeg_inputs_max end |
.ffprobe_cmd ⇒ Object
Returns the value of attribute ffprobe_cmd.
14 15 16 |
# File 'lib/ffmprb/util.rb', line 14 def ffprobe_cmd @ffprobe_cmd end |
Class Method Details
.assert_options_empty!(opts) ⇒ Object
73 74 75 |
# File 'lib/ffmprb/util.rb', line 73 def (opts) fail ArgumentError, "Unknown options: #{opts}" unless opts.empty? end |
.ffmpeg(*args, limit: nil, timeout: cmd_timeout, ignore_broken_pipes: true) ⇒ Object
TODO warn on broken pipes incompatibility with 4.x or something
22 23 24 25 26 |
# File 'lib/ffmprb/util.rb', line 22 def ffmpeg(*args, limit: nil, timeout: cmd_timeout, ignore_broken_pipes: true) args = ['-loglevel', 'debug'] + args if Ffmprb.ffmpeg_debug sh *ffmpeg_cmd, *args, output: :stderr, limit: limit, timeout: timeout, ignore_broken_pipes: ignore_broken_pipes end |
.ffprobe(*args, limit: nil, timeout: cmd_timeout) ⇒ Object
17 18 19 |
# File 'lib/ffmprb/util.rb', line 17 def ffprobe(*args, limit: nil, timeout: cmd_timeout) sh *ffprobe_cmd, *args, limit: limit, timeout: timeout end |
.sh(*cmd, input: nil, output: :stdout, limit: nil, timeout: cmd_timeout, ignore_broken_pipes: false) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/ffmprb/util.rb', line 28 def sh(*cmd, input: nil, output: :stdout, limit: nil, timeout: cmd_timeout, ignore_broken_pipes: false) cmd = cmd.map &:to_s unless cmd.size == 1 cmd_str = cmd.size != 1 ? cmd.map{|c| sh_escape c}.join(' ') : cmd.first timeout = [timeout, limit].compact.min thr = Thread.new "`#{cmd_str}`" do Ffmprb.logger.info "Popening `#{cmd_str}`..." Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thr| begin stdin.write input if input stdin.close log_cmd = cmd.first.upcase stdout_r = Reader.new(stdout, store: output == :stdout, log_with: log_cmd) stderr_r = Reader.new(stderr, store: true, log_with: log_cmd, log_as: output == :stderr && Logger::DEBUG || Logger::INFO) Thread.timeout_or_live(limit, log: "while waiting for `#{cmd_str}`", timeout: timeout) do |time| value = wait_thr.value status = value.exitstatus # NOTE blocking if status != 0 if value.signaled? && value.termsig == Signal.list['PIPE'] # TODO! this doesn't seem to work for ffmpeg 4.x (it ignores SIGPIPEs) if ignore_broken_pipes Ffmprb.logger.info "Ignoring broken pipe: #{cmd_str}" else fail BrokenPipeError, cmd_str end else status ||= "sig##{value.termsig}" fail Error, "#{cmd_str} (#{status}):\n#{stderr_r.read}" end end end Ffmprb.logger.debug{"FINISHED: #{cmd_str}"} Thread.join_children! limit, timeout: timeout # NOTE only one of them will return non-nil, see above stdout_r.read || stderr_r.read ensure process_dead! wait_thr, cmd_str, limit end end end thr.value end |