kastner-kompress 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.
data/kompress.gemspec ADDED
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "kompress"
3
+ s.version = "0.0.2"
4
+ s.date = "2008-09-14"
5
+ s.summary = "Kompress - kompress videos and see progress"
6
+ s.email = "kastner@gmail.com"
7
+ s.homepage = "http://github.com/kastner/kompress.git"
8
+ s.description = "Kompress - kompress videos and see progress"
9
+ s.has_rdoc = false
10
+ s.require_path = '.'
11
+ s.authors = ["Erik Kastner"]
12
+ s.files = ["kompress.gemspec", "lib/kompress", "lib/kompress/compress.rb",
13
+ "lib/kompress/config.rb", "lib/kompress/exceptions.rb", "lib/kompress/job.rb",
14
+ "lib/kompress.rb", "README.mkdn", "test/config_test.rb", "test/job-freeze",
15
+ "test/job-status", "test/job_test.rb", "test/test_helper.rb"]
16
+
17
+ s.rdoc_options = ["--main", "README.mkdn"]
18
+ end
data/lib/kompress.rb CHANGED
@@ -1,6 +1,11 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ require 'yaml'
4
+
1
5
  require 'kompress/compress'
2
6
  require 'kompress/config'
3
7
  require 'kompress/exceptions'
8
+ require 'kompress/job'
4
9
 
5
10
  module Kompress
6
11
  extend Compress
@@ -29,8 +29,12 @@ module Kompress
29
29
  end
30
30
  end
31
31
 
32
+ def reset
33
+ @commands = @settings = nil
34
+ end
35
+
32
36
  class Preset
33
- attr_reader :name
37
+ attr_reader :name, :command
34
38
  attr_accessor :options
35
39
 
36
40
  def initialize(name, options = {})
@@ -39,12 +43,6 @@ module Kompress
39
43
  @options = options
40
44
  end
41
45
 
42
- def command
43
- kc = Kompress::Config
44
- replacements = kc.settings.merge(kc.commands.merge(@options))
45
- @command.gsub(/:\w+/) {|s| replacements[s.gsub(/^:/,'').intern] || s }
46
- end
47
-
48
46
  def description
49
47
  @options[:description] || @name
50
48
  end
