sensible-cinema 0.28.1 → 0.34.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. data/{README → README.TXT} +35 -14
  2. data/Rakefile +49 -41
  3. data/TODO +337 -250
  4. data/VERSION +1 -1
  5. data/bin/sensible-cinema +15 -14
  6. data/bin/sensible-cinema-cli +1 -1
  7. data/business_ideas.txt +8 -0
  8. data/change_log_with_feature_list.txt +198 -1
  9. data/documentation/is_it_legal_to_copy_dvds.txt +44 -30
  10. data/goc.bat +1 -1
  11. data/gpl-2.0.txt +339 -0
  12. data/history_and_related_works_list.txt +37 -33
  13. data/{cone.png → inventionzy_files/cone.png} +0 -0
  14. data/legal_draft +23 -0
  15. data/lib/add_any_bundled_gems_to_load_path.rb +4 -3
  16. data/lib/check_installed_mac.rb +10 -10
  17. data/lib/count_down_timer_jruby_swing.rb +4 -4
  18. data/lib/edl_parser.rb +155 -142
  19. data/lib/extract/dumpstream.bat +1 -0
  20. data/lib/extract/get_init.bat +3 -0
  21. data/lib/extract/pause_early.rb +13 -0
  22. data/lib/gui/base.rb +707 -0
  23. data/lib/gui/create-file.rb +244 -0
  24. data/lib/gui/create.rb +565 -0
  25. data/lib/gui/dependencies.rb +177 -0
  26. data/lib/gui/normal.rb +190 -0
  27. data/lib/gui/{sensible-cinema-upconvert.rb → upconvert.rb} +33 -14
  28. data/lib/keyboard_input.rb +0 -2
  29. data/lib/mencoder_wrapper.rb +8 -3
  30. data/lib/movie_hasher.rb +27 -0
  31. data/lib/mplayer_edl.rb +1 -0
  32. data/lib/subtitle_profanity_finder.rb +141 -103
  33. data/lib/vlc_programmer.rb +1 -1
  34. data/lib/zoom_player_max_edl.rb +50 -0
  35. data/{developer_how_to_contribute_to_the_project.txt → notes_for_potential_developers.txt} +18 -11
  36. data/roadmap_possibilities +12 -0
  37. data/spec/arse.srt +6 -1
  38. data/spec/dragon.srt +3 -0
  39. data/spec/edl_parser.spec.rb +57 -52
  40. data/spec/mencoder_wrapper.spec.rb +26 -19
  41. data/spec/mplayer_edl.spec.rb +40 -10
  42. data/spec/notes +3043 -9
  43. data/spec/sensible_cinema_gui.spec.rb +8 -3
  44. data/spec/subtitle_profanity_finder.spec.rb +91 -36
  45. data/spec/zoom_player_max_edl.spec.rb +29 -0
  46. data/template_bats/README_DISTRO.TXT +3 -1
  47. data/template_bats/RUN SENSIBLE CINEMA CLICK HERE WINDOWS.bat +25 -0
  48. data/template_bats/mac/RUN SENSIBLE CINEMA CLICK HERE.command +2 -1
  49. data/template_bats/mac/advanced--create or edit sensible cinema edit list files.command +2 -1
  50. data/template_bats/mac/advanced--run-upconverting-video-player.command +2 -1
  51. data/template_bats/pc/advanced--create or edit sensible cinema edit list files.bat +2 -0
  52. data/template_bats/pc/advanced--run-upconverting-video-player.bat +2 -0
  53. data/todo.inventionzy.txt +69 -2
  54. data/todo.propaganda +34 -10
  55. data/todo.upconvert +8 -1
  56. data/{upconvert_netflix/latest2 → upconvert_from_screen}/go_upscaling.bat +0 -0
  57. data/{also_see_rogerdpack_youtube_account_and_sourceforge_files_movies_account → upconvert_from_screen/go_upscaling_works} +0 -0
  58. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/combine_video.avs +0 -0
  59. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/go_no_upscaling.bat +0 -0
  60. data/upconvert_from_screen/old/latest2/go_upscaling.bat +12 -0
  61. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/push2.GRF +0 -0
  62. data/upconvert_from_screen/old/latest2/push3.grf +0 -0
  63. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/setup_capture_coords.rb +0 -0
  64. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/setup_directshow_filter_params.rb +0 -0
  65. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/upconvert_from_screen_me2.avs +1 -1
  66. data/{upconvert_netflix → upconvert_from_screen}/old/latest_now_possibly_oudated/push2.GRF +0 -0
  67. data/{upconvert_netflix → upconvert_from_screen}/old/latest_now_possibly_oudated/upconvert_from_screen_me2.avs +0 -0
  68. data/{upconvert_netflix → upconvert_from_screen}/old/position_window.png +0 -0
  69. data/{upconvert_netflix → upconvert_from_screen}/old/push_source_desktop.GRF +0 -0
  70. data/{upconvert_netflix → upconvert_from_screen/old}/record_screen/record.bat +0 -0
  71. data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen.avs +0 -0
  72. data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen_me.avs +0 -0
  73. data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen_me2.avs +0 -0
  74. data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen_me_push_source.avs +0 -0
  75. data/{upconvert_netflix → upconvert_from_screen}/old/uscreen.GRF +0 -0
  76. data/{upconvert_netflix → upconvert_from_screen}/old/uscreen_me.GRF +0 -0
  77. data/upconvert_from_screen/push3.grf +0 -0
  78. data/upconvert_from_screen/upconvert_from_screen_me2.avs +19 -0
  79. data/vendor/mplayer_patches/apply.bat +12 -0
  80. data/vendor/{rdp-win32screenshot-0.0.9/RDP_BRANCH_HAS_MASTER_WITH_CORRECT_VERSION_NUMBER → mplayer_patches/configure_from_betterlogic} +0 -0
  81. data/vendor/mplayer_patches/libdvdnav/2905259c3b45529b3d8dedba572b6e4f67a2d8f4.diff +19 -0
  82. data/vendor/mplayer_patches/libdvdnav/83f1c9256f500285e46f1e44bcc74ffce90159db.diff +16 -0
  83. data/vendor/mplayer_patches/libdvdnav/eb91fb74680d30322461a1b9e425918ad4e2b2df.diff +21 -0
  84. data/vendor/mplayer_patches/libdvdnav/jump_to_time.diff +654 -0
  85. data/vendor/mplayer_patches/libdvdnav/non_strict.diff +13 -0
  86. data/vendor/mplayer_patches/mplayer_edl.diff +354 -0
  87. data/vendor/mplayer_patches/port_dir/PortIndex.quick +2 -0
  88. data/vendor/mplayer_patches/port_dir/how_to +13 -0
  89. data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/Portfile +300 -0
  90. data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/files/configure.x11.patch +20 -0
  91. data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/files/llvm-gcc-workaround.patch +11 -0
  92. data/vendor/mplayer_patches/port_dir/multimedia/rdp-projects/Portfile +43 -0
  93. data/vendor/{rdp-win32screenshot-0.0.9/RDP_VERSION_IS_IN_RDP_BRANCH → mplayer_patches/updated_lib_too} +0 -0
  94. data/vendor/{readme.txt → readme.txt.setpriority} +0 -0
  95. data/www/content_editor.html +28 -28
  96. data/www/index.html +6 -1
  97. data/www/upconverting_movie_player.html +13 -3
  98. data/www/youtube_edl/.htaccess +44 -0
  99. data/{inventionzy_files/control_youtube.html → www/youtube_edl/control_youtube.rhtml} +39 -33
  100. data/www/youtube_edl/dispatch.fcgi +25 -0
  101. data/www/youtube_edl/render_edited.rb +25 -0
  102. data/{inventionzy_files/serve.rb → www/youtube_edl/server_this_dir.rb} +0 -0
  103. data/www/youtube_edl/todo +23 -0
  104. data/www/zoomplayer_max.png +0 -0
  105. data/zamples/edit_decision_lists/dvds/Harry Potter 2 chamber of secrets.txt +10 -5
  106. data/zamples/edit_decision_lists/dvds/aladdin.txt +30 -0
  107. data/zamples/edit_decision_lists/dvds/bambi.txt +1 -1
  108. data/zamples/edit_decision_lists/dvds/big_buck_bunny_dvd.txt +2 -0
  109. data/zamples/edit_decision_lists/dvds/bobs_big_plan.txt +2 -2
  110. data/zamples/edit_decision_lists/dvds/cars_2.txt +26 -0
  111. data/zamples/edit_decision_lists/dvds/cars_disney.txt +1 -1
  112. data/zamples/edit_decision_lists/dvds/condor_man_widescreen.txt +22 -0
  113. data/zamples/edit_decision_lists/dvds/court_jester.txt +10 -13
  114. data/zamples/edit_decision_lists/dvds/edls_being_edited/making_marriage_work.txt +15 -0
  115. data/zamples/edit_decision_lists/dvds/edls_being_edited/national_treasure.txt +23 -0
  116. data/zamples/edit_decision_lists/dvds/edls_being_edited/ratatouille.txt +35 -0
  117. data/zamples/edit_decision_lists/dvds/edls_being_edited/the_explorers.txt +49 -0
  118. data/zamples/edit_decision_lists/dvds/finding_neverland.txt +32 -0
  119. data/zamples/edit_decision_lists/dvds/flight_of_the_navigator.txt +22 -16
  120. data/zamples/edit_decision_lists/dvds/harry_potter_3_prisoner_of_azkaban.txt +21 -4
  121. data/zamples/edit_decision_lists/dvds/hitchhiker's_guide_to_the_galaxy.txt +1 -1
  122. data/zamples/edit_decision_lists/dvds/{edls_being_edited/king_of_kings.txt → king_of_kings.txt} +5 -5
  123. data/zamples/edit_decision_lists/dvds/nanny_mcphee.txt +31 -0
  124. data/zamples/edit_decision_lists/dvds/pack_jackson_wedding_2007-03-03.txt +9 -2
  125. data/zamples/edit_decision_lists/dvds/remember_the_titans.txt +35 -0
  126. data/zamples/edit_decision_lists/dvds/sintel_open_source_blender_ntsc_dvd.txt +8 -4
  127. data/zamples/edit_decision_lists/dvds/speed_racer.txt +1 -1
  128. data/zamples/edit_decision_lists/dvds/tangled.txt +21 -0
  129. data/zamples/edit_decision_lists/dvds/tron_legacy.txt +4 -1
  130. data/zamples/edit_decision_lists/files/conference_music_video.txt +10 -0
  131. data/zamples/edit_decision_lists/notes_on_movies_without_edls_yet/tron.txt +10 -0
  132. data/zamples/edit_decision_lists/old_not_yet_updated/example_edit_decision_list.txt +1 -1
  133. metadata +139 -117
  134. data/conclusions +0 -6
  135. data/documentation/how_to_create_your_own_delete_lists.txt +0 -69
  136. data/lib/gui/sensible-cinema-base.rb +0 -620
  137. data/lib/gui/sensible-cinema-create.rb +0 -331
  138. data/lib/gui/sensible-cinema-dependencies.rb +0 -28
  139. data/lib/gui/sensible-cinema-normal.rb +0 -351
  140. data/lib/gui/sensible-cinema-side-by-side.rb +0 -27
  141. data/lib/shutdown_kill.rb +0 -32
  142. data/lib/storage.rb +0 -105
  143. data/ocr.todo_if_need_speed +0 -6
  144. data/upconvert_netflix/record_screen/recording/1.png +0 -0
  145. data/upconvert_netflix/record_screen/recording/10.png +0 -0
  146. data/upconvert_netflix/record_screen/recording/2.png +0 -0
  147. data/upconvert_netflix/record_screen/recording/3.png +0 -0
  148. data/upconvert_netflix/record_screen/recording/4.png +0 -0
  149. data/upconvert_netflix/record_screen/recording/5.png +0 -0
  150. data/upconvert_netflix/record_screen/recording/6.png +0 -0
  151. data/upconvert_netflix/record_screen/recording/7.png +0 -0
  152. data/upconvert_netflix/record_screen/recording/8.png +0 -0
  153. data/upconvert_netflix/record_screen/recording/9.png +0 -0
  154. data/upconvert_netflix/record_screen/recording/d.png +0 -0
  155. data/vendor/monkey.png +0 -0
  156. data/vendor/rdp-win32screenshot-0.0.9/.document +0 -5
  157. data/vendor/rdp-win32screenshot-0.0.9/History.rdoc +0 -53
  158. data/vendor/rdp-win32screenshot-0.0.9/LICENSE +0 -20
  159. data/vendor/rdp-win32screenshot-0.0.9/README.rdoc +0 -95
  160. data/vendor/rdp-win32screenshot-0.0.9/Rakefile +0 -63
  161. data/vendor/rdp-win32screenshot-0.0.9/VERSION +0 -1
  162. data/vendor/rdp-win32screenshot-0.0.9/enumerated +0 -55576
  163. data/vendor/rdp-win32screenshot-0.0.9/lib/aero_offscreen_srccopy_captureblt_doesnt_have_everything.bmp.gz +0 -0
  164. data/vendor/rdp-win32screenshot-0.0.9/lib/enumerate.rb +0 -6
  165. data/vendor/rdp-win32screenshot-0.0.9/lib/firefox.bmp +0 -0
  166. data/vendor/rdp-win32screenshot-0.0.9/lib/normal.bmp +0 -0
  167. data/vendor/rdp-win32screenshot-0.0.9/lib/normal2.bmp +0 -0
  168. data/vendor/rdp-win32screenshot-0.0.9/lib/notes +0 -5
  169. data/vendor/rdp-win32screenshot-0.0.9/lib/snapshot.rb +0 -10
  170. data/vendor/rdp-win32screenshot-0.0.9/lib/srccopy.bmp +0 -0
  171. data/vendor/rdp-win32screenshot-0.0.9/lib/srccopyplus.bmp +0 -0
  172. data/vendor/rdp-win32screenshot-0.0.9/lib/srccopyplusdirectx.bmp +0 -0
  173. data/vendor/rdp-win32screenshot-0.0.9/lib/vc.bmp +0 -0
  174. data/vendor/rdp-win32screenshot-0.0.9/lib/win32/screenshot.rb +0 -95
  175. data/vendor/rdp-win32screenshot-0.0.9/lib/win32/screenshot/bitmap_maker.rb +0 -200
  176. data/vendor/rdp-win32screenshot-0.0.9/lib/win32/util.rb +0 -93
  177. data/vendor/rdp-win32screenshot-0.0.9/spec/spec.opts +0 -1
  178. data/vendor/rdp-win32screenshot-0.0.9/spec/spec_helper.rb +0 -85
  179. data/vendor/rdp-win32screenshot-0.0.9/spec/win32_screenshot_spec.rb +0 -194
  180. data/vendor/rdp-win32screenshot-0.0.9/spec/win32_screenshot_util_spec.rb +0 -75
  181. data/vendor/rdp-win32screenshot-0.0.9/win32screenshot.gemspec +0 -69
  182. data/vendor/tsmuxer_1.10.6/licence.txt +0 -42
  183. data/zamples/edit_decision_lists/dvds/making_marriage_work.txt +0 -15
  184. data/zamples/edit_decision_lists/notes/tron.txt +0 -4
  185. data/zamples/edit_decision_lists/old_not_yet_updated/dvds/making marriage work.txt +0 -9
