content-editing-movie-player 0.38.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (273) hide show
  1. data/.gitmodules +3 -0
  2. data/.rvmrc +1 -0
  3. data/LICENSE.TXT +20 -0
  4. data/README.TXT +225 -0
  5. data/Rakefile +206 -0
  6. data/TODO +740 -0
  7. data/VERSION +1 -0
  8. data/_DO_NOT_RUN_IT_FROM_HERE_DOWNLOAD_THE_RELEASE_ZIP_FROM_SOURCEFORGE_INSTEAD +0 -0
  9. data/bin/sensible-cinema +60 -0
  10. data/bin/sensible-cinema-cli +161 -0
  11. data/business_ideas.txt +21 -0
  12. data/change_log_with_feature_list.txt +952 -0
  13. data/documentation/DOCUMENTATION_README.TXT +44 -0
  14. data/documentation/how_to_get_files_from_dvd.txt +30 -0
  15. data/documentation/is_it_legal_to_copy_dvds.txt +97 -0
  16. data/documentation/troubleshooting.txt +30 -0
  17. data/documentation/upconversion.txt +4 -0
  18. data/experimental_online_player_ocr_readme.txt +45 -0
  19. data/go +1 -0
  20. data/go.bat +2 -0
  21. data/go.sh +1 -0
  22. data/go_ocr_tracker.bat +1 -0
  23. data/goc +1 -0
  24. data/goc.bat +1 -0
  25. data/goc.sh +1 -0
  26. data/gpl-2.0.txt +339 -0
  27. data/gplv3.txt +219 -0
  28. data/history_and_related_works_list.txt +108 -0
  29. data/inventionzy_files/cone.png +0 -0
  30. data/inventionzy_files/md5s.txt +53 -0
  31. data/inventionzy_files/play_with_inserted_scene.bat +8 -0
  32. data/inventionzy_files/play_with_overlay.bat +24 -0
  33. data/inventionzy_files/transcript_mute_vlc.txt +117 -0
  34. data/legal_draft +23 -0
  35. data/lib/add_any_bundled_gems_to_load_path.rb +32 -0
  36. data/lib/auto_window_finder.rb +41 -0
  37. data/lib/blanker.rb +104 -0
  38. data/lib/check_installed_mac.rb +34 -0
  39. data/lib/convert_thirty_fps.rb +20 -0
  40. data/lib/edl_parser.rb +387 -0
  41. data/lib/eight_three.rb +28 -0
  42. data/lib/extract/dumpstream.bat +1 -0
  43. data/lib/extract/get_init.bat +3 -0
  44. data/lib/extract/pause_early.rb +13 -0
  45. data/lib/fake_blanker.rb +35 -0
  46. data/lib/frame_accurate.rb +3 -0
  47. data/lib/gui/base.rb +748 -0
  48. data/lib/gui/create-file.rb +24 -0
  49. data/lib/gui/create.rb +581 -0
  50. data/lib/gui/dependencies.rb +219 -0
  51. data/lib/gui/normal.rb +123 -0
  52. data/lib/gui/upconvert.rb +284 -0
  53. data/lib/keyboard_input.rb +60 -0
  54. data/lib/media_info_parser.rb +27 -0
  55. data/lib/mouse_forever.rb +19 -0
  56. data/lib/movie_hasher.rb +27 -0
  57. data/lib/mplayer_edl.rb +42 -0
  58. data/lib/muter.rb +87 -0
  59. data/lib/ocr.rb +125 -0
  60. data/lib/ocr_seed/netflix_b9.bmp +0 -0
  61. data/lib/overlayer.rb +373 -0
  62. data/lib/screen_tracker.rb +269 -0
  63. data/lib/subtitle_profanity_finder.rb +294 -0
  64. data/lib/vlc_programmer.rb +112 -0
  65. data/lib/zoom_player_max_edl.rb +50 -0
  66. data/never_do +40 -0
  67. data/notes_for_potential_developers.txt +46 -0
  68. data/preamble +17 -0
  69. data/roadmap_possibilities +12 -0
  70. data/spec/arse.srt +41 -0
  71. data/spec/auto_window_finder.spec.rb +65 -0
  72. data/spec/bad_beginning.srt +3778 -0
  73. data/spec/blanker.spec.rb +60 -0
  74. data/spec/common.rb +81 -0
  75. data/spec/convert_image.rb +25 -0
  76. data/spec/deity_end.srt +11 -0
  77. data/spec/dragon.srt +34 -0
  78. data/spec/edl_parser.spec.rb +270 -0
  79. data/spec/frame_accurate.spec.rb +71 -0
  80. data/spec/keyboard_input.spec.rb +73 -0
  81. data/spec/media_info_parser.spec.rb +29 -0
  82. data/spec/mplayer_edl.spec.rb +100 -0
  83. data/spec/muter.spec.rb +50 -0
  84. data/spec/notes +4996 -0
  85. data/spec/ocr.spec.rb +119 -0
  86. data/spec/overlayer.spec.rb +440 -0
  87. data/spec/screen_tracker.spec.rb +318 -0
  88. data/spec/sensible_cinema_gui.spec.rb +452 -0
  89. data/spec/subtitle_profanity_finder.spec.rb +224 -0
  90. data/spec/test_yaml.yml +4 -0
  91. data/spec/tsmuxer.output +33 -0
  92. data/spec/vlc_programmer.spec.rb +124 -0
  93. data/spec/youtube_edl.spec.rb +28 -0
  94. data/spec/zoom_player_max_edl.spec.rb +29 -0
  95. data/template_bats/README_DISTRO.TXT +8 -0
  96. data/template_bats/RUN SENSIBLE CINEMA CLICK HERE WINDOWS.bat +25 -0
  97. data/template_bats/_DO_NOT_RUN_IT_FROM_HERE_DOWNLOAD_THE_RELEASE_ZIP_FROM_SOURCEFORGE_INSTEAD +0 -0
  98. data/template_bats/mac/RUN SENSIBLE CINEMA CLICK HERE.command +5 -0
  99. data/template_bats/mac/advanced--create or edit sensible cinema edit list files.command +3 -0
  100. data/template_bats/mac/advanced--run-upconverting-video-player.command +3 -0
  101. data/template_bats/pc/advanced--create or edit sensible cinema edit list files.bat +2 -0
  102. data/template_bats/pc/advanced--run-upconverting-video-player.bat +2 -0
  103. data/todo.build_library.txt +11 -0
  104. data/todo.inventionzy.txt +162 -0
  105. data/todo.open_edl_list_org.txt +169 -0
  106. data/todo.propaganda +107 -0
  107. data/todo.subtitle +17 -0
  108. data/todo.upconvert +53 -0
  109. data/upconvert.bat +1 -0
  110. data/upconvert_from_screen/go_upscaling.bat +12 -0
  111. data/upconvert_from_screen/go_upscaling_works +0 -0
  112. data/upconvert_from_screen/old/latest2/combine_video.avs +23 -0
  113. data/upconvert_from_screen/old/latest2/go_no_upscaling.bat +1 -0
  114. data/upconvert_from_screen/old/latest2/go_upscaling.bat +12 -0
  115. data/upconvert_from_screen/old/latest2/push2.GRF +0 -0
  116. data/upconvert_from_screen/old/latest2/push3.grf +0 -0
  117. data/upconvert_from_screen/old/latest2/setup_capture_coords.rb +27 -0
  118. data/upconvert_from_screen/old/latest2/setup_directshow_filter_params.rb +29 -0
  119. data/upconvert_from_screen/old/latest2/upconvert_from_screen_me2.avs +19 -0
  120. data/upconvert_from_screen/old/latest_now_possibly_oudated/push2.GRF +0 -0
  121. data/upconvert_from_screen/old/latest_now_possibly_oudated/upconvert_from_screen_me2.avs +18 -0
  122. data/upconvert_from_screen/old/position_window.png +0 -0
  123. data/upconvert_from_screen/old/push_source_desktop.GRF +0 -0
  124. data/upconvert_from_screen/old/record_screen/record.bat +2 -0
  125. data/upconvert_from_screen/old/upconvert_from_screen.avs +21 -0
  126. data/upconvert_from_screen/old/upconvert_from_screen_me.avs +21 -0
  127. data/upconvert_from_screen/old/upconvert_from_screen_me2.avs +3 -0
  128. data/upconvert_from_screen/old/upconvert_from_screen_me_push_source.avs +3 -0
  129. data/upconvert_from_screen/old/uscreen.GRF +0 -0
  130. data/upconvert_from_screen/old/uscreen_me.GRF +0 -0
  131. data/upconvert_from_screen/push3.grf +0 -0
  132. data/upconvert_from_screen/upconvert_from_screen_me2.avs +19 -0
  133. data/vendor/movie-content-editor-read-only/.metadata/.lock +0 -0
  134. data/vendor/movie-content-editor-read-only/.metadata/.mylyn/.tasks.xml.zip +0 -0
  135. data/vendor/movie-content-editor-read-only/.metadata/.mylyn/repositories.xml.zip +0 -0
  136. data/vendor/movie-content-editor-read-only/.metadata/.mylyn/tasks.xml.zip +0 -0
  137. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version +1 -0
  138. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index +0 -0
  139. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version +1 -0
  140. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.resources/.root/2.tree +0 -0
  141. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources +0 -0
  142. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs +3 -0
  143. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs +14 -0
  144. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs +3 -0
  145. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs +5 -0
  146. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs +3 -0
  147. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache +0 -0
  148. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat +0 -0
  149. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml +2 -0
  150. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml +2 -0
  151. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml +10 -0
  152. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml +11 -0
  153. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.ui.intro/dialog_settings.xml +4 -0
  154. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml +10 -0
  155. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml +232 -0
  156. data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml +4 -0
  157. data/vendor/movie-content-editor-read-only/.metadata/version.ini +1 -0
  158. data/vendor/movie-content-editor-read-only/.project +17 -0
  159. data/vendor/movie-content-editor-read-only/.pydevproject +11 -0
  160. data/vendor/movie-content-editor-read-only/.settings/org.eclipse.core.resources.prefs +6 -0
  161. data/vendor/movie-content-editor-read-only/SubIt.py +171 -0
  162. data/vendor/movie-content-editor-read-only/VLCMacVideo.py +257 -0
  163. data/vendor/movie-content-editor-read-only/VideoMac.ui +102 -0
  164. data/vendor/movie-content-editor-read-only/badwords.txt +4 -0
  165. data/vendor/movie-content-editor-read-only/blank.srt +4 -0
  166. data/vendor/movie-content-editor-read-only/edit.py +197 -0
  167. data/vendor/movie-content-editor-read-only/mergeCommands.py +73 -0
  168. data/vendor/movie-content-editor-read-only/mute.txt +5 -0
  169. data/vendor/movie-content-editor-read-only/panda.srt +4235 -0
  170. data/vendor/movie-content-editor-read-only/panda_custom.txt +3 -0
  171. data/vendor/movie-content-editor-read-only/panda_edit.srt +4235 -0
  172. data/vendor/movie-content-editor-read-only/subtitle.py +90 -0
  173. data/vendor/movie-content-editor-read-only/vlc.py +5579 -0
  174. data/vendor/movie-content-editor-read-only/vlcwidget.py +154 -0
  175. data/vendor/mplayer_patches/how_to_doze.bat +6 -0
  176. data/vendor/mplayer_patches/port_dir/PortIndex.quick +2 -0
  177. data/vendor/mplayer_patches/port_dir/how_to +20 -0
  178. data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/Portfile +285 -0
  179. data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/files/configure.x11.patch +20 -0
  180. data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/files/llvm-gcc-workaround.patch +11 -0
  181. data/vendor/mplayer_patches/port_dir/multimedia/rdp-projects/Portfile +43 -0
  182. data/vendor/mplayer_patches/port_dir_is_for_mac +0 -0
  183. data/www/content_editor.html +92 -0
  184. data/www/index.html +47 -0
  185. data/www/upconverting_movie_player.html +62 -0
  186. data/www/video reel.jpg +0 -0
  187. data/www/youtube_edl/.htaccess +44 -0
  188. data/www/youtube_edl/control_youtube.rhtml +141 -0
  189. data/www/youtube_edl/dispatch.fcgi +25 -0
  190. data/www/youtube_edl/render_edited.rb +25 -0
  191. data/www/youtube_edl/server_this_dir.rb +6 -0
  192. data/www/youtube_edl/todo +23 -0
  193. data/www/zoomplayer_max.png +0 -0
  194. data/zamples/edit_decision_lists/dvds/Harry Potter 2 chamber of secrets.txt +22 -0
  195. data/zamples/edit_decision_lists/dvds/aa_example_delete_list_that_has_no_cuts_in_it.txt +10 -0
  196. data/zamples/edit_decision_lists/dvds/aladdin.txt +30 -0
  197. data/zamples/edit_decision_lists/dvds/bambi.txt +17 -0
  198. data/zamples/edit_decision_lists/dvds/big_buck_bunny_dvd.txt +23 -0
  199. data/zamples/edit_decision_lists/dvds/bob the builder pets in a pickle.txt +10 -0
  200. data/zamples/edit_decision_lists/dvds/bobs_big_plan.txt +10 -0
  201. data/zamples/edit_decision_lists/dvds/cars_2.txt +26 -0
  202. data/zamples/edit_decision_lists/dvds/cars_disney.txt +40 -0
  203. data/zamples/edit_decision_lists/dvds/condor_man_widescreen.txt +22 -0
  204. data/zamples/edit_decision_lists/dvds/cool runnings.txt +53 -0
  205. data/zamples/edit_decision_lists/dvds/court_jester.txt +24 -0
  206. data/zamples/edit_decision_lists/dvds/edls_being_edited/amazing_grace.txt +49 -0
  207. data/zamples/edit_decision_lists/dvds/edls_being_edited/father_goose.txt +41 -0
  208. data/zamples/edit_decision_lists/dvds/edls_being_edited/harry_potter_and_the_goblet_of_fire.txt +45 -0
  209. data/zamples/edit_decision_lists/dvds/edls_being_edited/hugo.txt +31 -0
  210. data/zamples/edit_decision_lists/dvds/edls_being_edited/making_marriage_work.txt +15 -0
  211. data/zamples/edit_decision_lists/dvds/edls_being_edited/national_treasure.txt +26 -0
  212. data/zamples/edit_decision_lists/dvds/edls_being_edited/percy_jackson_lightening_thief.txt +40 -0
  213. data/zamples/edit_decision_lists/dvds/edls_being_edited/percy_jackson_lightening_thief_mute_scary.txt +23 -0
  214. data/zamples/edit_decision_lists/dvds/edls_being_edited/prince_of_egypt.txt +28 -0
  215. data/zamples/edit_decision_lists/dvds/edls_being_edited/puss_in_boots.txt +33 -0
  216. data/zamples/edit_decision_lists/dvds/edls_being_edited/ratatouille.txt +35 -0
  217. data/zamples/edit_decision_lists/dvds/edls_being_edited/rio.txt +24 -0
  218. data/zamples/edit_decision_lists/dvds/edls_being_edited/test_delete_list_for_experimenting_with.txt +10 -0
  219. data/zamples/edit_decision_lists/dvds/edls_being_edited/the_explorers.txt +49 -0
  220. data/zamples/edit_decision_lists/dvds/finding_neverland.txt +32 -0
  221. data/zamples/edit_decision_lists/dvds/flight_of_the_navigator.txt +40 -0
  222. data/zamples/edit_decision_lists/dvds/happiest baby on the block.txt +9 -0
  223. data/zamples/edit_decision_lists/dvds/harry_potter_3_prisoner_of_azkaban.txt +37 -0
  224. data/zamples/edit_decision_lists/dvds/hitchhiker's_guide_to_the_galaxy.txt +32 -0
  225. data/zamples/edit_decision_lists/dvds/how_to_train_your_dragon.txt +25 -0
  226. data/zamples/edit_decision_lists/dvds/if_a_man_answers.txt +43 -0
  227. data/zamples/edit_decision_lists/dvds/innerspace.txt +77 -0
  228. data/zamples/edit_decision_lists/dvds/iq.txt +32 -0
  229. data/zamples/edit_decision_lists/dvds/king_of_kings.txt +28 -0
  230. data/zamples/edit_decision_lists/dvds/kung_fu_panda_1.txt +17 -0
  231. data/zamples/edit_decision_lists/dvds/legend_of_the_guardians_the_owls_of_gahoole.txt +18 -0
  232. data/zamples/edit_decision_lists/dvds/monsters_vs_aliens.txt +41 -0
  233. data/zamples/edit_decision_lists/dvds/muppet_treasure_island.txt +21 -0
  234. data/zamples/edit_decision_lists/dvds/nanny_mcphee.txt +31 -0
  235. data/zamples/edit_decision_lists/dvds/narnia_voyage_of_the_dawn_treader.txt +16 -0
  236. data/zamples/edit_decision_lists/dvds/pack_jackson_wedding_2007-03-03.txt +31 -0
  237. data/zamples/edit_decision_lists/dvds/peter_pan.txt +29 -0
  238. data/zamples/edit_decision_lists/dvds/remember_the_titans.txt +35 -0
  239. data/zamples/edit_decision_lists/dvds/sintel_open_source_blender_ntsc_dvd.txt +22 -0
  240. data/zamples/edit_decision_lists/dvds/snow_white_and_the_7_dwarfs_1937.txt +19 -0
  241. data/zamples/edit_decision_lists/dvds/speed_racer.txt +47 -0
  242. data/zamples/edit_decision_lists/dvds/tangled.txt +21 -0
  243. data/zamples/edit_decision_lists/dvds/tron_legacy.txt +29 -0
  244. data/zamples/edit_decision_lists/dvds/turn_around_alma_younger.txt +17 -0
  245. data/zamples/edit_decision_lists/files/conference_music_video.txt +10 -0
  246. data/zamples/edit_decision_lists/netflix_instant/avatar-last-air-bender-movie.txt +13 -0
  247. data/zamples/edit_decision_lists/netflix_instant/avatar-last-airbender-series.txt +1 -0
  248. data/zamples/edit_decision_lists/netflix_instant/greatest_story_ever_told_netflix.txt +10 -0
  249. data/zamples/edit_decision_lists/netflix_instant/wrinkle-in-time.txt +23 -0
  250. data/zamples/edit_decision_lists/notes_on_movies_without_edls_yet/tron.txt +10 -0
  251. data/zamples/edit_decision_lists/old_not_yet_updated/dvds/White Christmas.txt +15 -0
  252. data/zamples/edit_decision_lists/old_not_yet_updated/dvds/all_dogs_go_to_heaven.txt +9 -0
  253. data/zamples/edit_decision_lists/old_not_yet_updated/dvds/cars_disney.txt +24 -0
  254. data/zamples/edit_decision_lists/old_not_yet_updated/dvds/happy_feet.txt +12 -0
  255. data/zamples/edit_decision_lists/old_not_yet_updated/dvds/labyrinth.txt +17 -0
  256. data/zamples/edit_decision_lists/old_not_yet_updated/dvds/star_trek_generations_hulu.txt +8 -0
  257. data/zamples/edit_decision_lists/old_not_yet_updated/example_edit_decision_list.txt +14 -0
  258. data/zamples/edit_decision_lists/old_not_yet_updated/youtube/gummy_bear_song_youtube.txt +9 -0
  259. data/zamples/edit_decision_lists/youtube/demo_mutes.txt +12 -0
  260. data/zamples/edit_decision_lists/youtube/nuki_song_youtube.txt +14 -0
  261. data/zamples/edit_decision_lists/youtube/nuki_song_youtube_pointer.txt +3 -0
  262. data/zamples/players/how_to_create_more_players.txt +24 -0
  263. data/zamples/players/hulu/total_length_over_an_hour.txt +25 -0
  264. data/zamples/players/netflix/netflix_firefox_non_maximized.txt +25 -0
  265. data/zamples/players/vlc/full_screened_total_length_over_an_hour.txt +27 -0
  266. data/zamples/players/vlc/windowed_total_length_over_an_hour.txt +26 -0
  267. data/zamples/players/vlc/windowed_total_length_under_an_hour.txt +22 -0
  268. data/zamples/players/youtube/full_screened_1024x768.txt +20 -0
  269. data/zamples/players/youtube/full_screened_1152x864.txt +20 -0
  270. data/zamples/players/youtube/full_screened_1680x1050.txt +20 -0
  271. data/zamples/players/youtube/normal_in_youtube.com.chrome.txt +23 -0
  272. data/zamples/players/youtube/note_these_assume_less_than_10_minutes_length.txt +2 -0
  273. metadata +483 -0
