sensible-cinema 0.14.3 → 0.14.4

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,3 +1,7 @@
1
+ == 0.14.4 ==
2
+
3
+ Add a progress bar.
4
+
1
5
  == 0.14.{2,3} ==
2
6
 
3
7
  Minor changes.
data/Rakefile CHANGED
@@ -8,13 +8,12 @@ Jeweler::Tasks.new do |s|
8
8
  s.authors = ["Roger Pack"]
9
9
  s.add_dependency 'sane', '>= 0.22.0'
10
10
  s.add_dependency 'rdp-win32screenshot', '>= 0.0.7.3'
11
- s.add_dependency 'mini_magick' # for ocr...
11
+ s.add_dependency 'mini_magick', '>= 3.1' # for ocr...
12
12
  s.add_dependency 'jruby-win32ole'
13
13
  s.add_dependency 'rdp-ruby-wmi'
14
- s.add_dependency 'ffi'
14
+ s.add_dependency 'ffi' # mouse, etc.
15
15
  s.add_development_dependency 'rspec' # prefer rspec 2 I guess...
16
16
  s.add_development_dependency 'jeweler'
17
- s.add_development_dependency 'rdp-rmagick'
18
17
  s.add_development_dependency 'hitimes' # now jruby compat. yea!
19
18
  s.extensions = ["ext/mkrf_conf.rb"]
20
19
  end
data/TODO CHANGED
@@ -1,24 +1,21 @@
1
1
  == medium ==
2
2
 
3
-
4
3
  == probably next up+low prio ==
5
4
 
6
5
  better timing for the saver-er...
7
6
  match better
8
7
  merge better
9
8
  speed up unit tests
10
- add a progress bar for encoding
11
9
 
12
10
  == slightly lower than that even ==
13
11
 
14
- auto-select EDL
15
-
16
12
  == slightly lower than that ==
17
13
 
14
+ auto-select EDL
15
+
18
16
  can parse IMDB (require they put in the URL by hand fer now)
19
17
  add stuffs to imdb hmmm
20
18
  IMDB easy mapping
21
- screencast of things helpful (use, creation...).
22
19
  unit test the GUI
23
20
  can have collaborators re-selling EL's
24
21
  good license for their stuff like "public domain" or what not :P
@@ -36,7 +33,8 @@ auto-select EDL
36
33
  partner (Jon, Karlie if interested...give beta)
37
34
  survey/beta release
38
35
  a certified clean list (?)
39
- == DVD backlog ==
36
+
37
+ == DVD backlog (unordered) ==
40
38
 
41
39
  some way to choose between x,y,z when auto-select sees several
42
40
  careful phrasing "if you can't afford it..."
@@ -49,8 +47,6 @@ the authors of the program might not be liable for damages. We don't feel disho
49
47
  we own the DVD and have it with us when we watch the edited version.
50
48
  blu-ray support somehow (real-time? rip?)
51
49
 
52
- prototypes of the experimental stuff.
53
-
54
50
  some type of one click installer that can setup the registry...
55
51
  auto-assignment of EDL's to media:
56
52
  auto-play option for DVD's (auto-start?)
@@ -62,6 +58,15 @@ instructions on how to do their own (private) or do one and submit it (public),
62
58
 
63
59
  == random backlog ... note: just plow forward, to "grab" available ideas...except that for now, just what *I* plan on needing for myself (filters for what I need/want). ==
64
60
 
61
+ screencast of things helpful (use, creation...).
62
+ tune up the levels...
63
+ prototypes of the experimental stuff (overlay, track time while recording -> map file, specifiable levels, more?)
64
+
65
+ the overlayer "freeze frames" in vista
66
+
67
+ 0:01:01.9 next will be at 0:01:02.0s (r [or q to quit]):
68
+ 0:01:04.0 next will be at 0:01:06.5s (blanked) (r [or q to quit]): "warning--unable to track screen time for some reason" # *of course you can't track it now!*
69
+
65
70
  byu.tv descriptor
66
71
  youtube non full screen: work with all browsers
67
72
  easier "here's how on the command line, BTW"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.14.3
1
+ 0.14.4
data/bin/sensible-cinema CHANGED
@@ -25,8 +25,9 @@ module SensibleSwing
25
25
  jlabel.set_bounds(44,44,136,14)
26
26
  panel.add jlabel
