ffmprb 0.11.3 → 0.11.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +12 -0
  3. data/Gemfile +8 -1
  4. data/Gemfile.lock +121 -0
  5. data/README.md +10 -8
  6. data/TODO.md +1 -0
  7. data/bin/test +7 -0
  8. data/coverage/assets/0.10.0/application.css +799 -0
  9. data/coverage/assets/0.10.0/application.js +1707 -0
  10. data/coverage/assets/0.10.0/colorbox/border.png +0 -0
  11. data/coverage/assets/0.10.0/colorbox/controls.png +0 -0
  12. data/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
  13. data/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
  14. data/coverage/assets/0.10.0/favicon_green.png +0 -0
  15. data/coverage/assets/0.10.0/favicon_red.png +0 -0
  16. data/coverage/assets/0.10.0/favicon_yellow.png +0 -0
  17. data/coverage/assets/0.10.0/loading.gif +0 -0
  18. data/coverage/assets/0.10.0/magnify.png +0 -0
  19. data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  20. data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  21. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  22. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  23. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  24. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  25. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  26. data/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  27. data/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
  28. data/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  29. data/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
  30. data/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
  31. data/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  32. data/coverage/assets/0.10.2/application.css +799 -0
  33. data/coverage/assets/0.10.2/application.js +1707 -0
  34. data/coverage/assets/0.10.2/colorbox/border.png +0 -0
  35. data/coverage/assets/0.10.2/colorbox/controls.png +0 -0
  36. data/coverage/assets/0.10.2/colorbox/loading.gif +0 -0
  37. data/coverage/assets/0.10.2/colorbox/loading_background.png +0 -0
  38. data/coverage/assets/0.10.2/favicon_green.png +0 -0
  39. data/coverage/assets/0.10.2/favicon_red.png +0 -0
  40. data/coverage/assets/0.10.2/favicon_yellow.png +0 -0
  41. data/coverage/assets/0.10.2/loading.gif +0 -0
  42. data/coverage/assets/0.10.2/magnify.png +0 -0
  43. data/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  44. data/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  45. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  46. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  47. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  48. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  49. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  50. data/coverage/assets/0.10.2/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  51. data/coverage/assets/0.10.2/smoothness/images/ui-icons_222222_256x240.png +0 -0
  52. data/coverage/assets/0.10.2/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  53. data/coverage/assets/0.10.2/smoothness/images/ui-icons_454545_256x240.png +0 -0
  54. data/coverage/assets/0.10.2/smoothness/images/ui-icons_888888_256x240.png +0 -0
  55. data/coverage/assets/0.10.2/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  56. data/coverage/assets/0.12.2/DataTables-1.10.20/images/sort_asc.png +0 -0
  57. data/coverage/assets/0.12.2/DataTables-1.10.20/images/sort_asc_disabled.png +0 -0
  58. data/coverage/assets/0.12.2/DataTables-1.10.20/images/sort_both.png +0 -0
  59. data/coverage/assets/0.12.2/DataTables-1.10.20/images/sort_desc.png +0 -0
  60. data/coverage/assets/0.12.2/DataTables-1.10.20/images/sort_desc_disabled.png +0 -0
  61. data/coverage/assets/0.12.2/application.css +1 -0
  62. data/coverage/assets/0.12.2/application.js +7 -0
  63. data/coverage/assets/0.12.2/colorbox/border.png +0 -0
  64. data/coverage/assets/0.12.2/colorbox/controls.png +0 -0
  65. data/coverage/assets/0.12.2/colorbox/loading.gif +0 -0
  66. data/coverage/assets/0.12.2/colorbox/loading_background.png +0 -0
  67. data/coverage/assets/0.12.2/favicon_green.png +0 -0
  68. data/coverage/assets/0.12.2/favicon_red.png +0 -0
  69. data/coverage/assets/0.12.2/favicon_yellow.png +0 -0
  70. data/coverage/assets/0.12.2/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  71. data/coverage/assets/0.12.2/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  72. data/coverage/assets/0.12.2/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  73. data/coverage/assets/0.12.2/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  74. data/coverage/assets/0.12.2/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  75. data/coverage/assets/0.12.2/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  76. data/coverage/assets/0.12.2/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  77. data/coverage/assets/0.12.2/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  78. data/coverage/assets/0.12.2/images/ui-icons_222222_256x240.png +0 -0
  79. data/coverage/assets/0.12.2/images/ui-icons_2e83ff_256x240.png +0 -0
  80. data/coverage/assets/0.12.2/images/ui-icons_454545_256x240.png +0 -0
  81. data/coverage/assets/0.12.2/images/ui-icons_888888_256x240.png +0 -0
  82. data/coverage/assets/0.12.2/images/ui-icons_cd0a0a_256x240.png +0 -0
  83. data/coverage/assets/0.12.2/loading.gif +0 -0
  84. data/coverage/assets/0.12.2/magnify.png +0 -0
  85. data/coverage/index.html +24412 -0
  86. data/ffmprb.gemspec +34 -14
  87. data/lib/defaults.rb +1 -1
  88. data/lib/ffmprb.rb +3 -3
  89. data/lib/ffmprb/file.rb +8 -8
  90. data/lib/ffmprb/file/sample.rb +2 -2
  91. data/lib/ffmprb/file/threaded_buffered.rb +3 -3
  92. data/lib/ffmprb/filter.rb +4 -1
  93. data/lib/ffmprb/find_silence.rb +5 -2
  94. data/lib/ffmprb/process.rb +5 -3
  95. data/lib/ffmprb/process/input.rb +1 -1
  96. data/lib/ffmprb/process/input/looping.rb +6 -11
  97. data/lib/ffmprb/process/output.rb +9 -6
  98. data/lib/ffmprb/util.rb +5 -3
  99. data/lib/ffmprb/util/proc_vis.rb +1 -1
  100. data/lib/ffmprb/util/thread.rb +6 -5
  101. data/lib/ffmprb/util/threaded_io_buffer.rb +20 -19
  102. data/lib/ffmprb/version.rb +2 -2
  103. data/tmp/output.rb +383 -0
  104. metadata +90 -138
  105. data/.gitignore +0 -10
  106. data/.rspec +0 -4
  107. data/.ruby-version +0 -1
  108. data/.travis.yml +0 -3
  109. data/circle.yml +0 -7
