mediakit 0.0.3 → 0.0.5
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 +4 -4
- data/README.md +8 -5
- data/lib/mediakit/drivers.rb +2 -38
- data/lib/mediakit/utils/process_runner.rb +32 -42
- data/lib/mediakit/utils/shell_escape.rb +25 -0
- data/lib/mediakit/version.rb +1 -1
- data/mediakit.gemspec +0 -1
- metadata +3 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 739026ab070097e01f9e544c1838bbf532559641
|
4
|
+
data.tar.gz: bec5a0d43369988119be0a84d1999d781cdc4859
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34b726d533096261e10df0dc11c79b737247b4c3eab3b6b6f9d94558e20166574735fd1c83660a0725e350c76c7be4c6129f2509015c4015b3b7866b1ebf2c30
|
7
|
+
data.tar.gz: aece0527121a414e45f4b46d4efb3ae6610cae4a43e134963d1ba4dc810f5c51565c001a3b0ef7b409706d406ff65ba65a926060f92f1728577750d753b43989
|
data/README.md
CHANGED
@@ -10,10 +10,13 @@ I've design this library for following purpose.
|
|
10
10
|
|
11
11
|
## Development Plan
|
12
12
|
|
13
|
-
Currently
|
13
|
+
Currently you can use low-level inteface of mediakit!
|
14
14
|
|
15
15
|
* [x] low-level interface for ffmpeg
|
16
|
-
* [
|
16
|
+
* [*] low-level interface's basic feature
|
17
|
+
* [*] nice setting
|
18
|
+
* [*] read timeout setting
|
19
|
+
* [*] shell escape for security
|
17
20
|
* [ ] high-level interface for ffmpeg
|
18
21
|
* [ ] low-level interface for sox
|
19
22
|
* [ ] high-level interface for sox
|
@@ -43,14 +46,14 @@ So it need each binary command file.
|
|
43
46
|
|
44
47
|
## Usage
|
45
48
|
|
46
|
-
### Low Level
|
49
|
+
### Low Level Interface
|
47
50
|
|
48
51
|
The low level means it's near command line usage.
|
49
52
|
This is a little bore interface for constructing options,
|
50
53
|
but can pass certain it.
|
51
54
|
|
52
55
|
```rb
|
53
|
-
driver = Mediakit::Drivers::FFmpeg.new
|
56
|
+
driver = Mediakit::Drivers::FFmpeg.new(timeout: 30, nice: 0)
|
54
57
|
ffmpeg = Mediakit::FFmpeg.new(driver)
|
55
58
|
|
56
59
|
options = Mediakit::FFmpeg::Options.new(
|
@@ -75,7 +78,7 @@ puts "$ #{ffmpeg.command(options)}"
|
|
75
78
|
puts ffmpeg.run(options)
|
76
79
|
```
|
77
80
|
|
78
|
-
### High Level
|
81
|
+
### High Level Interface
|
79
82
|
|
80
83
|
TBD
|
81
84
|
|
data/lib/mediakit/drivers.rb
CHANGED
@@ -34,9 +34,8 @@ module Mediakit
|
|
34
34
|
def run(*args)
|
35
35
|
options = (args.last && args.last.kind_of?(Hash)) ? args.pop : {}
|
36
36
|
begin
|
37
|
-
escaped_args = Mediakit::Utils::ProcessRunner.escape(*args)
|
38
37
|
runner = Mediakit::Utils::ProcessRunner.new(options)
|
39
|
-
stdout, stderr, exit_status = runner.run(bin,
|
38
|
+
stdout, stderr, exit_status = runner.run(bin, *args)
|
40
39
|
raise(FailError, stderr) unless exit_status
|
41
40
|
stdout
|
42
41
|
rescue Mediakit::Utils::ProcessRunner::CommandNotFoundError => e
|
@@ -52,44 +51,11 @@ module Mediakit
|
|
52
51
|
# @param args [Array] arguments for command
|
53
52
|
# @return [String] command
|
54
53
|
def command(*args)
|
55
|
-
escaped_args = Mediakit::Utils::
|
54
|
+
escaped_args = Mediakit::Utils::ShellEscape.escape(*args)
|
56
55
|
"#{bin} #{escaped_args}"
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
60
|
-
class CocaineDriver < Base
|
61
|
-
# execute command and return result
|
62
|
-
#
|
63
|
-
# @overload run(args)
|
64
|
-
# @param args [String] arguments for command
|
65
|
-
# @overload run(*args, options)
|
66
|
-
# @param args [Array] arguments for command
|
67
|
-
# @option options [Hash] run options
|
68
|
-
# @return [Bool] stdout output
|
69
|
-
def run(args = '')
|
70
|
-
begin
|
71
|
-
# Force escape args string on here,
|
72
|
-
# because this design can't use Cocaine::CommandLine's safety solution.
|
73
|
-
escaped_args = Mediakit::Utils::ProcessRunner.escape(args.dup)
|
74
|
-
command_line = Cocaine::CommandLine.new(bin, escaped_args, swallow_stderr: true)
|
75
|
-
command_line.run
|
76
|
-
rescue Cocaine::ExitStatusError => e
|
77
|
-
raise(FailError, e.message)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# return command to execute
|
82
|
-
#
|
83
|
-
# @overload run(args)
|
84
|
-
# @param args [String] arguments for command
|
85
|
-
# @overload run(*args)
|
86
|
-
# @param args [Array] arguments for command
|
87
|
-
# @return [String] command commands to execute
|
88
|
-
def command(args = '')
|
89
|
-
Cocaine::CommandLine.new(bin, args).command
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
59
|
class FakeDriver < Base
|
94
60
|
def run(args = '')
|
95
61
|
true
|
@@ -120,8 +86,6 @@ module Mediakit
|
|
120
86
|
case type.to_sym
|
121
87
|
when :popen
|
122
88
|
PopenDriver.new(bin)
|
123
|
-
when :cocaine
|
124
|
-
CocaineDriver.new(bin)
|
125
89
|
when :fake
|
126
90
|
FakeDriver.new(bin)
|
127
91
|
else
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require 'shellwords'
|
2
1
|
require 'open3'
|
3
2
|
require 'thread'
|
4
3
|
require 'timeout'
|
5
4
|
require 'cool.io'
|
5
|
+
require 'mediakit/utils/shell_escape'
|
6
6
|
|
7
7
|
module Mediakit
|
8
8
|
module Utils
|
@@ -12,7 +12,9 @@ module Mediakit
|
|
12
12
|
class TimeoutError < StandardError;
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
DEFAULT_READ_TIMEOUT_INTERVAL = 30
|
16
|
+
|
17
|
+
def initialize(timeout: DEFAULT_READ_TIMEOUT_INTERVAL, nice: 0)
|
16
18
|
@timeout = timeout
|
17
19
|
@nice = nice
|
18
20
|
end
|
@@ -28,34 +30,28 @@ module Mediakit
|
|
28
30
|
# @return exit_status [Boolean] is succeeded
|
29
31
|
def run(bin, *args)
|
30
32
|
command = build_command(bin, *args)
|
31
|
-
|
32
|
-
out_reader, err_reader = nil
|
33
|
-
loop = Coolio::Loop.new
|
33
|
+
exit_status = nil
|
34
34
|
begin
|
35
35
|
stdin, stdout, stderr, wait_thr = Open3.popen3(command)
|
36
36
|
stdin.close
|
37
37
|
pid = wait_thr.pid
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
38
|
+
begin
|
39
|
+
loop = Coolio::Loop.new
|
40
|
+
timer, out_watcher, err_watcher = setup_watchers(loop, stdout, stderr)
|
41
|
+
loop_thread = Thread.new { loop.run }
|
42
|
+
wait_thr.join
|
43
|
+
exit_status = (wait_thr.value.exitstatus == 0)
|
44
|
+
rescue Timeout::Error => error
|
45
|
+
force_kill_process(pid)
|
46
|
+
raise(error)
|
47
|
+
ensure
|
48
|
+
out_watcher.close unless out_watcher && out_watcher.closed?
|
49
|
+
err_watcher.close unless err_watcher && err_watcher.closed?
|
50
|
+
timer.detach if timer
|
51
|
+
loop_thread.join if loop_thread
|
46
52
|
end
|
47
|
-
wait_thr.join
|
48
|
-
exit_status = (wait_thr.value.exitstatus == 0)
|
49
53
|
rescue Errno::ENOENT => e
|
50
54
|
raise(CommandNotFoundError, "Can't find command - #{command}, #{e.meessage}")
|
51
|
-
rescue Timeout::Error => error
|
52
|
-
safe_kill_process(pid)
|
53
|
-
raise(error)
|
54
|
-
ensure
|
55
|
-
out_watcher.close if out_watcher
|
56
|
-
err_watcher.close if err_watcher
|
57
|
-
timer.detach if timer
|
58
|
-
loop_thread.join
|
59
55
|
end
|
60
56
|
|
61
57
|
[out_watcher.data, err_watcher.data, exit_status]
|
@@ -63,36 +59,30 @@ module Mediakit
|
|
63
59
|
|
64
60
|
def build_command(bin, *args)
|
65
61
|
command = build_command_without_options(bin, *args)
|
66
|
-
|
67
|
-
"nice -n #{@nice} sh -c \"#{command}\""
|
68
|
-
else
|
62
|
+
if @nice == 0
|
69
63
|
command
|
64
|
+
else
|
65
|
+
"nice -n #{ShellEscape.escape(@nice)} sh -c \"#{command}\""
|
70
66
|
end
|
71
67
|
end
|
72
68
|
|
73
69
|
def build_command_without_options(bin, *args)
|
74
|
-
escaped_args =
|
70
|
+
escaped_args = ShellEscape.escape(*args)
|
75
71
|
"#{bin} #{escaped_args}"
|
76
72
|
end
|
77
73
|
|
78
|
-
def
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
74
|
+
def setup_watchers(loop, stdout, stderr)
|
75
|
+
timer = TimeoutTimer.new(@timeout, Thread.current)
|
76
|
+
timer.attach(loop)
|
77
|
+
out_watcher = IOWatcher.new(stdout) { timer.update }
|
78
|
+
out_watcher.attach(loop)
|
79
|
+
err_watcher = IOWatcher.new(stderr) { timer.update }
|
80
|
+
err_watcher.attach(loop)
|
88
81
|
|
89
|
-
|
90
|
-
splits = Shellwords.split(string)
|
91
|
-
splits = splits.map { |x| Shellwords.escape(x) }
|
92
|
-
splits.join(' ')
|
82
|
+
[timer, out_watcher, err_watcher]
|
93
83
|
end
|
94
84
|
|
95
|
-
def
|
85
|
+
def force_kill_process(pid)
|
96
86
|
Process.kill('SIGKILL', pid)
|
97
87
|
rescue Errno::ESRCH
|
98
88
|
warn 'already killedd'
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
3
|
+
module Mediakit
|
4
|
+
module Utils
|
5
|
+
module ShellEscape
|
6
|
+
def escape(*args)
|
7
|
+
case args.size
|
8
|
+
when 1
|
9
|
+
escape_with_split(args[0])
|
10
|
+
else
|
11
|
+
Shellwords.join(args.map { |x| Shellwords.escape(x) })
|
12
|
+
end
|
13
|
+
end
|
14
|
+
module_function(:escape)
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def self.escape_with_split(string)
|
19
|
+
splits = Shellwords.split(string)
|
20
|
+
splits = splits.map { |x| Shellwords.escape(x) }
|
21
|
+
splits.join(' ')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/mediakit/version.rb
CHANGED
data/mediakit.gemspec
CHANGED
@@ -22,7 +22,6 @@ EOS
|
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
|
-
spec.add_runtime_dependency "cocaine", "~> 0.5.7"
|
26
25
|
spec.add_runtime_dependency "activesupport", "~> 4"
|
27
26
|
spec.add_runtime_dependency "cool.io", "~> 1.3"
|
28
27
|
spec.add_development_dependency "rake", "~> 10.0"
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mediakit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
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-
|
11
|
+
date: 2015-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: cocaine
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 0.5.7
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 0.5.7
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: activesupport
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,6 +117,7 @@ files:
|
|
131
117
|
- lib/mediakit/ffmpeg/options.rb
|
132
118
|
- lib/mediakit/ffprobe.rb
|
133
119
|
- lib/mediakit/utils/process_runner.rb
|
120
|
+
- lib/mediakit/utils/shell_escape.rb
|
134
121
|
- lib/mediakit/version.rb
|
135
122
|
- mediakit.gemspec
|
136
123
|
- sample/configure.rb
|