@@ -0,0 +1,152 @@
1
+ module Kompress
2
+ class Job
3
+ attr_accessor :options, :job_id, :input_file, :container_type
4
+ attr_accessor :state
5
+
6
+ def self.from_file(file)
7
+ rpls = YAML.load(open(file).read)
8
+ job = new
9
+ job.instance_eval do
10
+ @state = :running
11
+ @job_id = rpls[:job_id]
12
+ @container_type = rpls[:container_type]
13
+ @input_file = rpls[:input_file]
14
+ @options = rpls
15
+ def replacements; @options; end
16
+ end
17
+ job
18
+ end
19
+
20
+ def self.from_preset(preset, input_file, container_type = "mp4")
21
+ config_preset = Kompress::Config.presets[preset]
22
+ raise Kompress::NoConfigurationError unless config_preset
23
+
24
+ job = new
25
+ job.fill(preset, config_preset.command, input_file, container_type, config_preset.options)
26
+ job
27
+ end
28
+
29
+ def fill(name, command, input_file, container_type, options)
30
+ @state = :pending
31
+ @options, @input_file, @command = options, input_file, command
32
+ @container_type = container_type
33
+ @job_id = Time.now.to_i.to_s + "-" + name.to_s
34
+ end
35
+
36
+ def kc_replacements
37
+ kc = Kompress::Config
38
+ (kc.settings || {}).merge((kc.commands || {}).merge(@options))
39
+ end
40
+
41
+ def replacements
42
+ rpl = {}
43
+ rpl[:job_id] = @job_id
44
+ rpl[:container_type] = @container_type
45
+ rpl[:input_file] = @input_file
46
+ rpl.merge(kc_replacements)
47
+ end
48
+
49
+ def command
50
+ substitute(@command, replacements)
51
+ end
52
+
53
+ def post_command
54
+ substitute(options[:post_command], replacements)
55
+ end
56
+
57
+ def temp_file
58
+ input_file.gsub(/\.(mov|avi|mp4|flv|wmv)$/, ".tmp.#{container_type}")
59
+ end
60
+
61
+ def output_file
62
+ input_file.gsub(/\.(mov|avi|mp4|flv|wmv)$/, ".#{container_type}")
63
+ end
64
+
65
+ def substitute(string, subs)
66
+ string.gsub(/:\w+/) do |s|
67
+ s.gsub!(/^:/, '')
68
+ if respond_to?(s)
69
+ send(s)
70
+ else
71
+ subs[s.gsub(/^:/,'').intern] || s
72
+ end
73
+ end
74
+ end
75
+
76
+ def status_file
77
+ kc_replacements[:directory] + "/kompress-#{@job_id}"
78
+ end
79
+
80
+ def state_file
81
+ kc_replacements[:directory] + "/kompress-#{@job_id}.state"
82
+ end
83
+
84
+ def done_file
85
+ kc_replacements[:directory] + "/kompress-#{@job_id}.done"
86
+ end
87
+
88
+ def status_contents
89
+ open(status_file).read
90
+ end
91
+
92
+ def frame_rate
93
+ @frame_rate ||= status_contents[@options[:frame_rate_regexp], 1].to_f
94
+ end
95
+
96
+ def duration
97
+ @duration ||= begin
98
+ d = status_contents[@options[:duration_regexp], 1]
99
+ if (d.match(/:/))
100
+ p = d.split(/:/)
101
+ p[-1].to_f + p[-2].to_f * 60 + p[-3].to_f * 60 * 60
102
+ else
103
+ d.to_f
104
+ end
105
+ end
106
+ end
107
+
108
+ def total_frames
109
+ duration * frame_rate
110
+ end
111
+
112
+ def current_frame
113
+ return 0 unless @state == :running
114
+ matches = status_contents.scan(@options[:current_frame_regexp])
115
+
116
+ if (File.exists?(done_file))
117
+ @state = :done
118
+ finalize
119
+ end
120
+
121
+ matches.last[0].to_i
122
+ end
123
+
124
+ def finalize
125
+ system(post_command) if post_command
126
+ cleanup
127
+ end
128
+
129
+ def cleanup
130
+ File.unlink(state_file)
131
+ File.unlink(status_file)
132
+ File.unlink(done_file)
133
+ File.unlink(temp_file)
134
+ end
135
+
136
+ def write_state_to_disk
137
+ File.open(state_file, "w") do |f|
138
+ f.puts replacements.to_yaml
139
+ end
140
+ end
141
+
142
+ def go
143
+ @state = :running
144
+ write_state_to_disk
145
+ Thread.new do
146
+ system command
147
+ end
148
+
149
+ while (!File.exists?(status_file)); sleep 0.2; end
150
+ end
151
+ end
152
+ end
data/test/config_test.rb CHANGED
@@ -26,8 +26,9 @@ describe "Kompress::Config" do
26
26
  Kompress::Config.settings[:directory].should == "/t"
27
27
  end
28
28
 
29
- it "should substitue placeholders" do
30
- Kompress::Config.presets[:test].command.should == "/usr/bin/ffmpeg go > /t"
29
+ it "should be emptyable" do
30
+ Kompress::Config.reset
31
+ Kompress::Config.settings.should == nil
31
32
  end
32
33
  end
33
34
 