@@ -6,14 +6,43 @@ require 'ffmprb/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'ffmprb'
8
8
  spec.version = Ffmprb::VERSION
9
- spec.authors = ["showbox.com", "Costa Shapiro"]
9
+ spec.authors = ["Costa Shapiro"]
10
10
  spec.email = ['costa@mouldwarp.com']
11
11
 
12
- spec.summary = "ffmprb is your audio/video montage friend, based on https://ffmpeg.org"
12
+ spec.summary = "ffmprb is your audio/video manipulation pal, based on https://ffmpeg.org"
13
13
  spec.description = "A video and audio composing DSL (Damn-Simple Language) and a micro-engine for ffmpeg and ffriends"
14
14
  spec.homepage = Ffmprb::GEM_GITHUB_URL
15
15
 
16
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ def self.ignore_match(pattern, path)
17
+ path = '/' + path unless path =~ %r'^/'
18
+ if File.directory?(path)
19
+ path += '/' unless path =~ %r'/$'
20
+ end
21
+ if pattern.is_a?(Array)
22
+ pattern
23
+ else
24
+ [pattern]
25
+ end.any? do |pattern|
26
+ pattern = '**/' + pattern unless pattern =~ %r'^/'
27
+ pattern += '**' if pattern =~ %r'/$'
28
+ File.fnmatch(pattern, path)
29
+ end
30
+ end
31
+
32
+ pattern =
33
+ if (ignore_pattern_lines = File.readlines('.gemignore') rescue nil)
34
+ ignore_pattern_lines.map do |line|
35
+ stripped = line.split(/(?<!\\)#/)[0].strip
36
+ stripped unless stripped.empty?
37
+ end.compact
38
+ else
39
+ %w[test/ spec/ features/]
40
+ end
41
+
42
+ # NOTE dotfiles are ignored by .glob
43
+ spec.files = Dir['**/*'].reject{|path| ignore_match pattern, path}
44
+ # TODO:rm spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
45
+
17
46
  spec.bindir = 'exe'
18
47
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
48
  spec.require_paths = ['lib']
@@ -23,15 +52,6 @@ Gem::Specification.new do |spec|
23
52
  # NOTE make it into an optional dependency? Nah for now
24
53
  spec.add_dependency 'thor', '~> 0.19.1'
25
54
 
26
- spec.add_development_dependency 'bundler', '>= 1.11.2'
27
- spec.add_development_dependency 'byebug', '>= 8.2.4'
28
- spec.add_development_dependency 'simplecov', '>= 0.11.2'
29
- spec.add_development_dependency 'guard-rspec', '>= 4.6.5'
30
- spec.add_development_dependency 'guard-bundler', '>= 2.1.0'
31
- spec.add_development_dependency 'rake', '>= 11.1.2'
32
- spec.add_development_dependency 'rmagick', '>= 2.15.4'
33
- spec.add_development_dependency 'ruby-sox', '>= 0.0.3'
34
- spec.add_development_dependency 'firebase', '>= 0.2.6'
35
-
36
- spec.post_install_message = "Have fun with your montage! To enable proc visualisation, install firebase gem and set FFMPRB_PROC_VIS_FIREBASE env." unless Ffmprb::FIREBASE_AVAILABLE
55
+ spec.post_install_message = "Have fun with your a/v! To enable proc visualisation, install firebase gem and set FFMPRB_PROC_VIS_FIREBASE env." unless
56
+ Ffmprb::FIREBASE_AVAILABLE
37
57
  end
@@ -19,7 +19,7 @@ module Ffmprb
19
19
  Process.input_video_fps = nil # NOTE the documented ffmpeg default is 25
20
20
 
21
21
  Process.output_video_resolution = CGA
22
- Process.output_video_fps = 16
22
+ Process.output_video_fps = 16 # NOTE the documented ffmpeg default is 25
23
23
  Process.output_audio_encoder = 'libmp3lame'
24
24
  Process.output_audio_sampling_freq = nil # NOTE Use ffmpeg default by default, specify otherwise e.g. 44100
25
25
 
@@ -25,13 +25,13 @@ module Ffmprb
25
25
  name ||= blk.source_location.map(&:to_s).map{ |s| ::File.basename s.to_s, ::File.extname(s) }.join(':')
26
26
  process = Process.new(name: name, **opts)
27
27
  proc_vis_node process if respond_to? :proc_vis_node # XXX simply include the ProcVis if it makes into a gem
28
- logger.debug "Starting process with #{args} #{opts} in #{blk.source_location}"
28
+ logger.debug{"Starting process with #{args} #{opts} in #{blk.source_location}"}
29
29
 
30
30
  process.instance_exec *args, &blk
31
- logger.debug "Initialized process with #{args} #{opts} in #{blk.source_location}"
31
+ logger.debug{"Initialized process with #{args} #{opts} in #{blk.source_location}"}
32
32
 
33
33
  process.run.tap do
34
- logger.debug "Finished process with #{args} #{opts} in #{blk.source_location}"
34
+ logger.debug{"Finished process with #{args} #{opts} in #{blk.source_location}"}
35
35
  end
36
36
  end
37
37
  alias :action! :process # ;)
@@ -17,27 +17,27 @@ module Ffmprb
17
17
  ->{
18
18
  path = file.respond_to?(:path)? file.path : file
19
19
  mode ||= file.respond_to?(mode)? file.mode.to_s[0] : 'r'
20
- Ffmprb.logger.debug "Trying to open #{path} (for #{mode}-buffering or something)"
20
+ Ffmprb.logger.debug{"Trying to open #{path} (for #{mode}-buffering or something)"}
21
21
  ::File.open(path, mode)
22
22
  }
23
23
  end
24
24
 
25
25
  def create(path)
26
26
  new(path: path, mode: :write).tap do |file|
27
- Ffmprb.logger.debug "Created file with path: #{file.path}"
27
+ Ffmprb.logger.debug{"Created file with path: #{file.path}"}
28
28
  end
29
29
  end
30
30
 
31
31
  def open(path)
32
32
  new(path: path, mode: :read).tap do |file|
33
- Ffmprb.logger.debug "Opened file with path: #{file.path}"
33
+ Ffmprb.logger.debug{"Opened file with path: #{file.path}"}
34
34
  end
35
35
  end
36
36
 
37
37
  def temp(extname)
38
38
  file = create(Tempfile.new(['', extname]))
39
39
  path = file.path
40
- Ffmprb.logger.debug "Created temp file with path: #{path}"
40
+ Ffmprb.logger.debug{"Created temp file with path: #{path}"}
41
41
 
42
42
  return file unless block_given?
43
43
 
@@ -49,7 +49,7 @@ module Ffmprb
49
49
  rescue
50
50
  Ffmprb.logger.warn "#{$!.class.name} removing temp file with path #{path}: #{$!.message}"
51
51
  end
52
- Ffmprb.logger.debug "Removed temp file with path: #{path}"
52
+ Ffmprb.logger.debug{"Removed temp file with path: #{path}"}
53
53
  end
54
54
  end
55
55
 
@@ -69,12 +69,12 @@ module Ffmprb
69
69
  rescue
70
70
  Ffmprb.logger.warn "#{$!.class.name} removing temp file with path #{path}: #{$!.message}"
71
71
  end
72
- Ffmprb.logger.debug "Removed temp file with path: #{path}"
72
+ Ffmprb.logger.debug{"Removed temp file with path: #{path}"}
73
73
  end
74
74
  end
75
75
 
76
76
  def temp_fifo_path(extname)
77
- ::File.join Dir.tmpdir, Dir::Tmpname.make_tmpname('', 'p' + extname)
77
+ ::File.join Dir.tmpdir, "#{rand(2**222)}p#{extname}"
78
78
  end
79
79
 
80
80
  def image?(extname)
@@ -168,7 +168,7 @@ module Ffmprb
168
168
  else
169
169
  FileUtils.remove_entry path
170
170
  end
171
- Ffmprb.logger.debug "Removed file with path: #{path}"
171
+ Ffmprb.logger.debug{"Removed file with path: #{path}"}
172
172
  @path = nil
173
173
  end
174
174
 
@@ -11,7 +11,7 @@ module Ffmprb
11
11
  audio = File.temp('.wav') if audio == true
12
12
  video = File.temp('.png') if video == true
13
13
 
14
- Ffmprb.logger.debug "Snap shooting files, video path: #{video ? video.path : 'NONE'}, audio path: #{audio ? audio.path : 'NONE'}"
14
+ Ffmprb.logger.debug{"Snap shooting files, video path: #{video ? video.path : 'NONE'}, audio path: #{audio ? audio.path : 'NONE'}"}
15
15
 
16
16
  fail Error, "Incorrect output extname (must be image)" unless !video || video.channel?(:video) && !video.channel?(:audio)
17
17
  fail Error, "Incorrect audio extname (must be sound)" unless !audio || audio.channel?(:audio) && !audio.channel?(:video)
@@ -30,7 +30,7 @@ module Ffmprb
30
30
  begin
31
31
  video.unlink if video
32
32
  audio.unlink if audio
33
- Ffmprb.logger.debug "Removed sample files"
33
+ Ffmprb.logger.debug{"Removed sample files"}
34
34
  rescue
35
35
  Ffmprb.logger.warn "#{$!.class.name} removing sample files: #{$!.message}"
36
36
  end
@@ -7,7 +7,7 @@ module Ffmprb
7
7
  def threaded_buffered_fifo(extname='.tmp', reader_open_on_writer_idle_limit: nil, proc_vis: nil)
8
8
  input_fifo_file = temp_fifo(extname)
9
9
  output_fifo_file = temp_fifo(extname)
10
- Ffmprb.logger.debug "Opening #{input_fifo_file.path}>#{output_fifo_file.path} for buffering"
10
+ Ffmprb.logger.debug{"Opening #{input_fifo_file.path}>#{output_fifo_file.path} for buffering"}
11
11
  Util::Thread.new do
12
12
  begin
13
13
  io_buff = Util::ThreadedIoBuffer.new(opener(input_fifo_file, 'r'), opener(output_fifo_file, 'w'), keep_outputs_open_on_input_idle_limit: reader_open_on_writer_idle_limit)
@@ -20,13 +20,13 @@ module Ffmprb
20
20
  ensure
21
21
  Util::Thread.join_children!
22
22
  end
23
- Ffmprb.logger.debug "IoBuffering from #{input_fifo_file.path} to #{output_fifo_file.path} ended"
23
+ Ffmprb.logger.debug{"IoBuffering from #{input_fifo_file.path} to #{output_fifo_file.path} ended"}
24
24
  ensure
25
25
  input_fifo_file.unlink if input_fifo_file
26
26
  output_fifo_file.unlink if output_fifo_file
27
27
  end
28
28
  end
29
- Ffmprb.logger.debug "IoBuffering from #{input_fifo_file.path} to #{output_fifo_file.path} started"
29
+ Ffmprb.logger.debug{"IoBuffering from #{input_fifo_file.path} to #{output_fifo_file.path} started"}
30
30
 
31
31
  [input_fifo_file, output_fifo_file]
32
32
  end
@@ -262,7 +262,10 @@ module Ffmprb
262
262
  end
263
263
 
264
264
  def complex_args(*filters)
265
- ['-filter_complex', filters.join('; ')] unless filters.empty?
265
+ [].tap do |args|
266
+ args << '-filter_complex' << filters.join('; ') unless
267
+ filters.empty?
268
+ end
266
269
  end
267
270
 
268
271
  private
@@ -5,7 +5,7 @@ module Ffmprb
5
5
  # NOTE not for streaming just yet
6
6
  def find_silence(input_file, output_file)
7
7
  path = "#{input_file.path}->#{output_file.path}"
8
- logger.debug "Finding silence (#{path})"
8
+ logger.debug{"Finding silence (#{path})"}
9
9
  silence = []
10
10
  Util.ffmpeg('-i', input_file.path, *find_silence_detect_args, output_file.path).
11
11
  scan(SILENCE_DETECT_REGEX).each do |mark, time|
@@ -25,7 +25,10 @@ module Ffmprb
25
25
  Ffmprb.warn "Unknown silence mark: #{mark}"
26
26
  end
27
27
  end
28
- logger.debug "Found silence (#{path}): [#{silence.map{|t,v| "#{t}: #{v}"}}]"
28
+ logger.debug{
29
+ silence_map = silence.map{|t,v| "#{t}: #{v}"}
30
+ "Found silence (#{path}): [#{silence_map}]"
31
+ }
29
32
  silence
30
33
  end
31
34
 
@@ -39,7 +39,7 @@ module Ffmprb
39
39
  def input_video_options
40
40
  {
41
41
  auto_rotate: input_video_auto_rotate,
42
- fps: input_video_fps
42
+ fps: input_video_fps # TODO seen failing on apng (w/ffmpeg v4.x)
43
43
  }
44
44
  end
45
45
  def input_audio_options
@@ -97,7 +97,10 @@ module Ffmprb
97
97
  end
98
98
  overlay in_over.volume ducked_overlay_volume
99
99
 
100
- Ffmprb.logger.debug "Ducking audio with volumes: {#{ducked_overlay_volume.map{|t,v| "#{t}: #{v}"}.join ', '}}"
100
+ Ffmprb.logger.debug{
101
+ ducked_overlay_volume_map = ducked_overlay_volume.map{|t,v| "#{t}: #{v}"}
102
+ "Ducking audio with volumes: {#{ducked_overlay_volume_map.join ', '}}"
103
+ }
101
104
  end
102
105
 
103
106
  end
@@ -157,7 +160,6 @@ module Ffmprb
157
160
  thr = Util::Thread.new main: !parent do
158
161
  proc_vis_node Thread.current
159
162
  # NOTE yes, an exception can occur anytime, and we'll just die, it's ok, see above
160
- # XXX just to return something -- no apparent practical use
161
163
  cmd = command
162
164
  opts = {limit: limit, timeout: timeout}
163
165
  opts[:ignore_broken_pipes] = ignore_broken_pipes unless ignore_broken_pipes.nil?
@@ -14,7 +14,7 @@ module Ffmprb
14
14
  end
15
15
  end
16
16
 
17
- # XXX check for unknown options
17
+ # TODO! check for unknown options
18
18
 
19
19
  def video_args(video=nil)
20
20
  video = Process.input_video_options.merge(video.to_h)
@@ -60,7 +60,7 @@ module Ffmprb
60
60
  end
61
61
  end
62
62
  cpy_io = File.temp_fifo(src_io.extname)
63
- Ffmprb.logger.debug "(L2) Temporising the raw input (#{src_io.path}) and creating copy (#{cpy_io.path})"
63
+ Ffmprb.logger.debug{"(L2) Temporising the raw input (#{src_io.path}) and creating copy (#{cpy_io.path})"}
64
64
 
65
65
  src_io.threaded_buffered_copy_to @raw.io, cpy_io
66
66
 
@@ -70,9 +70,8 @@ module Ffmprb
70
70
  @raw.process.proc_vis_node dst_io
71
71
 
72
72
  Util::Thread.new "looping input processor" do
73
- # Ffmprb.logger.debug "Processing before looping"
73
+ Ffmprb.logger.debug{"(L3) Pre-processing into (#{dst_io.path})"}
74
74
 
75
- Ffmprb.logger.debug "(L3) Pre-processing into (#{dst_io.path})"
76
75
  Ffmprb.process @_unfiltered, parent: @raw.process do |unfiltered| # TODO limit:
77
76
 
78
77
  inp = input(cpy_io)
@@ -83,10 +82,8 @@ module Ffmprb
83
82
  end
84
83
  end
85
84
 
86
- # Ffmprb.logger.debug "Preprocessed (from #{src_io.path}) looping input: #{dst_io.path}, output: #{io.io.path}, and raw input copy will go through #{buff_raw_io.path} to #{@raw.io.path}..."
87
-
88
85
  buff_ios = (1..times).map{File.temp_fifo intermediate_extname}
89
- Ffmprb.logger.debug "Preprocessed #{dst_io.path} will be teed to #{buff_ios.map(&:path).join '; '}"
86
+ Ffmprb.logger.debug{"Preprocessed #{dst_io.path} will be teed to #{buff_ios.map(&:path).join '; '}"}
90
87
  Util::Thread.new "cloning buffer watcher" do
91
88
  dst_io.threaded_buffered_copy_to(*buff_ios).tap do |io_buff|
92
89
  Util::Thread.join_children!
@@ -94,17 +91,15 @@ module Ffmprb
94
91
  end
95
92
  end
96
93
 
97
- # Ffmprb.logger.debug "Concatenation of #{buff_ios.map(&:path).join '; '} will go to #{@io.io.path} to be fed to this process"
98
-
99
94
  # NOTE additional (filtered, processed and looped) input io
100
95
  aux_io = File.temp_fifo(intermediate_extname)
101
96
 
102
97
  # NOTE (4)
103
98
 
104
99
  Util::Thread.new "looper" do
105
- Ffmprb.logger.debug "Looping #{buff_ios.size} times"
100
+ Ffmprb.logger.debug{"Looping #{buff_ios.size} times"}
106
101
 
107
- Ffmprb.logger.debug "(L4) Looping (#{buff_ios.map &:path}) into (#{aux_io.path})"
102
+ Ffmprb.logger.debug{"(L4) Looping (#{buff_ios.map &:path}) into (#{aux_io.path})"}
108
103
  begin # NOTE may not write its entire output, it's ok
109
104
  Ffmprb.process parent: @raw.process, ignore_broken_pipes: false do
110
105
 
@@ -121,7 +116,7 @@ module Ffmprb
121
116
 
122
117
  # NOTE (1)
123
118
 
124
- Ffmprb.logger.debug "(L1) Creating a new input (#{aux_io.path}) to the process"
119
+ Ffmprb.logger.debug{"(L1) Creating a new input (#{aux_io.path}) to the process"}
125
120
  @raw.process.input(aux_io)
126
121
  end
127
122
 
@@ -84,7 +84,7 @@ module Ffmprb
84
84
  # NOTE Image-Padding to match the target resolution
85
85
  # TODO full screen only at the moment (see exception above)
86
86
 
87
- Ffmprb.logger.debug "#{self} asking for filters of #{curr_reel.reel.io.inspect} video: #{channel(:video)}, audio: #{channel(:audio)}"
87
+ Ffmprb.logger.debug{"#{self} asking for filters of #{curr_reel.reel.io.inspect} video: #{channel(:video)}, audio: #{channel(:audio)}"}
88
88
  @filters.concat(
89
89
  curr_reel.reel.filters_for lbl, video: channel(:video), audio: channel(:audio)
90
90
  )
@@ -151,7 +151,7 @@ module Ffmprb
151
151
  ) if channel?(:audio)
