sensible-cinema 0.18.1 → 0.18.2
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/TODO +3 -8
- data/VERSION +1 -1
- data/bin/sensible-cinema +45 -12
- data/lib/mencoder_wrapper.rb +6 -1
- data/lib/mplayer_edl.rb +8 -10
- data/lib/vlc_programmer.rb +3 -1
- data/sensible-cinema.gemspec +1 -1
- data/spec/mplayer_edl.spec.rb +9 -0
- data/spec/sensible_cinema_gui.spec.rb +29 -18
- data/zamples/edit_decision_lists/dvds/bob the builder pets in a pickle.txt +4 -3
- metadata +2 -2
data/TODO
CHANGED
|
@@ -2,11 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
== up next release ==
|
|
4
4
|
|
|
5
|
-
realtime
|
|
6
|
-
mplayer EDL...
|
|
7
|
-
test...
|
|
8
|
-
out of order ok?
|
|
9
|
-
|
|
10
5
|
simplify/de-bugify
|
|
11
6
|
|
|
12
7
|
that button shows up? (issue 10)
|
|
@@ -15,7 +10,8 @@
|
|
|
15
10
|
re-run latest preview -> auto play in smplayer
|
|
16
11
|
move that one button *out* ...
|
|
17
12
|
only pick a drive once per session
|
|
18
|
-
|
|
13
|
+
only pick output filename once per session...
|
|
14
|
+
kill mencoder instances.
|
|
19
15
|
|
|
20
16
|
calculating disk's unique id...
|
|
21
17
|
F:\, Roger's Wedding, a2e3ece630251e4a785218ce71a20ce1
|
|
@@ -30,7 +26,6 @@ D:\dev\sensible-cinema-never-commit-from-here\zamples\edit_decision_lists\dvds/p
|
|
|
30
26
|
assert that at least one drive has a DVD in it...maybe loop refuse with message until this?
|
|
31
27
|
disallow choosing empty drive? fail cleaner? (issue 11)
|
|
32
28
|
|
|
33
|
-
|
|
34
29
|
== slightly lower than that, somewhat ordered ==
|
|
35
30
|
|
|
36
31
|
compare computer DVD timings with physical player...
|
|
@@ -53,6 +48,7 @@ D:\dev\sensible-cinema-never-commit-from-here\zamples\edit_decision_lists\dvds/p
|
|
|
53
48
|
|
|
54
49
|
== DVD backlog (unordered, some very low prio, basically never do) ==
|
|
55
50
|
|
|
51
|
+
fix some specz
|
|
56
52
|
can pull from imdb at package time [?]
|
|
57
53
|
delete fulli file
|
|
58
54
|
except if it's a specific scene run...
|
|
@@ -112,7 +108,6 @@ D:\dev\sensible-cinema-never-commit-from-here\zamples\edit_decision_lists\dvds/p
|
|
|
112
108
|
re-do DVD EDL's that need it :P
|
|
113
109
|
all dogs go to heaven...finish EDL
|
|
114
110
|
warn when labels exist and don't match...
|
|
115
|
-
kill old mencoder instances more often...
|
|
116
111
|
auto-download imagemagick, too
|
|
117
112
|
check all the many options to see if there's a "cross platform way to split files accurately" besides my hacky kludge.
|
|
118
113
|
can rip from a DVD-like local folder (would anybody ever need this?)
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.18.
|
|
1
|
+
0.18.2
|
data/bin/sensible-cinema
CHANGED
|
@@ -25,14 +25,19 @@ require 'sane' # failure here means you haven't bundled your dependencies...[rak
|
|
|
25
25
|
require_relative '../lib/mencoder_wrapper'
|
|
26
26
|
require_relative '../lib/storage'
|
|
27
27
|
require_relative '../lib/edl_parser'
|
|
28
|
+
require_relative '../lib/mplayer_edl'
|
|
28
29
|
|
|
29
30
|
require 'tmpdir'
|
|
30
31
|
require_relative '../lib/swing_helpers'
|
|
31
32
|
require_relative '../lib/drive_info'
|
|
32
33
|
require 'whichr'
|
|
33
34
|
|
|
35
|
+
# must put mencoder first, as it has a working mplayer.exe in it...
|
|
34
36
|
ENV['PATH'] = ENV['PATH'] + ';' + File.expand_path(File.dirname(__FILE__)) + '/../vendor/cache/mencoder'.to_filename
|
|
35
|
-
|
|
37
|
+
|
|
38
|
+
for drive in ['c', 'd', 'e']
|
|
39
|
+
ENV['PATH'] = ENV['PATH'] + ";#{drive}:\\Program Files\\SMPlayer;#{drive}"
|
|
40
|
+
end
|
|
36
41
|
|
|
37
42
|
module SensibleSwing
|
|
38
43
|
class MainWindow < JFrame
|
|
@@ -99,11 +104,31 @@ module SensibleSwing
|
|
|
99
104
|
@create.on_clicked {
|
|
100
105
|
do_copy_dvd_to_hard_drive false
|
|
101
106
|
}
|
|
107
|
+
|
|
108
|
+
@edl = new_jbutton( "Watch from DVD edited", false )
|
|
109
|
+
@edl.on_clicked {
|
|
110
|
+
drive, dvd_volume_name, md5sum, edl_path, descriptors = choose_dvd_and_edl_for_it
|
|
111
|
+
temp_dir = Dir.tmpdir
|
|
112
|
+
temp_file = temp_dir + '/mplayer.temp.edl'
|
|
113
|
+
edl_contents = MplayerEdl.convert_to_edl descriptors
|
|
114
|
+
File.write(temp_file, edl_contents)
|
|
115
|
+
title = descriptors["dvd_title_track"] || "1"
|
|
116
|
+
# oh the insanity...
|
|
117
|
+
popup = NonBlockingDialog.new("Running mplayer. To control it, use space for pause.\n
|
|
118
|
+
Also right and left arrows to seek, F key for full screen,
|
|
119
|
+
q to quit.")
|
|
120
|
+
# LODO dry up mplayer opts...
|
|
121
|
+
# LODO more user friendly re-player...
|
|
122
|
+
command = "mplayer dvdnav://#{title} -nocache -alang en -sid 1000 -edl #{File.expand_path temp_file} -dvd-device #{drive}"
|
|
123
|
+
p command
|
|
124
|
+
system_non_blocking command
|
|
125
|
+
}
|
|
102
126
|
|
|
103
|
-
@watch_unedited = new_jbutton("Watch the current DVD unedited (from hard drive)", true)
|
|
127
|
+
@watch_unedited = new_jbutton("Watch the current DVD unedited (from hard drive)", true)
|
|
104
128
|
@watch_unedited.on_clicked {
|
|
105
129
|
path = RubyWhich.new.which('smplayer')
|
|
106
|
-
|
|
130
|
+
path2 = RubyWhich.new.which('mplayer')
|
|
131
|
+
if(path.length == 0 || path2.length == 0)
|
|
107
132
|
# this one has its own license...
|
|
108
133
|
show_blocking_message_dialog("It appears that you need to install a dependency: SMPlayer.\n
|
|
109
134
|
Click ok to be directed to its download website, where you can download and install it.", "Lacking dependency", JOptionPane::ERROR_MESSAGE)
|
|
@@ -118,12 +143,15 @@ module SensibleSwing
|
|
|
118
143
|
if success_no_run
|
|
119
144
|
on_success.call
|
|
120
145
|
else
|
|
121
|
-
|
|
146
|
+
Thread.new {
|
|
147
|
+
sleep 5; on_success.call # start it anyway :)
|
|
148
|
+
}
|
|
149
|
+
#@after_success_once = on_success # shenanigans to be able to let that thread run...
|
|
122
150
|
end
|
|
123
151
|
end
|
|
124
152
|
}
|
|
125
153
|
|
|
126
|
-
@open_list = new_jbutton("Open/Edit a pre-existing DVD Edit List",
|
|
154
|
+
@open_list = new_jbutton("Open/Edit a pre-existing DVD Edit List", true)
|
|
127
155
|
@open_list.on_clicked {
|
|
128
156
|
dialog = FileDialog.new(self, "Pick file to edit")
|
|
129
157
|
dialog.set_directory EDL_DIR
|
|
@@ -262,7 +290,7 @@ EOL
|
|
|
262
290
|
download("http://downloads.sourceforge.net/project/sevenzip/7-Zip/9.20/7za920.zip", "7za920.zip")
|
|
263
291
|
system_blocking("unzip -o 7za920.zip") # -o means "overwrite" without prompting
|
|
264
292
|
# now we have 7za.exe
|
|
265
|
-
Kernel.print 'downloading mencoder'
|
|
293
|
+
Kernel.print 'downloading mencoder.7z...'
|
|
266
294
|
download("http://downloads.sourceforge.net/project/mplayer-win32/MPlayer%20and%20MEncoder/revision%2032492/MPlayer-rtm-svn-32492.7z", "mencoder.7z")
|
|
267
295
|
system_blocking("7za e mencoder.7z -y -omencoder")
|
|
268
296
|
Kernel.puts 'done'
|
|
@@ -306,8 +334,8 @@ EOL
|
|
|
306
334
|
def get_user_input(message, default = '')
|
|
307
335
|
start_time = JOptionPane.showInputDialog(message, default)
|
|
308
336
|
end
|
|
309
|
-
|
|
310
|
-
def
|
|
337
|
+
|
|
338
|
+
def choose_dvd_and_edl_for_it
|
|
311
339
|
drive, dvd_volume_name, md5sum = choose_dvd_drive
|
|
312
340
|
puts "#{drive}, #{dvd_volume_name}, #{md5sum}"
|
|
313
341
|
edit_list_path = single_edit_list_matches_dvd(md5sum)
|
|
@@ -317,9 +345,14 @@ EOL
|
|
|
317
345
|
fc.set_directory EDL_DIR
|
|
318
346
|
edit_list_path = fc.go
|
|
319
347
|
end
|
|
320
|
-
|
|
348
|
+
raise 'cancelled' unless edit_list_path
|
|
321
349
|
descriptors = EdlParser.parse_file edit_list_path
|
|
350
|
+
return drive, dvd_volume_name, md5sum, edit_list_path, descriptors
|
|
351
|
+
end
|
|
322
352
|
|
|
353
|
+
def do_copy_dvd_to_hard_drive should_prompt_for_start_and_end_times, want_full_list = false
|
|
354
|
+
drive, dvd_volume_name, md5sum, edit_list_path, descriptors = choose_dvd_and_edl_for_it
|
|
355
|
+
|
|
323
356
|
dvd_title = descriptors['title'] || dvd_volume_name
|
|
324
357
|
|
|
325
358
|
fc = new_filechooser
|
|
@@ -347,9 +380,9 @@ EOL
|
|
|
347
380
|
a = File.open(File.dirname(save_to) + "/test_file_to_see_if_we_have_permission_to_write_to_this_folder", "w")
|
|
348
381
|
a.close
|
|
349
382
|
File.delete a.path
|
|
350
|
-
dvd_title_track = descriptors["dvd_title_track"]
|
|
383
|
+
dvd_title_track = descriptors["dvd_title_track"] || "1"
|
|
351
384
|
# how does save_to map to fulli?
|
|
352
|
-
fulli = save_to
|
|
385
|
+
fulli = MencoderWrapper.calculate_final_filename save_to
|
|
353
386
|
if want_full_list
|
|
354
387
|
# make it create a dummy response file for us :)
|
|
355
388
|
start_time = "00:00"
|
|
@@ -416,7 +449,7 @@ EOL
|
|
|
416
449
|
@progress_bar.visible=false
|
|
417
450
|
@buttons.each{|b| b.set_enabled true}
|
|
418
451
|
if success
|
|
419
|
-
saved_to = save_to + '.avi'
|
|
452
|
+
saved_to = save_to + '.avi'
|
|
420
453
|
if @after_success_once
|
|
421
454
|
@after_success_once.call saved_to
|
|
422
455
|
else
|
data/lib/mencoder_wrapper.rb
CHANGED
|
@@ -34,10 +34,15 @@ class MencoderWrapper
|
|
|
34
34
|
out + "call mencoder dvdnav://#{@dvd_title_track} -of mpeg -mpegopts format=dvd:tsaf -alang en -nocache -sid 1000 -oac #{audio_codec} #{video_opts} -ovc lavc -o #{@big_temp} -dvd-device #{this_drive} && echo got_file > #{@big_temp}.done\n"
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
def calculate_final_filename to_here_final_file
|
|
38
|
+
@big_temp = to_here_final_file + ".fulli_unedited.tmp.mpg"
|
|
39
|
+
end
|
|
40
|
+
|
|
37
41
|
# called from the UI...
|
|
38
42
|
def get_bat_commands these_settings, this_drive, to_here_final_file, start_here = nil, end_here = nil, dvd_title_track = "1", delete_partials = false
|
|
39
43
|
combined = VLCProgrammer.convert_incoming_to_split_sectors these_settings
|
|
40
44
|
@dvd_title_track = dvd_title_track
|
|
45
|
+
assert dvd_title_track
|
|
41
46
|
if start_here || end_here
|
|
42
47
|
raise 'need both' unless end_here && start_here
|
|
43
48
|
start_here = OverLayer.translate_string_to_seconds(start_here)
|
|
@@ -48,7 +53,7 @@ class MencoderWrapper
|
|
|
48
53
|
else
|
|
49
54
|
previous_end = 0
|
|
50
55
|
end
|
|
51
|
-
|
|
56
|
+
calculate_final_filename to_here_final_file
|
|
52
57
|
out = get_header this_drive, these_settings
|
|
53
58
|
@idx = 0
|
|
54
59
|
combined.each {|start, endy, type|
|
data/lib/mplayer_edl.rb
CHANGED
|
@@ -15,20 +15,18 @@ 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
|
+
|
|
18
19
|
require_relative 'overlayer'
|
|
20
|
+
require_relative 'vlc_programmer'
|
|
19
21
|
|
|
20
22
|
class MplayerEdl
|
|
21
23
|
def self.convert_to_edl specs
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
24
|
+
combined = VLCProgrammer.convert_incoming_to_split_sectors specs
|
|
25
|
+
out = ''
|
|
26
|
+
map = {:mute => 1, :blank => 0}
|
|
27
|
+
for start, endy, type in combined
|
|
28
|
+
out += "#{start} #{endy} #{map[type]}\n"
|
|
27
29
|
end
|
|
28
|
-
|
|
29
|
-
out.sort.each{|start, endy, metric|
|
|
30
|
-
real_out += "#{start} #{endy} #{metric}\n"
|
|
31
|
-
}
|
|
32
|
-
real_out
|
|
30
|
+
out
|
|
33
31
|
end
|
|
34
32
|
end
|
data/lib/vlc_programmer.rb
CHANGED
|
@@ -24,6 +24,8 @@ class VLCProgrammer
|
|
|
24
24
|
@overlayer.translate_time_to_human_readable s
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
# divides up mutes and blanks so that they don't overlap, preferring blanks over mutes
|
|
28
|
+
# returns it like [[start,end,type], [s,e,t]...] type like :blank and :mute
|
|
27
29
|
def self.convert_incoming_to_split_sectors incoming
|
|
28
30
|
mutes = incoming["mutes"] || {}
|
|
29
31
|
blanks = incoming["blank_outs"] || {}
|
|
@@ -36,7 +38,7 @@ class VLCProgrammer
|
|
|
36
38
|
puts 'warning--detected an end before a start' if e < s
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
#
|
|
41
|
+
# VLCProgrammer.convert_to_full_xspf({ "mutes" => {5=> 7}, "blank_outs" => {6=>7} } )
|
|
40
42
|
# should mute 5-6, skip 6-7
|
|
41
43
|
combined.each_with_index{|(start, endy, type), index|
|
|
42
44
|
next if index == 0 # nothing to do there..
|
data/sensible-cinema.gemspec
CHANGED
data/spec/mplayer_edl.spec.rb
CHANGED
|
@@ -53,11 +53,15 @@ module SensibleSwing
|
|
|
53
53
|
it "should modify path to have mencder available, and ffmpeg, and download them on the fly" do
|
|
54
54
|
ENV['PATH'].should include("mencoder")
|
|
55
55
|
end
|
|
56
|
-
|
|
56
|
+
|
|
57
|
+
it "should not modify path to have mplayer available" do
|
|
58
|
+
ENV['PATH'].should_not include("mplayer")
|
|
59
|
+
end
|
|
60
|
+
|
|
57
61
|
before do
|
|
58
62
|
@subject = MainWindow.new
|
|
59
63
|
@subject.stub!(:choose_dvd_drive) {
|
|
60
|
-
["
|
|
64
|
+
["mock_dvd_drive", "Volume", "19d121ae8dc40cdd70b57ab7e8c74f76"] # happiest baby on the block
|
|
61
65
|
}
|
|
62
66
|
@subject.stub!(:get_mencoder_commands) { |*args|
|
|
63
67
|
args[-5].should match(/abc/)
|
|
@@ -90,10 +94,12 @@ module SensibleSwing
|
|
|
90
94
|
end
|
|
91
95
|
|
|
92
96
|
it "should be able to do a normal copy to hard drive, edited" do
|
|
93
|
-
@subject.do_copy_dvd_to_hard_drive(false).should == [false, "abc.
|
|
97
|
+
@subject.do_copy_dvd_to_hard_drive(false).should == [false, "abc.fulli_unedited.tmp.mpg"]
|
|
94
98
|
File.exist?('test_file_to_see_if_we_have_permission_to_write_to_this_folder').should be false
|
|
95
99
|
end
|
|
96
100
|
|
|
101
|
+
it "should have a good default title of 1"
|
|
102
|
+
|
|
97
103
|
it "should call through to explorer for the full thing" do
|
|
98
104
|
@subject.do_copy_dvd_to_hard_drive(false)
|
|
99
105
|
@subject.background_thread.join
|
|
@@ -103,13 +109,13 @@ module SensibleSwing
|
|
|
103
109
|
end
|
|
104
110
|
|
|
105
111
|
it "should be able to return the full list if it already exists" do
|
|
106
|
-
FileUtils.touch "abc.
|
|
107
|
-
@subject.do_copy_dvd_to_hard_drive(false,true).should == [true, "abc.
|
|
108
|
-
FileUtils.rm "abc.
|
|
112
|
+
FileUtils.touch "abc.fulli_unedited.tmp.mpg.done"
|
|
113
|
+
@subject.do_copy_dvd_to_hard_drive(false,true).should == [true, "abc.fulli_unedited.tmp.mpg"]
|
|
114
|
+
FileUtils.rm "abc.fulli_unedited.tmp.mpg.done"
|
|
109
115
|
end
|
|
110
116
|
|
|
111
117
|
it "should call explorer for the we can't reach this path of opening a partial without telling it what to do with it" do
|
|
112
|
-
@subject.do_copy_dvd_to_hard_drive(true).should == [false, "abc.
|
|
118
|
+
@subject.do_copy_dvd_to_hard_drive(true).should == [false, "abc.fulli_unedited.tmp.mpg"]
|
|
113
119
|
@subject.background_thread.join
|
|
114
120
|
@args[-2].should == 1
|
|
115
121
|
@args[-3].should == "01:00"
|
|
@@ -139,20 +145,17 @@ module SensibleSwing
|
|
|
139
145
|
|
|
140
146
|
|
|
141
147
|
it "if the .done file exists, it should directly call smplayer" do
|
|
142
|
-
FileUtils.touch "abc.
|
|
148
|
+
FileUtils.touch "abc.fulli_unedited.tmp.mpg.done"
|
|
143
149
|
@subject.instance_variable_get(:@watch_unedited).simulate_click
|
|
144
|
-
@command.should == "smplayer abc.
|
|
145
|
-
FileUtils.rm "abc.
|
|
150
|
+
@command.should == "smplayer abc.fulli_unedited.tmp.mpg"
|
|
151
|
+
FileUtils.rm "abc.fulli_unedited.tmp.mpg.done"
|
|
146
152
|
end
|
|
147
153
|
|
|
148
|
-
it "if the .done file does not exist, it should call
|
|
149
|
-
@subject.
|
|
150
|
-
@subject.
|
|
151
|
-
@command.should == nil # scary timing spec
|
|
152
|
-
@subject.background_thread.join
|
|
153
|
-
# should have cleaned up...
|
|
154
|
+
it "if the .done file does not exist, it should call smplayer ja" do
|
|
155
|
+
@subject.stub!(:sleep) {} # speed this up...
|
|
156
|
+
@subject.instance_variable_get(:@watch_unedited).simulate_click.join
|
|
154
157
|
@subject.after_success_once.should == nil
|
|
155
|
-
@command.should_not == nil
|
|
158
|
+
@command.should_not == nil # scary timing spec
|
|
156
159
|
end
|
|
157
160
|
|
|
158
161
|
it "should create a new file for ya" do
|
|
@@ -172,9 +175,17 @@ module SensibleSwing
|
|
|
172
175
|
end
|
|
173
176
|
end
|
|
174
177
|
|
|
175
|
-
it "should display unique" do
|
|
178
|
+
it "should display unique disc in an input box" do
|
|
176
179
|
@subject.instance_variable_get(:@display_unique).simulate_click.should == "01:00"
|
|
177
180
|
end
|
|
178
181
|
|
|
182
|
+
it "should create an edl" do
|
|
183
|
+
@subject.instance_variable_get(:@edl).simulate_click
|
|
184
|
+
|
|
185
|
+
@command.should match(/mplayer.*-edl/)
|
|
186
|
+
@command.should match(/-dvd-device /)
|
|
187
|
+
p @command
|
|
188
|
+
end
|
|
189
|
+
|
|
179
190
|
end
|
|
180
191
|
end
|