@@ -15,8 +15,6 @@ This file is part of Sensible Cinema.
15
15
  You should have received a copy of the GNU General Public License
16
16
  along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
17
17
  =end
18
- require 'rubygems'
19
- require 'sane'
20
18
  require 'Win32API'
21
19
 
22
20
  # does the jruby check inline
@@ -47,7 +47,12 @@ class MencoderWrapper
47
47
  # called from the UI...
48
48
  # only for transcoding.
49
49
  def get_bat_commands these_settings, this_from_file, to_here_final_file, start_here = nil, end_here = nil, dvd_title_track = "1", delete_partials = false, require_deletion_entry = false
50
- combined = EdlParser.convert_incoming_to_split_sectors these_settings
50
+
51
+ dvd_start_offset = these_settings['dvd_start_offset'] # assume we prefer DVD timings which...we do :P
52
+ raise 'EDL must have a dvd_start_offset, even if just 0.0 (or better yet, 0.28 is a common one), as we use this to translate from DVD to file times' unless dvd_start_offset
53
+ dvd_start_offset = EdlParser.translate_string_to_seconds(dvd_start_offset)
54
+
55
+ combined = EdlParser.convert_incoming_to_split_sectors these_settings, 0, dvd_start_offset, [], dvd_start_offset
51
56
  @dvd_title_track = dvd_title_track