152
152
 
153
153
  segments << new_prev_lbl
154
- Ffmprb.logger.debug "Concatting segments: #{new_prev_lbl} pushed"
154
+ Ffmprb.logger.debug{"Concatting segments: #{new_prev_lbl} pushed"}
155
155
  end
156
156
 
157
157
  if curr_reel.transition
@@ -264,7 +264,7 @@ module Ffmprb
264
264
  end
265
265
  process.proc_vis_edge process, main_av_o, :remove
266
266
  process.proc_vis_edge process, main_av_inter_i
267
- Ffmprb.logger.debug "Re-routed the main audio output (#{main_av_inter_i.path}->...->#{main_av_o.path}) through the process of audio ducking"
267
+ Ffmprb.logger.debug{"Re-routed the main audio output (#{main_av_inter_i.path}->...->#{main_av_o.path}) through the process of audio ducking"}
268
268
 
269
269
  over_a_i, over_a_o = File.threaded_buffered_fifo(Process.intermediate_channel_extname(audio: true, video: false), proc_vis: process)
270
270
  lbl_over = "o#{idx}l#{i}"
@@ -273,10 +273,10 @@ module Ffmprb
273
273
  )
274
274
  @channel_lbl_ios["#{lbl_over}:a"] = over_a_i
275
275
  process.proc_vis_edge process, over_a_i
