media 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -4,6 +4,10 @@ An `ffmpeg` or `avconv` wrapper
4
4
 
5
5
  ## Installation
6
6
 
7
+ Install ffmpeg:
8
+
9
+ brew install ffmpeg
10
+
7
11
  Add this line to your application's Gemfile:
8
12
 
9
13
  gem 'media'
@@ -18,56 +22,39 @@ Or install it yourself as:
18
22
 
19
23
  ## Usage
20
24
 
21
- Media.convert do
22
- option 'v', 'warning'
25
+ conversion = Media.convert do
26
+ options y: true
23
27
 
24
- input 'in1.mov'
25
-
26
- input 'in2.mov' do
27
- option 'foo', 'bar'
28
+ input 'http://www.google.com/images/srpr/logo3w.png' do
29
+ options loop: 1, f: 'image2'
28
30
  end
29
31
 
30
- output 'out.mov' do
32
+ output '/path/to/test2.webm' do
33
+ options vcodec: 'libvpx', acodec: 'libvorbis', t: 4
34
+ maps label('video'), label('audio')
31
35
  graph do
32
36
  chain do
33
- filter 'split' do
34
- input 'in'
35
- output 'T1'
36
- end
37
- filter 'fifo'
38
- filter 'overlay' do
39
- input 'T2'
40
- arg '0'
41
- arg 'H/2'
42
- output 'out'
37
+ filter 'negate'
38
+ filter 'hflip' do
39
+ outputs 'video'
43
40
  end
44
41
  end
45
42
  chain do
46
- filter 'fifo' do
47
- input 'T1'
48
- end
49
- filter 'crop' do
50
- arg 'iw'
51
- arg 'ih/2'
52
- arg '0'
53
- arg 'ih/2'
54
- end
55
- filter 'vflip' do
56
- output 'T2'
43
+ filter 'aevalsrc' do
44
+ arguments 'sin(440*2*PI*t)' => true
45
+ outputs 'audio'
57
46
  end
58
47
  end
59
48
  end
60
-
61
- map 'out'
62
-
63
- option 'f', 'prores'
64
49
  end
65
50
  end
66
-
67
- Outputs:
68
51
 
69
- ffmpeg -v warning -i in1.mov -foo bar -i in2.mov -filter_complex "[in] split [T1], fifo, [T2] overlay=0:H/2 [out]; [T1] fifo, crop=iw:ih/2:0:ih/2, vflip [T2]" -map out -f prores out.mov
52
+ conversion.call {|progress| p progress}
70
53
 
54
+ Outputs:
55
+
56
+ ffmpeg -v info -y -loop 1 -f image2 -i http://www.google.com/images/srpr/logo3w.png -vcodec libvpx -acodec libvorbis -t 4 -map [video] -map [audio] -filter_complex negate, hflip [video]; aevalsrc=sin(440*2*PI*t) [audio] /path/to/test2.webm
57
+
71
58
  ## Contributing
72
59
 
73
60
  1. Fork it
data/lib/media.rb CHANGED
@@ -4,17 +4,22 @@ require_relative 'media/command'
4
4
  require_relative 'media/container'
5
5
  require_relative 'media/filter'
6
6
  require_relative 'media/input'
7
- require_relative 'media/label'
8
7
  require_relative 'media/option'
9
8
  require_relative 'media/output'
10
- require_relative 'media/size'
11
-
12
- require_relative 'media/builder/command/converter'
9
+ require_relative 'media/helper'
13
10
 
14
11
  module Media
15
12
  extend self
16
13
 
17
- def convert(&blk)
18
- Command::Converter.extend(Builder::Command::Converter).build(&blk)
14
+ def convert(&block)
15
+ Media::Command::Converter.new(&block)
16
+ end
17
+
18
+ def size(args)
19
+ Media::Helper::Size.new(args)
20
+ end
21
+
22
+ def label(name)
23
+ Media::Helper::Label.new(name: name)
19
24
  end
20
25
  end
@@ -1,4 +1,6 @@
1
1
  require_relative 'subshell'
2
+ require_relative 'progress'
3
+ require_relative '../option'
2
4
 
3
5
  module Media
4
6
  module Command
@@ -6,21 +8,65 @@ module Media
6
8
 
7
9
  attr_accessor :options, :inputs, :outputs
8
10
 
9
- def initialize(args={})
11
+ def initialize(args={}, &block)
10
12
  @options = Array args.fetch(:options, [])
11
13
  @inputs = Array args.fetch(:inputs, [])
12
14
  @outputs = Array args.fetch(:outputs, [])
13
15
 
14
16
  @cmd = args.fetch(:cmd, 'ffmpeg')
15
17
  @subshell = args.fetch(:subshell, Subshell)
