Class: SensibleSwing::MainWindow

Inherits:
JFrame
  • Object
show all
Includes:
SwingHelpers
Defined in:
lib/gui/sensible-cinema-base.rb,
lib/gui/sensible-cinema-create.rb,
lib/gui/sensible-cinema-normal.rb,
lib/gui/sensible-cinema-upconvert.rb,
lib/gui/sensible-cinema-dependencies.rb,
lib/gui/sensible-cinema-side-by-side.rb

Constant Summary collapse

LocalStorage =
Storage.new("sensible_cinema_storage")
SMPlayerIniFile =
File.expand_path("~/.smplayer/smplayer.ini")
EdlTempFile =
Dir.tmpdir + '/mplayer.temp.edl'
MplayerBeginingBuffer =
1.0
MplayerEndBuffer =
0.0
NonDvd =

we need it for convenience, say you want to go through your indexed vids and convert them all?

'non dvd has no dvdid'
UpConvertKey =
'upconvert_setting'
UpConvertKeyExtra =
'upconvert_setting_extra'
UpConvertEnglish =
'upconvert_english_name'
ScreenMultipleFactor =
'screen_multiples'
SideBySide =

‘xbmc’ or ‘smplayer’

'side_by_side'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(be_visible = true) ⇒ MainWindow

Returns a new instance of MainWindow.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/gui/sensible-cinema-base.rb', line 86

def initialize be_visible = true
  super "Sensible-Cinema #{VERSION} (GPL)"
  force_accept_license_first
  setDefaultCloseOperation JFrame::EXIT_ON_CLOSE # default is exit on close
  @panel = JPanel.new
  @buttons = []
  @panel.set_layout nil
  add @panel # why can't I just slap these down? panel? huh?
  @starting_button_y = 40
  @button_width = 400      
  
  add_text_line "Welcome to Sensible Cinema!"
  @starting_button_y += 10 # kinder ugly...
  add_text_line "      Rest mouse over buttons for \"help\" type descriptions (tooltips)."
  add_text_line ""
  
  setIconImage(ImageIcon.new(__DIR__ + "/../vendor/profs.png").getImage())
  check_for_various_dependencies
  set_visible be_visible
end

Instance Attribute Details

#background_threadObject

Returns the value of attribute background_thread.



242
243
244
# File 'lib/gui/sensible-cinema-normal.rb', line 242

def background_thread
  @background_thread
end

#buttonsObject

Returns the value of attribute buttons.



242
243
244
# File 'lib/gui/sensible-cinema-normal.rb', line 242

def buttons
  @buttons
end

#parentObject

Returns the value of attribute parent.



24
25
26
# File 'lib/gui/sensible-cinema-normal.rb', line 24

def parent
  @parent
end

#upconv_lineObject

Returns the value of attribute upconv_line.



24
25
26
# File 'lib/gui/sensible-cinema-normal.rb', line 24

def upconv_line
  @upconv_line
end

Class Method Details

.download(full_url, to_here) ⇒ Object



8
9
10
11
12
13
14
15
# File 'lib/gui/sensible-cinema-dependencies.rb', line 8

def self.download full_url, to_here
  require 'open-uri'
  require 'openssl'
  eval("OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE") if full_url =~ /https/
  writeOut = open(to_here, "wb")
  writeOut.write(open(full_url).read)
  writeOut.close
end

.download_to_string(full_url) ⇒ Object



17
18
19
20
21
22
23
24
# File 'lib/gui/sensible-cinema-dependencies.rb', line 17

def self.download_to_string full_url
   require 'tempfile'
   to = Tempfile.new 'abc'
   download(full_url, to.path)
   out = File.binread(to.path)
   to.delete
   out
end

Instance Method Details

#add_change_upconvert_buttonsObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/gui/sensible-cinema-upconvert.rb', line 74