276
- Ffmprb.logger.debug "Routed and buffering auxiliary output fifos (#{over_a_i.path}>#{over_a_o.path}) for overlay"
276
+ Ffmprb.logger.debug{"Routed and buffering auxiliary output fifos (#{over_a_i.path}>#{over_a_o.path}) for overlay"}
277
277
 
278
278
  inter_i, inter_o = File.threaded_buffered_fifo(intermediate_extname, proc_vis: process)
279
- Ffmprb.logger.debug "Allocated fifos to buffer media (#{inter_i.path}>#{inter_o.path}) while finding silence"
279
+ Ffmprb.logger.debug{"Allocated fifos to buffer media (#{inter_i.path}>#{inter_o.path}) while finding silence"}
280
280
 
281
281
  ignore_broken_pipes_was = process.ignore_broken_pipes # XXX maybe throw an exception instead?
282
282
  process.ignore_broken_pipes = true # NOTE audio ducking process may break the overlay pipe
@@ -285,7 +285,10 @@ module Ffmprb
285
285
  process.proc_vis_edge main_av_inter_o, inter_i # XXX mark it better
286
286
  silence = Ffmprb.find_silence(main_av_inter_o, inter_i)
287
287
 
288
- Ffmprb.logger.debug "Audio ducking with silence: [#{silence.map{|s| "#{s.start_at}-#{s.end_at}"}.join ', '}]"
288
+ Ffmprb.logger.debug{
289
+ silence_map = silence.map{|s| "#{s.start_at}-#{s.end_at}"}
290
+ "Audio ducking with silence: [#{silence_map.join ', '}]"
291
+ }
289
292
 
