sensible-cinema 0.9.7 → 0.10.1
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/README +6 -7
- data/Rakefile +1 -0
- data/TODO +65 -39
- data/VERSION +1 -1
- data/bin/sensible-cinema +2 -2
- data/lib/blanker.rb +4 -0
- data/lib/ocr.rb +2 -1
- data/lib/overlayer.rb +3 -3
- data/lib/screen_tracker.rb +30 -23
- data/spec/common.rb +4 -47
- data/spec/ocr.spec.rb +4 -4
- data/spec/overlayer.spec.rb +2 -1
- data/spec/screen_tracker.spec.rb +236 -218
- data/zamples/players/hulu/total_length_over_an_hour.yml +2 -0
- data/zamples/players/youtube/full_screened_1024x768.yml +1 -2
- data/zamples/players/youtube/full_screened_1152x864.yml +2 -0
- data/zamples/players/youtube/full_screened_1680x1050.yml +2 -0
- data/zamples/players/youtube/{normal_in_youtube.com.yml → normal_in_youtube.com.chrome.yml} +1 -0
- data/zamples/players/youtube/note_these_assume_less_than_10_minutes_length.txt +2 -0
- data/zamples/scene_lists/dvds/cars_disney.yml +21 -0
- data/zamples/scene_lists/{gummy_bear_song_youtube.yml → youtube/gummy_bear_song_youtube.yml} +0 -0
- data/zamples/scene_lists/{nuki_song_youtube.yml → youtube/nuki_song_youtube.yml} +1 -1
- metadata +8 -8
- data/zamples/scene_lists/dvds/disney_cars.yml +0 -15
data/README
CHANGED
|
@@ -162,16 +162,15 @@ which you could use to translate into a sensible-cinema compatible list.
|
|
|
162
162
|
|
|
163
163
|
The concept isn't too novel:
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
http://
|
|
167
|
-
http://www.oreillynet.com/sysadmin/blog/2005/06/make_your_own_phantom_edit_wit.html
|
|
165
|
+
Edited "for airplane" movies
|
|
166
|
+
http://en.wikipedia.org/wiki/Edit_decision_list (it's a linear editing tool, after all)
|
|
167
|
+
http://www.oreillynet.com/sysadmin/blog/2005/06/make_your_own_phantom_edit_wit.html mplayer has had this ability for awhile.
|
|
168
168
|
http://forum.bsplayer.com/feature-requests-feedback-suggestions/7157-chapter-playlist-scene-cut-3.html
|
|
169
169
|
http://www.inmatrix.com/ "scene cut editor" of the zoom player
|
|
170
|
-
http://wiki.xbmc.org/?title=EDL_(commercial_skipping)_and_SceneMarker_support (XBMC's scene cut support--also links to
|
|
170
|
+
http://wiki.xbmc.org/?title=EDL_(commercial_skipping)_and_SceneMarker_support (XBMC's scene cut support--also contains links to some others)
|
|
171
171
|
http://code.google.com/p/movie-content-editor (same thing, but in Python and only for VLC)
|
|
172
|
-
http://
|
|
173
|
-
|
|
174
|
-
though none of them are universal like this one is :)
|
|
172
|
+
http://www.imdb.com/swiki/special?ParentalGuideHelp and search for "scene description"
|
|
173
|
+
http://clearplay.com similar, but commercial (closed source, costs money, no user contribution), and only for DVD's (uses its own DVD-player in its current incantation).
|
|
175
174
|
|
|
176
175
|
== Feedback ==
|
|
177
176
|
|
data/Rakefile
CHANGED
data/TODO
CHANGED
|
@@ -1,51 +1,80 @@
|
|
|
1
1
|
== medium ==
|
|
2
2
|
|
|
3
|
-
make all players actually play again
|
|
4
3
|
|
|
5
|
-
==
|
|
4
|
+
== probably next up/low prio ==
|
|
6
5
|
|
|
6
|
+
back off on mouse jerking if they're movin' it
|
|
7
|
+
screencast of things helpful (use, creation).
|
|
7
8
|
youtube non full screen: work with other browsers
|
|
8
|
-
|
|
9
|
-
can parse IMDB (require they put in the URL by hand)
|
|
10
|
-
|
|
11
|
-
PISH
|
|
9
|
+
speed up unit tests
|
|
10
|
+
can parse IMDB (require they put in the URL by hand fer now)
|
|
11
|
+
PISH, then
|
|
12
12
|
add stuffs to imdb hmmm
|
|
13
|
-
|
|
13
|
+
a netflix player descriptor
|
|
14
|
+
advertise on ruby flow
|
|
15
|
+
"just choose VLCx55" LOL
|
|
16
|
+
beep at them when not tracking [?]
|
|
17
|
+
default on...hmm
|
|
14
18
|
|
|
15
|
-
== random backlog ...
|
|
19
|
+
== 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). ==
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
run it off a normal person (hulu, DVD). rinse and repeat
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
check that youtube is working well again for all...
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
easier "here's how on the command line, BTW"
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
DRY up the levels--it's in the ocr spec as well as the others...
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
plan on needing for myself (filters for what I need/want).
|
|
29
|
+
unit tests pass with normal ruby
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
test every player with different screen resolutions...
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
add unit tests for each player for "make all players actually play again"
|
|
34
|
+
|
|
35
|
+
screen time change only detected... [unexpected] [rid myself of it]
|
|
36
|
+
|
|
37
|
+
stabilization on seconds -> 00 -> minutes++: make optional [?]
|
|
38
|
+
|
|
39
|
+
when polling for bmp changes, just use two lines (?)
|
|
40
|
+
|
|
41
|
+
try new GOCR version...
|
|
42
|
+
|
|
43
|
+
Do I *need* that other window always up or not? (Get rid of it...only do this after have a real window of my own though, that's always up)
|
|
44
|
+
|
|
45
|
+
preference for beeping at them, et al
|
|
46
|
+
|
|
47
|
+
itunes video on demand
|
|
48
|
+
|
|
49
|
+
blockbuster "rent" on demand, online
|
|
31
50
|
|
|
32
|
-
|
|
51
|
+
a real website
|
|
33
52
|
|
|
34
53
|
no money making for now...all volunteer...more respectful.
|
|
35
54
|
or make it so it can work with an editor of some kind...like a "save here" command line snip this tuck that.
|
|
36
55
|
probably only possible after creating the desktop streamer hmm
|
|
37
56
|
|
|
57
|
+
no popularizing it for now, I guess
|
|
58
|
+
|
|
38
59
|
integrate with librivox' audio so you can avoid profanity in classics. Somehow. This would be nice for portable players.
|
|
60
|
+
You know, for static things like this, a 'pre-cutter' would sure be convenient...
|
|
61
|
+
provide download of edited mp3's for people. ahhh.
|
|
62
|
+
|
|
63
|
+
some type of static 'ok grab it using x, then apply y' oh yeah. That would rock for the DVD market, really. Just not the online market.
|
|
39
64
|
|
|
40
65
|
itunes player for profanity (music)?
|
|
41
66
|
|
|
67
|
+
make a list of "known clean" movies or what not...hmm...
|
|
68
|
+
|
|
42
69
|
an "online anybody can chat while watching this movie" (or anybody can edit this wav and listen to it as overlay...) prefer the latter.
|
|
43
70
|
|
|
44
71
|
an online applet web runnable? Why not?
|
|
45
72
|
click here to watch your favorite film edited on hulu! Just click! [* yea!]
|
|
46
73
|
a chrome plugin with imdb/community backing :)
|
|
74
|
+
|
|
75
|
+
a known list of "compatible" imdb oners...
|
|
47
76
|
|
|
48
|
-
code refactors: "screen time change", order should be swapped in bin/x output
|
|
77
|
+
code refactors: "screen time change", order should be swapped in bin/x output (just cleanup)
|
|
49
78
|
|
|
50
79
|
auto-play on detect youtube url access...
|
|
51
80
|
|
|
@@ -53,17 +82,13 @@ easier installer for windows: release a zip file that they can just click on a .
|
|
|
53
82
|
later: it installs/uninstalls appropo
|
|
54
83
|
suggestion: self-extractor
|
|
55
84
|
|
|
56
|
-
|
|
85
|
+
can blank overlay with added text like "and you are one awesome klingon"
|
|
57
86
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
screencast of things helpful (use, creation).
|
|
87
|
+
ability to record it from online/live, then apply edits.
|
|
61
88
|
|
|
62
89
|
TSR that monitors "oh you're opening a VLC? you're playing the E drive? That's bob's big plan? You're maximized? Full screened? watching x on hulu? y on youtube?"
|
|
63
90
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
add my stuff to imdb...? wiki ?
|
|
91
|
+
add my stuff to imdb...? wiki?
|
|
67
92
|
|
|
68
93
|
make youtube work if you have *several* open
|
|
69
94
|
|
|
@@ -76,13 +101,16 @@ hulu non full screened descriptor
|
|
|
76
101
|
|
|
77
102
|
can overlay with wav file (would work already for VLC [?], could also "click to mute" for others...hmm...)
|
|
78
103
|
|
|
104
|
+
the muting currently is so togglesy...if VLC ever fixes itself, fix this!
|
|
105
|
+
|
|
79
106
|
fix any/all pending tests...
|
|
80
107
|
|
|
81
|
-
can permanently black out certain coords to keep things prettier...
|
|
108
|
+
can permanently black out certain coords to keep things prettier...et al
|
|
109
|
+
remove black when they really move the mouse?
|
|
82
110
|
|
|
83
111
|
Linux port (call that good enough for usability on TV's...), should be...
|
|
84
112
|
|
|
85
|
-
|
|
113
|
+
blanker outer with user specifiable color
|
|
86
114
|
better default color?
|
|
87
115
|
|
|
88
116
|
Auto mute/blank commercials?
|
|
@@ -90,25 +118,24 @@ Auto mute/blank commercials?
|
|
|
90
118
|
transfer ownership to an LLC
|
|
91
119
|
new github username
|
|
92
120
|
|
|
93
|
-
replay certain film sections :P
|
|
94
|
-
|
|
95
121
|
overlay/replace current playback with some url of audio or video
|
|
96
|
-
user editable overlays (like a wiki...)
|
|
122
|
+
user editable joke overlays (like a wiki...)
|
|
97
123
|
realtime overlays (like group chat for those watching the film...)
|
|
98
124
|
|
|
99
125
|
control volume programmatically (using mouse) on the player itself.
|
|
100
126
|
control mute programmatically (using mouse) on the player itself.
|
|
101
127
|
control location programmatically (using mouse) on the player itself.
|
|
102
128
|
|
|
103
|
-
compare VLC (and other) timings with a real DVD player
|
|
129
|
+
compare VLC (and other) timings with a real DVD player, and with netflix online, etc.
|
|
104
130
|
|
|
105
|
-
overlay with an alpha transparent pic
|
|
131
|
+
overlay with an alpha transparent pic (?)
|
|
106
132
|
|
|
107
133
|
Have a "list of all known movies (url's)" and be able to open (IE et al) to the correct part, and start playing them, and they work...
|
|
134
|
+
or known parseable imdb's
|
|
108
135
|
|
|
109
136
|
does my sweet heart have any suggestions? (make it work well for laymen)
|
|
110
137
|
|
|
111
|
-
some type of installer that can setup the registry...
|
|
138
|
+
some type of one click installer that can setup the registry...
|
|
112
139
|
|
|
113
140
|
auto-assignment of EDL's to media:
|
|
114
141
|
auto-play option for DVD's (auto-start?)
|
|
@@ -126,14 +153,13 @@ Programmatically do all of the above, by driving VLC with its real API.
|
|
|
126
153
|
|
|
127
154
|
star trek: generations first profanidade...
|
|
128
155
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
integrate with google TV/bravia...maybe...somehow...boxxee?
|
|
132
|
-
itunes TV, too?
|
|
156
|
+
integrate with google TV/bravia...maybe...somehow...boxxee? roku?
|
|
157
|
+
itunes TV? apple tv?
|
|
133
158
|
|
|
134
159
|
OCR the captioning as an auto profanity filter? (or perhaps download subtitles to be able to pre-screen), like the python fella does..
|
|
135
|
-
what else does python do that we can learn from? can we combine projects somehow, perhaps?
|
|
136
160
|
|
|
137
161
|
make an index of watchable on imdb based on stars (?)
|
|
138
162
|
|
|
139
|
-
|
|
163
|
+
--server? optionally higher prio?
|
|
164
|
+
|
|
165
|
+
http://en.wikipedia.org/wiki/RiffTrax (possible?)
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.10.1
|
data/bin/sensible-cinema
CHANGED
|
@@ -39,7 +39,7 @@ else
|
|
|
39
39
|
player_description = ARGV.shift.to_s
|
|
40
40
|
if !File.exist?(player_description)
|
|
41
41
|
puts 'Please Select Computer Player'
|
|
42
|
-
player_description = FileChooser.choose_file("
|
|
42
|
+
player_description = FileChooser.choose_file(" SELECT COMPUTER PLAYER", __dir__ + "/../zamples/players")
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
scene_list = ARGV.shift.to_s
|
|
@@ -51,7 +51,7 @@ else
|
|
|
51
51
|
else
|
|
52
52
|
if !File.exist? scene_list
|
|
53
53
|
puts 'Select Scene Descriptions file'
|
|
54
|
-
scene_list = FileChooser.choose_file("
|
|
54
|
+
scene_list = FileChooser.choose_file(" SELECT SCENE DESCRIPTIONS FILE", __dir__ + "/../zamples/scene_lists")
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
if !scene_list
|
data/lib/blanker.rb
CHANGED
|
@@ -12,9 +12,13 @@ else
|
|
|
12
12
|
@fr = JFrame.new("Sensible Cinema blanker-outer overlay window")
|
|
13
13
|
@fr.default_close_operation = JFrame::EXIT_ON_CLOSE
|
|
14
14
|
@fr.set_size(2000, 2000) # ltodo better size ?
|
|
15
|
+
cp = @fr.getContentPane
|
|
16
|
+
cp.setBackground(java.awt.Color.black);
|
|
17
|
+
|
|
15
18
|
|
|
16
19
|
@label = JLabel.new
|
|
17
20
|
@fr.add(@label)
|
|
21
|
+
@label.setForeground(java.awt.Color.white);
|
|
18
22
|
@label.repaint
|
|
19
23
|
@label.revalidate
|
|
20
24
|
|
data/lib/ocr.rb
CHANGED
|
@@ -40,6 +40,7 @@ module OCR
|
|
|
40
40
|
|
|
41
41
|
previous = nil
|
|
42
42
|
p options if $DEBUG
|
|
43
|
+
raise 'you must pass in OCR levels in the player description' unless options[:levels]
|
|
43
44
|
for level in options[:levels]
|
|
44
45
|
a = `#{GOCR} -l #{level} #{image.path} 2>NUL`
|
|
45
46
|
if a =~ /[0-9]/
|
|
@@ -72,7 +73,7 @@ module OCR
|
|
|
72
73
|
|
|
73
74
|
def unserialize_cache_from_disk
|
|
74
75
|
if File.exist? CACHE_FILE
|
|
75
|
-
CACHE.merge!(Marshal.load
|
|
76
|
+
CACHE.merge!(Marshal.load(File.binread(CACHE_FILE)))
|
|
76
77
|
end
|
|
77
78
|
|
|
78
79
|
end
|
data/lib/overlayer.rb
CHANGED
|
@@ -97,8 +97,8 @@ class OverLayer
|
|
|
97
97
|
def self.translate_yaml raw_yaml
|
|
98
98
|
begin
|
|
99
99
|
all = YAML.load(raw_yaml) || {}
|
|
100
|
-
rescue NoMethodError
|
|
101
|
-
p 'appears your file has a syntax error in it--perhaps missing quotation marks'
|
|
100
|
+
rescue NoMethodError, ArgumentError
|
|
101
|
+
p 'appears your file has a syntax error in it--perhaps missing quotation marks?'
|
|
102
102
|
return
|
|
103
103
|
end
|
|
104
104
|
# now it's like {:mutes => {"1:02.0" => "1:3.0"}}
|
|
@@ -151,7 +151,7 @@ class OverLayer
|
|
|
151
151
|
# ignore it, since it was probably just caused by the screen blipping
|
|
152
152
|
# at worse this will put us 1s behind...hmm.
|
|
153
153
|
@just_unblanked = false
|
|
154
|
-
p 'ignoring timestamp update ' + to_this_exact_string_might_be_nil if $VERBOSE
|
|
154
|
+
p 'ignoring timestamp update ' + to_this_exact_string_might_be_nil.to_s if $VERBOSE
|
|
155
155
|
else
|
|
156
156
|
set_seconds OverLayer.translate_string_to_seconds(to_this_exact_string_might_be_nil) + delta if to_this_exact_string_might_be_nil
|
|
157
157
|
end
|
data/lib/screen_tracker.rb
CHANGED
|
@@ -40,6 +40,7 @@ class ScreenTracker
|
|
|
40
40
|
end
|
|
41
41
|
@digits = digits
|
|
42
42
|
@displayed_warning = false
|
|
43
|
+
@dump_digit_count = 1
|
|
43
44
|
pps 'using x',@x, 'from x', x, 'y', @y, 'from y', y,'x2',@x2,'y2',@y2,'digits', @digits if $VERBOSE
|
|
44
45
|
end
|
|
45
46
|
|
|
@@ -56,7 +57,7 @@ class ScreenTracker
|
|
|
56
57
|
# allow ourselves the 'found it message' selectively
|
|
57
58
|
unless @hwnd
|
|
58
59
|
until @hwnd
|
|
59
|
-
print '
|
|
60
|
+
print 'unable to find the player window currently [%s] (maybe need to start program or move mouse over it)' % @name_or_regex.inspect
|
|
60
61
|
sleep 1
|
|
61
62
|
STDOUT.flush
|
|
62
63
|
@hwnd = Win32::Screenshot::BitmapMaker.hwnd(@name_or_regex, @use_class_name)
|
|
@@ -85,12 +86,11 @@ class ScreenTracker
|
|
|
85
86
|
end
|
|
86
87
|
|
|
87
88
|
def dump_digits digits
|
|
88
|
-
@digit_count ||= 1
|
|
89
89
|
for type, bitmap in get_digits_as_bitmaps
|
|
90
|
-
File.binwrite type.to_s + '.' + @
|
|
90
|
+
File.binwrite type.to_s + '.' + @dump_digit_count.to_s + '.bmp', bitmap
|
|
91
91
|
end
|
|
92
|
-
print 'debug dumped digits that Im about to parse:', @
|
|
93
|
-
@
|
|
92
|
+
print 'debug dumped digits that Im about to parse:', @dump_digit_count, "\n"
|
|
93
|
+
@dump_digit_count += 1
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
DIGIT_TYPES = [:hours, :minute_tens, :minute_ones, :second_tens, :second_ones]
|
|
@@ -120,14 +120,18 @@ class ScreenTracker
|
|
|
120
120
|
OCR.identify_digit(bitmap, @digits)
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
+
# we have to wait until the next change, because when we start, it might be half-way through
|
|
124
|
+
# the current second...
|
|
123
125
|
def wait_till_next_change
|
|
124
126
|
original = get_bmp
|
|
125
|
-
|
|
127
|
+
time_since_last_screen_change = Time.now
|
|
126
128
|
loop {
|
|
129
|
+
# save away the current time to try and be most accurate...
|
|
130
|
+
time_before_scan = Time.now
|
|
127
131
|
current = get_bmp
|
|
128
132
|
if current != original
|
|
129
133
|
if @digits
|
|
130
|
-
got = attempt_to_get_time_from_screen
|
|
134
|
+
got = attempt_to_get_time_from_screen time_before_scan
|
|
131
135
|
if @displayed_warning && got
|
|
132
136
|
# reassure user :)
|
|
133
137
|
p 'tracking it successfully again'
|
|
@@ -138,29 +142,32 @@ class ScreenTracker
|
|
|
138
142
|
puts 'screen time change only detected... [unexpected]'
|
|
139
143
|
return
|
|
140
144
|
end
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
else
|
|
146
|
+
# no screen change detected ...
|
|
147
|
+
sleep 0.02
|
|
148
|
+
if(Time.now - time_since_last_screen_change > 2)
|
|
149
|
+
# 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)
|
|
154
|
+
get_hwnd
|
|
155
|
+
end
|
|
149
156
|
end
|
|
150
157
|
}
|
|
151
158
|
end
|
|
152
159
|
|
|
153
|
-
def attempt_to_get_time_from_screen
|
|
160
|
+
def attempt_to_get_time_from_screen start
|
|
154
161
|
out = {}
|
|
155
|
-
# force it to have two matching in a row, to avoid race conditions grabbing the digits...
|
|
162
|
+
# force it to have two matching snapshots in a row, to avoid race conditions grabbing the digits...
|
|
156
163
|
previous = nil # 0.08s [!] not too accurate...ltodo
|
|
157
|
-
start = Time.now
|
|
158
164
|
until previous == (temp = get_digits_as_bitmaps)
|
|
159
165
|
previous = temp
|
|
160
|
-
sleep 0.05 # allow youtube to update (sigh)
|
|
161
|
-
# lodo it should probably poll *before* this, not here...maybe?
|
|
166
|
+
sleep 0.05 # allow youtube to update (sigh) lodo just for utube
|
|
167
|
+
# lodo it should probably poll *before* calling this, not here...maybe?
|
|
162
168
|
end
|
|
163
|
-
|
|
169
|
+
assert previous == temp
|
|
170
|
+
digits = temp
|
|
164
171
|
|
|
165
172
|
dump_digits(digits) if $DEBUG
|
|
166
173
|
DIGIT_TYPES.each{|type|
|
|
@@ -172,7 +179,7 @@ class ScreenTracker
|
|
|
172
179
|
@a += 1
|
|
173
180
|
@already_wrote ||= {}
|
|
174
181
|
unless @already_wrote[digits[type]]
|
|
175
|
-
p 'unable to identify capture!' + type.to_s + @a.to_s + ' capture no:' + @
|
|
182
|
+
p 'unable to identify capture!' + type.to_s + @a.to_s + ' capture no:' + @dump_digit_count.to_s
|
|
176
183
|
File.binwrite("bad_digit#{@a}#{type}.bmp", digits[type]) unless type == :hours
|
|
177
184
|
@already_wrote[digits[type]] = true
|
|
178
185
|
end
|
|
@@ -184,7 +191,7 @@ class ScreenTracker
|
|
|
184
191
|
return
|
|
185
192
|
end
|
|
186
193
|
else
|
|
187
|
-
p " got digit #{type} as #{digit} which was captured as #{@
|
|
194
|
+
p " got digit #{type} as #{digit} which was captured as #{@dump_digit_count} " if $DEBUG
|
|
188
195
|
end
|
|
189
196
|
out[type] = digit
|
|
190
197
|
else
|
data/spec/common.rb
CHANGED
|
@@ -13,6 +13,9 @@ require 'benchmark'
|
|
|
13
13
|
Thread.abort_on_exception = true
|
|
14
14
|
require 'timeout'
|
|
15
15
|
require 'fileutils'
|
|
16
|
+
require 'pathname'
|
|
17
|
+
|
|
18
|
+
Dir.chdir File.dirname(__FILE__) # always run from the right dir...
|
|
16
19
|
|
|
17
20
|
begin
|
|
18
21
|
require 'hitimes'
|
|
@@ -32,7 +35,7 @@ rescue LoadError
|
|
|
32
35
|
end
|
|
33
36
|
}
|
|
34
37
|
else
|
|
35
|
-
|
|
38
|
+
puts 'no hitimes available...'
|
|
36
39
|
end
|
|
37
40
|
|
|
38
41
|
end
|
|
@@ -43,65 +46,19 @@ end
|
|
|
43
46
|
#end
|
|
44
47
|
|
|
45
48
|
require 'ffi'
|
|
46
|
-
require 'ffi-inliner'
|
|
47
49
|
|
|
48
50
|
module GetPid
|
|
49
51
|
extend FFI::Library
|
|
50
|
-
extend Inliner
|
|
51
52
|
ffi_lib 'user32', 'kernel32'
|
|
52
53
|
ffi_convention :stdcall
|
|
53
54
|
attach_function :get_process_id_old, :GetProcessId, [ :ulong ], :uint
|
|
54
55
|
|
|
55
56
|
attach_function :GetWindowThreadProcessId, [:ulong, :pointer], :uint
|
|
56
57
|
|
|
57
|
-
|
|
58
58
|
def self.get_process_id_from_window hwnd
|
|
59
59
|
out = FFI::MemoryPointer.new(:uint)
|
|
60
60
|
GetWindowThreadProcessId(hwnd, out) # does translation automatically to ptr for us
|
|
61
61
|
out.get_uint32(0) # read_uint
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
inline <<-CODE
|
|
65
|
-
#include <windows.h>
|
|
66
|
-
//#include <strsafe.h> // not available in mingw...
|
|
67
|
-
|
|
68
|
-
void ErrorExit()
|
|
69
|
-
{
|
|
70
|
-
// Retrieve the system error message for the last-error code
|
|
71
|
-
LPTSTR lpszFunction = "abcdef";
|
|
72
|
-
LPVOID lpMsgBuf;
|
|
73
|
-
LPVOID lpDisplayBuf;
|
|
74
|
-
DWORD dw = GetLastError();
|
|
75
|
-
|
|
76
|
-
FormatMessage(
|
|
77
|
-
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
78
|
-
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
79
|
-
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
80
|
-
NULL,
|
|
81
|
-
dw,
|
|
82
|
-
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
83
|
-
(LPTSTR) &lpMsgBuf,
|
|
84
|
-
0, NULL );
|
|
85
|
-
|
|
86
|
-
// Display the error message and exit the process
|
|
87
|
-
printf("here1");
|
|
88
|
-
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
|
|
89
|
-
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
|
|
90
|
-
printf("here2");
|
|
91
|
-
snprintf((LPTSTR)lpDisplayBuf,
|
|
92
|
-
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
|
|
93
|
-
TEXT("%s failed with error %d: %s"),
|
|
94
|
-
lpszFunction, dw, lpMsgBuf);
|
|
95
|
-
printf("here3");
|
|
96
|
-
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
|
|
97
|
-
printf("here4 ");
|
|
98
|
-
|
|
99
|
-
LocalFree(lpMsgBuf);
|
|
100
|
-
LocalFree(lpDisplayBuf);
|
|
101
|
-
// ExitProcess(dw);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
CODE
|
|
106
|
-
|
|
107
64
|
end
|
data/spec/ocr.spec.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + '/common'
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/common')
|
|
2
2
|
require_relative "../lib/ocr"
|
|
3
3
|
require 'benchmark'
|
|
4
4
|
|
|
@@ -18,7 +18,7 @@ describe OCR do
|
|
|
18
18
|
options[:sharpen] = true if file =~ /youtube/
|
|
19
19
|
|
|
20
20
|
# 130 for vlc, 100 for hulu, 0 for some youtube full screen
|
|
21
|
-
# 200, 250 for youtube "light"
|
|
21
|
+
# 200, 250 for youtube "light" (windowed after awhile)
|
|
22
22
|
degrees = {'vlc' => [130], 'hulu' => [100], 'youtube' => [0], 'youtube_light' => [200, 250]}
|
|
23
23
|
file =~ /(vlc|hulu|youtube_light|youtube)/
|
|
24
24
|
options[:levels] = degrees[$1]
|
|
@@ -74,10 +74,10 @@ describe OCR do
|
|
|
74
74
|
new_time.should be < original_time
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
it "should not
|
|
77
|
+
it "should not results for failed reads (at least for now)" do
|
|
78
78
|
original_time = Benchmark.realtime { read_all_black }
|
|
79
79
|
new_time = Benchmark.realtime { 3.times { read_all_black} }
|
|
80
|
-
new_time.should be
|
|
80
|
+
new_time.should be < original_time
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
it "should serialize creating a cache file" do
|
data/spec/overlayer.spec.rb
CHANGED
|
@@ -409,7 +409,8 @@ describe OverLayer do
|
|
|
409
409
|
|
|
410
410
|
it "should not fail with verbose on, after it's past next states" do
|
|
411
411
|
at(500_000) do
|
|
412
|
-
@o.status.should
|
|
412
|
+
@o.status.should include("138:53:20")
|
|
413
|
+
@o.status.should include("q") # for quit
|
|
413
414
|
end
|
|
414
415
|
end
|
|
415
416
|
|
data/spec/screen_tracker.spec.rb
CHANGED
|
@@ -1,124 +1,124 @@
|
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/common')
|
|
2
2
|
require_relative '../lib/overlayer'
|
|
3
3
|
require_relative '../lib/screen_tracker'
|
|
4
|
-
require 'pathname'
|
|
5
4
|
|
|
6
5
|
describe ScreenTracker do
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
7
|
+
SILENCE = /silence.*VLC/
|
|
8
|
+
|
|
9
|
+
def start_vlc
|
|
10
|
+
# unfortunately this is run before every context [bug] with rspec 1.3...
|
|
11
|
+
unless $pid1
|
|
12
|
+
assert !$pid1
|
|
13
|
+
# enforce we only have at most one running...
|
|
14
|
+
begin
|
|
15
|
+
Win32::Screenshot.window(SILENCE, 0) {}
|
|
16
|
+
raise Exception.new('must close existing vlcs first')
|
|
17
|
+
rescue
|
|
18
|
+
silence = File.expand_path("./silence.wav").gsub("/", "\\")
|
|
19
|
+
Dir.chdir("/program files/VideoLan/VLC") do; IO.popen("vlc.exe #{silence}").pid; end # includes a work around for jruby...
|
|
20
|
+
until $pid1
|
|
21
|
+
$pid1 = GetPid.get_process_id_from_window(Win32::Screenshot::Util.window_hwnd(SILENCE)) rescue nil
|
|
22
|
+
sleep 0.01
|
|
24
23
|
end
|
|
25
24
|
end
|
|
26
25
|
end
|
|
27
|
-
|
|
28
|
-
before(:all) do
|
|
29
|
-
start_vlc
|
|
30
|
-
end
|
|
26
|
+
end
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
before(:all) do
|
|
29
|
+
start_vlc
|
|
30
|
+
end
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
end
|
|
32
|
+
before do
|
|
33
|
+
@a = ScreenTracker.new(SILENCE,10,10,20,20)
|
|
34
|
+
end
|
|
40
35
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
it "can take a regex or string" do
|
|
37
|
+
ScreenTracker.new(SILENCE,10,10,20,20)
|
|
38
|
+
ScreenTracker.new("silence",10,10,20,20)
|
|
39
|
+
end
|
|
44
40
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
ScreenTracker.new("this is supposed to be not running",10,10,20,20)
|
|
49
|
-
end
|
|
50
|
-
}.should raise_error(Timeout::Error)
|
|
51
|
-
end
|
|
41
|
+
it "should be able to grab a picture from screen coords...probably from the current active window" do
|
|
42
|
+
@a.get_bmp.should_not be_nil
|
|
43
|
+
end
|
|
52
44
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
it "should loop if unable to find the right window" do
|
|
46
|
+
proc {
|
|
47
|
+
Timeout::timeout(1) do
|
|
48
|
+
ScreenTracker.new("this is supposed to be not running",10,10,20,20)
|
|
49
|
+
end
|
|
50
|
+
}.should raise_error(Timeout::Error)
|
|
51
|
+
end
|
|
56
52
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
it "should be at least somewhat fast" do
|
|
54
|
+
Benchmark.realtime { @a.get_bmp }.should be < 0.3
|
|
55
|
+
end
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
it "should not allow for negative widths" do
|
|
58
|
+
proc {ScreenTracker.new("VLC",10,10,-20,20)}.should raise_error
|
|
59
|
+
end
|
|
64
60
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
b = ScreenTracker.new("VLC",10,10,50,50)
|
|
69
|
-
assert a.get_bmp != b.get_bmp
|
|
70
|
-
end
|
|
61
|
+
it "should disallow size 0 widths" do
|
|
62
|
+
proc {ScreenTracker.new("VLC",10,10,0,0)}.should raise_error
|
|
63
|
+
end
|
|
71
64
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
65
|
+
it "should have different bmp if sizes different" do
|
|
66
|
+
a = ScreenTracker.new("VLC",10,10,5,5)
|
|
67
|
+
assert a.get_relative_coords == [10,10,15,15]
|
|
68
|
+
b = ScreenTracker.new("VLC",10,10,50,50)
|
|
69
|
+
assert a.get_bmp != b.get_bmp
|
|
70
|
+
end
|
|
75
71
|
|
|
76
|
-
|
|
72
|
+
it "should allow for straight desktop if they specify Desktop or desktop" do
|
|
73
|
+
a = ScreenTracker.new("desktop",0,0,100,100)
|
|
74
|
+
end
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
a = ScreenTracker.new("VLC",-10,10,5,5)
|
|
80
|
-
a.get_bmp
|
|
81
|
-
a = ScreenTracker.new("VLC",-10,-10,10,10) # right to the edge
|
|
82
|
-
a.get_bmp
|
|
83
|
-
a = ScreenTracker.new("VLC",10,-10,5,5)
|
|
84
|
-
a.get_bmp
|
|
85
|
-
end
|
|
76
|
+
context "negative numbers should be interpreted as an offset" do
|
|
86
77
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
x2.should == x+5
|
|
96
|
-
y2.should == y+5
|
|
97
|
-
end
|
|
78
|
+
it "should allow for negative size parameter" do
|
|
79
|
+
a = ScreenTracker.new("VLC",-10,10,5,5)
|
|
80
|
+
a.get_bmp
|
|
81
|
+
a = ScreenTracker.new("VLC",-10,-10,10,10) # right to the edge
|
|
82
|
+
a.get_bmp
|
|
83
|
+
a = ScreenTracker.new("VLC",10,-10,5,5)
|
|
84
|
+
a.get_bmp
|
|
85
|
+
end
|
|
98
86
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
87
|
+
it "should assign right offsets" do
|
|
88
|
+
a = ScreenTracker.new("VLC",-10,-10,5,5)
|
|
89
|
+
a.get_bmp
|
|
90
|
+
x,y,x2,y2=a.get_relative_coords
|
|
91
|
+
hwnd = Win32::Screenshot::BitmapMaker.hwnd("VLC")
|
|
92
|
+
max_x, max_y = Win32::Screenshot::Util.dimensions_for(hwnd)
|
|
93
|
+
x.should == max_x-10
|
|
94
|
+
y.should == max_y-10
|
|
95
|
+
x2.should == x+5
|
|
96
|
+
y2.should == y+5
|
|
97
|
+
end
|
|
110
98
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
99
|
+
it "should take negative coords and appear to use them" do
|
|
100
|
+
a = ScreenTracker.new("VLC",10,10,50,50)
|
|
101
|
+
b = ScreenTracker.new("VLC",10,10,50,50)
|
|
102
|
+
c = ScreenTracker.new("VLC",-99,-99,50,50)
|
|
103
|
+
assert a.get_bmp == b.get_bmp
|
|
104
|
+
assert c.get_relative_coords != b.get_relative_coords
|
|
105
|
+
cb = c.get_bmp
|
|
106
|
+
bb = b.get_bmp
|
|
107
|
+
c.get_bmp.length == b.get_bmp.length
|
|
108
|
+
assert c.get_bmp != b.get_bmp
|
|
109
|
+
end
|
|
117
110
|
|
|
111
|
+
it "should fail with out of bounds or zero sizes" do
|
|
112
|
+
proc { a = ScreenTracker.new(SILENCE,-10,10,20,20) }.should raise_error
|
|
113
|
+
proc { a = ScreenTracker.new(SILENCE,10,-10,20,20) }.should raise_error
|
|
114
|
+
proc { a = ScreenTracker.new(SILENCE,-10,10,0,2) }.should raise_error
|
|
115
|
+
proc { a = ScreenTracker.new(SILENCE,10,10,2,0) }.should raise_error
|
|
118
116
|
end
|
|
119
117
|
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# lodo: this 7 looks rather redundant...
|
|
121
|
+
it "should parse yaml appropro" do
|
|
122
122
|
yaml = <<-YAML
|
|
123
123
|
name: VLC
|
|
124
124
|
x: 32
|
|
@@ -126,142 +126,160 @@ describe ScreenTracker do
|
|
|
126
126
|
width: 100
|
|
127
127
|
height: 20
|
|
128
128
|
digits:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
129
|
+
:hours:
|
|
130
|
+
:minute_tens:
|
|
131
|
+
- -90
|
|
132
|
+
- 7
|
|
133
|
+
:minute_ones:
|
|
134
|
+
- -82
|
|
135
|
+
- 7
|
|
136
|
+
:second_tens:
|
|
137
|
+
- -72
|
|
138
|
+
- 7
|
|
139
|
+
:second_ones:
|
|
140
|
+
- -66
|
|
141
|
+
- 7
|
|
142
|
+
YAML
|
|
143
|
+
a = ScreenTracker.new_from_yaml(yaml,nil)
|
|
144
|
+
a.get_relative_coords.should == [32,34,132,54]
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "should be able to dump images it uses" do
|
|
148
|
+
@a.dump_bmp
|
|
149
|
+
assert File.exist?('dump.bmp') && File.exist?('all.dump.bmp')
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
context "tracking a real player that is moving" do
|
|
153
|
+
|
|
154
|
+
before do
|
|
155
|
+
@a = ScreenTracker.new(SILENCE, -111, -16, 86, 13)
|
|
145
156
|
end
|
|
146
157
|
|
|
147
|
-
it "should be able to
|
|
148
|
-
@a.
|
|
149
|
-
|
|
158
|
+
it "should be able to poll the screen to know when something changes" do
|
|
159
|
+
@a.wait_till_next_change
|
|
160
|
+
# it updates every 1 second...
|
|
161
|
+
Benchmark.realtime { @a.wait_till_next_change }.should be > 0.2
|
|
162
|
+
@a.dump_bmp # for debugging...
|
|
150
163
|
end
|
|
151
164
|
|
|
152
|
-
|
|
165
|
+
it "should be able to track via class_name" do
|
|
166
|
+
a = ScreenTracker.new(SILENCE,10,10,20,20)
|
|
167
|
+
b = ScreenTracker.new(/qwidget/i,10,10,20,20, true, {:second_ones => [-66, 7]})
|
|
168
|
+
a.hwnd.should == b.hwnd
|
|
169
|
+
end
|
|
153
170
|
|
|
154
|
-
|
|
155
|
-
@a = ScreenTracker.new(SILENCE, -111, -16, 86, 13)
|
|
156
|
-
end
|
|
171
|
+
end
|
|
157
172
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
173
|
+
context "using hulu" do
|
|
174
|
+
it "should be able to parse all digits" do
|
|
175
|
+
pending "completion"
|
|
176
|
+
a = ScreenTracker.new_from_yaml File.read("../zamples/players/hulu/total_length_over_an_hour.yml"), nil
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
context "using youtube" do
|
|
182
|
+
it "should be able to parse"
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
context "using a digit capable setting" do
|
|
164
186
|
|
|
165
|
-
|
|
187
|
+
before do
|
|
188
|
+
@a = ScreenTracker.new_from_yaml File.read("../zamples/players/vlc/windowed_total_length_under_an_hour.yml"), nil
|
|
189
|
+
end
|
|
166
190
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
191
|
+
it "should use OCR against the changes appropriately" do
|
|
192
|
+
sleep 1.1 # sleep until it should show something for sure
|
|
193
|
+
output = @a.wait_till_next_change # grab a real change
|
|
194
|
+
output[0].should be_a(String)
|
|
195
|
+
output[0].should include("00:") # like 00:09 or what not...
|
|
196
|
+
output[0].should match(/[1-9]/)
|
|
197
|
+
output[1].should be_a(Float)
|
|
198
|
+
end
|
|
170
199
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
200
|
+
it "should be able to scan for/identify new windows, since VLC creates entirely new windows when it transition
|
|
201
|
+
from menu -> player" do
|
|
202
|
+
|
|
203
|
+
output = @a.wait_till_next_change
|
|
204
|
+
output[0].should_not be_nil
|
|
205
|
+
old_handle = @a.hwnd
|
|
206
|
+
kill_vlc
|
|
207
|
+
start_vlc
|
|
208
|
+
output = @a.wait_till_next_change
|
|
209
|
+
output[0].should_not be_nil
|
|
210
|
+
old_handle.should_not == @a.hwnd
|
|
211
|
+
end
|
|
178
212
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
it "should be ok with a non-existent hours image" do
|
|
188
|
-
@a.stub!(:get_digits_as_bitmaps) do
|
|
189
|
-
four = File.binread('images/vlc_4.bmp')
|
|
190
|
-
black = File.binread('images/black.bmp')
|
|
191
|
-
{:minute_tens=>four,:second_tens => four, :second_ones => four, :minute_ones => four,
|
|
192
|
-
:hours => black}
|
|
193
|
-
end
|
|
194
|
-
@a.attempt_to_get_time_from_screen[0].should == "0:44:44"
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
it "should track the screen until it stabilizes" do
|
|
198
|
-
time_through = 0
|
|
199
|
-
four = File.binread('images/vlc_4.bmp')
|
|
200
|
-
black = File.binread('images/black.bmp')
|
|
201
|
-
times_read=0
|
|
202
|
-
@a.stub!(:get_digits_as_bitmaps) do
|
|
203
|
-
time_through += 1
|
|
204
|
-
if time_through == 1
|
|
205
|
-
{:minute_tens=>four}
|
|
206
|
-
elsif time_through == 2
|
|
207
|
-
{:minute_tens=>black}
|
|
208
|
-
else
|
|
209
|
-
times_read += 1
|
|
210
|
-
{:minute_tens=>four,:second_tens => four, :second_ones => four, :minute_ones => four,
|
|
211
|
-
:hours => four}
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
@a.attempt_to_get_time_from_screen[0].should == "4:44:44"
|
|
216
|
-
times_read.should == 2
|
|
217
|
-
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
context "with an OCR that can change from hour to minutes during ads" do
|
|
221
|
-
it "should detect this change"
|
|
222
|
-
end
|
|
213
|
+
it "should be able to disk dump its digit images" do
|
|
214
|
+
@a.dump_bmp
|
|
215
|
+
# what is the right number here?
|
|
216
|
+
Pathname.new('minute_tens.1.bmp').should exist
|
|
217
|
+
Pathname.new('minute_tens.1.bmp').size.should be > 0
|
|
218
|
+
# doesn't have hours
|
|
219
|
+
Pathname.new('hours.1.bmp').should_not exist
|
|
220
|
+
end
|
|
223
221
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
@a.identify_digit('some binary bitmap data')
|
|
232
|
-
got_it[1][:should_invert].should be_true
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
it "should be able to scan for/identify new windows, since VLC changes signatures" do
|
|
236
|
-
output = @a.wait_till_next_change
|
|
237
|
-
output[0].should_not be_nil
|
|
238
|
-
old_handle = @a.hwnd
|
|
239
|
-
kill_vlc
|
|
240
|
-
start_vlc
|
|
241
|
-
output = @a.wait_till_next_change
|
|
242
|
-
output[0].should_not be_nil
|
|
243
|
-
old_handle.should_not == @a.hwnd
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
it "should be able to track via class_name" do
|
|
247
|
-
a = ScreenTracker.new(SILENCE,10,10,20,20)
|
|
248
|
-
b = ScreenTracker.new(/qwidget/i,10,10,20,20, true, {:second_ones => [-66, 7]})
|
|
249
|
-
a.hwnd.should == b.hwnd
|
|
250
|
-
end
|
|
251
|
-
|
|
222
|
+
it "should be ok with a non-existent (non-returned) hours image" do
|
|
223
|
+
@a.stub!(:get_digits_as_bitmaps) do
|
|
224
|
+
four = File.binread('images/vlc_4.bmp')
|
|
225
|
+
black = File.binread('images/black.bmp')
|
|
226
|
+
{:minute_tens=>four,:second_tens => four, :second_ones => four, :minute_ones => four,
|
|
227
|
+
:hours => black}
|
|
252
228
|
end
|
|
229
|
+
@a.attempt_to_get_time_from_screen(Time.now)[0].should == "0:44:44" # hour is zero
|
|
230
|
+
end
|
|
253
231
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
232
|
+
it "should track the screen until it stabilizes, as VLC has a slight lag when seconds turn but minutes don't for a tidge" do
|
|
233
|
+
time_through = 0
|
|
234
|
+
four = File.binread('images/vlc_4.bmp')
|
|
235
|
+
black = File.binread('images/black.bmp')
|
|
236
|
+
times_read=0
|
|
237
|
+
@a.stub!(:get_digits_as_bitmaps) do
|
|
238
|
+
time_through += 1
|
|
239
|
+
if time_through == 1
|
|
240
|
+
{:minute_tens=>four}
|
|
241
|
+
elsif time_through == 2
|
|
242
|
+
{:minute_tens=>black}
|
|
243
|
+
else
|
|
244
|
+
times_read += 1
|
|
245
|
+
{:minute_tens=>four,:second_tens => four, :second_ones => four, :minute_ones => four,
|
|
246
|
+
:hours => four}
|
|
247
|
+
end
|
|
265
248
|
end
|
|
249
|
+
|
|
250
|
+
# these assert the same thing
|
|
251
|
+
@a.attempt_to_get_time_from_screen(Time.now)[0].should == "4:44:44"
|
|
252
|
+
times_read.should == 2
|
|
253
|
+
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
context "with an OCR that can change from hour to minutes during ads" do
|
|
257
|
+
it "should detect this change and act appropriately"
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it "should be able to pass through the option to invert images" do
|
|
261
|
+
@a = ScreenTracker.new(SILENCE, 100, 100, 10, 10, false,
|
|
262
|
+
{:should_invert => true, :second_ones => [-66, 7]} )
|
|
263
|
+
got_it = nil
|
|
264
|
+
OCR.stub!(:identify_digit) {|*args|
|
|
265
|
+
got_it = args
|
|
266
|
+
}
|
|
267
|
+
@a.identify_digit('some binary bitmap data')
|
|
268
|
+
got_it[1][:should_invert].should be_true
|
|
266
269
|
end
|
|
267
270
|
end
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def kill_vlc
|
|
274
|
+
assert $pid1
|
|
275
|
+
# jruby...<sigh>
|
|
276
|
+
system("taskkill /pid #{$pid1}")
|
|
277
|
+
Process.kill 9, $pid1 # MRI...sigh.
|
|
278
|
+
FileUtils.rm_rf Dir['*.bmp']
|
|
279
|
+
$pid1 = nil
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
after(:all) do
|
|
283
|
+
kill_vlc
|
|
284
|
+
end
|
|
285
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: cars widescreen 2006
|
|
2
|
+
player: VLC
|
|
3
|
+
mutes:
|
|
4
|
+
"0:17:22" : "0:17:23.5" # you could see his [rusty] undercarriage
|
|
5
|
+
"0:17:40.1" : "0:17:41" # rust your bolts and freeze your... (implied nuts)
|
|
6
|
+
"0:27:30.0" : "0:27:33.75" # turn on yer lights fer dang sake...moron
|
|
7
|
+
"31:48.5" : "31:50.25" # is it true that McQueen is going to pose for Car-Girl [magazine]?
|
|
8
|
+
"0:32:31" : "0:32:32" # McQueen "Oh L..." (mumbled)
|
|
9
|
+
"0:34:36" : "0:34:38" # "may doc have mercy on your soul"
|
|
10
|
+
"36:09" : "36:11" # likes me for muh body
|
|
11
|
+
"37:05" : "37:06" # Mater makes a fart noise when discussing gas
|
|
12
|
+
"40:16" : "40:18" # ...good look at that sexy hot-rod
|
|
13
|
+
"44:24" : "44:46" # hill billy hxxx
|
|
14
|
+
"54:25" : "54:30" # crazy grandpa car what an idiot
|
|
15
|
+
"55:24" : "55:25" # mater "oh L....."
|
|
16
|
+
"57:06" : "57:07" # hill billy hxxx
|
|
17
|
+
"57:12" : "57:18" # sally: wait not spend the night "with me"...
|
|
18
|
+
"1:10:34.5" : "1:10:35.75" # he did what in his cup?
|
|
19
|
+
"1:30:02" : "1:30:04" # thank the manufacturer...
|
|
20
|
+
"1:55:39" : "1:55:40" # for the "love of Chrysler" please....
|
|
21
|
+
|
data/zamples/scene_lists/{gummy_bear_song_youtube.yml → youtube/gummy_bear_song_youtube.yml}
RENAMED
|
File without changes
|
metadata
CHANGED
|
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
|
4
4
|
prerelease: false
|
|
5
5
|
segments:
|
|
6
6
|
- 0
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
version: 0.
|
|
7
|
+
- 10
|
|
8
|
+
- 1
|
|
9
|
+
version: 0.10.1
|
|
10
10
|
platform: ruby
|
|
11
11
|
authors:
|
|
12
12
|
- Roger Pack
|
|
@@ -14,7 +14,7 @@ autorequire:
|
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
16
|
|
|
17
|
-
date: 2010-10-
|
|
17
|
+
date: 2010-10-14 00:00:00 -06:00
|
|
18
18
|
default_executable: sensible-cinema
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
@@ -231,19 +231,19 @@ files:
|
|
|
231
231
|
- zamples/players/youtube/full_screened_1024x768.yml
|
|
232
232
|
- zamples/players/youtube/full_screened_1152x864.yml
|
|
233
233
|
- zamples/players/youtube/full_screened_1680x1050.yml
|
|
234
|
-
- zamples/players/youtube/normal_in_youtube.com.yml
|
|
234
|
+
- zamples/players/youtube/normal_in_youtube.com.chrome.yml
|
|
235
235
|
- zamples/players/youtube/note_these_assume_less_than_10_minutes_length.txt
|
|
236
236
|
- zamples/scene_lists/category descriptions.yml
|
|
237
237
|
- zamples/scene_lists/dvds/White Christmas.yml
|
|
238
238
|
- zamples/scene_lists/dvds/all_dogs_go_to_heaven_dvd.yml
|
|
239
|
-
- zamples/scene_lists/dvds/
|
|
239
|
+
- zamples/scene_lists/dvds/cars_disney.yml
|
|
240
240
|
- zamples/scene_lists/dvds/happy_feet_dvd.yml
|
|
241
241
|
- zamples/scene_lists/dvds/labyrinth.yml
|
|
242
242
|
- zamples/scene_lists/dvds/making marriage work.yml
|
|
243
243
|
- zamples/scene_lists/example_scene_descriptions_list.yml
|
|
244
|
-
- zamples/scene_lists/gummy_bear_song_youtube.yml
|
|
245
|
-
- zamples/scene_lists/nuki_song_youtube.yml
|
|
246
244
|
- zamples/scene_lists/star_trek_generations_hulu.yml
|
|
245
|
+
- zamples/scene_lists/youtube/gummy_bear_song_youtube.yml
|
|
246
|
+
- zamples/scene_lists/youtube/nuki_song_youtube.yml
|
|
247
247
|
has_rdoc: true
|
|
248
248
|
homepage: http://github.com/rdp
|
|
249
249
|
licenses: []
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
name: cars widescreen 2006
|
|
2
|
-
player: VLC
|
|
3
|
-
mutes:
|
|
4
|
-
# one hour one minute and a half second to one hour one minute and 1.5s
|
|
5
|
-
"0:34:35" : "0:34:35" # "may doc have mercy on your soul"
|
|
6
|
-
"36:09" : "36:11" # likes me for muh body
|
|
7
|
-
"37:05" : "37:06" # Mater makes a fart noise when discussing gas
|
|
8
|
-
"40:16" : "40:18" # ...good look at that sexy hot-rod
|
|
9
|
-
"44:24" : "44:46" # hill billy hxxx
|
|
10
|
-
"54:25" : "54:30" # crazy grandpa car what an idiot
|
|
11
|
-
"55:24" : "55:25" # mater "oh L....."
|
|
12
|
-
"57:06" : "57:07" # hill billy hxxx
|
|
13
|
-
"57:12" : "57:18" # sally: wait not spend the night "with me"...
|
|
14
|
-
"1:55:39" : "1:55:40" # for the "love of Chrysler" please....
|
|
15
|
-
|