sensible-cinema 0.14.6 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +9 -0
- data/LICENSE +4 -1
- data/README +27 -130
- data/Rakefile +16 -8
- data/TODO +122 -52
- data/VERSION +1 -1
- data/bin/sensible-cinema +23 -21
- data/bin/sensible-cinema-cli +3 -4
- data/experimental_readme.txt +83 -0
- data/ext/mkrf_conf.rb +1 -0
- data/lib/add_any_bundled_gems_to_load_path.rb +14 -0
- data/lib/mencoder_wrapper.rb +98 -0
- data/lib/ocr.rb +2 -1
- data/lib/overlayer.rb +1 -1
- data/lib/screen_tracker.rb +2 -2
- data/lib/vlc_programmer.rb +27 -19
- data/sensible-cinema.gemspec +12 -6
- data/spec/mencoder_wrapper.spec.rb +163 -0
- data/spec/sensible_cinema_gui.spec.rb +21 -16
- data/spec/vlc_programmer.spec.rb +5 -9
- data/zamples/edit_decision_lists/dvds/{all_dogs_go_to_heaven_dvd.txt → all_dogs_go_to_heaven.txt} +0 -0
- data/zamples/edit_decision_lists/dvds/cars_disney.txt +2 -1
- data/zamples/edit_decision_lists/dvds/happiest baby on the block.txt +11 -0
- data/zamples/edit_decision_lists/dvds/{happy_feet_dvd.txt → happy_feet.txt} +0 -0
- data/zamples/edit_decision_lists/youtube/gummy_bear_song_youtube.txt +1 -1
- metadata +13 -19
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.15.0
|
data/bin/sensible-cinema
CHANGED
@@ -2,22 +2,21 @@
|
|
2
2
|
|
3
3
|
puts 'Loading Sensible Cinema...'
|
4
4
|
|
5
|
-
require
|
5
|
+
require File.dirname(__FILE__) + "/../lib/add_any_bundled_gems_to_load_path.rb"
|
6
|
+
require 'sane'
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
$: << lib_dir
|
10
|
-
}
|
8
|
+
for file in ['vlc_programmer']
|
9
|
+
require_relative '../lib/' + file
|
11
10
|
end
|
12
11
|
|
13
|
-
add_any_bundled_gems
|
14
|
-
|
15
|
-
require 'sane' # File.write
|
16
12
|
require 'ruby-wmi'
|
13
|
+
require 'tmpdir'
|
17
14
|
require_relative '../lib/swing_helpers'
|
18
15
|
require_relative '../lib/drive_info'
|
19
|
-
|
20
|
-
|
16
|
+
|
17
|
+
# add some common locations for vlc.exe to the path...
|
18
|
+
# lodo use the registry to pull out the 'right' path...
|
19
|
+
ENV['PATH'] = ENV['PATH'] + ";C:\\Program Files\\VideoLAN\\VLC"+ ";D:\\Program Files\\VideoLAN\\VLC" + ";E:\\Program Files\\VideoLAN\\VLC"
|
21
20
|
|
22
21
|
module SensibleSwing
|
23
22
|
class MainWindow < JFrame
|
@@ -35,6 +34,7 @@ module SensibleSwing
|
|
35
34
|
jlabel.set_bounds(44,44,136,14)
|
36
35
|
panel.add jlabel
|
37
36
|
b = JButton.new( "Play Hulu, Youtube, or a DVD (Tracking)" ).on_clicked {
|
37
|
+
load File.dirname(__FILE__) + '/sensible-cinema-cli'
|
38
38
|
Thread.new { go_sc([]) } # needs to be in its own thread becuase it blocks,
|
39
39
|
# so "this thread" is the uni-swing thread, gets blocked, and the overlayer can't repaint
|
40
40
|
self.close
|
@@ -119,7 +119,7 @@ module SensibleSwing
|
|
119
119
|
if should_save_file
|
120
120
|
fc = JFileChooser.new
|
121
121
|
# LODO allow for spaces in the save to file
|
122
|
-
fc.set_dialog_title "Pick where to save the file to"
|
122
|
+
fc.set_dialog_title "Pick where to save #{dvd_title || "the file"} edited to"
|
123
123
|
save_to_file_name = ((dvd_title || "my dvd") + ' edited copy').gsub(' ', '_').gsub( /\W/, '') # no punctuation for now...
|
124
124
|
fc.setSelectedFile(JFile.new(DriveInfo.get_drive_with_most_space_with_slash + save_to_file_name))
|
125
125
|
save_to = fc.go
|
@@ -128,25 +128,28 @@ module SensibleSwing
|
|
128
128
|
end
|
129
129
|
dvd_title_track = descriptors["dvd_title_track"]
|
130
130
|
bat_file_or_xspf = VLCProgrammer.convert_to_full_xspf(descriptors, save_to, drive, dvd_title_track, dvd_title)
|
131
|
+
|
132
|
+
temp_dir = Dir.tmpdir
|
133
|
+
temp_file = temp_dir + '/' + 'vlc.temp.xspf'
|
134
|
+
File.write(temp_file, bat_file_or_xspf)
|
135
|
+
puts bat_file_or_xspf
|
131
136
|
if should_save_file
|
132
|
-
|
133
|
-
|
134
|
-
|
137
|
+
popup = ModeLessDialog.new( "Copying to #{save_to}.\n" +
|
138
|
+
"Running edit list #{File.basename edit_list_path} against \n" +
|
139
|
+
" #{drive} (#{dvd_title})...\n" +
|
135
140
|
"This could take quite awhile, and will prompt you when it is done.\n" +
|
136
141
|
"It may also cause small popup ballon dialogs to appear.\n" +
|
137
142
|
"You can close this window and continue working while it runs.",
|
138
|
-
"OK")
|
143
|
+
"OK")
|
139
144
|
|
140
145
|
# this allows our popups to still be serviced while it is running
|
141
146
|
Thread.new {
|
142
147
|
run_copy_commands bat_file_or_xspf, save_to
|
148
|
+
popup.dispose
|
143
149
|
}
|
144
150
|
else
|
145
|
-
temp_dir = Dir.tmpdir
|
146
|
-
temp_file = temp_dir + '/' + 'vlc.temp.xspf'
|
147
|
-
File.write(temp_file, bat_file_or_xspf)
|
148
151
|
command = "vlc \"#{temp_file.to_filename}\" vlc://quit"
|
149
|
-
|
152
|
+
puts 'running playlist for DVD: ', command
|
150
153
|
system(command) # blocks the current window while running...
|
151
154
|
p 'done playing DVD'
|
152
155
|
end
|
@@ -169,14 +172,13 @@ module SensibleSwing
|
|
169
172
|
}
|
170
173
|
@progress_bar.visible=false
|
171
174
|
@buttons.each{|b| b.set_enabled true}
|
172
|
-
popup.dispose
|
173
175
|
if success
|
174
176
|
JOptionPane.showMessageDialog(nil, " Done--you may now watch file #{save_to}.ps in VLC player", "Done!", JOptionPane::INFORMATION_MESSAGE)
|
175
177
|
show_file = "explorer /e,/select,\"#{File.expand_path(save_to).to_filename}.ps\""
|
176
178
|
system show_file
|
177
179
|
self.close
|
178
180
|
else
|
179
|
-
JOptionPane.showMessageDialog(nil, " Failed--please examine
|
181
|
+
JOptionPane.showMessageDialog(nil, " Failed--please examine screen output and report back!", "Failed", JOptionPane::ERROR_MESSAGE)
|
180
182
|
end
|
181
183
|
end
|
182
184
|
|
data/bin/sensible-cinema-cli
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
|
-
require
|
3
|
+
require File.dirname(__FILE__) + "/../lib/add_any_bundled_gems_to_load_path.rb"
|
4
4
|
require 'sane'
|
5
5
|
|
6
|
-
Thread.abort_on_exception=true #gah
|
6
|
+
Thread.abort_on_exception=true # gah
|
7
7
|
|
8
8
|
for file in ['overlayer', 'keyboard_input', 'screen_tracker', 'mouse', 'file_chooser', 'ocr', 'vlc_programmer']
|
9
9
|
require_relative '../lib/' + file
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
12
|
def go_sc(args)
|
14
13
|
|
15
14
|
$VERBOSE = 1 if args.delete('-v')
|
@@ -96,7 +95,7 @@ def go_sc(args)
|
|
96
95
|
Blanker.shutdown # lodo move this and the 'q' key to within overlayer
|
97
96
|
OCR.serialize_cache_to_disk
|
98
97
|
}
|
99
|
-
puts "syntax from command line: #{player_description} #{edit_decision_list}"
|
98
|
+
puts "syntax from command line: \"#{player_description}\" \"#{edit_decision_list}\""
|
100
99
|
key_input.handle_keystrokes_forever # blocking...
|
101
100
|
|
102
101
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
Currently it takes as input a list of "skippable" scenes, and a player description.
|
2
|
+
It then tracks whichever player you are using, and mutes or blanks out the system appropriately,
|
3
|
+
during the scenes specified.
|
4
|
+
|
5
|
+
It works out of the box with the hulu and VLC players on windows. It isn't hard to
|
6
|
+
add new players, and probably wouldn't be too hard to add more operating systems etc.
|
7
|
+
|
8
|
+
== How to Use ==
|
9
|
+
|
10
|
+
Start playing your movie in its respective player, then startup sensible-cinema by running the file
|
11
|
+
run_sensible_cinema.bat
|
12
|
+
|
13
|
+
It prompts you for an EDL (Edit decision List) file (ex: bambi.txt),
|
14
|
+
and also for a player file (ex: hulu_full_screen.txt).
|
15
|
+
|
16
|
+
Sensible-cinema will now run in a console window, screen tracking the player to monitor its position,
|
17
|
+
and react'ing appropriately.
|
18
|
+
|
19
|
+
It is presumed that you'll then minimize sensible-cinema and proceed to enjoy the movie.
|
20
|
+
|
21
|
+
You'll know that it's working if, when you change the time of your player (ex: dragging it to a new spot
|
22
|
+
in the playback), the screen output in sensible-cinema's console should change to match the new time.
|
23
|
+
|
24
|
+
== How to install ==
|
25
|
+
|
26
|
+
You'll need to install imagemagick first: http://www.imagemagick.org/script/binary-releases.php
|
27
|
+
|
28
|
+
Next go and get the program: http://rogerdpack.t28.net
|
29
|
+
|
30
|
+
You can test that it's installed by running it (see above) and selecting the "example_edit_decision_list.txt", and
|
31
|
+
choosing the hulu player.
|
32
|
+
|
33
|
+
It will show you a few "demo" mutes and blank outs.
|
34
|
+
|
35
|
+
== FAQ ==
|
36
|
+
|
37
|
+
Q. Can I watch movies this way on my TV, not just on my computer?
|
38
|
+
|
39
|
+
A. Maybe. Or possible not yet, depending on your current hardware.
|
40
|
+
Currently you'll either need to attach your computer to your TV
|
41
|
+
(buy some long cables, or a new graphics card that matches your cables, etc.)
|
42
|
+
or get some computer that you can move closer to the TV to do the same
|
43
|
+
(ex: buy a used older laptop with s-video out, use that, or a laptop with DVI/HDMI would
|
44
|
+
work with an HDMI TV). If you're really aggressive you could run an ethernet cable from your computer, as well [1].
|
45
|
+
I'd be happy to do a linux port of sensible-cinema if anybody requests it, for use with
|
46
|
+
their dedicated TV computer.
|
47
|
+
There has also been some work toward getting ones computer to stream "live" to your existing wii/ps3/xbox.
|
48
|
+
Message me if you're interested in trying it out (testers wanted--plus I'll only work on it if there's demand)!
|
49
|
+
|
50
|
+
Q. What movies does this work with?
|
51
|
+
|
52
|
+
A. Any that you program it for :) (Assuming the computer player is compatible, which most probably are.)
|
53
|
+
|
54
|
+
Q. What movies are freely available to watch online?
|
55
|
+
|
56
|
+
A. Not many are available free (hulu, youtube have a few). Netflix has quite a few with its default subscription.
|
57
|
+
You can of course use it with any existing DVD, or rent or borrow DVD's and watch them using sensible-cinema.
|
58
|
+
|
59
|
+
Q. Why does my mouse bounce up and down while sensible-cinema is going?
|
60
|
+
|
61
|
+
A. This enables your player to keep its on-screen time tracker, which in turn allows sensible-cinema to track where
|
62
|
+
you're at. Message me if this bugs you too much and we'll see what we can do about it.
|
63
|
+
|
64
|
+
[1] http://ps3mediaserver.org/forum/viewtopic.php?f=6&t=5731#p34279
|
65
|
+
|
66
|
+
== Advanced Usage ==
|
67
|
+
|
68
|
+
You could specify the scene descriptions list and player list on the command-line, if you don't want to have
|
69
|
+
to pick them each time, like:
|
70
|
+
|
71
|
+
first install jruby, then
|
72
|
+
|
73
|
+
C:\> jruby -S gem install sensible-cinema (double check if that gives you the latest version)
|
74
|
+
|
75
|
+
C:\> jruby -S sensible-cinema edit_decision_list.yml player_description.yml
|
76
|
+
|
77
|
+
Also if you specify "test" for the scene descriptions file, it will pause 4s, take a snapshot of the player, then exit.
|
78
|
+
You can also specify -v or -t if you want to enable more verbose (chatty) output.
|
79
|
+
|
80
|
+
== Thanks ==
|
81
|
+
|
82
|
+
Thanks to Jarmo for the win32-screenshot gem, mini_magick gem authors, jruby guys, etc.
|
83
|
+
The combination made programming this actually something of a pleasure.
|
data/ext/mkrf_conf.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
def add_any_bundled_gems_to_load_path
|
3
|
+
raise 'no vendor dir?' unless File.directory? 'vendor'
|
4
|
+
if File.directory? 'vendor/cache'
|
5
|
+
Dir['vendor/cache/**/lib'].each{|lib_dir|
|
6
|
+
$: << lib_dir
|
7
|
+
}
|
8
|
+
else
|
9
|
+
require 'rubygems'
|
10
|
+
# they'll need imagemagick installed, as well, currently
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
add_any_bundled_gems_to_load_path
|
@@ -0,0 +1,98 @@
|
|
1
|
+
if $0 == __FILE__
|
2
|
+
require 'rubygems'
|
3
|
+
require 'sane'
|
4
|
+
end
|
5
|
+
|
6
|
+
require_relative 'vlc_programmer'
|
7
|
+
|
8
|
+
class MencoderWrapper
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def get_header this_drive
|
13
|
+
if File.exist?(@big_temp) && File.exist?(@big_temp + '.done')
|
14
|
+
''
|
15
|
+
else
|
16
|
+
"call mencoder dvd:// -oac copy -lavcopts keyint=1 -ovc lavc -o #{@big_temp} -dvd-device #{this_drive} && echo got_file > #{@big_temp}.done\n"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_bat_commands these_mutes, this_drive, to_here_final_file, start_here = nil, end_here = nil
|
21
|
+
combined = VLCProgrammer.convert_incoming_to_split_sectors these_mutes
|
22
|
+
|
23
|
+
if start_here || end_here
|
24
|
+
raise 'need both' unless end_here && start_here
|
25
|
+
start_here = OverLayer.translate_string_to_seconds(start_here)
|
26
|
+
end_here = OverLayer.translate_string_to_seconds(end_here)
|
27
|
+
combined.select!{|start, endy, type| start > start_here && endy < end_here }
|
28
|
+
# it's relative now, since we rip from not the beginning
|
29
|
+
raise Exception.new('unable to find any edit decisions to do within that range') unless combined.length > 0
|
30
|
+
previous_end = start_here
|
31
|
+
else
|
32
|
+
previous_end = 0
|
33
|
+
end
|
34
|
+
@big_temp = to_here_final_file + ".fulli.tmp.avi"
|
35
|
+
out = get_header this_drive
|
36
|
+
@idx = 0
|
37
|
+
combined.each {|start, endy, type|
|
38
|
+
if start > previous_end
|
39
|
+
out += get_section previous_end, start, false, to_here_final_file
|
40
|
+
end
|
41
|
+
# type is either mute or :blank or :mute
|
42
|
+
if type == :blank
|
43
|
+
# do nothing... clip will be skipped
|
44
|
+
else
|
45
|
+
out += get_section start, endy, true, to_here_final_file
|
46
|
+
end
|
47
|
+
previous_end = endy
|
48
|
+
}
|
49
|
+
out += get_section previous_end, end_here || 1_000_000, false, to_here_final_file
|
50
|
+
partials = (1..@idx).map{|n| "#{to_here_final_file}.#{n}.avi"}
|
51
|
+
|
52
|
+
out += "del #{to_here_final_file}\n"
|
53
|
+
# ridiculous
|
54
|
+
out += "call mencoder #{partials.join(' ')} -o #{to_here_final_file}.smplayer_or_vlc.avi -ovc copy -oac copy\n"
|
55
|
+
# LODO only do this if they want to watch it on their computer, with something other than smplayer, or want to make it smaller, as it takes *forever* longer
|
56
|
+
# LODO the "insta play" mode, or the "faster rip" mode (related...)
|
57
|
+
# out += "call mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf -vf scale=720:480,harddup -srate 48000 -af lavcresample=48000 -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:acodec=ac3:abitrate=192:aspect=16/9 -ofps 30000/1001 #{partials.join(' ')} -o #{to_here_final_file}\n"
|
58
|
+
|
59
|
+
out += "@rem del #{@big_temp}\n" # LODO
|
60
|
+
out += "@rem del " + partials.join(' ') + "\n"# LODO
|
61
|
+
out += "echo wrote to #{to_here_final_file}.smplayer_or_vlc.avi"
|
62
|
+
out
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_section start, endy, should_mute, to_here_final_file
|
66
|
+
raise if start == endy # should never actually happen...
|
67
|
+
# delete 0.001 as per wiki's suggestion.
|
68
|
+
endy = endy - start - 0.001
|
69
|
+
# very decreased volume is like muting :)
|
70
|
+
# LODO can we copy more here? ntsc-dvd supposedly remuxes...
|
71
|
+
codecs = should_mute ? "-vcodec copy -acodec ac3 -vol 0 " : "-vcodec copy -acodec copy " # LODO not have the ac3...hmm...
|
72
|
+
# ffmpeg -i from_here.avi -vcodec copy -acodec copy -ss 1:00 -t 1:00 out.avi
|
73
|
+
partial_filename = to_here_final_file + '.' + (@idx += 1).to_s + '.avi'
|
74
|
+
"del #{partial_filename}\ncall ffmpeg -i #{@big_temp} #{codecs} -ss #{start} -t #{endy} #{partial_filename}\n"
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
if $0 == __FILE__
|
82
|
+
require 'rubygems'
|
83
|
+
require 'sane'
|
84
|
+
puts 'syntax: yaml_file_name d:\ output (00:15 00:25) (--run)'
|
85
|
+
a = YAML.load_file ARGV.shift
|
86
|
+
drive = ARGV.shift
|
87
|
+
raise 'wrong drive' unless File.exist?(drive + "AUDIO_TS")
|
88
|
+
execute = ARGV.delete('--run')
|
89
|
+
commands =MencoderWrapper.get_bat_commands(a, drive, *ARGV)
|
90
|
+
if ARGV.length > 2
|
91
|
+
write_to = 'range.bat'
|
92
|
+
else
|
93
|
+
write_to = 'all.bat'
|
94
|
+
end
|
95
|
+
File.write(write_to, commands)
|
96
|
+
print 'wrote ' + write_to
|
97
|
+
system(write_to) if execute
|
98
|
+
end
|
data/lib/ocr.rb
CHANGED
@@ -6,7 +6,8 @@ ENV['PATH'] = im_path.to_filename + ';' + ENV['PATH']
|
|
6
6
|
|
7
7
|
if RubyWhich.new.which('identify').length == 0 || RubyWhich.new.which('convert').length == 0
|
8
8
|
# for gem users, so I don't have to bundle it :P
|
9
|
-
|
9
|
+
puts 'appears you do not have imagemagick installed (or not in your path) -- please install it first! http://www.imagemagick.org/script/binary-releases.php'
|
10
|
+
sleep 100
|
10
11
|
end
|
11
12
|
|
12
13
|
# helper for OCR'ing single digits that were screen captured
|
data/lib/overlayer.rb
CHANGED
data/lib/screen_tracker.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'win32/screenshot'
|
2
2
|
require 'sane'
|
3
3
|
require 'yaml'
|
4
|
-
|
4
|
+
require File.dirname(__FILE__)+ '/ocr'
|
5
5
|
|
6
6
|
class ScreenTracker
|
7
7
|
|
@@ -34,7 +34,7 @@ class ScreenTracker
|
|
34
34
|
@height = height
|
35
35
|
@x = x; @y = y; @x2 = x+width; @y2 = y+height; @callback = callback
|
36
36
|
@max_x = max_x
|
37
|
-
raise
|
37
|
+
raise "poor width or wrong window #{@x2} #{max_x} #{x}" if @x2 > max_x || @x2 == x
|
38
38
|
if @y2 > max_y || @y2 == y
|
39
39
|
raise 'poor height or wrong window'
|
40
40
|
end
|
data/lib/vlc_programmer.rb
CHANGED
@@ -1,21 +1,13 @@
|
|
1
1
|
require_relative 'overlayer'
|
2
2
|
|
3
|
-
# add some common locations for vlc.exe to the path...
|
4
|
-
ENV['PATH'] = ENV['PATH'] + ";C:\\Program Files\\VideoLAN\\VLC"+ ";D:\\Program Files\\VideoLAN\\VLC" + ";E:\\Program Files\\VideoLAN\\VLC"
|
5
|
-
|
6
3
|
class VLCProgrammer
|
7
4
|
|
8
5
|
def self.to_english s
|
9
6
|
@overlayer ||= OverLayer.allocate
|
10
7
|
@overlayer.translate_time_to_human_readable s
|
11
8
|
end
|
12
|
-
|
13
|
-
def self.convert_to_full_xspf incoming, filename = nil, drive_with_slash = nil, dvd_title_track = nil, dvd_title_name = nil
|
14
9
|
|
15
|
-
|
16
|
-
@filename_or_playlist_if_nil = filename
|
17
|
-
@dvd_title_track = dvd_title_track || "1"
|
18
|
-
@dvd_title_name = dvd_title_name
|
10
|
+
def self.convert_incoming_to_split_sectors incoming
|
19
11
|
mutes = incoming["mutes"] || {}
|
20
12
|
blanks = incoming["blank_outs"] || {}
|
21
13
|
mutes = mutes.map{|k, v| [OverLayer.translate_string_to_seconds(k), OverLayer.translate_string_to_seconds(v), :mute]}
|
@@ -59,23 +51,39 @@ class VLCProgrammer
|
|
59
51
|
raise 'unexpected'
|
60
52
|
end
|
61
53
|
}
|
54
|
+
|
55
|
+
combined.select{|start, endy, type|
|
56
|
+
(start != nil) && (endy > start) # ignore mutes wholly contained within blanks...
|
57
|
+
}
|
58
|
+
end
|
62
59
|
|
60
|
+
def self.convert_to_full_xspf incoming, filename = nil, drive_with_slash = nil, dvd_title_track = nil, dvd_title_name = nil
|
61
|
+
|
62
|
+
@drive = drive_with_slash || "e:\\"
|
63
|
+
@filename_or_playlist_if_nil = filename
|
64
|
+
@dvd_title_track = dvd_title_track || "1"
|
65
|
+
@dvd_title_name = dvd_title_name
|
66
|
+
combined = convert_incoming_to_split_sectors incoming
|
67
|
+
|
63
68
|
out = get_header
|
64
69
|
|
65
70
|
previous_end = 0
|
66
71
|
idx = 0
|
67
72
|
|
68
73
|
combined.each{|start, endy, type|
|
69
|
-
|
70
|
-
next if endy <= start
|
71
|
-
|
74
|
+
# next unless start
|
75
|
+
#next if endy <= start
|
76
|
+
real_start = start # NB that this fails with VLC or mplayer, because of i-frame difficulties (google mencoder start time)
|
72
77
|
if previous_end != start
|
73
|
-
# play up to next "questionable section"
|
74
|
-
out += get_section("#{@dvd_title_name} : #{to_english previous_end} to #{to_english start} (clean)", previous_end,
|
78
|
+
# play 'uncut' up to next "questionable section"
|
79
|
+
out += get_section("#{@dvd_title_name} : #{to_english previous_end} to #{to_english start} (clean)", previous_end, real_start, idx += 1)
|
80
|
+
else
|
81
|
+
# immediately let it do the next action
|
75
82
|
end
|
83
|
+
|
76
84
|
# now play through the muted section...
|
77
85
|
if type == :mute
|
78
|
-
out += get_section "#{@dvd_title_name} : #{to_english start}s to #{to_english endy}s muted",
|
86
|
+
out += get_section "#{@dvd_title_name} : #{to_english start}s to #{to_english endy}s muted", real_start, endy, idx += 1, true
|
79
87
|
end
|
80
88
|
previous_end = endy
|
81
89
|
}
|
@@ -100,7 +108,7 @@ class VLCProgrammer
|
|
100
108
|
end
|
101
109
|
|
102
110
|
def self.get_section title, start, stop, idx, no_audio = false
|
103
|
-
loc = "
|
111
|
+
loc = "dvdsimple://#{@drive}@#{@dvd_title_track}"
|
104
112
|
if @filename_or_playlist_if_nil == nil
|
105
113
|
"<track>
|
106
114
|
<title>#{title}</title>
|
@@ -125,9 +133,9 @@ class VLCProgrammer
|
|
125
133
|
filename = @filename_or_playlist_if_nil
|
126
134
|
files = (1..idx).map{|n| "#{filename}.ps.#{n}"}
|
127
135
|
# concat
|
128
|
-
line = '
|
129
|
-
line += "
|
130
|
-
line += "
|
136
|
+
line = 'copy /b ' + files.join('+')
|
137
|
+
line += " #{@filename_or_playlist_if_nil}.ps\n"
|
138
|
+
line += "@rem del " + files.join(' ') + "\n" # LODO!
|
131
139
|
line += "echo Done--you may now watch file #{filename}.ps in VLC player"
|
132
140
|
end
|
133
141
|
|