def add_change_upconvert_buttons
  raise 'should have already been set for us' unless LocalStorage[ScreenMultipleFactor]
  @medium_dvd = new_jbutton("Set upconvert options to DVD-style video") {
    luma_spatial = 0
    chroma_spatial = 1
    luma_tmp = 4
    chroma_tmp = 4
    LocalStorage[UpConvertKey] = "hqdn3d=%s:%s:%s:%s,scale=SCREEN_X:-10:0:0:2" % [luma_spatial, chroma_spatial, luma_tmp, chroma_tmp]
    # hqdn3d[=luma_spatial:chroma_spatial:luma_tmp:chroma_tmp]

    LocalStorage[UpConvertKeyExtra] = "-sws 9 -ssf ls=75.0 -ssf cs=7.0"
    LocalStorage[UpConvertEnglish] = "DVD"
    display_current_upconvert_setting_and_close_window
  }
  high_compression = new_jbutton("Set upconvert options to high compressed video file playback") {
    # -autoq 6 -vf pp [?]

    LocalStorage[UpConvertEnglish] = "high compressed"
    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...

    LocalStorage[UpConvertKeyExtra] = "-sws 9 -ssf ls=75.0 -ssf cs=25.0"
    display_current_upconvert_setting_and_close_window
    # -Processing method: mplayer with accurate deblocking ???

  }
  new_jbutton("Set upconvert options to experimental style playback") {
    LocalStorage[UpConvertKey] = "scale" # hqdn3d=7:7:5,scale=SCREEN_X:-10:0:0:10"

    LocalStorage[UpConvertKeyExtra] = "-sws 9 -ssf ls=100.0 -ssf cs=75.0"
    LocalStorage[UpConvertEnglish] = "experimental"
    display_current_upconvert_setting_and_close_window
  }
  
  # TODO tooltip from docu here +- this into tooltip

  # TODO "click here" link for more docu [?]

  add_text_line "Multiple factor screen widths"
  add_text_line "   (higher is better, but uses more cpu, 2x is good for high-end)." 
  add_text_line "   If mplayer just dies or displays only a black or white screen then lower this setting."
  slider = JSlider.new
  slider.setBorder(BorderFactory.createTitledBorder("Screen resolution multiple"));
  
  # I want tick for 1x, 1.5x, 2x, 2.5x, 3x

  # so let's do marker values of 10 -> 30, since it requires integers...

  
  labelTable = java.util.Hashtable.new
  i = java.lang.Integer
  l = JLabel
  
  # allow for 0.75 too, if you have a large monitor, slower cpu...

  local_minimum = (720.0/get_current_max_width_resolution)*100 # allows 1024 to use upscaling to 860, but we warn when they do this

  label_minimum = nil
  (0..300).step(25) do |n|
    if n > local_minimum
      label_minimum ||= n
      if (n % 100 == 0)
        labelTable.put(i.new(n), l.new("#{n/100}x")) # 1x

      elsif n == label_minimum # just for the bottom label, rest too chatty

        labelTable.put(i.new(n), l.new("#{n/100.0}x")) # 1.5x

      end
    end
  end
  slider.setLabelTable( labelTable )
  
  slider.maximum=300
  slider.minimum=label_minimum
  slider.setMajorTickSpacing(100) 
  slider.setMinorTickSpacing(25) 
  slider.setPaintTicks(true)
  slider.setPaintLabels(true)    
  slider.snap_to_ticks=true
  
  slider.set_value LocalStorage[ScreenMultipleFactor] * 100
  
  slider.add_change_listener { |event|
    if !slider.value_is_adjusting
      # they released their hold on it...

      old_value = LocalStorage[ScreenMultipleFactor]
      new_value = slider.value/100.0
      LocalStorage[ScreenMultipleFactor] = new_value
      if new_value != old_value
        if slider.value == label_minimum
          show_blocking_message_dialog "Setting it too low like that might make it not do much upconverting (DVD's, are 720px, you're setting it to upconvert to #{new_value * get_current_max_width_resolution})"
        end
        display_current_upconvert_setting_and_close_window
      end
    end
  }
  slider.set_bounds(44, @starting_button_y, @button_width, 66)
  2.times {increment_button_location}
  @panel.add(slider)
  
  increment_button_location
  
  @none = new_jbutton("Reset upconvert options to none (no upconversion)")
  @none.tool_tip = "Having no upconvert options is reasonably good, might use directx for scaling, nice for slow cpu's"
  @none.on_clicked {
    LocalStorage[UpConvertKey] = nil
    LocalStorage[UpConvertKeyExtra] = nil
    LocalStorage[UpConvertEnglish] = nil
    display_current_upconvert_setting_and_close_window
  }
  
  @generate_images = new_jbutton("Test current configuration by writing some images from playing a video file") do
    popup = warn_if_no_upconvert_options_currently_selected
    filename_mpg = new_existing_file_selector_and_select_file( "pick movie file (like moviename.mpg)")
    
    output_dir = get_same_drive_friendly_clean_temp_dir 'temp_upscaled_video_out'
    output_command = '-ss 2:44 -frames 300 -vo png:outdir="' + File.strip_drive_windows(output_dir) + '"'
    output_command += " -noframedrop" # don't want them to skip frames on cpu's without enough power to keep up

    thread = play_mplayer_edl_non_blocking [filename_mpg, nil], [output_command], true
    when_thread_done(thread) { popup.dispose; show_in_explorer(output_dir) }
  end
  @generate_images.tool_tip = "This creates a folder with images upconverted from some DVD or file, so you can tweak settings and compare." # TODO more tooltips


  @generate_screen_cast = new_jbutton("Test current configuration by watching video file and recording screen") do
    popup = warn_if_no_upconvert_options_currently_selected
    filename_mpg = new_existing_file_selector_and_select_file( "pick movie file (like moviename.mpg)")
    output_dir = get_same_drive_friendly_clean_temp_dir 'temp_screencast_dir'
    thread1 = play_mplayer_edl_non_blocking [filename_mpg, nil], [" -ss 2:44 -endpos 11"]
    # screen capture for 10s

    fps_to_grab = 5
    thread2 = Thread.new {  c = %!ffmpeg -f dshow -i video="screen-capture-recorder" -r #{fps_to_grab} -vframes #{fps_to_grab*10} -y #{File.strip_drive_windows(output_dir)}/%d.png!; system_blocking c }
    thread2.join
    show_blocking_message_dialog "ffmpeg done, close mplayer now!"
    thread1.join
    popup.dispose # just in case :P

    show_in_explorer(output_dir)
  end


end

#add_change_upconvert_options_buttonObject



42
43
44
45
46
47
48
# File 'lib/gui/sensible-cinema-upconvert.rb', line 42

def add_change_upconvert_options_button
  @show_upconvert_options = new_jbutton("Change/Test Playback Upconversion Quality Options") do
    upconvert_window = new_child_window
    upconvert_window.add_change_upconvert_buttons
  end
  @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."
end

#add_open_documentation_buttonObject



74
75
76
77
78
# File 'lib/gui/sensible-cinema-normal.rb', line 74

def add_open_documentation_button
  @open_help_file = new_jbutton("View Sensible Cinema Documentation") do
    show_in_explorer __DIR__ + "/../documentation" # TODO mac :)
  end
end

#add_options_that_use_local_filesObject

advanced buttons



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/gui/sensible-cinema-create.rb', line 175

def add_options_that_use_local_files
  add_text_line 'Create Options that first create/use a local intermediary file:'

  @preview_section = new_jbutton( "Preview a certain time frame from fulli file (edited)" )
  @preview_section.tool_tip = "    This allows you to preview an edit easily.\n    It is the equivalent of saying \\\"watch this file edited from exactly minute x second y to minute z second q\"\n    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.\n  EOL\n  @preview_section.on_clicked {\n    do_create_edited_copy_via_file true\n  }\n  \n  @preview_section_unedited = new_jbutton(\"Preview a certain time frame from fulli file (unedited)\" )\n  @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.\"\n  @preview_section_unedited.on_clicked {\n    do_create_edited_copy_via_file true, false, true\n  }\n\n  @rerun_preview = new_jbutton( \"Re-run most recently watched preview time frame from fulli file\" )\n  @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.\"\n  @rerun_preview.on_clicked {\n    repeat_last_copy_dvd_to_hard_drive\n  }\n  \n  # Maybe this button should go too...\n  @fast_preview = new_jbutton(\"fast preview all from fulli file (smplayer EDL)\")\n  @fast_preview.tool_tip = <<-EOL\n    Plays smplayer on a file with an EDL.\n    This gives you a rough estimate to see if your edits are accurate, and is really fast to seek, etc.\n    This is useful because you can't use mplayer on a DVD for accurate timestamps if it has any \n    timestamp splits in it [because some DVD's are buggy]\n  EOL\n  @fast_preview.on_clicked {\n    success, wrote_to_here_fulli = do_create_edited_copy_via_file false, true\n    sleep 0.5 # lodo take out ???\n    background_thread.join if background_thread # let it write out the original fulli, if necessary [?]\n    nice_file = wrote_to_here_fulli\n    run_smplayer_blocking nice_file, nil, \"-edl \#{normalize_path EdlTempFile}\", false, true, false\n  }\nend\n"

#add_play_upconvert_buttonsObject



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/gui/sensible-cinema-upconvert.rb', line 6

def add_play_upconvert_buttons

  @watch_file_upconvert = new_jbutton( "Watch a movie file upconverted (unedited)") do
    popup = warn_if_no_upconvert_options_currently_selected
    filename_mpg = new_existing_file_selector_and_select_file( "pick movie file (like moviename.mpg)")
    thread = play_mplayer_edl_non_blocking [filename_mpg, nil]
    when_thread_done(thread) { popup.dispose }
  end
  @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

  
  @watch_dvd_upconvert = new_jbutton( "Watch a DVD upconverted (unedited)") do
    popup = warn_if_no_upconvert_options_currently_selected
    thread = play_dvd_smplayer_unedited false, false, false
    when_thread_done(thread) { popup.dispose }
  end
  @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."
  
  add_text_line ''
  @upconv_line = add_text_line ''
  change_upconvert_line_to_current
  
  add_change_upconvert_options_button
  if !upconvert_set_to_anything?
    show_blocking_message_dialog 'please configure your upconvert settings first'
    @show_upconvert_options.simulate_click # make them choose one

  end
  add_text_line ''
  
end

#add_text_line(line) ⇒ Object



124
125
126
127
128
129
130
131
132
# File 'lib/gui/sensible-cinema-base.rb', line 124

def add_text_line line
  jlabel = JLabel.new line
  happy = Font.new("Tahoma", Font::PLAIN, 11)
  jlabel.setFont(happy)
  jlabel.set_bounds(44,@starting_button_y ,460,14)
  @panel.add jlabel
  increment_button_location 18
  jlabel
end

#assert_confirmed_dialog(returned, license_url_should_also_be_embedded_by_you_in_message) ⇒ Object



446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
# File 'lib/gui/sensible-cinema-base.rb', line 446

def assert_confirmed_dialog returned, license_url_should_also_be_embedded_by_you_in_message
  # :yes, :no, :cancel
  # 1 is view button was clicked
  # 0 is accept
  # 2 is cancel
  if returned == :no
    if license_url_should_also_be_embedded_by_you_in_message
      system_non_blocking("start #{license_url_should_also_be_embedded_by_you_in_message}")
      puts "Please restart after reading license agreement, to be able to then accept it."
    end
    System.exit 0
  elsif returned == :cancel
    p 'license not accepted...exiting'
    System.exit 1
  elsif returned == :exited
    p 'license exited early...exiting'
    System.exit 1
  elsif returned == :yes
    # ok
  else
    raise 'unknown'
  end
end

#assert_ownership_dialogObject



422
423
424
425
426
427
# File 'lib/gui/sensible-cinema-base.rb', line 422

def assert_ownership_dialog 
  message = "Do you certify you own the DVD this came of and have it in your possession?"
  title = "Verify ownership"
  returned = JOptionPane.show_select_buttons_prompt(message, {})
  assert_confirmed_dialog returned, nil
end

#change_upconvert_line_to_currentObject



59
60
61
62
63
64
65
66
67
# File 'lib/gui/sensible-cinema-upconvert.rb', line 59

def change_upconvert_line_to_current
  current = get_current_upconvert_as_phrase
  if @upconv_line
    @upconv_line.set_text current
  end
  if @parent && @parent.upconv_line
    @parent.upconv_line.set_text current
  end # LODO I think the child also wants a status line..

end

#check_for_exe(windows_full_loc, unix_name) ⇒ Object



497
498
499
500
501
502
503
504
505
506
507
508
509
# File 'lib/gui/sensible-cinema-base.rb', line 497

def check_for_exe windows_full_loc, unix_name
  # in windows, that exe *at that location* must exist...
  if OS.windows?
    File.exist?(windows_full_loc)
  else
    require 'lib/check_installed_mac.rb'
    if !CheckInstalledMac.check_for_installed(unix_name)
      exit 1 # it'll have already displayed a message...
    else
      true
    end
  end
end

#check_for_various_dependenciesObject



511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
# File 'lib/gui/sensible-cinema-base.rb', line 511

def check_for_various_dependencies
  if we_are_in_create_mode        
    if !check_for_exe('vendor/cache/mencoder/mencoder.exe', 'mencoder')
      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."
      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"
    end
  end

  # runtime dependencies, at least as of today...
  ffmpeg_exe_loc = File.expand_path('vendor/cache/ffmpeg/ffmpeg.exe')
  if !check_for_exe(ffmpeg_exe_loc, 'ffmpeg')
    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."
    download_zip_file_and_extract "ffmpeg (5MB)", "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-git-335bbe4-win32-static.7z", "ffmpeg"
  end
  if OS.mac?
    check_for_exe("mplayer", "mplayer") # mencoder and mplayer are separate for mac... [this checks for mac's mplayerx, too]
  else      
    path = RubyWhich.new.which('smplayer_portable')
    if(path.length == 0)
      # this one has its own installer...
      show_blocking_message_dialog("It appears that you need to install a pre-requisite dependency: MPlayer for Windows (MPUI).
      Click ok to be directed to its download website, where you can download and install it (recommend: MPUI....Full-Package.exe), 
      then restart sensible cinema.  NB that it takes awhile to install.  Sorry about that.", 
      "Lacking dependency", JOptionPane::ERROR_MESSAGE)
      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"
      System.exit 0
    end
  end
end

#choose_dvd_drive_or_file(force_choose_only_dvd_drive) ⇒ Object

returns e:, volume_name, dvd_id or full_path.mkv, filename, ”



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/gui/sensible-cinema-normal.rb', line 287

def choose_dvd_drive_or_file force_choose_only_dvd_drive
  opticals = DriveInfo.get_dvd_drives_as_openstruct
  if @saved_opticals == opticals && @_choose_dvd_drive_or_file
    # memoize...if disks haven't changed :)
    return @_choose_dvd_drive_or_file
  else
    @saved_opticals = opticals # save currently mounted disk list, so we know if we should re-select later... 
    # is this ok for os x?
  end

  has_at_least_one_dvd_inserted = opticals.find{|d| d.VolumeName }
  if !has_at_least_one_dvd_inserted && force_choose_only_dvd_drive
    show_blocking_message_dialog 'insert a dvd first' 
    raise 'no dvd found'
  end
  names = opticals.map{|d| d.Name + "\\" + " (" +  (d.VolumeName || 'Insert DVD to use') + ")"}
  if !force_choose_only_dvd_drive && !has_at_least_one_dvd_inserted
    names += ['No DVD mounted so choose Local File (or insert DVD, re-try)'] # LODO cannot read it...
    used_local_file_option = true
  end
  
  count = 0
  opticals.each{|d| count += 1 if d.VolumeName}
  if count == 1 && !used_local_file_option
   # just choose it if there's only one disk available..
   p 'selecting only disk present in the various DVD drives'
   selected_idx = opticals.index{|d| d.VolumeName}
   unless selected_idx
     show_blocking_message_dialog "Please insert a disk first"
     raise 'inset disk'
   end

  else
    dialog = get_disk_chooser_window names
    dialog.setSize 200, 125
    dialog.show
    selected_idx = dialog.selected_idx
  end
  
  if selected_idx
    if used_local_file_option
      raise unless selected_idx == 0 # it was our only option...
      filename = new_existing_file_selector_and_select_file("Select yer previously grabbed from DVD file")
      assert_ownership_dialog
      return [filename, File.basename(filename), NonDvd]
    else
      disk = opticals[selected_idx]
      out = show_non_blocking_message_dialog "calculating current disk's unique id...if this pauses more than 10s then clean your DVD..."
      begin
  dvd_id = DriveInfo.md5sum_disk(disk.MountPoint)
      rescue Exception => e
  show_blocking_message_dialog e.to_s # todo a bit ugly...
      raise
ensure
  out.dispose
end
      @_choose_dvd_drive_or_file = [disk.MountPoint, opticals[selected_idx].VolumeName, dvd_id]
      return @_choose_dvd_drive_or_file
    end
  else
    raise 'did not select a drive...'
  end
end

#choose_dvd_or_file_and_edl_for_it(force_choose_edl_file_if_no_easy_match = true) ⇒ Object



351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/gui/sensible-cinema-base.rb', line 351

def choose_dvd_or_file_and_edl_for_it force_choose_edl_file_if_no_easy_match = true
  drive_or_file, dvd_volume_name, dvd_id = choose_dvd_drive_or_file false
  
  unless @_edit_list_path # cache file selection...
    edit_list_path = EdlParser.single_edit_list_matches_dvd(dvd_id)
    if !edit_list_path && force_choose_edl_file_if_no_easy_match
      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)
      raise 'cancelled choosing an EDL' unless edit_list_path
    end
    @_edit_list_path = edit_list_path
  end
  p 'reloading'
  if @_edit_list_path
    # reload it every time just in case it has changed on disk
    descriptors = nil
    begin
      descriptors = parse_edl @_edit_list_path
    rescue SyntaxError => e
      show_non_blocking_message_dialog("this file has an error--please fix then hit ok: \n" + @_edit_list_path + "\n " + e)
      raise e
    end
  end
  [drive_or_file, dvd_volume_name, dvd_id, @_edit_list_path, descriptors]
