sensible-cinema 0.25.1 → 0.25.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ require 'java'
2
+
3
+ module SensibleSwing
4
+
5
+ class MainWindow < javax.swing.JFrame
6
+ def self.download full_url, to_here
7
+ require 'open-uri'
8
+ require 'openssl'
9
+ eval("OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE")
10
+ writeOut = open(to_here, "wb")
11
+ writeOut.write(open(full_url).read)
12
+ writeOut.close
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,24 @@
1
+ == 0.25.2 ==
2
+
3
+ It tracks better now if the current OCR tracked player is paused, reverting back to its current timestamp.
4
+ Added ability to "auto-select" based on the url of currently open browsers, the right EDL.
5
+ Added ability to "auto-download" an EDL based on the current movie playing in the browser. Video also shows
6
+ retraining when window changes.
7
+ Added ability to "auto-select" player based on what is running, browser windows up, crossed with movies running.
8
+ Added the above, without file download (earlier commit could do them both however).
9
+ Note that this also means that it can scan over several player descriptions to "pick the right one" automatically.
10
+
11
+ Added a demo of VLC doing "transparent" and "opaque" overlays on another running image, based on timing.
12
+ NB That I already have shown a demo of adjusting volume and/or overlaying new audio on top of existing
13
+ media (a la rifftrax) previously.
14
+ Added demo of merging two video clips, with or without opacity/user configurable locations/dynamic ok too.
15
+
16
+ Added some demo commits showing how it could assign new/improved/user configurable/
17
+ ratings to EDL's and/or pieces of them.
18
+
19
+ Added ability to have one EDL "refer" to another..allowing multiple DVD's/dvd-id's to re-utilize the same EDL,
20
+ and even add more settings of their own, if desired.
21
+
1
22
  == 0.25.1 ==
2
23
 
3
24
  Added ability to dynamically "find" which window contained the playing movie, and capture it, from desktop,
@@ -5,6 +26,8 @@ for upscaling or capturing.
5
26
 
6
27
  added ability to "minimize" and "unminimize" a movie player window in order to "simulate" blanking.
7
28
 
29
+ possible speedup for slower systems without upconversion
30
+
8
31
  == 0.25.0 ==
9
32
 
10
33
  Created my own directshow screen capture filter to go along with netflix instant upconvert,
@@ -153,7 +176,7 @@ Also fixed up some unit tests.
153
176
 
154
177
  OS X compatibility. Though not heavily used it might work.
155
178
 
156
- Subtitle parser/scanner: now it can scan for "complete" words (e.g. hello is no longer considered a profanity)
179
+ Subtitle parser/scanner: now it can scan for "complete" and "incomplete" words (e.g. hello is no longer considered a profanity)
157
180
  even if they complete words are at the end of lines, middle, beginning, or the entire line. With unit tests.
158
181
 
159
182
  Added a "play unedited with smplayer/mplayer" buttons that work better now. These are useful for
data/cone.png ADDED
Binary file
@@ -5,6 +5,7 @@ http://rogerdpack.t28.net/sensible-cinema/releases/dvd_isos has it and a few oth
5
5
  On windows daemon tools helps there, or "magic ISO" or the like.
6
6
 
7
7
  Or you could alternatively burn a copy of big buck bunny to DVD, then use that to test it against (a slightly more cross platform approach).
8
+ Or http://rogerdpack.t28.net/sensible-cinema/releases/dvd_isos has an extra copy of the file and you can just use the "file based" options.
8
9
 
9
10
  Then rip it and use the output.
10
11
 
