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.
Files changed (51) hide show
  1. data/.gitmodules +3 -0
  2. data/README +9 -6
  3. data/TODO +91 -41
  4. data/VERSION +1 -1
  5. data/bin/sensible-cinema +13 -1506
  6. data/bin/sensible-cinema-cli +156 -151
  7. data/change_log_with_feature_list.txt +17 -2
  8. data/developer_how_to_contribute_to_the_project.txt +3 -2
  9. data/documentation/upconversion.txt +4 -0
  10. data/history_and_related_works_list.txt +1 -0
  11. data/{play_with_inserted_scene.bat → legal/play_with_inserted_scene.bat} +0 -0
  12. data/{play_with_overlay.bat → legal/play_with_overlay.bat} +0 -0
  13. data/legal2 +2 -0
  14. data/lib/count_down_timer_jruby_swing.rb +3 -4
  15. data/lib/edl_parser.rb +345 -339
  16. data/lib/eight_three.rb +6 -1
  17. data/lib/gui/sensible-cinema-base.rb +671 -0
  18. data/lib/gui/sensible-cinema-create.rb +304 -0
  19. data/lib/{sensible-cinema-dependencies.rb → gui/sensible-cinema-dependencies.rb} +0 -0
  20. data/lib/gui/sensible-cinema-normal.rb +349 -0
  21. data/lib/gui/sensible-cinema-side-by-side.rb +27 -0
  22. data/lib/gui/sensible-cinema-upconvert.rb +254 -0
  23. data/lib/screen_tracker.rb +1 -0
  24. data/spec/edl_parser.spec.rb +6 -0
  25. data/spec/notes +107 -16
  26. data/spec/sensible_cinema_gui.spec.rb +63 -58
  27. data/todo.inventionzy.txt +12 -0
  28. data/todo.propaganda +1 -2
  29. data/todo.upconvert +3 -1
  30. data/upconvert_netflix/record_screen/record.bat +2 -0
  31. data/upconvert_netflix/record_screen/recording/1.png +0 -0
  32. data/upconvert_netflix/record_screen/recording/10.png +0 -0
  33. data/upconvert_netflix/record_screen/recording/2.png +0 -0
  34. data/upconvert_netflix/record_screen/recording/3.png +0 -0
  35. data/upconvert_netflix/record_screen/recording/4.png +0 -0
  36. data/upconvert_netflix/record_screen/recording/5.png +0 -0
  37. data/upconvert_netflix/record_screen/recording/6.png +0 -0
  38. data/upconvert_netflix/record_screen/recording/7.png +0 -0
  39. data/upconvert_netflix/record_screen/recording/8.png +0 -0
  40. data/upconvert_netflix/record_screen/recording/9.png +0 -0
  41. data/upconvert_netflix/record_screen/recording/d.png +0 -0
  42. data/www/content_editor.html +2 -2
  43. data/zamples/edit_decision_lists/dvds/edls_being_edited/cars_disney.txt +5 -7
  44. data/zamples/edit_decision_lists/dvds/innerspace.txt +77 -0
  45. data/zamples/edit_decision_lists/netflix_instant/avatar-last-air-bender-movie.txt +12 -0
  46. data/zamples/edit_decision_lists/netflix_instant/avatar-last-airbender-series.txt +1 -0
  47. data/zamples/players/netflix/netflix_firefox_non_maximized.txt +1 -1
  48. metadata +28 -11
  49. data/lib/file_chooser.rb +0 -46
  50. data/lib/swing_helpers.rb +0 -142
  51. data/www/monkey.png +0 -0
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "lib/jruby-swing-helpers"]
2
+ path = lib/jruby-swing-helpers
3
+ url = https://rdp@github.com/rdp/jruby-swing-helpers.git
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 has little community collaboration/review (though you can email them feedback).
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 are too
138
- obscure.) If there isn't one, you basically have to request one and then *hope* they get around to it.
139
- Until then, you are out of luck.
140
- They might never get around to it, or it might take a bit longer than you'd hope. Or they might never.
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 web site/api-ify
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
- netflix instant descriptor for OS X
27
-
28
- == yes do ordered in conjunction with the above probably ==
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
- bouhty ffmpeg stuff (motion detect, directshow)
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 if some create buttons are now outdated...
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 title.edl
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 PPC
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.txt file
179
+ todo.open_edl_list_org_todo
152
180
  todo.build_library
153
181
  todo.subtitle
154
- todo.virtual_audio
182
+ virtual_audio TODO
183
+ screen_capture TODO
155
184
 
156
185
  == DVD decide later to move up or down ==
157
- ffmpeg compile it mingw, see if it runs dshow windows
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
- make it load faster! this is cuh-razy! or at least splash screen! yes!
161
- try buy edit lists from all x,y,z [?] offer them money LOL
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: can I use zoomplayer max?
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 (at work), mac (to make sure volume name doesn't have spaces)
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.0
1
+ 0.26.1
data/bin/sensible-cinema CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby # so my editor will like it...
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 oddities :P
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
- def do_create_edited_copy_via_file should_prompt_for_start_and_end_times, exit_early_if_fulli_exists = false, watch_unedited = false
1242
- drive_or_file, dvd_volume_name, dvd_id, edit_list_path, descriptors = choose_dvd_or_file_and_edl_for_it
1243
-
1244
- descriptors = parse_edl(edit_list_path)
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/video upconverting player
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
- --exit-immediately [don't show the GUI, for benchmarking startup times]
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