27
27
  b = JButton.new( "Play Hulu, Youtube, or a DVD (Tracking)" ).on_clicked {
28
+ Thread.new { go_sc } # needs to be in its own thread becuase it blocks,
29
+ # so "this thread" is the uni-swing thread, gets blocked, and the overlayer can't repaint
28
30
  self.close
29
- go_sc
30
31
  }
31
32
  button_width = 230
32
33
  b.set_bounds(44,120,button_width,23)
@@ -57,8 +58,12 @@ module SensibleSwing
57
58
  eval File.read(__FILE__), nil, __FILE__
58
59
  p 're-evaled it'
59
60
  }
60
- reload.set_bounds(44,280,200,23)
61
+ reload.set_bounds(44,300,200,23)
61
62
  panel.add reload if ARGV.find{|a| a == '--test'}
63
+ @p = JProgressBar.new(0, 100)
64
+ @p.set_value 0
65
+ @p.set_bounds(44,280,button_width,23)
66
+ panel.add @p
62
67
  @buttons = [b,c,d,@exit]
63
68
 
64
69
  end
@@ -87,37 +92,45 @@ module SensibleSwing
87
92
  bat_file_or_xspf = VLCProgrammer.convert_to_full_xspf(descriptors, save_to, drive, dvd_title_track)
88
93
  temp_dir = Dir.tmpdir
89
94
  if should_save_file
90
- temp_file = temp_dir + '/' + 'convert_it.bat'
91
- File.write(temp_file, bat_file_or_xspf)
92
95
  # allow our popups to still be serviced while it is running
93
96
  Thread.new {
94
- run_copy_commands temp_file, save_to
97
+ run_copy_commands bat_file_or_xspf, save_to
95
98
  }
96
99
  else
97
100
  temp_file = temp_dir + '/' + 'vlc.xspf'
98
101
  File.write(temp_file, bat_file_or_xspf)
99
102
  command = "vlc \"#{temp_file.to_filename}\" vlc://quit"
100
103
  p 'running', command
101
- system(c) # blocks the current window while running...
104
+ system(commands) # blocks the current window while running...
102
105
  end
103
106
  # TODO warn if they don't have VLC installed, with instructions...
104
107
  # LODO warn if they will overwrite a file in the end
105
108
  end
106
109
 
107
- def run_copy_commands temp_file, save_to
110
+ def run_copy_commands batch_file, save_to
108
111
  popup = ModeLessDialog.new("Running the encoding in the background...\n" +
109
112
  "This could take quite awhile, and will prompt you when it is done.\n" +
110
113
  "It may also cause small popup ballon dialogs to appear.")
111
- p 'running', temp_file, 'to ' + save_to + '.ps'
114
+ p 'saving to ' + save_to + '.ps'
112
115
  @buttons.each{|b| b.set_enabled false}
113
- success = system(temp_file) unless ARGV.find{|a| a == '--test'}
116
+ success = true
117
+ lines = batch_file.lines.to_a
118
+ total_size = lines.length.to_f
119
+ lines.each_with_index{|l, idx|
120
+ if success
121
+ p 'running', l, 'percent', idx/total_size
122
+ success = system(l) unless ARGV.find{|a| a == '--test'} # doesn't seem to cancel out early for some reason..
123
+ @p.set_value(idx/total_size*100)
124
+ sleep 1
125
+ end
126
+ }
127
+ @p.set_value(0)
114
128
  @buttons.each{|b| b.set_enabled true}
115
129
  popup.dispose
116
130
  if success
117
131
  JOptionPane.showMessageDialog(nil, " Done--you may now watch file #{save_to}.ps in VLC player", "Done!", JOptionPane::INFORMATION_MESSAGE)
118
132
  show_file = "explorer /e,/select,\"#{File.expand_path(save_to).to_filename}.ps\""
119
133
  system show_file
120
- File.delete temp_file
121
134
  self.close
122
135
  else
123
136
  JOptionPane.showMessageDialog(nil, " Failed--please examine #{temp_file} and screen output and report back!", "Failed", JOptionPane::ERROR_MESSAGE)
@@ -10,10 +10,10 @@ for file in ['overlayer', 'keyboard_input', 'screen_tracker', 'mouse', 'file_cho
10
10
  end
11
11
 
12
12
 
13
- def go_sc(args=ARGV)
13
+ def go_sc(args)
14
14
 
15
15
  $VERBOSE = 1 if args.delete('-v')
16
- $TEST = 1 if args.delete('-t')
16
+ $DEBUG = 1 if args.delete('-d')
17
17
  if args.delete('--clear-cache')
18
18
  OCR.clear_cache!
19
19
  puts 'cleared cache'
@@ -96,12 +96,13 @@ def go_sc(args=ARGV)
96
96
  Blanker.shutdown # lodo move this and the 'q' key to within overlayer
97
97
  OCR.serialize_cache_to_disk
98
98
  }