@@ -0,0 +1,41 @@
1
+ require 'rautomation'
2
+ require_relative 'edl_parser'
3
+
4
+ class AutoWindowFinder
5
+
6
+ # when they select a file, it contains a...url say...
7
+ # so look for that url, with "this" child window class [?]
8
+ # so basically, if a browser window is "open" to such and such a url
9
+ # and it is mentioned in a file
10
+ # it should find it
11
+
12
+ def self.search_for_single_url_match regexp = /Chrome/
13
+ EdlParser.find_single_edit_list_matching(true) {|parsed|
14
+ if url = parsed["url"]
15
+ window = RAutomation::Window.new(:title => regexp)
16
+ if window.exist?
17
+ if window.text =~ Regexp.new(Regexp.escape url.gsub(/http(s|):\/\//, ""))
18
+ p 'got match' + url
19
+ true
20
+ else
21
+ false
22
+ end
23
+ end
24
+ end
25
+ }
26
+ end
27
+
28
+ def self.search_for_player_and_url_match player_root_dir
29
+ for filename in Dir[player_root_dir + '/*/*.txt']
30
+ settings = YAML.load_file filename
31
+ if regex = settings["window_title"] # assume regex :)
32
+ p 'searching for player regex', regex
33
+ if search_for_single_url_match regex # applies the regex X url
34
+ return filename
35
+ end
36
+ end
37
+ end
38
+ nil
39
+ end
40
+
41
+ end
data/lib/blanker.rb CHANGED
@@ -48,7 +48,7 @@ else
48
48
  end
49
49
 
50
50
  @@use_mouse = false
51
- @@use_foreground_window_minimize = true
51
+ @@use_foreground_window_minimize = false
52
52
  if @@use_foreground_window_minimize
53
53
  require 'win32/screenshot'
54
54
  SW_MINIMIZE = 6
data/lib/edl_parser.rb CHANGED
@@ -15,18 +15,31 @@ This file is part of Sensible Cinema.
15
15
  You should have received a copy of the GNU General Public License
16
16
  along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
17
17
  =end
18
+ require 'sane'
18
19
  class EdlParser
19
20
 
20
- # returns {"mutes" => [["00:00", "00:00", string1, string2], ...], "blank_outs" -> [...]}
21
+ EDL_DIR = File.expand_path(__DIR__ + "/../zamples/edit_decision_lists/dvds")
22
+
23
+ if File::ALT_SEPARATOR
24
+ EDL_DIR.gsub! File::SEPARATOR, File::ALT_SEPARATOR # to_filename...
25
+ end
26
+
27
+ # returns {"mutes" => [["00:00", "00:00", string1, string2, ...], ...], "blank_outs" -> [...], "url" => ...}
21
28
  def self.parse_file filename
22
- parse_string File.read(filename), filename, [] # LODO categories stuff out...
29
+ output = parse_string File.read(filename), filename, []
30
+ if relative = output["take_from_relative_file"]
31
+ new_filename = File.dirname(filename) + '/' + relative
32
+ new_input = parse_file new_filename
33
+ output.merge! new_input
34
+ end
35
+ output
23
36
  end
24
37
 
25
38
  private
26
39
 
27
- # better eye-ball these before letting people run them, eh? XXXX
40
+ # better eye-ball these before letting people run them, eh? TODO
28
41
  # but I couldn't think of any other way to parse the files tho
29
- def self.parse_string string, filename, ok_categories_array
42
+ def self.parse_string string, filename, ok_categories_array = []
30
43
  string = '{' + string + "\n}"
31
44
  if filename
32
45
  raw = eval(string, binding, filename)
@@ -187,7 +200,45 @@ class EdlParser
187
200
  out << "%06.3f" % seconds # man that is tricky...
188
201
  end
189
202
  end
190
-
203
+
204
+ def self.all_edl_files_parsed use_all_not_just_dvds
205
+ dir = EDL_DIR
206
+ dir += "/.." if use_all_not_just_dvds
207
+ Dir[dir + '/**/*.txt'].map{|filename|
208
+ begin
209
+ parsed = parse_file(filename)
210
+ [filename, parsed]
211
+ rescue SyntaxError => e
212
+ # ignore poorly formed edit lists for the auto choose phase...
213
+ p 'warning, unable to parse a file:' + filename + " " + e.to_s
214
+ nil
215
+ end
216
+ }.compact
217
+ end
218
+
219
+ # returns single matching filename
220
+ def self.find_single_edit_list_matching use_all = false
221
+ matching = all_edl_files_parsed(use_all).map{|filename, parsed|
222
+ yield(parsed) ? filename : nil
223
+ }.compact
224
+ if matching.length == 1
225
+ file = matching[0]
226
+ p "selecting the one only matching EDL: #{file}"
227
+ file
228
+ elsif matching.length > 1
229
+ p "found multiple matches for media? #{matching.inspect}"
230
+ nil
231
+ else
232
+ nil
233
+ end
234
+ end
235
+
236
+ def self.single_edit_list_matches_dvd dvd_id
237
+ return nil unless dvd_id
238
+ find_single_edit_list_matching {|parsed|
239
+ parsed["disk_unique_id"] == dvd_id
240
+ }
241
+ end
191
242
 
192
243
 
193
244
  end
@@ -207,4 +258,4 @@ if $0 == __FILE__
207
258
  require 'rubygems'
208
259
  require 'sane'
209
260
  p EdlParser.parse_file(*ARGV)
210
- end
261
+ end
@@ -78,6 +78,7 @@ class ScreenTracker
78
78
  @hwnd = hwnd = Win32::Screenshot::BitmapMaker.desktop_window
79
79
  return
80
80
  else
81
+ raise if OS.mac?
81
82
  @hwnd = Win32::Screenshot::BitmapMaker.hwnd(@name_or_regex, @use_class_name)
82
83
  end
83
84
 
@@ -171,11 +172,11 @@ class ScreenTracker
171
172
  time_since_last_screen_change = Time.now
172
173
  loop {
173
174
  # save away the current time to try and be most accurate...
174
- time_before_scan = Time.now
175
+ time_before_current_scan = Time.now
175
176
  current = get_bmp
176
177
  if current != original
177
178
  if @digits
178
- got = attempt_to_get_time_from_screen time_before_scan
179
+ got = attempt_to_get_time_from_screen time_before_current_scan
179
180
  if @previously_displayed_warning && got
180
181
  # reassure user :)
181
182
  p 'tracking it successfully again'
@@ -183,22 +184,24 @@ class ScreenTracker
183
184
  end
184
185
  return got
185
186
  else
186
- puts 'screen time change only detected... [unexpected]' # unit tests do this still
187
+ puts 'screen time change only detected... [unexpected]' # unit tests do this still <sigh>
187
188
  return
188
189
  end
189
190
  else
190
- # no screen change detected ...
191
- sleep 0.02
192
191
  if(Time.now - time_since_last_screen_change > 2.0)
193
- # display a warning
194
- p 'warning--unable to track screen time for some reason [perhaps screen obscured or it\'s not playing yet, or paused?] ' + @hwnd.to_s
195
- p Win32::Screenshot::Util.dimensions_for(hwnd)
196
- @previously_displayed_warning = true
192
+ got_implies_able_to_still_ocr = attempt_to_get_time_from_screen time_before_current_scan
193
+ if got_implies_able_to_still_ocr
194
+ return got_implies_able_to_still_ocr
195
+ else
196
+ p 'warning--unable to track screen time for some reason [perhaps screen obscured or it\'s not playing yet?] ' + @hwnd.to_s
197
+ @previously_displayed_warning = true
198
+ # also reget window hwnd, just in case that's the problem...(can be with VLC moving from title to title)
199
+ get_hwnd_loop_forever
200
+ end
197
201
  time_since_last_screen_change = Time.now
198
- # also reget window hwnd, just in case that's the problem...(can be with VLC moving from title to title)
199
- get_hwnd_loop_forever
200
202
  end
201
203
  end
204
+ sleep 0.02
202
205
  }
203
206
  end
204
207
 
@@ -262,4 +265,4 @@ class ScreenTracker
262
265
  }
263
266
  end
264
267
 
265
- end
268
+ end
@@ -130,19 +130,19 @@ module SubtitleProfanityFinder
130
130
  bad_profanities.merge! extra_profanity_hash # LODO make easier to use...
131
131
 
132
132
  semi_bad_profanities = {}
133
- ['bloody', 'moron', 'idiot', 'sex', 'genital', 'make love', 'suck',
133
+ ['bloody', 'moron', 'breast', 'idiot',
134
+ 'sex', 'genital', 'make love',
134
135
  'making love', 'love mak',
135
- 'breast',
136
+ 'dumb', 'suck',
136
137
  'piss'].each{|name|
137
138
  # butter?
138
139
  semi_bad_profanities[name] = name
139
140
  }
140
141
  semi_bad_profanities['crap'] = ['crap', :full_word]
141
- semi_bad_profanities['crap'] = ['butt', :full_word]
142
+ semi_bad_profanities['butt'] = ['butt', :full_word]
142
143
 
143
144
  all_profanity_combinationss = [convert_to_regexps(bad_profanities), convert_to_regexps(semi_bad_profanities)]
144
145
 
145
-
146
146
  output = ''
147
147
  for all_profanity_combinations in all_profanity_combinationss
148
148
  output += "\n"
@@ -0,0 +1,8 @@
1
+ call vlc dvd://d:\@2 --start-time=10 --stop-time=15 vlc://quit
2
+ call vlc dvd://d:\@1 --start-time=10 --stop-time=15 vlc://quit
3
+ call vlc dvd://d:\@2 --start-time=15 --stop-time=20 vlc://quit
4
+ call vlc dvd://d:\@1 --start-time=10 --stop-time=15 vlc://quit
5
+ call vlc dvd://d:\@2 --start-time=35 --stop-time=40 vlc://quit @rem should have been 20
6
+ call vlc g:\downloads\big_buck_bunny_480p_h264.mov.crdownload --stop-time=4 vlc://quit
7
+
8
+
@@ -0,0 +1,24 @@
1
+ call vlc --sub-filter "logo{file='transparent.png,256'}" dvd://d:\@2 --stop-time=56 --start-time=45 vlc://quit
2
+ call vlc --sub-filter "logo{file='cone.png,256'}" dvd://d:\@2 --start-time=56 --stop-time=57 vlc://quit
3
+ call vlc --sub-filter "logo{file='transparent.png,256'}" dvd://d:\@2 --start-time=57 --stop-time=65 vlc://quit
4
+ call vlc --sub-filter "logo{file='cone.png,256'}" dvd://d:\@2 --start-time=65 --stop-time=74.5 vlc://quit
5
+ call vlc dvd://d:\@2 --start-time=74.5 vlc://quit
6
+
7
+
8
+ "00:00:56.0" , "00:00:57.0", "violence", "knife stabbing",
9
+ "00:01:05.0" , "00:01:14.5", "violence", "stab through",
10
+
11
+
12
+
13
+
14
+
15
+ @rem working: -> vlc --sub-filter "logo{file='cone.png,5000,128;transparent.png,2000,128;cone.png,10000,256'}" dvd://d:\@2 --stop-time=30
16
+ @rem vlc --sub-filter "logo{file='cone.png,500000,128;transparent.png,1000,128'}" dvd://d:\@2 --stop-time=30
17
+
18
+ @rem dvd://d:\@2 :start-time=10 :stop-time=20 dvd://d:\@2 :start-time=20 :stop-time=25 :sub-filter=logo{file=g:\video\sintel_ntsc\cone.png,transparency=128} dvd://d:\@2 :start-time=25 :stop-time=30 vlc://quit
19
+
20
+
21
+
22
+
23
+ @rem vlc dvd://d:\@2 :start-time=70 :stop-time=75 :sub-filter=logo{file=g:\video\sintel_ntsc\cone.png,transparency=128}
24
+
@@ -0,0 +1,65 @@
1
+ =begin
2
+ Copyright 2010, Roger Pack
3
+ This file is part of Sensible Cinema.
4
+
5
+ Sensible Cinema is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ Sensible Cinema is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
17
+ =end
18
+ require File.dirname(__FILE__) + "/common"
19
+ require_relative '../lib/auto_window_finder'
20
+
21
+ describe AutoWindowFinder do
22
+
23
+ EdlParser::EDL_DIR.gsub!(/^.*$/, 'files/edls')
24
+
25
+ context "a browser window is open" do
26
+ before do
27
+ fake_window = ''
28
+ def fake_window.exist?
29
+ true
30
+ end
31
+ def fake_window.text
32
+ "www.youtube.com/watch?v=xd12hR68sWM"
33
+ end
34
+ RAutomation::Window.stub!(:new).and_return(fake_window)
35
+ end
36
+
37
+ context "it is mentioned in a file" do
38
+
39
+ before do
40
+ out = "files/edls/auto_url.txt"
41
+ File.write out, %!"url" => "http://www.youtube.com/watch?v=xd12hR68sWM"!
42
+ end
43
+
44
+ it "should connect the two automagically" do
45
+ AutoWindowFinder.search_for_single_url_match().should == "files/edls/../edls/auto_url.txt"
46
+ end
47
+
48
+ it "should search automatically iff the player specifies it to" # ?
49
+
50
+ it "should be able to find with browser and url" do
51
+ FileUtils.mkdir_p 'temp/players'
52
+ File.write('temp/players/go.txt', "window_title: !ruby/regexp /Chrome/")
53
+ AutoWindowFinder.search_for_player_and_url_match('temp').should == "temp/players/go.txt"
54
+ File.write('temp/players/go.txt', "window_title: !ruby/regexp /asdf/")
55
+ RAutomation::Window.unstub!(:new)
56
+ AutoWindowFinder.search_for_player_and_url_match('temp').should be nil
57
+ end
58
+
59
+ end
60
+
61
+
62
+ end
63
+
64
+
65
+ end
@@ -27,7 +27,7 @@ describe EdlParser do
27
27
  end
28
28
 
29
29
  it "should get mutes and blank_outs" do
30
- string = File.read(__dir__ + "/../zamples/edit_decision_lists/old_not_yet_updated/example_edit_decision_list.txt")
30
+ string = File.read(__DIR__ + "/../zamples/edit_decision_lists/old_not_yet_updated/example_edit_decision_list.txt")
31
31
  expected =
32
32
  {
33
33
  "mutes"=>[["00:00:01", "00:00:02"],
@@ -68,7 +68,7 @@ describe EdlParser do
68
68
  end
69
69
 
70
70
  it "should parse a real file" do
71
- E.parse_file(File.expand_path(__dir__) + "/../zamples/edit_decision_lists/dvds/bobs_big_plan.txt").should ==
71
+ E.parse_file(File.expand_path(__DIR__) + "/../zamples/edit_decision_lists/dvds/bobs_big_plan.txt").should ==
72
72
  {"title"=>"Bob's Big Plan", "dvd_title_track"=>1, "other notes"=>"could use more nit-picking of the song, as some parts seem all right in the end", "mutes"=>[["00:03.8", "01:03", "theme song is a bit raucous at times"], ["28:13.5", "29:40", "theme song again"], ["48:46", "49:08", "theme song again"]], "blank_outs"=>[]}
73
73
  end
74
74
 
@@ -98,10 +98,6 @@ describe EdlParser do
98
98
  proc {E.parse_string '"mutes"=>["0:33", "0:34"]', 'filename'}.should_not raise_error
99
99
  end
100
100
 
101
- it "should be able to optionally ignore settings" do
102
- E.parse_string('"mutes"=>["0:33", "0:34"]', 'filename', [], true)['mutes'].should == []
103
- end
104
-
105
101
  it "should sort exactly overlapping segments" do
106
102
  proc { go({"mutes"=>{105=>145}, "blank_outs"=>{105=>145}})}.should raise_error(SyntaxError)
107
103
  proc { go({"mutes"=>{105=>145}, "blank_outs"=>{110=>130}})}.should raise_error(SyntaxError)
@@ -170,11 +166,56 @@ describe EdlParser do
170
166
 
171
167
  it "should translate ints to english timestamps well" do
172
168
  english(60).should == "01:00"
173
- english(60.1).should == "01:00.1"
169
+ english(60.1).should == "01:00.100"
174
170
  english(3600).should == "1:00:00"
175
171
  english(3599).should == "59:59"
176
172
  english(3660).should == "1:01:00"
177
- english(3660 + 0.1).should == "1:01:00.1"
178
- end
179
-
180
- end
173
+ english(3660 + 0.1).should == "1:01:00.100"
174
+ end
175
+
176
+ it "should auto-select a EDL if it matches a DVD's title" do
177
+ EdlParser.single_edit_list_matches_dvd("deadbeef|8b27d001").should_not be nil
178
+ end
179
+
180
+ it "should not auto-select if you pass it nil" do
181
+ EdlParser.single_edit_list_matches_dvd(nil).should be nil
182
+ end
183
+
184
+
185
+ EdlParser::EDL_DIR.gsub!(/^.*$/, 'files/edls')
186
+
187
+ it "should not select a file if poorly formed" do
188
+ EdlParser.stub!(:parse_file) {
189
+ eval("a----")
190
+ }
191
+ EdlParser.single_edit_list_matches_dvd('fake md5') # doesn't choke
192
+ end
193
+
194
+ it "should return false if two EDL's match a DVD title" do
195
+ begin
196
+ EdlParser.single_edit_list_matches_dvd("abcdef1234").should be nil
197
+ File.binwrite('files/edls/a.txt', "\"disk_unique_id\" => \"abcdef1234\"")
198
+ EdlParser.single_edit_list_matches_dvd("abcdef1234").should == "files/edls/a.txt"
199
+ File.binwrite('files/edls//b.txt', "\"disk_unique_id\" => \"abcdef1234\"")
200
+ EdlParser.single_edit_list_matches_dvd("abcdef1234").should be nil
201
+ ensure
202
+ FileUtils.rm_rf 'files/edls/a.txt'
203
+ FileUtils.rm_rf 'files/edls/b.txt'
204
+ end
205
+ end
206
+
207
+
208
+ it "should merge two files if one specifies another" do
209
+ begin
210
+ File.binwrite('files/edls/a.txt', %!"take_from_relative_file" => "b.txt"!)
211
+ File.binwrite('files/edls/b.txt', %!!) # empty to start out with ...nothing up my sleeve...
212
+ EdlParser.parse_file('files/edls/a.txt').should == {"take_from_relative_file" => "b.txt", "mutes" => [], "blank_outs" => []}
213
+ File.binwrite('files/edls/b.txt', %!"blank_outs" => ["00:01", "00:03", "violence"], "yo" => "33"!)
214
+ EdlParser.parse_file('files/edls/a.txt').should == {"take_from_relative_file" => "b.txt", "mutes" => [], "blank_outs" => [["00:01", "00:03", "violence"]], "yo" => "33"}
215
+ ensure
216
+ FileUtils.rm_rf 'files/edls/a.txt'
217
+ FileUtils.rm_rf 'files/edls/b.txt'
218
+ end
219
+ end
220
+
221
+ end