290
293
  Process.duck_audio inter_o, over_a_o, silence, main_av_o,
291
294
  process_options: {parent: process, ignore_broken_pipes: ignore_broken_pipes_was, timeout: process.timeout},
@@ -18,8 +18,10 @@ module Ffmprb
18
18
  sh *ffprobe_cmd, *args, limit: limit, timeout: timeout
19
19
  end
20
20
 
21
+ # TODO warn on broken pipes incompatibility with 4.x or something
21
22
  def ffmpeg(*args, limit: nil, timeout: cmd_timeout, ignore_broken_pipes: true)
22
- args = ['-loglevel', 'debug'] + args if Ffmprb.ffmpeg_debug
23
+ args = ['-loglevel', 'debug'] + args if
24
+ Ffmprb.ffmpeg_debug
23
25
  sh *ffmpeg_cmd, *args, output: :stderr, limit: limit, timeout: timeout, ignore_broken_pipes: ignore_broken_pipes
24
26
  end
25
27
 
@@ -42,7 +44,7 @@ module Ffmprb
42
44
  value = wait_thr.value
43
45
  status = value.exitstatus # NOTE blocking
44
46
  if status != 0
45
- if value.signaled? && value.termsig == Signal.list['PIPE']
47
+ if value.signaled? && value.termsig == Signal.list['PIPE'] # TODO! this doesn't seem to work for ffmpeg 4.x (it ignores SIGPIPEs)
46
48
  if ignore_broken_pipes