end

#choose_file_and_edl_and_create_sxs_or_play(just_create_dot_edl_file_instead_of_play) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/gui/sensible-cinema-normal.rb', line 80

def choose_file_and_edl_and_create_sxs_or_play just_create_dot_edl_file_instead_of_play
  filename_mpg = new_existing_file_selector_and_select_file( "Pick moviefile (like moviename.mpg or video_ts/anything.ext)")
  edl_filename = new_existing_file_selector_and_select_file( "Pick an EDL file to use with it", EdlParser::EDL_DIR)
  assert_ownership_dialog
  if just_create_dot_edl_file_instead_of_play
    descriptors = EdlParser.parse_file edl_filename
    # LODO these timings...DRY up...plus is XBMC the same? what about on a slower computer?
    # NB these are just for the Side by side EDL's!
    
    edl_contents = MplayerEdl.convert_to_edl descriptors, add_secs_end = MplayerEndBuffer, MplayerBeginingBuffer, splits = []
    output_file = filename_mpg.gsub(/\.[^\.]+$/, '') + '.edl' # sanitize...
    File.write(output_file, edl_contents)
    raise unless File.exist?(output_file)
    show_blocking_message_dialog("created #{output_file}")
  else
    play_mplayer_edl_non_blocking [filename_mpg, edl_filename]
  end
end

#create_brand_new_edlObject



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/gui/sensible-cinema-create.rb', line 289

def create_brand_new_edl
  drive, volume, dvd_id = choose_dvd_drive_or_file true
  english_name = get_user_input("Enter a human readable DVD description for #{volume}", volume.gsub('_', ' ').downcase)
  input = "# comments can go after a # on any line, for example this one.\n\"name\" => \"\#{english_name}\",\n\n\"mutes\" => [\n  # an example line, uncomment the leading \"#\" to make it active\n  # \"0:00:01.0\", \"0:00:02.0\", \"profanity\", \"da..\", \n],\n\n\"blank_outs\" => [\n  # an example line, uncomment the leading \"#\" to make it active\n  # \"00:03:00.0\" , \"00:04:00.0\", \"violence\", \"of some sort\",\n],\n\n\"volume_name\" => \"\#{volume}\",\n\"disk_unique_id\" => \"\#{dvd_id}\",\n\"dvd_title_track\" => \"1\", # the \"show DVD info\" button will tell you title lengths (typically longest title is the title track)\n# \"dvd_title_track_length\" => \"9999\", # length, on the DVD, of dvd_title_track (use the show DVD info button to get this number).\n# \"subtitle_url\" => \"1234567\",\n# \"not edited out stuff\" => \"some...\",\n# \"closing thoughts\" => \"only...\",\n# 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\n# \"mplayer_dvd_splits\" => [\"59:59\", \"1:04:59\"], # or [] if there are none.  Additive currently.  12345.6 ok. \n    EOL\n  # TODO auto-ify above, move docs to a file in documentation.\n  filename = EdlParser::EDL_DIR + \"/edls_being_edited/\" + english_name.gsub(' ', '_') + '.txt'\n  filename.downcase!\n  File.write(filename, input) unless File.exist?(filename) # lodo let them choose name (?)\n  open_file_to_edit_it filename\nend\n"

#display_current_upconvert_setting_and_close_windowObject



212
213
214
215
216
# File 'lib/gui/sensible-cinema-upconvert.rb', line 212

def display_current_upconvert_setting_and_close_window
  change_upconvert_line_to_current
  show_blocking_message_dialog get_current_upconvert_as_phrase
  self.dispose
end

#do_create_edited_copy_via_file(should_prompt_for_start_and_end_times, exit_early_if_fulli_exists = false, watch_unedited = false) ⇒ Object



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/gui/sensible-cinema-create.rb', line 217

def do_create_edited_copy_via_file should_prompt_for_start_and_end_times, exit_early_if_fulli_exists = false, watch_unedited = false
  drive_or_file, dvd_volume_name, dvd_id, edit_list_path, descriptors = choose_dvd_or_file_and_edl_for_it
  
  descriptors = parse_edl(edit_list_path)
  if watch_unedited
    # reset them
    descriptors['mutes'] = descriptors['blank_outs'] = []
  end
  
  # LODO allow for spaces in the save_to filename
  if should_prompt_for_start_and_end_times
    # only show this message once :)
    @show_block ||= show_blocking_message_dialog("      Ok, let's preview just a portion of it. \n      Note that you'll want to preview a section that wholly includes a deleted section in it.\n      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.\n      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.\n      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.\n      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.\n    EOL\n    old_start = LocalStorage['start_time']\n    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'])\n    default_end = LocalStorage['end_time']\n    if start_time and start_time != old_start\n      default_end = EdlParser.translate_string_to_seconds(start_time) + 10\n      default_end = EdlParser.translate_time_to_human_readable(default_end)\n    end\n    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)\n    unless start_time and end_time\n      # this one is raw showMessageDialog...\n      JOptionPane.showMessageDialog(nil, \" Please choose start and end\", \"Failed\", JOptionPane::ERROR_MESSAGE)\n      return\n    end\n    LocalStorage['start_time'] = start_time\n    LocalStorage['end_time'] = end_time\n  end\n  dvd_friendly_name = descriptors['name']\n  unless dvd_friendly_name\n    drive_or_file, dvd_volume_name, dvd_id, edit_list_path, descriptors = choose_dvd_or_file_and_edl_for_it\n    descriptors = parse_edl(edit_list_path)\n    raise 'no dvd name in EDL?' + edit_list_path + File.read(edit_list_path)\n  end\n  \n  dvd_title_track = get_title_track(descriptors)\n  if dvd_id == NonDvd\n    file_from = drive_or_file\n  else\n    file_from = get_grabbed_equivalent_filename_once dvd_friendly_name, dvd_title_track # we don't even care about the drive letter anymore...\n  end\n  if file_from =~ /\\.mkv/i\n    show_blocking_message_dialog \"warning .mkv files from makemkv have been known to be off timing wise, please convert to a .ts file using tsmuxer first if it came from makemkv\"\n  end\n  if file_from !~ /\\.(ts|mpg|mpeg)$/i\n    show_blocking_message_dialog(\"warning: file \#{file_from} is not a .mpg or .ts file--it may not work properly all the way, but we'll try...\") \n  end\n  \n  save_to_edited = get_save_to_filename dvd_friendly_name\n  fulli = MencoderWrapper.calculate_fulli_filename save_to_edited\n  if exit_early_if_fulli_exists\n    if fulli_dot_done_file_exists? save_to_edited\n      return [true, fulli]\n    end\n    # make it create a dummy response file for us :)\n    start_time = \"00:00\"\n    end_time = \"00:01\"\n  end\n  should_run_mplayer = should_prompt_for_start_and_end_times || exit_early_if_fulli_exists\n  require_deletion_entry = true unless watch_unedited\n  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\n  [false, fulli] # false means it's running in a background thread :P\nend\n", "Preview")

