sensible-cinema 0.9.3 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +7 -4
- data/README +42 -28
- data/Rakefile +1 -1
- data/TODO +53 -51
- data/VERSION +1 -1
- data/bin/sensible-cinema +30 -27
- data/lib/blanker.rb +3 -3
- data/lib/keyboard_input.rb +1 -1
- data/lib/ocr.rb +12 -9
- data/lib/overlayer.rb +17 -5
- data/lib/screen_tracker.rb +33 -22
- data/never_do +27 -0
- data/spec/images/{4.bmp → vlc_2_4.bmp} +0 -0
- data/spec/images/youtube_2_3.bmp +0 -0
- data/spec/images/youtube_light_0.bmp +0 -0
- data/spec/images/youtube_light_2_1.bmp +0 -0
- data/spec/images/youtube_light_2_3.bmp +0 -0
- data/spec/images/youtube_light_4.bmp +0 -0
- data/spec/images/youtube_light_4_3.bmp +0 -0
- data/spec/images/youtube_light_5.bmp +0 -0
- data/spec/images/youtube_light_5_0.bmp +0 -0
- data/spec/images/youtube_light_8.bmp +0 -0
- data/spec/images/youtube_light_9.bmp +0 -0
- data/spec/ocr.spec.rb +25 -12
- data/spec/screen_tracker.spec.rb +47 -15
- data/zamples/players/{how_to_create_a_new_player_description.txt → how_to_create_more.txt} +7 -0
- data/zamples/players/vlc/full_screened_total_length_over_an_hour.yml +3 -0
- data/zamples/players/vlc/{vlc_windows_total_length_over_an_hour.yml → windowed_total_length_over_an_hour.yml} +5 -1
- data/zamples/players/vlc/{non_full_screened_total_length_under_an_hour.yml → windowed_total_length_under_an_hour.yml} +3 -1
- data/zamples/players/youtube/full_screened_1024x768.yml +3 -0
- data/zamples/players/youtube/normal_in_youtube.com.yml +22 -0
- data/zamples/scene_lists/White Christmas.yml +15 -0
- data/zamples/scene_lists/all_dogs_go_to_heaven_dvd.yml +9 -0
- data/zamples/scene_lists/category descriptions.yml +6 -2
- data/zamples/scene_lists/{example_scene_list.yml → example_scene_descriptions_list.yml} +26 -24
- data/zamples/scene_lists/gummy_bear_song_youtube.yml +8 -7
- data/zamples/scene_lists/nuki_song_youtube.yml +9 -9
- metadata +24 -10
data/LICENSE
CHANGED
@@ -4,13 +4,16 @@ May contain some 3rd party libraries under their own (separate, open source) lic
|
|
4
4
|
|
5
5
|
Note that this software should be legal in the EU,
|
6
6
|
as it is only software and therefore theoretically not subject to patents (see "What about patent licenses?" in [2]).
|
7
|
-
|
7
|
+
It's basically for use in the EU.
|
8
8
|
If it's not legal in your country, don't use it!
|
9
9
|
|
10
|
-
http://en.wikipedia.org/wiki/Family_Entertainment_and_Copyright_Act describes a recent
|
11
|
-
in its favor.
|
10
|
+
The http://en.wikipedia.org/wiki/Family_Entertainment_and_Copyright_Act describes a recent
|
11
|
+
US law that appears related (and is in its favor).
|
12
|
+
|
13
|
+
A history of various related thoughts was described here:
|
14
|
+
http://betterlogic.com/roger/?p=2618
|
12
15
|
|
13
|
-
|
16
|
+
Enjoy!
|
14
17
|
|
15
18
|
[1] http://www.gnu.org/licenses/gpl.html, also gplv3 file.
|
16
19
|
[2] http://www.videolan.org/support/faq.html
|
data/README
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
Sensible-cinema is a program that allows you to do pre-programmed scene selection (i.e. "mute out"
|
2
2
|
or "bleep out" scenes) on arbitrary media players like netflix online, vlc, etc.
|
3
3
|
|
4
|
-
|
5
4
|
Currently it takes as input a list of "skippable" scenes, and a player description.
|
6
5
|
It then tracks whichever player you are using, and mutes or blanks out the system appropriately,
|
7
6
|
during the scenes specified.
|
@@ -51,9 +50,9 @@ To program sensible-cinema, you create a scene description list it can use.
|
|
51
50
|
|
52
51
|
An Edit Decision List (EDL) looks something like this trivial example:
|
53
52
|
|
54
|
-
mutes:
|
55
|
-
"01:00:00" : "01:01:02.5" # mute from exactly one hour to one hour, one minute, two seconds and a half will be muted.
|
56
|
-
blank_outs:
|
53
|
+
mutes:
|
54
|
+
"01:00:00" : "01:01:02.5" # mute from exactly one hour to one hour, one minute, two seconds and a half will be muted.
|
55
|
+
blank_outs:
|
57
56
|
"01:00:00" : "01:01:02.5" # also blank out (overlay with blank window) the same.
|
58
57
|
|
59
58
|
Here's one with more detail
|
@@ -89,35 +88,34 @@ This will create the file "example_scene_list Copy.yml"
|
|
89
88
|
Right click on it, choose rename, and give it a better name.
|
90
89
|
Now "right click -> Open" to open it in an editor (recommend installing notepad++ and using that).
|
91
90
|
|
92
|
-
== FAQ ==
|
93
|
-
|
94
|
-
Q. Can I watch movies this way on my TV, not just on my computer?
|
95
|
-
|
96
|
-
A.
|
97
|
-
|
98
|
-
(
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
91
|
+
== FAQ ==
|
92
|
+
|
93
|
+
Q. Can I watch movies this way on my TV, not just on my computer?
|
94
|
+
|
95
|
+
A. Maybe. Or possible not yet, depending on your current hardware.
|
96
|
+
Currently you'll either need to attach your computer to your TV
|
97
|
+
(buy some long cables, or a new graphics card that matches your cables, etc.)
|
98
|
+
or get some computer that you can move closer to the TV to do the same
|
99
|
+
(ex: buy a used older laptop with s-video out, use that, or a laptop with DVI/HDMI would
|
100
|
+
work with an HDMI TV). If you're really aggressive you could run an ethernet cable from your computer, as well [1].
|
101
|
+
I'd be happy to do a linux port of sensible-cinema if anybody requests it, for use with
|
102
|
+
their dedicated TV computer.
|
103
|
+
There has also been some work toward getting ones computer to stream "live" to your existing wii/ps3/xbox.
|
104
|
+
Message me if you're interested in trying it out (testers wanted--plus I'll only work on it if there's demand)!
|
103
105
|
|
104
106
|
Q. What movies does this work with?
|
105
107
|
|
106
|
-
A. Any that you program it for :) (Assuming the player is compatible, which most probably are.)
|
108
|
+
A. Any that you program it for :) (Assuming the computer player is compatible, which most probably are.)
|
107
109
|
|
108
110
|
Q. What movies are freely available to watch online?
|
109
111
|
|
110
|
-
A. Not many are available free (hulu, youtube have a few)
|
111
|
-
|
112
|
+
A. Not many are available free (hulu, youtube have a few). Netflix has quite a few with its default subscription.
|
113
|
+
You can of course use it with any existing DVD, or rent or borrow DVD's and watch them using sensible-cinema.
|
112
114
|
|
113
115
|
Q. Why does my mouse bounce up and down while sensible-cinema is going?
|
114
116
|
|
115
117
|
A. This enables your player to keep its on-screen time tracker, which in turn allows sensible-cinema to track where
|
116
|
-
you're at. Message me if this bugs you too much and we'll see what we can do
|
117
|
-
|
118
|
-
Q. Why does it seem really laggy at time detection at the beginning?
|
119
|
-
|
120
|
-
A. It takes it awhile to warm up its digit detection. Ping me if you would like to see this improved speed-wise.
|
118
|
+
you're at. Message me if this bugs you too much and we'll see what we can do about it.
|
121
119
|
|
122
120
|
[1] http://ps3mediaserver.org/forum/viewtopic.php?f=6&t=5731#p34279
|
123
121
|
|
@@ -131,6 +129,15 @@ to pick them each time, like:
|
|
131
129
|
Also if you specify "test" for the scene descriptions file, it will pause 4s, take a snapshot of the player, then exit.
|
132
130
|
You can also specify -v or -t if you want to enable more verbose (chatty) output.
|
133
131
|
|
132
|
+
== Caveats ==
|
133
|
+
|
134
|
+
NB that "someone" will have to create a scene descriptions list, per DVD/online movie.
|
135
|
+
Unless it already exists, then "someone" already did.
|
136
|
+
|
137
|
+
Also note that it takes a bit to get "warmed" up when you first start using it (it uses OCR
|
138
|
+
to track the screen time), so it might be a tidge laggy at time tracking when first used.
|
139
|
+
Ping me if you want this improved.
|
140
|
+
|
134
141
|
== Thanks ==
|
135
142
|
|
136
143
|
Thanks to Jarmo for the win32-screenshot gem, mini_magick gem authors, jruby guys, etc.
|
@@ -142,15 +149,22 @@ See the LICENSE file for licensing, usage terms (basically gplv3).
|
|
142
149
|
|
143
150
|
== Related ==
|
144
151
|
|
152
|
+
http://imdb.com tends to have reasonably good lists of what occurs in movies (find a movie, click on "parent's guide" on the left).
|
153
|
+
Sometimes it even lists the time signatures for events (ex: "Labyrinth" http://www.imdb.com/title/tt0047673/parentalguide)
|
154
|
+
which you could use to translate into a sensible-cinema compatible list.
|
155
|
+
|
145
156
|
The concept isn't too novel:
|
146
157
|
|
147
|
-
http://en.wikipedia.org/wiki/Edit_decision_list (linear editing tool)
|
148
|
-
http://www.imdb.com/swiki/special?ParentalGuideHelp search for "scene description"
|
158
|
+
http://en.wikipedia.org/wiki/Edit_decision_list (it's linear editing tool)
|
159
|
+
http://www.imdb.com/swiki/special?ParentalGuideHelp and search for "scene description"
|
149
160
|
http://www.oreillynet.com/sysadmin/blog/2005/06/make_your_own_phantom_edit_wit.html
|
161
|
+
http://forum.bsplayer.com/feature-requests-feedback-suggestions/7157-chapter-playlist-scene-cut-3.html
|
162
|
+
http://www.inmatrix.com/ "scene cut editor" of the zoom player
|
163
|
+
http://wiki.xbmc.org/?title=EDL_(commercial_skipping)_and_SceneMarker_support (XBMC's scene cut support--also links to more others)
|
164
|
+
http://code.google.com/p/movie-content-editor (same thing, but in Python and only for VLC)
|
165
|
+
http://clearplay.com similar, but commercial (closed), and only for DVD's (has its own DVD-player)
|
150
166
|
|
151
|
-
|
152
|
-
Sometimes it even lists the time signatures for events (ex: "Labyrinth" http://www.imdb.com/title/tt0047673/parentalguide)
|
153
|
-
which you could use to translate into a sensible-cinema compatible list.
|
167
|
+
though none of them are universal like this one is :)
|
154
168
|
|
155
169
|
== Feedback ==
|
156
170
|
|
data/Rakefile
CHANGED
@@ -7,7 +7,7 @@ Jeweler::Tasks.new do |s|
|
|
7
7
|
s.homepage = "http://github.com/rdp"
|
8
8
|
s.authors = ["Roger Pack"]
|
9
9
|
s.add_dependency 'sane', '>= 0.22.0'
|
10
|
-
s.add_dependency 'rdp-win32screenshot', '>= 0.0.
|
10
|
+
s.add_dependency 'rdp-win32screenshot', '>= 0.0.7.3'
|
11
11
|
s.add_dependency 'mini_magick' # for ocr...
|
12
12
|
s.add_development_dependency 'rspec' # prefer rspec 2 I guess...
|
13
13
|
s.add_development_dependency 'jeweler'
|
data/TODO
CHANGED
@@ -1,73 +1,77 @@
|
|
1
1
|
== medium ==
|
2
2
|
|
3
|
+
make all players actually play again
|
4
|
+
|
3
5
|
== low but actually want to do eventually (me) low prio: just do these...==
|
4
6
|
|
5
|
-
|
7
|
+
youtube non full screen: work with other browsers
|
8
|
+
slightly more accurate timestamp...
|
9
|
+
can parse IMDB (require they put in the URL by hand)
|
10
|
+
try the new GOCR sources...
|
11
|
+
PISH
|
12
|
+
add stuffs to imdb
|
6
13
|
|
7
14
|
== random backlog ... based on user request..remember: just local files for my own needs...==
|
8
|
-
note: just plow forward, to "grab" available ideas...
|
9
|
-
except that for now, just what *I* plan on needing for myself.
|
10
15
|
|
11
|
-
|
16
|
+
note: just plow forward, to "grab" available ideas...except that for now, just what *I*
|
17
|
+
plan on needing for myself (filters for what I need/want).
|
18
|
+
|
19
|
+
re-advertise on ruby talk
|
20
|
+
|
21
|
+
no money making for now...all volunteer...
|
22
|
+
|
23
|
+
an "online anybody can chat while watching this movie" (or anybody can edit this wav and listen to it a overlay...)
|
12
24
|
|
13
|
-
|
25
|
+
an online applet web runnable? Why not?
|
26
|
+
click here to watch your favorite film edited! Just click! [* yea!]
|
27
|
+
a chrome plugin with imdb/community backing :)
|
14
28
|
|
15
|
-
|
29
|
+
code refactors: "screen time change", order should be swapped in bin/x output
|
30
|
+
|
31
|
+
auto-play on detect youtube url access...
|
16
32
|
|
17
33
|
easier installer for windows: release a zip file that they can just click on a .bat file to run it
|
18
34
|
later: it installs/uninstalls appropo
|
19
35
|
suggestion: self-extractor
|
20
36
|
|
21
|
-
|
22
|
-
|
23
|
-
make it able to use multiple players so I can maximize VLC...
|
37
|
+
make it able to use both windowed and maximized VLC (and full screen) seamlessly
|
24
38
|
|
25
|
-
blank overlay text like "and you are one awesome klingon"
|
39
|
+
can blank overlay with text like "and you are one awesome klingon"
|
26
40
|
|
27
41
|
screencast of things helpful (use, creation).
|
28
42
|
|
29
|
-
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?"
|
43
|
+
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?"
|
30
44
|
|
31
|
-
a netflix online player
|
45
|
+
a netflix online player descriptor
|
32
46
|
|
33
|
-
add my stuff to imdb
|
47
|
+
add my stuff to imdb...?
|
34
48
|
|
35
|
-
|
49
|
+
make youtube work if you have *several* open
|
36
50
|
|
37
51
|
user customizable levels...
|
38
52
|
maybe even "I don't like ones that are x, y, z", or "boring level x"
|
39
53
|
|
40
|
-
|
41
|
-
|
42
|
-
can overlay with a "fuzzer-outer" for specific coordinates somehow or other...
|
54
|
+
with VLC/youtube non full screen, it does the annoying mouse thing needlessly (which doesn't bug as much these days...)
|
43
55
|
|
44
|
-
|
56
|
+
hulu non full screened descriptor
|
45
57
|
|
46
|
-
|
58
|
+
can overlay with wav file (would work already for VLC [?], could also "click to mute" for others...hmm...)
|
47
59
|
|
48
|
-
|
60
|
+
fix any/all pending tests...
|
49
61
|
|
50
|
-
|
62
|
+
can permanently black out certain coords to keep things prettier...
|
51
63
|
|
52
|
-
|
53
|
-
|
54
|
-
can black out certain coords to keep things prettier...
|
55
|
-
|
56
|
-
allow x2,y2 for player descriptions...
|
57
|
-
|
58
|
-
Linux port (call that good enough for usability on TV's...) between that and a VLC version...
|
59
|
-
|
60
|
-
a web runnable? Why not?
|
61
|
-
click here to watch your favorite film edited! Just click!
|
64
|
+
Linux port (call that good enough for usability on TV's...), should be...
|
62
65
|
|
63
66
|
blank out with specifiable color
|
64
67
|
better default color?
|
65
68
|
|
66
69
|
Auto mute/blank commercials?
|
67
70
|
|
68
|
-
|
71
|
+
transfer ownership to an LLC
|
72
|
+
new github username
|
69
73
|
|
70
|
-
replay
|
74
|
+
replay certain film sections :P
|
71
75
|
|
72
76
|
overlay/replace current playback with some url of audio or video
|
73
77
|
user editable overlays (like a wiki...)
|
@@ -76,34 +80,32 @@ control volume programmatically (using mouse) on the player itself.
|
|
76
80
|
control mute programmatically (using mouse) on the player itself.
|
77
81
|
control location programmatically (using mouse) on the player itself.
|
78
82
|
|
79
|
-
compare timings with a real DVD player...
|
83
|
+
compare VLC (and other) timings with a real DVD player...
|
80
84
|
|
81
85
|
overlay with an alpha transparent pic
|
82
86
|
|
83
87
|
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...
|
84
88
|
|
85
|
-
|
89
|
+
does my sweet heart have any suggestions? (make it work well for laymen)
|
86
90
|
|
87
|
-
|
91
|
+
some type of installer that can setup the registry...
|
88
92
|
|
89
93
|
auto-assignment of EDL's to media:
|
94
|
+
auto-play option for DVD's (auto-start?)
|
95
|
+
use normal differentiation
|
96
|
+
use spiffy differentiation for DVD's on windows
|
90
97
|
DVD's (right click on DVD player, play with scene-skipper?)
|
91
98
|
web browser plugin?
|
92
|
-
auto start on DVD insertion (?)
|
93
|
-
and show appropriate scene-lists available based on title/md5 of something?
|
94
99
|
|
95
|
-
Programmatically do all of the above, by driving
|
100
|
+
Programmatically do all of the above, by driving VLC with its real API.
|
96
101
|
VLC
|
97
|
-
Allow it to record
|
102
|
+
Allow it to record somehow (recordable)
|
98
103
|
burnable to DVD/CD ...
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
For now it's either a cable, a computer (with its cable), or pay.
|
108
|
-
todo: make a VLC wrapper so it works *if your soundcard supports it*
|
109
|
-
after: make the same work awesome on doze 7 without soundcard support :)
|
104
|
+
use VLC's web interface? telnet?
|
105
|
+
optimize it with best appropriate iframes (LOL)
|
106
|
+
|
107
|
+
star trek: generations first profanidade...
|
108
|
+
|
109
|
+
"Showing EDL Information During Playback"
|
110
|
+
|
111
|
+
integrate with google TV/bravia...maybe...somehow...boxxee?
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.4
|
data/bin/sensible-cinema
CHANGED
@@ -4,12 +4,16 @@ require 'sane'
|
|
4
4
|
|
5
5
|
Thread.abort_on_exception=true #gah
|
6
6
|
|
7
|
-
for file in ['overlayer', 'keyboard_input', 'screen_tracker', 'mouse', 'file_chooser']
|
7
|
+
for file in ['overlayer', 'keyboard_input', 'screen_tracker', 'mouse', 'file_chooser', 'ocr']
|
8
8
|
require_relative '../lib/' + file
|
9
9
|
end
|
10
10
|
|
11
11
|
$VERBOSE = 1 if ARGV.delete('-v')
|
12
12
|
$TEST = 1 if ARGV.delete('-t')
|
13
|
+
if ARGV.delete('--clear-cache')
|
14
|
+
OCR.clear_cache!
|
15
|
+
puts 'cleared cache'
|
16
|
+
end
|
13
17
|
|
14
18
|
$stderr.puts 'warning: currently windows only for certain parts currently' unless ENV['OS'] == 'Windows_NT'
|
15
19
|
|
@@ -17,63 +21,59 @@ if ARGV.detect{|arg| arg == '-h' || arg == '--help'}
|
|
17
21
|
|
18
22
|
puts <<-END
|
19
23
|
|
20
|
-
syntax:
|
24
|
+
syntax: player_description.yml|test scene_descriptions_list.yml [-t -v --clear-cache] (or nothing to prompt for files)
|
21
25
|
END
|
22
26
|
|
23
27
|
for file in Dir[__dir__ + '../zamples/mute*/*']
|
24
28
|
puts "\n", "Example file:", file + "\n\n", File.read(file)
|
25
29
|
end
|
26
30
|
|
27
|
-
puts '', 'Available files:'
|
28
|
-
for file in Dir[__dir__ + '../zamples/*/*']
|
29
|
-
puts File.expand_path(file) unless File.directory?(file)
|
30
|
-
end
|
31
31
|
exit 1
|
32
32
|
|
33
33
|
else
|
34
34
|
|
35
35
|
# allow for command line filenames
|
36
|
-
|
37
|
-
|
36
|
+
|
37
|
+
player_description = ARGV.shift.to_s
|
38
|
+
if !File.exist?(player_description)
|
39
|
+
puts 'Please Select Computer Player'
|
40
|
+
player_description = FileChooser.choose_file("SELECT COMPUTER PLAYER", __dir__ + "/../zamples/players")
|
41
|
+
end
|
42
|
+
|
43
|
+
scene_list = ARGV.shift.to_s
|
38
44
|
|
39
45
|
if scene_list == 'test'
|
40
46
|
overlay = nil
|
41
47
|
p 'got test...just doing screen dump'
|
42
|
-
$VERBOSE=true # some extra output
|
48
|
+
$VERBOSE=true # adds some extra output
|
43
49
|
else
|
44
|
-
if !File.exist? scene_list
|
50
|
+
if !File.exist? scene_list
|
45
51
|
puts 'Select Scene Descriptions file'
|
46
52
|
scene_list = FileChooser.choose_file("SELECT SCENE DESCRIPTIONS FILE", __dir__ + "/../zamples/scene_lists")
|
47
53
|
end
|
48
54
|
|
49
|
-
|
55
|
+
if !scene_list
|
50
56
|
puts "error: have to specify a scene descriptions file\n or specify \"test\" on the command line if you just want to snapshot your player"
|
51
57
|
exit 1
|
52
58
|
end
|
53
|
-
puts 'Selected scene descriptions file ' + File.basename(scene_list) + "\n\t(#{scene_list})"
|
54
|
-
Blanker.startup
|
55
59
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
player_description = FileChooser.choose_file("SELECT COMPUTER PLAYER", __dir__ + "/../zamples/players")
|
62
|
-
end
|
63
|
-
|
64
|
-
# start it late as it has an annoying startup blip
|
65
|
-
overlay = OverLayer.new(scene_list)
|
60
|
+
puts 'Selected scene descriptions file ' + File.basename(scene_list) + "\n\t(full path: #{scene_list})"
|
61
|
+
Blanker.startup
|
62
|
+
# todo start it late as it has an annoying startup blip
|
63
|
+
overlay = OverLayer.new(scene_list)
|
64
|
+
end
|
66
65
|
|
67
66
|
if File.exist? player_description.to_s
|
68
|
-
puts 'Selected player ' + File.basename(player_description) + "\n\t(#{player_description})"
|
67
|
+
puts 'Selected player ' + File.basename(player_description) + "\n\t(full path: #{player_description})"
|
69
68
|
# this one doesn't use any updates, so just pass in file contents, not filename
|
70
69
|
screen_tracker = ScreenTracker.new_from_yaml File.binread(player_description), overlay
|
71
70
|
Mouse.jitter_forever_in_own_thread # when this ends you know the snapshot was taken...
|
72
71
|
|
73
72
|
# exit early if we just wanted a screen dump...a little kludgey...
|
74
73
|
unless overlay
|
75
|
-
puts 'warning--only doing screen dump in
|
74
|
+
puts 'warning--only doing screen dump in t-minus 4s...'
|
76
75
|
sleep 4
|
76
|
+
puts 'snap!'
|
77
77
|
screen_tracker.dump_bmp
|
78
78
|
exit 1
|
79
79
|
end
|
@@ -81,14 +81,17 @@ else
|
|
81
81
|
else
|
82
82
|
puts 'warning--not using any screen tracking...'
|
83
83
|
end
|
84
|
+
|
84
85
|
OCR.unserialize_cache_from_disk # do this every time so we don't delete it if they don't have one...
|
85
86
|
|
86
87
|
puts "Opening the curtains... (please play in player now)"
|
87
88
|
overlay.start_thread true
|
88
89
|
key_input = KeyboardInput.new overlay
|
89
90
|
key_input.start_thread # status thread
|
91
|
+
at_exit {
|
92
|
+
Blanker.shutdown # lodo move this and the 'q' key to within overlayer
|
93
|
+
OCR.serialize_cache_to_disk
|
94
|
+
}
|
90
95
|
key_input.handle_keystrokes_forever # when this method exits, we want to exit fully...
|
91
|
-
Blanker.shutdown # lodo move this and the 'q' key to within overlayer
|
92
|
-
OCR.serialize_cache_to_disk
|
93
96
|
|
94
97
|
end
|
data/lib/blanker.rb
CHANGED
@@ -9,11 +9,11 @@ else
|
|
9
9
|
JLabel = javax.swing.JLabel
|
10
10
|
|
11
11
|
def self.startup
|
12
|
-
@fr = JFrame.new("
|
12
|
+
@fr = JFrame.new("Sensible Cinema blanker-outer overlay window")
|
13
13
|
@fr.default_close_operation = JFrame::EXIT_ON_CLOSE
|
14
|
-
@fr.set_size(2000, 2000) # ltodo better size
|
14
|
+
@fr.set_size(2000, 2000) # ltodo better size ?
|
15
15
|
|
16
|
-
@label = JLabel.new
|
16
|
+
@label = JLabel.new
|
17
17
|
@fr.add(@label)
|
18
18
|
@label.repaint
|
19
19
|
@label.revalidate
|
data/lib/keyboard_input.rb
CHANGED
@@ -31,7 +31,7 @@ class KeyboardInput
|
|
31
31
|
def handle_keystrokes_forever
|
32
32
|
raise 'only jruby supported, as it looks just too messy in normal ruby' unless OS.java?
|
33
33
|
while(ch = getch)
|
34
|
-
|
34
|
+
exit if ch == 3 # ctrl+c
|
35
35
|
# lodo handle arrow keys, too, which is a bit more complicated...
|
36
36
|
handle_keystroke ch
|
37
37
|
end
|
data/lib/ocr.rb
CHANGED
@@ -10,10 +10,12 @@ module OCR
|
|
10
10
|
|
11
11
|
# options are :might_be_colon, :should_invert
|
12
12
|
def identify_digit memory_bitmap, options = {}
|
13
|
-
require 'mini_magick' # installation woe, but actually
|
13
|
+
require 'mini_magick' # here because of installation woe, but actually not a big slowdown
|
14
14
|
|
15
15
|
if CACHE.has_key?(memory_bitmap)
|
16
16
|
return CACHE[memory_bitmap] unless (defined?($OCR_NO_CACHE) && $OCR_NO_CACHE)
|
17
|
+
else
|
18
|
+
puts 'cache miss' if $DEBUG && $VERBOSE
|
17
19
|
end
|
18
20
|
if options[:might_be_colon]
|
19
21
|
# do processing in-line <sigh>
|
@@ -31,24 +33,25 @@ module OCR
|
|
31
33
|
# but doesn't want sharpen, for whatever reason...
|
32
34
|
# mogrify calls it negate...
|
33
35
|
image.negate
|
34
|
-
else
|
35
|
-
# youtube wants sharpen...
|
36
|
-
image.sharpen(2)
|
37
36
|
end
|
38
37
|
|
39
38
|
image.format(:pnm)
|
40
|
-
|
39
|
+
image.sharpen(2) if options[:sharpen] # hulu does *not* want sharpen, though I haven't checked it too closely...
|
40
|
+
|
41
|
+
previous = nil
|
42
|
+
p options if $DEBUG
|
43
|
+
for level in options[:levels]
|
41
44
|
a = `#{GOCR} -l #{level} #{image.path} 2>NUL`
|
42
|
-
# a can be like "_1_\n"
|
43
45
|
if a =~ /[0-9]/
|
46
|
+
# it can be like "_1_\n"
|
44
47
|
a.strip!
|
45
48
|
a.gsub!('_', '')
|
46
49
|
a = a.to_i
|
47
|
-
CACHE[memory_bitmap] = a
|
48
|
-
return a
|
50
|
+
return CACHE[memory_bitmap] = a
|
49
51
|
end
|
50
52
|
end
|
51
|
-
#
|
53
|
+
# cache failures here, for VLC's hour clock' sake
|
54
|
+
CACHE[memory_bitmap] = nil
|
52
55
|
nil
|
53
56
|
end
|
54
57
|
|
data/lib/overlayer.rb
CHANGED
@@ -40,6 +40,7 @@ class OverLayer
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def unblank!
|
43
|
+
@just_unblanked = true
|
43
44
|
@am_blanked = false
|
44
45
|
Blanker.unblank_full_screen!
|
45
46
|
end
|
@@ -89,6 +90,7 @@ class OverLayer
|
|
89
90
|
@cv = ConditionVariable.new
|
90
91
|
@file_mtime = nil
|
91
92
|
check_reload_yaml
|
93
|
+
@just_unblanked = false
|
92
94
|
@start_time = Time.now_f # assume they want to start immediately...
|
93
95
|
end
|
94
96
|
|
@@ -145,7 +147,14 @@ class OverLayer
|
|
145
147
|
end
|
146
148
|
|
147
149
|
def timestamp_changed to_this_exact_string_might_be_nil, delta
|
148
|
-
|
150
|
+
if @just_unblanked
|
151
|
+
# ignore it, since it was probably just caused by the screen blipping
|
152
|
+
# at worse this will put us 1s behind...hmm.
|
153
|
+
@just_unblanked = false
|
154
|
+
p 'ignoring timestamp update ' + to_this_exact_string_might_be_nil if $VERBOSE
|
155
|
+
else
|
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
|
+
end
|
149
158
|
end
|
150
159
|
|
151
160
|
def self.translate_string_to_seconds s
|
@@ -176,20 +185,20 @@ class OverLayer
|
|
176
185
|
end
|
177
186
|
|
178
187
|
def status
|
179
|
-
time =
|
188
|
+
time = cur_english_time
|
180
189
|
begin
|
181
190
|
mute, blank, next_sig = get_current_state
|
182
191
|
if next_sig == :done
|
183
|
-
state = " no more
|
192
|
+
state = " no more after this point..."
|
184
193
|
else
|
185
|
-
state = " next
|
194
|
+
state = " next will be at #{translate_time_to_human_readable next_sig}s "
|
186
195
|
end
|
187
196
|
if blank? or muted?
|
188
197
|
state += "(" + [muted? ? "muted" : nil, blank? ? "blanked" : nil ].compact.join(' ') + ") "
|
189
198
|
end
|
190
199
|
end
|
191
200
|
check_reload_yaml
|
192
|
-
time + state + "(r
|
201
|
+
time + state + "(r [or q to quit]): "
|
193
202
|
end
|
194
203
|
|
195
204
|
def keyboard_input char
|
@@ -201,6 +210,9 @@ class OverLayer
|
|
201
210
|
when 's' then 1
|
202
211
|
when 'S' then -1
|
203
212
|
when 't' then 0.1
|
213
|
+
when 'q' then
|
214
|
+
puts '','quitting'
|
215
|
+
exit(1)
|
204
216
|
when 'T' then -0.1
|
205
217
|
when 'v' then
|
206
218
|
$VERBOSE = !$VERBOSE
|
data/lib/screen_tracker.rb
CHANGED
@@ -7,19 +7,18 @@ class ScreenTracker
|
|
7
7
|
|
8
8
|
def self.new_from_yaml yaml, callback
|
9
9
|
settings = YAML.load yaml
|
10
|
-
|
11
|
-
|
12
|
-
digits = settings["digits"]
|
13
|
-
return new(settings["name"], settings["x"], settings["y"], settings["width"], settings["height"], digits, callback)
|
10
|
+
return new(settings["name"], settings["x"], settings["y"], settings["width"],
|
11
|
+
settings["height"], settings["use_class_name"], settings["digits"], callback)
|
14
12
|
end
|
15
13
|
|
16
14
|
attr_accessor :hwnd
|
17
15
|
|
18
16
|
# digits are like {:hours => [100,5], :minute_tens, :minute_ones, :second_tens, :second_ones}
|
19
17
|
# digits share the height start point, have their own x and width...
|
20
|
-
def initialize name_or_regex,x,y,width,height,digits=nil,callback=nil
|
18
|
+
def initialize name_or_regex,x,y,width,height,use_class_name=nil,digits=nil,callback=nil
|
21
19
|
# cache to save us 0.00445136 per time LOL
|
22
20
|
@name_or_regex = name_or_regex
|
21
|
+
@use_class_name = use_class_name
|
23
22
|
get_hwnd
|
24
23
|
pps 'height', height, 'width', width if $VERBOSE
|
25
24
|
raise 'poor dimentia' if width <= 0 || height <= 0
|
@@ -36,7 +35,9 @@ class ScreenTracker
|
|
36
35
|
@x = x; @y = y; @x2 = x+width; @y2 = y+height; @callback = callback
|
37
36
|
@max_x = max_x
|
38
37
|
raise 'poor width or wrong window' if @x2 > max_x || @x2 == x
|
39
|
-
|
38
|
+
if @y2 > max_y || @y2 == y
|
39
|
+
raise 'poor height or wrong window'
|
40
|
+
end
|
40
41
|
@digits = digits
|
41
42
|
@displayed_warning = false
|
42
43
|
pps 'using x',@x, 'from x', x, 'y', @y, 'from y', y,'x2',@x2,'y2',@y2,'digits', @digits if $VERBOSE
|
@@ -45,19 +46,22 @@ class ScreenTracker
|
|
45
46
|
def get_hwnd
|
46
47
|
if @name_or_regex.to_s.downcase == 'desktop'
|
47
48
|
# full screen option
|
49
|
+
assert !@use_class_name # not an option
|
48
50
|
@hwnd = hwnd = Win32::Screenshot::BitmapMaker.desktop_window
|
51
|
+
return
|
49
52
|
else
|
50
|
-
@hwnd = Win32::Screenshot::BitmapMaker.hwnd(@name_or_regex)
|
53
|
+
@hwnd = Win32::Screenshot::BitmapMaker.hwnd(@name_or_regex, @use_class_name)
|
51
54
|
end
|
52
55
|
|
56
|
+
# allow ourselves the 'found it message' selectively
|
53
57
|
unless @hwnd
|
54
58
|
until @hwnd
|
55
|
-
print 'perhaps not running yet? [%s]' % @name_or_regex
|
59
|
+
print 'perhaps not running yet? [%s]' % @name_or_regex.inspect
|
56
60
|
sleep 1
|
57
61
|
STDOUT.flush
|
58
|
-
@hwnd = Win32::Screenshot::BitmapMaker.hwnd(@name_or_regex)
|
62
|
+
@hwnd = Win32::Screenshot::BitmapMaker.hwnd(@name_or_regex, @use_class_name)
|
59
63
|
end
|
60
|
-
puts 'found window'
|
64
|
+
puts 're-found window'
|
61
65
|
end
|
62
66
|
|
63
67
|
end
|
@@ -77,18 +81,16 @@ class ScreenTracker
|
|
77
81
|
def dump_bmp filename = 'dump.bmp'
|
78
82
|
File.binwrite filename, get_bmp
|
79
83
|
File.binwrite 'all.' + filename, get_full_bmp
|
80
|
-
dump_digits
|
84
|
+
dump_digits get_digits_as_bitmaps if @digits
|
81
85
|
end
|
82
86
|
|
83
|
-
def dump_digits
|
84
|
-
if @digits
|
87
|
+
def dump_digits digits
|
85
88
|
@digit_count ||= 1
|
86
|
-
@digit_count += 1
|
87
89
|
for type, bitmap in get_digits_as_bitmaps
|
88
90
|
File.binwrite type.to_s + '.' + @digit_count.to_s + '.bmp', bitmap
|
89
91
|
end
|
90
|
-
print '
|
91
|
-
|
92
|
+
print 'debug dumped digits that Im about to parse:', @digit_count, "\n"
|
93
|
+
@digit_count += 1
|
92
94
|
end
|
93
95
|
|
94
96
|
DIGIT_TYPES = [:hours, :minute_tens, :minute_ones, :second_tens, :second_ones]
|
@@ -150,9 +152,17 @@ class ScreenTracker
|
|
150
152
|
|
151
153
|
def attempt_to_get_time_from_screen
|
152
154
|
out = {}
|
153
|
-
|
154
|
-
|
155
|
+
# force it to have two matching in a row, to avoid race conditions grabbing the digits...
|
156
|
+
previous = nil # 0.08s [!] not too accurate...ltodo
|
155
157
|
start = Time.now
|
158
|
+
until previous == (temp = get_digits_as_bitmaps)
|
159
|
+
previous = temp
|
160
|
+
sleep 0.05 # allow youtube to update (sigh)
|
161
|
+
# lodo it should probably poll *before* this, not here...maybe?
|
162
|
+
end
|
163
|
+
digits = previous
|
164
|
+
|
165
|
+
dump_digits(digits) if $DEBUG
|
156
166
|
DIGIT_TYPES.each{|type|
|
157
167
|
if digits[type]
|
158
168
|
digit = identify_digit(digits[type])
|
@@ -162,18 +172,19 @@ class ScreenTracker
|
|
162
172
|
@a += 1
|
163
173
|
@already_wrote ||= {}
|
164
174
|
unless @already_wrote[digits[type]]
|
165
|
-
p 'unable to identify capture!' + type.to_s + @a.to_s
|
175
|
+
p 'unable to identify capture!' + type.to_s + @a.to_s + ' capture no:' + @digit_count.to_s
|
166
176
|
File.binwrite("bad_digit#{@a}#{type}.bmp", digits[type]) unless type == :hours
|
167
177
|
@already_wrote[digits[type]] = true
|
168
178
|
end
|
169
179
|
end
|
170
180
|
if type == :hours
|
171
|
-
digit = 0 # this one can fail in VLC
|
181
|
+
digit = 0 # this one can fail and that's ok in VLC bottom right
|
172
182
|
else
|
173
|
-
# early return
|
174
|
-
p 'identity failure ' + type.to_s if $VERBOSE
|
183
|
+
# early failure return
|
175
184
|
return
|
176
185
|
end
|
186
|
+
else
|
187
|
+
p " got digit #{type} as #{digit} which was captured as #{@digit_count} " if $DEBUG
|
177
188
|
end
|
178
189
|
out[type] = digit
|
179
190
|
else
|
data/never_do
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
== well, probably never :P ==
|
2
|
+
|
3
|
+
allow x2,y2 for player descriptions...
|
4
|
+
|
5
|
+
user-assignable "confidence" (how much time to 'wrap' surround the mutes, etc. to accomodate for slow computers/laggy internet/different players/poor input)
|
6
|
+
|
7
|
+
able to make it "quieter" at certain parts, arbitrarily...
|
8
|
+
|
9
|
+
OCR the captioning as an auto profanity filter?
|
10
|
+
|
11
|
+
can overlay with a "fuzzer-outer" for specific coordinates somehow or other...
|
12
|
+
|
13
|
+
super easy streamer windows -> {XBOX360, wii, etc..} basically playon.tv competitor, which appears to have no free equivalent, I guess, though you can
|
14
|
+
Currently it's either a cable, a computer (with its cable), or "ask me for this it might already work"
|
15
|
+
todo: refit a VLC version that works *if your soundcard supports it*
|
16
|
+
test it on the home PC--does it already work? (i.e. can work OOTB with right card)...
|
17
|
+
after: make the same work awesome on doze 7 without quality soundcard :)
|
18
|
+
make it work with ps3ms?
|
19
|
+
make it work from mac...
|
20
|
+
make it work seamlessly with all (XBOX360, wii x2, PS3, bravia)
|
21
|
+
also make it into a low quality "skype recorder"
|
22
|
+
also can I use a "lesser, faster encoder" to get higher resolution?
|
23
|
+
is it faster with ffdshow? mencoder?
|
24
|
+
blu-ray
|
25
|
+
over wired (?)
|
26
|
+
LAN?
|
27
|
+
does blu-ray work with HDMI well?
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/ocr.spec.rb
CHANGED
@@ -10,38 +10,51 @@ describe OCR do
|
|
10
10
|
OCR.version.should_not be_blank
|
11
11
|
end
|
12
12
|
|
13
|
-
Dir['images/*[0-9].bmp'].each{ |file|
|
13
|
+
Dir['images/*[0-9].bmp'].sort_by{|f| File.stat(f).mtime}.reverse.each{ |file|
|
14
14
|
it "should be able to OCR #{file}" do
|
15
|
+
p file if $DEBUG
|
15
16
|
options = {}
|
16
17
|
options[:should_invert] = true if file =~ /hulu/
|
18
|
+
options[:sharpen] = true if file =~ /youtube/
|
19
|
+
|
20
|
+
# 130 for vlc, 100 for hulu, 0 for some youtube full screen
|
21
|
+
# 200, 250 for youtube "light"
|
22
|
+
degrees = {'vlc' => [130], 'hulu' => [100], 'youtube' => [0], 'youtube_light' => [200, 250]}
|
23
|
+
file =~ /(vlc|hulu|youtube_light|youtube)/
|
24
|
+
options[:levels] = degrees[$1]
|
25
|
+
assert options[:levels]
|
17
26
|
file =~ /(.)\.bmp/
|
18
27
|
expected_digit = $1.to_i
|
19
|
-
|
28
|
+
got_digit = OCR.identify_digit(File.binread(file), options)
|
29
|
+
if got_digit != expected_digit
|
20
30
|
p "fail:" + file
|
21
31
|
begin
|
22
|
-
require 'ruby-debug'
|
23
|
-
debugger
|
32
|
+
#require 'ruby-debug'
|
33
|
+
#debugger
|
24
34
|
OCR.identify_digit(File.binread(file), options)
|
25
35
|
rescue LoadError
|
26
36
|
puts 'unable to load ruby-debug'
|
27
37
|
end
|
28
|
-
|
38
|
+
got_digit.should == expected_digit
|
29
39
|
end
|
30
40
|
end
|
31
41
|
}
|
32
42
|
|
33
43
|
it "should be able to grab a colon" do
|
34
|
-
pending "caring about colons"
|
35
|
-
|
36
|
-
end
|
44
|
+
pending "caring about colons"
|
45
|
+
OCR.identify_digit(File.binread("images/colon.bmp"), :might_be_colon => true, :levels => [130]).should == ":"
|
37
46
|
end
|
38
47
|
|
39
48
|
def read_digit
|
40
|
-
|
49
|
+
OCR.identify_digit(File.binread("images/youtube_3_0.bmp"), :sharpen => true, :levels => [130])
|
41
50
|
end
|
42
51
|
|
43
52
|
it "should return nil if it can't identify a digit" do
|
44
|
-
|
53
|
+
read_all_black.should be_nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def read_all_black
|
57
|
+
OCR.identify_digit(File.binread("images/black.bmp"),:levels => [130])
|
45
58
|
end
|
46
59
|
|
47
60
|
context "cache" do
|
@@ -62,8 +75,8 @@ describe OCR do
|
|
62
75
|
end
|
63
76
|
|
64
77
|
it "should not cache results for failed reads" do
|
65
|
-
original_time = Benchmark.realtime {
|
66
|
-
new_time = Benchmark.realtime { 3.times {
|
78
|
+
original_time = Benchmark.realtime { read_all_black }
|
79
|
+
new_time = Benchmark.realtime { 3.times { read_all_black} }
|
67
80
|
new_time.should be > original_time
|
68
81
|
end
|
69
82
|
|
data/spec/screen_tracker.spec.rb
CHANGED
@@ -8,18 +8,19 @@ describe ScreenTracker do
|
|
8
8
|
SILENCE = /silence.*VLC/
|
9
9
|
|
10
10
|
def start_vlc
|
11
|
-
# unfortunately this is run before every context with rspec 1.3...
|
11
|
+
# unfortunately this is run before every context [bug] with rspec 1.3...
|
12
12
|
unless $pid1
|
13
13
|
assert !$pid1
|
14
|
-
# enforce we only have at most one running
|
14
|
+
# enforce we only have at most one running...
|
15
15
|
begin
|
16
16
|
Win32::Screenshot.window(SILENCE, 0) {}
|
17
|
-
raise Exception.new('must
|
17
|
+
raise Exception.new('must close existing vlcs first')
|
18
18
|
rescue
|
19
19
|
silence = File.expand_path("./silence.wav").gsub("/", "\\")
|
20
|
-
Dir.chdir("/program files/VideoLan/VLC") do; IO.popen("vlc.exe #{silence}").pid; end # work around for jruby...
|
21
|
-
|
22
|
-
|
20
|
+
Dir.chdir("/program files/VideoLan/VLC") do; IO.popen("vlc.exe #{silence}").pid; end # includes a work around for jruby...
|
21
|
+
until $pid1
|
22
|
+
$pid1 = GetPid.get_process_id_from_window(Win32::Screenshot::Util.window_hwnd(SILENCE)) rescue nil
|
23
|
+
end
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
@@ -169,9 +170,10 @@ describe ScreenTracker do
|
|
169
170
|
|
170
171
|
it "should be able to disk dump snapshotted digits" do
|
171
172
|
@a.dump_bmp
|
172
|
-
|
173
|
-
Pathname.new('minute_tens.bmp').
|
174
|
-
Pathname.new('
|
173
|
+
# what is the right number here?
|
174
|
+
Pathname.new('minute_tens.1.bmp').should exist
|
175
|
+
Pathname.new('minute_tens.1.bmp').size.should be > 0
|
176
|
+
Pathname.new('hours.1.bmp').should_not exist
|
175
177
|
end
|
176
178
|
|
177
179
|
it "should use OCR against the changes appropriately" do
|
@@ -182,22 +184,46 @@ describe ScreenTracker do
|
|
182
184
|
output[1].should be_a Float
|
183
185
|
end
|
184
186
|
|
185
|
-
it "should be ok with a
|
187
|
+
it "should be ok with a non-existent hours image" do
|
186
188
|
@a.stub!(:get_digits_as_bitmaps) do
|
187
|
-
four = File.binread('images/
|
189
|
+
four = File.binread('images/vlc_4.bmp')
|
190
|
+
black = File.binread('images/black.bmp')
|
188
191
|
{:minute_tens=>four,:second_tens => four, :second_ones => four, :minute_ones => four,
|
189
|
-
:hours =>
|
192
|
+
:hours => black}
|
190
193
|
end
|
191
194
|
@a.attempt_to_get_time_from_screen[0].should == "0:44:44"
|
192
195
|
end
|
193
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
|
+
|
194
220
|
context "with an OCR that can change from hour to minutes during ads" do
|
195
221
|
it "should detect this change"
|
196
222
|
end
|
197
223
|
|
198
|
-
it "should be able to use invert on images" do
|
199
|
-
@a = ScreenTracker.new(SILENCE,
|
200
|
-
{:should_invert => true, :
|
224
|
+
it "should be able to use invert on captured images" do
|
225
|
+
@a = ScreenTracker.new(SILENCE, 100, 100, 10, 10, false,
|
226
|
+
{:should_invert => true, :second_ones => [-66, 7]} )
|
201
227
|
got_it = nil
|
202
228
|
OCR.stub!(:identify_digit) {|*args|
|
203
229
|
got_it = args
|
@@ -217,6 +243,12 @@ describe ScreenTracker do
|
|
217
243
|
old_handle.should_not == @a.hwnd
|
218
244
|
end
|
219
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
|
+
|
220
252
|
end
|
221
253
|
|
222
254
|
def kill_vlc
|
@@ -14,4 +14,11 @@ NB that the clock coords can have negative start offsets, which mean "distance f
|
|
14
14
|
NB that you can specify "desktop" for the window name, meaning full screen. This is easier, though not necessarily better,
|
15
15
|
than finding out the real way.
|
16
16
|
|
17
|
+
Here is how to specify a regex anywhere:
|
18
|
+
|
19
|
+
!ruby/regexp /abc/
|
20
|
+
|
21
|
+
like
|
22
|
+
key_name: !ruby/regexp /abc/
|
23
|
+
|
17
24
|
Post back with difficulties and/or questions.
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: !ruby/regexp /nativewindowclass/i
|
2
|
+
use_class_name: true
|
3
|
+
x: 71
|
4
|
+
y : -18
|
5
|
+
width: 23
|
6
|
+
height: 11
|
7
|
+
digits:
|
8
|
+
:hours:
|
9
|
+
:minute_tens:
|
10
|
+
:minute_ones:
|
11
|
+
- 72
|
12
|
+
- 8
|
13
|
+
:second_tens:
|
14
|
+
- 82
|
15
|
+
- 6
|
16
|
+
:second_ones:
|
17
|
+
- 88
|
18
|
+
- 6
|
19
|
+
:levels:
|
20
|
+
- 200
|
21
|
+
- 250
|
22
|
+
:sharpen: true
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# comments can go after the # on each line
|
2
|
+
mutes:
|
3
|
+
23:03 : 23:05 # all "religious references"
|
4
|
+
23:12 : 23:14
|
5
|
+
37:02 : 37:03
|
6
|
+
37:10 : 37:12
|
7
|
+
51:20 : 51:21
|
8
|
+
51:27 : 51:28
|
9
|
+
|
10
|
+
blank_outs:
|
11
|
+
58:09 : 1:04:03 # skimpy dancing/costumes in the background
|
12
|
+
|
13
|
+
title: White Christmas
|
14
|
+
source: VLC
|
15
|
+
non_got_yet: some of the same material in the previews (it's still there), a few scenes with skimpier clothing
|
@@ -1,11 +1,15 @@
|
|
1
1
|
"profanity categories, so you don't have to write them":
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
euphemized:
|
4
|
+
oh my gosh, dang, etc. (these prolly aren't as important to note)
|
5
|
+
|
6
|
+
religious reference:
|
7
|
+
"lord have mercy"
|
5
8
|
|
6
9
|
religious exclamation:
|
7
10
|
da**...
|
8
11
|
he**
|
12
|
+
|
9
13
|
religious exclamation deity:
|
10
14
|
oh my ****
|
11
15
|
g** d*** ***
|
@@ -1,24 +1,26 @@
|
|
1
|
-
# comments can go after the # on each line
|
2
|
-
mutes:
|
3
|
-
2.0 : 3.0
|
4
|
-
4.0 : 5.0 # mute from second 4 to second 5
|
5
|
-
9.0 : 13.0 # mute from second 9 to second 13
|
6
|
-
44.0 : 50.0 # mute for 6 seconds starting at second 44
|
7
|
-
# This next means mute from one minute to one minute one second
|
8
|
-
1:00 : 1:01
|
9
|
-
10:01 : 10:02 # mute from ten minutes, one second to ten minutes, 2 seconds
|
10
|
-
# if you use decimals, you'll have to put them in quotes
|
11
|
-
# 01:01:01.05 (for one hour, one minute, one second and a half) does not work
|
12
|
-
# "01:01:01.05" does
|
13
|
-
"01:01:00.5" : "01:01:01.5" # mute from one hour one minute and a half second to one hour one minute and 1.5s
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
1
|
+
# comments can go after the # on each line
|
2
|
+
mutes:
|
3
|
+
2.0 : 3.0
|
4
|
+
4.0 : 5.0 # mute from second 4 to second 5
|
5
|
+
9.0 : 13.0 # mute from second 9 to second 13
|
6
|
+
44.0 : 50.0 # mute for 6 seconds starting at second 44
|
7
|
+
# This next means mute from one minute to one minute one second
|
8
|
+
1:00 : 1:01
|
9
|
+
10:01 : 10:02 # mute from ten minutes, one second to ten minutes, 2 seconds
|
10
|
+
# if you use decimals, you'll have to put them in quotes
|
11
|
+
# 01:01:01.05 (for one hour, one minute, one second and a half) does not work
|
12
|
+
# "01:01:01.05" does
|
13
|
+
"01:01:00.5" : "01:01:01.5" # mute from one hour one minute and a half second to one hour one minute and 1.5s
|
14
|
+
# items can be out of chronological order
|
15
|
+
2.0 : 3.0
|
16
|
+
|
17
|
+
blank_outs:
|
18
|
+
"00:15" : "00:18" # blank from second 15 to 18
|
19
|
+
01:01 : "01:02.0" # blank from one minute one second to one minute two seconds, etc.
|
20
|
+
1:00:00 : 1:00:30 # note also that if you blank something out it isn't muted unless you *also* add it to the mute list, above. Message me if you want that changed.
|
21
|
+
|
22
|
+
title: Forever Strong
|
23
|
+
source: Hulu # these aren't required fields -- mutes and blank_outs are
|
24
|
+
something_else: "for now you can add whatever categories you want, like what_it_would_now_be_rated
|
25
|
+
what_aspects_were_not_able_to_be_removed, url, DVD label, etc, though in reality the only required ones are mutes and blank_outs"
|
26
|
+
|
@@ -1,8 +1,9 @@
|
|
1
|
-
mutes:
|
2
|
-
# none
|
3
|
-
blank_outs:
|
4
|
-
"0:01:02" : "0:01:06" # bum waggin'
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
mutes:
|
2
|
+
# none
|
3
|
+
blank_outs:
|
4
|
+
"0:01:02" : "0:01:06.5" # bum waggin'
|
5
|
+
0:02:17.5 : 0:02:19
|
6
|
+
|
7
|
+
title: The Gummy Bear Song - Long English Version (probably works with other languages')
|
8
|
+
source: youtube
|
8
9
|
url: http://www.youtube.com/watch?v=astISOttCQ0
|
@@ -1,9 +1,9 @@
|
|
1
|
-
mutes:
|
2
|
-
# none
|
3
|
-
blank_outs:
|
4
|
-
# bum wigglin'
|
5
|
-
"00:46.5" : "00:
|
6
|
-
"02:18.5" : "02:20"
|
7
|
-
title: Nuki Song
|
8
|
-
source: youtube
|
9
|
-
url: http://www.youtube.com/watch?v=xd12hR68sWM
|
1
|
+
mutes:
|
2
|
+
# none
|
3
|
+
blank_outs:
|
4
|
+
# bum wigglin'
|
5
|
+
"00:46.5" : "00:49"
|
6
|
+
"02:18.5" : "02:20"
|
7
|
+
title: Nuki Song
|
8
|
+
source: youtube
|
9
|
+
url: http://www.youtube.com/watch?v=xd12hR68sWM
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 9
|
8
|
-
-
|
9
|
-
version: 0.9.
|
8
|
+
- 4
|
9
|
+
version: 0.9.4
|
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-
|
17
|
+
date: 2010-09-12 00:00:00 -06:00
|
18
18
|
default_executable: sensible-cinema
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -43,9 +43,9 @@ dependencies:
|
|
43
43
|
segments:
|
44
44
|
- 0
|
45
45
|
- 0
|
46
|
-
-
|
46
|
+
- 7
|
47
47
|
- 3
|
48
|
-
version: 0.0.
|
48
|
+
version: 0.0.7.3
|
49
49
|
type: :runtime
|
50
50
|
version_requirements: *id002
|
51
51
|
- !ruby/object:Gem::Dependency
|
@@ -141,10 +141,10 @@ files:
|
|
141
141
|
- lib/ocr.rb
|
142
142
|
- lib/overlayer.rb
|
143
143
|
- lib/screen_tracker.rb
|
144
|
+
- never_do
|
144
145
|
- spec/blanker.spec.rb
|
145
146
|
- spec/common.rb
|
146
147
|
- spec/convert_image.rb
|
147
|
-
- spec/images/4.bmp
|
148
148
|
- spec/images/black.bmp
|
149
149
|
- spec/images/colon.bmp
|
150
150
|
- spec/images/hulu_0.bmp
|
@@ -160,6 +160,7 @@ files:
|
|
160
160
|
- spec/images/hulu_8.bmp
|
161
161
|
- spec/images/hulu_slash.bmp
|
162
162
|
- spec/images/vlc_0.bmp
|
163
|
+
- spec/images/vlc_2_4.bmp
|
163
164
|
- spec/images/vlc_2_6.bmp
|
164
165
|
- spec/images/vlc_4.bmp
|
165
166
|
- spec/images/vlc_5.bmp
|
@@ -169,6 +170,7 @@ files:
|
|
169
170
|
- spec/images/youtube_0.bmp
|
170
171
|
- spec/images/youtube_1.bmp
|
171
172
|
- spec/images/youtube_2_0.bmp
|
173
|
+
- spec/images/youtube_2_3.bmp
|
172
174
|
- spec/images/youtube_2_5.bmp
|
173
175
|
- spec/images/youtube_2_6.bmp
|
174
176
|
- spec/images/youtube_3_0.bmp
|
@@ -176,6 +178,15 @@ files:
|
|
176
178
|
- spec/images/youtube_4_0.bmp
|
177
179
|
- spec/images/youtube_5.bmp
|
178
180
|
- spec/images/youtube_6.bmp
|
181
|
+
- spec/images/youtube_light_0.bmp
|
182
|
+
- spec/images/youtube_light_2_1.bmp
|
183
|
+
- spec/images/youtube_light_2_3.bmp
|
184
|
+
- spec/images/youtube_light_4.bmp
|
185
|
+
- spec/images/youtube_light_4_3.bmp
|
186
|
+
- spec/images/youtube_light_5.bmp
|
187
|
+
- spec/images/youtube_light_5_0.bmp
|
188
|
+
- spec/images/youtube_light_8.bmp
|
189
|
+
- spec/images/youtube_light_9.bmp
|
179
190
|
- spec/images/youtube_small_0.bmp
|
180
191
|
- spec/images/youtube_small_2.bmp
|
181
192
|
- spec/images/youtube_small_2_0.bmp
|
@@ -212,18 +223,21 @@ files:
|
|
212
223
|
- vendor/imagemagick/msvcp90.dll
|
213
224
|
- vendor/imagemagick/msvcr90.dll
|
214
225
|
- vendor/imagemagick/vcomp90.dll
|
215
|
-
- zamples/players/
|
226
|
+
- zamples/players/how_to_create_more.txt
|
216
227
|
- zamples/players/hulu/total_length_over_an_hour.yml
|
217
228
|
- zamples/players/vlc/full_screened_total_length_over_an_hour.yml
|
218
|
-
- zamples/players/vlc/
|
219
|
-
- zamples/players/vlc/
|
229
|
+
- zamples/players/vlc/windowed_total_length_over_an_hour.yml
|
230
|
+
- zamples/players/vlc/windowed_total_length_under_an_hour.yml
|
220
231
|
- zamples/players/youtube/full_screened_1024x768.yml
|
221
232
|
- zamples/players/youtube/full_screened_1152x864.yml
|
222
233
|
- zamples/players/youtube/full_screened_1680x1050.yml
|
234
|
+
- zamples/players/youtube/normal_in_youtube.com.yml
|
223
235
|
- zamples/players/youtube/note_these_assume_less_than_10_minutes_length.txt
|
236
|
+
- zamples/scene_lists/White Christmas.yml
|
237
|
+
- zamples/scene_lists/all_dogs_go_to_heaven_dvd.yml
|
224
238
|
- zamples/scene_lists/category descriptions.yml
|
225
239
|
- zamples/scene_lists/disney_cars.yml
|
226
|
-
- zamples/scene_lists/
|
240
|
+
- zamples/scene_lists/example_scene_descriptions_list.yml
|
227
241
|
- zamples/scene_lists/gummy_bear_song_youtube.yml
|
228
242
|
- zamples/scene_lists/happy_feet_dvd.yml
|
229
243
|
- zamples/scene_lists/labyrinth.yml
|