content-editing-movie-player 0.38.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitmodules +3 -0
- data/.rvmrc +1 -0
- data/LICENSE.TXT +20 -0
- data/README.TXT +225 -0
- data/Rakefile +206 -0
- data/TODO +740 -0
- data/VERSION +1 -0
- data/_DO_NOT_RUN_IT_FROM_HERE_DOWNLOAD_THE_RELEASE_ZIP_FROM_SOURCEFORGE_INSTEAD +0 -0
- data/bin/sensible-cinema +60 -0
- data/bin/sensible-cinema-cli +161 -0
- data/business_ideas.txt +21 -0
- data/change_log_with_feature_list.txt +952 -0
- data/documentation/DOCUMENTATION_README.TXT +44 -0
- data/documentation/how_to_get_files_from_dvd.txt +30 -0
- data/documentation/is_it_legal_to_copy_dvds.txt +97 -0
- data/documentation/troubleshooting.txt +30 -0
- data/documentation/upconversion.txt +4 -0
- data/experimental_online_player_ocr_readme.txt +45 -0
- data/go +1 -0
- data/go.bat +2 -0
- data/go.sh +1 -0
- data/go_ocr_tracker.bat +1 -0
- data/goc +1 -0
- data/goc.bat +1 -0
- data/goc.sh +1 -0
- data/gpl-2.0.txt +339 -0
- data/gplv3.txt +219 -0
- data/history_and_related_works_list.txt +108 -0
- data/inventionzy_files/cone.png +0 -0
- data/inventionzy_files/md5s.txt +53 -0
- data/inventionzy_files/play_with_inserted_scene.bat +8 -0
- data/inventionzy_files/play_with_overlay.bat +24 -0
- data/inventionzy_files/transcript_mute_vlc.txt +117 -0
- data/legal_draft +23 -0
- data/lib/add_any_bundled_gems_to_load_path.rb +32 -0
- data/lib/auto_window_finder.rb +41 -0
- data/lib/blanker.rb +104 -0
- data/lib/check_installed_mac.rb +34 -0
- data/lib/convert_thirty_fps.rb +20 -0
- data/lib/edl_parser.rb +387 -0
- data/lib/eight_three.rb +28 -0
- 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/fake_blanker.rb +35 -0
- data/lib/frame_accurate.rb +3 -0
- data/lib/gui/base.rb +748 -0
- data/lib/gui/create-file.rb +24 -0
- data/lib/gui/create.rb +581 -0
- data/lib/gui/dependencies.rb +219 -0
- data/lib/gui/normal.rb +123 -0
- data/lib/gui/upconvert.rb +284 -0
- data/lib/keyboard_input.rb +60 -0
- data/lib/media_info_parser.rb +27 -0
- data/lib/mouse_forever.rb +19 -0
- data/lib/movie_hasher.rb +27 -0
- data/lib/mplayer_edl.rb +42 -0
- data/lib/muter.rb +87 -0
- data/lib/ocr.rb +125 -0
- data/lib/ocr_seed/netflix_b9.bmp +0 -0
- data/lib/overlayer.rb +373 -0
- data/lib/screen_tracker.rb +269 -0
- data/lib/subtitle_profanity_finder.rb +294 -0
- data/lib/vlc_programmer.rb +112 -0
- data/lib/zoom_player_max_edl.rb +50 -0
- data/never_do +40 -0
- data/notes_for_potential_developers.txt +46 -0
- data/preamble +17 -0
- data/roadmap_possibilities +12 -0
- data/spec/arse.srt +41 -0
- data/spec/auto_window_finder.spec.rb +65 -0
- data/spec/bad_beginning.srt +3778 -0
- data/spec/blanker.spec.rb +60 -0
- data/spec/common.rb +81 -0
- data/spec/convert_image.rb +25 -0
- data/spec/deity_end.srt +11 -0
- data/spec/dragon.srt +34 -0
- data/spec/edl_parser.spec.rb +270 -0
- data/spec/frame_accurate.spec.rb +71 -0
- data/spec/keyboard_input.spec.rb +73 -0
- data/spec/media_info_parser.spec.rb +29 -0
- data/spec/mplayer_edl.spec.rb +100 -0
- data/spec/muter.spec.rb +50 -0
- data/spec/notes +4996 -0
- data/spec/ocr.spec.rb +119 -0
- data/spec/overlayer.spec.rb +440 -0
- data/spec/screen_tracker.spec.rb +318 -0
- data/spec/sensible_cinema_gui.spec.rb +452 -0
- data/spec/subtitle_profanity_finder.spec.rb +224 -0
- data/spec/test_yaml.yml +4 -0
- data/spec/tsmuxer.output +33 -0
- data/spec/vlc_programmer.spec.rb +124 -0
- data/spec/youtube_edl.spec.rb +28 -0
- data/spec/zoom_player_max_edl.spec.rb +29 -0
- data/template_bats/README_DISTRO.TXT +8 -0
- data/template_bats/RUN SENSIBLE CINEMA CLICK HERE WINDOWS.bat +25 -0
- data/template_bats/_DO_NOT_RUN_IT_FROM_HERE_DOWNLOAD_THE_RELEASE_ZIP_FROM_SOURCEFORGE_INSTEAD +0 -0
- data/template_bats/mac/RUN SENSIBLE CINEMA CLICK HERE.command +5 -0
- data/template_bats/mac/advanced--create or edit sensible cinema edit list files.command +3 -0
- data/template_bats/mac/advanced--run-upconverting-video-player.command +3 -0
- 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.build_library.txt +11 -0
- data/todo.inventionzy.txt +162 -0
- data/todo.open_edl_list_org.txt +169 -0
- data/todo.propaganda +107 -0
- data/todo.subtitle +17 -0
- data/todo.upconvert +53 -0
- data/upconvert.bat +1 -0
- data/upconvert_from_screen/go_upscaling.bat +12 -0
- data/upconvert_from_screen/go_upscaling_works +0 -0
- data/upconvert_from_screen/old/latest2/combine_video.avs +23 -0
- data/upconvert_from_screen/old/latest2/go_no_upscaling.bat +1 -0
- data/upconvert_from_screen/old/latest2/go_upscaling.bat +12 -0
- data/upconvert_from_screen/old/latest2/push2.GRF +0 -0
- data/upconvert_from_screen/old/latest2/push3.grf +0 -0
- data/upconvert_from_screen/old/latest2/setup_capture_coords.rb +27 -0
- data/upconvert_from_screen/old/latest2/setup_directshow_filter_params.rb +29 -0
- data/upconvert_from_screen/old/latest2/upconvert_from_screen_me2.avs +19 -0
- data/upconvert_from_screen/old/latest_now_possibly_oudated/push2.GRF +0 -0
- data/upconvert_from_screen/old/latest_now_possibly_oudated/upconvert_from_screen_me2.avs +18 -0
- data/upconvert_from_screen/old/position_window.png +0 -0
- data/upconvert_from_screen/old/push_source_desktop.GRF +0 -0
- data/upconvert_from_screen/old/record_screen/record.bat +2 -0
- data/upconvert_from_screen/old/upconvert_from_screen.avs +21 -0
- data/upconvert_from_screen/old/upconvert_from_screen_me.avs +21 -0
- data/upconvert_from_screen/old/upconvert_from_screen_me2.avs +3 -0
- data/upconvert_from_screen/old/upconvert_from_screen_me_push_source.avs +3 -0
- data/upconvert_from_screen/old/uscreen.GRF +0 -0
- data/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/movie-content-editor-read-only/.metadata/.lock +0 -0
- data/vendor/movie-content-editor-read-only/.metadata/.mylyn/.tasks.xml.zip +0 -0
- data/vendor/movie-content-editor-read-only/.metadata/.mylyn/repositories.xml.zip +0 -0
- data/vendor/movie-content-editor-read-only/.metadata/.mylyn/tasks.xml.zip +0 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version +1 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index +0 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version +1 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.resources/.root/2.tree +0 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources +0 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs +3 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs +14 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs +3 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs +5 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs +3 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache +0 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat +0 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml +2 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml +2 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml +10 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml +11 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.ui.intro/dialog_settings.xml +4 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml +10 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml +232 -0
- data/vendor/movie-content-editor-read-only/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml +4 -0
- data/vendor/movie-content-editor-read-only/.metadata/version.ini +1 -0
- data/vendor/movie-content-editor-read-only/.project +17 -0
- data/vendor/movie-content-editor-read-only/.pydevproject +11 -0
- data/vendor/movie-content-editor-read-only/.settings/org.eclipse.core.resources.prefs +6 -0
- data/vendor/movie-content-editor-read-only/SubIt.py +171 -0
- data/vendor/movie-content-editor-read-only/VLCMacVideo.py +257 -0
- data/vendor/movie-content-editor-read-only/VideoMac.ui +102 -0
- data/vendor/movie-content-editor-read-only/badwords.txt +4 -0
- data/vendor/movie-content-editor-read-only/blank.srt +4 -0
- data/vendor/movie-content-editor-read-only/edit.py +197 -0
- data/vendor/movie-content-editor-read-only/mergeCommands.py +73 -0
- data/vendor/movie-content-editor-read-only/mute.txt +5 -0
- data/vendor/movie-content-editor-read-only/panda.srt +4235 -0
- data/vendor/movie-content-editor-read-only/panda_custom.txt +3 -0
- data/vendor/movie-content-editor-read-only/panda_edit.srt +4235 -0
- data/vendor/movie-content-editor-read-only/subtitle.py +90 -0
- data/vendor/movie-content-editor-read-only/vlc.py +5579 -0
- data/vendor/movie-content-editor-read-only/vlcwidget.py +154 -0
- data/vendor/mplayer_patches/how_to_doze.bat +6 -0
- data/vendor/mplayer_patches/port_dir/PortIndex.quick +2 -0
- data/vendor/mplayer_patches/port_dir/how_to +20 -0
- data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/Portfile +285 -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/mplayer_patches/port_dir_is_for_mac +0 -0
- data/www/content_editor.html +92 -0
- data/www/index.html +47 -0
- data/www/upconverting_movie_player.html +62 -0
- data/www/video reel.jpg +0 -0
- data/www/youtube_edl/.htaccess +44 -0
- data/www/youtube_edl/control_youtube.rhtml +141 -0
- data/www/youtube_edl/dispatch.fcgi +25 -0
- data/www/youtube_edl/render_edited.rb +25 -0
- data/www/youtube_edl/server_this_dir.rb +6 -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 +22 -0
- data/zamples/edit_decision_lists/dvds/aa_example_delete_list_that_has_no_cuts_in_it.txt +10 -0
- data/zamples/edit_decision_lists/dvds/aladdin.txt +30 -0
- data/zamples/edit_decision_lists/dvds/bambi.txt +17 -0
- data/zamples/edit_decision_lists/dvds/big_buck_bunny_dvd.txt +23 -0
- data/zamples/edit_decision_lists/dvds/bob the builder pets in a pickle.txt +10 -0
- data/zamples/edit_decision_lists/dvds/bobs_big_plan.txt +10 -0
- data/zamples/edit_decision_lists/dvds/cars_2.txt +26 -0
- data/zamples/edit_decision_lists/dvds/cars_disney.txt +40 -0
- data/zamples/edit_decision_lists/dvds/condor_man_widescreen.txt +22 -0
- data/zamples/edit_decision_lists/dvds/cool runnings.txt +53 -0
- data/zamples/edit_decision_lists/dvds/court_jester.txt +24 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/amazing_grace.txt +49 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/father_goose.txt +41 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/harry_potter_and_the_goblet_of_fire.txt +45 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/hugo.txt +31 -0
- 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 +26 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/percy_jackson_lightening_thief.txt +40 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/percy_jackson_lightening_thief_mute_scary.txt +23 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/prince_of_egypt.txt +28 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/puss_in_boots.txt +33 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/ratatouille.txt +35 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/rio.txt +24 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/test_delete_list_for_experimenting_with.txt +10 -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 +40 -0
- data/zamples/edit_decision_lists/dvds/happiest baby on the block.txt +9 -0
- data/zamples/edit_decision_lists/dvds/harry_potter_3_prisoner_of_azkaban.txt +37 -0
- data/zamples/edit_decision_lists/dvds/hitchhiker's_guide_to_the_galaxy.txt +32 -0
- data/zamples/edit_decision_lists/dvds/how_to_train_your_dragon.txt +25 -0
- data/zamples/edit_decision_lists/dvds/if_a_man_answers.txt +43 -0
- data/zamples/edit_decision_lists/dvds/innerspace.txt +77 -0
- data/zamples/edit_decision_lists/dvds/iq.txt +32 -0
- data/zamples/edit_decision_lists/dvds/king_of_kings.txt +28 -0
- data/zamples/edit_decision_lists/dvds/kung_fu_panda_1.txt +17 -0
- data/zamples/edit_decision_lists/dvds/legend_of_the_guardians_the_owls_of_gahoole.txt +18 -0
- data/zamples/edit_decision_lists/dvds/monsters_vs_aliens.txt +41 -0
- data/zamples/edit_decision_lists/dvds/muppet_treasure_island.txt +21 -0
- data/zamples/edit_decision_lists/dvds/nanny_mcphee.txt +31 -0
- data/zamples/edit_decision_lists/dvds/narnia_voyage_of_the_dawn_treader.txt +16 -0
- data/zamples/edit_decision_lists/dvds/pack_jackson_wedding_2007-03-03.txt +31 -0
- data/zamples/edit_decision_lists/dvds/peter_pan.txt +29 -0
- 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 +22 -0
- data/zamples/edit_decision_lists/dvds/snow_white_and_the_7_dwarfs_1937.txt +19 -0
- data/zamples/edit_decision_lists/dvds/speed_racer.txt +47 -0
- data/zamples/edit_decision_lists/dvds/tangled.txt +21 -0
- data/zamples/edit_decision_lists/dvds/tron_legacy.txt +29 -0
- data/zamples/edit_decision_lists/dvds/turn_around_alma_younger.txt +17 -0
- data/zamples/edit_decision_lists/files/conference_music_video.txt +10 -0
- data/zamples/edit_decision_lists/netflix_instant/avatar-last-air-bender-movie.txt +13 -0
- data/zamples/edit_decision_lists/netflix_instant/avatar-last-airbender-series.txt +1 -0
- data/zamples/edit_decision_lists/netflix_instant/greatest_story_ever_told_netflix.txt +10 -0
- data/zamples/edit_decision_lists/netflix_instant/wrinkle-in-time.txt +23 -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/dvds/White Christmas.txt +15 -0
- data/zamples/edit_decision_lists/old_not_yet_updated/dvds/all_dogs_go_to_heaven.txt +9 -0
- data/zamples/edit_decision_lists/old_not_yet_updated/dvds/cars_disney.txt +24 -0
- data/zamples/edit_decision_lists/old_not_yet_updated/dvds/happy_feet.txt +12 -0
- data/zamples/edit_decision_lists/old_not_yet_updated/dvds/labyrinth.txt +17 -0
- data/zamples/edit_decision_lists/old_not_yet_updated/dvds/star_trek_generations_hulu.txt +8 -0
- data/zamples/edit_decision_lists/old_not_yet_updated/example_edit_decision_list.txt +14 -0
- data/zamples/edit_decision_lists/old_not_yet_updated/youtube/gummy_bear_song_youtube.txt +9 -0
- data/zamples/edit_decision_lists/youtube/demo_mutes.txt +12 -0
- data/zamples/edit_decision_lists/youtube/nuki_song_youtube.txt +14 -0
- data/zamples/edit_decision_lists/youtube/nuki_song_youtube_pointer.txt +3 -0
- data/zamples/players/how_to_create_more_players.txt +24 -0
- data/zamples/players/hulu/total_length_over_an_hour.txt +25 -0
- data/zamples/players/netflix/netflix_firefox_non_maximized.txt +25 -0
- data/zamples/players/vlc/full_screened_total_length_over_an_hour.txt +27 -0
- data/zamples/players/vlc/windowed_total_length_over_an_hour.txt +26 -0
- data/zamples/players/vlc/windowed_total_length_under_an_hour.txt +22 -0
- data/zamples/players/youtube/full_screened_1024x768.txt +20 -0
- data/zamples/players/youtube/full_screened_1152x864.txt +20 -0
- data/zamples/players/youtube/full_screened_1680x1050.txt +20 -0
- data/zamples/players/youtube/normal_in_youtube.com.chrome.txt +23 -0
- data/zamples/players/youtube/note_these_assume_less_than_10_minutes_length.txt +2 -0
- metadata +483 -0
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.
|
@@ -0,0 +1,32 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
|
19
|
+
def add_any_bundled_gems_to_load_path
|
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
|
24
|
+
$: << lib_dir
|
25
|
+
}
|
26
|
+
else
|
27
|
+
require 'rubygems'
|
28
|
+
# they'll need imagemagick installed, as well, currently
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
add_any_bundled_gems_to_load_path
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rautomation'
|
2
|
+
require_relative 'edl_parser'
|
3
|
+
|
4
|
+
class AutoWindowFinder
|
5
|
+
|
6
|
+
# when they select a file, it contains a...url say...
|
7
|
+
# so look for that url, with "this" child window class [?]
|
8
|
+
# so basically, if a browser window is "open" to such and such a url
|
9
|
+
# and it is mentioned in a file
|
10
|
+
# it should find it
|
11
|
+
|
12
|
+
def self.search_for_single_url_match regexp = /Chrome/
|
13
|
+
EdlParser.find_single_edit_list_matching(true) {|parsed|
|
14
|
+
if url = parsed["url"]
|
15
|
+
window = RAutomation::Window.new(:title => regexp)
|
16
|
+
if window.exist?
|
17
|
+
if window.text =~ Regexp.new(Regexp.escape url.gsub(/http(s|):\/\//, ""))
|
18
|
+
p 'got match' + url
|
19
|
+
true
|
20
|
+
else
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.search_for_player_and_url_match player_root_dir
|
29
|
+
for filename in Dir[player_root_dir + '/*/*.txt']
|
30
|
+
settings = YAML.load_file filename
|
31
|
+
if regex = settings["window_title"] # assume regex :)
|
32
|
+
p 'searching for player regex', regex
|
33
|
+
if search_for_single_url_match regex # applies the regex X url
|
34
|
+
return filename
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/blanker.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
|
19
|
+
if RUBY_PLATFORM !~ /java/
|
20
|
+
require_relative 'fake_blanker'
|
21
|
+
else
|
22
|
+
|
23
|
+
require 'java'
|
24
|
+
|
25
|
+
class Blanker
|
26
|
+
JFrame = javax.swing.JFrame
|
27
|
+
JLabel = javax.swing.JLabel
|
28
|
+
|
29
|
+
def self.startup
|
30
|
+
@fr = JFrame.new("Sensible Cinema blanker-outer overlay window")
|
31
|
+
@fr.default_close_operation = JFrame::EXIT_ON_CLOSE
|
32
|
+
@fr.set_size(2000, 2000) # ltodo better size ?
|
33
|
+
cp = @fr.getContentPane
|
34
|
+
cp.setBackground(java.awt.Color.black);
|
35
|
+
|
36
|
+
@label = JLabel.new
|
37
|
+
@label.set_text 'blanked'
|
38
|
+
@fr.add(@label)
|
39
|
+
@label.setForeground(java.awt.Color.white);
|
40
|
+
@label.repaint
|
41
|
+
@label.revalidate
|
42
|
+
|
43
|
+
@fr.set_resizable(false)
|
44
|
+
@fr.set_visible(true) # have to do this once, to ever see the thing
|
45
|
+
# lodo does this really speed things up to pre-create it? that icon is a bit ugly in the taskbar...
|
46
|
+
@fr.repaint
|
47
|
+
@fr.set_visible(false) # hide it to start
|
48
|
+
end
|
49
|
+
|
50
|
+
@@use_mouse = false
|
51
|
+
@@use_foreground_window_minimize = false
|
52
|
+
if @@use_foreground_window_minimize
|
53
|
+
require 'win32/screenshot'
|
54
|
+
SW_MINIMIZE = 6
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.minimize_hwnd hwnd
|
58
|
+
Win32::Screenshot::BitmapMaker.show_window(hwnd, SW_MINIMIZE)
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.restore_hwnd hwnd
|
62
|
+
Win32::Screenshot::BitmapMaker.restore(hwnd)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.blank_full_screen! seconds
|
66
|
+
|
67
|
+
if @@use_mouse
|
68
|
+
Mouse.single_click_left_mouse_button
|
69
|
+
elsif @@use_foreground_window_minimize
|
70
|
+
@foreground_hwnd ||= Win32::Screenshot::BitmapMaker.foreground_window
|
71
|
+
minimize_hwnd @foreground_hwnd
|
72
|
+
else
|
73
|
+
# somewhat hacky work around for doze: http://www.experts-exchange.com/Programming/Languages/Java/Q_22977145.html
|
74
|
+
@fr.setAlwaysOnTop(false)
|
75
|
+
@fr.setAlwaysOnTop(true)
|
76
|
+
@fr.set_location(0,0)
|
77
|
+
@fr.repaint # early paint, just in case that helps it pop up faster :)
|
78
|
+
if seconds
|
79
|
+
@label.set_text " #{seconds} s"
|
80
|
+
else
|
81
|
+
@label.set_text " Blank section"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.unblank_full_screen!
|
87
|
+
if @@use_mouse
|
88
|
+
Mouse.single_click_left_mouse_button
|
89
|
+
elsif @@use_foreground_window_minimize
|
90
|
+
restore_hwnd @foreground_hwnd
|
91
|
+
else
|
92
|
+
# just move it off screen...lodo
|
93
|
+
@fr.set_location(-2100, -2100)
|
94
|
+
@fr.repaint 0
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.shutdown
|
99
|
+
@fr.dispose
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'os'
|
3
|
+
success = true
|
4
|
+
|
5
|
+
ENV['PATH'] = '/opt/rdp_project_local/bin/:' + ENV['PATH'] # macports' bin in first
|
6
|
+
|
7
|
+
module CheckInstalledMac
|
8
|
+
|
9
|
+
# should output an error message...
|
10
|
+
def self.check_for_installed name
|
11
|
+
# check for these with generic "does it run"
|
12
|
+
|
13
|
+
command = {"gocr" => "gocr --help", "convert" => "convert --help", "ffmpeg" => "ffmpeg -version", "mplayer" => "mplayer"}[name]
|
14
|
+
|
15
|
+
raise 'unknown ' + name unless command # sanity check
|
16
|
+
|
17
|
+
unless system("/opt/rdp_project_local/bin/#{command} 1>/dev/null 2>&1")
|
18
|
+
name = 'ImageMagick' if name == 'convert' # special case...
|
19
|
+
puts 'lacking dependency! Please install ' + name + ' by installing from the mac dependencies link from the website first'
|
20
|
+
false
|
21
|
+
else
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if $0 == __FILE__
|
29
|
+
for name in ['gocr', 'convert', 'mplayer', 'ffmpeg'] do
|
30
|
+
if CheckInstalledMac.check_for_installed name
|
31
|
+
puts 'has dep:' + name
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ConvertThirtyFps
|
2
|
+
|
3
|
+
def self.from_thirty seconds_float
|
4
|
+
twentyNinePointNineSeven = 30000/1001.0 # 29.97
|
5
|
+
seconds_float * 30/twentyNinePointNineSeven
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.from_twenty_nine_nine_seven seconds_float
|
9
|
+
twentyNinePointNineSeven = 30000/1001.0
|
10
|
+
seconds_float * twentyNinePointNineSeven/30
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
if $0 == __FILE__
|
16
|
+
p 'syntax: second to convert '
|
17
|
+
seconds = eval(ARGV[0] || "1000").to_f
|
18
|
+
p 'converted value from 30 to 29.97 is', ConvertThirtyFps.from_thirty(seconds) # should be bigger...
|
19
|
+
p 'converted value from 29.97 to 30 is', ConvertThirtyFps.from_twenty_nine_nine_seven(seconds)
|
20
|
+
end
|
data/lib/edl_parser.rb
ADDED
@@ -0,0 +1,387 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
|
19
|
+
require 'sane'
|
20
|
+
require_relative 'convert_thirty_fps'
|
21
|
+
|
22
|
+
class EdlParser
|
23
|
+
|
24
|
+
def self.on_any_file_changed_single_cached_thread &this_block
|
25
|
+
raise unless this_block
|
26
|
+
get_files_hash = proc {
|
27
|
+
glob = EDL_DIR + '/../**/*'
|
28
|
+
Dir[glob].map{|f|
|
29
|
+
[f, File.mtime(f)]
|
30
|
+
}.sort
|
31
|
+
}
|
32
|
+
old_value = get_files_hash.call
|
33
|
+
@@checking_thread ||= Thread.new {
|
34
|
+
loop {
|
35
|
+
current_value = get_files_hash.call
|
36
|
+
if current_value != old_value
|
37
|
+
print 'detected some file was changed! Re-parsing to update...'
|
38
|
+
old_value = current_value
|
39
|
+
this_block.call
|
40
|
+
puts 'done.'
|
41
|
+
end
|
42
|
+
sleep 2 # 0.02 for size 70, so...hopefully this is ok...
|
43
|
+
}
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
# this one is 1:01:02.0 => 36692.0
|
48
|
+
# its reverse is this: translate_time_to_human_readable
|
49
|
+
def self.translate_string_to_seconds s
|
50
|
+
# might actually already be a float, or int, depending on the yaml
|
51
|
+
# int for 8 => 9 and also for 1:09 => 1:10
|
52
|
+
if s.is_a? Numeric
|
53
|
+
return s.to_f # easy out.
|
54
|
+
end
|
55
|
+
|
56
|
+
s = s.strip
|
57
|
+
# s is like 1:01:02.0
|
58
|
+
total = 0.0
|
59
|
+
seconds = nil
|
60
|
+
seconds = s.split(":")[-1]
|
61
|
+
raise 'does not look like a timestamp? ' + seconds.inspect unless seconds =~ /^\d+(|[,.]\d+)$/
|
62
|
+
seconds.gsub!(',', '.')
|
63
|
+
total += seconds.to_f
|
64
|
+
minutes = s.split(":")[-2] || "0"
|
65
|
+
total += 60 * minutes.to_i
|
66
|
+
hours = s.split(":")[-3] || "0"
|
67
|
+
total += 60* 60 * hours.to_i
|
68
|
+
total
|
69
|
+
end
|
70
|
+
|
71
|
+
EDL_DIR = File.expand_path(__DIR__ + "/../zamples/edit_decision_lists/dvds")
|
72
|
+
|
73
|
+
if File::ALT_SEPARATOR
|
74
|
+
EDL_DIR.gsub! File::SEPARATOR, File::ALT_SEPARATOR # to_filename...
|
75
|
+
end
|
76
|
+
|
77
|
+
# returns {"mutes" => [["00:00", "00:00", string1, string2, ...], ...], "blank_outs" -> [...], "url" => ...}
|
78
|
+
def self.parse_file filename, expand = true
|
79
|
+
output = parse_string File.read(filename), filename, []
|
80
|
+
# now respect a few options
|
81
|
+
if relative = output["take_from_relative_file"]
|
82
|
+
new_filename = File.dirname(filename) + '/' + relative
|
83
|
+
new_input = parse_file new_filename
|
84
|
+
output.merge! new_input
|
85
|
+
end
|
86
|
+
|
87
|
+
require_relative 'gui/dependencies' # for download methods...
|
88
|
+
|
89
|
+
if expand
|
90
|
+
|
91
|
+
if output["from_url"] # replacement
|
92
|
+
downloaded = SensibleSwing::MainWindow.download_to_string(output["from_url"])
|
93
|
+
output = parse_string downloaded # full replacement
|
94
|
+
end
|
95
|
+
|
96
|
+
if imdb_id = output["imdb_id"]
|
97
|
+
parse_imdb output, imdb_id
|
98
|
+
end
|
99
|
+
end
|
100
|
+
output
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.parse_imdb output, imdb_id
|
104
|
+
require_relative 'convert_thirty_fps'
|
105
|
+
url = "http://www.imdb.com/title/#{imdb_id}/parentalguide"
|
106
|
+
all = SensibleSwing::MainWindow.download_to_string(url)
|
107
|
+
|
108
|
+
header, violence_word, violence_section, profanity_word, profanity_section, alcohol_word, alcohol_section, frightening_word, frightening_section =
|
109
|
+
sections = all.split(/<span>(Violence|Profanity|Alcohol|Frightening)/)
|
110
|
+
header = sections.shift
|
111
|
+
all ={}
|
112
|
+
while(!sections.empty?) # my klugey to_hash method
|
113
|
+
word_type = sections.shift
|
114
|
+
settings = sections.shift
|
115
|
+
assert word_type.in? ['Violence', 'Profanity', 'Alcohol', 'Frightening']
|
116
|
+
all[word_type] = settings
|
117
|
+
end
|
118
|
+
# blank_outs or mutes for each...
|
119
|
+
# TODO make the -> optional
|
120
|
+
split_into_timestamps = /([\d:]+(?:\.\d+|))\W*->\W*([\d:]+(?:\.\d+|))([^\d\n]+)/
|
121
|
+
for type, settings in all
|
122
|
+
settings.scan(split_into_timestamps) do |begin_ts, end_ts, description|
|
123
|
+
puts "parsing from wiki imdb entry violence: #{begin_ts} #{end_ts} #{description} #{type}"
|
124
|
+
start_seconds = translate_string_to_seconds begin_ts
|
125
|
+
end_seconds = translate_string_to_seconds end_ts
|
126
|
+
# convert from 30 to 29.97 fps ... we presume ...
|
127
|
+
start_seconds = ConvertThirtyFps.from_twenty_nine_nine_seven start_seconds
|
128
|
+
start_seconds = ("%.02f" % start_seconds).to_f # round
|
129
|
+
start_seconds = translate_time_to_human_readable start_seconds, true
|
130
|
+
end_seconds = ConvertThirtyFps.from_twenty_nine_nine_seven end_seconds
|
131
|
+
end_seconds = ("%.02f" % end_seconds).to_f # round
|
132
|
+
end_seconds = translate_time_to_human_readable end_seconds, true
|
133
|
+
p end_seconds
|
134
|
+
if type == 'Profanity'
|
135
|
+
output['mutes'] << [start_seconds, end_seconds]
|
136
|
+
else
|
137
|
+
output['blank_outs'] << [start_seconds, end_seconds]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
def self.download full_url, to_here
|
146
|
+
::SwingHelpers::MainWindow.download full_url, to_here
|
147
|
+
end
|
148
|
+
|
149
|
+
# better eye-ball these before letting people run them, eh? TODO
|
150
|
+
# but I couldn't think of any other way to parse the files tho
|
151
|
+
def self.parse_string string, filename = nil, ok_categories_array = []
|
152
|
+
string = '{' + string + "\n}"
|
153
|
+
begin
|
154
|
+
if filename
|
155
|
+
raw = eval(string, binding, filename, 0)
|
156
|
+
else
|
157
|
+
raw = eval string
|
158
|
+
end
|
159
|
+
rescue Exception => e
|
160
|
+
string.strip.lines.to_a[0..-3].each_with_index{|l, idx| # last line doesn't need a comma check
|
161
|
+
orig_line = l
|
162
|
+
l = l.split('#')[0]
|
163
|
+
l = l.strip
|
164
|
+
|
165
|
+
unless l.empty?
|
166
|
+
# todo strip off # comments at the end of lines too...
|
167
|
+
end_char = l[-1..-1]
|
168
|
+
if !end_char.in? ['[', '{'] # these are probably ok...
|
169
|
+
puts "warning: #{File.basename filename} line #{idx} might be bad: (maybe needs comma after?) " + l unless end_char == ','
|
170
|
+
end
|
171
|
+
end
|
172
|
+
}
|
173
|
+
raise SyntaxError.new(e.to_s) # to_s as a workaround for jruby #6353
|
174
|
+
end
|
175
|
+
|
176
|
+
raise SyntaxError.new("maybe missing quotation marks somewhere?" + string) if raw.keys.contain?(nil)
|
177
|
+
|
178
|
+
# mutes and blank_outs need to be special parsed into arrays...
|
179
|
+
mutes = raw["mutes"] || []
|
180
|
+
blanks = raw["blank_outs"] || []
|
181
|
+
raw["mutes"] = convert_to_timestamp_arrays(mutes, ok_categories_array)
|
182
|
+
raw["blank_outs"] = convert_to_timestamp_arrays(blanks, ok_categories_array)
|
183
|
+
raw
|
184
|
+
end
|
185
|
+
|
186
|
+
# converts "blanks" => ["00:00:00", "00", "reason", "01", "01", "02", "02"] into sane arrays, also filters based on category, though not used in production
|
187
|
+
def self.convert_to_timestamp_arrays array, ok_categories_array
|
188
|
+
out = []
|
189
|
+
while(single_element = extract_entry!(array))
|
190
|
+
# assume that it (could be, at least) start_time, end_time, category, number
|
191
|
+
category = single_element[-2]
|
192
|
+
category_number = single_element[-1]
|
193
|
+
include = true
|
194
|
+
if ok_categories_array.index([category, category_number])
|
195
|
+
include = false
|
196
|
+
elsif ok_categories_array.index([category])
|
197
|
+
include = false
|
198
|
+
elsif ok_categories_array.detect{|cat, setting| setting.is_a? Fixnum}
|
199
|
+
for cat, setting in ok_categories_array
|
200
|
+
if cat == category && setting.is_a?(Fixnum)
|
201
|
+
# check for a number for filtering out based on level
|
202
|
+
if category_number.to_i.to_s == category_number
|
203
|
+
as_number = category_number.to_i
|
204
|
+
if as_number < setting
|
205
|
+
include = false
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
out << single_element if include
|
213
|
+
end
|
214
|
+
out
|
215
|
+
end
|
216
|
+
|
217
|
+
# TimeStamp = /(^\d+:\d\d[\d:\.]*$|\d+)/ # this one also allows for 4444 [?] and also weirdness like "don't kill the nice butterfly 2!" ...
|
218
|
+
TimeStamp = /^\s*(\d+:\d\d[\d:\.]*|\d+\.\d+)\s*$/ # allow 00:00:00 00:00:00.0 1222.4 " 2:04 "
|
219
|
+
# disallow's 1905 too but elsewhere in the code
|
220
|
+
|
221
|
+
def self.extract_entry! from_this
|
222
|
+
return nil if from_this.length == 0
|
223
|
+
# two digits, then whatever else you see, that's not a digit...
|
224
|
+
out = from_this.shift(2)
|
225
|
+
out.each{|d|
|
226
|
+
unless d =~ TimeStamp
|
227
|
+
raise SyntaxError.new('non timestamp? ' + d.inspect)
|
228
|
+
end
|
229
|
+
}
|
230
|
+
while(from_this[0] && from_this[0] !~ TimeStamp)
|
231
|
+
raise SyntaxError.new('straight digits not allowed use 1000.0 instead') if from_this[0] =~ /^\d+$/
|
232
|
+
out << from_this.shift
|
233
|
+
end
|
234
|
+
out
|
235
|
+
end
|
236
|
+
|
237
|
+
public
|
238
|
+
|
239
|
+
# called later, from external files
|
240
|
+
# divides up mutes and blanks so that they don't overlap, preferring blanks over mutes
|
241
|
+
# returns it like [[start,end,type], [s,e,t]...] type like either :blank and :mute
|
242
|
+
# [ [70.0, 73.0, :blank], [378.0, 379.1, :mute], ... ]
|
243
|
+
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
|
244
|
+
raise if subtract_this_from_beginnings < 0
|
245
|
+
raise if add_this_to_all_ends < 0
|
246
|
+
raise if subtract_this_from_ends < 0
|
247
|
+
add_this_to_all_ends -= subtract_this_from_ends # now we allow negative :)
|
248
|
+
# raise if splits.size > 0 # just ignore them for now
|
249
|
+
mutes = incoming["mutes"] || {}
|
250
|
+
blanks = incoming["blank_outs"] || {}
|
251
|
+
mutes = mutes.map{|k, v| [k,v,:mute]}
|
252
|
+
blanks = blanks.map{|k, v| [k,v,:blank]}
|
253
|
+
combined = (mutes+blanks).map{|s,e,type| [translate_string_to_seconds(s), translate_string_to_seconds(e), type]}.sort
|
254
|
+
|
255
|
+
# detect any weirdness...
|
256
|
+
previous = nil
|
257
|
+
combined.map!{ |current|
|
258
|
+
s,e,type = current
|
259
|
+
if e < s || !s || !e || !type
|
260
|
+
p caller
|
261
|
+
raise SyntaxError.new("detected an end before a start or other weirdness: #{s} > #{e}")
|
262
|
+
end
|
263
|
+
if previous
|
264
|
+
ps, previous_end, pt = previous
|
265
|
+
if (s < previous_end)
|
266
|
+
raise SyntaxError.new("detected an overlap current #{s} < #{previous_end} of current: #{current.join(' ')} previous: #{previous.join(' ')}")
|
267
|
+
end
|
268
|
+
end
|
269
|
+
previous = current
|
270
|
+
# do the math later to allow for ones that barely hit into each other 1.0 2.0, 2.0 3.0
|
271
|
+
[s-subtract_this_from_beginnings, e+add_this_to_all_ends,type]
|
272
|
+
}
|
273
|
+
combined
|
274
|
+
end
|
275
|
+
|
276
|
+
|
277
|
+
# its reverse: translate_string_to_seconds
|
278
|
+
def self.translate_time_to_human_readable seconds, force_hour_stamp = false
|
279
|
+
# 3600 => "1:00:00"
|
280
|
+
out = ''
|
281
|
+
hours = seconds.to_i / 3600
|
282
|
+
if hours > 0 || force_hour_stamp
|
283
|
+
out << "%d" % hours
|
284
|
+
out << ":"
|
285
|
+
end
|
286
|
+
seconds = seconds - hours*3600
|
287
|
+
minutes = seconds.to_i / 60
|
288
|
+
out << "%02d" % minutes
|
289
|
+
seconds = seconds - minutes * 60
|
290
|
+
out << ":"
|
291
|
+
|
292
|
+
# avoid an ugly .0 at the end
|
293
|
+
# if seconds == seconds.to_i
|
294
|
+
# out << "%02d" % seconds
|
295
|
+
# else
|
296
|
+
out << "%05.2f" % seconds # man that printf syntax is tricky...
|
297
|
+
# end
|
298
|
+
|
299
|
+
end
|
300
|
+
|
301
|
+
def self.all_edl_files_parsed use_all_not_just_dvds
|
302
|
+
dir = EDL_DIR
|
303
|
+
dir += "/.." if use_all_not_just_dvds
|
304
|
+
Dir[dir + '/**/*.txt'].map{|filename|
|
305
|
+
begin
|
306
|
+
parsed = parse_file(filename)
|
307
|
+
[filename, parsed]
|
308
|
+
rescue SyntaxError => e
|
309
|
+
# ignore poorly formed edit lists for the auto choose phase...
|
310
|
+
puts 'warning, unable to parse a file:' + filename + " " + e.to_s
|
311
|
+
nil
|
312
|
+
end
|
313
|
+
}.compact
|
314
|
+
end
|
315
|
+
|
316
|
+
# returns single matching filename
|
317
|
+
# requires a block
|
318
|
+
def self.find_single_edit_list_matching use_all_not_just_dvd_dir = false, return_first_if_there_are_several = false
|
319
|
+
matching = all_edl_files_parsed(use_all_not_just_dvd_dir).map{|filename, parsed|
|
320
|
+
yield(parsed) ? filename : nil
|
321
|
+
}.compact
|
322
|
+
if matching.length == 1
|
323
|
+
file = matching[0]
|
324
|
+
file
|
325
|
+
elsif matching.length > 1
|
326
|
+
p "found multiple matches for media? #{matching.inspect}"
|
327
|
+
if return_first_if_there_are_several
|
328
|
+
matching[0]
|
329
|
+
else
|
330
|
+
nil
|
331
|
+
end
|
332
|
+
else
|
333
|
+
nil
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
def self.single_edit_list_matches_dvd dvd_id, return_first_if_there_are_several = false
|
338
|
+
return nil unless dvd_id
|
339
|
+
find_single_edit_list_matching(false, return_first_if_there_are_several) {|parsed|
|
340
|
+
parsed["disk_unique_id"] == dvd_id
|
341
|
+
}
|
342
|
+
end
|
343
|
+
|
344
|
+
def self.convert_to_dvd_nav_times combined, start_type, start_mpeg_time, dvd_nav_packet_offsets, time_multiplier
|
345
|
+
start_dvdnav_time = dvd_nav_packet_offsets[1] - dvd_nav_packet_offsets[0]
|
346
|
+
raise unless start_type == 'dvd_start_offset' # for now :P
|
347
|
+
out = []
|
348
|
+
add_this_to_all_of_them = start_dvdnav_time - start_mpeg_time
|
349
|
+
#[[70.0, 73.0, :blank], [378.0, 379.1, :mute]]
|
350
|
+
for start, endy, type in combined
|
351
|
+
if time_multiplier == 30
|
352
|
+
# ok
|
353
|
+
elsif time_multiplier == 29.97
|
354
|
+
start = ConvertThirtyFps.from_twenty_nine_nine_seven start
|
355
|
+
endy = ConvertThirtyFps.from_twenty_nine_nine_seven endy
|
356
|
+
else
|
357
|
+
raise time_multiplier
|
358
|
+
end
|
359
|
+
start += start_dvdnav_time
|
360
|
+
endy += start_dvdnav_time
|
361
|
+
out << [start, endy, type]
|
362
|
+
end
|
363
|
+
out
|
364
|
+
end
|
365
|
+
|
366
|
+
end
|
367
|
+
|
368
|
+
# == 1.8.7 1.9 Symbol compat
|
369
|
+
|
370
|
+
class Symbol
|
371
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Symbol.html]
|
372
|
+
def <=>(with)
|
373
|
+
return nil unless with.is_a? Symbol
|
374
|
+
to_s <=> with.to_s
|
375
|
+
end unless method_defined? :"<=>"
|
376
|
+
end
|
377
|
+
|
378
|
+
if $0 == __FILE__
|
379
|
+
p 'syntax: filename'
|
380
|
+
require 'rubygems'
|
381
|
+
require 'sane'
|
382
|
+
parsed = EdlParser.parse_file(*ARGV)
|
383
|
+
p 'parsed well'
|
384
|
+
p parsed
|
385
|
+
require 'yaml'
|
386
|
+
print YAML.dump parsed
|
387
|
+
end
|