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
@@ -1,32 +1,31 @@
1
-
2
1
  == Overly Verbose History ==
3
2
 
4
- Sensible Cinema was preceded/inspired by EDL's of editors in the 90's, cleanflicks (both analog and digital incantations, late 90's),
5
- then mplayer began to support EDL, zoomplayer added a scene-cut editor,
3
+ Sensible Cinema was preceded by EDL's [2] of video editors in the 90's,
4
+ cleanflicks (both analog and digital/DVD incantations, late 90's),
5
+ then more recently mplayer began to support EDL, zoomplayer added a scene-cut editor some years ago,
6
6
  http://code.google.com/p/movie-content-editor came along, and also many
7
- other editors have historically supported EDL for content creation and/or playback (see wikipedia's "edit decision list"),
8
- such as mythtv/XBMC's EDL support (as suggested by the phantom edit [1], oreillynet.com),
9
- VLC also added playlists with optional start and stop positions per entry. Ffmpeg, mencoder were high quality video editing open source tools.
10
- Once I discovered all of these previously existing programs, I knew the right elements were ready for
11
- something like sensible cinema.
7
+ other editors have supported EDL for content creation and/or playback,
8
+ such as mythtv/XBMC's EDL support (as suggested by the phantom edit [1], from oreillynet.com),
9
+ VLC also added playlists with optional start and stop positions per entry.
10
+ Ffmpeg, mencoder were high quality video editing open source video tools.
11
+ Once I discovered all of these previously existing programs, I knew the right pieces were ready.
12
12
 
13
13
  See also the "related" section, and "motivation" section. See also the change_log_with_feature_list.txt file, and several
14
- blog entries I've posted historically.
14
+ blog entries I've posted to various blogs.
15
15
 
16
16
  Originally the project started as a prototype to "watch hulu (online) and netflix instant movies
17
- edited" (it uses/used screen snapshots (of specific locations where the digits are expected, based on windows position)
17
+ edited" (it uses screen snapshots (of specific locations where the digits are expected, based on window positions)
18
18
  and then tracks, using OCR of the on-screen (convert to timestamp), to monitor it for specific times relative
19
- to an EDL, and react appropriately.
20
- However, this functionality, though working and available, is disabled currently for potential patent
21
- issues. Some older released versions had it enabled, but not the later releases.
22
- Then I realized I could basically have the same effect by instructing a video player (VLC) to "play from second x to y"
19
+ to an EDL, and reacts appropriately.
20
+ Then I realized I could basically have the same effect by instructing any video player (VLC) to "play from second x to y"
23
21
  ok "now play from z to q muted" etc. (so kind of a stop and go video player, kind of like controlling the remote for you).
24
22
  It basically was implementing Edit Decision Lists (EDL's) using playlists and
25
23
  VLC.
26
- I just passed VLC a playlist, it did all the work for me, without any necessary real-time tracking. This seemed patent friendly,
27
- so I went with this. There are a few released versions with this feature enabled.
24
+ I just passed VLC a playlist, it did all the work for me, without any necessary tracking on my part.
25
+ This seemed to be a different approach than some other programs out there take, so I
26
+ explored this route. There were even a few released versions with this feature.
28
27
  They avoid real-time tracking by specifying "play from here to here"
29
- not "skip from here to here" as some other editing players do.
28
+ not "skip from here to here" as some other players do.
30
29
 
31
30
  Then it occurred to me that one could grab the several clean segments
32
31
  off a movie file, and piece them together to create an edited clean version ( a la cleanflix ). This also avoids
@@ -34,7 +33,8 @@ realtime tracking, so I also included this ability.
34
33
  The playlist option is disabled in later releases, as it was deemed too user-non-friendly, and because VLC timing
35
34
  is "different" than standard DVD players, so I decided to just use standardized timing, though it worked fine
36
35
  for VLC playbacks.
37
- I replaced it with support for mplayer's EDL format, which works better, and has consistent timing, though is still a bit buggy.
36
+ I replaced it with support for mplayer's EDL format, which works better, and has consistent timing,
37
+ though is still a bit buggy, please report any issues you may find on it.
38
38
 
39
39
  You can see a full list of other features that have been published and demonstrated
40
40
  in the accompanying file change_log_with_feature_list.txt. Each feature mentioned works
@@ -44,33 +44,34 @@ in some released version of sensible-cinema though some features have been remov
44
44
  Who knows what the future will hold...
45
45
 
46
46
  [1] http://www.oreillynet.com/sysadmin/blog/2005/06/make_your_own_phantom_edit_wit.html
47
+ [2] http://en.wikipedia.org/wiki/Edit_decision_list
47
48
 
48
49
  == Related ==
49
50
 
50
51
  The concepts I use aren't novel. Some other previously existing related type examples:
51
52
 
52
53
  Edited "airplane edit" style movies.
53
- Commercial TV (ABC, NBC) show their own (edited) movies.
54
+ Commercial TV (ABC, NBC) show their own (edited for TV) movies, for instance Schindler's List was slightly edited when shown on television.
54
55
  http://en.wikipedia.org/wiki/Linear_video_editing
55
56
  http://en.wikipedia.org/wiki/Edit_decision_list#Systems_supporting_EDL_playback.2C_not_just_EDL_cutting lists a lot of players that support EDL DVD playback in some form or another.
56
- http://imdb.com tends to have reasonably good lists of what occurs in movies (find a movie, click on "parent's guide" on the left). Sometimes it even lists the time signatures for events (ex: "Labyrinth" http://www.imdb.com/title/tt0091369/parentalguide) which you could use to translate into a sensible-cinema compatible list.
57
+ http://imdb.com tends to have reasonably good lists of what occurs in movies (find a movie, click on "parent's guide" on the left). Sometimes it even lists the time signatures for events (ex: "Labyrinth" http://www.imdb.com/title/tt0091369/parentalguide) which you could use to translate into a sensible-cinema compatible list. I've even released a version of SC that has working time edits pulled from a wiki like that.
57
58
  Normal DVD's versus "directors cut" versions of movies (one is at times preferable, content wise)
58
59
  http://en.wikipedia.org/wiki/Edit_decision_list (it's a linear editing tool, after all--so see the vast list of those)
59
60
  Clean Flicks (used to) sell edited movies
60
61
  http://college.swankmp.com/insti/edited.asp prisoners apparently have access to a few "edited" versions of movies (not many though, but there are some listed there)
61
62
  http://www.videoredo.com/en/index.htm lets you "cut out" offensive content (commercials et al) and burn DVD's from mpeg's/h264 streams, and has its own EDL syntax http://wiki.xbmc.org/?title=EDL_%28commercial_skipping%29_and_SceneMarker_support
62
63
  http://www.microsoft.com/windows/windowsmedia/howto/articles/device_control.aspx Windows Media Encoder supports EDL's by timestamp
63
- http://cutlist.at shared "commercial skip" cutlists
64
+ http://cutlist.at has community shared cutlists (in this instance, for commercials)
64
65
  http://www.mplayerhq.hu/DOCS/HTML/en/edl.html
65
- Time programmable VCR's (at the least, 'skip the first few minutes')
66
+ Time programmable VCR's (at the least, it can 'skip the first few minutes' of a movie or what not, and, if you're handy with the pause and rewind buttons on you remote, edit offensive content)
66
67
  http://www.amazon.com/Make-Edited-Movies-ebook/dp/B004EYT3BU
67
68
  http://www.sharewareconnection.com/fast-compress-content-and-anti-profanity.htm replaces profanity in web pages with euphemized content.
68
69
  MovieMask apparently had capability of "overlaying" DVD playback, like adding new clothing to people, and other features.
69
70
  http://www.oreillynet.com/sysadmin/blog/2005/06/make_your_own_phantom_edit_wit.html (mplayer has had this ability for awhile, with no complaints).
70
71
  http://fanedit.org/49 fanedits take the original and remix it through some means for more enjoyable playbacks.
71
72
  http://clearplay.com a commercial "filtering" DVD player See the "motivation" section for a description.
72
- It does offer a few features that sensible cinema supports but disables by default, for patent reasons,
73
- like automatic (user flexible) content decisions.
73
+ It does offer a few features that sensible cinema supports but does not provide access to,
74
+ like (user flexible) content decisions.
74
75
  http://en.wikipedia.org/wiki/RiffTrax has an interesting idea of "overlaying" audio over the original video, and synchronizing between the two (their re-player does, anyway).
75
76
  http://forum.bsplayer.com/feature-requests-feedback-suggestions/7157-chapter-playlist-scene-cut-3.html
76
77
  http://www.inmatrix.com zoom player's "scene cut editor"
@@ -78,27 +79,30 @@ edited released movies by the producer, like http://en.wikipedia.org/wiki/Seven_
78
79
  http://wiki.xbmc.org/?title=EDL_(commercial_skipping)_and_SceneMarker_support (XBMC's scene cut supporter--also contains links to some other editors' support for EDL's)
79
80
  http://dvdshrink.info "Re-author" mode: to make "movie-only" backups, compilations, combine "flippers",.... DvdShrink has the ability to "crop or cut parts of a title" etc.
80
81
  The VCR with its record button, coupled with the stop+rewind button and a list of edits (if even in your head).
81
- http://kb2.adobe.com/cps/191/tn_19151.html Adobe Director MX 2004 can "script" DVD playback.
82
+ http://kb2.adobe.com/cps/191/tn_19151.html Adobe Director MX 2004 can "script" DVD playback apparently.
82
83
  DVD's themselves allow for "scripted" playback of certain content, allowing controls for jumping from location to location, switching audio/video tracks, etc.
83
- http://code.google.com/p/movie-content-editor (player written in Python, controls VLC based on subtitles and user-input, using edit decision lists in realtime)
84
+ DVD's with different titles based on content.
85
+ http://code.google.com/p/movie-content-editor (player written in Python, controls VLC based on subtitles and user-input'ed EDL's, using edit decision lists in realtime)
84
86
  http://forums.gbpvr.com/showthread.php?10606-Automated-Cutting-and-Transcoding-Guide-Using-Mencoder/page45
85
87
  http://www.imdb.com/swiki/special?ParentalGuideHelp (search for "scene description")
86
88
  http://www.mythtv.org/wiki/Removing_Commercials
87
89
  showanalyzer http://www.dragonglobal.biz/showanalyzer.html and comskip analyze videos to look for "segments to cut out" automatically (commercials, in this case, but the principle still applies)
88
90
  Old-school: using the remote control with the pause, mute, stop, fast forward, and play buttons, along with previous knowledge of "questionable" scene locations
89
- The scissors and old VHS tapes (Clean Flicks' origin, if I remember correctly). http://www.familysafemedia.com/home_movie_editor.html (was a helper kit for cutting VHS tape)
91
+ The scissors and old VHS tapes (Clean Flicks' original method, if I remember correctly). http://www.familysafemedia.com/home_movie_editor.html (was a helper kit for cutting VHS tape)
90
92
  Windows Movie Maker. Allows for users to cut and copy scenes of movies. Really any editor can do this.
91
93
  http://forum.videolan.org/viewtopic.php?f=7&t=56998 VLC Media Player using EDL's via playlists
92
- Corel WinDVD has "Quick Clip" settings for capturing from DVD.
94
+ Corel WinDVD has "Quick Clip" settings for capturing movie from DVD's.
93
95
  Microsoft's built-in magnifier basically copies DVD's screen output if mouse is placed over playing DVD.
94
96
  http://superuser.com/questions/85278/how-can-i-cut-scenes-out-of-a-dvd
95
97
  moviemask once had several advanced features: http://theeditedmovieencyclopedia.blogspot.com/2008/06/cleaning-up-movies-part-2.html
96
98
  http://blog.josephhall.com/2008/09/command-line-dvd-authoring-part-1.html
97
99
  AviSynth can script dvd playback http://forum.doom9.org/archive/index.php/t-109558.html
98
- ps3 media server has edl support: https://github.com/chocolateboy/PMS-EDL maybe would work with DVD's dunno
99
- Anydvd HD's "magic file replacement" for DVD's/blu-ray's
100
- RiffTrax allows for an audio "overlay" to a DVD playback, have their own player to coordinate the two.
101
- "fan subs" are edited subtitles, displayed overlaid on the original track/video
100
+ ps3 media server has edl support: https://github.com/chocolateboy/PMS-EDL
101
+ Anydvd HD's "magic file replacement" for DVD's/blu-ray's. Google for it.
102
+ RiffTrax allows for an audio "overlay" to a DVD playback, have their own player to coordinate the extra audio track with the playing video.
103
+ http://www.youtube.com/watch?v=0vumR5Hcz7s is an Emacs "EDL editor" which uses mplayer and Media Lovin' Toolkit framework.
104
+ "fan subs" are edited subtitles, displayed overlaid on the original track/video, or so I'm told.
102
105
  Avatar DVD was released with an audio track that was "euphemized" of the profanity.
106
+ kids-in-mind.com lists basically all the bad things that happen in movies (very detailedly) as also does common sense media, though without any timestamps unfortunately.
103
107
 
104
- BYU's Varsity theater used to edit movies, and show them.
108
+ BYU's Varsity theater used to edit movies, and show them on the big screen.
File without changes
@@ -0,0 +1,23 @@
1
+ The design, not the idea.
2
+
3
+ OCR can work on internet or standalone players.
4
+ time elapsed "since the timestamp changed" on screen infers the more precise millisecond
5
+ you are at, for being able to skip, mute, overlay, apply overlaid transparent image/video more precisely.
6
+ You can grab the specific coordinates by precise location, or by iterating over windows, or by relative location to screen coordinates/window coordinates.
7
+ You can use the url to infer the title desired.
8
+ You can use user preferences to infer how to use each setting within the "EDL" by saving the user preference, and comparing it
9
+ against each entry in the EDL when you parse it.
10
+
11
+ It can mute by clicking a mute button, by accessing an API.
12
+ It can work by monitoring, using an API, the current playback time.
13
+
14
+ It can react to "seek" commands to coordinate position within EDL's.
15
+
16
+ Another invention: it can apply editing "commands" to a player that is playing back blu-ray discs (hardware or software), as originally described in other clearplay
17
+ patents, like US6889383 and those issued to them afterward.
18
+
19
+ You can get the specific digits by "absolute digit location" or by "OCR on the entire timestamp"
20
+
21
+ Could also playback using avisynth.
22
+
23
+ Can create edited files.
@@ -17,9 +17,10 @@ This file is part of Sensible Cinema.
17
17
  =end
18
18
 
19
19
  def add_any_bundled_gems_to_load_path
20
- raise 'no vendor dir?' unless File.directory? 'vendor'
21
- if File.directory? 'vendor/cache'
22
- Dir['vendor/**/lib'].sort.reverse.each{|lib_dir| # prefers newer versioned copies of gems in case I have duplicates
20
+ vendor_dir = File.dirname(__FILE__) + '/../vendor'
21
+ raise 'no vendor dir?' unless File.directory?(vendor_dir)
22
+ if File.directory? vendor_dir + '/cache'
23
+ Dir[vendor_dir + '/**/lib'].sort.reverse.each{|lib_dir| # prefers newer versioned copies of gems in case I have duplicates
23
24
  $: << lib_dir
24
25
  }
25
26
  else
@@ -2,8 +2,11 @@ require 'rubygems'
2
2
  require 'os'
3
3
  success = true
4
4
 
5
- # MPlayer OSX Extended instead of smplayer... ?
5
+ ENV['PATH'] = '/opt/rdp_project_local/bin/:' + ENV['PATH'] # macports' bin in first
6
+
6
7
  module CheckInstalledMac
8
+
9
+ # should output an error message...
7
10
  def self.check_for_installed name
8
11
  if name == 'mencoder'
9
12
  output = `mencoder --fail 2>&1`
@@ -16,17 +19,14 @@ module CheckInstalledMac
16
19
  end
17
20
 
18
21
  if name == 'mplayer'
19
- for path in ["/Applications/MPlayerX.app/Contents/Resources/binaries/m32", File.expand_path('~') + "/Downloads/MPlayerX.app/Contents/Resources/binaries/m32/"]
20
- if File.exist? path + "/mplayer"
21
- ENV['PATH'] = path + ':' + ENV['PATH']
22
- return true
23
- end
22
+ unless File.exist?('/opt/rdp_project_local/bin/mplayer')
23
+ puts "please install mplayer edl, please install mplayer-edl, see website http://rogerdpack.t28.net/sensible-cinema/content_editor.html"
24
+ return false
24
25
  end
25
- puts 'lacking mplayer! please install MPlayerX from the App Store first'
26
- return false
26
+ return true
27
27
  end
28
28
 
29
- # check for the others as generics
29
+ # check for the others generically
30
30
 
31
31
  command = {"gocr" => "gocr --help", "convert" => "convert --help", "ffmpeg" => "ffmpeg -version"}[name]
32
32
 
@@ -34,7 +34,7 @@ module CheckInstalledMac
34
34
 
35
35
  unless system(command + " 1> " + OS.dev_null + " 2>" + OS.dev_null)
36
36
  name = 'ImageMagick' if name == 'convert' # special case...
37
- puts 'lacking dependency! Please install ' + name + ' by installing macports and running in terminal: $ sudo port install ' + name
37
+ puts 'lacking dependency! Please install ' + name + ' by installing the contrib pkg from the website'
38
38
  false
39
39
  else
40
40
  true
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- require 'sane'
2
+ require 'sane' # require_relative
3
3
  require_relative 'jruby-swing-helpers/swing_helpers'
4
4
 
5
5
  include SwingHelpers
@@ -7,9 +7,9 @@ include SwingHelpers
7
7
  class MainWindow < JFrame
8
8
 
9
9
  def show_blocking_message_dialog(message, title = message.split("\n")[0], style= JOptionPane::INFORMATION_MESSAGE)
10
- # I think I'm already on top...
11
- setVisible(true);
12
- toFront()
10
+ # I think I'm already on top...
11
+ setVisible(true);
12
+ toFront()
13
13
  JOptionPane.showMessageDialog(nil, message, title, style)
14
14
  true
15
15
  end
@@ -17,8 +17,34 @@ This file is part of Sensible Cinema.
17
17
  =end
18
18
 
19
19
  require 'sane'
20
+ require_relative 'convert_thirty_fps'
21
+
20
22
  class EdlParser
21
23
 
24
+ # this one is 1:01:02.0 => 36692.0
25
+ # its reverse is this: translate_time_to_human_readable
26
+ def self.translate_string_to_seconds s
27
+ # might actually already be a float, or int, depending on the yaml
28
+ # int for 8 => 9 and also for 1:09 => 1:10
29
+ if s.is_a? Numeric
30
+ return s.to_f # easy out.
31
+ end
32
+
33
+ s = s.strip
34
+ # s is like 1:01:02.0
35
+ total = 0.0
36
+ seconds = nil
37
+ seconds = s.split(":")[-1]
38
+ raise 'does not look like a timestamp? ' + seconds.inspect unless seconds =~ /^\d+(|[,.]\d+)$/
39
+ seconds.gsub!(',', '.')
40
+ total += seconds.to_f
41
+ minutes = s.split(":")[-2] || "0"
42
+ total += 60 * minutes.to_i
43
+ hours = s.split(":")[-3] || "0"
44
+ total += 60* 60 * hours.to_i
45
+ total
46
+ end
47
+
22
48
  EDL_DIR = File.expand_path(__DIR__ + "/../zamples/edit_decision_lists/dvds")
23
49
 
24
50
  if File::ALT_SEPARATOR
@@ -35,7 +61,7 @@ class EdlParser
35
61
  output.merge! new_input
36
62
  end
37
63
 
38
- require_relative 'gui/sensible-cinema-dependencies' # for download method...
64
+ require_relative 'gui/dependencies' # for download methods...
39
65
 
40
66
  if expand
41
67
 
@@ -52,65 +78,78 @@ class EdlParser
52
78
  end
53
79
 
54
80
  def self.parse_imdb output, imdb_id
55
- require_relative 'convert_thirty_fps'
56
- url = "http://www.imdb.com/title/#{imdb_id}/parentalguide"
57
- all = SensibleSwing::MainWindow.download_to_string(url)
58
-
59
- header, violence_word, violence_section, profanity_word, profanity_section, alcohol_word, alcohol_section, frightening_word, frightening_section =
60
- sections = all.split(/<span>(Violence|Profanity|Alcohol|Frightening)/)
61
- header = sections.shift
62
- all ={}
63
- while(!sections.empty?) # my klugey to_hash method
64
- word_type = sections.shift
65
- settings = sections.shift
66
- assert word_type.in? ['Violence', 'Profanity', 'Alcohol', 'Frightening']
67
- all[word_type] = settings
68
- end
69
- # blank_outs or mutes for each...
70
- # TODO make the -> optional
71
- split_into_timestamps = /([\d:]+(?:\.\d+|))\W*-&gt;\W*([\d:]+(?:\.\d+|))([^\d\n]+)/
72
- for type, settings in all
73
- settings.scan(split_into_timestamps) do |begin_ts, end_ts, description|
74
- puts "parsing from wiki imdb entry violence: #{begin_ts} #{end_ts} #{description} #{type}"
75
- start_seconds = translate_string_to_seconds begin_ts
76
- end_seconds = translate_string_to_seconds end_ts
77
- # convert from 30 to 29.97 fps ... we presume ...
78
- start_seconds = ConvertThirtyFps.from_twenty_nine_nine_seven start_seconds
79
- start_seconds = ("%.02f" % start_seconds).to_f # round
80
- start_seconds = translate_time_to_human_readable start_seconds, true
81
- end_seconds = ConvertThirtyFps.from_twenty_nine_nine_seven end_seconds
82
- end_seconds = ("%.02f" % end_seconds).to_f # round
83
- end_seconds = translate_time_to_human_readable end_seconds, true
84
- p end_seconds
85
- if type == 'Profanity'
86
- output['mutes'] << [start_seconds, end_seconds]
87
- else
88
- output['blank_outs'] << [start_seconds, end_seconds]
89
- end
90
- end
81
+ require_relative 'convert_thirty_fps'
82
+ url = "http://www.imdb.com/title/#{imdb_id}/parentalguide"
83
+ all = SensibleSwing::MainWindow.download_to_string(url)
84
+
85
+ header, violence_word, violence_section, profanity_word, profanity_section, alcohol_word, alcohol_section, frightening_word, frightening_section =
86
+ sections = all.split(/<span>(Violence|Profanity|Alcohol|Frightening)/)
87
+ header = sections.shift
88
+ all ={}
89
+ while(!sections.empty?) # my klugey to_hash method
90
+ word_type = sections.shift
91
+ settings = sections.shift
92
+ assert word_type.in? ['Violence', 'Profanity', 'Alcohol', 'Frightening']
93
+ all[word_type] = settings
94
+ end
95
+ # blank_outs or mutes for each...
96
+ # TODO make the -> optional
97
+ split_into_timestamps = /([\d:]+(?:\.\d+|))\W*-&gt;\W*([\d:]+(?:\.\d+|))([^\d\n]+)/
98
+ for type, settings in all
99
+ settings.scan(split_into_timestamps) do |begin_ts, end_ts, description|
100
+ puts "parsing from wiki imdb entry violence: #{begin_ts} #{end_ts} #{description} #{type}"
101
+ start_seconds = translate_string_to_seconds begin_ts
102
+ end_seconds = translate_string_to_seconds end_ts
103
+ # convert from 30 to 29.97 fps ... we presume ...
104
+ start_seconds = ConvertThirtyFps.from_twenty_nine_nine_seven start_seconds
105
+ start_seconds = ("%.02f" % start_seconds).to_f # round
106
+ start_seconds = translate_time_to_human_readable start_seconds, true
107
+ end_seconds = ConvertThirtyFps.from_twenty_nine_nine_seven end_seconds
108
+ end_seconds = ("%.02f" % end_seconds).to_f # round
109
+ end_seconds = translate_time_to_human_readable end_seconds, true
110
+ p end_seconds
111
+ if type == 'Profanity'
112
+ output['mutes'] << [start_seconds, end_seconds]
113
+ else
114
+ output['blank_outs'] << [start_seconds, end_seconds]
91
115
  end
116
+ end
117
+ end
92
118
  end
93
119
 
94
120
  private
95
121
 
96
122
  def self.download full_url, to_here
97
- require 'open-uri'
98
- writeOut = open(to_here, "wb")
99
- writeOut.write(open(full_url).read)
100
- writeOut.close
123
+ ::SwingHelpers::MainWindow.download full_url, to_here
101
124
  end
102
125
 
103
126
  # better eye-ball these before letting people run them, eh? TODO
104
127
  # but I couldn't think of any other way to parse the files tho
105
- def self.parse_string string, filename, ok_categories_array = []
128
+ def self.parse_string string, filename = nil, ok_categories_array = []
106
129
  string = '{' + string + "\n}"
107
- if filename
108
- raw = eval(string, binding, filename)
109
- else
110
- raw = eval string
111
- end
130
+ begin
131
+ if filename
132
+ raw = eval(string, binding, filename, 0)
133
+ else
134
+ raw = eval string
135
+ end
136
+ rescue Exception => e
137
+ string.strip.lines.to_a[0..-3].each_with_index{|l, idx| # last line doesn't need a comma check
138
+ orig_line = l
139
+ l = l.split('#')[0]
140
+ l = l.strip
141
+ unless l.empty?
142
+ # todo strip off # comments at the end of lines too...
143
+ end_char = l[-1..-1]
144
+ if !end_char.in? [']', '[', '{'] # these are probably all ok...
145
+ puts "warning: line #{idx} might be bad: (maybe needs comma after?) " + l unless end_char == ','
146
+ end
147
+ end
148
+ }
149
+ raise SyntaxError.new(e.to_s) # to_s as a workaround for jruby #6353
150
+ end
112
151
 
113
- raise SyntaxError.new("maybe missing quotation marks?" + string) if raw.keys.contain?(nil)
152
+ raise SyntaxError.new("maybe missing quotation marks somewhere?" + string) if raw.keys.contain?(nil)
114
153
 
115
154
  # mutes and blank_outs need to be special parsed into arrays...
116
155
  mutes = raw["mutes"] || []
@@ -120,7 +159,7 @@ class EdlParser
120
159
  raw
121
160
  end
122
161
 
123
- # converts "blanks" => ["00:00:00", "00", "reason", "01", "01", "02", "02"] into sane arrays, also filters based on category, though disabled for production
162
+ # converts "blanks" => ["00:00:00", "00", "reason", "01", "01", "02", "02"] into sane arrays, also filters based on category, though not used in production
124
163
  def self.convert_to_timestamp_arrays array, ok_categories_array
125
164
  out = []
126
165
  while(single_element = extract_entry!(array))
@@ -151,10 +190,9 @@ class EdlParser
151
190
  out
152
191
  end
153
192
 
154
- #TimeStamp = /(^\d+:\d\d[\d:\.]*$|\d+)/ # this one also allows for 4444 [?] and also weirdness like "don't kill the nice butterfly 2!" ...
155
- TimeStamp = /(^\d+:\d\d[\d:\.]*|\d+\.\d+)$/ # allow 00:00:00 00:00:00.0 1222.4
156
- # disallow 1905 too but in the code
157
- # starts with a digit, has at least one colon followed by two digits,then some combo of digits and colons and periods...
193
+ # TimeStamp = /(^\d+:\d\d[\d:\.]*$|\d+)/ # this one also allows for 4444 [?] and also weirdness like "don't kill the nice butterfly 2!" ...
194
+ TimeStamp = /^\s*(\d+:\d\d[\d:\.]*|\d+\.\d+)\s*$/ # allow 00:00:00 00:00:00.0 1222.4 " 2:04 "
195
+ # disallow's 1905 too but elsewhere in the code
158
196
 
159
197
  def self.extract_entry! from_this
160
198
  return nil if from_this.length == 0
@@ -162,7 +200,7 @@ class EdlParser
162
200
  out = from_this.shift(2)
163
201
  out.each{|d|
164
202
  unless d =~ TimeStamp
165
- raise SyntaxError.new('non timestamp? ' + d)
203
+ raise SyntaxError.new('non timestamp? ' + d.inspect)
166
204
  end
167
205
  }
168
206
  while(from_this[0] && from_this[0] !~ TimeStamp)
@@ -172,99 +210,45 @@ class EdlParser
172
210
  out
173
211
  end
174
212
 
175
- def self.get_secs timestamp_string_begin, timestamp_string_end, add_begin, add_end, splits
176
- answers = []
177
- unless timestamp_string_begin
178
- raise 'non begin'
179
- end
180
- unless timestamp_string_end
181
- raise 'non end'
182
- end
183
- for type, offset, multiplier in [[timestamp_string_begin, add_begin, -1], [timestamp_string_end, add_end, 1]]
184
- original_secs = translate_string_to_seconds(type) + offset
185
- # now if splits is 900 and we'are at 909, then we're just 9
186
- closest_split_idx = splits.reverse.index{|t| t < original_secs}
187
- if closest_split_idx
188
- closest_split = splits.reverse[closest_split_idx]
189
- # add some extra seconds onto these if they're "past" a split, too
190
- original_secs = original_secs - closest_split + multiplier * (splits.length - closest_split_idx)
191
- original_secs = [0, original_secs].max # no negatives allowed :)
192
- end
193
- answers << original_secs
194
- end
195
- answers
196
- end
197
-
198
213
  public
199
214
 
200
- # called later, from external
215
+ # called later, from external files
201
216
  # divides up mutes and blanks so that they don't overlap, preferring blanks over mutes
202
217
  # returns it like [[start,end,type], [s,e,t]...] type like either :blank and :mute
203
- # [[70.0, 73.0, :blank], [378.0, 379.1, :mute]]
204
- def self.convert_incoming_to_split_sectors incoming, add_this_to_all_ends = 0, subtract_this_from_beginnings = 0, splits = []
218
+ # [ [70.0, 73.0, :blank], [378.0, 379.1, :mute], ... ]
219
+ def self.convert_incoming_to_split_sectors incoming, add_this_to_all_ends = 0, subtract_this_from_beginnings = 0, splits = [], subtract_this_from_ends = 0
205
220
  raise if subtract_this_from_beginnings < 0
206
221
  raise if add_this_to_all_ends < 0
207
- if splits != []
208
- # allow it to do all the double checks we later skip, just in case :)
209
- self.convert_incoming_to_split_sectors incoming
210
- end
222
+ raise if subtract_this_from_ends < 0
223
+ add_this_to_all_ends -= subtract_this_from_ends # now we allow negative :)
224
+ #raise if splits.size > 0 # for now
211
225
  mutes = incoming["mutes"] || {}
212
226
  blanks = incoming["blank_outs"] || {}
213
- mutes = mutes.map{|k, v| get_secs(k, v, -subtract_this_from_beginnings, add_this_to_all_ends, splits) + [:mute]}
214
- blanks = blanks.map{|k, v| get_secs(k, v, -subtract_this_from_beginnings, add_this_to_all_ends, splits) + [:blank]}
215
- combined = (mutes+blanks).sort
227
+ mutes = mutes.map{|k, v| [k,v,:mute]}
228
+ blanks = blanks.map{|k, v| [k,v,:blank]}
229
+ combined = (mutes+blanks).sort.map{|s,e,type| [translate_string_to_seconds(s), translate_string_to_seconds(e), type]}
216
230
 
217
- # detect overlap...
231
+ # detect any weirdness...
218
232
  previous = nil
219
- combined.each_with_index{|current, idx|
220
- s,e,t = current
221
- if e < s
222
- raise SyntaxError.new("detected an end before a start: #{e} < #{s}") if e < s unless splits.length > 0
233
+ combined.map!{|current|
234
+ s,e,type = current
235
+ if e < s || !s || !e || !type
236
+ raise SyntaxError.new("detected an end before a start or other weirdness: #{e} < #{s}")
223
237
  end
224
238
  if previous
225
- ps, pe, pt = previous
226
- if (s < pe)
227
- raise SyntaxError.new("detected an overlap #{[s,e,t].join(' ')} #{previous.join(' ')}") unless splits.length > 0
228
- # our start might be within the previous' in which case its their start, with (greater of our, their ending)
229
- preferred_end = [e,pe].max
230
- preferred_type = [t,pt].detect{|t| t == :blank} || :mute # prefer blank to mute
231
- combined[idx-1] = [ps, preferred_end, preferred_type]
232
- combined[idx] = nil # allow it to be culled later
239
+ ps, previous_end, pt = previous
240
+ if (s < previous_end)
241
+ raise SyntaxError.new("detected an overlap #{current.join(' ')} #{previous.join(' ')}")
233
242
  end
234
243
 
235
244
  end
236
245
  previous = current
246
+ # do the math later to allow for ones that barely hit into each other 1.0 2.0, 2.0 3.0
247
+ [s-subtract_this_from_beginnings, e+add_this_to_all_ends,type]
237
248
  }
238
- combined.compact
249
+ combined
239
250
  end
240
251
 
241
- # this one is 1:01:02.0 => 36692.0
242
- # its reverse is: translate_time_to_human_readable
243
- def self.translate_string_to_seconds s
244
- # might actually already be a float, or int, depending on the yaml
245
- # int for 8 => 9 and also for 1:09 => 1:10
246
- if s.is_a? Numeric
247
- return s.to_f
248
- end
249
-
250
- # s is like 1:01:02.0
251
- total = 0.0
252
- seconds = nil
253
- begin
254
- seconds = s.split(":")[-1]
255
- rescue Exception => e
256
- p 'failed!', s
257
- raise e
258
- end
259
- raise unless seconds =~ /^\d+(|[,.]\d+)$/
260
- seconds.gsub!(',', '.')
261
- total += seconds.to_f
262
- minutes = s.split(":")[-2] || "0"
263
- total += 60 * minutes.to_i
264
- hours = s.split(":")[-3] || "0"
265
- total += 60* 60 * hours.to_i
266
- total
267
- end
268
252
 
269
253
  # its reverse: translate_string_to_seconds
270
254
  def self.translate_time_to_human_readable seconds, force_hour_stamp = false
@@ -282,11 +266,12 @@ class EdlParser
282
266
  out << ":"
283
267
 
284
268
  # avoid an ugly .0 at the end
285
- if seconds == seconds.to_i
286
- out << "%02d" % seconds
287
- else
269
+ # if seconds == seconds.to_i
270
+ # out << "%02d" % seconds
271
+ # else
288
272
  out << "%05.2f" % seconds # man that printf syntax is tricky...
289
- end
273
+ # end
274
+
290
275
  end
291
276
 
292
277
  def self.all_edl_files_parsed use_all_not_just_dvds
@@ -298,36 +283,61 @@ class EdlParser
298
283
  [filename, parsed]
299
284
  rescue SyntaxError => e
300
285
  # ignore poorly formed edit lists for the auto choose phase...
301
- p 'warning, unable to parse a file:' + filename + " " + e.to_s
286
+ puts 'warning, unable to parse a file:' + filename + " " + e.to_s
302
287
  nil
303
288
  end
304
289
  }.compact
305
290
  end
306
291
 
307
292
  # returns single matching filename
308
- def self.find_single_edit_list_matching use_all = false
309
- matching = all_edl_files_parsed(use_all).map{|filename, parsed|
293
+ # requires a block
294
+ def self.find_single_edit_list_matching use_all_not_just_dvd_dir = false, return_first_if_there_are_several = false
295
+ matching = all_edl_files_parsed(use_all_not_just_dvd_dir).map{|filename, parsed|
310
296
  yield(parsed) ? filename : nil
311
297
  }.compact
312
298
  if matching.length == 1
313
299
  file = matching[0]
314
- p "selecting the one only matching EDL: #{file}"
315
300
  file
316
301
  elsif matching.length > 1
317
- p "found multiple matches for media? #{matching.inspect}"
318
- nil
302
+ p "found multiple matches for media? #{matching.inspect}"
303
+ if return_first_if_there_are_several
304
+ matching[0]
305
+ else
306
+ nil
307
+ end
319
308
  else
320
309
  nil
321
310
  end
322
311
  end
323
312
 
324
- def self.single_edit_list_matches_dvd dvd_id
313
+ def self.single_edit_list_matches_dvd dvd_id, return_first_if_there_are_several = false
325
314
  return nil unless dvd_id
326
- find_single_edit_list_matching {|parsed|
315
+ find_single_edit_list_matching(false, return_first_if_there_are_several) {|parsed|
327
316
  parsed["disk_unique_id"] == dvd_id
328
317
  }
329
318
  end
330
-
319
+
320
+ def self.convert_to_dvd_nav_times combined, start_type, start_mpeg_time, dvd_nav_packet_offsets, time_multiplier
321
+ start_dvdnav_time = dvd_nav_packet_offsets[1] - dvd_nav_packet_offsets[0]
322
+ raise unless start_type == 'dvd_start_offset' # for now :P
323
+ out = []
324
+ add_this_to_all_of_them = start_dvdnav_time - start_mpeg_time
325
+ #[[70.0, 73.0, :blank], [378.0, 379.1, :mute]]
326
+ for start, endy, type in combined
327
+ if time_multiplier == 30
328
+ # ok
329
+ elsif time_multiplier == 29.97
330
+ start = ConvertThirtyFps.from_twenty_nine_nine_seven start
331
+ endy = ConvertThirtyFps.from_twenty_nine_nine_seven endy
332
+ else
333
+ raise time_multiplier
334
+ end
335
+ start += start_dvdnav_time
336
+ endy += start_dvdnav_time
337
+ out << [start, endy, type]
338
+ end
339
+ out
340
+ end
331
341
 
332
342
  end
333
343
 
@@ -345,6 +355,9 @@ if $0 == __FILE__
345
355
  p 'syntax: filename'
346
356
  require 'rubygems'
347
357
  require 'sane'
348
- p EdlParser.parse_file(*ARGV)
358
+ parsed = EdlParser.parse_file(*ARGV)
349
359
  p 'parsed well'
360
+ p parsed
361
+ require 'yaml'
362
+ print YAML.dump parsed
350
363
  end