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.
- data/Rakefile +8 -8
- data/TODO +47 -57
- data/VERSION +1 -1
- data/bin/sensible-cinema +28 -48
- data/bin/sensible-cinema-cli +93 -71
- data/bin/sensible-cinema-dependencies.rb +15 -0
- data/change_log_with_feature_list.txt +24 -1
- data/cone.png +0 -0
- data/developer_how_to_contribute_to_the_project.txt +1 -0
- data/lib/auto_window_finder.rb +41 -0
- data/lib/blanker.rb +1 -1
- data/lib/edl_parser.rb +57 -6
- data/lib/screen_tracker.rb +15 -12
- data/lib/subtitle_profanity_finder.rb +4 -4
- data/play_with_inserted_scene.bat +8 -0
- data/play_with_overlay.bat +24 -0
- data/spec/auto_window_finder.spec.rb +65 -0
- data/spec/edl_parser.spec.rb +52 -11
- data/{zamples/edit_decision_lists/dvds → spec/files/edls}/edls_being_edited/edl_for_unit_tests.txt +0 -0
- data/spec/screen_tracker.spec.rb +13 -2
- data/spec/sensible_cinema_gui.spec.rb +12 -41
- data/todo.inventionzy.txt +13 -14
- data/todo.upconvert +5 -12
- data/transparent.png +0 -0
- data/upconvert_netflix/latest2/combine_video.avs +23 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/court_jester.txt +2 -0
- data/zamples/edit_decision_lists/youtube/nuki_song_youtube.txt +1 -0
- data/zamples/edit_decision_lists/youtube/nuki_song_youtube_pointer.txt +2 -0
- data/zamples/players/youtube/normal_in_youtube.com.chrome.txt +2 -1
- metadata +20 -10
@@ -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
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
|
-
|
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, []
|
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?
|
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
|
data/lib/screen_tracker.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
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', '
|
133
|
+
['bloody', 'moron', 'breast', 'idiot',
|
134
|
+
'sex', 'genital', 'make love',
|
134
135
|
'making love', 'love mak',
|
135
|
-
'
|
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['
|
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
|
data/spec/edl_parser.spec.rb
CHANGED
@@ -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(
|
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(
|
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.
|
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.
|
178
|
-
end
|
179
|
-
|
180
|
-
|
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
|