@@ -0,0 +1,28 @@
1
+ require 'ffi'
2
+
3
+ module EightThree
4
+ extend FFI::Library
5
+ ffi_lib 'kernel32'
6
+ ffi_convention :stdcall
7
+
8
+ =begin
9
+ DWORD WINAPI GetShortPathName(
10
+ __in LPCTSTR lpszLongPath,
11
+ __out LPTSTR lpszShortPath,
12
+ __in DWORD cchBuffer
13
+ );
14
+ =end
15
+
16
+ attach_function :path_to_8_3, :GetShortPathNameA, [:pointer, :pointer, :uint], :uint
17
+ def self.convert_path_to_8_3 path
18
+ out = FFI::MemoryPointer.new 256 # bytes
19
+ path_to_8_3(path, out, out.size)
20
+ out = out.get_string 0
21
+ if out.size == 0
22
+ raise 'unable to convert--probably file does not exist yet ' + path
23
+ else
24
+ out
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1 @@
1
+ mplayer -dumpstream dvd://1 -dvd-device d: -dumpfile dvdout.mpg
@@ -0,0 +1,3 @@
1
+ @rem with track 1, DVD drive d:\
2
+ mplayer -benchmark -endpos 10 dvdnav://1/d: -vo null -nosound 2>&1 > output2.txt
3
+ @rem then examine output2.txt
@@ -0,0 +1,13 @@
1
+ start = 33.26
2
+ #play_this = "g:\\Video\\Sintel_NTSC\\Sintel_NTSC-2.m4v"
3
+ play_this = "dvdnav://1/d:"
4
+ #play_this = "dvd://1/d:"
5
+ #play_this = "title00.ts"
6
+ #play_this = "dvdout.mpg"
7
+ in_out = IO.popen("mplayer -vo direct3d -osdlevel 2 #{play_this} -ss #{start} -slave -font c:\\windows\\fonts\\arial.ttf", 'w')
8
+ in_out.puts "pause"
9
+ loop {
10
+ p 'accepting from console'
11
+ incoming = STDIN.gets
12
+ in_out.puts incoming.strip
13
+ }
@@ -0,0 +1,35 @@
1
+ =begin
2
+ Copyright 2010, Roger Pack
3
+ This file is part of Sensible Cinema.
4
+
5
+ Sensible Cinema is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ Sensible Cinema is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
17
+ =end
18
+ puts 'warning--using fake blanker'
19
+
20
+ class Blanker
21
+
22
+ def self.startup
23
+ end
24
+ def self.shutdown
25
+ end
26
+
27
+ def self.blank_full_screen! text
28
+ puts 'the screen is now...blank!'
29
+ end
30
+
31
+ def self.unblank_full_screen!
32
+ puts 'the screen is now...visible!'
33
+ end
34
+
35
+ end
@@ -0,0 +1,3 @@
1
+ class FrameAccurate
2
+
3
+ end
@@ -0,0 +1,748 @@
1
+ #!/usr/bin/ruby # so my editor will like the file...
2
+ =begin
3
+ Copyright 2010, Roger Pack
4
+ This file is part of Sensible Cinema.
5
+
6
+ Sensible Cinema is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ Sensible Cinema is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
18
+ =end
19
+
20
+ alias system_original system
21
+ require 'fileutils'
22
+
23
+ class String
24
+ def snake_case
25
+ self.gsub(/::/, '/').
26
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
27
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
28
+ tr("-", "_").
29
+ downcase
30
+ end
31
+ def quotify
32
+ '"' + self + '"'
33
+ end
34
+ end
35
+
36
+ # a few I'll always need no matter what...
37
+ require_relative '../jruby-swing-helpers/swing_helpers'
38
+ require_relative '../jruby-swing-helpers/storage'
39
+ require_relative '../edl_parser'
40
+ require 'tmpdir'
41
+ require 'whichr'
42
+ require 'os'
43
+
44
+ if OS.doze?
45
+ autoload :WMI, 'ruby-wmi'
46
+ autoload :EightThree, './lib/eight_three'
47
+ end
48
+
49
+ # attempt to load on demand...i.e. faster...gah
50
+ for kls in [:MplayerEdl, :PlayAudio, :SubtitleProfanityFinder, :ConvertThirtyFps]
51
+ autoload kls, "./lib/#{kls.to_s.snake_case}"
52
+ end
53
+
54
+ for kls in [:PlayAudio, :RubyClip, :DriveInfo]
55
+ autoload kls, "./lib/jruby-swing-helpers/#{kls.to_s.snake_case}"
56
+ end
57
+
58
+ if OS.windows?
59
+ vendor_cache = File.expand_path(File.dirname(__FILE__)) + '/../../vendor/cache'
60
+ for name in ['.', 'ffmpeg', 'mplayer_edl']
61
+ # put them all before the old path
62
+ ENV['PATH'] = (vendor_cache + '/' + name).to_filename + ';' + ENV['PATH']
63
+ end
64
+
65
+ def add_smplayer_paths
66
+ discovered_smplayer_folders = Dir['{c,d,e,f,g}:/program files*/smplayer']
67
+
68
+ for folder in discovered_smplayer_folders
69
+ ENV['PATH'] = ENV['PATH'] + ";#{folder.gsub('/', "\\")}"
70
+ end
71
+ end
72
+
73
+ add_smplayer_paths
74
+
75
+ else
76
+ # handled in check_mac_installed.rb file
77
+
78
+ end
79
+
80
+ import 'javax.swing.ImageIcon'
81
+
82
+ module SensibleSwing
83
+ include SwingHelpers # various swing classes
84
+ JFrame
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
+ include SwingHelpers # work-around?
92
+
93
+ def initialize start_visible = true, args = ARGV # lodo not optionals
94
+ super "Sensible-Cinema #{VERSION} (GPL)"
95
+ @args = args # save them away so this works with sub-child-windows
96
+ force_accept_license_first # in other file :P
97
+ setDefaultCloseOperation JFrame::EXIT_ON_CLOSE # closes the whole app when they hit X ...
98
+ @panel = JPanel.new
99
+ @buttons = []
100
+ @panel.set_layout nil
101
+ add @panel # why can't I just slap these down? panel? huh?
102
+ @starting_button_y = 40
103
+ @button_width = 400
104
+
105
+ add_text_line "Welcome to Sensible Cinema!"
106
+ @starting_button_y += 10 # kinder ugly...
107
+ add_text_line " Rest mouse over buttons for \"help\" type descriptions (tooltips)."
108
+ @current_dvds_line1 = add_text_line "Checking present DVD's..."
109
+ @current_dvds_line2 = add_text_line ""
110
+ @callbacks_for_dvd_edl_present = []
111
+ DriveInfo.create_looping_drive_cacher
112
+ DriveInfo.add_notify_on_changed_disks { update_currently_inserted_dvd_list }
113
+ icon_filename = __DIR__ + "/../../vendor/profs.png"
114
+ raise unless File.exist? icon_filename # it doesn't check this for us?
115
+ setIconImage(ImageIcon.new(icon_filename).getImage())
116
+ check_for_various_dependencies
117
+ LocalStorage.set_once('init_preferences_once') {
118
+ show_blocking_message_dialog "let's setup user preferences once..."
119
+ set_individual_preferences
120
+ }
121
+ set_visible start_visible
122
+ end
123
+
124
+ def add_callback_for_dvd_edl_present &block
125
+ raise unless block
126
+ @callbacks_for_dvd_edl_present << block
127
+ update_currently_inserted_dvd_list # updates them :P
128
+ end
129
+
130
+ def update_currently_inserted_dvd_list
131
+ present_discs = []
132
+ DriveInfo.get_dvd_drives_as_openstruct.each{|disk|
133
+ if disk.VolumeName
134
+ dvd_id = DriveInfo.md5sum_disk(disk.MountPoint)
135
+ edit_list_path_if_present = EdlParser.single_edit_list_matches_dvd(dvd_id, true)
136
+ if edit_list_path_if_present
137
+ human_name = parse_edl(edit_list_path_if_present)['name']
138
+ human_name ||= ''
139
+ end
140
+ present_discs << [human_name, disk.VolumeName, edit_list_path_if_present]
141
+ end
142
+ }
143
+ found_one = false
144
+ present_discs.map!{|human_name, volume_name, has_edl|
145
+ if human_name
146
+ found_one = true
147
+ "DVD: #{human_name} has an Edit List available! (#{volume_name})"
148
+ else
149
+ "DVD: (#{volume_name}) has NO Edit List available!"
150
+ end
151
+ }
152
+ if present_discs.length > 0
153
+ @current_dvds_line1.text= ' ' + present_discs[0]
154
+ @current_dvds_line2.text= ' ' + present_discs[1..2].join(" ")
155
+ else
156
+ @current_dvds_line1.text= ' No DVD discs currently inserted.'
157
+ @current_dvds_line2.text = ''
158
+ end
159
+ @callbacks_for_dvd_edl_present.each{|c| c.call(present_discs.length > 0, found_one)}
160
+ end
161
+
162
+ def get_title_track_string descriptors, use_default_of_one = true
163
+ given = descriptors["dvd_title_track"]
164
+ given ||= "1" if use_default_of_one
165
+ given
166
+ end
167
+
168
+ def get_srt_filename descriptors, edl_filename
169
+ path = descriptors['subtitles_to_display_relative_path'] if descriptors
170
+ if path
171
+ path = File.expand_path(File.dirname(edl_filename) + '/' + path)
172
+ raise 'nonexisting srt file must be relative to the edl file...' + path unless File.exist? path
173
+ end
174
+ path
175
+ end
176
+
177
+ def we_are_in_create_mode
178
+ @args.index("--create-mode")
179
+ end
180
+
181
+ def we_are_in_developer_mode?
182
+ @args.detect{|a| a == '--developer-mode'}
183
+ end
184
+
185
+ def new_jbutton title, tooltip = nil
186
+ button = JButton.new title
187
+ button.tool_tip = tooltip
188
+ button.set_bounds(44, @starting_button_y, @button_width, 23)
189
+ @panel.add button
190
+ @buttons << button
191
+ if block_given? # allow for new_jbutton("xx") do ... end [this is possible through some miraculous means LOL]
192
+ button.on_clicked { yield }
193
+ end
194
+ increment_button_location
195
+ button
196
+ end
197
+
198
+ def add_text_line line
199
+ jlabel = JLabel.new line
200
+ happy = Font.new("Tahoma", Font::PLAIN, 11)
201
+ jlabel.setFont(happy)
202
+ jlabel.set_bounds(44,@starting_button_y ,460,14)
203
+ @panel.add jlabel
204
+ increment_button_location 18
205
+ jlabel
206
+ end
207
+
208
+ def increment_button_location how_much = 30
209
+ @starting_button_y += how_much
210
+ setSize @button_width+80, @starting_button_y + 50
211
+ end
212
+
213
+ LocalStorage = Storage.new("sensible_cinema_storage_#{VERSION}")
214
+
215
+ def when_thread_done(thread)
216
+ Thread.new {thread.join; yield }
217
+ end
218
+
219
+
220
+ # a window that when closed doesn't bring the whole app down
221
+ def new_child_window
222
+ child = MainWindow.new true, []
223
+ child.setDefaultCloseOperation(JFrame::DISPOSE_ON_CLOSE) # don't exit on close
224
+ child.parent=self # this should have failed in the PPL
225
+ # make both windows visible by moving the child down and to the right of its parent
226
+ x, y = self.get_location.x, self.get_location.y
227
+ child.set_location(x + 100, y + 100)
228
+ child
229
+ end
230
+
231
+ def run_smplayer_non_blocking *args
232
+ @background_thread = Thread.new {
233
+ run_smplayer_blocking *args
234
+ }
235
+ end
236
+
237
+ # basically run mplayer/smplayer on a file or DVD
238
+ def run_smplayer_blocking play_this, title_track_maybe_nil, passed_in_extra_options, force_use_mplayer, show_subs, start_full_screen, srt_filename
239
+ raise unless passed_in_extra_options # cannot be nil
240
+ extra_options = []
241
+ # -framedrop is for slow CPU's
242
+ # same with -autosync to try and help it stay in sync... -mc 0.03 is to A/V correct 1s audio per 2s video
243
+ # -hardframedrop might help but hurts the eyes just too much
244
+ extra_options << "-framedrop" # even in create mode, if the audio ever gets off, we're hosed with making accurate timestamps...so drop, until I hear otherwise...
245
+ extra_options << "-mc 2"
246
+ extra_options << "-autosync 30"
247
+
248
+ if we_are_in_create_mode
249
+ extra_options << "-osdlevel 2"
250
+ extra_options << "-osd-verbose" if we_are_in_developer_mode?
251
+ end
252
+ extra_options << "-osd-fractions 1"
253
+
254
+ if !show_subs && !srt_filename
255
+ # disable all subtitles :P
256
+ extra_options << "-nosub -noautosub -forcedsubsonly -sid 1000"
257
+ end
258
+ if srt_filename
259
+ extra_options << "-sub #{srt_filename}"
260
+ else
261
+ extra_options << "-alang en"
262
+ extra_options << "-slang en"
263
+ end
264
+
265
+ force_use_mplayer ||= OS.mac?
266
+ parent_parent = File.basename(File.dirname(play_this))
267
+ if parent_parent == 'VIDEO_TS'
268
+ # case d:\yo\VIDEO_TS\title0.vob
269
+ dvd_device_dir = normalize_path(File.dirname(play_this))
270
+ play_this = "\"dvdnav://#{title_track_maybe_nil}/#{dvd_device_dir}/..\""
271
+ elsif File.exist?(play_this + '/VIDEO_TS') || (play_this =~ /\/dev\/rdisk\d/)
272
+ # case d:\ where d:\VIDEO_TS exists [DVD mounted in drive, or DVD dir] or mac's /dev/rdisk1
273
+ play_this = "\"dvdnav://#{title_track_maybe_nil}/#{play_this}\""
274
+ else
275
+ # case g:\video\filename.mpg
276
+ # leave it the same...
277
+ end
278
+ if play_this =~ /dvdnav/ && title_track_maybe_nil
279
+ extra_options << "-msglevel identify=4" # prevent smplayer from using *forever* to look up info on DVD's with -identify ...
280
+ end
281
+
282
+ extra_options << "-mouse-movements #{get_upconvert_secondary_settings}" # just in case smplayer also needs -mouse-movements... :) LODO
283
+ extra_options << "-lavdopts threads=#{OS.cpu_count}" # just in case this helps [supposed to with h.264] # NB fast *crashes* doze...
284
+ if force_use_mplayer
285
+ extra_options << "-font #{File.expand_path('vendor/subfont.ttf')}"
286
+ key_strokes = <<-EOL
287
+ RIGHT seek +10
288
+ LEFT seek -10
289
+ DOWN seek -60
290
+ UP seek +60
291
+ ENTER {dvdnav} dvdnav select
292
+ MOUSE_BTN0 {dvdnav} dvdnav select
293
+ MOUSE_BTN0_DBL vo_fullscreen
294
+ MOUSE_BTN2 vo_fullscreen
295
+ KP_ENTER dvdnav select
296
+ # some for os x, some for doze. huh?
297
+ EOL
298
+ conf_file = File.expand_path './mplayer_input_conf'
299
+ File.write conf_file, key_strokes
300
+ extra_options << "-volume 100" # why start low? mplayer why oh why LODO
301
+ if OS.windows?
302
+ # direct3d for windows 7 old nvidia cards' sake [yipes] and also dvdnav sake
303
+ extra_options << "-vo direct3d"
304
+ conf_file = conf_file[2..-1] # strip off drive letter, which it doesn't seem to like no sir
305
+ end
306
+ if start_full_screen
307
+ extra_options << "-fs"
308
+ upconv = get_upconvert_vf_settings
309
+ upconv = "-vf #{upconv}" if upconv.present?
310
+ else
311
+ upconv = ""
312
+ end
313
+ if OS.doze?
314
+ mplayer_loc = LocalModifiedMplayer
315
+ assert File.exist?(mplayer_loc)
316
+ else
317
+ mplayer_loc = "mplayer"
318
+ end
319
+ c = "#{mplayer_loc} #{extra_options.join(' ')} #{upconv} -input conf=\"#{conf_file}\" #{passed_in_extra_options} \"#{play_this}\" "
320
+ else
321
+ if OS.windows?
322
+ extra_options << "-vo direct3d" # more light nvidia...should be ok...this wastes cpu...but we have to have it I guess...
323
+ end
324
+ set_smplayer_opts extra_options.join(' ') + " " + passed_in_extra_options, get_upconvert_vf_settings, show_subs
325
+ c = "smplayer \"#{play_this}\" -config-path \"#{File.dirname EightThree.convert_path_to_8_3(SMPlayerIniFile)}\" "
326
+ c += " -fullscreen " if start_full_screen
327
+ if !we_are_in_create_mode
328
+ #c += " -close-at-end " # still too unstable...
329
+ end
330
+ end
331
+ puts c
332
+ system_blocking c
333
+ end
334
+
335
+ SMPlayerIniFile = File.expand_path("~/.smplayer_sensible_cinema/smplayer.ini")
336
+ LocalModifiedMplayer = File.expand_path "vendor/cache/mplayer_edl/mplayer.exe"
337
+
338
+ def set_smplayer_opts to_this, video_settings, show_subs = false
339
+ p 'setting smplayer extra opts to this:' + to_this
340
+ old_prefs = File.read(SMPlayerIniFile) rescue ''
341
+ unless old_prefs.length > 0
342
+ # LODO double check the rest here...
343
+ old_prefs = "[%General]\nmplayer_bin=\n[advanced]\nmplayer_additional_options=\nmplayer_additional_video_filters=\n[subtitles]\nautoload_sub=false\n[performance]\npriority=3"
344
+ end
345
+ raise to_this if to_this =~ /"/ # unexpected, unfortunately... <smplayer bug>
346
+ assert new_prefs = old_prefs.gsub(/mplayer_additional_options=.*/, "mplayer_additional_options=#{to_this}")
347
+ assert new_prefs.gsub!(/autoload_sub=.*$/, "autoload_sub=#{show_subs.to_s}")
348
+ raise 'unexpected' if get_upconvert_vf_settings =~ /"/
349
+ assert new_prefs.gsub!(/mplayer_additional_video_filters=.*$/, "mplayer_additional_video_filters=\"#{video_settings}\"")
350
+ raise 'smplayer on non doze not expected...' unless OS.doze?
351
+ mplayer_to_use = LocalModifiedMplayer
352
+ assert File.exist?(mplayer_to_use)
353
+ new_value = "\"" + mplayer_to_use.to_filename.gsub("\\", '/') + '"' # forward slashes. Weird.
354
+ assert new_prefs.gsub!(/mplayer_bin=.*$/, "mplayer_bin=" + new_value)
355
+ # now some less important ones...
356
+ new_prefs.gsub!(/priority=.*$/, "priority=3") # normal priority...scary otherwise! lodo tell smplayer...
357
+ # enable dvdnav navigation, just for kicks I guess.
358
+ new_prefs.gsub!(/use_dvdnav=.*$/, "use_dvdnav=true")
359
+
360
+ FileUtils.mkdir_p File.dirname(SMPlayerIniFile)
361
+ File.write(SMPlayerIniFile, new_prefs)
362
+ new_prefs.each_line{|l| print l if l =~ /additional_video/} # debug
363
+ end
364
+
365
+ def system_blocking command
366
+ return true if command =~ /^@rem/ # JRUBY-5890 bug
367
+ raise command + " failed env #{ENV['PATH']}" unless system_original command
368
+ end
369
+
370
+ def system_non_blocking command
371
+ @background_thread = Thread.new { system_original command }
372
+ end
373
+
374
+ # force them choose which system call to use explicitly
375
+ if respond_to? :system
376
+ undef system
377
+ else # it's a reload
378
+ end
379
+
380
+ def play_dvd_smplayer_unedited use_mplayer_instead
381
+ drive_or_file, dvd_volume_name, dvd_id, edl_path_maybe_nil, descriptors = choose_dvd_or_file_and_edl_for_it(force_choose_edl_file_if_no_easy_match = true)
382
+ title_track_maybe_nil = get_title_track_string(descriptors, false)
383
+ if is_dvd?(drive_or_file)
384
+ dvd_options = get_dvd_playback_options(descriptors)
385
+ else
386
+ dvd_options = ''
387
+ end
388
+ run_smplayer_non_blocking drive_or_file, title_track_maybe_nil, dvd_options, use_mplayer_instead, true, false, get_srt_filename(descriptors, edl_path_maybe_nil)
389
+ end
390
+
391
+ def get_dvd_playback_options descriptors
392
+ out = []
393
+
394
+ nav, mpeg_time = descriptors['dvd_nav_packet_offset'] # like [0.5, 0.734067]
395
+ if nav
396
+ mpeg_time *= 1/1.001 # -> 29.97 fps
397
+ offset_time = mpeg_time - nav
398
+ else
399
+ # readings: 0.213 0.173 0.233 0.21 0.18 0.197 they're almost all right around 0.20...
400
+ show_blocking_message_dialog "error--your DVD EDL doesn\'t list a start offset time [dvd_nav_packet_offset] which is needed for precise accurate timing. Please run\nadvanced mode -> Display information about current DVD\nand add it to the EDL. Using a default for now...if you tweak any timing info you may want to set this more accurately first!"
401
+ offset_time = 0.20
402
+ end
403
+ raise if offset_time <= 0 # unexpected...
404
+ # -osd-add is because the initial NAV packet is "x" seconds off from the mpeg, and since
405
+ # we have it set within mplayer to "prefer to just give you the MPEG time when you haven't passed a DVD block"
406
+ # we wanted to match that more precisely once we did get past it.
407
+ # so basically today we are trying to "match" the underlying MPEG time well. Which is wrong, of course.
408
+ # either match the file or match the DVD, punk!
409
+ out << "-osd-add #{ "%0.3f" % offset_time}"
410
+ out.join(' ')
411
+ end
412
+
413
+ if OS.doze? # avoids spaces in filenames :)
414
+ EdlTempFile = EightThree.convert_path_to_8_3(Dir.tmpdir) + '\\mplayer.edl' # stay 8.3 friendly :)
415
+ else
416
+ raise if Dir.tmpdir =~ / / # that would be unexpected, and possibly cause problems...
417
+ EdlTempFile = Dir.tmpdir + '/mplayer.temp.edl'
418
+ end
419
+
420
+ EdlFilesChosen = {} # allow for switching tapes but still cache EDL loc. :P
421
+
422
+ def choose_dvd_or_file_and_edl_for_it force_choose_edl_file_if_no_easy_match = true
423
+ drive_or_file, dvd_volume_name, dvd_id = choose_dvd_drive_or_file false
424
+ edl_path = EdlFilesChosen[dvd_id]
425
+ if !edl_path
426
+ edl_path = EdlParser.single_edit_list_matches_dvd(dvd_id)
427
+ if !edl_path && force_choose_edl_file_if_no_easy_match
428
+ message = "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, if one doesn't exist yet"
429
+ show_blocking_message_dialog message
430
+ edl_path = new_existing_file_selector_and_select_file(message, EdlParser::EDL_DIR)
431
+ end
432
+ end
433
+ p 're/loading ' + edl_path # in case it has changed on disk
434
+ if edl_path # sometimes they don't have to choose one [?]
435
+ descriptors = nil
436
+ begin
437
+ descriptors = parse_edl edl_path
438
+ rescue SyntaxError => e
439
+ show_non_blocking_message_dialog("this file has an error--please fix then hit ok: \n" + edl_path + "\n " + e)
440
+ raise e
441
+ end
442
+ end
443
+ EdlFilesChosen[dvd_id] ||= edl_path
444
+ [drive_or_file, dvd_volume_name, dvd_id, edl_path, descriptors]
445
+ end
446
+
447
+ LocalStorage.set_default('mplayer_beginning_buffer', 0.5)
448
+
449
+ def is_dvd? drive_or_file
450
+ # it's like a/b/VIDEO_TS or d:/
451
+ if File.basename(File.dirname(drive_or_file)) == 'VIDEO_TS'
452
+ # /a/b/c/VIDEO_TS/yo.vob
453
+ true
454
+ elsif File.exist?(drive_or_file + '/VIDEO_TS')
455
+ # d:\
456
+ true
457
+ elsif OS.mac? && (drive_or_file =~ /\/dev\/rdisk\d+/)
458
+ true
459
+ else
460
+ false
461
+ end
462
+ end
463
+
464
+ # MplayerBeginingBuffer = 1.0
465
+ # MplayerEndBuffer = 0.0
466
+ def begin_buffer_preference
467
+ LocalStorage['mplayer_beginning_buffer']
468
+ end
469
+
470
+ def play_smplayer_edl_non_blocking optional_file_with_edl_path = nil, extra_mplayer_commands_array = [], force_mplayer = false, start_full_screen = true, add_secs_end = 0,
471
+ add_secs_begin = begin_buffer_preference, show_subs = false
472
+ if we_are_in_create_mode
473
+ assert(add_secs_begin == 0 && add_secs_end == 0)
474
+ end
475
+ if optional_file_with_edl_path
476
+ drive_or_file, edl_path = optional_file_with_edl_path
477
+ dvd_id = NonDvd # fake it out...LODO a bit smelly/ugly
478
+ else
479
+ drive_or_file, dvd_volume_name, dvd_id, edl_path, descriptors = choose_dvd_or_file_and_edl_for_it
480
+ end
481
+ start_add_this_to_all_ts = 0
482
+
483
+ if edl_path # some don't have one [?]
484
+ begin
485
+ # TODO combine these 2 methods yipzers
486
+ descriptors = EdlParser.parse_file edl_path
487
+ splits = [] # TODO not pass as parameter either
488
+ edl_contents = MplayerEdl.convert_to_edl descriptors, add_secs_end, add_secs_begin, splits, start_add_this_to_all_ts # add a sec to mutes to accomodate for mplayer's oddness..
489
+ File.write(EdlTempFile, edl_contents)
490
+ extra_mplayer_commands_array << "-edl #{EdlTempFile}"
491
+ rescue SyntaxError => e
492
+ show_blocking_message_dialog "unable to parse file! #{edl_path} #{e}"
493
+ raise
494
+ end
495
+ title_track = get_title_track_string(descriptors)
496
+ end
497
+
498
+ if is_dvd?(drive_or_file)
499
+ # it's a DVD of some sort
500
+ extra_mplayer_commands_array << get_dvd_playback_options(descriptors)
501
+ else
502
+ check_for_ffmpeg_installed
503
+ # it's a file
504
+ # check if it has a start offset...
505
+ all = `ffmpeg -i "#{drive_or_file}" 2>&1` # => Duration: 01:35:49.59, start: 600.000000
506
+ all =~ /Duration.*start: ([\d\.]+)/
507
+ start = $1.to_f
508
+ if start > 1 # LODO dvd's themselves start at 0.3 [sintel], but I don't think much higher than that never seen it...
509
+ show_non_blocking_message_dialog "Warning: file seems to start at an extra offset, adding it to the timestamps... #{start}
510
+ maybe not compatible with XBMC, if that's what you use, and you probably don't" # LODO test it XBMC...
511
+ start_add_this_to_all_ts = start
512
+ end
513
+ end
514
+
515
+ run_smplayer_non_blocking drive_or_file, title_track, extra_mplayer_commands_array.join(' '), force_mplayer, show_subs, start_full_screen, get_srt_filename(descriptors, edl_path)
516
+ end
517
+
518
+ def print *args
519
+ 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)
520
+ end
521
+
522
+ def open_file_to_edit_it filename, options = {} # :start_minimized is the only option
523
+ if OS.windows?
524
+ if options[:start_minimized]
525
+ system_non_blocking "start /min notepad \"#{filename}\""
526
+ else
527
+ system_non_blocking "notepad \"#{filename}\""
528
+ end
529
+ else
530
+ # ignore minimized :P
531
+ system_non_blocking "open -a TextEdit \"#{filename}\""
532
+ end
533
+ end
534
+
535
+ def new_nonexisting_filechooser_and_go title = nil, default_dir = nil, default_file = nil
536
+ bring_to_front unless OS.mac? # causes triples on mac! TODO rdp
537
+ JFileChooser.new_nonexisting_filechooser_and_go title, default_dir, default_file
538
+ end
539
+
540
+ # also caches directory previously selected ...
541
+ def new_existing_file_selector_and_select_file title, dir = nil
542
+ bring_to_front unless OS.mac? # causes duplicate prompts or something?
543
+ unique_trace = caller.inspect
544
+ if LocalStorage[unique_trace]
545
+ dir = LocalStorage[unique_trace]
546
+ end
547
+ p 'using system default dir' unless dir # happens more frequently after code changes alter the path :P
548
+ p 'using lookup dir ' + dir, LocalStorage[unique_trace] if $VERBOSE
549
+ got = SwingHelpers.new_previously_existing_file_selector_and_go title, dir
550
+ LocalStorage[unique_trace] = File.dirname(got)
551
+ got
552
+ end
553
+
554
+ def show_blocking_message_dialog(message, title = message.split("\n")[0], style= JOptionPane::INFORMATION_MESSAGE)
555
+ SwingHelpers.show_blocking_message_dialog message, title, style
556
+ end
557
+
558
+ # call dispose on this to close it if it hasn't been canceled yet...
559
+ def show_non_blocking_message_dialog message, close_button_text = 'Close'
560
+ bring_to_front
561
+ # lodo NonBlockingDialog it can get to the top instead of being so buried...
562
+ SwingHelpers.show_non_blocking_message_dialog message, close_button_text
563
+ end
564
+
565
+ java_import javax.swing.UIManager
566
+
567
+ def get_user_input_with_persistence(message, storage_key)
568
+ got = get_user_input(message, LocalStorage[storage_key])
569
+ LocalStorage[storage_key] = got
570
+ got
571
+ end
572
+ def get_user_input(message, default = '', cancel_ok = false)
573
+ SwingHelpers.get_user_input message, default, cancel_ok
574
+ end
575
+
576
+ def show_copy_pastable_string(message, value)
577
+ bring_to_front
578
+ RubyClip.set_clipboard value
579
+ get_user_input message + " (has been copied to clipboard)", value, true
580
+ end
581
+
582
+ def show_in_explorer filename
583
+ SwingHelpers.show_in_explorer filename
584
+ end
585
+
586
+ def show_select_buttons_prompt message, names ={}
587
+ SwingHelpers.show_select_buttons_prompt(message, names)
588
+ end
589
+
590
+ def parse_edl path
591
+ EdlParser.parse_file path
592
+ end
593
+
594
+ def get_freespace path
595
+ JFile.new(File.dirname(path)).get_usable_space
596
+ end
597
+
598
+ def get_drive_with_most_space_with_slash
599
+ DriveInfo.get_drive_with_most_space_with_slash
600
+ end
601
+
602
+ attr_accessor :background_thread, :buttons
603
+
604
+ NonDvd = 'non dvd has no dvdid' # we need it for convenience, say you want to go through your indexed vids and convert them all?
605
+
606
+ # returns e:\, volume_name, dvd_id
607
+ # or full_path.mkv, filename, ''
608
+ def choose_dvd_drive_or_file force_choose_only_dvd_drive
609
+ opticals = DriveInfo.get_dvd_drives_as_openstruct
610
+ if @saved_opticals == opticals && @_choose_dvd_drive_or_file
611
+ # memoize...if disks haven't changed :)
612
+ return @_choose_dvd_drive_or_file
613
+ else
614
+ @saved_opticals = opticals # save currently mounted disk list, so we know if we should re-select later...
615
+ # is this ok for os x?
616
+ end
617
+
618
+ has_at_least_one_dvd_inserted = opticals.find{|d| d.VolumeName }
619
+ if !has_at_least_one_dvd_inserted && force_choose_only_dvd_drive
620
+ show_blocking_message_dialog 'insert a dvd first'
621
+ raise 'no dvd found'
622
+ end
623
+ names = opticals.map{|d| d.Name + "\\" + " (" + (d.VolumeName || 'Insert DVD to use') + ")"}
624
+ if !force_choose_only_dvd_drive && !has_at_least_one_dvd_inserted
625
+ names += ['No DVD mounted so click to choose a Local File (or insert DVD, then re-try)']
626
+ used_local_file_option = true
627
+ end
628
+
629
+ count = 0
630
+ opticals.each{|d| count += 1 if d.VolumeName}
631
+ if count == 1 && !used_local_file_option
632
+ # just choose it if there's only one disk available..
633
+ p 'selecting only disk currently present in the various DVD drives [if you have more than one, that is]'
634
+ selected_idx = opticals.index{|d| d.VolumeName}
635
+ unless selected_idx
636
+ show_blocking_message_dialog "Please insert a disk first"
637
+ raise 'inset disk'
638
+ end
639
+ else
640
+ dialog = get_disk_chooser_window names
641
+ selected_idx = dialog.go_selected_index
642
+ end
643
+ if used_local_file_option
644
+ raise unless selected_idx == 0 # it was our only option...they must have selected it!
645
+ filename = new_existing_file_selector_and_select_file("Select yer previously grabbed from DVD file")
646
+ assert_ownership_dialog
647
+ return [filename, File.basename(filename), NonDvd]
648
+ else
649
+ disk = opticals[selected_idx]
650
+ out = show_non_blocking_message_dialog "calculating current disk's unique id...if this pauses more than 10s then clean your DVD..."
651
+ begin
652
+ dvd_id = DriveInfo.md5sum_disk(disk.MountPoint)
653
+ rescue Exception => e
654
+ show_blocking_message_dialog e.to_s # todo a bit ugly...
655
+ raise
656
+ ensure
657
+ out.dispose
658
+ end
659
+ @_choose_dvd_drive_or_file = [disk.DevicePoint, opticals[selected_idx].VolumeName, dvd_id]
660
+ return @_choose_dvd_drive_or_file
661
+ end
662
+ end
663
+
664
+
665
+ def display_and_raise error_message
666
+ show_blocking_message_dialog error_message
667
+ raise error_message
668
+ end
669
+
670
+ def with_autoclose_message(message)
671
+ a = show_non_blocking_message_dialog message
672
+ yield
673
+ a.close
674
+ end
675
+
676
+ def we_are_in_upconvert_mode
677
+ @args.index("--upconvert-mode")
678
+ end
679
+
680
+ def setup_default_buttons
681
+ if we_are_in_upconvert_mode
682
+ add_play_upconvert_buttons
683
+ else
684
+ if we_are_in_create_mode
685
+ setup_create_buttons
686
+ else
687
+ setup_normal_buttons
688
+ end
689
+
690
+ end # big else
691
+
692
+ @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!")
693
+ @exit.on_clicked {
694
+ Thread.new { self.close } # don't waste the time to close it :P
695
+ puts 'Thank you for using Sensible Cinema. Come again!'
696
+ System.exit 0
697
+ }
698
+
699
+ increment_button_location
700
+ increment_button_location
701
+ self
702
+
703
+ end
704
+
705
+ def get_disk_chooser_window names
706
+ DropDownSelector.new(self, names, "Click to select DVD drive")
707
+ end
708
+
709
+ def get_temp_file_name name_with_ext
710
+ File.dirname(EdlTempFile) + '/' + name_with_ext
711
+ end
712
+
713
+ # converts to full path, 8.3 if on doze
714
+ def normalize_path path
715
+ path = File.expand_path path
716
+ path = EightThree.convert_path_to_8_3 path if OS.doze?
717
+ end
718
+
719
+
720
+ end
721
+
722
+ end
723
+
724
+
725
+ class ::File
726
+ def self.get_root_dir this_path
727
+ this_path = File.expand_path this_path
728
+ if OS.doze?
729
+ this_path[0..2]
730
+ else
731
+ this_path.split('/')[0]
732
+ end
733
+ end
734
+
735
+ def self.strip_drive_windows this_complete_path
736
+ if OS.doze?
737
+ this_complete_path[2..-1]
738
+ else
739
+ this_complete_path
740
+ end
741
+ end
742
+ end
743
+
744
+ class ::String
745
+ def just_letters
746
+ gsub(/[^a-z0-9]/i, '').downcase
747
+ end
748
+ end