99
- key_input.handle_keystrokes_forever # when this method exits, we want to exit fully...
99
+ puts 'syntax from command line: ' + player_description + ' ' + scene_list
100
+ key_input.handle_keystrokes_forever # blocking...
100
101
 
101
102
  end
102
103
  end
103
104
 
104
105
  if __FILE__ == $0
105
106
  puts 'Welcome to Sensible Cinema...'
106
- go_sc
107
+ go_sc ARGV
107
108
  end
data/lib/blanker.rb CHANGED
@@ -13,10 +13,10 @@ else
13
13
  @fr.default_close_operation = JFrame::EXIT_ON_CLOSE
14
14
  @fr.set_size(2000, 2000) # ltodo better size ?
15
15
  cp = @fr.getContentPane
16
- cp.setBackground(java.awt.Color.black);
17
-
16
+ cp.setBackground(java.awt.Color.black);
18
17
 
19
18
  @label = JLabel.new
19
+ @label.set_text 'blanked'
20
20
  @fr.add(@label)
21
21
  @label.setForeground(java.awt.Color.white);
22
22
  @label.repaint
@@ -25,24 +25,27 @@ else
25
25
  @fr.set_resizable(false)
26
26
  @fr.set_visible(true) # have to do this once, to ever see the thing
27
27
  # lodo does this really speed things up to pre-create it? that icon is a bit ugly...
28
+ @fr.repaint
28
29
  unblank_full_screen! # and hide it to start
29
30
  end
30
31
 
31
32
  def self.blank_full_screen! seconds
33
+ # somewhat hacky work around for doze: http://www.experts-exchange.com/Programming/Languages/Java/Q_22977145.html
34
+ @fr.setAlwaysOnTop(false)
35
+ @fr.setAlwaysOnTop(true)
36
+ @fr.set_location(0,0)
37
+ @fr.repaint # early paint, just in case that helps it pop up faster :)
32
38
  if seconds
33
39
  @label.set_text " #{seconds} s"
34
40
  else
35
41
  @label.set_text " Blank section"
36
42
  end
37
- # somewhat hacky work around for doze: http://www.experts-exchange.com/Programming/Languages/Java/Q_22977145.html
38
- @fr.setAlwaysOnTop(false)
39
- @fr.setAlwaysOnTop(true)
40
- @fr.set_location(0,0)
41
43
  end
42
44
 
43
45
  def self.unblank_full_screen!
44
- # off screen...
46
+ # move it off screen...
45
47
  @fr.set_location(-2100, -2100)
48
+ @fr.repaint 0
46
49
  end
47
50
 
48
51
  def self.shutdown
data/lib/ocr.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  im_path = File.expand_path(File.dirname(__FILE__) + "/../vendor/imagemagick") # convert.exe wants to only be chosen from here...
2
- ENV['PATH'] = im_path + ';' + ENV['PATH']
2
+ #ENV['PATH'] = im_path + ';' + ENV['PATH']
3
3
 
4
4
  # helper for OCR'ing single digits that were screen captured
5
5
  module OCR
6
6
 
7
- GOCR = File.expand_path(File.dirname(__FILE__) + "/../vendor/gocr048.exe -C 0-9:/ ")
7
+ GOCR = File.expand_path(File.dirname(__FILE__) + "/../vendor/gocr049.exe -C 0-9:/ ")
8
8
 
9
9
  CACHE = {}
10
10
 
@@ -26,7 +26,7 @@ module OCR
26
26
  return ":"
27
27
  end
28
28
  end
29
- image = MiniMagick::Image.from_blob(memory_bitmap)
29
+ image = MiniMagick::Image.read(memory_bitmap)
30
30
  # any operation on image is expensive, requires convert.exe in path...
31
31
  if options[:should_invert]
32
32
  # hulu wants negate
@@ -36,15 +36,17 @@ module OCR
36
36
  end
37
37
 
38
38
  image.format(:pnm)
39
+ # I think it's VLC full screen that wants sharpening...
39
40
  image.sharpen(2) if options[:sharpen] # hulu does *not* want sharpen, though I haven't checked it too closely...
