mediakit 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba4ab75bf6e7d06e4d47117147e26dd2dccdb650
4
- data.tar.gz: d4e1e172178d66a94c581696e00235a896567cf0
3
+ metadata.gz: 6bce22e6bb5655d6ef5522dfb86cd95660b56119
4
+ data.tar.gz: 4ae5b7f5a0c1348aa22de26b0da11a80c47f0f05
5
5
  SHA512:
6
- metadata.gz: 02b9db5afc15386e6398f267513cb5c7b040e540e7f6f677f5b9d9f70d410b49c16a28cea77a3006df674a95ce67d2e5ef8209629ce69e38c16bb52da3acdcb7
7
- data.tar.gz: b42d2eb275b21769af3c90e3a8df77220cdd81abe5bc060f10912995ec6d2e0ffa230dba12f43eb34f036373aeacf7575e2e779b4d505f0c7878dd6405fd5b9b
6
+ metadata.gz: 67789568de47730bc876c7be8971d45bfa6e69179cb227abd4052a390e41aea7eb52939932b144a27bcc2752abe02c690361e88c8e8b9f5973ae3a2897d8ed54
7
+ data.tar.gz: 8db964b6558ceec920bc45833bcb7e57cccc1a5f6891c69540c40b3934a35761feb7d02f440f0abb0bbfda304bf463c02de0b20b3d21cab73f8854032dc751ef
data/.travis.yml CHANGED
@@ -1,3 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.2.0
4
+ before_install:
5
+ - gem update --system
6
+ - gem update bundler
7
+ - gem --version
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Mediakit
2
2
 