47
49
  Ffmprb.logger.info "Ignoring broken pipe: #{cmd_str}"
48
50
  else
@@ -54,7 +56,7 @@ module Ffmprb
54
56
  end
55
57
  end
56
58
  end
57
- Ffmprb.logger.debug "FINISHED: #{cmd_str}"
59
+ Ffmprb.logger.debug{"FINISHED: #{cmd_str}"}
58
60
 
59
61
  Thread.join_children! limit, timeout: timeout
60
62
 
@@ -137,7 +137,7 @@ module Ffmprb
137
137
  @proc_vis_firebase_client =
138
138
  if proc_vis_firebase
139
139
  url = "https://#{proc_vis_firebase}.firebaseio.com/proc/"
140
- Ffmprb.logger.debug "Connecting to #{url}"
140
+ Ffmprb.logger.debug{"Connecting to #{url}"}
141
141
  begin
142
142
  Firebase::Client.new(url).tap do
143
143
  Ffmprb.logger.info "Connected to #{url}"
@@ -42,12 +42,13 @@ module Ffmprb
42
42
  attr_reader :name
43
43
 
44
44
  def initialize(name="some", main: false, &blk)
45
+ orig_caller = caller
45
46
  @name = name
46
47
  @parent = Thread.current
47
48
  @live_children = []