40
41
 
41
42
  previous = nil
42
43
  p options if $DEBUG
43
44
  raise 'you must pass in OCR levels in the player description' unless options[:levels]
44
45
  for level in options[:levels]
45
- a = `#{GOCR} -l #{level} #{image.path} 2>NUL`
46
+ command = "#{GOCR} -l #{level} #{image.path} 2>NUL"
47
+ a = `#{command}`
46
48
  if a =~ /[0-9]/
47
- # it can be like "_1_\n"
49
+ # it might be funky like "_1_\n"
48
50
  a.strip!
49
51
  a.gsub!('_', '')
50
52
  a = a.to_i
@@ -74,8 +76,7 @@ module OCR
74
76
  def unserialize_cache_from_disk
75
77
  if File.exist? CACHE_FILE
76
78
  CACHE.merge!(Marshal.load(File.binread(CACHE_FILE)))
77
- end
78
-
79
+ end
79
80
  end
80
81
 
81
82
  extend self
data/lib/overlayer.rb CHANGED
@@ -192,7 +192,7 @@ class OverLayer
192
192
  end
193
193
  end
194
194
  check_reload_yaml
195
- time + state + "(r [or q to quit]): "
195
+ time + state + "(r [or ctrl+c to quit]): "
196
196
  end
197
197
 
198
198
  def keyboard_input char
@@ -39,7 +39,7 @@ class ScreenTracker
39
39
  raise 'poor height or wrong window'
40
40
  end
41
41
  @digits = digits
42
- @displayed_warning = false
42
+ @previously_displayed_warning = false
43
43
  @dump_digit_count = 1
44
44
  pps 'using x',@x, 'from x', x, 'y', @y, 'from y', y,'x2',@x2,'y2',@y2,'digits', @digits if $VERBOSE
45
45
  end
@@ -82,18 +82,20 @@ class ScreenTracker
82
82
  def dump_bmp filename = 'dump.bmp'
83
83
  File.binwrite filename, get_bmp
84
84
  File.binwrite 'all.' + filename, get_full_bmp
85
- dump_digits get_digits_as_bitmaps if @digits
85
+ dump_digits(get_digits_as_bitmaps, 'dump_bmp') if @digits
86
86
  end
87
87
 
88
- def dump_digits digits
89
- for type, bitmap in get_digits_as_bitmaps
90
- File.binwrite type.to_s + '.' + @dump_digit_count.to_s + '.bmp', bitmap
91
- end
92
- print 'debug dumped digits that Im about to parse:', @dump_digit_count, "\n"
93
- @dump_digit_count += 1
88
+ def dump_digits digits, message
89
+ p "#{message} dumping digits to dump no: #{@dump_digit_count} #{Time.now.to_f}"
90
+ for type, bitmap in digits
91
+ File.binwrite type.to_s + '.' + @dump_digit_count.to_s + '.bmp', bitmap
92
+ end
93
+ File.binwrite @dump_digit_count.to_s + '.mrsh', Marshal.dump(digits)
94
+ @dump_digit_count += 1
94
95
  end
95
96
 
96
97
  DIGIT_TYPES = [:hours, :minute_tens, :minute_ones, :second_tens, :second_ones]
98
+
97
99
  # returns like {:hours => nil, :minutes_tens => raw_bmp, ...
98
100
  def get_digits_as_bitmaps
99
101
  # @digits are like {:hours => [100,5], :minute_tens => [x, width], :minute_ones, :second_tens, :second_ones}
@@ -115,7 +117,6 @@ class ScreenTracker
115
117
  [@x,@y,@x2,@y2]
116
118
  end
117
119
 
118
- # split out for unit testing purposes
119
120
  def identify_digit bitmap
120
121
  OCR.identify_digit(bitmap, @digits)
121
122
  end
@@ -132,66 +133,76 @@ class ScreenTracker
132
133
  if current != original
133
134
  if @digits
134
135
  got = attempt_to_get_time_from_screen time_before_scan
135
- if @displayed_warning && got
136
+ if @previously_displayed_warning && got
136
137
  # reassure user :)
137
138
  p 'tracking it successfully again'
138
- @displayed_warning = false
139
+ @previously_displayed_warning = false
139
140
  end
140
141
  return got
141
142
  else
142
- puts 'screen time change only detected... [unexpected]'
143
+ puts 'screen time change only detected... [unexpected]' # unit tests do this still
143
144
  return