#download_7zipObject



474
475
476
477
478
479
480
481
482
483
# File 'lib/gui/sensible-cinema-base.rb', line 474

def download_7zip
  Dir.mkdir('./vendor/cache') unless File.directory? 'vendor/cache' # development may not have it created yet... [?]
  unless File.exist? 'vendor/cache/7za.exe'
    Dir.chdir('vendor/cache') do
      print 'downloading unzipper (7zip--400K) ...'
      MainWindow.download("http://downloads.sourceforge.net/project/sevenzip/7-Zip/9.20/7za920.zip", "7za920.zip")
      system_blocking("../unzip.exe -o 7za920.zip") # -o means "overwrite" without prompting
    end
  end
end

#download_zip_file_and_extract(english_name, url, to_this) ⇒ Object



485
486
487
488
489
490
491
492
493
494
495
# File 'lib/gui/sensible-cinema-base.rb', line 485

def download_zip_file_and_extract english_name, url, to_this
  download_7zip
  Dir.chdir('vendor/cache') do
    file_name = url.split('/')[-1]
    print "downloading #{english_name} ..."
    MainWindow.download(url, file_name)
    system_blocking("7za e #{file_name} -y -o#{to_this}")
    puts 'done ' + english_name
    # creates vendor/cache/mencoder/mencoder.exe...
  end
end

#force_accept_license_firstObject



139
140
141
142
143
144
145
146
147
# File 'lib/gui/sensible-cinema-base.rb', line 139

def force_accept_license_first
  if !(LocalStorage['main_license_accepted'] == VERSION)
    require_blocking_license_accept_dialog 'Sensible Cinema', 'gplv3', 'http://www.gnu.org/licenses/gpl.html', 'Sensible Cinema license agreement', 
        "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"
    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"), 
        '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'
    LocalStorage['main_license_accepted'] = VERSION
  end
end

#fulli_dot_done_file_exists?(save_to_edited) ⇒ Boolean

Returns:

  • (Boolean)


191
192
193
194
# File 'lib/gui/sensible-cinema-normal.rb', line 191

def fulli_dot_done_file_exists? save_to_edited
  fulli = MencoderWrapper.calculate_fulli_filename save_to_edited
  File.exist?(fulli + ".done") # stinky!
end

#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) ⇒ Object



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/gui/sensible-cinema-normal.rb', line 202

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
  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]
  begin
    commands = get_mencoder_commands descriptors, file_from, save_to, start_time, end_time, dvd_title_track, require_deletion_entry
  rescue MencoderWrapper::TimingError => e
    show_blocking_message_dialog("Appears you chose a time frame with no deletion segment in it--please try again:" + e)
    return
  rescue Errno::EACCES => e
    show_blocking_message_dialog("Appears a file on the system is locked: perhaps you need to close down some instance of mplayer?" + e)
    return
  end
  temp_dir = Dir.tmpdir
  temp_file = temp_dir + '/vlc.temp.bat'
  File.write(temp_file, commands)
  popup_message = "    Applying \#{File.basename edit_list_path} \n       to \#{file_from} (\#{dvd_title}).\n    Copying to \#{save_to}.\n  EOL\n  if !fulli_dot_done_file_exists?(save_to)\n    popup_message += \"This could take quite awhile (several hours), and will prompt you with a chime noise when it is done.\\n\n    You can close this window and minimize sensible cinema and continue using your computer while it runs in the background.\\n\"\n  end\n  \n  if !start_time\n    # assume a full run..\n    popup_message += <<-EOL\n      NB that the created file will be playable only with VLC (possibly also with smplayer), \n      but probably not with windows media player.\n    EOL\n  end\n  \n  popup = show_non_blocking_message_dialog(popup_message, \"OK\")\n\n  # allow our popups to still be serviced while it is running\n  @background_thread = Thread.new { run_batch_file_commands_and_use_output_somehow commands, save_to, file_from, run_mplayer }\n  when_thread_done(@background_thread) { popup.dispose }\n  # LODO warn if they will overwrite a file in the end...\nend\n"

#get_current_max_width_resolutionObject



228
229
230
231
# File 'lib/gui/sensible-cinema-upconvert.rb', line 228

def get_current_max_width_resolution
  # choose width of widest monitor (why would they display it on the other, right?)

  java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment.getScreenDevices.map{|gd| gd.display_mode.width}.max.to_i
end

#get_current_upconvert_as_phraseObject



218
219
220
221
222
223
224
225
226
# File 'lib/gui/sensible-cinema-upconvert.rb', line 218

def get_current_upconvert_as_phrase
  settings = LocalStorage[UpConvertEnglish]
  out = "Upconvert options are now #{  settings ? "set to #{settings} style" : "NOT SET"}"
  if settings
    multiple = LocalStorage[ScreenMultipleFactor]
    out += " (screen multiplier #{get_current_max_width_resolution}*#{multiple} = #{(multiple * get_current_max_width_resolution).to_i}px)."
  end
  out
end

#get_disk_chooser_window(names) ⇒ Object



605
606
607
# File 'lib/gui/sensible-cinema-base.rb', line 605

def get_disk_chooser_window names
  GetDisk.new(self, names)
end

#get_drive_with_most_space_with_slashObject



187
188
189
# File 'lib/gui/sensible-cinema-normal.rb', line 187

def get_drive_with_most_space_with_slash
  DriveInfo.get_drive_with_most_space_with_slash
end

#get_freespace(path) ⇒ Object



146
147
148
# File 'lib/gui/sensible-cinema-normal.rb', line 146

def get_freespace path
  JFile.new(File.dirname(path)).get_usable_space
end

#get_grabbed_equivalent_filename_once(dvd_title, dvd_title_track) ⇒ Object



156
157
158
159
160
161
# File 'lib/gui/sensible-cinema-normal.rb', line 156

def get_grabbed_equivalent_filename_once dvd_title, dvd_title_track
  @_get_grabbed_equivalent_filename_once ||=
  begin
    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)"
  end
end

#get_mencoder_commands(descriptors, file_from, save_to, start_time, end_time, dvd_title_track, require_deletion_entry) ⇒ Object

to make it stubbable :)



197
198
199
200
# File 'lib/gui/sensible-cinema-normal.rb', line 197

def get_mencoder_commands descriptors, file_from, save_to, start_time, end_time, dvd_title_track, require_deletion_entry
  delete_partials = true unless start_time # in case anybody wants to look really really close [?]
  MencoderWrapper.get_bat_commands descriptors, file_from, save_to, start_time, end_time, dvd_title_track, delete_partials, require_deletion_entry
end

#get_same_drive_friendly_clean_temp_dir(suffix) ⇒ Object



201
202
203
204
205
206
207
208
209
210
# File 'lib/gui/sensible-cinema-upconvert.rb', line 201

def get_same_drive_friendly_clean_temp_dir suffix
    output_dir = Dir.tmpdir
    if File.get_root_dir(output_dir) != File.get_root_dir(Dir.pwd) # you are hosed!

      output_dir = File.get_root_dir(Dir.pwd) # we'll raise if it's not writable...

    end
    output_dir = output_dir + '/' + suffix
    FileUtils.rm_rf output_dir
    Dir.mkdir output_dir
    output_dir
end

#get_save_to_filename(dvd_title) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/gui/sensible-cinema-normal.rb', line 163