data/test/job-freeze ADDED
@@ -0,0 +1,11 @@
1
+ ---
2
+ :frame_rate_regexp: !ruby/regexp /0.0,,,,,Video,.*q=.*,([\d\.]+)$/
3
+ :job_id: 1221549341-rad
4
+ :post_command: ":qt_faststart :temp_file :output_file"
5
+ :qt_faststart: /usr/bin/qt-faststart
6
+ :current_frame_regexp: !ruby/regexp /frame=\s*(\d+)/
7
+ :input_file: ~/Development/Ruby/test.mov
8
+ :container_type: mp4
9
+ :duration_regexp: !ruby/regexp /Duration-(\d+)/
10
+ :ffmpeg: /Library/Application\ Support/Techspansion/vh131ffmpeg
11
+ :directory: /tmp
data/test/job-status ADDED
@@ -0,0 +1,24 @@
1
+ FFmpeg version SVN-r9226, Copyright (c) 2000-2007 Fabrice Bellard, et al.
2
+ libavutil: 49.4.0 libavcodec: 51.40.4 libavformat: 51.12.1
3
+ built: Feb 12 2008 19:58:15, gcc: 4.0.1 (Apple Computer, Inc. build 5367), i386
4
+
5
+ Seems stream 0 codec frame rate differs from container frame rate: 1000.00 (1000/1) -> 44.92 (539/12)
6
+ Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/kastner/Development/Ruby/test.mov':
7
+ Duration-06
8
+ start-0.000000
9
+ bitrate-1585
10
+
11
+ 0.0,,,(eng),,Video,mpeg4,yuv420p,640,480,44.92
12
+ 0.1,,,(eng),,Audio,mpeg4aac,44100,2
13
+ Output #0, mp4, to '/Users/kastner/Development/Ruby/test.tmp.mp4':
14
+ 0.0,,,,,Video,mpeg4,yuv420p,640,480, q=1-31,44.92
15
+ 0.1,,,,,Audio,libfaac,44100,2,64
16
+ Stream mapping:
17
+ Stream #0.0 -> #0.0
18
+ Stream #0.1 -> #0.1
19
+ Press [q] to stop encoding
20
+ frame= 54 fps= 0 q=4.2 size= 183kB time=1.2 bitrate=1244.3kbits/s
21
+ frame= 114 fps=113 q=8.9 size= 269kB time=2.5 bitrate= 895.3kbits/s
22
+ frame= 157 fps=115 q=9.4 Lsize= 330kB time=3.4 bitrate= 796.3kbits/s
23
+ video:12kB audio:19kB global headers:0kB muxing overhead 935.696529%
24
+ Received signal 2: terminating.
data/test/job_test.rb ADDED
@@ -0,0 +1,115 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ describe "Kompress::Job" do
4
+ setup do
5
+ Kompress::Config.write do |k|
6
+ k.command :ffmpeg => "/usr/bin/ffmpeg"
7
+ k.setting :directory => "/t"
8
+
9
+ k.preset :test => {
10
+ :command => ":ffmpeg go > :directory/:job_id"
11
+ }
12
+ end
13
+
14
+ @job = Kompress::Job.from_preset(:test, "")
15
+ end
16
+
17
+ it "should substitue placeholders" do
18
+ @job.command.should.match /\/ffmpeg/
19
+ end
20
+
21
+ it "should substitue job_id placeholder" do
22
+ @job.command.should == "/usr/bin/ffmpeg go > /t/#{@job.job_id}"
23
+ end
24
+
25
+ it "should set a status file" do
26
+ @job.status_file.should == "/t/kompress-#{@job.job_id}"
27
+ end
28
+ end
29
+
30
+ describe "A fake job" do
31
+ setup do
32
+ Kompress::Config.write do |k|
33
+ k.preset :t => { :duration_regexp => /Duration: ([\d:]+)/ }
34
+ end
35
+
36
+ @job = Kompress::Job.from_preset(:t, "")
37
+ @job.stubs(:status_contents).returns("Duration: 00:01:26.95, start: 0.0000")
38
+ end
39
+
40
+ it "should calculate seconds" do
41
+ @job.duration.should == 86.0
42
+ end
43
+ end
44
+
45
+ describe "A real job" do
46
+ setup do
47
+ Kompress::Config.write do |k|
48
+ k.command :ffmpeg => "/Library/Application\\ Support/Techspansion/vh131ffmpeg"
49
+ k.setting :directory => "/tmp"
50
+ k.setting :qt_faststart => "/usr/bin/qt-faststart"
51
+
52
+ k.preset :rad => {
53
+ :command => %Q{:ffmpeg -y -i :input_file :temp_file 2>> :status_file ; echo done > :done_file},
54
+ :post_command => %Q{:qt_faststart :temp_file :output_file},
55
+ :frame_rate_regexp => /0.0,,,,,Video,.*q=.*,([\d\.]+)$/,
56
+ :duration_regexp => /Duration-(\d+)/,
57
+ :current_frame_regexp => /frame=\s*(\d+)/
58
+ }
59
+
60
+ @job = Kompress::Job.from_preset(:rad, "~/Development/Ruby/test.mov")
61
+ @job.state = :running
62
+ end
63
+
64
+ @job.stubs(:status_contents).returns(open(File.dirname(__FILE__) + '/job-status').read)
65
+ end
66
+
67
+ it "should know it's post_command" do
68
+ @job.post_command.should == "/usr/bin/qt-faststart ~/Development/Ruby/test.tmp.mp4 ~/Development/Ruby/test.mp4"
69
+ end
70
+
71
+ it "should know frame rate" do
72
+ @job.frame_rate.should == 44.92
73
+ end
74
+
75
+ it "should know duration" do
76
+ @job.duration.should == 6.0
77
+ end
78
+
79
+ it "should know total frames" do
80
+ @job.total_frames.should == 269.52
81
+ end
82
+
83
+ it "should know it's current frame #" do
84
+ @job.current_frame.should == 157
85
+ # puts @job.replacements.to_yaml
86
+ end
87
+ end
88
+
89
+ describe "A frozen job" do
90
+ setup do
91
+ Kompress::Config.reset
92
+ @job = Kompress::Job.from_file(File.dirname(__FILE__) + "/job-freeze")
93
+ @job.stubs(:status_contents).returns(open(File.dirname(__FILE__) + '/job-status').read)
94
+ end
95
+
96
+ it "should have the right job id" do
97
+ @job.job_id.should == "1221549341-rad"
98
+ end
99
+
100
+ it "should be able to fetch the duration" do
101
+ @job.duration.should == 6.0
102
+ end
103
+
104
+ it "should have the right post_command" do
105
+ @job.post_command.should == "/usr/bin/qt-faststart ~/Development/Ruby/test.tmp.mp4 ~/Development/Ruby/test.mp4"
106
+ end
107
+
108
+ it "should have a lame kc_replacements method" do
109
+ @job.kc_replacements.should == @job.options
110
+ end
111
+
112
+ it "should be considered active" do
113
+ @job.state.should == :running
114
+ end
115
+ end
data/test/test_helper.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  begin
2
2
  require 'test/spec'
3
+ require 'mocha'
3
4
  rescue LoadError
4
5
  require 'rubygems'
5
6
  require 'test/spec'
7
+ require 'mocha'
6
8
  end
7
9
 
8
10
  begin
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kastner-kompress
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
  - Erik Kastner
@@ -22,13 +22,19 @@ extensions: []
22
22
  extra_rdoc_files: []
23
23
 
24
24
  files:
25
- - lib/kompress.rb
26
- - README.mkdn
25
+ - kompress.gemspec
26
+ - lib/kompress
27
27
  - lib/kompress/compress.rb
28
28
  - lib/kompress/config.rb
29
29
  - lib/kompress/exceptions.rb
30
- - test/test_helper.rb
30
+ - lib/kompress/job.rb
31
+ - lib/kompress.rb
32
+ - README.mkdn
31
33
  - test/config_test.rb
34
+ - test/job-freeze
35
+ - test/job-status
36
+ - test/job_test.rb
37
+ - test/test_helper.rb
32
38
  has_rdoc: false
33
39
  homepage: http://github.com/kastner/kompress.git
34
40
  post_install_message: