sensible-cinema 0.17.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/ChangeLog +4 -0
  2. data/LICENSE.TXT +70 -0
  3. data/README +95 -29
  4. data/TODO +85 -71
  5. data/USAGE_TERMS.TXT +15 -0
  6. data/VERSION +1 -1
  7. data/bin/sensible-cinema +90 -32
  8. data/bin/sensible-cinema-cli +17 -0
  9. data/edit sensible cinema decision list files.bat b/data/create new sensible cinema decision list → files.bat +0 -0
  10. data/ext/mkrf_conf.rb +17 -0
  11. data/how_to_create +1 -0
  12. data/lib/add_any_bundled_gems_to_load_path.rb +17 -0
  13. data/lib/blanker.rb +17 -0
  14. data/lib/drive_info.rb +17 -0
  15. data/lib/edl_parser.rb +17 -0
  16. data/lib/fake_blanker.rb +17 -0
  17. data/lib/file_chooser.rb +17 -0
  18. data/lib/keyboard_input.rb +17 -0
  19. data/lib/mencoder_wrapper.rb +32 -33
  20. data/lib/mouse.rb +17 -0
  21. data/lib/mouse_forever.rb +17 -0
  22. data/lib/mplayer_edl.rb +31 -0
  23. data/lib/muter.rb +17 -0
  24. data/lib/ocr.rb +17 -0
  25. data/lib/overlayer.rb +17 -0
  26. data/lib/screen_tracker.rb +18 -1
  27. data/lib/storage.rb +99 -82
  28. data/lib/swing_helpers.rb +17 -0
  29. data/lib/vlc_programmer.rb +17 -0
  30. data/preamble +17 -0
  31. data/sensible-cinema.gemspec +12 -5
  32. data/spec/blanker.spec.rb +17 -0
  33. data/spec/common.rb +17 -0
  34. data/spec/convert_image.rb +17 -0
  35. data/spec/drive_info.spec.rb +17 -0
  36. data/spec/edl_parser.spec.rb +17 -0
  37. data/spec/keyboard_input.spec.rb +17 -0
  38. data/spec/mencoder_wrapper.spec.rb +61 -21
  39. data/spec/mouse.spec.rb +17 -0
  40. data/spec/mplayer_edl.spec.rb +33 -0
  41. data/spec/muter.spec.rb +17 -0
  42. data/spec/ocr.spec.rb +17 -0
  43. data/spec/overlayer.spec.rb +17 -0
  44. data/spec/screen_tracker.spec.rb +17 -0
  45. data/spec/sensible_cinema_gui.spec.rb +38 -16
  46. data/spec/swing_helpers.spec.rb +17 -0
  47. data/spec/vlc_programmer.spec.rb +17 -0
  48. data/zamples/edit_decision_lists/dvds/COOL_RUNNINGS.txt +23 -1
  49. data/zamples/edit_decision_lists/dvds/Harry Potter 2.txt +18 -0
  50. data/zamples/edit_decision_lists/dvds/pack_wedding_2007-03-03.txt +24 -0
  51. data/zamples/edit_decision_lists/example_edit_decision_list.txt +1 -1
  52. metadata +13 -6
  53. data/LICENSE +0 -56
@@ -1,3 +1,20 @@
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
1
18
  if $0 == __FILE__
2
19
  require 'rubygems'
3
20
  require 'sane'
@@ -9,19 +26,21 @@ class MencoderWrapper
9
26
 
10
27
  class << self
11
28
 
12
- def get_header this_drive
29
+ def get_header this_drive, these_settings
13
30
  out = ''
14
31
  if File.exist?(@big_temp) && File.exist?(@big_temp + '.done')
15
32
  out = '@rem '
16
33
  end
34
+ # video_opts = "-ovc lavc -lavcopts keyint=1" # seems reasonable quality somehow...
17
35
  # equivalent of ffmpeg's -target ntsc-dvd...I think...except that aspect thing terrifies me...
18
- lavcopts = "vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=1:vstrict=0:acodec=ac3:abitrate=192:aspect=4/3"
19
- #lavcopts = "keyint=1"
20
- out + "call mencoder dvdnav://#{@dvd_title_track} -sid 1000 -oac copy -lavcopts #{lavcopts} -ofps 30000/1001 -ovc lavc -o #{@big_temp} -dvd-device #{this_drive} && echo got_file > #{@big_temp}.done\n"
36
+ audio_codec = these_settings['audio_codec'] || 'copy'
37
+ video_opts = "-ovc lavc -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=1:vstrict=0:acodec=ac3:abitrate=192:autoaspect -ofps 30000/1001"
38
+ out + "call mencoder dvdnav://#{@dvd_title_track} -of mpeg -mpegopts format=dvd:tsaf -alang en -nocache -sid 1000 -oac #{audio_codec} #{video_opts} -ovc lavc -o #{@big_temp} -dvd-device #{this_drive} && echo got_file > #{@big_temp}.done\n"
21
39
  end
22
40
 
23
- def get_bat_commands these_mutes, this_drive, to_here_final_file, start_here = nil, end_here = nil, dvd_title_track = "1"
24
- combined = VLCProgrammer.convert_incoming_to_split_sectors these_mutes
41
+ # called from the UI...
42
+ def get_bat_commands these_settings, this_drive, to_here_final_file, start_here = nil, end_here = nil, dvd_title_track = "1", delete_partials = false
43
+ combined = VLCProgrammer.convert_incoming_to_split_sectors these_settings
25
44
  @dvd_title_track = dvd_title_track
26
45
  if start_here || end_here
27
46
  raise 'need both' unless end_here && start_here
@@ -33,8 +52,8 @@ class MencoderWrapper
33
52
  else
34
53
  previous_end = 0
35
54
  end
36
- @big_temp = to_here_final_file + ".fulli.tmp.avi"
37
- out = get_header this_drive
55
+ @big_temp = to_here_final_file + ".fulli_unedited.tmp.mpg"
56
+ out = get_header this_drive, these_settings
38
57
  @idx = 0
