sensible-cinema 0.26.0 → 0.26.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitmodules +3 -0
- data/README +9 -6
- data/TODO +91 -41
- data/VERSION +1 -1
- data/bin/sensible-cinema +13 -1506
- data/bin/sensible-cinema-cli +156 -151
- data/change_log_with_feature_list.txt +17 -2
- data/developer_how_to_contribute_to_the_project.txt +3 -2
- data/documentation/upconversion.txt +4 -0
- data/history_and_related_works_list.txt +1 -0
- data/{play_with_inserted_scene.bat → legal/play_with_inserted_scene.bat} +0 -0
- data/{play_with_overlay.bat → legal/play_with_overlay.bat} +0 -0
- data/legal2 +2 -0
- data/lib/count_down_timer_jruby_swing.rb +3 -4
- data/lib/edl_parser.rb +345 -339
- data/lib/eight_three.rb +6 -1
- data/lib/gui/sensible-cinema-base.rb +671 -0
- data/lib/gui/sensible-cinema-create.rb +304 -0
- data/lib/{sensible-cinema-dependencies.rb → gui/sensible-cinema-dependencies.rb} +0 -0
- data/lib/gui/sensible-cinema-normal.rb +349 -0
- data/lib/gui/sensible-cinema-side-by-side.rb +27 -0
- data/lib/gui/sensible-cinema-upconvert.rb +254 -0
- data/lib/screen_tracker.rb +1 -0
- data/spec/edl_parser.spec.rb +6 -0
- data/spec/notes +107 -16
- data/spec/sensible_cinema_gui.spec.rb +63 -58
- data/todo.inventionzy.txt +12 -0
- data/todo.propaganda +1 -2
- data/todo.upconvert +3 -1
- data/upconvert_netflix/record_screen/record.bat +2 -0
- data/upconvert_netflix/record_screen/recording/1.png +0 -0
- data/upconvert_netflix/record_screen/recording/10.png +0 -0
- data/upconvert_netflix/record_screen/recording/2.png +0 -0
- data/upconvert_netflix/record_screen/recording/3.png +0 -0
- data/upconvert_netflix/record_screen/recording/4.png +0 -0
- data/upconvert_netflix/record_screen/recording/5.png +0 -0
- data/upconvert_netflix/record_screen/recording/6.png +0 -0
- data/upconvert_netflix/record_screen/recording/7.png +0 -0
- data/upconvert_netflix/record_screen/recording/8.png +0 -0
- data/upconvert_netflix/record_screen/recording/9.png +0 -0
- data/upconvert_netflix/record_screen/recording/d.png +0 -0
- data/www/content_editor.html +2 -2
- data/zamples/edit_decision_lists/dvds/edls_being_edited/cars_disney.txt +5 -7
- data/zamples/edit_decision_lists/dvds/innerspace.txt +77 -0
- data/zamples/edit_decision_lists/netflix_instant/avatar-last-air-bender-movie.txt +12 -0
- data/zamples/edit_decision_lists/netflix_instant/avatar-last-airbender-series.txt +1 -0
- data/zamples/players/netflix/netflix_firefox_non_maximized.txt +1 -1
- metadata +28 -11
- data/lib/file_chooser.rb +0 -46
- data/lib/swing_helpers.rb +0 -142
- data/www/monkey.png +0 -0
data/.gitmodules
ADDED
data/README
CHANGED
@@ -132,12 +132,12 @@ Clearplay apparently also runs a rather
|
|
132
132
|
confusing subscription policy, or so I'm told [1], and their DVD players that
|
133
133
|
are a bit weak at times [2]. Their DVD players aren't quite as readily accessible (read:
|
134
134
|
can't buy them at walmart), nor as cheap to buy as some others.
|
135
|
-
Clearplay also
|
135
|
+
Clearplay also doesn't seem to have much community collaboration/review (though you can email them feedback).
|
136
136
|
They also did't have filters for all movies that I, at times, wanted to watch edited (Condorman and Tron
|
137
|
-
lacking last time I checked...probably because they
|
138
|
-
obscure.
|
139
|
-
|
140
|
-
|
137
|
+
lacking last time I checked...probably because they were too
|
138
|
+
obscure. Also it doesn't have filters for educational videos, etc.)
|
139
|
+
If there isn't a filter, you basically have to request one and then *hope* they get around to it.
|
140
|
+
It might take a bit longer than you'd hope (read: years). Or it might never be made.
|
141
141
|
Also, some people watch movies only on computer, and they
|
142
142
|
no longer seem to offer a computer player, just hardware players. They also don't edit streamed
|
143
143
|
online movies either (last time I checked, anyway), nor offer an edited blu-ray player.
|
@@ -153,6 +153,7 @@ Or use it on their home dvd's. Clearplay does not allow for any of these.
|
|
153
153
|
Also clearplay doesn't seem to users for example leave comments on their filters, to improve them, etc.
|
154
154
|
Also you can't tell from clearplay's list whether a DVD is absent because it's clean, or because they
|
155
155
|
haven't done a filter for it.
|
156
|
+
Also sometimes certain DVD's "don't work" with clearplay for some reason (rental versions?) [3]
|
156
157
|
|
157
158
|
So overall I wanted to build my own that overcame some of these hurdles.
|
158
159
|
|
@@ -170,6 +171,8 @@ See also the "Overly Verbose History" section.
|
|
170
171
|
and they told us the model we got was defective, and that the new one was much better and we could get it at a discount, but
|
171
172
|
the next one just died also."
|
172
173
|
|
174
|
+
[3] http://blog.clearplay.com/2010/02/time-travelers-wife.html comments
|
175
|
+
|
173
176
|
== History ==
|
174
177
|
|
175
178
|
See the file history_and_related_works_list.txt for an overly verbose history.
|
@@ -221,4 +224,4 @@ Note that competition/use of files from sensible cinema is welcome!
|
|
221
224
|
In fact, the current end goal is to publish the edit lists (EDL's) to a separate repository with its
|
222
225
|
own API under the CC license, meaning that even "for profit" users can use them for whatever other use they want, hopefully
|
223
226
|
good uses :) More direct direct competitors are also welcome here. I only made this because I had to
|
224
|
-
and nothing like it existed, so if something else springs up, I'm actually happy to use it instead, too.
|
227
|
+
and nothing like it existed, so if something else springs up, I'm actually happy to use it instead, too.
|
data/TODO
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
== roadmap [for just tasks, see below though] ==
|
2
2
|
|
3
|
+
remember this stuff is all "oh gosh I have to do that too?" crud time, don't even want it.
|
3
4
|
netflix
|
4
5
|
upconv netflix
|
5
|
-
mac'ify OCR
|
6
|
+
mac'ify OCR/Mouse
|
6
7
|
upconvert DVD
|
7
|
-
srt release
|
8
|
+
srt expand, release
|
8
9
|
tweaks/docu
|
9
10
|
C EDL
|
10
11
|
|
11
|
-
=== non ordered/eventually ===
|
12
|
+
=== non ordered/eventually (also add line items for them) ===
|
12
13
|
create a skype recorder
|
13
14
|
compare netflix/blu-ray timings et al
|
15
|
+
netflix/skype "disable screen saver while running" program [?]
|
14
16
|
linearize [?] hmm...
|
15
17
|
re-update todo/all docu/user feedback etc.
|
16
|
-
create
|
18
|
+
create openedls.org/api-ify
|
17
19
|
LLC
|
18
20
|
if...back off to just the ffmpeg (plus an "[A,B]" viewer) only...but for now stick with just DVD playback [?] until people want more...
|
19
21
|
no propaganda...
|
@@ -23,30 +25,65 @@
|
|
23
25
|
== high prio like blocking bugs ==
|
24
26
|
|
25
27
|
== under next release specific items: ==
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
test out DVD upscale
|
29
|
+
no super scale res?
|
30
|
+
|
31
|
+
== next things I was working on ==
|
32
|
+
a srt that works with my DVD...does it match netflix instant jonah?
|
33
|
+
unit tests work
|
34
|
+
innerspace
|
35
|
+
screen recording
|
36
|
+
more netflix instant timing
|
37
|
+
bluray jonah
|
38
|
+
|
39
|
+
== yes do ordered for release ==
|
40
|
+
add srt instructions to docu, release
|
41
|
+
fake "tenseness" metric
|
42
|
+
netflix instant descriptor for OS X/work at all
|
43
|
+
post release notes to the google group
|
44
|
+
real "screen record" of upconverting sintel, see if it shows a difference
|
45
|
+
then see if I need to fix my receiver...
|
29
46
|
|
30
47
|
== yes do, un-ordered currently, from the various future release options ==
|
48
|
+
warn other wordpresses
|
49
|
+
legal2
|
50
|
+
test mplayer -vo gl at home
|
51
|
+
extra printf's for scanning for matching
|
52
|
+
Ben's DVD (hook)
|
53
|
+
Ben's other DVD's
|
54
|
+
from an EDL, it can "just play" for netflix (auto-open browser etc.)
|
55
|
+
template-ify for netflix too "create for netflix"
|
56
|
+
add netflix instant instructions,
|
57
|
+
then add a blog post comment after releasing it as template
|
58
|
+
netflix HD versus none...
|
59
|
+
prototype new style EDL
|
60
|
+
"note" competitor upconverters
|
61
|
+
add a "record start stop" + record x time for the virtual audio and other
|
62
|
+
rename as sanitizer
|
63
|
+
note "we are in the creation phase and need your help"
|
64
|
+
that extra .5s DVD reports for file size...
|
65
|
+
TODO test DVD upconv it at 720*x resolution too...
|
66
|
+
investigate the srt morpher...
|
67
|
+
EDL gottman
|
68
|
+
bounty hqdn3d for ffmpeg
|
69
|
+
Greg's DVD's
|
31
70
|
srt/parsing buttons new window [?]
|
71
|
+
demo of conference "music video from file"
|
32
72
|
change upconvert options needs its own "close" button
|
33
|
-
propaganda the upconverting DVD player
|
34
|
-
tweak web stuff/propaganda for upconverter filenames et al
|
35
73
|
real docu on how to use the srt scanner
|
36
74
|
lightning strike from various outlets...
|
37
75
|
accomodate splits vs. blanks and work
|
38
|
-
research VOB dirs
|
39
|
-
still needs timesplits? what about in XBMC? what about XBMC with DVD's
|
40
76
|
todo.upconvert
|
41
77
|
netflix quality upconverter, have a go at it
|
42
78
|
finalize screen capturer
|
43
|
-
have people test it
|
44
79
|
me test it
|
45
80
|
1x, 2x Sintel
|
46
81
|
snapshots of Sintel "normal", then deploy the various comparison pics
|
47
82
|
DVD test it (+- with others testing it for me too)
|
48
83
|
add new open button "edit the EDL for current DVD"
|
49
|
-
|
84
|
+
add "play at 1.5x speed" mplayer button, I guess
|
85
|
+
play in mplayer unedited button should display OSD by default
|
86
|
+
bounty ffmpeg stuff (motion detect, directshow)
|
50
87
|
"fix" mplayer EDL pausing their code
|
51
88
|
the open button should open in the "editing" EDL dir.
|
52
89
|
warn against makemkv (and check vs. handbrake, and offer a bounty)
|
@@ -55,15 +92,6 @@
|
|
55
92
|
an overlapping mute failure when you hit the "watch edited realtime" should popup.
|
56
93
|
witch lady
|
57
94
|
split out the "dependency" codes
|
58
|
-
research XBMC
|
59
|
-
break out into its own separate window?
|
60
|
-
@XBMC: your stuff is broken in at least these two ways (bug reports)
|
61
|
-
also are they 30fps or not? and how do they handle timesplits?
|
62
|
-
is there another format that will actually mute?
|
63
|
-
XBMC mode doesn't mind the 600 starting offset...
|
64
|
-
oh wait we weren't even using it right to begin with LOL
|
65
|
-
plus it needs to "always just skip instead of mute" for now I guess
|
66
|
-
report XBMC bugs, too.
|
67
95
|
consistency for flight of nav. srt? huh?
|
68
96
|
consistency of others, also "DVD reported full-time versus ts time" for others...
|
69
97
|
subtitles: if at beginning of a sub, add extra offset...hmm...why not?
|
@@ -74,13 +102,11 @@
|
|
74
102
|
new upconv button: auto-take some snapshots (just to straight mjpeg or jpeg or the what not [?])
|
75
103
|
advertise urug again?
|
76
104
|
after works in mac for capture+overlay :)
|
77
|
-
advertise virtual audio
|
78
|
-
advertise screen capture
|
79
105
|
create skype recorder windows
|
80
106
|
mplayer directx patch check it...
|
81
107
|
auto-add largest title to the generator EDL
|
82
108
|
complain if times look wrong...on playback? sum time
|
83
|
-
splits... [add better instructions...]
|
109
|
+
splits... [add better instructions on how to be precise...]
|
84
110
|
open EDL to edit it can have a rememberable DIR
|
85
111
|
@instructions "this is great for comparing srt's, except...when it isn't, then you have to..."
|
86
112
|
@instructions: full srt how-to document instead of tooltip [?] or combine the two! yes!
|
@@ -95,8 +121,7 @@
|
|
95
121
|
can auto-use tsmuxer at all [?]
|
96
122
|
mac just die with instructions to use tsmuxer first...
|
97
123
|
actually don't do this, just make sure to warn them if they pass us an mkv...indeed.
|
98
|
-
check
|
99
|
-
check with blu-rays...do they match timing-wise? sub-title wise?
|
124
|
+
check with blu-rays...do they match timing-wise? sub-title wise? do subs match something else?
|
100
125
|
youtube/hulu timings
|
101
126
|
split LLC's website+consumer
|
102
127
|
get LLC before a "real" domain name
|
@@ -116,7 +141,7 @@
|
|
116
141
|
PlayPeriodInTitleAutoStop EC_DVD_PLAYPERIOD_AUTOSTOP
|
117
142
|
make it frame accurate output text :)
|
118
143
|
use 29.97 fps
|
119
|
-
folder, look for
|
144
|
+
folder, look for title_number.edl
|
120
145
|
allow it to "just play from X to Y exactly" ...
|
121
146
|
can start fullscreen
|
122
147
|
does this line up right/perfect? can it work, at all?
|
@@ -128,6 +153,7 @@
|
|
128
153
|
note to them windows vista/7: use ac3filter [?]
|
129
154
|
[A,B]
|
130
155
|
once I can jump around, advertise as a phantom editor :)
|
156
|
+
maybe even before?
|
131
157
|
ask for more beta testers for use, ask for more beta testers for creation, too
|
132
158
|
create a semi-accurate phantom edit EDL [?] just with splits
|
133
159
|
http://www.chefelf.com/forums/index.php?showtopic=6176
|
@@ -136,29 +162,54 @@
|
|
136
162
|
add to docu
|
137
163
|
refresh bug try to reproduce
|
138
164
|
can edit books, too.
|
139
|
-
+- list/publish :)
|
165
|
+
+- list/publish :) [like a manual list et al]
|
140
166
|
create the following EDL: 10 commandments DVD to skip the intro music LOL
|
141
167
|
inventionzy: blu-ray stuff from todo.inventionzy
|
142
168
|
sons of provo "music video" EDL
|
143
|
-
port to mac OS X
|
169
|
+
port to mac OS X
|
170
|
+
PPC dvdid
|
144
171
|
documentation button? notepad?
|
172
|
+
ffmpeg compile it mingw, see if it runs dshow windows
|
145
173
|
|
146
|
-
== other lists to not do (duplicate the todo here if want to actually do it though) ==
|
174
|
+
== other lists to not do (duplicate the todo here if want to actually do it though, basically no do) ==
|
147
175
|
|
148
176
|
todo.upconvert
|
149
177
|
todo.propaganda
|
150
178
|
todo.inventionzy
|
151
|
-
open_edl_list_org_todo
|
179
|
+
todo.open_edl_list_org_todo
|
152
180
|
todo.build_library
|
153
181
|
todo.subtitle
|
154
|
-
|
182
|
+
virtual_audio TODO
|
183
|
+
screen_capture TODO
|
155
184
|
|
156
185
|
== DVD decide later to move up or down ==
|
157
|
-
|
186
|
+
add option "just skip don't mute"
|
158
187
|
|
159
188
|
== DVD+-DVD-realtime backlog (totally unordered, some very low prio, basically all never do) ==
|
160
|
-
|
161
|
-
|
189
|
+
tweak web stuff/propaganda for upconverter filenames et al
|
190
|
+
propaganda DVD upconverter
|
191
|
+
advertise virtual audio
|
192
|
+
advertise screen capture
|
193
|
+
report ffplay -t 6 doesn't stop bug
|
194
|
+
report ffplay -vol 1 doesn't work
|
195
|
+
research XBMC
|
196
|
+
break out into its own separate window?
|
197
|
+
@XBMC: your stuff is broken in at least these two ways (bug reports)
|
198
|
+
also are they 30fps or not? and how do they handle timesplits?
|
199
|
+
is there another format that will actually mute?
|
200
|
+
XBMC mode doesn't mind the 600 starting offset...
|
201
|
+
oh wait we weren't even using it right to begin with LOL
|
202
|
+
plus it needs to "always just skip instead of mute" for now I guess
|
203
|
+
report XBMC bugs, too.
|
204
|
+
research VOB dirs
|
205
|
+
still needs timesplits? what about in XBMC? what about XBMC with DVD's
|
206
|
+
@avisynth: 6 fps from 2? huh? also why are some progs [ffmpeg] seemingly resetting the graphedit pins? huh? also tell that one already logged bug how I work around it...
|
207
|
+
virtual audio TS's line up
|
208
|
+
sout-keep for VLC EDL'ish?
|
209
|
+
local cache volume_name -> dvd id's, in case that can speed things up
|
210
|
+
check if some create buttons are now outdated...
|
211
|
+
make it load faster! this is cuh-razy! or at least splash screen!
|
212
|
+
try buy edit lists from all x,y,z [?]
|
162
213
|
http://www.familysafemovies.com
|
163
214
|
cleanflix (earl? that guy [John webster http://www.amazon.com/Make-Edited-Movies-ebook/dp/B004EYT3BU]?)
|
164
215
|
cougar video (that looks tough...)
|
@@ -172,8 +223,7 @@
|
|
172
223
|
family flix
|
173
224
|
http://theeditedmovieencyclopedia.blogspot.com/2008/08/clean-play-dvds-grand-opening-e-mail.html has grande list
|
174
225
|
movie mask wayback machine
|
175
|
-
test court jester :)
|
176
|
-
ppc dvdid work?
|
226
|
+
test court jester watch it :)
|
177
227
|
accomodate ISO's as input as if they were DVD's themselves
|
178
228
|
fix ffmpeg's "red hue" within their code
|
179
229
|
be a hero and sync the dvdnav repo's [?] also fix mplayer not being able to startup on some dvd's what the...this is nuts!
|
@@ -186,14 +236,14 @@
|
|
186
236
|
"save to" -> same dir as "get from" yeah
|
187
237
|
figure out a way to get to the roku [ps3ms?], +- netflix edited to roku LOL
|
188
238
|
prompt something if the EDL is actually "empty" :)
|
189
|
-
already donated: rubular, mplayer, vlc, menumeter, http://instantitunes.wordpress.com/2010/02/26/use-tsmuxer-on-snow-leopard, unlocker, mac fan thing, open office, many sourceforge tops, 7zip, VLC, mplayer, cannot donate: ffmpeg, http://ffmpeg.zeranoe.com/builds, tsmuxer (sent email), asked mulder, smplayer ($5), http://lame.buanzo.com.ar, sox
|
239
|
+
already donated: rubular, mplayer, vlc, menumeter, http://instantitunes.wordpress.com/2010/02/26/use-tsmuxer-on-snow-leopard, unlocker, mac fan thing, open office, many sourceforge tops, 7zip, VLC, mplayer, cannot donate: ffmpeg, http://ffmpeg.zeranoe.com/builds, tsmuxer (sent email), asked mulder, smplayer ($5), http://lame.buanzo.com.ar, sox, smcFanControl (eidac)
|
190
240
|
note "you want to optimize your reverse blitting first... :)"
|
191
241
|
if 2 EDL's, still can choose a title trackfor automatically playing it right.
|
192
242
|
fast preview: change it to be aggressive sometimes yes, other times no
|
193
243
|
fast preview mode: watch for modifications to file, kill mplayer instances for them on change :)
|
194
244
|
fast preview tends to "go too far" [like the end of profanity is still there when played via the "real way"]
|
195
245
|
note to them [in how_to_create]: can do the two types of preview at same time...concurrently...to save time...
|
196
|
-
investigate:
|
246
|
+
investigate: use zoomplayer max cutscene support?
|
197
247
|
|
198
248
|
can I make playback more smooth by upping mplayer cache? does smplayer pass it a parameter? It does jerk a bit doesn't it, on slower?
|
199
249
|
can I just use ffmpeg for an initial -> ts ? http://eotmsnotes.wordpress.com/2011/04/25/tsmuxer-notes/
|
@@ -216,7 +266,7 @@
|
|
216
266
|
detected an overlap 1397.51 1401.275 mute 1395.474 1397.874 mute
|
217
267
|
SyntaxError
|
218
268
|
lua VLC EDL plugin?
|
219
|
-
test with cars-ws
|
269
|
+
test with cars-ws, mac (to make sure volume name doesn't have spaces)
|
220
270
|
the distro could be made smaller yet [at least not as many gem deps needed...maybe more possible...]
|
221
271
|
@mplayer: chooses wrong language ts from jester...sigh
|
222
272
|
@mplayer: crash: http://betterlogic.com/roger/2011/07/mplayer-mac-os-x-woe/
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.26.
|
1
|
+
0.26.1
|
data/bin/sensible-cinema
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/bin/ruby # so my editor will like
|
1
|
+
#!/usr/bin/ruby # so my editor will like the file...
|
2
2
|
=begin
|
3
3
|
Copyright 2010, Roger Pack
|
4
4
|
This file is part of Sensible Cinema.
|
@@ -17,7 +17,10 @@ This file is part of Sensible Cinema.
|
|
17
17
|
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
=end
|
19
19
|
|
20
|
+
|
21
|
+
# load sane
|
20
22
|
print 'Starting Sensible Cinema...'
|
23
|
+
|
21
24
|
require File.expand_path(File.dirname(__FILE__) + "/../lib/add_any_bundled_gems_to_load_path.rb")
|
22
25
|
begin
|
23
26
|
require 'sane'
|
@@ -27,1517 +30,23 @@ rescue LoadError
|
|
27
30
|
end
|
28
31
|
|
29
32
|
raise 'need jruby' unless OS.java?
|
30
|
-
raise 'need newer jruby!' unless RUBY_DESCRIPTION >= 'jruby 1.6.0' # may not need this since we still have to accomodate for so many
|
31
|
-
|
32
|
-
alias system_original system
|
33
|
-
require 'fileutils'
|
34
|
-
|
35
|
-
class String
|
36
|
-
def snake_case
|
37
|
-
self.gsub(/::/, '/').
|
38
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
39
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
40
|
-
tr("-", "_").
|
41
|
-
downcase
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
require_relative '../lib/swing_helpers'
|
46
|
-
|
47
|
-
# attempt to load on demand...i.e. faster...
|
48
|
-
for kls in [:MencoderWrapper, :MplayerEdl, :PlayAudio, :SubtitleProfanityFinder, :ConvertThirtyFps, :RubyClip, :DriveInfo]
|
49
|
-
autoload kls, "./lib/#{kls.to_s.snake_case}"
|
50
|
-
end
|
51
|
-
|
52
|
-
# a few I'll always need eventually...
|
53
|
-
require_relative '../lib/storage'
|
54
|
-
require_relative '../lib/edl_parser'
|
55
|
-
require 'tmpdir'
|
56
|
-
require 'whichr'
|
57
|
-
require 'os'
|
58
|
-
if OS.doze?
|
59
|
-
autoload :WMI, 'ruby-wmi'
|
60
|
-
autoload :EightThree, './lib/eight_three'
|
61
|
-
end
|
62
|
-
|
63
|
-
vendor_cache = File.expand_path(File.dirname(__FILE__)) + '/../vendor/cache'
|
64
|
-
|
65
|
-
if OS.windows?
|
66
|
-
for name in ['.', 'mencoder', 'ffmpeg']
|
67
|
-
# put them all before the old path
|
68
|
-
ENV['PATH'] = (vendor_cache + '/' + name).to_filename + ';' + ENV['PATH']
|
69
|
-
end
|
70
|
-
|
71
|
-
installed_smplayer_folders = Dir['{c,d,e,f,g}:/program files*/MPlayer for Windows*'] # sometimes ends with UI? huh?
|
72
|
-
|
73
|
-
for folder in installed_smplayer_folders
|
74
|
-
ENV['PATH'] = ENV['PATH'] + ";#{folder.gsub('/', "\\")}"
|
75
|
-
end
|
76
|
-
|
77
|
-
else
|
78
|
-
ENV['PATH'] = ENV['PATH'] + ':' + '/opt/local/bin' # add macports' bin in, just in case...
|
79
|
-
end
|
80
|
-
|
81
|
-
import 'javax.swing.ImageIcon'
|
82
|
-
require_relative '../lib/sensible-cinema-dependencies'
|
83
|
-
|
84
|
-
module SensibleSwing
|
85
|
-
VERSION = File.read(File.dirname(__FILE__) + "/../VERSION").strip
|
86
|
-
puts "v. " + VERSION
|
87
|
-
|
88
|
-
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) # sigh
|
89
|
-
|
90
|
-
class MainWindow < JFrame
|
91
|
-
|
92
|
-
def we_are_in_create_mode
|
93
|
-
ARGV.index("--create-mode")
|
94
|
-
end
|
95
|
-
|
96
|
-
def new_jbutton title, tooltip = nil
|
97
|
-
button = JButton.new title
|
98
|
-
button.tool_tip = tooltip
|
99
|
-
button.set_bounds(44, @starting_button_y, @button_width, 23)
|
100
|
-
@panel.add button
|
101
|
-
@buttons << button
|
102
|
-
if block_given? # allow for new_jbutton("xx") do ... end [this is possible through some miraculous means LOL]
|
103
|
-
button.on_clicked { yield }
|
104
|
-
end
|
105
|
-
increment_button_location
|
106
|
-
button
|
107
|
-
end
|
108
|
-
|
109
|
-
def add_text_line line
|
110
|
-
jlabel = JLabel.new line
|
111
|
-
happy = Font.new("Tahoma", Font::PLAIN, 11)
|
112
|
-
jlabel.setFont(happy)
|
113
|
-
jlabel.set_bounds(44,@starting_button_y ,460,14)
|
114
|
-
@panel.add jlabel
|
115
|
-
increment_button_location 18
|
116
|
-
jlabel
|
117
|
-
end
|
118
|
-
|
119
|
-
def increment_button_location how_much = 30
|
120
|
-
@starting_button_y += how_much
|
121
|
-
setSize @button_width+80, @starting_button_y + 50
|
122
|
-
end
|
123
|
-
|
124
|
-
def force_accept_license_first
|
125
|
-
if !(LocalStorage['main_license_accepted'] == VERSION)
|
126
|
-
require_blocking_license_accept_dialog 'Sensible Cinema', 'gplv3', 'http://www.gnu.org/licenses/gpl.html', 'Sensible Cinema license agreement',
|
127
|
-
"Sensible Cinema is distributed under the gplv3 (http://www.gnu.org/licenses/gpl.html).\nBY CLICKING \"accept\" YOU SIGNIFY THAT YOU HAVE READ, UNDERSTOOD AND AGREED TO ABIDE BY THE TERMS OF THIS AGREEMENT"
|
128
|
-
require_blocking_license_accept_dialog 'Sensible Cinema', 'is_it_legal_to_copy_dvds.txt file', File.expand_path(File.dirname(__FILE__) + "/../documentation/is_it_legal_to_copy_dvds.txt"),
|
129
|
-
'is_it_legal_to_copy_dvds.txt file', 'I acknowledge that I have read, understand, accept and agree to abide by the implications noted in the documentation/is_it_legal_to_copy_dvds.txt file'
|
130
|
-
LocalStorage['main_license_accepted'] = VERSION
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
LocalStorage = Storage.new("sensible_cinema_storage")
|
135
|
-
|
136
|
-
def close_when_done thread, j_item
|
137
|
-
if j_item
|
138
|
-
Thread.new { thread.join; j_item.dispose }
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def add_play_upconvert_buttons
|
143
|
-
|
144
|
-
@watch_file_upconvert = new_jbutton( "Watch a movie file upconverted (unedited)") do
|
145
|
-
popup = warn_if_no_upconvert_options_currently_selected
|
146
|
-
filename_mpg = new_existing_file_selector_and_select_file( "pick movie file (like moviename.mpg)")
|
147
|
-
thread = play_mplayer_edl_non_blocking [filename_mpg, nil]
|
148
|
-
close_when_done(thread, popup)
|
149
|
-
end
|
150
|
-
@watch_file_upconvert.tool_tip= "This plays back a movie file, like moviefile.mpg, or moviename.vob using your current upconverter settings.\nTo playback a file edited upconverted, set upconvert options here first, then run them using sensible cinema main--it will automatically use your new upconverting options.\n" # LODO
|
151
|
-
|
152
|
-
@watch_dvd_upconvert = new_jbutton( "Watch a DVD upconverted (unedited)") do
|
153
|
-
popup = warn_if_no_upconvert_options_currently_selected
|
154
|
-
thread = play_dvd_smplayer_unedited false, false, false
|
155
|
-
close_when_done(thread, popup)
|
156
|
-
end
|
157
|
-
@watch_dvd_upconvert.tool_tip = "Plays back the currently inserted DVD, using your current upconverter settings.\nIf it fails (dies immediately, blank screen, etc.), try setting upconvert options to a smaller screen resolution multiple.\nOr try playing the DVD with VLC first, then it might work.\nTo playback a DVD edited upconverted, set upconvert options here first, then run them using sensible cinema main--it will automatically use your new upconverting options."
|
158
|
-
|
159
|
-
add_text_line ''
|
160
|
-
@upconv_line = add_text_line ''
|
161
|
-
change_upconvert_line_to_current
|
162
|
-
|
163
|
-
add_change_upconvert_options_button
|
164
|
-
add_text_line ''
|
165
|
-
|
166
|
-
end
|
167
|
-
|
168
|
-
# a window that when closed doesn't bring the whole app down
|
169
|
-
def new_child_window
|
170
|
-
child = MainWindow.new
|
171
|
-
child.setDefaultCloseOperation(JFrame::DISPOSE_ON_CLOSE)
|
172
|
-
child.parent=self # this should have failed in the PPL
|
173
|
-
child
|
174
|
-
end
|
175
|
-
|
176
|
-
attr_accessor :parent, :upconv_line
|
177
|
-
|
178
|
-
def add_change_upconvert_options_button
|
179
|
-
@show_upconvert_options = new_jbutton("Set Playback Upconversion Quality Options") do
|
180
|
-
|
181
|
-
unless LocalStorage[ScreenMultipleFactor]
|
182
|
-
=begin show_blocking_message_dialog <<-EOL
|
183
|
-
With upconversion, if your monitor is 1024 pixels wide and you upconvert to 2048 pixels then display it on 1024, it looks better.
|
184
|
-
Sensible Cinema sets the default default resolution to be 2x your screen resolution, which is better for high end cpu's.
|
185
|
-
If you have a low powered system or laptop you may need to change it (drag the slider) lower to avoid it displaying only a black or white screen, as your system can't handle it,
|
186
|
-
so adjust accordingly if you have a lesser system. Also changing this setting can make it use more or less CPU overall.
|
187
|
-
EOL
|
188
|
-
=end
|
189
|
-
# LODO make into tooltip too [?]
|
190
|
-
LocalStorage['screen_multiples'] = 2.0
|
191
|
-
end
|
192
|
-
|
193
|
-
upconvert_window = new_child_window
|
194
|
-
upconvert_window.add_change_upconvert_buttons
|
195
|
-
end
|
196
|
-
@show_upconvert_options.tool_tip= "Allows you to set your upconvert options.\nUpconverting attempts to playback your movie with higher quality on high resolution monitors."
|
197
|
-
end
|
198
|
-
|
199
|
-
def warn_if_no_upconvert_options_currently_selected
|
200
|
-
if !LocalStorage[UpConvertEnglish]
|
201
|
-
show_non_blocking_message_dialog "Warning: upconvert options have not been set yet--set upconvert options first and restart, if desired."
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
def change_upconvert_line_to_current
|
206
|
-
current = get_current_upconvert_as_phrase
|
207
|
-
if @upconv_line
|
208
|
-
@upconv_line.set_text current
|
209
|
-
end
|
210
|
-
if @parent && @parent.upconv_line
|
211
|
-
@parent.upconv_line.set_text current
|
212
|
-
end # LODO we want both [?]
|
213
|
-
end
|
214
|
-
|
215
|
-
def select_new_sxs_style
|
216
|
-
answer = show_select_buttons_prompt 'Select EDL file style creation for this program', :yes => 'Smplayer style', :no => 'XBMC style'
|
217
|
-
if answer == 0
|
218
|
-
LocalStorage[SideBySide] = 'smplayer'
|
219
|
-
elsif answer == 1
|
220
|
-
LocalStorage[SideBySide] = 'xbmc'
|
221
|
-
else
|
222
|
-
show_blocking_message_dialog 'please choose one--smplayer if you don\'t know'
|
223
|
-
select_new_sxs_style
|
224
|
-
end
|
225
|
-
|
226
|
-
end
|
227
|
-
|
228
|
-
SideBySide = 'side_by_side' # 'xbmc' or 'smplayer'
|
229
|
-
UpConvertKey = 'upconvert_setting'
|
230
|
-
UpConvertKeyExtra = 'upconvert_setting_extra'
|
231
|
-
UpConvertEnglish = 'upconvert_english_name'
|
232
|
-
ScreenMultipleFactor = 'screen_multiples'
|
233
|
-
|
234
|
-
def add_change_upconvert_buttons
|
235
|
-
raise 'should have already been set for us' unless LocalStorage[ScreenMultipleFactor]
|
236
|
-
@none = new_jbutton("Reset upconvert options to default (no upconversion)")
|
237
|
-
@none.tool_tip = "Having no upconvert options is reasonably good, might use directx for scaling, nice for slow cpu's"
|
238
|
-
@none.on_clicked {
|
239
|
-
LocalStorage[UpConvertKey] = nil
|
240
|
-
LocalStorage[UpConvertKeyExtra] = nil
|
241
|
-
LocalStorage[UpConvertEnglish] = nil
|
242
|
-
display_current_upconvert_setting
|
243
|
-
}
|
244
|
-
@medium_dvd = new_jbutton("Change upconvert options for DVD-style video") {
|
245
|
-
LocalStorage[UpConvertKey] = "hqdn3d=0:1:4:4,scale=SCREEN_X:-10:0:0:2"
|
246
|
-
# hqdn3d[=luma_spatial:chroma_spatial:luma_tmp:chroma_tmp]
|
247
|
-
LocalStorage[UpConvertKeyExtra] = "-sws 9 -ssf ls=75.0 -ssf cs=7.0"
|
248
|
-
LocalStorage[UpConvertEnglish] = "DVD"
|
249
|
-
display_current_upconvert_setting
|
250
|
-
}
|
251
|
-
high_compression = new_jbutton("Change upconvert options for playing high compressed video files") {
|
252
|
-
# -autoq 6 -vf pp [?]
|
253
|
-
LocalStorage[UpConvertEnglish] = "high compressed"
|
254
|
-
LocalStorage[UpConvertKey] = "hqdn3d=0:1:4:4,pp=hb:y/vb:y,scale=SCREEN_X:-10:0:0:3" # pp should be after hqdn3d I think... and hqdn3d should be before scale...
|
255
|
-
LocalStorage[UpConvertKeyExtra] = "-sws 9 -ssf ls=75.0 -ssf cs=25.0"
|
256
|
-
display_current_upconvert_setting
|
257
|
-
# -Processing method: mplayer with accurate deblocking ???
|
258
|
-
}
|
259
|
-
new_jbutton("Change upconvert options to experimental style playback") {
|
260
|
-
LocalStorage[UpConvertKey] = "hqdn3d=7:7:5,scale=SCREEN_X:-10:0:0:10"
|
261
|
-
LocalStorage[UpConvertKeyExtra] = "-sws 9 -ssf ls=100.0 -ssf cs=75.0"
|
262
|
-
LocalStorage[UpConvertEnglish] = "experimental"
|
263
|
-
display_current_upconvert_setting
|
264
|
-
}
|
265
|
-
add_text_line "Multiple factor screen widths (higher is better, but uses more cpu, 2x is good for high-end)."
|
266
|
-
add_text_line "If mplayer just dies or displays only a black or white screen then lower this setting."
|
267
|
-
slider = JSlider.new
|
268
|
-
slider.setBorder(BorderFactory.createTitledBorder("Screen resolution multiple"));
|
269
|
-
|
270
|
-
# I want tick for 1x, 1.5x, 2x, 2.5x, 3x
|
271
|
-
# so let's do 10 -> 30 ...
|
272
|
-
|
273
|
-
labelTable = java.util.Hashtable.new
|
274
|
-
i = java.lang.Integer
|
275
|
-
l = JLabel
|
276
|
-
|
277
|
-
# allow for 0.75 too, if you have a large monitor, slower cpu...
|
278
|
-
local_minimum = (720.0/get_current_max_width_resolution)*100 # allow 1024 to use upscaling to 860 LOL
|
279
|
-
# => 70 for 1024 monitor, so we'll then allow for the 75 below...
|
280
|
-
label_minimum = nil
|
281
|
-
(0..300).step(25) do |n|
|
282
|
-
if n > local_minimum
|
283
|
-
label_minimum ||= n
|
284
|
-
if (n % 100 == 0)
|
285
|
-
labelTable.put(i.new(n), l.new("#{n/100}x")) # 1x
|
286
|
-
elsif n == label_minimum # just for the bottom label, rest too chatty
|
287
|
-
labelTable.put(i.new(n), l.new("#{n/100.0}x")) # 1.5x
|
288
|
-
end
|
289
|
-
end
|
290
|
-
end
|
291
|
-
slider.setLabelTable( labelTable )
|
292
|
-
|
293
|
-
slider.maximum=300
|
294
|
-
slider.minimum=label_minimum
|
295
|
-
slider.setMajorTickSpacing(100)
|
296
|
-
slider.setMinorTickSpacing(25)
|
297
|
-
slider.setPaintTicks(true)
|
298
|
-
slider.setPaintLabels(true)
|
299
|
-
slider.snap_to_ticks=true
|
300
|
-
|
301
|
-
slider.set_value LocalStorage[ScreenMultipleFactor] * 100
|
302
|
-
|
303
|
-
slider.add_change_listener { |event|
|
304
|
-
if !slider.value_is_adjusting
|
305
|
-
# they released their hold on it...
|
306
|
-
old_value = LocalStorage[ScreenMultipleFactor]
|
307
|
-
new_value = slider.value/100.0
|
308
|
-
LocalStorage[ScreenMultipleFactor] = new_value
|
309
|
-
if new_value != old_value
|
310
|
-
display_current_upconvert_setting
|
311
|
-
if slider.value == label_minimum
|
312
|
-
show_blocking_message_dialog "Setting it too low like that might make it not do much upconverting (DVD's, are 720px)"
|
313
|
-
end
|
314
|
-
end
|
315
|
-
end
|
316
|
-
}
|
317
|
-
slider.set_bounds(44, @starting_button_y, @button_width, 66)
|
318
|
-
2.times {increment_button_location}
|
319
|
-
@panel.add(slider)
|
320
|
-
end
|
321
|
-
|
322
|
-
def display_current_upconvert_setting
|
323
|
-
change_upconvert_line_to_current
|
324
|
-
show_non_blocking_message_dialog get_current_upconvert_as_phrase
|
325
|
-
end
|
326
|
-
|
327
|
-
def get_current_upconvert_as_phrase
|
328
|
-
settings = LocalStorage[UpConvertEnglish]
|
329
|
-
out = "Upconvert options currently #{ settings ? "are set to #{settings} style" : "are NOT SET"}"
|
330
|
-
if settings
|
331
|
-
multiple = LocalStorage[ScreenMultipleFactor]
|
332
|
-
out += " (screen multiplier #{get_current_max_width_resolution}*#{multiple} = #{(multiple * get_current_max_width_resolution).to_i}px)."
|
333
|
-
end
|
334
|
-
out
|
335
|
-
end
|
336
|
-
|
337
|
-
def get_current_max_width_resolution
|
338
|
-
java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment.getScreenDevices.map{|gd| gd.display_mode.width}.max.to_i
|
339
|
-
end
|
340
|
-
|
341
|
-
def get_upconvert_vf_settings
|
342
|
-
template = LocalStorage[UpConvertKey]
|
343
|
-
if template
|
344
|
-
# choose width of widest monitor (why would they display it on the other?)
|
345
|
-
screen_multiple = LocalStorage[ScreenMultipleFactor]
|
346
|
-
upc = template.gsub('SCREEN_X', (get_current_max_width_resolution*screen_multiple).to_i.to_s) # has to be an integer...
|
347
|
-
upc = 'pullup,softskip,' + upc
|
348
|
-
p 'using upconvert settings ' + upc
|
349
|
-
upc
|
350
|
-
else
|
351
|
-
p 'not using any specific upconversion'
|
352
|
-
# TODO not for straight mplayer [?] tangled fails mac
|
353
|
-
if OS.mac?
|
354
|
-
'' # avoid odd message try appending the scale filter <sigh> I don't *want* the scale filter with no upconversion gah.
|
355
|
-
else
|
356
|
-
# until I find out if they were making me too slow on older comps'
|
357
|
-
# "pullup,softskip"
|
358
|
-
''
|
359
|
-
end
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
|
-
def get_upconvert_secondary_settings
|
364
|
-
LocalStorage[UpConvertKeyExtra]
|
365
|
-
end
|
366
|
-
|
367
|
-
def setup_advanced_buttons
|
368
|
-
|
369
|
-
new_jbutton("Display the standard buttons") do
|
370
|
-
window = new_child_window
|
371
|
-
window.setup_normal_buttons
|
372
|
-
end
|
373
|
-
|
374
|
-
add_text_line 'Realtime/Create Options:'
|
375
|
-
|
376
|
-
@create_new_edl_for_current_dvd = new_jbutton("Create new Edit List for a DVD",
|
377
|
-
"If your DVD doesn't have an EDL created for it, this will be your first step--create an EDL file for it.")
|
378
|
-
@create_new_edl_for_current_dvd.on_clicked do
|
379
|
-
create_brand_new_edl
|
380
|
-
@display_dvd_info.simulate_click # for now...
|
381
|
-
end
|
382
|
-
|
383
|
-
@open_list = new_jbutton("Open/Edit a previously created Edit List file", "If your DVD has a previously existing EDL for it, you can open it to edit it with this button.")
|
384
|
-
@open_list.on_clicked {
|
385
|
-
filename = new_existing_file_selector_and_select_file( "Pick any file to open in editor", EdlParser::EDL_DIR)
|
386
|
-
open_file_to_edit_it filename
|
387
|
-
}
|
388
|
-
|
389
|
-
@play_smplayer = new_jbutton( "Watch full DVD unedited (realtime smplayer)")
|
390
|
-
@play_smplayer.tool_tip = <<-EOL
|
391
|
-
This will play the DVD unedited within smplayer.
|
392
|
-
NB it will default to title 1, so updated your EDL file that matches this DVD with the proper title if this doesn't work for you
|
393
|
-
i.e. if it just plays a single preview title or what not, and not the main title, you need to change this value.
|
394
|
-
This is useful if you want to just kind of watch the movie to enjoy it, and look for scenes to cut out.
|
395
|
-
You can use the built-in OSD (on-screen-display) to see what time frame the questionable scenes are at
|
396
|
-
(type "o" to toggle it). However, just realize that the OSD is in 30 fps, and our time stamps are all in 29.97
|
397
|
-
fps, so you'll need to convert it (the convert timestamp button) to be able to use it in a file.
|
398
|
-
EOL
|
399
|
-
@play_smplayer.on_clicked {
|
400
|
-
play_dvd_smplayer_unedited false, true, true
|
401
|
-
}
|
402
|
-
|
403
|
-
@play_mplayer_raw = new_jbutton( "Watch full DVD unedited (realtime mplayer)")
|
404
|
-
@play_mplayer_raw.tool_tip = <<-EOL
|
405
|
-
This is also useful for comparing subtitle files to see if they have accurate timings.
|
406
|
-
If you turn on subtitles (use the v button), then compare your srt file at say, the 1 hour mark, or 2 hour mark,
|
407
|
-
with the subtitles that mplayer displays, it *should* match exactly with the output in the command line,
|
408
|
-
like "V: 3600.0" should match your subtitle line "01:00:00,000 --> ..."
|
409
|
-
EOL
|
410
|
-
@play_mplayer_raw.on_clicked {
|
411
|
-
play_dvd_smplayer_unedited true, true, true
|
412
|
-
}
|
413
|
-
|
414
|
-
@parse_srt = new_jbutton("Scan a subtitle file (.srt) to detect profanity times automatically" )
|
415
|
-
@parse_srt.tool_tip = <<-EOL
|
416
|
-
You can download a .srt file and use it to automatically search for profanities.
|
417
|
-
Basically download it from opensubtitles.org (possibly from other sites, too),
|
418
|
-
(enter dvd name in the search box, click a result, click one from the list with an English flag, then click 'Download(zip)')
|
419
|
-
Once you download the zip, unzip it, and then compare the timestamps in it with those on the DVD (see the button "Watch DVD unedited (realtime mplayer)")
|
420
|
-
NB that you'll first want/need to *carefully* double check your subtitle
|
421
|
-
file with the actual DVD. (ex: smplayer, hit the 'o' button to display
|
422
|
-
the current timestamp, then go to the end, stop at some point with text
|
423
|
-
and hit the '.' key until a subtitle very first displays.
|
424
|
-
Next convert that number to 29.97 fps (using the button given).
|
425
|
-
The numbers should match precisely. If they don't, edit this file
|
426
|
-
so that it will have some offsets given.
|
427
|
-
EOL
|
428
|
-
|
429
|
-
@parse_srt.on_clicked do
|
430
|
-
filename = new_existing_file_selector_and_select_file("Pick srt file to scan for profanity:")
|
431
|
-
add_to_beginning = get_user_input("How much time to subtract from the beginning of each subtitle entry (ex: 1:00 -> 1:01 becomes 0:59 -> 1:01)", "0.0")
|
432
|
-
add_to_end = get_user_input("How much time to add to the end of each subtitle entry (ex: 1:00 -> 1:01 becomes 1:00 -> 1:02)", "0.0")
|
433
|
-
parsed = SubtitleProfanityFinder.edl_output filename, {}, add_to_beginning.to_f, add_to_end.to_f # flight: TODO necessary typically ??? 0.35, 0.25
|
434
|
-
File.write(EdlTempFile, "# add these into your mute section if you deem them mute-worthy\n" + parsed)
|
435
|
-
open_file_to_edit_it filename, true
|
436
|
-
sleep 0.3 if OS.mac? # add delay...
|
437
|
-
open_file_to_edit_it EdlTempFile
|
438
|
-
end
|
439
|
-
|
440
|
-
@display_dvd_info = new_jbutton( "Display information about current DVD (ID, etc.)" )
|
441
|
-
@display_dvd_info.tool_tip = "This is useful to setup a DVD's 'unique ID' within an EDL for it. \nIf your EDL doesn't have a line like disk_unique_id => \"...\" then you will want to run this to be able to add that line in."
|
442
|
-
@display_dvd_info.on_clicked {
|
443
|
-
drive, volume_name, dvd_id = choose_dvd_drive_or_file true # real DVD disk
|
444
|
-
# display it, allow them to copy and paste it out
|
445
|
-
title_lengths = nil
|
446
|
-
t = Thread.new { title_lengths= `mplayer dvdnav:// -nocache -dvd-device #{drive} -identify -frames 0 2>&1| grep LENGTH` }
|
447
|
-
id_string = "\"disk_unique_id\" => \"#{dvd_id}\", # #{volume_name}"
|
448
|
-
show_copy_pastable_string "#{drive} #{volume_name} for your copying+pasting pleasure (highlight, then ctrl+c to copy)\n
|
449
|
-
This is USED eventually to identify a disk to match it to its EDL, later.", id_string
|
450
|
-
t.join
|
451
|
-
File.write EdlTempFile, id_string + "\n" + title_lengths
|
452
|
-
open_file_to_edit_it EdlTempFile
|
453
|
-
id_string
|
454
|
-
}
|
455
|
-
|
456
|
-
@convert_seconds_to_ts = new_jbutton( "Convert 3600 <-> 1:00:00 style timestamps" )
|
457
|
-
@convert_seconds_to_ts.on_clicked {
|
458
|
-
input = get_user_input("Enter \"from\" timestamps, like 3600 or 1:40:00:", "1:00:00.1 or 3600.1")
|
459
|
-
while(input)
|
460
|
-
if input =~ /:/
|
461
|
-
output = EdlParser.translate_string_to_seconds input
|
462
|
-
else
|
463
|
-
output = EdlParser.translate_time_to_human_readable input.to_f, true
|
464
|
-
end
|
465
|
-
input = show_copy_pastable_string("Converted:", output)
|
466
|
-
end
|
467
|
-
}
|
468
|
-
|
469
|
-
@convert_timestamp = new_jbutton( "Convert timestamp from DVD player time to EDL time (30->29.97 fps)" )
|
470
|
-
@convert_timestamp.tool_tip=<<-EOL
|
471
|
-
Our EDL's assume 29.97 fps (which is what a DVD actually has). Unfortunately most hardware or commercial DVD players
|
472
|
-
think that the DVD is 30 fps, which means that if you use them for timestamps for your EDL's,
|
473
|
-
you will be slightly off (at the end of a 2 hour film, by 8 seconds). So all your edits will be wrong.
|
474
|
-
How to fix: convert your times from "DVD player" time to "EDL accurate" time by using this button.
|
475
|
-
This is necessary for all hardware DVD player timestamps, PowerDVD player (software), Windows Media Player (playing a DVD),
|
476
|
-
and mplayer's "on screen display" DVD timestamps.
|
477
|
-
It is not necessary for smplayer timestamps (or mplayer's "V: 3600" in the command line), which are already 29.97.
|
478
|
-
smplayer's on-screen-display (the 'o' key) is accurate (and doesn't suffer from dvd_mplayer_splits)
|
479
|
-
but is 30 fps, so timestamps would need to be converted.
|
480
|
-
Dont use VLC for DVD timestamps at all--it can get up to 30s off! VLC playing back a file is usually pretty accurate to 29.97.
|
481
|
-
In general, GUI's like VLC or smplayer are always a tidge off (maybe 0.3s) from the right timestamp, so take that into consideration.
|
482
|
-
Mplayers "V: 3600" is usually right on (29.97 fps), however.
|
483
|
-
EOL
|
484
|
-
@convert_timestamp.on_clicked {
|
485
|
-
thirty_fps = get_user_input("Enter your DVD (30 fps) timestamp, I'll convert it to 29.97 (usable in EDL's):", "1:00:00.1")
|
486
|
-
thirty_fps_in_seconds = EdlParser.translate_string_to_seconds thirty_fps
|
487
|
-
twenty_nine_seven_fps = ConvertThirtyFps.from_thirty(thirty_fps_in_seconds)
|
488
|
-
human_twenty_nine_seven = EdlParser.translate_time_to_human_readable twenty_nine_seven_fps, true
|
489
|
-
show_copy_pastable_string("Sensible cinema usable value (29.97 fps) for #{thirty_fps} would be: ", human_twenty_nine_seven)
|
490
|
-
}
|
491
|
-
|
492
|
-
@create_dot_edl = new_jbutton( "Create a side-by-side moviefilename.edl file")
|
493
|
-
@create_dot_edl.tool_tip = <<-EOL
|
494
|
-
Creates a moviefilename.edl file (corresponding to some moviefilename.some_ext file already existing)
|
495
|
-
XBMC/smplayer (smplayer can be used by WMC plugins, etc.) "automagically detect",
|
496
|
-
if it exists, and automatically use it .edl to show that file edited played back.
|
497
|
-
If you use smplayer, note that you'll need to download the "lord mulder mplayer"
|
498
|
-
version (which includes an updated version of mplayer that fixes some bugs in EDL playback)
|
499
|
-
EOL
|
500
|
-
@create_dot_edl.on_clicked {
|
501
|
-
choose_file_and_edl_and_create_sxs_or_play true
|
502
|
-
}
|
503
|
-
|
504
|
-
# new_jbutton("Select side by side EDL file style (smplayer vs. XBMC)") do
|
505
|
-
# select_new_sxs_style # TODO
|
506
|
-
# end
|
507
|
-
|
508
|
-
|
509
|
-
add_text_line 'Create Options with local intermediary file:'
|
510
|
-
|
511
|
-
new_jbutton("Show options with local intermediary file") do
|
512
|
-
window = new_child_window
|
513
|
-
window.add_options_that_use_local_files
|
514
|
-
end
|
515
|
-
|
516
|
-
# @reload = new_jbutton("reload bin/sensible-cinema code") do
|
517
|
-
# load $0
|
518
|
-
# end
|
519
|
-
|
520
|
-
end # advanced buttons
|
521
|
-
|
522
|
-
def add_options_that_use_local_files
|
523
|
-
add_text_line 'Create Options that first create/use a local intermediary file:'
|
524
|
-
|
525
|
-
@preview_section = new_jbutton( "Preview a certain time frame from fulli file (edited)" )
|
526
|
-
@preview_section.tool_tip = <<-EOL
|
527
|
-
This allows you to preview an edit easily.
|
528
|
-
It is the equivalent of saying \"watch this file edited from exactly minute x second y to minute z second q"
|
529
|
-
Typically if you want to test an edit, you can start a few seconds before, and end a few seconds after it, to test it precisely.
|
530
|
-
EOL
|
531
|
-
@preview_section.on_clicked {
|
532
|
-
do_create_edited_copy_via_file true
|
533
|
-
}
|
534
|
-
|
535
|
-
@preview_section_unedited = new_jbutton("Preview a certain time frame from fulli file (unedited)" )
|
536
|
-
@preview_section.tool_tip = "Allows you to view a certain time frame unedited (ex: 10:00 to 10:05), so you can narrow down to pinpoint where questionable scenes are, etc. This is the only way to view a specific scene if there are not cuts within that scene yet."
|
537
|
-
@preview_section_unedited.on_clicked {
|
538
|
-
do_create_edited_copy_via_file true, false, true
|
539
|
-
}
|
540
|
-
|
541
|
-
@rerun_preview = new_jbutton( "Re-run most recently watched preview time frame from fulli file" )
|
542
|
-
@rerun_preview.tool_tip = "This will re-run the preview that you most recently performed. Great for checking to see if you last edits were successful or not."
|
543
|
-
@rerun_preview.on_clicked {
|
544
|
-
repeat_last_copy_dvd_to_hard_drive
|
545
|
-
}
|
546
|
-
|
547
|
-
# Maybe this button should go too...
|
548
|
-
@fast_preview = new_jbutton("fast preview all from fulli file (smplayer EDL)")
|
549
|
-
@fast_preview.tool_tip = <<-EOL
|
550
|
-
Plays smplayer on a file with an EDL.
|
551
|
-
This gives you a rough estimate to see if your edits are accurate, and is really fast to seek, etc.
|
552
|
-
This is useful because you can't use mplayer on a DVD for accurate timestamps if it has any
|
553
|
-
timestamp splits in it [because some DVD's are buggy]
|
554
|
-
EOL
|
555
|
-
@fast_preview.on_clicked {
|
556
|
-
success, wrote_to_here_fulli = do_create_edited_copy_via_file false, true
|
557
|
-
sleep 0.5 # lodo take out ???
|
558
|
-
background_thread.join if background_thread # let it write out the original fulli, if necessary [?]
|
559
|
-
nice_file = wrote_to_here_fulli
|
560
|
-
run_smplayer_blocking nice_file, nil, "-edl #{normalize_path EdlTempFile}", false, true
|
561
|
-
}
|
562
|
-
end
|
563
|
-
|
564
|
-
# converts to full path, 8.3 if on doze
|
565
|
-
def normalize_path path
|
566
|
-
path = File.expand_path path
|
567
|
-
path = EightThree.convert_path_to_8_3 path if OS.doze?
|
568
|
-
end
|
569
|
-
|
570
|
-
def setup_normal_buttons
|
571
|
-
add_text_line ""
|
572
|
-
|
573
|
-
@mplayer_edl = new_jbutton( "Watch DVD edited (realtime)")
|
574
|
-
@mplayer_edl.tool_tip = "This will watch your DVD in realtime from your computer while skipping/muting questionable scenes."
|
575
|
-
@mplayer_edl.on_clicked {
|
576
|
-
play_mplayer_edl_non_blocking
|
577
|
-
}
|
578
|
-
|
579
|
-
@create = new_jbutton( "Create edited copy of DVD/file on Your Hard Drive" )
|
580
|
-
@create.tool_tip = <<-EOL
|
581
|
-
This takes a file and creates a new file on your hard disk like dvd_name_edited.mpg that you can watch when it's done.
|
582
|
-
The file you create will contain the whole movie edited.
|
583
|
-
It takes quite awhile maybe 2 hours. Sometimes the progress bar will look paused--it typically continues eventually.
|
584
|
-
EOL
|
585
|
-
@create.on_clicked {
|
586
|
-
do_create_edited_copy_via_file false
|
587
|
-
}
|
588
|
-
|
589
|
-
@watch_file_edl = new_jbutton( "Watch movie file edited (realtime)" ) do
|
590
|
-
choose_file_and_edl_and_create_sxs_or_play false
|
591
|
-
end
|
592
|
-
|
593
|
-
if LocalStorage[UpConvertEnglish]
|
594
|
-
add_text_line ''
|
595
|
-
add_open_documentation_button
|
596
|
-
@upconv_line = add_text_line " #{get_current_upconvert_as_phrase}"
|
597
|
-
else
|
598
|
-
@upconv_line = add_text_line ''
|
599
|
-
add_open_documentation_button
|
600
|
-
end
|
601
|
-
|
602
|
-
add_change_upconvert_options_button
|
603
|
-
|
604
|
-
@progress_bar = JProgressBar.new(0, 100)
|
605
|
-
@progress_bar.set_bounds(44,@starting_button_y,@button_width,23)
|
606
|
-
@progress_bar.visible = false
|
607
|
-
@panel.add @progress_bar
|
608
|
-
|
609
|
-
end
|
610
|
-
|
611
|
-
def add_open_documentation_button
|
612
|
-
@open_help_file = new_jbutton("View Sensible Cinema Documentation") do
|
613
|
-
show_in_explorer __DIR__ + "/../documentation" # TODO mac :)
|
614
|
-
end
|
615
|
-
end
|
616
|
-
|
617
|
-
def choose_file_and_edl_and_create_sxs_or_play just_create_dot_edl_file_instead_of_play
|
618
|
-
filename_mpg = new_existing_file_selector_and_select_file( "Pick moviefile (like moviename.mpg or video_ts/anything.ext)")
|
619
|
-
edl_filename = new_existing_file_selector_and_select_file( "Pick an EDL file to use with it", EdlParser::EDL_DIR)
|
620
|
-
assert_ownership_dialog
|
621
|
-
if just_create_dot_edl_file_instead_of_play
|
622
|
-
descriptors = EdlParser.parse_file edl_filename
|
623
|
-
# LODO these timings...DRY up...plus is XBMC the same? what about on a slower computer?
|
624
|
-
# NB these are just for the Side by side EDL's!
|
625
|
-
|
626
|
-
edl_contents = MplayerEdl.convert_to_edl descriptors, add_secs_end = MplayerEndBuffer, MplayerBeginingBuffer, splits = []
|
627
|
-
output_file = filename_mpg.gsub(/\.[^\.]+$/, '') + '.edl' # sanitize...
|
628
|
-
File.write(output_file, edl_contents)
|
629
|
-
raise unless File.exist?(output_file)
|
630
|
-
show_blocking_message_dialog("created #{output_file}")
|
631
|
-
else
|
632
|
-
play_mplayer_edl_non_blocking [filename_mpg, edl_filename]
|
633
|
-
end
|
634
|
-
end
|
635
|
-
|
636
|
-
def we_are_in_upconvert_mode
|
637
|
-
ARGV.index("--upconvert-mode")
|
638
|
-
end
|
639
|
-
|
640
|
-
def initialize be_visible = true
|
641
|
-
super "Sensible-Cinema #{VERSION} (GPL)"
|
642
|
-
force_accept_license_first
|
643
|
-
|
644
|
-
setDefaultCloseOperation JFrame::EXIT_ON_CLOSE # default is exit on close
|
645
|
-
@panel = JPanel.new
|
646
|
-
@buttons = []
|
647
|
-
@panel.set_layout nil
|
648
|
-
add @panel # why can't I just slap these down? panel? huh?
|
649
|
-
@starting_button_y = 40
|
650
|
-
@button_width = 400
|
651
|
-
|
652
|
-
add_text_line "Welcome to Sensible Cinema!"
|
653
|
-
@starting_button_y += 10 # kinder ugly...
|
654
|
-
add_text_line " Rest mouse over buttons for \"help\" type descriptions (tooltips)."
|
655
|
-
add_text_line ""
|
656
|
-
|
657
|
-
setIconImage(ImageIcon.new(__DIR__ + "/../vendor/profs.png").getImage())
|
658
|
-
check_for_various_dependencies
|
659
|
-
set_visible be_visible
|
660
|
-
end
|
661
|
-
|
662
|
-
def setup_default_buttons
|
663
|
-
if we_are_in_upconvert_mode
|
664
|
-
add_play_upconvert_buttons
|
665
|
-
else
|
666
|
-
|
667
|
-
if we_are_in_create_mode
|
668
|
-
setup_advanced_buttons
|
669
|
-
add_text_line 'Contact:'
|
670
|
-
else
|
671
|
-
setup_normal_buttons
|
672
|
-
end
|
673
|
-
|
674
|
-
@upload = new_jbutton("Submit Feedback/Upload new EDL's/Request Help") # keeps this one last! :)
|
675
|
-
@upload.tool_tip = "We welcome all feedback!\nQuestion, comments, request help.\nAlso if you create a new EDL, please submit it back to us so that others can benefit from it later!"
|
676
|
-
@upload.on_clicked {
|
677
|
-
system_non_blocking("start mailto:sensible-cinema@googlegroups.com")
|
678
|
-
system_non_blocking("start http://groups.google.com/group/sensible-cinema")
|
679
|
-
}
|
680
|
-
increment_button_location
|
681
|
-
|
682
|
-
end
|
683
|
-
|
684
|
-
@exit = new_jbutton("Exit", "Exits the application and kills any background processes that are running at all--don't exit unless you are done processing all the way!")
|
685
|
-
@exit.on_clicked {
|
686
|
-
Thread.new { self.close } # don't waste the time to close it :P
|
687
|
-
puts 'Thank you for using Sensible Cinema. Come again!'
|
688
|
-
System.exit 0
|
689
|
-
}
|
690
|
-
|
691
|
-
increment_button_location
|
692
|
-
increment_button_location
|
693
|
-
self
|
694
|
-
|
695
|
-
end
|
696
|
-
|
697
|
-
def run_smplayer_non_blocking *args
|
698
|
-
@background_thread = Thread.new {
|
699
|
-
run_smplayer_blocking *args
|
700
|
-
}
|
701
|
-
end
|
702
|
-
|
703
|
-
def run_smplayer_blocking play_this, title_track_maybe_nil, extra_options, force_use_mplayer, show_subs
|
704
|
-
unless File.exist?(File.expand_path(play_this))
|
705
|
-
raise play_this + ' non existing?' # till these go away in mac :)
|
706
|
-
end
|
707
|
-
|
708
|
-
# -framedrop is for slow CPU's
|
709
|
-
# same with -autosync to try and help it stay in sync... -mc 0.03 is to A/V correct 1s audio per 2s video
|
710
|
-
# -hardframedrop might help but hurts just too much
|
711
|
-
extra_options << " -framedrop "
|
712
|
-
# ?? extra_mplayer_commands << "-mc 0.016" ??
|
713
|
-
extra_options << " -autosync 15 "
|
714
|
-
|
715
|
-
unless show_subs
|
716
|
-
# disable subtitles
|
717
|
-
extra_options << " -nosub -noautosub -forcedsubsonly -sid 1000 "
|
718
|
-
end
|
719
|
-
extra_options << " -alang en "
|
720
|
-
extra_options += " -slang en "
|
721
|
-
|
722
|
-
parent_parent = File.basename(File.dirname(play_this))
|
723
|
-
force_use_mplayer ||= OS.mac?
|
724
|
-
if parent_parent == 'VIDEO_TS'
|
725
|
-
# case d:\yo\VIDEO_TS\title0.vob
|
726
|
-
dvd_device_dir = normalize_path(File.dirname(play_this))
|
727
|
-
if force_use_mplayer
|
728
|
-
extra_options += " -dvd-device \"#{dvd_device_dir}/..\""
|
729
|
-
else
|
730
|
-
# smplayer
|
731
|
-
raise if dvd_device_dir =~ / / && OS.mac? # not accomodated <sniff>
|
732
|
-
extra_options += " -dvd-device #{dvd_device_dir}/.."
|
733
|
-
end
|
734
|
-
play_this = "dvdnav://#{title_track_maybe_nil}"
|
735
|
-
elsif File.exist?(play_this + '/VIDEO_TS')
|
736
|
-
# case d:\ where d:\VIDEO_TS exists [DVD mounted in drive] or mac's /Volumes/YO
|
737
|
-
raise if play_this =~ / / # unexpected
|
738
|
-
extra_options += " -nocache -dvd-device #{play_this}"
|
739
|
-
play_this = "dvdnav://#{title_track_maybe_nil}"
|
740
|
-
else
|
741
|
-
# case g:\video\filename.mpg
|
742
|
-
# leave it the same...
|
743
|
-
end
|
744
|
-
if play_this =~ /dvdnav/ && title_track_maybe_nil
|
745
|
-
extra_options << " -msglevel identify=4 " # prevent smplayer from using *forever* to look up info on DVD's with -identify ...
|
746
|
-
end
|
747
|
-
|
748
|
-
extra_options += " -mouse-movements #{get_upconvert_secondary_settings} " # just in case smplayer also needs -mouse-movements... :) LODO
|
749
|
-
extra_options += " -lavdopts threads=#{OS.cpu_count} " # just in case this helps [supposed to with h.264] # fast *crashes* doze...
|
750
|
-
if force_use_mplayer
|
751
|
-
show_mplayer_instructions_once
|
752
|
-
conf_file = File.expand_path './mplayer_input_conf'
|
753
|
-
File.write conf_file, "ENTER {dvdnav} dvdnav select\nMOUSE_BTN0 {dvdnav} dvdnav select\nMOUSE_BTN0_DBL vo_fullscreen\nMOUSE_BTN2 vo_fullscreen\nKP_ENTER dvdnav select\n" # that KP_ENTER doesn't actually work. Nor the MOUSE_BTN0 on windows. Weird.
|
754
|
-
extra_options += " -font #{File.expand_path('subfont.ttf')} "
|
755
|
-
extra_options += " -volume 100 " # why start low? mplayer why oh why
|
756
|
-
if OS.windows?
|
757
|
-
# direct3d for windows 7 old nvidia cards' sake [yipes] and also dvdnav sake
|
758
|
-
extra_options += " -vo direct3d "
|
759
|
-
conf_file = conf_file[2..-1] # strip off drive letter, which it doesn't seem to like no sir
|
760
|
-
end
|
761
|
-
extra_options += " -fs " # full screen
|
762
|
-
|
763
|
-
upconv = get_upconvert_vf_settings
|
764
|
-
upconv = "-vf #{upconv}" if upconv.present?
|
765
|
-
c = "mplayer #{extra_options} #{upconv} -input conf=\"#{conf_file}\" \"#{play_this}\" "
|
766
|
-
else
|
767
|
-
if OS.windows?
|
768
|
-
extra_options += " -vo direct3d " # more light nvidia...should be ok...
|
769
|
-
end
|
770
|
-
set_smplayer_opts extra_options, get_upconvert_vf_settings, show_subs
|
771
|
-
c = "smplayer_portable \"#{play_this}\" -fullscreen -config-path \"#{File.dirname SMPlayerIniFile}\" "
|
772
|
-
if !we_are_in_create_mode
|
773
|
-
#c += " -close-at-end " # we're still too unstable...
|
774
|
-
end
|
775
|
-
end
|
776
|
-
puts c
|
777
|
-
system_blocking c
|
778
|
-
end
|
779
|
-
|
780
|
-
SMPlayerIniFile = File.expand_path("~/.smplayer/smplayer.ini")
|
781
|
-
|
782
|
-
def set_smplayer_opts to_this, video_, show_subs = false
|
783
|
-
p 'set smplayer extra opts to this:' + to_this
|
784
|
-
old_prefs = File.read(SMPlayerIniFile) rescue ''
|
785
|
-
unless old_prefs.length > 0
|
786
|
-
# LODO double check the rest here...
|
787
|
-
old_prefs = "[advanced]\nmplayer_additional_options=\nmplayer_additional_video_filters=\n[subtitles]\nautoload_sub=false\n[performance]\npriority=3"
|
788
|
-
end
|
789
|
-
raise to_this if to_this =~ /"/ # unexpected, unfortunately... <smplayer bug>
|
790
|
-
assert new_prefs = old_prefs.gsub(/mplayer_additional_options=.*/, "mplayer_additional_options=#{to_this}")
|
791
|
-
assert new_prefs.gsub!(/autoload_sub=.*$/, "autoload_sub=#{show_subs.to_s}")
|
792
|
-
raise if get_upconvert_vf_settings =~ /"/
|
793
|
-
assert new_prefs.gsub!(/mplayer_additional_video_filters=.*$/, "mplayer_additional_video_filters=\"#{get_upconvert_vf_settings}\"")
|
794
|
-
new_prefs.gsub!(/priority=.*$/, "priority=3") # normal priority...scary otherwise! lodo tell smplayer...
|
795
|
-
# enable dvdnav navigation, just for kicks I guess.
|
796
|
-
new_prefs.gsub!(/use_dvdnav=.*$/, "use_dvdnav=true")
|
797
|
-
|
798
|
-
FileUtils.mkdir_p File.dirname(SMPlayerIniFile) # case it doesn't yet exist
|
799
|
-
File.write(SMPlayerIniFile, new_prefs)
|
800
|
-
new_prefs.each_line{|l| print l if l =~ /additional_video/}
|
801
|
-
end
|
802
|
-
|
803
|
-
def create_brand_new_edl
|
804
|
-
drive, volume, dvd_id = choose_dvd_drive_or_file true
|
805
|
-
english_name = get_user_input("Enter a human readable DVD description for #{volume}", volume.gsub('_', ' ').downcase)
|
806
|
-
input = <<-EOL
|
807
|
-
# comments can go after a # on any line, for example this one.
|
808
|
-
"name" => "#{english_name}",
|
809
|
-
|
810
|
-
"mutes" => [
|
811
|
-
# an example line, uncomment the leading "#" to make it active
|
812
|
-
# "0:00:01.0", "0:00:02.0", "profanity", "da..",
|
813
|
-
],
|
814
|
-
|
815
|
-
"blank_outs" => [
|
816
|
-
# an example line, uncomment the leading "#" to make it active
|
817
|
-
# "00:03:00.0" , "00:04:00.0", "violence", "of some sort",
|
818
|
-
],
|
819
|
-
|
820
|
-
"volume_name" => "#{volume}",
|
821
|
-
"disk_unique_id" => "#{dvd_id}",
|
822
|
-
"dvd_title_track" => "1", # the "show DVD info" button will tell you title lengths (typically longest title is the title track)
|
823
|
-
# "dvd_title_track_length" => "6095", # sum length, on the DVD, use the show DVD info button to retrieve it.
|
824
|
-
# "opensubtitles_number" => "1234567",
|
825
|
-
# "not edited out stuff" => "some violence left in...",
|
826
|
-
# "closing thoughts" => "only did the...",
|
827
|
-
# "mplayer_dvd_splits" => ["59:59", "1:04:59"], # or [] if there are none. Additive currently. 12345.6 ok. In mplayer, the DVD timestamp "resets" to zero for some reason, so you need to specify when if you want to use mplayer DVD realtime playback, or use mencoder -edl to split your file. See http://goo.gl/yMfqX
|
828
|
-
EOL
|
829
|
-
# TODO auto-ify above, move docs to a file in documentation.
|
830
|
-
filename = EdlParser::EDL_DIR + "/edls_being_edited/" + english_name.gsub(' ', '_') + '.txt'
|
831
|
-
filename.downcase!
|
832
|
-
File.write(filename, input) unless File.exist?(filename) # lodo let them choose name (?)
|
833
|
-
open_file_to_edit_it filename
|
834
|
-
end
|
835
|
-
|
836
|
-
def system_blocking command, low_prio = false
|
837
|
-
return true if command =~ /^@rem/ # JRUBY-5890 bug
|
838
|
-
if low_prio
|
839
|
-
out = IO.popen(command) # + " 2>&1"
|
840
|
-
low_prio = 64 # from msdn
|
841
|
-
|
842
|
-
if command =~ /(ffmpeg|mencoder)/
|
843
|
-
# XXXX not sure if there's a better way...because some *are* complex and have ampersands...
|
844
|
-
# unfortunately have to check for nil because it could exit too early [?]
|
845
|
-
exe_name = $1 + '.exe'
|
846
|
-
begin
|
847
|
-
p = proc{ ole = WMI::Win32_Process.find(:first, :conditions => {'Name' => exe_name}); sleep 1 unless ole; ole }
|
848
|
-
piddy = p.call || p.call || p.call # we actually do need this to loop...guess we're too quick
|
849
|
-
# but the first time through this still inexplicably fails all 3...odd
|
850
|
-
piddys = WMI::Win32_Process.find(:all, :conditions => {'Name' => exe_name})
|
851
|
-
for piddy in piddys
|
852
|
-
# piddy.SetPriority low_prio # this call can seg fault at times...JRUBY-5422
|
853
|
-
pid = piddy.ProcessId # this doesn't seg fault, tho
|
854
|
-
system_original("vendor\\setpriority -lowest #{pid}") # uses PID for the command line
|
855
|
-
end
|
856
|
-
rescue Exception => e
|
857
|
-
p 'warning, got exception trying to set priority [jruby prob? ...]', e
|
858
|
-
end
|
859
|
-
end
|
860
|
-
print out.read # let it finish
|
861
|
-
out.close
|
862
|
-
$?.exitstatus == 0 # 0 means success
|
863
|
-
else
|
864
|
-
raise command + ' failed' unless system_original command
|
865
|
-
end
|
866
|
-
end
|
867
|
-
|
868
|
-
def system_non_blocking command
|
869
|
-
@background_thread = Thread.new { system_original command }
|
870
|
-
end
|
871
|
-
|
872
|
-
if respond_to?(:system)
|
873
|
-
# make them choose which system call to use explicitly
|
874
|
-
undef system
|
875
|
-
end
|
876
|
-
|
877
|
-
|
878
|
-
def play_dvd_smplayer_unedited use_mplayer_instead, show_instructions, show_subs
|
879
|
-
drive_or_file, dvd_volume_name, dvd_id, edl_path_maybe_nil, descriptors_maybe_nil = choose_dvd_or_file_and_edl_for_it false
|
880
|
-
if descriptors_maybe_nil
|
881
|
-
title_track_maybe_nil = get_title_track(descriptors_maybe_nil, false)
|
882
|
-
end
|
883
|
-
if show_instructions
|
884
|
-
# want this even with smplayer sometimes I guess...
|
885
|
-
show_mplayer_instructions_once
|
886
|
-
end
|
887
|
-
run_smplayer_non_blocking drive_or_file, title_track_maybe_nil, "-osd-fractions 2", use_mplayer_instead, show_subs
|
888
|
-
|
889
|
-
end
|
890
|
-
|
891
|
-
if OS.doze? # avoid spaces :)
|
892
|
-
EdlTempFile = EightThree.convert_path_to_8_3(Dir.tmpdir + '/mplayer.temp.edl')
|
893
|
-
else
|
894
|
-
raise if Dir.tmpdir =~ / / # that would be odd...
|
895
|
-
EdlTempFile = Dir.tmpdir + '/mplayer.temp.edl'
|
896
|
-
end
|
897
|
-
|
898
|
-
def show_mplayer_instructions_once
|
899
|
-
@_show_mplayer_instructions_once ||= show_non_blocking_message_dialog <<-EOL
|
900
|
-
About to run mplayer. To control it, use
|
901
|
-
spacebar : pause,
|
902
|
-
double clicky/right click : toggle full screen,
|
903
|
-
arrow keys (left, right, up down, pg up, pg dn) to seek/scan
|
904
|
-
/ and * : inc/dec volume.
|
905
|
-
'o' key: turn on on-screen-display timestamps (note: the OSD timestamps [upper left] are 30 fps so will need to be converted to use).
|
906
|
-
'v' key: turn off subtitles.
|
907
|
-
'.' key: step one frame.
|
908
|
-
# key: change audio language track
|
909
|
-
EOL
|
910
|
-
end
|
911
|
-
|
912
|
-
MplayerBeginingBuffer = 1.0
|
913
|
-
MplayerEndBuffer = 0.0
|
914
|
-
|
915
|
-
def play_mplayer_edl_non_blocking optional_file_with_edl_path = nil
|
916
|
-
extra_mplayer_commands = []
|
917
|
-
if optional_file_with_edl_path
|
918
|
-
drive_or_file, edl_path = optional_file_with_edl_path
|
919
|
-
dvd_id = NonDvd # fake it out...LODO a bit smelly
|
920
|
-
else
|
921
|
-
drive_or_file, dvd_volume_name, dvd_id, edl_path, descriptors = choose_dvd_or_file_and_edl_for_it
|
922
|
-
end
|
923
|
-
start_add_this_to_all_ts = 0
|
924
|
-
if edl_path # some don't care...
|
925
|
-
descriptors = EdlParser.parse_file edl_path
|
926
|
-
title_track = get_title_track(descriptors)
|
927
|
-
splits = descriptors['mplayer_dvd_splits']
|
928
|
-
end
|
929
|
-
|
930
|
-
if dvd_id == NonDvd && !(File.basename(File.dirname(drive_or_file)) == 'VIDEO_TS') # VOB's...always start at 0
|
931
|
-
# check if starts offset...
|
932
|
-
all = `ffmpeg -i "#{drive_or_file}" 2>&1`
|
933
|
-
# Duration: 01:35:49.59, start: 600.000000
|
934
|
-
all =~ /Duration.*start: ([\d\.]+)/
|
935
|
-
start = $1.to_f
|
936
|
-
if start > 1 # LODO huh? dvd's themselves start at 0.3 [sintel]?
|
937
|
-
show_non_blocking_message_dialog "Warning: file seems to start at an extra offset, adding it to the timestamps... #{start}
|
938
|
-
maybe not compatible with XBMC, if that's what you use, and you probably don't" # TODO test it XBMC...
|
939
|
-
start_add_this_to_all_ts = start
|
940
|
-
end
|
941
|
-
splits = []
|
942
|
-
else
|
943
|
-
if splits == nil
|
944
|
-
show_blocking_message_dialog("warning: edit list does not contain mplayer replay information [mplayer_dvd_splits] so edits past a certain time period might not won't work ( http://goo.gl/yMfqX ).")
|
945
|
-
splits = []
|
946
|
-
end
|
947
|
-
end
|
948
|
-
|
949
|
-
if edl_path
|
950
|
-
splits.map!{|s| EdlParser.translate_string_to_seconds(s) }
|
951
|
-
edl_contents = MplayerEdl.convert_to_edl descriptors, add_secs_end = MplayerEndBuffer, add_secs_begin = MplayerBeginingBuffer, splits, start_add_this_to_all_ts # add a sec to mutes to accomodate for mplayer's oddness..
|
952
|
-
File.write(EdlTempFile, edl_contents)
|
953
|
-
extra_mplayer_commands << "-edl #{File.expand_path EdlTempFile}"
|
954
|
-
end
|
955
|
-
|
956
|
-
run_smplayer_non_blocking drive_or_file, title_track, extra_mplayer_commands.join(' '), false, false
|
957
|
-
end
|
958
|
-
|
959
|
-
def assert_ownership_dialog
|
960
|
-
message = "Do you certify you own the DVD this came of and have it in your possession?"
|
961
|
-
title = "Verify ownership"
|
962
|
-
returned = JOptionPane.showConfirmDialog self, message, title, JOptionPane::YES_NO_CANCEL_OPTION
|
963
|
-
assert_confirmed_dialog returned, nil
|
964
|
-
end
|
965
|
-
|
966
|
-
# returns 0,1,2 for yes, no, cancel equivs
|
967
|
-
def show_select_buttons_prompt message, names_hash
|
968
|
-
old = ['no', 'yes', 'ok'].map{|name| 'OptionPane.' + name + 'ButtonText'}.map{|name| [name, UIManager.get(name)]}
|
969
|
-
if names_hash[:yes]
|
970
|
-
UIManager.put("OptionPane.yesButtonText", names_hash[:yes])
|
971
|
-
end
|
972
|
-
if names_hash[:no]
|
973
|
-
UIManager.put("OptionPane.noButtonText", names_hash[:no])
|
974
|
-
end
|
975
|
-
# if names_hash[:ok] # ???
|
976
|
-
# UIManager.put("OptionPane.okButtonText", names_hash[:ok])
|
977
|
-
# end
|
978
|
-
if names_hash[:cancel]
|
979
|
-
UIManager.put("OptionPane.noButtonText", names_hash[:cancel])
|
980
|
-
end
|
981
|
-
returned = JOptionPane.showConfirmDialog self, message, title, JOptionPane::YES_NO_CANCEL_OPTION
|
982
|
-
old.each{|name, old_setting| UIManager.put(name, old_setting)}
|
983
|
-
returned
|
984
|
-
end
|
985
|
-
|
986
|
-
def require_blocking_license_accept_dialog program, license_name, license_url_should_also_be_embedded_by_you_in_message,
|
987
|
-
title = 'Confirm Acceptance of License Agreement', message = nil
|
988
|
-
puts 'Please confirm license agreement in open window.'
|
989
|
-
# cancel button stays the same...
|
990
|
-
|
991
|
-
message ||= "Sensible Cinema requires a separately installed program (#{program}), not yet installed.
|
992
|
-
You can install this program manually to the vendor/cache subdirectory, or Sensible Cinema can download it for you.
|
993
|
-
By clicking accept, below, you are confirming that you have read and agree to be bound by the
|
994
|
-
terms of its license (the #{license_name}), located at #{license_url_should_also_be_embedded_by_you_in_message}.
|
995
|
-
Click 'View License' to view it. If you do not agree to these terms, click 'Cancel'. You also agree that this is a
|
996
|
-
separate program, with its own distribution, license, ownership and copyright.
|
997
|
-
You agree that you are responsible for the download and use of this program, within sensible cinema or otherwise."
|
998
|
-
returned = show_select_buttons_prompt message, :yes => 'Accept', :no => "View #{license_name}"
|
999
|
-
assert_confirmed_dialog returned, license_url_should_also_be_embedded_by_you_in_message
|
1000
|
-
p 'confirmation of sensible cinema related license saved of: ' + license_name
|
1001
|
-
throw unless returned == 0
|
1002
|
-
|
1003
|
-
end
|
1004
|
-
|
1005
|
-
def assert_confirmed_dialog returned, license_url_should_also_be_embedded_by_you_in_message
|
1006
|
-
# 1 is view button was clicked
|
1007
|
-
# 0 is accept
|
1008
|
-
# 2 is cancel
|
1009
|
-
if returned == 1
|
1010
|
-
if license_url_should_also_be_embedded_by_you_in_message
|
1011
|
-
system_non_blocking("start #{license_url_should_also_be_embedded_by_you_in_message}")
|
1012
|
-
puts "Please restart after reading license agreement, to be able to then accept it."
|
1013
|
-
end
|
1014
|
-
System.exit 0
|
1015
|
-
end
|
1016
|
-
if returned == 2
|
1017
|
-
p 'license not accepted...exiting'
|
1018
|
-
System.exit 1
|
1019
|
-
end
|
1020
|
-
if returned == -1
|
1021
|
-
p 'license exited early...exiting'
|
1022
|
-
System.exit 1
|
1023
|
-
end
|
1024
|
-
end
|
1025
|
-
|
1026
|
-
def print *args
|
1027
|
-
Kernel.print *args # avoid bin\sensible-cinema.rb:83:in `system_blocking': cannot convert instance of class org.jruby.RubyString to class java.awt.Graphics (TypeError)
|
1028
|
-
end
|
1029
|
-
|
1030
|
-
def download_7zip
|
1031
|
-
Dir.mkdir('./vendor/cache') unless File.directory? 'vendor/cache' # development may not have it created yet... [?]
|
1032
|
-
unless File.exist? 'vendor/cache/7za.exe'
|
1033
|
-
Dir.chdir('vendor/cache') do
|
1034
|
-
print 'downloading unzipper (7zip--400K) ...'
|
1035
|
-
MainWindow.download("http://downloads.sourceforge.net/project/sevenzip/7-Zip/9.20/7za920.zip", "7za920.zip")
|
1036
|
-
system_blocking("../unzip.exe -o 7za920.zip") # -o means "overwrite" without prompting
|
1037
|
-
end
|
1038
|
-
end
|
1039
|
-
end
|
1040
|
-
|
1041
|
-
def download_zip_file_and_extract english_name, url, to_this
|
1042
|
-
download_7zip
|
1043
|
-
Dir.chdir('vendor/cache') do
|
1044
|
-
file_name = url.split('/')[-1]
|
1045
|
-
print "downloading #{english_name} ..."
|
1046
|
-
MainWindow.download(url, file_name)
|
1047
|
-
system_blocking("7za e #{file_name} -y -o#{to_this}")
|
1048
|
-
puts 'done ' + english_name
|
1049
|
-
# creates vendor/cache/mencoder/mencoder.exe...
|
1050
|
-
end
|
1051
|
-
end
|
1052
|
-
|
1053
|
-
def check_for_exe windows_full_loc, unix_name
|
1054
|
-
# in windows, that exe *at that location* must exist...
|
1055
|
-
if OS.windows?
|
1056
|
-
File.exist?(windows_full_loc)
|
1057
|
-
else
|
1058
|
-
require 'lib/check_installed_mac.rb'
|
1059
|
-
if !CheckInstalledMac.check_for_installed(unix_name)
|
1060
|
-
exit 1 # it'll have already displayed a message...
|
1061
|
-
else
|
1062
|
-
true
|
1063
|
-
end
|
1064
|
-
end
|
1065
|
-
end
|
1066
|
-
|
1067
|
-
def check_for_various_dependencies
|
1068
|
-
if we_are_in_create_mode
|
1069
|
-
if !check_for_exe('vendor/cache/mencoder/mencoder.exe', 'mencoder')
|
1070
|
-
require_blocking_license_accept_dialog 'mplayer', 'gplv2', 'http://www.gnu.org/licenses/gpl-2.0.html', "Appears that you need to install a dependency: mplayer with mencoder."
|
1071
|
-
download_zip_file_and_extract "Mplayer/mencoder (6MB)", "http://sourceforge.net/projects/mplayer-win32/files/MPlayer%20and%20MEncoder/revision%2033883/MPlayer-rtm-svn-33883.7z", "mencoder"
|
1072
|
-
end
|
1073
|
-
end
|
1074
|
-
|
1075
|
-
# runtime dependencies, at least as of today...
|
1076
|
-
ffmpeg_exe_loc = File.expand_path('vendor/cache/ffmpeg/ffmpeg.exe')
|
1077
|
-
if !check_for_exe(ffmpeg_exe_loc, 'ffmpeg')
|
1078
|
-
require_blocking_license_accept_dialog 'ffmpeg', 'gplv2', 'http://www.gnu.org/licenses/gpl-2.0.html', "Appears that you need to install a dependency: ffmpeg."
|
1079
|
-
download_zip_file_and_extract "ffmpeg (5MB)", "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-git-335bbe4-win32-static.7z", "ffmpeg"
|
1080
|
-
end
|
1081
|
-
if OS.mac?
|
1082
|
-
check_for_exe("mplayer", "mplayer") # mencoder and mplayer are separate for mac... [this checks for mac's mplayerx, too]
|
1083
|
-
else
|
1084
|
-
path = RubyWhich.new.which('smplayer_portable')
|
1085
|
-
if(path.length == 0)
|
1086
|
-
# this one has its own installer...
|
1087
|
-
show_blocking_message_dialog("It appears that you need to install a pre-requisite dependency: MPlayer for Windows (MPUI).
|
1088
|
-
Click ok to be directed to its download website, where you can download and install it (recommend: MPUI....Full-Package.exe),
|
1089
|
-
then restart sensible cinema. NB that it takes awhile to install. Sorry about that.",
|
1090
|
-
"Lacking dependency", JOptionPane::ERROR_MESSAGE)
|
1091
|
-
open_url_to_view_it_non_blocking "http://code.google.com/p/mulder/downloads/list?can=2&q=MPlayer&sort=-uploaded&colspec=Filename%20Summary%20Type%20Uploaded%20Size%20DownloadCount"
|
1092
|
-
System.exit 0
|
1093
|
-
end
|
1094
|
-
end
|
1095
|
-
end
|
1096
|
-
|
1097
|
-
def open_url_to_view_it_non_blocking url
|
1098
|
-
if OS.windows?
|
1099
|
-
system_non_blocking("start #{url.gsub('&', '^&')}") # LODO would launchy help/work here with the full url?
|
1100
|
-
else
|
1101
|
-
system_non_blocking "#{OS.open_file_command} \"#{url}\"" # LODO test
|
1102
|
-
end
|
1103
|
-
end
|
1104
|
-
|
1105
|
-
def open_file_to_edit_it filename, start_minimized=false
|
1106
|
-
if OS.windows?
|
1107
|
-
if start_minimized
|
1108
|
-
system_non_blocking "start /min notepad \"#{filename}\""
|
1109
|
-
else
|
1110
|
-
system_non_blocking "notepad \"#{filename}\""
|
1111
|
-
end
|
1112
|
-
else
|
1113
|
-
system_non_blocking "open -a TextEdit \"#{filename}\""
|
1114
|
-
end
|
1115
|
-
end
|
1116
|
-
|
1117
|
-
def repeat_last_copy_dvd_to_hard_drive
|
1118
|
-
generate_and_run_bat_file *LocalStorage['last_params']
|
1119
|
-
end
|
1120
|
-
|
1121
|
-
def new_nonexisting_filechooser title = nil, default_dir = nil
|
1122
|
-
out = JFileChooser.new
|
1123
|
-
out.set_title title
|
1124
|
-
if default_dir
|
1125
|
-
out.set_current_directory JFile.new(default_dir)
|
1126
|
-
end
|
1127
|
-
out
|
1128
|
-
end
|
1129
|
-
|
1130
|
-
def show_blocking_message_dialog(message, title = message.split("\n")[0], style= JOptionPane::INFORMATION_MESSAGE)
|
1131
|
-
JOptionPane.showMessageDialog(nil, message, title, style)
|
1132
|
-
true
|
1133
|
-
end
|
1134
|
-
|
1135
|
-
# call dispose on this to close it if it hasn't been canceled yet...
|
1136
|
-
def show_non_blocking_message_dialog message, close_button_text = 'Close'
|
1137
|
-
# lodo NonBlockingDialog it can get to the top instead of being so buried...
|
1138
|
-
NonBlockingDialog.new(message, close_button_text)
|
1139
|
-
end
|
1140
|
-
|
1141
|
-
include_class javax.swing.UIManager
|
1142
|
-
|
1143
|
-
def get_user_input(message, default = '', cancel_ok = false)
|
1144
|
-
received = JOptionPane.showInputDialog(message, default)
|
1145
|
-
unless cancel_ok
|
1146
|
-
raise 'user cancelled' unless received
|
1147
|
-
end
|
1148
|
-
received
|
1149
|
-
end
|
1150
|
-
|
1151
|
-
def show_copy_pastable_string(message, value)
|
1152
|
-
RubyClip.set_clipboard value
|
1153
|
-
get_user_input message + " (has been copied to clipboard)", value, true
|
1154
|
-
end
|
1155
|
-
|
1156
|
-
def parse_edl path
|
1157
|
-
EdlParser.parse_file path
|
1158
|
-
end
|
1159
|
-
|
1160
|
-
def get_freespace path
|
1161
|
-
JFile.new(File.dirname(path)).get_usable_space
|
1162
|
-
end
|
1163
|
-
|
1164
|
-
def new_existing_file_selector_and_select_file title, dir=nil
|
1165
|
-
out = FileDialog.new(self, title, FileDialog::LOAD)
|
1166
|
-
out.set_title title
|
1167
|
-
dir ||= LocalStorage[caller.inspect]
|
1168
|
-
out.set_directory dir.to_filename if dir
|
1169
|
-
got = out.go
|
1170
|
-
raise 'cancelled choosing existing file method' unless got # I think we always want to raise...
|
1171
|
-
LocalStorage[caller.inspect] = File.dirname(got)
|
1172
|
-
got
|
1173
|
-
end
|
1174
|
-
|
1175
|
-
def choose_dvd_or_file_and_edl_for_it force_choose_edl_file_if_no_easy_match = true
|
1176
|
-
drive_or_file, dvd_volume_name, dvd_id = choose_dvd_drive_or_file false
|
1177
|
-
|
1178
|
-
unless @_edit_list_path # cache file selection...
|
1179
|
-
edit_list_path = EdlParser.single_edit_list_matches_dvd(dvd_id)
|
1180
|
-
if !edit_list_path && force_choose_edl_file_if_no_easy_match
|
1181
|
-
edit_list_path = new_existing_file_selector_and_select_file("Please pick a DVD Edit List File (none or more than one were found that seem to match #{dvd_volume_name})--may need to create one for it", EdlParser::EDL_DIR)
|
1182
|
-
raise 'cancelled choosing an EDL' unless edit_list_path
|
1183
|
-
end
|
1184
|
-
@_edit_list_path = edit_list_path
|
1185
|
-
end
|
1186
|
-
|
1187
|
-
if @_edit_list_path
|
1188
|
-
# reload it every time just in case it has changed on disk
|
1189
|
-
descriptors = nil
|
1190
|
-
while(!descriptors)
|
1191
|
-
begin
|
1192
|
-
descriptors = parse_edl @_edit_list_path
|
1193
|
-
rescue SyntaxError => e
|
1194
|
-
puts e
|
1195
|
-
show_blocking_message_dialog("this file has an error--please fix then hit ok: \n" + @_edit_list_path + "\n " + e)
|
1196
|
-
end
|
1197
|
-
end
|
1198
|
-
end
|
1199
|
-
[drive_or_file, dvd_volume_name, dvd_id, @_edit_list_path, descriptors]
|
1200
|
-
end
|
1201
|
-
|
1202
|
-
def get_title_track descriptors, use_default_of_one = true
|
1203
|
-
given = descriptors["dvd_title_track"]
|
1204
|
-
given ||= "1" if use_default_of_one
|
1205
|
-
given
|
1206
|
-
end
|
1207
|
-
|
1208
|
-
def get_import_from_filename dvd_title, dvd_title_track
|
1209
|
-
@_get_import_from_filename ||=
|
1210
|
-
begin
|
1211
|
-
new_existing_file_selector_and_select_file "Please choose the file that is your ripped equivalent of #{dvd_title} (title track #{dvd_title_track}) (.mpg or .ts--see file documentation/how_to_get_files_from_dvd.txt)"
|
1212
|
-
end
|
1213
|
-
end
|
1214
|
-
|
1215
|
-
def get_save_to_filename dvd_title
|
1216
|
-
@_get_save_to_filename ||=
|
1217
|
-
begin
|
1218
|
-
fc = new_nonexisting_filechooser "Pick where to save #{dvd_title} edited version to"
|
1219
|
-
save_to_file_name = dvd_title + ' edited version'
|
1220
|
-
save_to_file_name = save_to_file_name.gsub(' ', '_').gsub( /\W/, '') + ".avi" # no punctuation or spaces for now, to not complicate...
|
1221
|
-
fc.set_file(get_drive_with_most_space_with_slash + save_to_file_name)
|
1222
|
-
save_to = fc.go
|
1223
|
-
raise 'no spaces allowed yet' if save_to =~ / /
|
1224
|
-
begin
|
1225
|
-
a = File.open(File.dirname(save_to) + "/test_file_to_see_if_we_have_permission_to_write_to_this_folder", "w")
|
1226
|
-
a.close
|
1227
|
-
File.delete a.path
|
1228
|
-
rescue Errno::EACCES => e
|
1229
|
-
show_blocking_message_dialog "unable to write to that directory, please pick again: " + e.to_s
|
1230
|
-
raise 'pick again!'
|
1231
|
-
end
|
1232
|
-
freespace = get_freespace(save_to)
|
1233
|
-
if freespace < 8_000_000_000
|
1234
|
-
show_blocking_message_dialog("Warning: there may not be enough space on the disk for #{save_to}
|
1235
|
-
(depending on DVD size, you may need around 10G free--you have #{freespace/1_000_000_000}GB free). Click OK to continue.")
|
1236
|
-
end
|
1237
|
-
save_to.gsub(/\.avi$/, '')
|
1238
|
-
end
|
1239
|
-
end
|
33
|
+
raise 'need newer jruby!' unless RUBY_DESCRIPTION >= 'jruby 1.6.0' # may not need this since we still have to accomodate for so many...oddities in it :P
|
1240
34
|
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
if watch_unedited
|
1246
|
-
# reset them
|
1247
|
-
descriptors['mutes'] = descriptors['blank_outs'] = []
|
1248
|
-
end
|
1249
|
-
|
1250
|
-
# LODO allow for spaces in the save_to filename
|
1251
|
-
if should_prompt_for_start_and_end_times
|
1252
|
-
# only show this message once :)
|
1253
|
-
@show_block ||= show_blocking_message_dialog(<<-EOL, "Preview")
|
1254
|
-
Ok, let's preview just a portion of it.
|
1255
|
-
Note that you'll want to preview a section that wholly includes a deleted section in it.
|
1256
|
-
For example, if it mutes from second 1 to second 10, you'll want to play from 00:00 to 00:12 or what not.
|
1257
|
-
Also note that the first time you preview a section of a video, it will take a long time (like an hour) as it sets up the entire video for processing.
|
1258
|
-
Subsequent previews will be faster, though, as long as you use the same filename, as it won't have to re-set it up for processing.
|
1259
|
-
Also note that if you change your edit list, you'll need to close, and restart the video to be able to see it with your new settings.
|
1260
|
-
EOL
|
1261
|
-
old_start = LocalStorage['start_time']
|
1262
|
-
start_time = get_user_input("At what point in the video would you like to start your preview? (like 01:00 for starting at 1 minute)", LocalStorage['start_time'])
|
1263
|
-
default_end = LocalStorage['end_time']
|
1264
|
-
if start_time and start_time != old_start
|
1265
|
-
default_end = EdlParser.translate_string_to_seconds(start_time) + 10
|
1266
|
-
default_end = EdlParser.translate_time_to_human_readable(default_end)
|
1267
|
-
end
|
1268
|
-
end_time = get_user_input("At what point in the video would you like to finish your preview? (like 02:00 for ending at the 2 minute mark)", default_end)
|
1269
|
-
unless start_time and end_time
|
1270
|
-
JOptionPane.showMessageDialog(nil, " Please choose start and end", "Failed", JOptionPane::ERROR_MESSAGE)
|
1271
|
-
return
|
1272
|
-
end
|
1273
|
-
LocalStorage['start_time'] = start_time
|
1274
|
-
LocalStorage['end_time'] = end_time
|
1275
|
-
end
|
1276
|
-
dvd_friendly_name = descriptors['name']
|
1277
|
-
unless dvd_friendly_name
|
1278
|
-
_dbg
|
1279
|
-
drive_or_file, dvd_volume_name, dvd_id, edit_list_path, descriptors = choose_dvd_or_file_and_edl_for_it
|
1280
|
-
|
1281
|
-
descriptors = parse_edl(edit_list_path)
|
1282
|
-
raise 'no dvd name in EDL?'
|
1283
|
-
end
|
1284
|
-
|
1285
|
-
dvd_title_track = get_title_track(descriptors)
|
1286
|
-
if dvd_id == NonDvd
|
1287
|
-
file_from = drive_or_file
|
1288
|
-
else
|
1289
|
-
file_from = get_import_from_filename dvd_friendly_name, dvd_title_track # we don't even care about the drive letter anymore...
|
1290
|
-
end
|
1291
|
-
show_blocking_message_dialog("warning: file #{file_from} is not a .mpg or .ts file--it may not work properly all the way--if it's mkv and fails consider first converting to ts by using tsmuxer.") unless file_from =~ /\.(ts|mpg|mpeg)$/i
|
1292
|
-
save_to_edited = get_save_to_filename dvd_friendly_name
|
1293
|
-
fulli = MencoderWrapper.calculate_fulli_filename save_to_edited
|
1294
|
-
if exit_early_if_fulli_exists
|
1295
|
-
if fulli_dot_done_file_exists? save_to_edited
|
1296
|
-
return [true, fulli]
|
1297
|
-
end
|
1298
|
-
# make it create a dummy response file for us :)
|
1299
|
-
start_time = "00:00"
|
1300
|
-
end_time = "00:01"
|
1301
|
-
end
|
1302
|
-
|
1303
|
-
should_run_mplayer = should_prompt_for_start_and_end_times || exit_early_if_fulli_exists
|
1304
|
-
require_deletion_entry = true unless watch_unedited
|
1305
|
-
generate_and_run_bat_file save_to_edited, edit_list_path, descriptors, file_from, dvd_friendly_name, start_time, end_time, dvd_title_track, should_run_mplayer, require_deletion_entry
|
1306
|
-
[false, fulli] # false means it's running in a background thread :P
|
1307
|
-
end
|
1308
|
-
|
1309
|
-
def get_drive_with_most_space_with_slash
|
1310
|
-
DriveInfo.get_drive_with_most_space_with_slash
|
1311
|
-
end
|
1312
|
-
|
1313
|
-
def fulli_dot_done_file_exists? save_to_edited
|
1314
|
-
fulli = MencoderWrapper.calculate_fulli_filename save_to_edited
|
1315
|
-
File.exist?(fulli + ".done") # stinky!
|
1316
|
-
end
|
1317
|
-
|
1318
|
-
# to make it stubbable :)
|
1319
|
-
def get_mencoder_commands descriptors, file_from, save_to, start_time, end_time, dvd_title_track, require_deletion_entry
|
1320
|
-
delete_partials = true unless start_time # in case anybody wants to look really really close [?]
|
1321
|
-
MencoderWrapper.get_bat_commands descriptors, file_from, save_to, start_time, end_time, dvd_title_track, delete_partials, require_deletion_entry
|
1322
|
-
end
|
1323
|
-
|
1324
|
-
def generate_and_run_bat_file save_to, edit_list_path, descriptors, file_from, dvd_title, start_time, end_time, dvd_title_track, run_mplayer, require_deletion_entry
|
1325
|
-
LocalStorage['last_params'] = [save_to, edit_list_path, descriptors, file_from, dvd_title, start_time, end_time, dvd_title_track, run_mplayer, require_deletion_entry]
|
1326
|
-
begin
|
1327
|
-
commands = get_mencoder_commands descriptors, file_from, save_to, start_time, end_time, dvd_title_track, require_deletion_entry
|
1328
|
-
rescue MencoderWrapper::TimingError => e
|
1329
|
-
show_blocking_message_dialog("Appears you chose a time frame with no deletion segment in it--please try again:" + e)
|
1330
|
-
return
|
1331
|
-
rescue Errno::EACCES => e
|
1332
|
-
show_blocking_message_dialog("Appears a file on the system is locked: perhaps you need to close down some instance of mplayer?" + e)
|
1333
|
-
return
|
1334
|
-
end
|
1335
|
-
temp_dir = Dir.tmpdir
|
1336
|
-
temp_file = temp_dir + '/vlc.temp.bat'
|
1337
|
-
File.write(temp_file, commands)
|
1338
|
-
popup_message = <<-EOL
|
1339
|
-
Applying #{File.basename edit_list_path}
|
1340
|
-
to #{file_from} (#{dvd_title}).
|
1341
|
-
Copying to #{save_to}.
|
1342
|
-
EOL
|
1343
|
-
if !fulli_dot_done_file_exists?(save_to)
|
1344
|
-
popup_message += "This could take quite awhile (several hours), and will prompt you with a chime noise when it is done.\n
|
1345
|
-
You can close this window and minimize sensible cinema and continue using your computer while it runs in the background.\n"
|
1346
|
-
end
|
1347
|
-
|
1348
|
-
if !start_time
|
1349
|
-
# assume a full run..
|
1350
|
-
popup_message += <<-EOL
|
1351
|
-
NB that the created file will be playable only with VLC (possibly also with smplayer),
|
1352
|
-
but probably not with windows media player.
|
1353
|
-
EOL
|
1354
|
-
end
|
1355
|
-
|
1356
|
-
popup = show_non_blocking_message_dialog(popup_message, "OK")
|
1357
|
-
|
1358
|
-
# allow our popups to still be serviced while it is running
|
1359
|
-
@background_thread = Thread.new { run_batch_file_commands_and_use_output_somehow commands, save_to, file_from, run_mplayer }
|
1360
|
-
close_when_done(@background_thread, popup)
|
1361
|
-
# LODO warn if they will overwrite a file in the end...
|
1362
|
-
end
|
1363
|
-
|
1364
|
-
attr_accessor :background_thread, :buttons
|
1365
|
-
|
1366
|
-
def run_batch_file_commands_and_use_output_somehow batch_commands, save_to, file_from, run_mplayer_after_done
|
1367
|
-
@buttons.each{|b| b.set_enabled false}
|
1368
|
-
success = true
|
1369
|
-
lines = batch_commands.lines.to_a
|
1370
|
-
total_size = lines.length.to_f
|
1371
|
-
@progress_bar.visible=true
|
1372
|
-
@progress_bar.set_value(10) # start at 10% always, so they can see something.
|
1373
|
-
lines.each_with_index{|line, idx|
|
1374
|
-
if success
|
1375
|
-
puts "running #{line}"
|
1376
|
-
success = system_blocking(line, true)
|
1377
|
-
if !success
|
1378
|
-
puts "\n", 'line failed: ' + line + "\n" + ' see troubleshooting section in README.txt file! ignoring further processing commands...'
|
1379
|
-
end
|
1380
|
-
end
|
1381
|
-
@progress_bar.set_value(10 + idx/total_size*90)
|
1382
|
-
}
|
1383
|
-
@progress_bar.visible=false
|
1384
|
-
@buttons.each{|b| b.set_enabled true}
|
1385
|
-
if success
|
1386
|
-
saved_to = save_to + '.avi'
|
1387
|
-
if run_mplayer_after_done
|
1388
|
-
run_smplayer_non_blocking saved_to, nil, '', false, false
|
1389
|
-
else
|
1390
|
-
if File.exist?(saved_to) && (File.size(saved_to).to_f/File.size(file_from) < 0.5) # less than 50% size is suspicious...indeed...check if exists for unit tests.
|
1391
|
-
show_blocking_message_dialog("Warning: file size differs by more than 50%--it's possible that transcoding failed somehow")
|
1392
|
-
end
|
1393
|
-
show_in_explorer saved_to
|
1394
|
-
PlayAudio.play(File.expand_path(File.dirname(__FILE__)) + "/../vendor/music.wav")
|
1395
|
-
msg = "Done--you may now watch file\n #{saved_to}\n in VLC player (or possibly smplayer)"
|
1396
|
-
puts msg # for being able to tell it's done on the command line
|
1397
|
-
show_blocking_message_dialog msg
|
1398
|
-
show_in_explorer saved_to # and again, just for kicks [?]
|
1399
|
-
end
|
1400
|
-
else
|
1401
|
-
show_blocking_message_dialog("Failed--please examine console output and report back!\nAlso consult the documentation/troubleshooting file.", "Failed", JOptionPane::ERROR_MESSAGE)
|
1402
|
-
end
|
1403
|
-
end
|
1404
|
-
|
1405
|
-
def show_in_explorer filename
|
1406
|
-
begin
|
1407
|
-
system_blocking "explorer /e,/select,\"#{File.expand_path(filename).to_filename}\"" # command returns immediately...
|
1408
|
-
rescue => why_does_this_happen_ignore_this_exception_it_probably_actually_succeeded
|
1409
|
-
end
|
1410
|
-
end
|
1411
|
-
|
1412
|
-
def get_disk_chooser_window names
|
1413
|
-
GetDisk.new(self, names)
|
1414
|
-
end
|
1415
|
-
|
1416
|
-
NonDvd = 'non dvd has no dvdid' # we need it for convenience, say you want to go through your indexed vids and convert them all?
|
1417
|
-
|
1418
|
-
# returns e:\, volume_name, dvd_id
|
1419
|
-
# or full_path.mkv, filename, ''
|
1420
|
-
def choose_dvd_drive_or_file force_choose_only_dvd_drive
|
1421
|
-
opticals = DriveInfo.get_dvd_drives_as_openstruct
|
1422
|
-
if @saved_opticals == opticals && @_choose_dvd_drive_or_file
|
1423
|
-
# memoize...if disks haven't changed :)
|
1424
|
-
return @_choose_dvd_drive_or_file
|
1425
|
-
else
|
1426
|
-
@saved_opticals = opticals # save currently mounted disk list, so we know if we should re-select later...
|
1427
|
-
# is this ok for os x?
|
1428
|
-
end
|
1429
|
-
|
1430
|
-
has_at_least_one_dvd_inserted = opticals.find{|d| d.VolumeName }
|
1431
|
-
if !has_at_least_one_dvd_inserted && force_choose_only_dvd_drive
|
1432
|
-
show_blocking_message_dialog 'insert a dvd first'
|
1433
|
-
raise 'no dvd found'
|
1434
|
-
end
|
1435
|
-
names = opticals.map{|d| d.Name + "\\" + " (" + (d.VolumeName || 'Insert DVD to use') + ")"}
|
1436
|
-
if !force_choose_only_dvd_drive && !has_at_least_one_dvd_inserted
|
1437
|
-
names += ['No DVD mounted so choose Local File (or insert DVD, re-try)'] # LODO cannot read it...
|
1438
|
-
used_local_file_option = true
|
1439
|
-
end
|
1440
|
-
|
1441
|
-
count = 0
|
1442
|
-
opticals.each{|d| count += 1 if d.VolumeName}
|
1443
|
-
if count == 1 && !used_local_file_option
|
1444
|
-
# just choose it if there's only one disk available..
|
1445
|
-
p 'selecting only disk present in the various DVD drives'
|
1446
|
-
selected_idx = opticals.index{|d| d.VolumeName}
|
1447
|
-
unless selected_idx
|
1448
|
-
show_blocking_message_dialog "Please insert a disk first"
|
1449
|
-
raise 'inset disk'
|
1450
|
-
end
|
1451
|
-
|
1452
|
-
else
|
1453
|
-
dialog = get_disk_chooser_window names
|
1454
|
-
dialog.setSize 200, 125
|
1455
|
-
dialog.show
|
1456
|
-
selected_idx = dialog.selected_idx
|
1457
|
-
end
|
1458
|
-
|
1459
|
-
if selected_idx
|
1460
|
-
if used_local_file_option
|
1461
|
-
raise unless selected_idx == 0 # it was our only option...
|
1462
|
-
filename = new_existing_file_selector_and_select_file("Select yer previously grabbed from DVD file")
|
1463
|
-
assert_ownership_dialog
|
1464
|
-
return [filename, File.basename(filename), NonDvd]
|
1465
|
-
else
|
1466
|
-
disk = opticals[selected_idx]
|
1467
|
-
out = show_non_blocking_message_dialog "calculating current disk's unique id...if this freezes clean your disk..." # useful, believe it or not
|
1468
|
-
dvd_id = DriveInfo.md5sum_disk(disk.MountPoint)
|
1469
|
-
out.dispose
|
1470
|
-
@_choose_dvd_drive_or_file = [disk.MountPoint, opticals[selected_idx].VolumeName, dvd_id]
|
1471
|
-
return @_choose_dvd_drive_or_file
|
1472
|
-
end
|
1473
|
-
else
|
1474
|
-
raise 'did not select a drive...'
|
1475
|
-
end
|
1476
|
-
end
|
1477
|
-
|
1478
|
-
end
|
1479
|
-
|
1480
|
-
class GetDisk < JDialog
|
1481
|
-
attr_reader :selected_idx
|
1482
|
-
def initialize parent, options_array
|
1483
|
-
super parent, true
|
1484
|
-
|
1485
|
-
box = JComboBox.new
|
1486
|
-
box.add_action_listener do |e|
|
1487
|
-
idx = box.get_selected_index
|
1488
|
-
if idx != 0
|
1489
|
-
# don't count choosing the first as a real entry
|
1490
|
-
@selected_idx = box.get_selected_index - 1
|
1491
|
-
dispose
|
1492
|
-
end
|
1493
|
-
end
|
1494
|
-
|
1495
|
-
box.add_item "Click to select DVD drive" # put something in index 0
|
1496
|
-
options_array.each{|drive|
|
1497
|
-
box.add_item drive
|
1498
|
-
}
|
1499
|
-
add box
|
1500
|
-
pack # how do you get this arbitrary size? what the...
|
1501
|
-
end
|
1502
|
-
end
|
1503
|
-
end
|
1504
|
-
|
1505
|
-
# LODO move to sane :) also remove the andand dep.
|
1506
|
-
class String
|
1507
|
-
def present?
|
1508
|
-
length > 0
|
1509
|
-
end
|
1510
|
-
end
|
1511
|
-
|
1512
|
-
class NilClass
|
1513
|
-
def present?
|
1514
|
-
false
|
1515
|
-
end
|
1516
|
-
end
|
1517
|
-
class Object
|
1518
|
-
def present?
|
1519
|
-
true
|
1520
|
-
end
|
1521
|
-
end
|
1522
|
-
|
1523
|
-
class Array
|
1524
|
-
def present?
|
1525
|
-
length > 0
|
1526
|
-
end
|
1527
|
-
end
|
1528
|
-
|
1529
|
-
|
35
|
+
require_relative '../lib/gui/sensible-cinema-base'
|
36
|
+
require_relative '../lib/gui/sensible-cinema-normal'
|
37
|
+
require_relative '../lib/gui/sensible-cinema-create'
|
38
|
+
require_relative '../lib/gui/sensible-cinema-upconvert'
|
1530
39
|
|
1531
40
|
if $0 == __FILE__
|
1532
41
|
if ARGV.index('-h') || ARGV.index('--help')
|
1533
42
|
puts <<-EOL
|
1534
43
|
# jruby bin/sensible-cinema # DVD/file EDL player
|
1535
44
|
$ jruby bin/sensible-cinema --create-mode # DVD output "parser/cutter" create mode [advanced]
|
1536
|
-
$ jruby bin/sensible-cinema --upconvert-mode # DVD/
|
1537
|
-
$ jruby bin/sensible-cinema-cli # the experimental OCR tracker for arbitrary online/local/internet players.
|
1538
|
-
See "Advanced" section in the developer_how_to.txt file
|
45
|
+
$ jruby bin/sensible-cinema --upconvert-mode # DVD/file upconverting player
|
46
|
+
$ jruby bin/sensible-cinema-cli # the experimental OCR tracker for edited arbitrary online/local/internet players.
|
47
|
+
See "Advanced" section in the developer_how_to.txt file, has its own set of options
|
1539
48
|
|
1540
|
-
|
49
|
+
--exit-immediately [don't show the GUI, for benchmarking startup times]
|
1541
50
|
EOL
|
1542
51
|
else
|
1543
52
|
a = SensibleSwing::MainWindow.new
|
@@ -1548,5 +57,3 @@ if $0 == __FILE__
|
|
1548
57
|
end
|
1549
58
|
end
|
1550
59
|
end
|
1551
|
-
|
1552
|
-
# icon derived from: http://www.threes.com/index.php?option=com_content&view=article&id=1800:three-wise-monkeys&catid=82:mythology&Itemid=62
|