52
57
  assert dvd_title_track
53
58
  if start_here || end_here
@@ -84,8 +89,8 @@ class MencoderWrapper
84
89
  p 'warning, overwriting+deleting previous ' + to_here_final_file
85
90
  FileUtils.rm to_here_final_file # raises on deletion failure...which is what we want I think...typically...early warning...
86
91
  end
87
- out += "call mencoder #{partials.join(' ')} -o #{to_here_final_file} -ovc copy -oac copy\n"
88
- out += "@rem old DISABLED join way... call mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf -vf scale=720:480,harddup -srate 48000 -af lavcresample=48000 -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:acodec=ac3:abitrate=192:aspect=16/9 -ofps 30000/1001 #{partials.join(' ')} -o #{to_here_final_file}\n"
92
+ out += "mencoder #{partials.join(' ')} -o #{to_here_final_file} -ovc copy -oac copy\n"
93
+ out += "@rem old DISABLED join way... mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf -vf scale=720:480,harddup -srate 48000 -af lavcresample=48000 -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:acodec=ac3:abitrate=192:aspect=16/9 -ofps 30000/1001 #{partials.join(' ')} -o #{to_here_final_file}\n"
89
94
 
90
95
  delete_prefix = delete_partials ? "" : "@rem "
91
96
  delete_prefix = "@rem" if am_on_developer_machine? # for ease of double checking...