3
+ [![Build Status](https://travis-ci.org/ainame/mediakit.svg)](https://travis-ci.org/ainame/mediakit)
4
+
3
5
  mediakit is the libraries for ffmpeg and sox backed media manipulation something.
4
6
  I've design this library for following purpose.
5
7
 
@@ -8,7 +10,10 @@ I've design this library for following purpose.
8
10
 
9
11
  ## Development Plan
10
12
 
13
+ Currently under development.
14
+
11
15
  * [x] low-level interface for ffmpeg
16
+ * [ ] low-level interface's basic feature
12
17
  * [ ] high-level interface for ffmpeg
13
18
  * [ ] low-level interface for sox
14
19
  * [ ] high-level interface for sox
@@ -46,18 +51,18 @@ but can pass certain it.
46
51
 
47
52
  ```rb
48
53
  driver = Mediakit::Drivers::FFmpeg.new
49
- ffmpeg = Mediakit::Runners::FFmpeg.new(driver)
54
+ ffmpeg = Mediakit::FFmpeg.new(driver)
50
55
 
51
- options = Mediakit::Runners::FFmpeg::Options.new(
52
- Mediakit::Runners::FFmpeg::Options::GlobalOption.new(
56
+ options = Mediakit::FFmpeg::Options.new(
57
+ Mediakit::FFmpeg::Options::GlobalOption.new(
53
58
  't' => 100,
54
59
  'y' => true,
55
60
  ),
56
- Mediakit::Runners::FFmpeg::Options::InputFileOption.new(
61
+ Mediakit::FFmpeg::Options::InputFileOption.new(
57
62
  options: nil,
58
63
  path: input,
59
64
  ),
60
- Mediakit::Runners::FFmpeg::Options::OutputFileOption.new(
65
+ Mediakit::FFmpeg::Options::OutputFileOption.new(
61
66
  options: {
62
67
  'vf' => 'crop=320:320:0:0',
63
68
  'ar' => '44100',
@@ -66,7 +71,7 @@ options = Mediakit::Runners::FFmpeg::Options.new(
66
71
  path: output,
67
72
  ),
68
73
  )
69
- puts "$ ffmpeg #options"
74
+ puts "$ #{ffmpeg.command(options)}"
70
75
  puts ffmpeg.run(options)
71
76
  ```
72
77
 
data/Rakefile CHANGED
@@ -1 +1,16 @@
1
- require "bundler/gem_tasks"
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'bundler/gem_tasks'
4
+ require 'yard'
5
+ require 'yard/rake/yardoc_task'
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.libs << 'test'
9
+ t.test_files = FileList['test/**/test_*.rb']
10
+ end
11
+
12
+ task(default: :test)
13
+
14
+ YARD::Rake::YardocTask.new do |t|
15
+ t.files = ['lib/**/*.rb']
16
+ end
@@ -1,9 +1,10 @@
1
1
  require 'shellwords'
2
- require 'mediakit/utils/popen_helper'
2
+ require 'mediakit/utils/process_runner'
3
3
 
4
4
  module Mediakit
5
5
  module Drivers
6
6
  class DriverError < StandardError; end
7
+ class FailError < DriverError; end
7
8
  class ConfigurationError < DriverError; end
8
9
 
9
10
  class Base
@@ -25,18 +26,21 @@ module Mediakit
25
26
  # execute command and return result
26
27
  #
27
28
  # @overload run(args)
28
- # @param args [String] arguments for command
29
- # @overload run(*args)
30
- # @param args [Array] arguments for command
31
- # @return result [Bool] runners result
29
+ # @param [String] args string argument for command
30
+ # @overload run(*args, options)
31
+ # @param [Array] args arguments for command
32
+ # @option [Hash] options run options
33
+ # @return [Bool] stdout output
32
34
  def run(*args)
35
+ options = (args.last && args.last.kind_of?(Hash)) ? args.pop : {}
33
36
  begin
34
- escaped_args = Mediakit::Utils::PopenHelper.escape(*args)
35
- Mediakit::Utils::PopenHelper.run(bin, escaped_args)
36
- rescue Mediakit::Utils::PopenHelper::CommandNotFoundError => e
37
+ escaped_args = Mediakit::Utils::ProcessRunner.escape(*args)
38
+ runner = Mediakit::Utils::ProcessRunner.new(options)
39
+ stdout, stderr, exit_status = runner.run(bin, escaped_args)
40
+ raise(FailError, stderr) unless exit_status
41
+ stdout
42
+ rescue Mediakit::Utils::ProcessRunner::CommandNotFoundError => e
37
43
  raise(ConfigurationError, "cant' find bin in #{bin}.")
38
- rescue => e
39
- raise(DriverError, "#{self.class} catch error with command(#{Mediakit::Utils::PopenHelper.command(bin,escaped_args)}) - #{e.message}, #{e.backtrace.join("\n")}")
40
44
  end
41
45
  end
42
46
 
@@ -46,9 +50,9 @@ module Mediakit
46
50
  # @param args [String] arguments for command
47
51
  # @overload run(*args)
48
52
  # @param args [Array] arguments for command
49
- # @return result [String] runners to execute
53
+ # @return [String] command
50
54
  def command(*args)
51
- escaped_args = Mediakit::Utils::PopenHelper.escape(*args)
55
+ escaped_args = Mediakit::Utils::ProcessRunner.escape(*args)
52
56
  "#{bin} #{escaped_args}"
53
57
  end
54
58
  end
@@ -58,18 +62,19 @@ module Mediakit
58
62
  #
59
63
  # @overload run(args)
60
64
  # @param args [String] arguments for command
61
- # @overload run(*args)
65
+ # @overload run(*args, options)
62
66
  # @param args [Array] arguments for command
63
- # @return result [Bool] runners result
67
+ # @option options [Hash] run options
68
+ # @return [Bool] stdout output
64
69
  def run(args = '')
65
70
  begin
66
71
  # Force escape args string on here,
67
72
  # because this design can't use Cocaine::CommandLine's safety solution.
68
- escaped_args = Mediakit::Utils::PopenHelper.escape(args.dup)
73
+ escaped_args = Mediakit::Utils::ProcessRunner.escape(args.dup)
69
74
  command_line = Cocaine::CommandLine.new(bin, escaped_args, swallow_stderr: true)
70
75
  command_line.run
71
- rescue => e
72
- raise(DriverError, "#{self.class} catch error with runners [$ #{command_line.command}] - #{e.message}, #{e.backtrace.join("\n")}")
76
+ rescue Cocaine::ExitStatusError => e
77
+ raise(FailError, e.message)
73
78
  end
74
79
  end
75
80
 
@@ -79,7 +84,7 @@ module Mediakit
79
84
  # @param args [String] arguments for command
80
85
  # @overload run(*args)
81
86
  # @param args [Array] arguments for command
82
- # @return result [String] runners to execute
87
+ # @return [String] command commands to execute
83
88
  def command(args = '')
84
89
  Cocaine::CommandLine.new(bin, args).command
85
90
  end
@@ -126,12 +131,15 @@ module Mediakit
126
131
  end
127
132
  end
128
133
 
134
+ # factory class for ffmpeg driver
129
135
  class FFmpeg < AbstractFactory
130
136
  end
131
137
 
138
+ # factory class for ffprobe driver
132
139
  class FFprobe < AbstractFactory
133
140
  end
134
141
 
142
+ # factory class for sox driver
135
143
  class Sox < AbstractFactory
136
144
  end
137
145
  end
@@ -0,0 +1,29 @@
1
+ module Mediakit
2
+ class FFmpeg
3
+ module Introspection
4
+ DELIMITER_FOR_CODECS = "\n -------\n".freeze
5
+ DELIMITER_FOR_FORMATS = "\n --\n".freeze
6
+ DELIMITER_FOR_CODER = "\n ------\n".freeze
7
+
8
+ def codecs
9
+ @codecs ||= run(global_options('codecs')).split(DELIMITER_FOR_CODECS)[1].each_line.to_a
10
+ end
11
+
12
+ def formats
13
+ @formats ||= run(global_options('formats')).split(DELIMITER_FOR_FORMATS)[1].each_line.to_a
14
+ end
15
+
16
+ def decoders
17
+ @decoders ||= run(global_options('decoders')).split(DELIMITER_FOR_CODER)[1].each_line.to_a
18
+ end
19
+
20
+ def encoders
21
+ @encoders ||= run(global_options('encoders')).split(DELIMITER_FOR_CODER)[1].each_line.to_a
22
+ end
23
+
24
+ def global_options(flag)
25
+ Options.new(Options::GlobalOption.new(flag => true))
26
+ end
27
+ end
28
+ end
29
+ end
@@ -9,11 +9,10 @@ module Mediakit
9
9
  #
10
10
  class Options
11
11
  attr_reader(:global, :inputs, :output)
12
- # constructor
13
- #
14
- # @option args [Mediakit::FFmpeg::Options::GlobalOption]
15
- # @option args [Array<Mediakit::FFmpeg::Options::InputFileOption>] array object Mediakit::FFmpeg::Options::InputOption
16
- # @option args [Mediakit::FFmpeg::Options::OutputFileOption]
12
+
13
+ # @option [Mediakit::FFmpeg::Options::GlobalOption] args option
14
+ # @option [Mediakit::FFmpeg::Options::InputFileOption] args Mediakit::FFmpeg::Options::InputOption
15
+ # @option [Mediakit::FFmpeg::Options::OutputFileOption] args output file option
17
16
  def initialize(*args)
18
17
  @global, @inputs, @output = nil, [], nil
19
18
  args.each do |option|
@@ -61,9 +60,7 @@ module Mediakit
61
60
 
62
61
  # Base class for Options
63
62
  class OrderedHash < ActiveSupport::OrderedHash
64
- # initializer
65
- #
66
- # @param options [Hash] initial option values
63
+ # @param [Hash] options initial option values
67
64
  def initialize(options = {})
68
65
  options.each { |key, value| raise_if_invalid_arg_error(key, value) } if options
69
66
  self.merge!(options) if options && options.kind_of?(Hash)
@@ -119,8 +116,8 @@ module Mediakit
119
116
  end
120
117
 
121
118
  class InputFileOption < OptionPathPair
122
- # @param options [Hash] input options
123
- # @param path [String] input file path
119
+ # @param [Hash] :options input options
120
+ # @param [String] :path input file path
124
121
  def initialize(options:, path:)
125
122
  ordered_hash = OrderedHash.new(options)
126
123
  super(options: ordered_hash, path: path)
@@ -132,8 +129,8 @@ module Mediakit
132
129
  end
133
130
 
134
131
  class OutputFileOption < OptionPathPair
135
- # @param options [Hash] output options
136
- # @param path [String] output file path
132
+ # @param [Hash] :options output options
133
+ # @param [String] :path output file path
137
134
  def initialize(options:, path:)
138
135
  ordered_hash = OrderedHash.new(options)
139
136
  super(options: ordered_hash, path: path)
@@ -144,23 +141,14 @@ module Mediakit
144
141
  end
145
142
  end
146
143
 
147
- class InputFileOptionCollection
148
- attr_reader(:input_file_options)
149
-
150
- # @param *input_file_options [Mediakit::FFmpeg::InputFileOptions]
151
- def initialize(*input_file_options)
152
- @options = input_file_options
153
- end
154
-
155
- def empty?
156
- @options.empty?
144
+ class QuoteString
145
+ def initialize(string)
146
+ @string = string
157
147
  end
158
148
 
159
- def compose
160
- @options.map(&:compose).join(' ')
149
+ def to_s
150
+ "\"#{@string}\""
161
151
  end
162
-
163
- alias_method :to_s, :compose
164
152
  end
165
153
 
166
154
  # see https://www.ffmpeg.org/ffmpeg.html#Stream-specifiers-1
@@ -1,14 +1,12 @@
1
- require 'mediakit/ffmpeg/options'
2
1
  require 'mediakit/drivers'
2
+ require 'mediakit/ffmpeg/options'
3
+ require 'mediakit/ffmpeg/introspection'
3
4
 
4
5
  module Mediakit
5
6
  class FFmpeg
6
- class FFmpegError < StandardError;
7
- end
7
+ include Introspection
8
+ class FFmpegError < StandardError; end
8
9
 
9
- DELIMITER_FOR_CODECS = "\n -------\n".freeze
10
- DELIMITER_FOR_FORMATS = "\n --\n".freeze
11
- DELIMITER_FOR_CODER = "\n ------\n".freeze
12
10
 
13
11
  def initialize(driver)
14
12
  @driver = driver
@@ -16,7 +14,7 @@ module Mediakit
16
14
 
17
15
  # execute runners with options object
18
16
  #
19
- # @param options [Mediakit::Runners::FFmpeg::Options] options object to create CLI argument
17
+ # @param [Mediakit::Runners::FFmpeg::Options] options options to create CLI argument
20
18
  def run(options)
21
19
  args = options.compose
22
20
  execute(args)
@@ -27,38 +25,10 @@ module Mediakit
27
25
  @driver.command(args)
28
26
  end
29
27
 
30
- def codecs
31
- @codecs ||= run(global_options('codecs')).split(DELIMITER_FOR_CODECS)[1].each_line.to_a
32
- end
33
-
34
- def formats
35
- @formats ||= run(global_options('formats')).split(DELIMITER_FOR_FORMATS)[1].each_line.to_a
36
- end
37
-
38
- def decoders
39
- @decoders ||= run(global_options('decoders')).split(DELIMITER_FOR_CODER)[1].each_line.to_a
40
- end
41
-
42
- def encoders
43
- @encoders ||= run(global_options('encoders')).split(DELIMITER_FOR_CODER)[1].each_line.to_a
44
- end
45
-
46
28
  private
47
29
 
48
30
  def execute(args = '')
49
- begin
50
- @driver.run(args)
51
- rescue Drivers::DriverError => e
52
- raise(FFmpegError, "#catch driver's error - #{e.message}, #{e.backtrace.join("\n")}")
53
- end
54
- end
55
-
56
- def global_options(flag)
57
- Mediakit::FFmpeg::Options.new(
58
- Mediakit::FFmpeg::Options::GlobalOptions.new(
59
- flag => true,
60
- ),
61
- )
31
+ @driver.run(args)
62
32
  end
63
33
  end
64
34
  end
@@ -10,11 +10,7 @@ module Mediakit
10
10
  end
11
11
 
12
12
  def execute(args = '')
13
- begin
14
- driver.run(args)
15
- rescue => e
16
- raise(FFprobeError, "#{self.class} catch error - #{e.message}, #{e.backtrace.join("\n")}")
17
- end
13
+ driver.run(args)
18
14
  end
19
15
 
20
16
  def get_json(path)
@@ -0,0 +1,159 @@
1
+ require 'shellwords'
2
+ require 'open3'
3
+ require 'thread'
4
+ require 'timeout'
5
+
6
+
7
+ module Mediakit
8
+ module Utils
9
+ class ProcessRunner
10
+ class CommandNotFoundError < StandardError;
11
+ end
12
+ class TimeoutError < StandardError;
13
+ end
14
+
15
+ def initialize(timeout: nil)
16
+ @timeout = timeout
17
+ end
18
+
19
+ # @overload run(command, *args)
20
+ # @param command [String]
21
+ # @param args [Array] args as array for safety shellescape
22
+ # @overload run(command, args)
23
+ # @param command [String] command name
24
+ # @param args [Array] args as string
25
+ # @return out [String] stdout of command
26
+ # @return err [String] stderr of command
27
+ # @return exit_status [Boolean] is succeeded
28
+ def run(bin, *args)
29
+ command = self.class.command(bin, *args)
30
+
31
+ pid, out, err, exit_status = nil
32
+ out_reader, err_reader = nil
33
+ watch = TimeoutWatch.new(@timeout)
34
+ begin
35
+ stdin, stdout, stderr, wait_thr = Open3.popen3(command)
36
+ stdin.close
37
+ pid = wait_thr.pid
38
+ watch.start(Thread.current)
39
+ out_reader = IOReader.new(stdout) { |chunk| watch.update }
40
+ err_reader = IOReader.new(stderr) { |chunk| watch.update }
41
+
42
+ wait_thr.join
43
+ exit_status = (wait_thr.value.exitstatus == 0)
44
+ rescue Errno::ENOENT => e
45
+ raise(CommandNotFoundError, "Can't find command - #{command}, #{e.meessage}")
46
+ rescue Timeout::Error => error
47
+ Process.kill('SIGKILL', pid)
48
+ raise(error)
49
+ ensure
50
+ out_reader.finish
51
+ err_reader.finish
52
+ watch.finish
53
+ end
54
+
55
+ [out_reader.data, err_reader.data, exit_status]
56
+ end
57
+
58
+ def self.command(bin, *args)
59
+ escaped_args = escape(*args)
60
+ "#{bin} #{escaped_args}"
61
+ end
62
+
63
+ def self.escape(*args)
64
+ case args.size
65
+ when 1
66
+ escape_with_split(args[0])
67
+ else
68
+ Shellwords.join(args.map { |x| Shellwords.escape(x) })
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def self.escape_with_split(string)
75
+ splits = Shellwords.split(string)
76
+ splits = splits.map { |x| Shellwords.escape(x) }
77
+ splits.join(' ')
78
+ end
79
+
80
+ class IOReader
81
+ attr_reader(:data)
82
+
83
+ def initialize(io, &block)
84
+ raise(ArgumentError) unless block_given?
85
+ @io = io
86
+ @data = ''
87
+ @block = block
88
+ start
89
+ end
90
+
91
+ def finish
92
+ @thread.join
93
+ @thread.kill
94
+ end
95
+
96
+ private
97
+ def start
98
+ @thread = Thread.new { read }
99
+ nil
100
+ end
101
+
102
+ def read
103
+ return if @io.closed?
104
+ begin
105
+ while chunk = @io.gets
106
+ @data << chunk
107
+ @block.call(chunk) if @block
108
+ end
109
+ rescue IOError => e
110
+ warn "[WARN] IOError #{e.message}"
111
+ ensure
112
+ @io.close unless @io.closed?
113
+ end
114
+ end
115
+ end
116
+
117
+ # watch process progress by io.
118
+ # when wait time exceed duration, then kill process.
119
+ class TimeoutWatch
120
+ attr_reader(:duration)
121
+
122
+ def initialize(duration)
123
+ @duration = duration
124
+ @watched_at = Time.now
125
+ @mutex = Mutex.new
126
+ end
127
+
128
+ def start(current_thread, &block)
129
+ @current_thread = current_thread
130
+ @watch_thread = Thread.new do
131
+ loop do
132
+ if timeout?
133
+ @current_thread.raise(Timeout::Error, "wait timeout error with #{duration} sec.")
134
+ end
135
+ sleep(0.1)
136
+ end
137
+ end
138
+ nil
139
+ end
140
+
141
+ def finish
142
+ @watch_thread.kill
143
+ end
144
+
145
+ def update
146
+ @mutex.synchronize do
147
+ @watched_at = Time.now
148
+ end
149
+ end
150
+
151
+ private
152
+
153
+ def timeout?
154
+ (Time.now - @watched_at) > duration
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
@@ -1,3 +1,3 @@
1
1
  module Mediakit
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/mediakit.gemspec CHANGED
@@ -24,8 +24,8 @@ EOS
24
24
 
25
25
  spec.add_runtime_dependency "cocaine", "~> 0.5.7"
26
26
  spec.add_runtime_dependency "activesupport", "~> 4"
27
- spec.add_development_dependency "bundler", "~> 1.9"
28
27
  spec.add_development_dependency "rake", "~> 10.0"
29
- spec.add_development_dependency "pry", "~> 0.10"
28
+ spec.add_development_dependency "pry", '~> 0.10'
30
29
  spec.add_development_dependency "ruby-debug-ide", "~> 0.4"
30
+ spec.add_development_dependency "yard", "> 0.8"
31
31
  end
@@ -0,0 +1,9 @@
1
+ require 'mediakit'
2
+
3
+ root = File.expand_path(File.join(File.dirname(__FILE__), '../'))
4
+ Mediakit::Drivers::FFmpeg.configure do |config|
5
+ config.bin_path = File.join(root, 'test/supports/ffmpeg')
6
+ end
7
+
8
+ driver = Mediakit::Drivers::FFmpeg.new
9
+ puts driver.run('-version')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mediakit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ainame
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-05-10 00:00:00.000000000 Z
11
+ date: 2015-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cocaine
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '4'
41
- - !ruby/object:Gem::Dependency
42
- name: bundler
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '1.9'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '1.9'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: rake
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +80,20 @@ dependencies:
94
80
  - - "~>"
95
81
  - !ruby/object:Gem::Version
96
82
  version: '0.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.8'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.8'
97
97
  description: |
98
98
  mediakit is the libraries for ffmpeg and sox backed media manipulation something.
99
99
  you can create complex manipulation for media as a ruby code.
@@ -113,11 +113,13 @@ files:
113
113
  - lib/mediakit.rb
114
114
  - lib/mediakit/drivers.rb
115
115
  - lib/mediakit/ffmpeg.rb
116
+ - lib/mediakit/ffmpeg/introspection.rb
116
117
  - lib/mediakit/ffmpeg/options.rb
117
118
  - lib/mediakit/ffprobe.rb
118
- - lib/mediakit/utils/popen_helper.rb
119
+ - lib/mediakit/utils/process_runner.rb
119
120
  - lib/mediakit/version.rb
120
121
  - mediakit.gemspec
122
+ - sample/configure.rb
121
123
  - sample/raw_crop.rb
122
124
  - templates/codec.rb.erb
123
125
  - templates/decoder.rb.erb
@@ -142,8 +144,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
144
  version: '0'
143
145
  requirements: []
144
146
  rubyforge_project:
145
- rubygems_version: 2.4.5
147
+ rubygems_version: 2.4.6
146
148
  signing_key:
147
149
  specification_version: 4
148
150
  summary: mediakit is the libraries for ffmpeg and sox backed media manipulation something.
149
151
  test_files: []
152
+ has_rdoc:
@@ -1,68 +0,0 @@
1
- require 'shellwords'
2
- require 'open3'
3
-
4
- module Mediakit
5
- module Utils
6
- module PopenHelper
7
-
8
- class CommandNotFoundError < StandardError;
9
- end
10
-
11
- # @overload run(command, *args)
12
- # @param command [String]
13
- # @param args [Array] args as array for safety shellescape
14
- # @overload run(command, args)
15
- # @param command [String] command name
16
- # @param args [Array] args as string
17
- # @return out [String] stdout of command
18
- # @return err [String] stderr of command
19
- # @return exit_status [Boolean] is succeeded
20
- def run(bin, *args)
21
- command = command(bin, *args)
22
-
23
- out, err, exit_status = nil
24
- begin
25
- Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
26
- stdin.close
27
- out = stdout.read
28
- err = stderr.read
29
- exit_status = (wait_thr.value.exitstatus == 0)
30
- end
31
- rescue Errno::ENOENT => e
32
- raise(CommandNotFoundError, "Can't find command - #{command}, #{e.meessage}")
33
- end
34
-
35
- [out, err, exit_status]
36
- end
37
-
38
- module_function(:run)
39
-
40
- def command(bin, *args)
41
- escaped_args = escape(*args)
42
- "#{bin} #{escaped_args}"
43
- end
44
-
45
- module_function(:command)
46
-
47
- def escape(*args)
48
- case args.size
49
- when 1
50
- _escape_with_split(args[0])
51
- else
52
- Shellwords.join(args.map { |x| Shellwords.escape(x) })
53
- end
54
- end
55
-
56
- module_function(:escape)
57
-
58
- def _escape_with_split(string)
59
- splits = Shellwords.split(string)
60
- splits = splits.map { |x| Shellwords.escape(x) }
61
- splits.join(' ')
62
- end
63
-
64
- module_function(:_escape_with_split)
65
-
66
- end
67
- end
68
- end