39
58
  combined.each {|start, endy, type|
40
59
  if start > previous_end
@@ -54,15 +73,15 @@ class MencoderWrapper
54
73
  if File.exist? to_here_final_file
55
74
  FileUtils.rm to_here_final_file # raises on failure...which is what we want I think
56
75
  end
57
- # ridiculous
58
76
  out += "call mencoder #{partials.join(' ')} -o #{to_here_final_file} -ovc copy -oac copy\n"
59
77
  # LODO only do this if they want to watch it on their computer, with something other than smplayer, or want to make it smaller, as it takes *forever* longer
60
- # LODO the "insta play" mode, or the "faster rip" mode (related...)
61
78
  out += "@rem call mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf -vf scale=720:480,harddup -srate 48000 -af lavcresample=48000 -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:acodec=ac3:abitrate=192:aspect=16/9 -ofps 30000/1001 #{partials.join(' ')} -o #{to_here_final_file}\n"
79
+
80
+ delete_prefix = delete_partials ? "" : "@rem "
62
81
 
63
82
  out += "@rem del #{@big_temp}\n" # LODO no @rem
64
- out += "@rem del " + partials.join(' ') + "\n"# LODO no @rem
65
- out += "echo wrote to #{to_here_final_file}"
83
+ out += "#{delete_prefix} del " + partials.join(' ') + "\n"
84
+ out += "echo wrote (probably successfully) to #{to_here_final_file}"
66
85
  out
67
86
  end
68
87
 
@@ -73,33 +92,13 @@ class MencoderWrapper
73
92
  # very decreased volume is like muting :)
74
93
  # LODO can we copy more here? ntsc-dvd supposedly remuxes...
75
94
  codecs = should_mute ? "-vcodec copy -acodec ac3 -vol 0 " : "-vcodec copy -acodec copy " # LODO the ac3 must match the copy...hmm...
76
- # ffmpeg -i from_here.avi -vcodec copy -acodec copy -ss 1:00 -t 1:00 out.avi
77
95
  partial_filename = to_here_final_file + '.' + (@idx += 1).to_s + '.avi'
78
96
  if File.exist? partial_filename
79
97
  FileUtils.rm partial_filename
80
98
  end
81
- "del #{partial_filename}\ncall ffmpeg -i #{@big_temp} #{codecs} -ss #{start} -t #{endy} #{partial_filename}\n"
99
+ "call ffmpeg -i #{@big_temp} #{codecs} -ss #{start} -t #{endy} #{partial_filename}\n"
82
100
  end
83
101
 
84
102
  end
85
103
 
86
104
  end
87
-
88
- if $0 == __FILE__
89
- require 'rubygems'
90
- require 'sane'
91
- puts 'syntax: yaml_file_name d:\ output (00:15 00:25) (--run)'
92
- a = YAML.load_file ARGV.shift
93
- drive = ARGV.shift
94
- raise 'wrong drive' unless File.exist?(drive + "AUDIO_TS")
95
- execute = ARGV.delete('--run')
96
- commands = MencoderWrapper.get_bat_commands(a, drive, *ARGV)
97
- if ARGV.length > 2
98
- write_to = 'range.bat'
99
- else
100
- write_to = 'all.bat'
101
- end
102
- File.write(write_to, commands)
103
- print 'wrote ' + write_to
104
- system(write_to) if execute
105
- end
data/lib/mouse.rb CHANGED
@@ -1,3 +1,20 @@
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
1
18
  require 'rubygems'
2
19
  require 'ffi'
3
20
 
data/lib/mouse_forever.rb CHANGED
@@ -1,2 +1,19 @@
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
1
18
  require './../lib/mouse.rb'
2
19
  Mouse::jitter_forever_in_own_thread.join
@@ -0,0 +1,31 @@
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
+ require_relative 'overlayer'
19
+
20
+ class MplayerEdl
21
+ def self.convert_to_edl specs
22
+ out = ""
23
+ for type, metric in {"mutes" => 1, "blank_outs" => 0}
24
+ specs[type].each{|start, endy, other|
25
+ out += "#{OverLayer.translate_string_to_seconds start} #{OverLayer.translate_string_to_seconds endy} #{metric}\n"
26
+ }
27
+ end
28
+ out
29
+
30
+ end
31
+ end
data/lib/muter.rb CHANGED
@@ -1,3 +1,20 @@
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
1
18
  require 'rubygems' # ugh
2
19
  require 'ffi'
3
20
 
data/lib/ocr.rb CHANGED
@@ -1,3 +1,20 @@
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
1
18
  require 'sane' # gem
2
19
  require 'whichr' # gem
3
20
  require_relative 'swing_helpers' # to_filename lodo not have it there
data/lib/overlayer.rb CHANGED
@@ -1,3 +1,20 @@
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
1
18
  require 'sane'
2
19
  require 'thread'
3
20
  require 'timeout'
@@ -1,3 +1,20 @@
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
1
18
  require 'win32/screenshot'
2
19
  require 'sane'
3
20
  require 'yaml'
@@ -41,7 +58,7 @@ class ScreenTracker
41
58
  @digits = digits
42
59
  @previously_displayed_warning = false
43
60
  @dump_digit_count = 1
44
- pps 'using x',@x, 'from x', x, 'y', @y, 'from y', y,'x2',@x2,'y2',@y2,'digits', @digits if $VERBOSE
61
+ pps 'using x',@x, 'from x', x, 'y', @y, 'from y', y,'x2',@x2,'y2',@y2,'digits', @digits if $VERBOSE
45
62
  end
46
63
 
47
64
  def get_hwnd
data/lib/storage.rb CHANGED
@@ -1,82 +1,99 @@
1
- # use it like
2
-
3
- class Storage
4
- class << self
5
- attr_writer :storage_dir
6
- end
7
-
8
- def self.storage_dir
9
- @user_dir ||= File.join(File.expand_path('~'), ".storage")
10
- end
11
-
12
- # Open a storage file or create it if it doesn't exist.
13
- #
14
- # @param [String] a (short) name, should be suitable for use as a filename
15
- def initialize(name)
16
- @name = name
17
- unless File.exists?(Storage.storage_dir)
18
- FileUtils.mkdir_p(Storage.storage_dir)
19
- end
20
- rollback
21
- end
22
-
23
- # Save the storage to disk.
24
- def save
25
- File.open(path, "w") { |f| YAML.dump(@storage, f) }
26
- update_timestamp
27
- self
28
- end
29
-
30
- # Rollback the storage to the latest revision saved to disk or empty it if
31
- # it hasn't been saved.
32
- def rollback
33
- if File.exists?(path)
34
- @storage = YAML.load_file(path)
35
- raise 'storage file is corrupted--please delete ' + path unless @storage.is_a? Hash
36
- update_timestamp
37
- else
38
- @storage = {}
39
- end
40
- self
41
- end
42
-
43
- # retrieve key value
44
- # note: it does not re-read from disk before returning you this value
45
- def [](key)
46
- if @last_modified_time
47
- if File.exist?(path()) && (File.stat(path()).mtime != @last_modified_time)
48
- rollback
49
- end
50
- end
51
- @storage[key]
52
- end
53
-
54
- # set key to value
55
- # note: it automatically saves this to disk
56
- def []=(key, value)
57
- @storage[key] = value
58
- save
59
- value
60
- end
61
-
62
- def set_default(key, value)
63
- unless @storage.has_key?(key)
64
- self[key] = value
65
- end
66
- value
67
- end
68
-
69
- def keys
70
- @storage.keys
71
- end
72
-
73
- private
74
-
75
- def path
76
- File.join(Storage.storage_dir, @name + ".yaml")
77
- end
78
-
79
- def update_timestamp
80
- @last_modified_time = File.stat(path()).mtime
81
- end
82
- end
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
+ # use it like
19
+
20
+ class Storage
21
+ class << self
22
+ attr_writer :storage_dir
23
+ end
24
+
25
+ def self.storage_dir
26
+ @user_dir ||= File.join(File.expand_path('~'), ".storage")
27
+ end
28
+
29
+ # Open a storage file or create it if it doesn't exist.
30
+ #
31
+ # @param [String] a (short) name, should be suitable for use as a filename
32
+ def initialize(name)
33
+ @name = name
34
+ unless File.exists?(Storage.storage_dir)
35
+ FileUtils.mkdir_p(Storage.storage_dir)
36
+ end
37
+ rollback
38
+ end
39
+
40
+ # Save the storage to disk.
41
+ def save
42
+ File.open(path, "w") { |f| YAML.dump(@storage, f) }
43
+ update_timestamp
44
+ self
45
+ end
46
+
47
+ # Rollback the storage to the latest revision saved to disk or empty it if
48
+ # it hasn't been saved.
49
+ def rollback
50
+ if File.exists?(path)
51
+ @storage = YAML.load_file(path)
52
+ raise 'storage file is corrupted--please delete ' + path unless @storage.is_a? Hash
53
+ update_timestamp
54
+ else
55
+ @storage = {}
56
+ end
57
+ self
58
+ end
59
+
60
+ # retrieve key value
61
+ # note: it does not re-read from disk before returning you this value
62
+ def [](key)
63
+ if @last_modified_time
64
+ if File.exist?(path()) && (File.stat(path()).mtime != @last_modified_time)
65
+ rollback
66
+ end
67
+ end
68
+ @storage[key]
69
+ end
70
+
71
+ # set key to value
72
+ # note: it automatically saves this to disk
73
+ def []=(key, value)
74
+ @storage[key] = value
75
+ save
76
+ value
77
+ end
78
+
79
+ def set_default(key, value)
80
+ unless @storage.has_key?(key)
81
+ self[key] = value
82
+ end
83
+ value
84
+ end
85
+
86
+ def keys
87
+ @storage.keys
88
+ end
89
+
90
+ private
91
+
92
+ def path
93
+ File.join(Storage.storage_dir, @name + ".yaml")
94
+ end
95
+
96
+ def update_timestamp
97
+ @last_modified_time = File.stat(path()).mtime
98
+ end
99
+ end