@@ -0,0 +1,27 @@
1
+ module MovieHasher
2
+
3
+ CHUNK_SIZE = 64 * 1024 # in bytes
4
+
5
+ def self.compute_hash(filename)
6
+ filesize = File.size(filename)
7
+ hash = filesize
8
+
9
+ # Read 64 kbytes, divide up into 64 bits and add each
10
+ # to hash. Do for beginning and end of file.
11
+ File.open(filename, 'rb') do |f|
12
+ # Q = unsigned long long = 64 bit
13
+ f.read(CHUNK_SIZE).unpack("Q*").each do |n|
14
+ hash = hash + n & 0xffffffffffffffff # to remain as 64 bit number
15
+ end
16
+
17
+ f.seek([0, filesize - CHUNK_SIZE].max, IO::SEEK_SET)
18
+
19
+ # And again for the end of the file
20
+ f.read(CHUNK_SIZE).unpack("Q*").each do |n|
21
+ hash = hash + n & 0xffffffffffffffff
22
+ end
23
+ end
24
+
25
+ sprintf("%016x", hash)
26
+ end
27
+ end
@@ -20,6 +20,7 @@ require_relative 'edl_parser'
20
20
 
21
21
  class MplayerEdl
22
22
  def self.convert_to_edl specs, add_this_many_to_end = 0, add_this_many_to_beginning = 0, splits = [], extra_time_to_all = 0.0
23
+
23
24
  # simple re-map to EDL style output
24
25
  combined = EdlParser.convert_incoming_to_split_sectors specs, add_this_many_to_end, add_this_many_to_beginning, splits
25
26
 
@@ -1,27 +1,58 @@
1
1
  #
2
- # warning: somewhat scary/explicit!
3
-
4
- # see subtitle_todo file
5
-
6
-
2
+ # warning: somewhat scary/explicit down there!
3
+ # see also todo.subtitle file, though what's here is mostly pretty well functional
4
+ #
5
+ begin
6
+ require 'sane'
7
+ rescue LoadError
8
+ require 'rubygems'
9
+ require 'sane'
10
+ end
7
11
  require_relative 'edl_parser'
8
-
12
+ require 'ostruct'
9
13
 
10
14
  module SubtitleProfanityFinder
11
15
 
