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.
- data/{README → README.TXT} +35 -14
- data/Rakefile +49 -41
- data/TODO +337 -250
- data/VERSION +1 -1
- data/bin/sensible-cinema +15 -14
- data/bin/sensible-cinema-cli +1 -1
- data/business_ideas.txt +8 -0
- data/change_log_with_feature_list.txt +198 -1
- data/documentation/is_it_legal_to_copy_dvds.txt +44 -30
- data/goc.bat +1 -1
- data/gpl-2.0.txt +339 -0
- data/history_and_related_works_list.txt +37 -33
- data/{cone.png → inventionzy_files/cone.png} +0 -0
- data/legal_draft +23 -0
- data/lib/add_any_bundled_gems_to_load_path.rb +4 -3
- data/lib/check_installed_mac.rb +10 -10
- data/lib/count_down_timer_jruby_swing.rb +4 -4
- data/lib/edl_parser.rb +155 -142
- data/lib/extract/dumpstream.bat +1 -0
- data/lib/extract/get_init.bat +3 -0
- data/lib/extract/pause_early.rb +13 -0
- data/lib/gui/base.rb +707 -0
- data/lib/gui/create-file.rb +244 -0
- data/lib/gui/create.rb +565 -0
- data/lib/gui/dependencies.rb +177 -0
- data/lib/gui/normal.rb +190 -0
- data/lib/gui/{sensible-cinema-upconvert.rb → upconvert.rb} +33 -14
- data/lib/keyboard_input.rb +0 -2
- data/lib/mencoder_wrapper.rb +8 -3
- data/lib/movie_hasher.rb +27 -0
- data/lib/mplayer_edl.rb +1 -0
- data/lib/subtitle_profanity_finder.rb +141 -103
- data/lib/vlc_programmer.rb +1 -1
- data/lib/zoom_player_max_edl.rb +50 -0
- data/{developer_how_to_contribute_to_the_project.txt → notes_for_potential_developers.txt} +18 -11
- data/roadmap_possibilities +12 -0
- data/spec/arse.srt +6 -1
- data/spec/dragon.srt +3 -0
- data/spec/edl_parser.spec.rb +57 -52
- data/spec/mencoder_wrapper.spec.rb +26 -19
- data/spec/mplayer_edl.spec.rb +40 -10
- data/spec/notes +3043 -9
- data/spec/sensible_cinema_gui.spec.rb +8 -3
- data/spec/subtitle_profanity_finder.spec.rb +91 -36
- data/spec/zoom_player_max_edl.spec.rb +29 -0
- data/template_bats/README_DISTRO.TXT +3 -1
- data/template_bats/RUN SENSIBLE CINEMA CLICK HERE WINDOWS.bat +25 -0
- data/template_bats/mac/RUN SENSIBLE CINEMA CLICK HERE.command +2 -1
- data/template_bats/mac/advanced--create or edit sensible cinema edit list files.command +2 -1
- data/template_bats/mac/advanced--run-upconverting-video-player.command +2 -1
- data/template_bats/pc/advanced--create or edit sensible cinema edit list files.bat +2 -0
- data/template_bats/pc/advanced--run-upconverting-video-player.bat +2 -0
- data/todo.inventionzy.txt +69 -2
- data/todo.propaganda +34 -10
- data/todo.upconvert +8 -1
- data/{upconvert_netflix/latest2 → upconvert_from_screen}/go_upscaling.bat +0 -0
- data/{also_see_rogerdpack_youtube_account_and_sourceforge_files_movies_account → upconvert_from_screen/go_upscaling_works} +0 -0
- data/{upconvert_netflix → upconvert_from_screen/old}/latest2/combine_video.avs +0 -0
- data/{upconvert_netflix → upconvert_from_screen/old}/latest2/go_no_upscaling.bat +0 -0
- data/upconvert_from_screen/old/latest2/go_upscaling.bat +12 -0
- data/{upconvert_netflix → upconvert_from_screen/old}/latest2/push2.GRF +0 -0
- data/upconvert_from_screen/old/latest2/push3.grf +0 -0
- data/{upconvert_netflix → upconvert_from_screen/old}/latest2/setup_capture_coords.rb +0 -0
- data/{upconvert_netflix → upconvert_from_screen/old}/latest2/setup_directshow_filter_params.rb +0 -0
- data/{upconvert_netflix → upconvert_from_screen/old}/latest2/upconvert_from_screen_me2.avs +1 -1
- data/{upconvert_netflix → upconvert_from_screen}/old/latest_now_possibly_oudated/push2.GRF +0 -0
- data/{upconvert_netflix → upconvert_from_screen}/old/latest_now_possibly_oudated/upconvert_from_screen_me2.avs +0 -0
- data/{upconvert_netflix → upconvert_from_screen}/old/position_window.png +0 -0
- data/{upconvert_netflix → upconvert_from_screen}/old/push_source_desktop.GRF +0 -0
- data/{upconvert_netflix → upconvert_from_screen/old}/record_screen/record.bat +0 -0
- data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen.avs +0 -0
- data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen_me.avs +0 -0
- data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen_me2.avs +0 -0
- data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen_me_push_source.avs +0 -0
- data/{upconvert_netflix → upconvert_from_screen}/old/uscreen.GRF +0 -0
- data/{upconvert_netflix → upconvert_from_screen}/old/uscreen_me.GRF +0 -0
- data/upconvert_from_screen/push3.grf +0 -0
- data/upconvert_from_screen/upconvert_from_screen_me2.avs +19 -0
- data/vendor/mplayer_patches/apply.bat +12 -0
- data/vendor/{rdp-win32screenshot-0.0.9/RDP_BRANCH_HAS_MASTER_WITH_CORRECT_VERSION_NUMBER → mplayer_patches/configure_from_betterlogic} +0 -0
- data/vendor/mplayer_patches/libdvdnav/2905259c3b45529b3d8dedba572b6e4f67a2d8f4.diff +19 -0
- data/vendor/mplayer_patches/libdvdnav/83f1c9256f500285e46f1e44bcc74ffce90159db.diff +16 -0
- data/vendor/mplayer_patches/libdvdnav/eb91fb74680d30322461a1b9e425918ad4e2b2df.diff +21 -0
- data/vendor/mplayer_patches/libdvdnav/jump_to_time.diff +654 -0
- data/vendor/mplayer_patches/libdvdnav/non_strict.diff +13 -0
- data/vendor/mplayer_patches/mplayer_edl.diff +354 -0
- data/vendor/mplayer_patches/port_dir/PortIndex.quick +2 -0
- data/vendor/mplayer_patches/port_dir/how_to +13 -0
- data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/Portfile +300 -0
- data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/files/configure.x11.patch +20 -0
- data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/files/llvm-gcc-workaround.patch +11 -0
- data/vendor/mplayer_patches/port_dir/multimedia/rdp-projects/Portfile +43 -0
- data/vendor/{rdp-win32screenshot-0.0.9/RDP_VERSION_IS_IN_RDP_BRANCH → mplayer_patches/updated_lib_too} +0 -0
- data/vendor/{readme.txt → readme.txt.setpriority} +0 -0
- data/www/content_editor.html +28 -28
- data/www/index.html +6 -1
- data/www/upconverting_movie_player.html +13 -3
- data/www/youtube_edl/.htaccess +44 -0
- data/{inventionzy_files/control_youtube.html → www/youtube_edl/control_youtube.rhtml} +39 -33
- data/www/youtube_edl/dispatch.fcgi +25 -0
- data/www/youtube_edl/render_edited.rb +25 -0
- data/{inventionzy_files/serve.rb → www/youtube_edl/server_this_dir.rb} +0 -0
- data/www/youtube_edl/todo +23 -0
- data/www/zoomplayer_max.png +0 -0
- data/zamples/edit_decision_lists/dvds/Harry Potter 2 chamber of secrets.txt +10 -5
- data/zamples/edit_decision_lists/dvds/aladdin.txt +30 -0
- data/zamples/edit_decision_lists/dvds/bambi.txt +1 -1
- data/zamples/edit_decision_lists/dvds/big_buck_bunny_dvd.txt +2 -0
- data/zamples/edit_decision_lists/dvds/bobs_big_plan.txt +2 -2
- data/zamples/edit_decision_lists/dvds/cars_2.txt +26 -0
- data/zamples/edit_decision_lists/dvds/cars_disney.txt +1 -1
- data/zamples/edit_decision_lists/dvds/condor_man_widescreen.txt +22 -0
- data/zamples/edit_decision_lists/dvds/court_jester.txt +10 -13
- data/zamples/edit_decision_lists/dvds/edls_being_edited/making_marriage_work.txt +15 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/national_treasure.txt +23 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/ratatouille.txt +35 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/the_explorers.txt +49 -0
- data/zamples/edit_decision_lists/dvds/finding_neverland.txt +32 -0
- data/zamples/edit_decision_lists/dvds/flight_of_the_navigator.txt +22 -16
- data/zamples/edit_decision_lists/dvds/harry_potter_3_prisoner_of_azkaban.txt +21 -4
- data/zamples/edit_decision_lists/dvds/hitchhiker's_guide_to_the_galaxy.txt +1 -1
- data/zamples/edit_decision_lists/dvds/{edls_being_edited/king_of_kings.txt → king_of_kings.txt} +5 -5
- data/zamples/edit_decision_lists/dvds/nanny_mcphee.txt +31 -0
- data/zamples/edit_decision_lists/dvds/pack_jackson_wedding_2007-03-03.txt +9 -2
- data/zamples/edit_decision_lists/dvds/remember_the_titans.txt +35 -0
- data/zamples/edit_decision_lists/dvds/sintel_open_source_blender_ntsc_dvd.txt +8 -4
- data/zamples/edit_decision_lists/dvds/speed_racer.txt +1 -1
- data/zamples/edit_decision_lists/dvds/tangled.txt +21 -0
- data/zamples/edit_decision_lists/dvds/tron_legacy.txt +4 -1
- data/zamples/edit_decision_lists/files/conference_music_video.txt +10 -0
- data/zamples/edit_decision_lists/notes_on_movies_without_edls_yet/tron.txt +10 -0
- data/zamples/edit_decision_lists/old_not_yet_updated/example_edit_decision_list.txt +1 -1
- metadata +139 -117
- data/conclusions +0 -6
- data/documentation/how_to_create_your_own_delete_lists.txt +0 -69
- data/lib/gui/sensible-cinema-base.rb +0 -620
- data/lib/gui/sensible-cinema-create.rb +0 -331
- data/lib/gui/sensible-cinema-dependencies.rb +0 -28
- data/lib/gui/sensible-cinema-normal.rb +0 -351
- data/lib/gui/sensible-cinema-side-by-side.rb +0 -27
- data/lib/shutdown_kill.rb +0 -32
- data/lib/storage.rb +0 -105
- data/ocr.todo_if_need_speed +0 -6
- data/upconvert_netflix/record_screen/recording/1.png +0 -0
- data/upconvert_netflix/record_screen/recording/10.png +0 -0
- data/upconvert_netflix/record_screen/recording/2.png +0 -0
- data/upconvert_netflix/record_screen/recording/3.png +0 -0
- data/upconvert_netflix/record_screen/recording/4.png +0 -0
- data/upconvert_netflix/record_screen/recording/5.png +0 -0
- data/upconvert_netflix/record_screen/recording/6.png +0 -0
- data/upconvert_netflix/record_screen/recording/7.png +0 -0
- data/upconvert_netflix/record_screen/recording/8.png +0 -0
- data/upconvert_netflix/record_screen/recording/9.png +0 -0
- data/upconvert_netflix/record_screen/recording/d.png +0 -0
- data/vendor/monkey.png +0 -0
- data/vendor/rdp-win32screenshot-0.0.9/.document +0 -5
- data/vendor/rdp-win32screenshot-0.0.9/History.rdoc +0 -53
- data/vendor/rdp-win32screenshot-0.0.9/LICENSE +0 -20
- data/vendor/rdp-win32screenshot-0.0.9/README.rdoc +0 -95
- data/vendor/rdp-win32screenshot-0.0.9/Rakefile +0 -63
- data/vendor/rdp-win32screenshot-0.0.9/VERSION +0 -1
- data/vendor/rdp-win32screenshot-0.0.9/enumerated +0 -55576
- data/vendor/rdp-win32screenshot-0.0.9/lib/aero_offscreen_srccopy_captureblt_doesnt_have_everything.bmp.gz +0 -0
- data/vendor/rdp-win32screenshot-0.0.9/lib/enumerate.rb +0 -6
- data/vendor/rdp-win32screenshot-0.0.9/lib/firefox.bmp +0 -0
- data/vendor/rdp-win32screenshot-0.0.9/lib/normal.bmp +0 -0
- data/vendor/rdp-win32screenshot-0.0.9/lib/normal2.bmp +0 -0
- data/vendor/rdp-win32screenshot-0.0.9/lib/notes +0 -5
- data/vendor/rdp-win32screenshot-0.0.9/lib/snapshot.rb +0 -10
- data/vendor/rdp-win32screenshot-0.0.9/lib/srccopy.bmp +0 -0
- data/vendor/rdp-win32screenshot-0.0.9/lib/srccopyplus.bmp +0 -0
- data/vendor/rdp-win32screenshot-0.0.9/lib/srccopyplusdirectx.bmp +0 -0
- data/vendor/rdp-win32screenshot-0.0.9/lib/vc.bmp +0 -0
- data/vendor/rdp-win32screenshot-0.0.9/lib/win32/screenshot.rb +0 -95
- data/vendor/rdp-win32screenshot-0.0.9/lib/win32/screenshot/bitmap_maker.rb +0 -200
- data/vendor/rdp-win32screenshot-0.0.9/lib/win32/util.rb +0 -93
- data/vendor/rdp-win32screenshot-0.0.9/spec/spec.opts +0 -1
- data/vendor/rdp-win32screenshot-0.0.9/spec/spec_helper.rb +0 -85
- data/vendor/rdp-win32screenshot-0.0.9/spec/win32_screenshot_spec.rb +0 -194
- data/vendor/rdp-win32screenshot-0.0.9/spec/win32_screenshot_util_spec.rb +0 -75
- data/vendor/rdp-win32screenshot-0.0.9/win32screenshot.gemspec +0 -69
- data/vendor/tsmuxer_1.10.6/licence.txt +0 -42
- data/zamples/edit_decision_lists/dvds/making_marriage_work.txt +0 -15
- data/zamples/edit_decision_lists/notes/tron.txt +0 -4
- 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
|
5
|
-
|
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
|
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.
|
10
|
-
|
11
|
-
|
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
|
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
|
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
|
20
|
-
|
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
|
27
|
-
|
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
|
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,
|
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
|
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
|
73
|
-
like
|
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
|
-
|
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'
|
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
|
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
|
101
|
-
"
|
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
|
data/legal_draft
ADDED
@@ -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
|
-
|
21
|
-
|
22
|
-
|
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
|
data/lib/check_installed_mac.rb
CHANGED
@@ -2,8 +2,11 @@ require 'rubygems'
|
|
2
2
|
require 'os'
|
3
3
|
success = true
|
4
4
|
|
5
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
26
|
-
return false
|
26
|
+
return true
|
27
27
|
end
|
28
28
|
|
29
|
-
# check for the others
|
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
|
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
|
-
|
12
|
-
|
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
|
data/lib/edl_parser.rb
CHANGED
@@ -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/
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
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*->\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
|
-
|
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
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
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
|
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 =
|
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
|
208
|
-
|
209
|
-
|
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|
|
214
|
-
blanks = blanks.map{|k, v|
|
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
|
231
|
+
# detect any weirdness...
|
218
232
|
previous = nil
|
219
|
-
combined.
|
220
|
-
s,e,
|
221
|
-
if e < s
|
222
|
-
raise SyntaxError.new("detected an end before a start: #{e} < #{s}")
|
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,
|
226
|
-
if (s <
|
227
|
-
raise SyntaxError.new("detected an overlap #{
|
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
|
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
|
-
|
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
|
-
|
309
|
-
|
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
|
-
|
318
|
-
|
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
|
-
|
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
|