18
+ @progress = args.fetch(:progress, Progress)
19
+
20
+ block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
21
+ end
22
+
23
+ def call(&blk)
24
+ progress = @progress.new
25
+
26
+ process = @subshell.new(cmd: to_a).call do |line|
27
+ progress.update(line, &blk)
28
+ end
29
+ progress.complete(&blk) if process.success?
30
+
31
+ process
16
32
  end
17
33
 
18
- def call
19
- @subshell.new(cmd: to_s).call
34
+ def to_a
35
+ [
36
+ @cmd,
37
+ (required_options + options).map(&:to_a),
38
+ inputs.map(&:to_a),
39
+ outputs.map(&:to_a)
40
+ ].flatten
20
41
  end
21
42
 
22
43
  def to_s
23
- [@cmd, options, inputs, outputs].reject(&:empty?).join(' ')
44
+ to_a.join(' ')
45
+ end
46
+
47
+ def options(value=nil)
48
+ return @options unless value
49
+
50
+ @options = value.map {|k,v| Option.new(key: k, value: v)}
51
+ end
52
+ alias_method :options=, :options
53
+
54
+ def add_input(url, &block)
55
+ @inputs << Input.new(url: url, &block)
56
+ end
57
+ alias_method :input, :add_input
58
+
59
+ def add_output(url, &block)
60
+ @outputs << Output.new(url: url, &block)
61
+ end
62
+ alias_method :output, :add_output
63
+
64
+ private
65
+
66
+ def required_options
67
+ [
68
+ Option.new(key: 'v', value: 'info')
69
+ ]
24
70
  end
25
71
  end
26
72
  end
@@ -13,11 +13,15 @@ module Media
13
13
  end
14
14
 
15
15
  def call
16
- @subshell.new(cmd: to_s).call
16
+ @subshell.new(cmd: to_a).call
17
17
  end
18
18
 
19
- def to_s
20
- [@cmd, @options, @input].reject(&:empty?).join(' ')
19
+ def to_a
20
+ [
21
+ @cmd,
22
+ @options.map(&:to_a),
23
+ @input
24
+ ].flatten
21
25
  end
22
26
  end
23
27
  end
@@ -0,0 +1,36 @@
1
+ module Media
2
+ module Command
3
+ class Progress
4
+
5
+ DURATION = /Duration: (\d+):(\d+):(\d+.\d+), start: (\d+.\d+)/
6
+ TIME = /time=(\d+):(\d+):(\d+.\d+)/
7
+
8
+ attr_reader :duration, :time
9
+
10
+ def initialize(args={})
11
+ @duration = args.fetch(:duration, 0.0)
12
+ @time = args.fetch(:time, 0.0)
13
+ end
14
+
15
+ def update(line)
16
+ case line
17
+ when DURATION
18
+ @duration = ($1.to_i * 3600) + ($2.to_i * 60) + $3.to_f + $4.to_f
19
+ yield self if block_given?
20
+ when TIME
21
+ @time = ($1.to_i * 3600) + ($2.to_i * 60) + $3.to_f
22
+ yield self if block_given?
23
+ end
24
+ end
25
+
26
+ def complete
27
+ @time = @duration
28
+ yield self if block_given?
29
+ end
30
+
31
+ def to_f
32
+ time / duration rescue ZeroDivisionError 0.0
33
+ end
34
+ end
35
+ end
36
+ end
@@ -10,11 +10,30 @@ module Media
10
10
  attr_reader :out, :error, :status
11
11
 
12
12
  def initialize(args)
13
- @cmd = args.fetch(:cmd)
13
+ @cmd = Array(args.fetch(:cmd))
14
14
  end
15
15
 
16
16
  def call
17
- @out, @error, @status = Open3.capture3(@cmd)
17
+ @out, @error, @status = Open3.popen3(*@cmd) {|stdin,stdout,stderr,thread|
18
+
19
+ out = Thread.new do
20
+ stdout.each_with_object([]) do |line, memo|
21
+ memo << line
22
+ yield line.strip if block_given?
23
+ end.join
24
+ end
25
+
26
+ err = Thread.new do
27
+ stderr.each_with_object([]) do |line, memo|
28
+ memo << line
29
+ yield line.strip if block_given?
30
+ end.join
31
+ end
32
+
33
+ stdin.close
34
+
35
+ [out.value, err.value, thread.value]
36
+ }
18
37
  self
19
38
  end
20
39
 
@@ -6,9 +6,13 @@ require_relative 'option'
6
6
 
7
7
  module Media
8
8
  class Container
9
+
10
+ attr_reader :url, :options
11
+
9
12
  def initialize(args)