48
49
  @children_mon = Monitor.new
49
50
  @dead_children_q = Queue.new
50
- Ffmprb.logger.debug "about to launch #{name}"
51
+ Ffmprb.logger.debug{"about to launch #{name}"}
51
52
  sync_q = Queue.new
52
53
  super() do
53
54
  @parent.proc_vis_node self if @parent.respond_to? :proc_vis_node
@@ -57,10 +58,10 @@ module Ffmprb
57
58
  Ffmprb.logger.warn "Not the main: true thread run by a not #{self.class.name} thread" unless main
58
59
  end
59
60
  sync_q.enq :ok
60
- Ffmprb.logger.debug "#{name} thread launched"
61
+ Ffmprb.logger.debug{"#{name} thread launched"}
61
62
  begin
62
63
  blk.call.tap do
63
- Ffmprb.logger.debug "#{name} thread done"
64
+ Ffmprb.logger.debug{"#{name} thread done"}
64
65
  end
65
66
  rescue Exception
66
67
  Ffmprb.logger.warn "#{$!.class.name} raised in #{name} thread: #{$!.message}\nBacktrace:\n\t#{$!.backtrace.join("\n\t")}"
@@ -84,7 +85,7 @@ module Ffmprb
84
85
 
85
86
  def child_lives(thr)
86
87
  @children_mon.synchronize do
87
- Ffmprb.logger.debug "picking up #{thr.name} thread"
88
+ Ffmprb.logger.debug{"picking up #{thr.name} thread"}
88
89
  @live_children << thr
89
90
  end
90
91
  proc_vis_edge self, thr
@@ -92,7 +93,7 @@ module Ffmprb
92
93
 
93
94
  def child_dies(thr)
94
95
  @children_mon.synchronize do
95
- Ffmprb.logger.debug "releasing #{thr.name} thread"
96
+ Ffmprb.logger.debug{"releasing #{thr.name} thread"}
96
97
  @dead_children_q.enq thr
97
98
  fail "System Error" unless @live_children.delete thr
98
99
  end