def get_save_to_filename dvd_title
  @_get_save_to_filename ||=
  begin
    save_to_file_name = dvd_title + ' edited version'
    save_to_file_name = save_to_file_name.gsub(' ', '_').gsub( /\W/, '') + ".avi" # no punctuation or spaces for now, to not complicate...
    save_to = new_nonexisting_filechooser_and_go "Pick where to save #{dvd_title} edited version to", nil, get_drive_with_most_space_with_slash + save_to_file_name
    raise 'no spaces allowed yet' if save_to =~ / /
    begin
      a = File.open(File.dirname(save_to) + "/test_file_to_see_if_we_have_permission_to_write_to_this_folder", "w")
      a.close
      File.delete a.path
    rescue Errno::EACCES => e
      show_blocking_message_dialog "unable to write to that directory, please pick again: " + e.to_s
      raise 'pick again!'
    end
    freespace = get_freespace(save_to)
    if freespace < 8_000_000_000
      show_blocking_message_dialog("Warning: there may not be enough space on the disk for #{save_to} 
      (depending on DVD size, you may need around 10G free--you have #{freespace/1_000_000_000}GB free).  Click OK to continue.")
    end
    save_to.gsub(/\.avi$/, '')
  end
end

#get_title_track(descriptors, use_default_of_one = true) ⇒ Object



150
151
152
153
154
# File 'lib/gui/sensible-cinema-normal.rb', line 150

def get_title_track descriptors, use_default_of_one = true
  given = descriptors["dvd_title_track"] 
  given ||= "1" if use_default_of_one
  given
end

#get_upconvert_secondary_settingsObject



247
248
249
# File 'lib/gui/sensible-cinema-upconvert.rb', line 247

def get_upconvert_secondary_settings
  LocalStorage[UpConvertKeyExtra]
end

#get_upconvert_vf_settingsObject



233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/gui/sensible-cinema-upconvert.rb', line 233

def get_upconvert_vf_settings
  template = LocalStorage[UpConvertKey]
  if template
    screen_multiple = LocalStorage[ScreenMultipleFactor]
    upc = template.gsub('SCREEN_X', (get_current_max_width_resolution*screen_multiple).to_i.to_s) # has to be an integer...

    upc = 'pullup,softskip,' + upc
    p 'using upconvert settings: ' + upc
    upc
  else
    p 'not using any specific upconversion-ing'
    # pullup, softskip -- might slow things down too much for slow cpus

  end
end

#get_user_input(message, default = '', cancel_ok = false) ⇒ Object



581
582
583
584
# File 'lib/gui/sensible-cinema-base.rb', line 581

def get_user_input(message, default = '', cancel_ok = false)
  bring_to_front
  SwingHelpers.get_user_input message, default, cancel_ok
end

#increment_button_location(how_much = 30) ⇒ Object



134
135
136
137
# File 'lib/gui/sensible-cinema-base.rb', line 134

def increment_button_location how_much = 30
  @starting_button_y += how_much
  setSize @button_width+80, @starting_button_y + 50
end

#new_child_windowObject

a window that when closed doesn’t bring the whole app down



157
158
159
160
161
162
163
164
165
# File 'lib/gui/sensible-cinema-base.rb', line 157

def new_child_window
  child = MainWindow.new
  child.setDefaultCloseOperation(JFrame::DISPOSE_ON_CLOSE)
  child.parent=self # this should have failed in the PPL
  # make both windows visible z-wise
  x, y = self.get_location.x, self.get_location.y
  child.set_location(x + 100, y + 100)
  child
end

#new_existing_file_selector_and_select_file(title, dir = nil) ⇒ Object

also caches directory previously selected …



593
594
595
596
597
598
599
# File 'lib/gui/sensible-cinema-base.rb', line 593

def new_existing_file_selector_and_select_file title, dir = nil
  bring_to_front
  dir ||= LocalStorage[caller.inspect]
  got = FileDialog.new_previously_existing_file_selector_and_go title, dir
  LocalStorage[caller.inspect] = File.dirname(got)
  got
end

#new_jbutton(title, tooltip = nil) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/gui/sensible-cinema-base.rb', line 111

def new_jbutton title, tooltip = nil
  button = JButton.new title
  button.tool_tip = tooltip
  button.set_bounds(44, @starting_button_y, @button_width, 23)
  @panel.add button
  @buttons << button
  if block_given? # allow for new_jbutton("xx") do ... end [this is possible through some miraculous means LOL]
    button.on_clicked { yield }
  end
  increment_button_location
  button
end

#new_nonexisting_filechooser_and_go(title = nil, default_dir = nil, default_file = nil) ⇒ Object



562
563
564
565
# File 'lib/gui/sensible-cinema-base.rb', line 562

def new_nonexisting_filechooser_and_go title = nil, default_dir = nil, default_file = nil
  bring_to_front
  JFileChooser.new_nonexisting_filechooser_and_go title, default_dir, default_file
end

#normalize_path(path) ⇒ Object

converts to full path, 8.3 if on doze



28
29
30
31
# File 'lib/gui/sensible-cinema-normal.rb', line 28

def normalize_path path
  path = File.expand_path path
  path = EightThree.convert_path_to_8_3 path if OS.doze?
end

#open_file_to_edit_it(filename, options = {}) ⇒ Object

:start_minimized



549
550
551
552
553
554
555
556
557
558
559
560
# File 'lib/gui/sensible-cinema-base.rb', line 549

def open_file_to_edit_it filename, options = {} # :start_minimized
  if OS.windows?
    if options[:start_minimized]
      system_non_blocking "start /min notepad \"#{filename}\""
    else
      system_non_blocking "notepad \"#{filename}\""
    end
  else
    # ignore minimized :P
    system_non_blocking "open -a TextEdit \"#{filename}\""
  end
end

#open_url_to_view_it_non_blocking(url) ⇒ Object



541
542
543
544
545
546
547
# File 'lib/gui/sensible-cinema-base.rb', line 541

def open_url_to_view_it_non_blocking url
  if OS.windows?
    system_non_blocking("start #{url.gsub('&', '^&')}") # LODO would launchy help/work here with the full url?
  else
    system_non_blocking "#{OS.open_file_command} \"#{url}\"" # LODO test
  end
end

#parse_edl(path) ⇒ Object



142
143
144
# File 'lib/gui/sensible-cinema-normal.rb', line 142

def parse_edl path
  EdlParser.parse_file path
end

#play_dvd_smplayer_unedited(use_mplayer_instead, show_instructions, show_subs) ⇒ Object



317
318
319
320
321
322
323
324
325
326
327
# File 'lib/gui/sensible-cinema-base.rb', line 317

def play_dvd_smplayer_unedited use_mplayer_instead, show_instructions, show_subs
  drive_or_file, dvd_volume_name, dvd_id, edl_path_maybe_nil, descriptors_maybe_nil = choose_dvd_or_file_and_edl_for_it false
  if descriptors_maybe_nil
    title_track_maybe_nil = get_title_track(descriptors_maybe_nil, false)
  end
  if show_instructions
    # want these even with smplayer sometimes I guess, if in power user mode anyway
    show_mplayer_instructions_once
  end
  run_smplayer_non_blocking drive_or_file, title_track_maybe_nil, "-osd-fractions 2", use_mplayer_instead, show_subs, false
end

#play_mplayer_edl_non_blocking(optional_file_with_edl_path = nil, extra_mplayer_commands_array = [], force_mplayer = false, start_full_screen = true) ⇒ Object



379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# File 'lib/gui/sensible-cinema-base.rb', line 379

def play_mplayer_edl_non_blocking optional_file_with_edl_path = nil, extra_mplayer_commands_array = [], force_mplayer = false, start_full_screen = true
  if optional_file_with_edl_path
    drive_or_file, edl_path = optional_file_with_edl_path
    dvd_id = NonDvd # fake it out...LODO a bit smelly
  else
    drive_or_file, dvd_volume_name, dvd_id, edl_path, descriptors = choose_dvd_or_file_and_edl_for_it
  end
  start_add_this_to_all_ts = 0
  if edl_path # some don't care...
    descriptors = EdlParser.parse_file edl_path
    title_track = get_title_track(descriptors)
    splits = descriptors['mplayer_dvd_splits']
  end
  
  if dvd_id == NonDvd && !(File.basename(File.dirname(drive_or_file)) == 'VIDEO_TS') # VOB's...always start at 0
    # check if starts offset...
    all =  `ffmpeg -i "#{drive_or_file}" 2>&1`
    # Duration: 01:35:49.59, start: 600.000000
    all =~ /Duration.*start: ([\d\.]+)/
    start = $1.to_f
    if start > 1 # LODO huh? dvd's themselves start at 0.3 [sintel]?
      show_non_blocking_message_dialog "Warning: file seems to start at an extra offset, adding it to the timestamps... #{start}
        maybe not compatible with XBMC, if that's what you use, and you probably don't" # TODO test it XBMC...
      start_add_this_to_all_ts = start
    end
    splits = []
  else
    if splits == nil
      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 ).")
      splits = []
    end
  end
  
  if edl_path
    splits.map!{|s|  EdlParser.translate_string_to_seconds(s) }
    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..
    File.write(EdlTempFile, edl_contents)
    extra_mplayer_commands_array << "-edl #{File.expand_path EdlTempFile}" 
  end
  
  run_smplayer_non_blocking drive_or_file, title_track, extra_mplayer_commands_array.join(' '), force_mplayer, false, start_full_screen
end


470
471
472
# File 'lib/gui/sensible-cinema-base.rb', line 470

def print *args
  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)
end

#repeat_last_copy_dvd_to_hard_driveObject



138
139
140
# File 'lib/gui/sensible-cinema-normal.rb', line 138

def repeat_last_copy_dvd_to_hard_drive
  generate_and_run_bat_file *LocalStorage['last_params']
end