10
- @input = args.fetch(:input)
11
- @probe = args.fetch(:probe, Command::Probe)
13
+ @url = args.fetch(:url)
14
+ @probe = args.fetch(:probe, Command::Probe)
15
+ @options = args.fetch(:options, []) + required_options
12
16
  end
13
17
 
14
18
  def format
@@ -29,10 +33,10 @@ module Media
29
33
  end
30
34
 
31
35
  def probe
32
- @probe.new(input: @input, options: options).call
36
+ @probe.new(input: @url, options: options).call
33
37
  end
34
38
 
35
- def options
39
+ def required_options
36
40
  [
37
41
  Option.new(key: 'print_format', value: 'json'),
38
42
  Option.new(key: 'show_format'),
data/lib/media/filter.rb CHANGED
@@ -1,25 +1,46 @@
1
- require 'shellwords'
2
-
3
1
  require_relative 'filter/argument'
4
2
  require_relative 'filter/chain'
5
3
  require_relative 'filter/graph'
6
- require_relative 'label'
4
+ require_relative 'helper/label'
7
5
 
8
6
  module Media
9
7
  class Filter
10
- attr_reader :name, :arguments, :inputs, :outputs
8
+ attr_reader :name
11
9
 
12
- def initialize(args)
10
+ def initialize(args, &block)
13
11
  @name = args.fetch(:name)
14
12
  @arguments = Array args.fetch(:arguments, [])
15
13
  @inputs = Array args.fetch(:inputs, [])
16
14
  @outputs = Array args.fetch(:outputs, [])
15
+
16
+ block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
17
17
  end
18
18
 
19
19
  def to_s
20
20
  [inputs, filter, outputs].reject(&:empty?).join(' ')
21
21
  end
22
22
 
23
+ def inputs(*value)
24
+ return @inputs if value.empty?
25
+
26
+ @inputs = value.map {|name| Helper::Label.new(name: name)}
27
+ end
28
+ alias_method :inputs=, :inputs
29
+
30
+ def outputs(*value)
31
+ return @outputs if value.empty?
32
+
33
+ @outputs = value.map {|name| Helper::Label.new(name: name)}
34
+ end
35
+ alias_method :outputs=, :outputs
36
+
37
+ def arguments(value=nil)
38
+ return @arguments unless value
39
+
40
+ @arguments = value.map {|k,v| Argument.new(key: k, value: v)}
41
+ end
42
+ alias_method :arguments=, :arguments
43
+
23
44
  private
24
45
 
25
46
  def filter
@@ -3,12 +3,12 @@ module Media
3
3
  class Argument
4
4
  def initialize(args)
5
5
  @key = args.fetch(:key)
6
- @value = args.fetch(:value, true)
6
+ @value = args.fetch(:value, true)
7
7
  end
8
8
 
9
9
  def to_s
10
10
  case @value
11
- when TrueClass, FalseClass then @key
11
+ when TrueClass, FalseClass then @key.to_s
12
12
  else "#{@key}=#{value}"
13
13
  end
14
14
  end
@@ -16,7 +16,7 @@ module Media
16
16
  private
17
17
 
18
18
  def value
19
- @value.gsub(/([\[\]=;,])/, "\\\\\\1")
19
+ @value.to_s.gsub(/([\[\]=;,])/, "\\\\\\1")
20
20
  end
21
21
  end
22
22
  end
@@ -3,13 +3,20 @@ module Media
3
3
  class Chain
4
4
  attr_reader :filters
5
5
 
6
- def initialize(args={}, &blk)
6
+ def initialize(args={}, &block)
7
7
  @filters = args.fetch(:filters, [])
8
+
9
+ block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
8
10
  end
9
11
 
10
12
  def to_s
11
13
  filters.join(', ')
12
14
  end
15
+
16
+ def add_filter(name, &block)
17
+ @filters << Filter.new(name: name, &block)
18
+ end
19
+ alias_method :filter, :add_filter
13
20
  end
14
21
  end
15
22
  end
@@ -5,13 +5,20 @@ module Media
5
5
  class Graph
6
6
  attr_reader :chains
7
7
 
8
- def initialize(args={}, &blk)
8
+ def initialize(args={}, &block)
9
9
  @chains = args.fetch(:chains, [])
10
+
11
+ block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
10
12
  end
11
13
 
12
14
  def to_s
13
- "\"#{chains.join('; ')}\""
15
+ chains.join('; ')
14
16
  end
17
+
18
+ def add_chain(&block)
19
+ @chains << Filter::Chain.new(&block)
20
+ end
21
+ alias_method :chain, :add_chain
15
22
  end
16
23
  end
17
24
  end
@@ -0,0 +1,2 @@
1
+ require_relative 'helper/size'
2
+ require_relative 'helper/label'
@@ -0,0 +1,13 @@
1
+ module Media
2
+ module Helper
3
+ class Label
4
+ def initialize(args)
5
+ @name = args.fetch(:name, [])
6
+ end
7
+
8
+ def to_s
9
+ "[#{@name}]"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Media
2
+ module Helper
3
+ class Size
4
+ def initialize(args)
5
+ @width = args.fetch(:width)
6
+ @height = args.fetch(:height)
7
+ end
8
+
9
+ def to_s
10
+ [@width, @height].join('x')
11
+ end
12
+ end
13
+ end
14
+ end
data/lib/media/input.rb CHANGED
@@ -3,21 +3,36 @@ require_relative 'filter/graph'
3
3
 
4
4
  module Media
5
5
  class Input
6
- attr_reader :options
7
6
 
8
- def initialize(args)
9
- @url = args.fetch(:url)
7
+ def initialize(args, &block)
8
+ @url = args.fetch(:url) { raise ':url required'}
10
9
  @options = Array args.fetch(:options, [])
10
+
11
+ block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
11
12
  end
12
13
 
13
- def to_s
14
- [options, url].reject(&:empty?).join(' ')
14
+ def to_a
15
+ (options << graph << url).compact.map(&:to_a)
15
16
  end
16
17
 
18
+ def options(value=nil)
19
+ return @options unless value
20
+
21
+ @options = value.map {|k,v| Option.new(key: k, value: v)}
22
+ end
23
+ alias_method :options=, :options
24
+
25
+ def graph(&block)
26
+ return @graph unless block_given?
27
+
28
+ @graph = Option.new(key: 'filter_complex', value: Filter::Graph.new(&block))
29
+ end
30
+ alias_method :graph=, :graph
31
+
17
32
  private
18
33
 
19
34
  def url
20
- Option.new(key: 'i', value: @url).to_s
35
+ Option.new(key: 'i', value: @url)
21
36
  end
22
37
  end
23
38
  end
data/lib/media/option.rb CHANGED
@@ -5,11 +5,11 @@ module Media
5
5
  @value = args.fetch(:value, true)
6
6
  end
7
7
 
8
- def to_s
8
+ def to_a
9
9
  case @value
10
- when TrueClass then "-#{@key}"
11
- when FalseClass then "-no#{@key}"
12
- else "-#{@key} #{@value}"
10
+ when TrueClass then ["-#{@key}"]
11
+ when FalseClass then ["-no#{@key}"]
12
+ else ["-#{@key}", @value.to_s]
13
13
  end
14
14
  end
15
15
  end
data/lib/media/output.rb CHANGED
@@ -3,15 +3,43 @@ require_relative 'option'
3
3
  module Media
4
4
  class Output
5
5
 
6
- attr_reader :options
6
+ attr_reader :options, :maps
7
7
 
8
- def initialize(args, &blk)
9
- @url = args.fetch(:url)
8
+ def initialize(args, &block)
9
+ @url = args.fetch(:url) { raise ':url required'}
10
10
  @options = Array args.fetch(:options, [])
11
+ @maps = Array args.fetch(:maps, [])
12
+
13
+ block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
11
14
  end
12
15
 
13
- def to_s
14
- [options, @url].join(' ')
16
+ def to_a
17
+ (options + maps << graph).compact.map(&:to_a) + [@url]
15
18
  end
19
+
20
+ def options(value=nil)
21
+ return @options unless value
22
+
23
+ @options = value.map {|k,v| Option.new(key: k, value: v)}
24
+ end
25
+ alias_method :options=, :options
26
+
27
+ def maps(*value)
28
+ return @maps if value.empty?
29
+
30
+ @maps = value.map {|v| Option.new(key: 'map', value: v)}
31
+ end
32
+ alias_method :maps=, :maps
33
+
34
+ def label(name)
35
+ Media.label(name)
36
+ end
37
+
38
+ def graph(&block)
39
+ return @graph unless block_given?
40
+
41
+ @graph = Option.new(key: 'filter_complex', value: Filter::Graph.new(&block))
42
+ end
43
+ alias_method :graph=, :graph
16
44
  end
17
45
  end
data/lib/media/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Media
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
@@ -18,27 +18,31 @@ module Media
18
18
  end
19
19
 
20
20
  def test_empty_call
21
- subshell.expect(:new, subshell, [cmd: 'ffmpeg'])
22
- subshell.expect(:call, true)
21
+ stub = Class.new do
22
+ def success?; true; end
23
+ end
24
+
25
+ subshell.expect(:new, subshell, [cmd: ['ffmpeg', '-v', 'info']])
26
+ subshell.expect(:call, stub.new)
23
27
 
24
28
  subject.call
25
29
  end
26
30
 
27
31
  def test_with_options
28
- assert_equal 'ffmpeg options', subject(options: ['options']).to_s
32
+ assert_equal ['ffmpeg', '-v', 'info', 'option'], subject(options: [['option']]).to_a
29
33
  end
30
34
 
31
35
  def test_call_with_inputs
32
- assert_equal 'ffmpeg inputs', subject(inputs: ['inputs']).to_s
36
+ assert_equal ['ffmpeg', '-v', 'info', 'input'], subject(inputs: [['input']]).to_a
33
37
  end
34
38
 
35
39
  def test_call_with_outputs
36
- assert_equal 'ffmpeg outputs', subject(outputs: ['outputs']).to_s
40
+ assert_equal ['ffmpeg', '-v', 'info', 'output'], subject(outputs: [['output']]).to_a
37
41
  end
38
42
 
39
43
  def test_call_with_all
40
- assert_equal 'ffmpeg options inputs outputs',
41
- subject(options: ['options'], inputs: ['inputs'], outputs: ['outputs']).to_s
44
+ assert_equal ['ffmpeg', '-v', 'info', 'option', 'input', 'output'],
45
+ subject(options: [['option']], inputs: [['input']], outputs: [['output']]).to_a
42
46
  end
43
47
  end
44
48
  end
@@ -18,19 +18,19 @@ module Media
18
18
  end
19
19
 
20
20
  def test_call
21
- subshell.expect(:new, subshell, [cmd: 'ffprobe input'])
21
+ subshell.expect(:new, subshell, [cmd: ['ffprobe', 'input']])
22
22
  subshell.expect(:call, true)
23
23
 
24
24
  subject(input: ['input']).call
25
25
  end
26
26
 
27
27
  def test_call_with_input
28
- assert_equal 'ffprobe input', subject(input: ['input']).to_s
28
+ assert_equal ['ffprobe', 'input'], subject(input: ['input']).to_a
29
29
  end
30
30
 
31
31
  def test_call_with_all
32
- assert_equal 'ffprobe options input',
33
- subject(options: ['options'], input: ['input']).to_s
32
+ assert_equal ['ffprobe', 'option', 'input'],
33
+ subject(options: [['option']], input: ['input']).to_a
34
34
  end
35
35
  end
36
36
  end
@@ -10,15 +10,15 @@ module Media
10
10
  end
11
11
 
12
12
  def test_stdout
13
- shell = subject.new(cmd: 'echo hello')
13
+ shell = subject.new(cmd: ['echo', 'hello'])
14
14
 
15
15
  assert_equal("hello\n", shell.call.out)
16
16
  end
17
17
 
18
18
  def test_stderr
19
- shell = subject.new(cmd: 'echo hello 1>&2')
20
-
21
- assert_equal("hello\n", shell.call.error)
19
+ shell = subject.new(cmd: ['ffprobe'])
20
+
21
+ assert_match(/^ffprobe/, shell.call.error)
22
22
  end
23
23
 
24
24
  def test_success
@@ -32,6 +32,15 @@ module Media
32
32
 
33
33
  refute(shell.call.success?)
34
34
  end
35
+
36
+ def test_streaming
37
+ shell = subject.new(cmd: ['echo', "hello\n", 'there'])
38
+
39
+ out = []
40
+ shell.call {|line| out << line}
41
+
42
+ assert_equal(['hello', 'there'], out)
43
+ end
35
44
  end
36
45
  end
37
46
  end
@@ -6,7 +6,7 @@ module Media
6
6
  class TestGraph < MiniTest::Unit::TestCase
7
7
 
8
8
  def test_to_s
9
- assert_equal('"a; b; c"', Graph.new(chains: %w(a b c)).to_s)
9
+ assert_equal('a; b; c', Graph.new(chains: %w(a b c)).to_s)
10
10
  end
11
11
  end
12
12
  end
@@ -1,11 +1,11 @@
1
1
  require 'helper'
2
- require 'media/label'
2
+ require 'media/helper/label'
3
3
 
4
4
  module Media
5
5
  class TestLabel < MiniTest::Unit::TestCase
6
6
 
7
7
  def test_to_s
8
- assert_equal '[foo]', Label.new(name: 'foo').to_s
8
+ assert_equal '[foo]', Helper::Label.new(name: 'foo').to_s
9
9
  end
10
10
  end
11
11
  end
@@ -5,9 +5,9 @@ module Media
5
5
  class TestInput < MiniTest::Unit::TestCase
6
6
 
7
7
  def test_to_s
8
- input = Input.new(url: 'url', options: 'options')
8
+ input = Input.new(url: 'url', options: [['option']])
9
9
 
10
- assert_equal('options -i url', input.to_s)
10
+ assert_equal([['option'], ['-i', 'url']], input.to_a)
11
11
  end
12
12
  end
13
13
  end
@@ -9,15 +9,15 @@ module Media
9
9
  end
10
10
 
11
11
  def test_option
12
- assert_equal '-foo bar', subject.new(key: 'foo', value: 'bar').to_s
12
+ assert_equal ['-foo', 'bar'], subject.new(key: 'foo', value: 'bar').to_a
13
13
  end
14
14
 
15
15
  def test_true_flag
16
- assert_equal '-foo', subject.new(key: 'foo').to_s
16
+ assert_equal ['-foo'], subject.new(key: 'foo').to_a
17
17
  end
18
18
 
19
19
  def test_false_flag
20
- assert_equal '-nofoo', subject.new(key: 'foo', value: false).to_s
20
+ assert_equal ['-nofoo'], subject.new(key: 'foo', value: false).to_a
21
21
  end
22
22
  end
23
23
  end
@@ -5,9 +5,9 @@ module Media
5
5
  class TestOutput < MiniTest::Unit::TestCase
6
6
 
7
7
  def test_to_s
8
- output = Output.new(url: 'url', options: 'options')
8
+ output = Output.new(url: 'url', options: [['option']])
9
9
 
10
- assert_equal('options url', output.to_s)
10
+ assert_equal([['option'], 'url'], output.to_a)
11
11
  end
12
12
  end
13
13
  end
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: media
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.3
5
+ version: 0.0.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jamie Hodge
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-13 00:00:00.000000000 Z
12
+ date: 2013-02-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  prerelease: false
@@ -62,24 +62,14 @@ files:
62
62
  UmFrZWZpbGU=
63
63
  - !binary |-
64
64
  bGliL21lZGlhLnJi
65
- - !binary |-
66
- bGliL21lZGlhL2J1aWxkZXIvY29tbWFuZC9jb252ZXJ0ZXIucmI=
67
- - !binary |-
68
- bGliL21lZGlhL2J1aWxkZXIvZmlsdGVyLnJi
69
- - !binary |-
70
- bGliL21lZGlhL2J1aWxkZXIvZmlsdGVyL2NoYWluLnJi
71
- - !binary |-
72
- bGliL21lZGlhL2J1aWxkZXIvZmlsdGVyL2dyYXBoLnJi
73
- - !binary |-
74
- bGliL21lZGlhL2J1aWxkZXIvaW5wdXQucmI=
75
- - !binary |-
76
- bGliL21lZGlhL2J1aWxkZXIvb3V0cHV0LnJi
77
65
  - !binary |-
78
66
  bGliL21lZGlhL2NvbW1hbmQucmI=
79
67
  - !binary |-
80
68
  bGliL21lZGlhL2NvbW1hbmQvY29udmVydGVyLnJi
81
69
  - !binary |-
82
70
  bGliL21lZGlhL2NvbW1hbmQvcHJvYmUucmI=
71
+ - !binary |-
72
+ bGliL21lZGlhL2NvbW1hbmQvcHJvZ3Jlc3MucmI=
83
73
  - !binary |-
84
74
  bGliL21lZGlhL2NvbW1hbmQvc3Vic2hlbGwucmI=
85
75
  - !binary |-
@@ -93,15 +83,17 @@ files:
93
83
  - !binary |-
94
84
  bGliL21lZGlhL2ZpbHRlci9ncmFwaC5yYg==
95
85
  - !binary |-
96
- bGliL21lZGlhL2lucHV0LnJi
86
+ bGliL21lZGlhL2hlbHBlci5yYg==
97
87
  - !binary |-
98
- bGliL21lZGlhL2xhYmVsLnJi
88
+ bGliL21lZGlhL2hlbHBlci9sYWJlbC5yYg==
89
+ - !binary |-
90
+ bGliL21lZGlhL2hlbHBlci9zaXplLnJi
91
+ - !binary |-
92
+ bGliL21lZGlhL2lucHV0LnJi
99
93
  - !binary |-
100
94
  bGliL21lZGlhL29wdGlvbi5yYg==
101
95
  - !binary |-
102
96
  bGliL21lZGlhL291dHB1dC5yYg==
103
- - !binary |-
104
- bGliL21lZGlhL3NpemUucmI=
105
97
  - !binary |-
106
98
  bGliL21lZGlhL3ZlcnNpb24ucmI=
107
99
  - !binary |-
@@ -120,12 +112,12 @@ files:
120
112
  dGVzdC9tZWRpYS9maWx0ZXIvdGVzdF9jaGFpbi5yYg==
121
113
  - !binary |-
122
114
  dGVzdC9tZWRpYS9maWx0ZXIvdGVzdF9ncmFwaC5yYg==
115
+ - !binary |-
116
+ dGVzdC9tZWRpYS9oZWxwZXIvdGVzdF9sYWJlbC5yYg==
123
117
  - !binary |-
124
118
  dGVzdC9tZWRpYS90ZXN0X2ZpbHRlci5yYg==
125
119
  - !binary |-
126
120
  dGVzdC9tZWRpYS90ZXN0X2lucHV0LnJi
127
- - !binary |-
128
- dGVzdC9tZWRpYS90ZXN0X2xhYmVsLnJi
129
121
  - !binary |-
130
122
  dGVzdC9tZWRpYS90ZXN0X29wdGlvbi5yYg==
131
123
  - !binary |-
@@ -175,12 +167,12 @@ test_files:
175
167
  dGVzdC9tZWRpYS9maWx0ZXIvdGVzdF9jaGFpbi5yYg==
176
168
  - !binary |-
177
169
  dGVzdC9tZWRpYS9maWx0ZXIvdGVzdF9ncmFwaC5yYg==
170
+ - !binary |-
171
+ dGVzdC9tZWRpYS9oZWxwZXIvdGVzdF9sYWJlbC5yYg==
178
172
  - !binary |-
179
173
  dGVzdC9tZWRpYS90ZXN0X2ZpbHRlci5yYg==
180
174
  - !binary |-
181
175
  dGVzdC9tZWRpYS90ZXN0X2lucHV0LnJi
182
- - !binary |-
183
- dGVzdC9tZWRpYS90ZXN0X2xhYmVsLnJi
184
176
  - !binary |-
185
177
  dGVzdC9tZWRpYS90ZXN0X29wdGlvbi5yYg==
186
178
  - !binary |-
@@ -1,55 +0,0 @@
1
- require_relative '../../option'
2
- require_relative '../../input'
3
- require_relative '../../output'
4
-
5
- require_relative '../../builder/input'
6
- require_relative '../../builder/output'
7
-
8
- module Media
9
- module Builder
10
- module Command
11
- module Converter
12
-
13
- module ClassMethods
14
-
15
- def build(&blk)
16
- converter = new
17
-
18
- if block_given?
19
- context = eval('self', blk.binding)
20
- converter.instance_variable_set(:@context, context)
21
-
22
- converter.instance_eval(&blk)
23
- end
24
- converter
25
- end
26
- end
27
-
28
- module InstanceMethods
29
-
30
- def option(key, value)
31
- options << Media::Option.new(key: key, value: value)
32
- end
33
-
34
- def input(url, &blk)
35
- inputs << Media::Input.extend(Builder::Input).build(url, &blk)
36
- end
37
-
38
- def output(url, &blk)
39
- outputs << Media::Output.extend(Builder::Output).build(url, &blk)
40
- end
41
-
42
- def method_missing(method, *args, &blk)
43
- @context && @context.send(method, *args, &blk)
44
- end
45
- end
46
-
47
- def self.extended(receiver)
48
- receiver.extend(ClassMethods)
49
- receiver.send(:include, InstanceMethods)
50
- end
51
- end
52
- end
53
- end
54
- end
55
-
@@ -1,48 +0,0 @@
1
- require_relative '../filter/argument'
2
-
3
- module Media
4
- module Builder
5
- module Filter
6
-
7
- module ClassMethods
8
-
9
- def build(name, &blk)
10
- filter = new(name: name)
11
-
12
- if block_given?
13
- context = eval('self', blk.binding)
14
- filter.instance_variable_set(:@context, context)
15
-
16
- filter.instance_eval(&blk)
17
- end
18
- filter
19
- end
20
- end
21
-
22
- module InstanceMethods
23
-
24
- def input(name)
25
- inputs << Media::Label.new(name: name)
26
- end
27
-
28
- def output(name)
29
- outputs << Media::Label.new(name: name)
30
- end
31
-
32
- def argument(key, value=true)
33
- arguments << Media::Filter::Argument.new(key: key, value: value)
34
- end
35
- alias :arg :argument
36
-
37
- def method_missing(method, *args, &blk)
38
- @context && @context.send(method, *args, &blk)
39
- end
40
- end
41
-
42
- def self.extended(receiver)
43
- receiver.extend(ClassMethods)
44
- receiver.send(:include, InstanceMethods)
45
- end
46
- end
47
- end
48
- end
@@ -1,41 +0,0 @@
1
- require_relative '../filter'
2
-
3
- module Media
4
- module Builder
5
- module Filter
6
- module Chain
7
-
8
- module ClassMethods
9
-
10
- def build(&blk)
11
- chain = new
12
-
13
- if block_given?
14
- context = eval('self', blk.binding)
15
- chain.instance_variable_set(:@context, context)
16
-
17
- chain.instance_eval(&blk)
18
- end
19
- chain
20
- end
21
- end
22
-
23
- module InstanceMethods
24
-
25
- def filter(name, &blk)
26
- filters << Media::Filter.extend(Filter).build(name, &blk)
27
- end
28
-
29
- def method_missing(method, *args, &blk)
30
- @context && @context.send(method, *args, &blk)
31
- end
32
- end
33
-
34
- def self.extended(receiver)
35
- receiver.extend(ClassMethods)
36
- receiver.send(:include, InstanceMethods)
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,43 +0,0 @@
1
- require_relative '../../filter/chain'
2
-
3
- require_relative 'chain'
4
-
5
- module Media
6
- module Builder
7
- module Filter
8
- module Graph
9
-
10
- module ClassMethods
11
-
12
- def build(&blk)
13
- graph = new
14
-
15
- if block_given?
16
- context = eval('self', blk.binding)
17
- graph.instance_variable_set(:@context, context)
18
-
19
- graph.instance_eval(&blk)
20
- end
21
- graph
22
- end
23
- end
24
-
25
- module InstanceMethods
26
-
27
- def chain(&blk)
28
- chains << Media::Filter::Chain.extend(Chain).build(&blk)
29
- end
30
-
31
- def method_missing(method, *args, &blk)
32
- @context && @context.send(method, *args, &blk)
33
- end
34
- end
35
-
36
- def self.extended(receiver)
37
- receiver.extend(ClassMethods)
38
- receiver.send(:include, InstanceMethods)
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,46 +0,0 @@
1
- require_relative 'filter/graph'
2
-
3
- module Media
4
- module Builder
5
- module Input
6
-
7
- module ClassMethods
8
-
9
- def build(url, &blk)
10
- input = new(url: url)
11
-
12
- if block_given?
13
- context = eval('self', blk.binding)
14
- input.instance_variable_set(:@context, context)
15
-
16
- input.instance_eval(&blk)
17
- end
18
- input
19
- end
20
- end
21
-
22
- module InstanceMethods
23
-
24
- def option(key, value=true)
25
- @options << Media::Option.new(key: key, value: value).to_s
26
- end
27
-
28
- def graph(&blk)
29
- @options << Option.new(
30
- key: 'filter_complex',
31
- value: Media::Filter::Graph.extend(Filter::Graph).build(&blk)
32
- )
33
- end
34
-
35
- def method_missing(method, *args, &blk)
36
- @context && @context.send(method, *args, &blk)
37
- end
38
- end
39
-
40
- def self.extended(receiver)
41
- receiver.extend(ClassMethods)
42
- receiver.send(:include, InstanceMethods)
43
- end
44
- end
45
- end
46
- end
@@ -1,51 +0,0 @@
1
- require_relative '../option'
2
- require_relative '../filter/graph'
3
-
4
- require_relative 'filter/graph'
5
-
6
- module Media
7
- module Builder
8
- module Output
9
-
10
- module ClassMethods
11
-
12
- def build(url, &blk)
13
- output = new(url: url)
14
-
15
- if block_given?
16
- context = eval('self', blk.binding)
17
- output.instance_variable_set(:@context, context)
18
-
19
- output.instance_eval(&blk)
20
- end
21
- output
22
- end
23
- end
24
-
25
- module InstanceMethods
26
-
27
- def option(key, value=true)
28
- @options << Media::Option.new(key: key, value: value)
29
- end
30
-
31
- def map(value)
32
- @options << Media::Option.new(key: 'map', value: value)
33
- end
34
-
35
- def graph(&blk)
36
- @options << Media::Option.new(key: 'filter_complex',
37
- value: Media::Filter::Graph.extend(Filter::Graph).build(&blk))
38
- end
39
-
40
- def method_missing(method, *args, &blk)
41
- @context && @context.send(method, *args, &blk)
42
- end
43
- end
44
-
45
- def self.extended(receiver)
46
- receiver.extend(ClassMethods)
47
- receiver.send(:include, InstanceMethods)
48
- end
49
- end
50
- end
51
- end
data/lib/media/label.rb DELETED
@@ -1,11 +0,0 @@
1
- module Media
2
- class Label
3
- def initialize(args)
4
- @name = args.fetch(:name, [])
5
- end
6
-
7
- def to_s
8
- "[#{@name}]"
9
- end
10
- end
11
- end
data/lib/media/size.rb DELETED
@@ -1,12 +0,0 @@
1
- module Media
2
- class Size
3
- def initialize(args)
4
- @width = args.fetch(:width)
5
- @height = args.fetch(:height)
6
- end
7
-
8
- def to_s
9
- [@width, @height].join('x')
10
- end
11
- end
12
- end