12
16
  # splits into timestamps -> timestamps\ncontent blocks
13
- def self.split_to_glops subtitles
14
- subtitles.scan(/\d\d:\d\d:\d\d.*?^$/m)
17
+ def self.split_to_entries subtitles_raw_text
18
+ all = subtitles_raw_text.gsub("\r\n", "\n").scan(/^\d+\n\d\d:\d\d:\d\d.*?^$/m) # line endings so that it parses right when linux reads a windows file <huh?>
19
+ all.map{|glop|
20
+ lines = glop.lines.to_a
21
+ index_line = lines[0]
22
+ timing_line = lines[1].strip
23
+ text = lines.to_a[2..-1].join("") # they still have separating "\n"'s
24
+ # create english-ified version
25
+ text.gsub!(/<(.|)(\/|)i>/i, '') # kill <i> type things
26
+ text.gsub!(/[^a-zA-Z0-9\-!,.\?'\n\(\)]/, ' ') # kill weird stuff like ellipseses, also quotes would hurt so kill them too
27
+ text.gsub!(/ +/, ' ') # remove duplicate " " 's now since we may have inserted many
28
+ # extract timing info
29
+ # "00:03:00.0" , "00:04:00.0", "violence", "of some sort",
30
+ timing_line =~ /((\d\d:\d\d:\d\d),(\d\d\d) --> (\d\d:\d\d:\d\d),(\d\d\d))/
31
+ ts_begin = "#{$2}.#{$3}"
32
+ ts_end = "#{$4}.#{$5}"
33
+ out = OpenStruct.new
34
+ out.index_number = index_line.strip.to_i
35
+ out.beginning_time = EdlParser.translate_string_to_seconds ts_begin
36
+ out.ending_time = EdlParser.translate_string_to_seconds ts_end
37
+ out.text = text.strip # harmless right?
38
+ out.single_line_text = text.strip.gsub(/^[- ,_\.]+/, '').gsub(/[- ,_]+$/, '').gsub(/[\r\n]/, ' ')
39
+ out
40
+ }
15
41
  end
16
42
 
43
+ # convert string to regexp, also accomodating for "full word" type profanities
17
44
  def self.convert_to_regexps profanity_hash
18
45
  all_profanity_combinations = []
19
46
  profanity_hash.to_a.sort.reverse.each{|profanity, sanitized|
20
47
  as_regexp = Regexp.new(profanity, Regexp::IGNORECASE)
21
48
  if sanitized.is_a? Array
22
- is_single_word_profanity = true
23
- raise unless sanitized[1] == :full_word
24
- raise unless sanitized.length == 2
49
+ # like 'bad word' => ['vain use', :partial_word, 'deity']
50
+ raise unless sanitized.length.in? [2, 3]
51
+ raise unless sanitized[1].in? [:full_word, :partial_word]
52
+ is_single_word_profanity = true if sanitized[1] == :full_word
53
+ if sanitized.length == 3
54
+ category = sanitized[2]
55
+ end
25
56
  sanitized = sanitized[0]
26
57
  end
27
58
 
@@ -33,55 +64,43 @@ module SubtitleProfanityFinder
33
64
  permutations << profanity.gsub(/i/i, 'l')
34
65
  end
35
66
 
36
- bracketized = '[' + sanitized + ']'
67
+ replace_with = '[' + sanitized + ']'
68
+ category ||= sanitized
37
69
 
38
70
  for permutation in permutations
39
71
  if is_single_word_profanity
40
- # oh wow this is ughly...
41
- sanitized_version = bracketized
42
- as_regexp = Regexp.new("\s" + permutation + "\s", Regexp::IGNORECASE)
43
- all_profanity_combinations << [as_regexp, ' ' + bracketized + ' ']
44
- as_regexp = Regexp.new("^" + permutation + "\s", Regexp::IGNORECASE)
45
- all_profanity_combinations << [as_regexp, bracketized + ' ']
46
- as_regexp = Regexp.new("\s" + permutation + "$", Regexp::IGNORECASE)
47
- all_profanity_combinations << [as_regexp, ' ' + bracketized]
48
- as_regexp = Regexp.new("^" + permutation + "$", Regexp::IGNORECASE)
49
- all_profanity_combinations << [as_regexp, bracketized]
72
+ # \s is whitespace
73
+ as_regexp = Regexp.new("(?:\s|^|[^a-zA-Z])" + permutation + "(?:\s|$|[^a-zA-Z])", Regexp::IGNORECASE)
74
+ all_profanity_combinations << [as_regexp, category, ' ' + replace_with + ' '] # might introduce an extra space in there, but that's prolly ok since they're full-word already, and we collapse them
50
75
  else
51
- all_profanity_combinations << [as_regexp, bracketized]
76
+ all_profanity_combinations << [as_regexp, category, replace_with]
52
77
  end
53
78
  end
54
79
  }
55
80
  all_profanity_combinations
56
- end
57
-
58
-
81
+ end
59
82
 
60
- def self.edl_output incoming_filename, extra_profanity_hash = {}, subtract_from_each_beginning_ts = 0, add_to_end_each_ts = 0, beginning_srt = "00:00", beginning_actual_movie = "00:00", ending_srt = "10:00:00", ending_actual = "10:00:00"
61
- edl_output_from_string File.read(incoming_filename), extra_profanity_hash, subtract_from_each_beginning_ts, add_to_end_each_ts, beginning_srt, beginning_actual_movie, ending_srt, ending_actual
83
+ def self.edl_output incoming_filename, extra_profanity_hash = {}, subtract_from_each_beginning_ts = 0, add_to_end_each_ts = 0, beginning_srt = 0.0, beginning_actual_movie = 0.0, ending_srt = 7200.0, ending_actual = 7200.0
84
+ edl_output_from_string(File.read(incoming_filename), extra_profanity_hash, subtract_from_each_beginning_ts, add_to_end_each_ts, beginning_srt, beginning_actual_movie, ending_srt, ending_actual)[0]
62
85
  end
63
86
 
64
- def self.edl_output_from_string subtitles, extra_profanity_hash, subtract_from_each_beginning_ts, add_to_end_each_ts, starting_timestamp_given_srt, starting_timestamp_actual, ending_srt, ending_actual
65
- subtitles.gsub!("\r\n", "\n")
87
+ # **_time means "a float"
88
+
89
+ def self.edl_output_from_string subtitles, extra_profanity_hash, subtract_from_each_beginning_ts, add_to_end_each_ts, starting_time_given_srt, starting_time_actual, ending_srt_time, ending_actual_time, include_minor_profanities=true # lodo may not need include_minor_profs :P
66
90
  raise if subtract_from_each_beginning_ts < 0 # these have to be positive...in my twisted paradigm
67
91
  raise if add_to_end_each_ts < 0
68
92
 
69
- starting_timestamp_given_srt = EdlParser.translate_string_to_seconds(starting_timestamp_given_srt)
70
- starting_timestamp_actual = EdlParser.translate_string_to_seconds(starting_timestamp_actual)
71
- ending_srt = EdlParser.translate_string_to_seconds(ending_srt)
72
- ending_actual = EdlParser.translate_string_to_seconds ending_actual
73
-
74
- # accomodate for both styles of rewrite, except it messes up the math, so just leave it separate:
93
+ # accomodate for both styles of rewrite, except it messes up the math...delete this soon...
75
94
  # difference = starting_timestamp_given_srt - starting_timestamp_actual
76
95
  # subtract_from_each_beginning_ts += difference
77
96
  # add_to_end_each_ts -= difference
78
97
 
79
98
  # you minus the initial srt time... (given)
80
99
  # ratio = (end actual - init actual/ end given - init given)*(how far you are past the initial srt) plus initial actual
81
- multiply_by_this_factor = (ending_actual - starting_timestamp_actual)/(ending_srt - starting_timestamp_given_srt)
82
-
83
- multiply_proc = proc {|you|
84
- ((you - starting_timestamp_given_srt) * multiply_by_this_factor) + starting_timestamp_actual
100
+ multiply_by_this_factor = (ending_actual_time - starting_time_actual)/(ending_srt_time - starting_time_given_srt)
101
+
102
+ multiply_proc = proc {|you|
103
+ ((you - starting_time_given_srt) * multiply_by_this_factor) + starting_time_actual
85
104
  }
86
105
 
87
106
 
@@ -112,9 +131,10 @@ module SubtitleProfanityFinder
112
131
 
113
132
 
114
133
 
115
- bad_profanities = {'hell' => ['he..', :full_word],
134
+ bad_profanities = {'hell' => ['h...', :full_word],
116
135
  'g' +
117
- 'o' + 100.chr => 'goodness', 'g' +
136
+ 111.chr +
137
+ 100.chr => ['vain use', :partial_word, 'deity'], 'g' +
118
138
  111.chr +
119
139
  100.chr +
120
140
  's' => 'deitys',
@@ -126,7 +146,7 @@ module SubtitleProfanityFinder
126
146
  99.chr +
127
147
  107.chr =>
128
148
  'f...',
129
- 'allah' => 'allah',
149
+ 'allah' => 'all..',
130
150
  'bi' +
131
151
  'tc' + 104.chr => 'b....',
132
152
  'bas' +
@@ -135,95 +155,113 @@ module SubtitleProfanityFinder
135
155
  's'*2)) => ['a..', :full_word],
136
156
  arse + 'h' +
137
157
  'ole' => 'a..h...',
138
- 'dieu' => ['deity', :full_word], # TODO fails...
139
- arse + 'wipe' => 'a..w....',
158
+ 'dieu' => ['deity', :full_word],
159
+ arse + 'w' +
160
+ 'ipe' => 'a..w...',
140
161
  'jes' +
141
- 'u' + 's' => 'j....',
162
+ 'u' + 's' => ['vain use', :partial_word, 'deity'],
142
163
  'chri' +
143
- 'st'=> ['chr...', :full_word], # allow for christian[ity] [good idea or not?]
164
+ 'st'=> ['vain use', :full_word, 'deity'], # allow for christian[ity]
144
165
  'sh' +
145
166
  'i' + 't' => 'sh..',
146
- 'a realllly bad word' => ['test edited bad word', :full_word]
167
+ 'cu' +
168
+ 'nt' => 'c...',
169
+ 'cocksucker' => 'cock......',
147
170
  }
148
171
 
149
172
  bad_profanities.merge! extra_profanity_hash # LODO make easier to use...
150
173
 
151
174
  semi_bad_profanities = {}
152
- ['bloody', 'moron', 'breast', 'idiot',
153
- 'sex', 'genital', 'boob', 'make love',
154
- 'making love', 'love mak',
155
- 'dumb', 'suck',
156
- 'piss'
175
+ ['moron', 'breast', 'idiot',
176
+ 'sex', 'genital',
177
+ 'boob',
178
+ 'tits',
179
+ 'make love', 'pen' +
180
+ 'is',
181
+ 'pussy',
182
+ 'fart',
183
+ 'making' +
184
+ ' love', 'love mak',
185
+ 'dumb', 'suck', 'piss', 'c' +
186
+ 'u' + 'nt',
187
+ 'd' + 'ick', 'vag' +
188
+ 'i' + 'na',
157
189
  ].each{|name|
158
- # butter?
159
190
  semi_bad_profanities[name] = name
160
191
  }
192
+ semi_bad_profanities['bloody'] = 'bloo..'
161
193
  semi_bad_profanities['crap'] = ['crap', :full_word]
162
194
  semi_bad_profanities['butt'] = ['butt', :full_word]
163
-
164
- all_profanity_combinationss = [convert_to_regexps(bad_profanities), convert_to_regexps(semi_bad_profanities)]
195
+ # butter?
196
+
197
+ all_profanity_combinationss = [convert_to_regexps(bad_profanities)]
198
+ if include_minor_profanities
199
+ all_profanity_combinationss += [convert_to_regexps(semi_bad_profanities)]
200
+ end
165
201
 
166
202
  output = ''
203
+ entries = split_to_entries(subtitles)
167
204
  for all_profanity_combinations in all_profanity_combinationss
168
205
  output += "\n"
169
- for glop in split_to_glops(subtitles)
170
- for profanity, (sanitized, whole_word) in all_profanity_combinations
171
- # dunno if we should force words to just start with this or contain it anywhere...
172
- # what about 'g..ly' for example?
173
- # or 'un...ly' ? I think we're ok there...
174
-
175
- if glop =~ profanity
176
- # create english-ified version
177
- # take out timing line, number line
178
- sanitized_glop = glop.lines.to_a[1..-1].join(' ')
179
- sanitized_glop.gsub!(/[\r\n]/, '') # flatten 3 lines to 1
180
- sanitized_glop.gsub!(/<(.|)(\/|)i>/i, '') # kill <i>
181
- sanitized_glop.gsub!(/[^a-zA-Z0-9'""]/, ' ') # kill weird stuff like ellipses
182
- sanitized_glop.gsub!(/\W\W+/, ' ') # remove duplicate " " 's
183
-
184
- # sanitize the subtitles themselves...
185
- for all_profanity_combinations2 in all_profanity_combinationss
186
- for (prof2, (sanitized2, whole_word2)) in all_profanity_combinations2
187
- if sanitized_glop =~ prof2
188
- sanitized_glop.gsub!(prof2, sanitized2)
189
- end
190
- end
191
- end
192
-
193
- # because we have duplicate's for the letter l/i, refactor [[[profanity]]]
194
- sanitized_glop.gsub!(/\[+/, '[')
195
- sanitized_glop.gsub!(/\]+/, ']')
196
-
197
- # extract timing info
198
- timing_line = glop.split("\n").first.strip
199
- timing_line =~ /((\d\d:\d\d:\d\d),(\d\d\d) --> (\d\d:\d\d:\d\d),(\d\d\d))/
200
- # "00:03:00.0" , "00:04:00.0", "violence", "of some sort",
201
- ts_begin = "#{$2}.#{$3}"
202
- ts_begin = EdlParser.translate_string_to_seconds ts_begin
203
- ts_begin -= subtract_from_each_beginning_ts
204
- ts_begin = multiply_proc.call(ts_begin)
205
- ts_begin = EdlParser.translate_time_to_human_readable ts_begin, true
206
- ts_end = "#{$4}.#{$5}"
207
- ts_end = EdlParser.translate_string_to_seconds ts_end
208
- ts_end += add_to_end_each_ts
209
- ts_end = multiply_proc.call(ts_end)
210
- ts_end = EdlParser.translate_time_to_human_readable ts_end, true
211
- unless output.contain? ts_begin
212
- output += %!"#{ts_begin}" , "#{ts_end}", "profanity", "#{sanitized.gsub(/[\[\]]/, '').strip}", "#{sanitized_glop.strip}",\n!
206
+ for entry in entries
207
+ text = entry.text
208
+ ts_begin = entry.beginning_time
209
+ ts_begin -= subtract_from_each_beginning_ts
210
+ ts_begin = multiply_proc.call(ts_begin)
211
+
212
+ ts_end = entry.ending_time
213
+ ts_end += add_to_end_each_ts
214
+ ts_end = multiply_proc.call(ts_end)
215
+ found_category = nil
216
+ for (profanity, category, sanitized) in all_profanity_combinations
217
+ if text =~ profanity
218
+ found_category = category
219
+ break
220
+ end
221
+ end
222
+
223
+ if found_category
224
+ # sanitize/euphemize the subtitle text for all profanities...
225
+ for all_profanity_combinations2 in all_profanity_combinationss
226
+ for (profanity, category, sanitized) in all_profanity_combinations2
227
+ text.gsub!(profanity, sanitized)
213
228
  end
214
229
  end
230
+
231
+ # because we now have duplicate's for the letter l/i, refactor [[[word]]] to just [word]
232
+ text.gsub!(/\[+/, '[')
233
+ text.gsub!(/\]+/, ']')
234
+ entry.text = text
235
+ text = text.gsub(/[\r\n]|\n/, ' ') # flatten up to 3 lines of text to just 1
236
+ ts_begin_human = EdlParser.translate_time_to_human_readable ts_begin, true
237
+ ts_end_human = EdlParser.translate_time_to_human_readable ts_end, true
238
+ unless output.contain? ts_begin_human # some previous profanity already found this line :P
239
+ output += %! "#{ts_begin_human}" , "#{ts_end_human}", "profanity", "#{found_category}", "#{text}",\n!
240
+ end
215
241
  end
216
242
  end
217
243
  end
218
- output
219
-
244
+ # update timestamps to be synchro'ed
245
+ for entry in entries
246
+ entry.beginning_time = multiply_proc.call(entry.beginning_time)
247
+ entry.ending_time = multiply_proc.call(entry.ending_time)
248
+ end
249
+ [output, entries]
220
250
  end
221
251
  end
222
252
 
223
253
  if $0 == __FILE__
224
254
  if ARGV.empty?
225
- p 'syntax: filename.srt [prof1 sanitized_equivalent1 prof2 sanitized_equivalent2 ...]'
255
+ p 'syntax: [filename.srt | [--create-edl|--create-edl-including-minor-profanities] input_name.srt output_name.edl]'
226
256
  exit
257
+ elsif ARGV[0].in? ['--create-edl', '--create-edl-including-minor-profanities']
258
+ require_relative 'mplayer_edl'
259
+ incoming_filename = ARGV[1]
260
+ include_minors = true if ARGV[0] == '--create-edl-including-minor-profanities'
261
+ mutes = SubtitleProfanityFinder.edl_output_from_string File.read(incoming_filename), {}, 0, 0, "00:00", "00:00", "10:00:00", "10:00:00", include_minors
262
+ specs = EdlParser.parse_string %!"mutes" => [#{mutes}]!
263
+ File.write(ARGV[2], MplayerEdl.convert_to_edl(specs))
264
+ puts "wrote to #{ARGV[2]}"
227
265
  else
228
266
  print SubtitleProfanityFinder.edl_output ARGV.first
229
267
  end
@@ -89,7 +89,7 @@ class VLCProgrammer
89
89
  </track>"
90
90
  else
91
91
  "vlc --qt-start-minimized #{loc} --start-time=#{start} --stop-time=#{stop} --sout=\"file/ps:#{@filename_or_playlist_if_nil}.ps.#{idx}\" #{"--no-sout-audio" if no_audio} vlc://quit\n" # +
92
- #"call vlc #{@filename_or_playlist_if_nil}.ps.#{idx}.tmp --sout=file/ps:go.ps
92
+ #"vlc #{@filename_or_playlist_if_nil}.ps.#{idx}.tmp --sout=file/ps:go.ps
93
93
  end
94
94
  end
95
95
 
@@ -0,0 +1,50 @@
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
+
19
+ require_relative 'edl_parser'
20
+
21
+ class ZoomPlayerMaxEdl
22
+
23
+ def self.convert_to_edl_string specs
24
+
25
+ raise 'needs timestamps_relative_to--or rather, ping me if you want this for file based' unless specs['timestamps_relative_to']
26
+ combined = EdlParser.convert_incoming_to_split_sectors specs
27
+ raise unless mpeg_offset = specs['dvd_start_offset'] # TODO make this a class... also rename it mpeg_dvd_start_offset
28
+ raise unless dvd_nav_packet_offsets = specs['dvd_nav_packet_offset']
29
+ combined2 = EdlParser.convert_to_dvd_nav_times combined, specs['timestamps_relative_to'][0], mpeg_offset.to_f, dvd_nav_packet_offsets, specs['timestamps_relative_to'][1].to_f
30
+ out = ""
31
+ track = specs['dvd_title_track']
32
+ out += "DVDTitle(#{track})\n"
33
+ =begin
34
+ DVDTitle(1)
35
+ CutSegment("Start=27.389","End=32.209")
36
+ CutSegment("Start=73.510","End=78.510")
37
+ MuteAudio("From=39.389","Duration=41.389")
38
+ =end
39
+ for start, endy, type in combined2
40
+ if type == :mute
41
+ out += %!MuteAudio("From=#{start}","Duration=#{endy-start}")\n!
42
+ elsif type == :blank
43
+ out += %!CutSegment("Start=#{start}","End=#{endy}")\n!
44
+ else
45
+ raise
46
+ end
47
+ end
48
+ out
49
+ end
50
+ end