#require_blocking_license_accept_dialog(program, license_name, license_url_should_also_be_embedded_by_you_in_message, title = 'Confirm Acceptance of License Agreement', message = nil) ⇒ Object



429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
# File 'lib/gui/sensible-cinema-base.rb', line 429

def require_blocking_license_accept_dialog program, license_name, license_url_should_also_be_embedded_by_you_in_message, 
  title = 'Confirm Acceptance of License Agreement', message = nil
  puts 'Please confirm license agreement in open window.'
  
  message ||= "Sensible Cinema requires a separately installed program (#{program}), not yet installed.
    You can install this program manually to the vendor/cache subdirectory, or Sensible Cinema can download it for you.
    By clicking accept, below, you are confirming that you have read and agree to be bound by the
    terms of its license (the #{license_name}), located at #{license_url_should_also_be_embedded_by_you_in_message}.  
    Click 'View License' to view it.  If you do not agree to these terms, click 'Cancel'.  You also agree that this is a 
    separate program, with its own distribution, license, ownership and copyright.  
    You agree that you are responsible for the download and use of this program, within sensible cinema or otherwise."
  answer = JOptionPane.show_select_buttons_prompt message, :yes => 'Accept', :no => "View #{license_name}"
  assert_confirmed_dialog answer, license_url_should_also_be_embedded_by_you_in_message
  p 'confirmation of sensible cinema related license noted of: ' + license_name # LODO require all licenses together :P
  throw unless answer == :yes
end

#run_batch_file_commands_and_use_output_somehow(batch_commands, save_to, file_from, run_mplayer_after_done) ⇒ Object



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/gui/sensible-cinema-normal.rb', line 244

def run_batch_file_commands_and_use_output_somehow batch_commands, save_to, file_from, run_mplayer_after_done
  @buttons.each{|b| b.set_enabled false}
  success = true
  lines = batch_commands.lines.to_a
  total_size = lines.length.to_f
  @progress_bar.visible=true
  @progress_bar.set_value(10) # start at 10% always, so they can see something.
  lines.each_with_index{|line, idx|
    if success
      puts "running #{line}"
      success = system_blocking(line, true)
      if !success
        puts "\n", 'line failed: ' + line + "\n" + '   see troubleshooting section in README.txt file! ignoring further processing commands...'
      end
    end
    @progress_bar.set_value(10 + idx/total_size*90)
  }
  @progress_bar.visible=false
  @buttons.each{|b| b.set_enabled true}
  if success
    saved_to = save_to + '.avi'
    if run_mplayer_after_done
      run_smplayer_non_blocking saved_to, nil, '', false, false, true
    else
      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.
        show_blocking_message_dialog("Warning: file size differs by more than 50%--it's possible that transcoding failed somehow")
      end            
      show_in_explorer saved_to
      PlayAudio.play(File.expand_path(File.dirname(__FILE__)) + "/../vendor/music.wav")
      msg =  "Done--you may now watch file\n #{saved_to}\n in VLC player (or possibly smplayer)"
      puts msg # for being able to tell it's done on the command line
      show_blocking_message_dialog msg
      show_in_explorer saved_to # and again, just for kicks [?]
    end
  else
    SwingHelpers.show_blocking_message_dialog "Failed--please examine console output and report back!\nAlso consult the documentation/troubleshooting file.", "Failed", JOptionPane::ERROR_MESSAGE
  end
end

#run_smplayer_blocking(play_this, title_track_maybe_nil, passed_in_extra_options, force_use_mplayer, show_subs, start_full_screen) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/gui/sensible-cinema-base.rb', line 174

def run_smplayer_blocking play_this, title_track_maybe_nil, passed_in_extra_options, force_use_mplayer, show_subs, start_full_screen
  unless File.exist?(File.expand_path(play_this))
    raise play_this + ' non existing?' # till these go away in mac :)
  end

  extra_options = ""
  # -framedrop is for slow CPU's
  # same with -autosync to try and help it stay in sync... -mc 0.03 is to A/V correct 1s audio per 2s video
  # -hardframedrop might help but hurts just too much
  extra_options << " -framedrop "      
  # ?? extra_mplayer_commands << "-mc 0.016" ??
  extra_options << " -autosync 15 " 
  
  unless show_subs
    # disable subtitles
    extra_options << " -nosub -noautosub -forcedsubsonly -sid 1000 "
  end
  extra_options << " -alang en "
  extra_options += " -slang en "

  parent_parent = File.basename(File.dirname(play_this))
  force_use_mplayer ||= OS.mac?
  if parent_parent == 'VIDEO_TS'
    # case d:\yo\VIDEO_TS\title0.vob
    dvd_device_dir = normalize_path(File.dirname(play_this))
    if force_use_mplayer
      extra_options += " -dvd-device \"#{dvd_device_dir}/..\""
    else 
      # smplayer
      raise if dvd_device_dir =~ / / && OS.mac? # not accomodated <sniff>
      extra_options += " -dvd-device #{dvd_device_dir}/.."
    end
    play_this = "dvdnav://#{title_track_maybe_nil}"
  elsif File.exist?(play_this + '/VIDEO_TS')
    # case d:\ where d:\VIDEO_TS exists [DVD mounted in drive] or mac's /Volumes/YO
    raise if play_this =~ / / # unexpected
    extra_options += " -nocache -dvd-device #{play_this}"
    play_this = "dvdnav://#{title_track_maybe_nil}"
  else
    # case g:\video\filename.mpg
    # leave it the same...
  end
  if play_this =~ /dvdnav/ && title_track_maybe_nil
    extra_options << " -msglevel identify=4 " # prevent smplayer from using *forever* to look up info on DVD's with -identify ...
  end
  
  extra_options += " -mouse-movements #{get_upconvert_secondary_settings} " # just in case smplayer also needs -mouse-movements... :) LODO
  extra_options += " -lavdopts threads=#{OS.cpu_count} " # just in case this helps [supposed to with h.264] # fast *crashes* doze...
  if force_use_mplayer
   show_mplayer_instructions_once
   conf_file = File.expand_path './mplayer_input_conf'
   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.
   extra_options += " -font #{File.expand_path('subfont.ttf')} "
   extra_options += " -volume 100 " # why start low? mplayer why oh why LODO
   if OS.windows?
    # direct3d for windows 7 old nvidia cards' sake [yipes] and also dvdnav sake
    extra_options += " -vo direct3d "
    conf_file = conf_file[2..-1] # strip off drive letter, which it doesn't seem to like no sir
   end
   if start_full_screen
     extra_options += " -fs "
     upconv = get_upconvert_vf_settings
     upconv = "-vf #{upconv}" if upconv.present?
   else
    upconv = ""
   end
   c = "mplayer #{extra_options} #{upconv} -input conf=\"#{conf_file}\" #{passed_in_extra_options} \"#{play_this}\" "
  else
    if OS.windows?
      extra_options += " -vo direct3d " # more light nvidia...should be ok...
    end
    set_smplayer_opts extra_options + " " + passed_in_extra_options, get_upconvert_vf_settings, show_subs
    c = "smplayer_portable \"#{play_this}\" -config-path \"#{File.dirname SMPlayerIniFile}\" " 
    c += " -fullscreen " if start_full_screen
    if !we_are_in_create_mode
      #c += " -close-at-end " # we're still too unstable, mate...
    end
  end
  puts c 
  system_blocking c
end

#run_smplayer_non_blocking(*args) ⇒ Object



167
168
169
170
171
172
# File 'lib/gui/sensible-cinema-base.rb', line 167

def run_smplayer_non_blocking *args
  pp caller
  @background_thread = Thread.new {
    run_smplayer_blocking *args
  }
end

#select_new_sxs_styleObject



8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/gui/sensible-cinema-side-by-side.rb', line 8

def select_new_sxs_style
  answer = show_select_buttons_prompt 'Select EDL file style creation for this program', :yes => 'Smplayer style', :no => 'XBMC style'
  if answer == :yes
    LocalStorage[SideBySide] = 'smplayer'
  elsif answer == :no
    LocalStorage[SideBySide] = 'xbmc'
  else
    show_blocking_message_dialog 'please choose one--smplayer if you don\'t know'
    select_new_sxs_style
  end
    
end

#set_smplayer_opts(to_this, video_, show_subs = false) ⇒ Object



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/gui/sensible-cinema-base.rb', line 258

def set_smplayer_opts to_this, video_, show_subs = false
  p 'set smplayer extra opts to this:' + to_this
  old_prefs = File.read(SMPlayerIniFile) rescue ''
  unless old_prefs.length > 0
    # LODO double check the rest here...
    old_prefs = "[advanced]\nmplayer_additional_options=\nmplayer_additional_video_filters=\n[subtitles]\nautoload_sub=false\n[performance]\npriority=3" 
  end
  raise to_this if to_this =~ /"/ # unexpected, unfortunately... <smplayer bug>
  assert new_prefs = old_prefs.gsub(/mplayer_additional_options=.*/, "mplayer_additional_options=#{to_this}")
  assert new_prefs.gsub!(/autoload_sub=.*$/, "autoload_sub=#{show_subs.to_s}")
  raise if get_upconvert_vf_settings =~ /"/
  assert new_prefs.gsub!(/mplayer_additional_video_filters=.*$/, "mplayer_additional_video_filters=\"#{get_upconvert_vf_settings}\"")
  new_prefs.gsub!(/priority=.*$/, "priority=3") # normal priority...scary otherwise! lodo tell smplayer...
  # enable dvdnav navigation, just for kicks I guess.
  new_prefs.gsub!(/use_dvdnav=.*$/, "use_dvdnav=true")
  
  FileUtils.mkdir_p File.dirname(SMPlayerIniFile) # case it doesn't yet exist
  File.write(SMPlayerIniFile, new_prefs)
  new_prefs.each_line{|l| print l if l =~ /additional_video/} # debug
end

#setup_advanced_buttonsObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/gui/sensible-cinema-create.rb', line 5

def setup_advanced_buttons

  new_jbutton("Display the standard buttons") do
    window = new_child_window
    window.setup_normal_buttons
  end
  
  @mplayer_edl = new_jbutton( "Watch DVD edited (realtime) (mplayer)")
  @mplayer_edl.on_clicked {
    play_mplayer_edl_non_blocking nil, [], true, false
  }

  add_text_line 'Realtime/Create Options:'
  
  @create_new_edl_for_current_dvd = new_jbutton("Create new Edit List for a DVD", 
    "If your DVD doesn't have an EDL created for it, this will be your first step--create an EDL file for it.")
  @create_new_edl_for_current_dvd.on_clicked do
    create_brand_new_edl
    @display_dvd_info.simulate_click # for now...
  end
  
  @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.")
  @open_list.on_clicked {
    filename = new_existing_file_selector_and_select_file( "Pick any file to open in editor", EdlParser::EDL_DIR)
    open_file_to_edit_it filename
  }
  
  @play_smplayer = new_jbutton( "Watch full DVD unedited (realtime smplayer)")
  @play_smplayer.tool_tip = "    This will play the DVD unedited within smplayer.\n    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 \n    i.e. if it just plays a single preview title or what not, and not the main title, you need to change this value.\n    This is useful if you want to just kind of watch the movie to enjoy it, and look for scenes to cut out.\n    You can use the built-in OSD (on-screen-display) to see what time frame the questionable scenes are at\n    (type \"o\" to toggle it).  However, just realize that the OSD is in 30 fps, and our time stamps are all in 29.97\n    fps, so you'll need to convert it (the convert timestamp button) to be able to use it in a file.\n  EOL\n  @play_smplayer.on_clicked {\n    play_dvd_smplayer_unedited false, true, true\n  }\n\n  @play_mplayer_raw = new_jbutton( \"Watch full DVD unedited (realtime mplayer)\")\n  @play_mplayer_raw.tool_tip = <<-EOL\n    This is also useful for comparing subtitle files to see if they have accurate timings.\n    If you turn on subtitles (use the v button), then compare your srt file at say, the 1 hour mark, or 2 hour mark,\n    with the subtitles that mplayer displays, it *should* match exactly with the output in the command line,\n    like \"V: 3600.0\" should match your subtitle line \"01:00:00,000 --> ...\"\n  EOL\n  @play_mplayer_raw.on_clicked {\n    play_dvd_smplayer_unedited true, true, true\n  }\n  \n  @parse_srt = new_jbutton(\"Scan a subtitle file (.srt) to detect profanity times automatically\" )\n  @parse_srt.tool_tip = <<-EOL\n    You can download a .srt file and use it to programmatically search for the location of various profanities.\n    Basically download it from opensubtitles.org (or engsub.net et al),\n    (for opensubtitles.org enter dvd title in the search box, click on a result, click one from the list with an English flag, \n    then choose 'Download(zip)', then unzip the file)\n    NB that you'll want/need to *carefully* double check your subtitle file for accuracy. Here's how:\n    Now carefully compare a beginning timestamp in it with the actual words in the .srt file \n    with the actual DVD.\n    (see the button \"Watch DVD unedited (realtime mplayer)\")\n    (smplayer can kind of do it, too, play it, hit the 'o' button to display\n    the OSD timestamp, then go to just before the verbiage, \n    and hit the '.' key until a subtitle very first appears.\n    Next convert that number to 29.97 fps (using the button for that).\n  EOL\n\n  @parse_srt.on_clicked do\n    srt_filename = new_existing_file_selector_and_select_file(\"Pick srt file to scan for profanity:\")\n    # TODO nuke\n    add_to_beginning = \"0.0\"#get_user_input(\"How much time to subtract from the beginning of every subtitle entry (ex: (1:00,1:01) becomes (0:59,1:01))\", \"0.0\")\n    add_to_end = \"0.0\"#get_user_input(\"How much time to add to the end of every subtitle entry (ex: (1:00,1:04) becomes (1:00,1:05))\", \"0.0\")\n    \n    @show_parse_instructions ||= show_blocking_message_dialog \"Now enter some values which will adjust the .srt time signatures\\nso that it matches the movie more precisely.\\nWe also need these values to coordinate it with other devices that may have different timestamps.\\nFor DVD playback this will be the timestamps mplayer shows within the console window [the mplayer unedited button].\"\n    open_file_to_edit_it srt_filename\n    sleep 0.5 # let it open first\n    bring_to_front\n    start_text = get_user_input(\"enter the text from any subtitle entry near beginning [like \\\"Hello, welcome to our movie.\\\"]\", \"...\")\n    start_srt = get_user_input(\"enter beginning timestamp within the .srt file \#{File.basename(srt_filename)[0..10]}... for \\\"\#{start_text}\\\"\", \"00:00:00,000\")\n    start_movie_ts = get_user_input(\"enter beginning timestamp within the movie itself for said text\", \"0:00:00\")\n    \n    end_text = get_user_input(\"enter the text from a subtitle entry far within or near the end of the movie\", \"...\")\n    end_srt = get_user_input(\"enter the beginning timestamps within the .srt for \\\"\#{end_text}\\\"\", \"02:30:00,000\")\n    end_movie_ts  = get_user_input(\"enter beginning timestamps within the movie itself for \\\"\#{end_text}\\\"\", \"2:30:00.0 or 9000.0\")\n    \n    parsed_profanities = SubtitleProfanityFinder.edl_output srt_filename, {}, add_to_beginning.to_f, add_to_end.to_f, start_srt, start_movie_ts, end_srt, end_movie_ts\n    File.write EdlTempFile, \"# add these into your mute section if you deem them mute-worthy\\n\" + parsed_profanities +\n      %!\\n\\n#Also add these two lines for later coordination:\\n\"beginning_subtitle\" => [\"\#{start_text}\", \"\#{start_movie_ts}\"],! +\n       %!\\n\"ending_subtitle_entry\" => [\"\#{end_text}\", \"\#{end_movie_ts}\"]!\n    open_file_to_edit_it EdlTempFile\n  end\n\n  @display_dvd_info = new_jbutton( \"Display information about current DVD (ID, etc.)\" )\n  @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.\"\n  @display_dvd_info.on_clicked {\n    drive, volume_name, dvd_id = choose_dvd_drive_or_file true # real DVD disk\n    # display it, allow them to copy and paste it out\n    title_lengths = nil\n    t = Thread.new { title_lengths= `mplayer dvdnav:// -nocache -dvd-device \#{drive} -identify -frames 0 2>&1| grep LENGTH` }\n    id_string = \"\\\"disk_unique_id\\\" => \\\"\#{dvd_id}\\\", # \#{volume_name}\"\n    show_copy_pastable_string \"\#{drive} \#{volume_name} for your copying+pasting pleasure (highlight, then ctrl+c to copy)\\n\n    This is USED eventually to identify a disk to match it to its EDL, later.\", id_string\n    t.join\n    File.write EdlTempFile, id_string + \"\\n\" + title_lengths\n    open_file_to_edit_it EdlTempFile\n    id_string\n  }\n\n  @convert_seconds_to_ts = new_jbutton( \"Convert 3600.0 <-> 1:00:00 style timestamps\" )\n  @convert_seconds_to_ts.on_clicked {\n    input = get_user_input(\"Enter \\\"from\\\" timestamps, like 3600 or 1:40:00:\", \"1:00:00.1 or 3600.1\")\n    while(input)\n      if input =~ /:/\n        output = EdlParser.translate_string_to_seconds input\n      else\n        output = EdlParser.translate_time_to_human_readable input.to_f, true\n      end \n      input = show_copy_pastable_string(\"Converted:\", output)         \n    end\n  }\n  \n  @convert_timestamp = new_jbutton( \"Convert timestamp from DVD player time to EDL time (30->29.97 fps)\" )\n  @convert_timestamp.tool_tip=<<-EOL\n    Our EDL's assume 29.97 fps (which is what a DVD actually has).  Unfortunately most hardware or commercial DVD players\n    think that the DVD is 30 fps, which means that if you use them for timestamps for your EDL's,\n    you will be slightly off (at the end of a 2 hour film, by 8 seconds).  So all your edits will be wrong.\n    How to fix: convert your times from \"DVD player\" time to \"EDL accurate\" time by using this button.\n    This is necessary for all hardware DVD player timestamps, PowerDVD player (software), Windows Media Player (playing a DVD), \n    and mplayer's \"on screen display\" DVD timestamps.\n    It is not necessary for smplayer timestamps (or mplayer's \"V: 3600\" in the command line), which are already 29.97.\n    smplayer's on-screen-display (the 'o' key) is accurate (and doesn't suffer from dvd_mplayer_splits) \n    but is 30 fps, so timestamps would need to be converted.\n    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.\n    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.\n    Mplayers \"V: 3600\" is usually right on (29.97 fps), however.\n  EOL\n  @convert_timestamp.on_clicked {\n    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\")\n    thirty_fps_in_seconds = EdlParser.translate_string_to_seconds thirty_fps\n    twenty_nine_seven_fps = ConvertThirtyFps.from_thirty(thirty_fps_in_seconds)\n    human_twenty_nine_seven = EdlParser.translate_time_to_human_readable twenty_nine_seven_fps, true\n    show_copy_pastable_string(\"Sensible cinema usable value (29.97 fps) for \#{thirty_fps} would be:                \", human_twenty_nine_seven)\n  }\n  \n  @create_dot_edl = new_jbutton( \"Create a side-by-side moviefilename.edl file\")\n  @create_dot_edl.tool_tip = <<-EOL\n    Creates a moviefilename.edl file (corresponding to some moviefilename.some_ext file already existing)\n    XBMC/smplayer (smplayer can be used by WMC plugins, etc.) \"automagically detect\", \n    if it exists, and automatically use it .edl to show that file edited played back.\n    If you use smplayer, note that you'll need to download the \"lord mulder mplayer\"\n    version (which includes an updated version of mplayer that fixes some bugs in EDL playback)\n  EOL\n  @create_dot_edl.on_clicked {\n    choose_file_and_edl_and_create_sxs_or_play true\n  }\n  \n  add_text_line 'Create Options with local intermediary file:'\n  \n  new_jbutton(\"Show options with local intermediary file\") do\n    window = new_child_window\n    window.add_options_that_use_local_files\n  end\n  \n#      @reload = new_jbutton(\"reload bin/sensible-cinema code\") do\n#        load $0\n#      end\n  \nend\n"

#setup_default_buttonsObject



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/gui/sensible-cinema-normal.rb', line 103

def setup_default_buttons
  if we_are_in_upconvert_mode
    add_play_upconvert_buttons
  else
  
    if we_are_in_create_mode
      setup_advanced_buttons
      add_text_line 'Contact:'
    else
      setup_normal_buttons
    end
  
    @upload = new_jbutton("Submit Feedback/Upload new EDL's/Request Help") # keeps this one last! :)
    @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!"
    @upload.on_clicked {
      system_non_blocking("start mailto:[email protected]")
      system_non_blocking("start http://groups.google.com/group/sensible-cinema")
    }
    increment_button_location

  end
  
  @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!")
  @exit.on_clicked {
    Thread.new { self.close } # don't waste the time to close it :P
    puts 'Thank you for using Sensible Cinema. Come again!'
    System.exit 0
  }

  increment_button_location
  increment_button_location
  self

end

#setup_normal_buttonsObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/gui/sensible-cinema-normal.rb', line 33

def setup_normal_buttons
  add_text_line ""
  
  @mplayer_edl = new_jbutton( "Watch DVD edited (realtime)")
  @mplayer_edl.tool_tip = "This will watch your DVD in realtime from your computer while skipping/muting questionable scenes."
  @mplayer_edl.on_clicked {
    play_mplayer_edl_non_blocking
  }
  
  @create = new_jbutton( "Create edited copy of DVD/file on Your Hard Drive" )
  @create.tool_tip = "    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.\n    The file you create will contain the whole movie edited.\n    It takes quite awhile maybe 2 hours.  Sometimes the progress bar will look paused--it typically continues eventually.\n  EOL\n  @create.on_clicked {\n    do_create_edited_copy_via_file false\n  }\n  \n  @watch_file_edl = new_jbutton( \"Watch movie file edited (realtime)\" ) do\n    choose_file_and_edl_and_create_sxs_or_play false \n  end\n  \n  if LocalStorage[UpConvertEnglish]\n    add_text_line ''\n    add_open_documentation_button\n    @upconv_line = add_text_line \"    \#{get_current_upconvert_as_phrase}\"\n  else\n    @upconv_line = add_text_line ''\n    add_open_documentation_button\n  end\n  \n  add_change_upconvert_options_button\n  \n  @progress_bar = JProgressBar.new(0, 100)\n  @progress_bar.set_bounds(44,@starting_button_y,@button_width,23)\n  @progress_bar.visible = false\n  @panel.add @progress_bar\n\nend\n"

#show_blocking_message_dialog(message, title = , style = JOptionPane::INFORMATION_MESSAGE) ⇒ Object



567
568
569
570
# File 'lib/gui/sensible-cinema-base.rb', line 567

def show_blocking_message_dialog(message, title = message.split("\n")[0], style= JOptionPane::INFORMATION_MESSAGE)
  bring_to_front
  SwingHelpers.show_blocking_message_dialog message, title, style
end

#show_copy_pastable_string(message, value) ⇒ Object



586
587
588
589
590
# File 'lib/gui/sensible-cinema-base.rb', line 586

def show_copy_pastable_string(message, value)
  bring_to_front
  RubyClip.set_clipboard value            
  get_user_input message + " (has been copied to clipboard)", value, true
end

#show_in_explorer(filename) ⇒ Object



601
602
603
# File 'lib/gui/sensible-cinema-base.rb', line 601

def show_in_explorer filename
  SwingHelpers.show_in_explorer filename
end

#show_mplayer_instructions_onceObject



336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/gui/sensible-cinema-base.rb', line 336

def show_mplayer_instructions_once
  @_show_mplayer_instructions_once ||= show_non_blocking_message_dialog "    About to run mplayer.  To control it, use\n    spacebar : pause,\n    double clicky/right click : toggle full screen,\n    arrow keys (left, right, up down, pg up, pg dn) to seek/scan\n    / and * : inc/dec volume.\n    '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).\n    'v' key: turn off subtitles.\n    '.' key: step one frame.\n     # key: change audio language track\n  EOL\nend\n"

#show_non_blocking_message_dialog(message, close_button_text = 'Close') ⇒ Object

call dispose on this to close it if it hasn’t been canceled yet…



573
574
575
576
577
# File 'lib/gui/sensible-cinema-base.rb', line 573

def show_non_blocking_message_dialog message, close_button_text = 'Close'
  bring_to_front
  # lodo NonBlockingDialog it can get to the top instead of being so buried...
  NonBlockingDialog.new(message, close_button_text)
end

#system_blocking(command, low_prio = false) ⇒ Object



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/gui/sensible-cinema-base.rb', line 278

def system_blocking command, low_prio = false
  return true if command =~ /^@rem/ # JRUBY-5890 bug
  if low_prio
    out = IO.popen(command) # + " 2>&1"
    low_prio = 64 # from msdn
    
    if command =~ /(ffmpeg|mencoder)/
      # XXXX not sure if there's a better way...because some *are* complex and have ampersands...
      # unfortunately have to check for nil because it could exit too early [?]
      exe_name = $1 + '.exe'
      begin
        p = proc{ ole = WMI::Win32_Process.find(:first,  :conditions => {'Name' => exe_name}); sleep 1 unless ole; ole }
        piddy = p.call || p.call || p.call # we actually do need this to loop...guess we're too quick
        # but the first time through this still inexplicably fails all 3...odd
        piddys = WMI::Win32_Process.find(:all,  :conditions => {'Name' => exe_name})
        for piddy in piddys
          # piddy.SetPriority low_prio # this call can seg fault at times...JRUBY-5422
          pid = piddy.ProcessId # this doesn't seg fault, tho
          system_original("vendor\\setpriority -lowest #{pid}") # uses PID for the command line
        end
      rescue Exception => e
        p 'warning, got exception trying to set priority [jruby prob? ...]', e
      end
    end
    print out.read # let it finish
    out.close
    $?.exitstatus == 0 # 0 means success
  else
    raise command + " failed env #{ENV['PATH']}" unless system_original command
  end
end

#system_non_blocking(command) ⇒ Object



310
311
312
# File 'lib/gui/sensible-cinema-base.rb', line 310

def system_non_blocking command
  @background_thread = Thread.new { system_original command }
end

#upconvert_set_to_anything?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/gui/sensible-cinema-upconvert.rb', line 36

def upconvert_set_to_anything?
  LocalStorage[UpConvertEnglish].present?
end

#warn_if_no_upconvert_options_currently_selectedObject



51
52
53
54
55
56
57
# File 'lib/gui/sensible-cinema-upconvert.rb', line 51

def warn_if_no_upconvert_options_currently_selected
  if !upconvert_set_to_anything?
    show_non_blocking_message_dialog "Warning: upconvert options have not been set yet--set upconvert options first, if desired."
  else
    JFrame.new # something it can call dispose on :P

  end
end

#we_are_in_create_modeObject



107
108
109
# File 'lib/gui/sensible-cinema-base.rb', line 107

def we_are_in_create_mode
 ARGV.index("--create-mode")
end

#we_are_in_upconvert_modeObject



99
100
101
# File 'lib/gui/sensible-cinema-normal.rb', line 99

def we_are_in_upconvert_mode
   ARGV.index("--upconvert-mode")
end

#when_thread_done(thread) ⇒ Object



151
152
153
# File 'lib/gui/sensible-cinema-base.rb', line 151

def when_thread_done(thread)
  Thread.new {thread.join; yield }
end