144
145
  end
145
146
  else
146
147
  # no screen change detected ...
147
148
  sleep 0.02
148
- if(Time.now - time_since_last_screen_change > 2)
149
+ if(Time.now - time_since_last_screen_change > 2.0)
149
150
  # display a warning
150
- p 'warning--unable to track screen time for some reason'
151
- @displayed_warning = true
152
- time_since_last_screen_change = Time.now
153
- # also reget window hwnd, just in case that's the problem...(can be with VLC)
151
+ p 'warning--unable to track screen time for some reason [perhaps screen obscured or it\'s not playing yet?]'
152
+ @previously_displayed_warning = true
153
+ time_since_last_screen_change = Time.now
154
+ # also reget window hwnd, just in case that's the problem...(can be with VLC moving from title to title)
154
155
  get_hwnd
155
156
  end
156
157
  end
157
158
  }
158
159
  end
159
160
 
160
- def attempt_to_get_time_from_screen start
161
+ def attempt_to_get_time_from_screen start_time
161
162
  out = {}
163
+ start = get_digits_as_bitmaps
164
+ dump_digits(start, 'started_as')
162
165
  # force it to have two matching snapshots in a row, to avoid race conditions grabbing the digits...
163
- previous = nil # 0.08s [!] not too accurate...ltodo
164
- until previous == (temp = get_digits_as_bitmaps)
165
- previous = temp
166
- sleep 0.05 # allow youtube to update (sigh) lodo just for utube
166
+ previous = nil
167
+ current = start
168
+ until previous == (current)
169
+ previous = current
170
+ sleep 0.25 # allow youtube to update (sigh) lodo just for utube
171
+ current = get_digits_as_bitmaps
172
+ p previous == current
173
+ dump_digits(current, 'current is')
167
174
  # lodo it should probably poll *before* calling this, not here...maybe?
168
175
  end
169
- assert previous == temp
170
- digits = temp
176
+ assert previous == current
177
+ digits = current = previous
171
178
 
172
- dump_digits(digits) if $DEBUG
179
+ if $DEBUG
180
+ dump_digits(digits, 'using digits')
181
+ end
173
182
  DIGIT_TYPES.each{|type|
174
183
  if digits[type]
175
184
  digit = identify_digit(digits[type])
176
185
  unless digit
177
- if $DEBUG || $VERBOSE
186
+ bitmap = digits[type]
187
+ # unable to identify a digit?
188
+ if $DEBUG || $VERBOSE && (type != :hours)
178
189
  @a ||= 1
179
190
  @a += 1
180
191
  @already_wrote ||= {}
181
- unless @already_wrote[digits[type]]
182
- p 'unable to identify capture!' + type.to_s + @a.to_s + ' capture no:' + @dump_digit_count.to_s
183
- File.binwrite("bad_digit#{@a}#{type}.bmp", digits[type]) unless type == :hours
184
- @already_wrote[digits[type]] = true
192
+ unless @already_wrote[bitmap]
193
+ p 'unable to identify capture!' + type.to_s + @a.to_s + ' dump:' + @dump_digit_count.to_s
194
+ File.binwrite("bad_digit#{@a}#{type}.bmp", bitmap)
195
+ @already_wrote[bitmap] = true
185
196
  end
186
197
  end
187
198
  if type == :hours
188
199
  digit = 0 # this one can fail and that's ok in VLC bottom right
189
200
  else
190
- # early failure return
191
- return
201
+ # early (failure) return
202
+ return nil
192
203
  end
193
204
  else
194
- p " got digit #{type} as #{digit} which was captured as #{@dump_digit_count} " if $DEBUG
205
+ p " got digit #{type} OCR as #{digit} which was captured to dump #{@dump_digit_count - 1} #{Time.now_f}" if $DEBUG
195
206
  end
196
207
  out[type] = digit
197
208
  else
@@ -200,8 +211,8 @@ class ScreenTracker
200
211
  end
201
212
  }
202
213
  out = "%d:%d%d:%d%d" % DIGIT_TYPES.map{ |type| out[type] }
203
- puts '', 'got new screen time ' + out + " tracking delta:" + (Time.now - start).to_s if $VERBOSE
204
- return out, Time.now-start
214
+ puts '', 'got new screen time ' + out + " tracking delta:" + (Time.now - start_time).to_s if $VERBOSE
215
+ return out, Time.now-start_time
205
216
  end
206
217
 
207
218
  def process_forever_in_thread