sensible-cinema 0.15.0 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +15 -1
- data/LICENSE +46 -35
- data/Rakefile +7 -10
- data/TODO +61 -67
- data/VERSION +1 -1
- data/bin/sensible-cinema +195 -113
- data/lib/edl_parser.rb +54 -0
- data/lib/mencoder_wrapper.rb +8 -9
- data/lib/storage.rb +82 -0
- data/lib/swing_helpers.rb +19 -1
- data/run_sensible_cinema_in_create_mode.bat +5 -0
- data/sensible-cinema.gemspec +141 -136
- data/spec/edl_parser.spec.rb +76 -0
- data/spec/mencoder_wrapper.spec.rb +10 -12
- data/spec/sensible_cinema_gui.spec.rb +12 -10
- data/vendor/unzip.exe +0 -0
- data/zamples/edit_decision_lists/category descriptions.txt +1 -0
- data/zamples/edit_decision_lists/dvds/bobs_big_plan.txt +9 -12
- data/zamples/edit_decision_lists/dvds/happiest baby on the block.txt +8 -11
- data/zamples/edit_decision_lists/dvds/White Christmas.txt b/data/zamples/edit_decision_lists/dvds/old_and_inaccurate/White → Christmas.txt +0 -0
- data/zamples/edit_decision_lists/dvds/{all_dogs_go_to_heaven.txt → old_and_inaccurate/all_dogs_go_to_heaven.txt} +0 -0
- data/zamples/edit_decision_lists/dvds/{cars_disney.txt → old_and_inaccurate/cars_disney.txt} +0 -0
- data/zamples/edit_decision_lists/dvds/{happy_feet.txt → old_and_inaccurate/happy_feet.txt} +0 -0
- data/zamples/edit_decision_lists/dvds/{labyrinth.txt → old_and_inaccurate/labyrinth.txt} +0 -0
- data/zamples/edit_decision_lists/dvds/making marriage work.txt b/data/zamples/edit_decision_lists/dvds/old_and_inaccurate/making marriage → work.txt +0 -0
- data/zamples/edit_decision_lists/{star_trek_generations_hulu.txt → dvds/old_and_inaccurate/star_trek_generations_hulu.txt} +0 -0
- data/zamples/edit_decision_lists/example_edit_decision_list.txt +36 -20
- data/zamples/edit_decision_lists/{youtube → old_not_yet_update/youtube}/gummy_bear_song_youtube.txt +0 -0
- data/zamples/edit_decision_lists/{youtube → old_not_yet_update/youtube}/nuki_song_youtube.txt +0 -0
- metadata +291 -285
data/ChangeLog
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
|
+
== 0.16.0 ==
|
|
2
|
+
|
|
3
|
+
Change the YAML style so that it can have filterable categories (disabled for now, but there are unit tests
|
|
4
|
+
that show the use of such as a form of "combining user preferences" with the EDL to produce a
|
|
5
|
+
new customized one.
|
|
6
|
+
|
|
7
|
+
Allow for quite more easily user creation/editing of EDL's by allowing users to access just specific "scenes" of the video edited.
|
|
8
|
+
|
|
9
|
+
Disable title auto selection use, now use md5sum of the DVD's IFO files for auto-selection of EDL.
|
|
10
|
+
|
|
1
11
|
== 0.15.0 ==
|
|
2
12
|
|
|
3
13
|
Use all i-frames for more accurate precision in cutting segments.
|
|
4
14
|
Also use ffmpeg and mencoder for the same (no more VLC for encoding). Phew.
|
|
15
|
+
Note that by at least this version, auto DVD title selection as a parameter has been built in (see git log).
|
|
16
|
+
Note that by at least this version, it could compute an md5sum of a DVD's IFO files to compute
|
|
17
|
+
a unique ID for that disk.
|
|
18
|
+
Note that before this, I was using the volume name to generate filenames.
|
|
5
19
|
|
|
6
20
|
== 0.14.8 ==
|
|
7
21
|
|
|
@@ -13,7 +27,7 @@ Auto-select EDL depending on which disk they have.
|
|
|
13
27
|
|
|
14
28
|
== 0.14.5 ==
|
|
15
29
|
|
|
16
|
-
|
|
30
|
+
Made it distributable more easily.
|
|
17
31
|
|
|
18
32
|
== 0.14.4 ==
|
|
19
33
|
|
data/LICENSE
CHANGED
|
@@ -1,42 +1,53 @@
|
|
|
1
|
-
All files released under the GPLv3 license [1] unless otherwise specified. Ping me if you want this changed.
|
|
2
|
-
|
|
3
|
-
May contain some 3rd party libraries under their own (separate, open source) licenses.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
All files released under the GPLv3 license [1] unless otherwise specified. Ping me if you want/need this changed.
|
|
2
|
+
|
|
3
|
+
May contain some 3rd party libraries/executables under their own (separate, open source) licenses.
|
|
4
|
+
|
|
5
|
+
Is this legal?
|
|
6
|
+
|
|
7
|
+
Unclear. In general ripping personal DVD's is fine.
|
|
8
|
+
It is controversial to use open source software to play/rip DVD's.
|
|
9
|
+
There are a few conflicting views.
|
|
10
|
+
Sensible-cinema doesn't actually do any decryption or decoding, nor has any knowledge of it,
|
|
11
|
+
but calls out to another separate program to rip. It doesn't even have knowledge
|
|
12
|
+
as to whether it is ripping something encrypted or not. We don't distribute sensible-cinema with
|
|
13
|
+
that program, either.
|
|
14
|
+
You can ask the authors of that program if it is legal. Apparently
|
|
15
|
+
libdvdcss that it uses has never been challenged in court, and uses a slightly different algorithm
|
|
16
|
+
than those that have.
|
|
17
|
+
Note also that fair use does allow one to "record" things (especially things that they own)
|
|
18
|
+
for personal use/backup.
|
|
19
|
+
Using sensible-cinema is probably not any more unethical than ripping your DVD collection to your hard
|
|
20
|
+
drive so you can keep your DVD's all in one place.
|
|
21
|
+
Also note that if you watch an edited DVD, your are using a DVD player that conforms
|
|
22
|
+
with DMCA specifications, so that might have some influence.
|
|
23
|
+
|
|
24
|
+
In general, you are responsible for your actions and use of this program.
|
|
25
|
+
It is possible that the authors of sensible-cinema are not cupable of anything
|
|
26
|
+
regarding its use themselves, since they re-distribute no edited media,
|
|
27
|
+
nor distribute cracking codes. In general, check your country's rules first.
|
|
28
|
+
|
|
29
|
+
In terms of copyright, it could indeed be legal, at least in the United States, when viewed
|
|
30
|
+
using the "playlist" option (v 0.10'ish).
|
|
31
|
+
In general, if I have the original DVD sitting next to my TV, I don't feel bad about watching
|
|
32
|
+
its edited copy at the same time, but please consult a laywer first if you have any concerns.
|
|
33
|
+
|
|
34
|
+
Do not redistribute copied commercial DVD's. We have learned from clean flicks that
|
|
35
|
+
redistributing edited commercial DVD's is illegal in the US. We hope that sensible-cinema
|
|
36
|
+
is more legal, since you can get the DVD's from wherever you want, and it doesn't change their
|
|
37
|
+
structure at all. Please don't redistribute.
|
|
38
|
+
|
|
39
|
+
DO NOT MAKE ILLEGAL COPIES.
|
|
40
|
+
|
|
41
|
+
Note that this software might well be legal in the EU,
|
|
42
|
+
as it is only software and therefore thus possibly not subject to patents (see "What about patent licenses?" in [2]).
|
|
8
43
|
If it's not legal in your country, don't use it!
|
|
9
44
|
|
|
10
|
-
|
|
11
|
-
US law that appears related (and is in its favor).
|
|
12
|
-
|
|
13
|
-
A history of various related thoughts was described here:
|
|
45
|
+
A more ancient history of various related thoughts was described here:
|
|
14
46
|
http://betterlogic.com/roger/?p=2618
|
|
15
47
|
|
|
16
|
-
|
|
48
|
+
Also note that several ideas have been released in the code that are disabled in the final release. Please see the blog
|
|
49
|
+
for release notes http://betterlogic.com/roger, as well as http://ruby-forum.com (ruby talk ML there), and rubygems.org
|
|
50
|
+
which lists the various releases, and github.com/rdp/sensible-cinema which lists commits and changes and releases.
|
|
17
51
|
|
|
18
52
|
[1] http://www.gnu.org/licenses/gpl.html, also gplv3 file.
|
|
19
53
|
[2] http://www.videolan.org/support/faq.html
|
|
20
|
-
|
|
21
|
-
add note "we don't distribute anything that breaks encryption keys" like http://k9copy.sourceforge.net/
|
|
22
|
-
|
|
23
|
-
honest about DMCA (we don't distribute the cracker, we don't redistribute, don't perform any acts, etc.)
|
|
24
|
-
if you burn you'll eventually be using a DMCA compatible player :P
|
|
25
|
-
long list of players...we're not alone :)
|
|
26
|
-
the authors of the program might not be liable for damages. We don't feel dishonest about it, as long as
|
|
27
|
-
we own the DVD and have it with us when we watch the edited version.
|
|
28
|
-
|
|
29
|
-
not more unethical than ripping your DVD collection to hard drive so you can keep your DVD's all in one
|
|
30
|
-
place and don't have to worry about losing them. Then you edit them manually to remove cruft, and watch them
|
|
31
|
-
from there.
|
|
32
|
-
|
|
33
|
-
for me, the images and audio are unencrypted, so storing/saving those away might well be fair use, but check your countries rules first
|
|
34
|
-
(similar to how recording using a VCR might well not be illegal under fair use). But don't take my word for it.
|
|
35
|
-
|
|
36
|
-
note that you are watching it using only bits and pieces of the original, similar to said bill. And the
|
|
37
|
-
authors of the program might not be cupable of copyright infringement themselves, since they distribute no infringed materials.
|
|
38
|
-
|
|
39
|
-
Not responsible for your actions. Don't redistribute. "You run the risk on your own"
|
|
40
|
-
"should the courts someday rule..." If DVD next to me...
|
|
41
|
-
|
|
42
|
-
fair use may apply
|
data/Rakefile
CHANGED
|
@@ -69,19 +69,11 @@ task 'bundle_dependencies' => 'gemspec' do
|
|
|
69
69
|
dependencies.each{|d|
|
|
70
70
|
system("#{Gem.ruby} -S gem unpack #{d.name}")
|
|
71
71
|
}
|
|
72
|
-
# add imagemagick
|
|
73
|
-
puts 'copying in imagemagick'
|
|
74
|
-
Dir.mkdir 'imagemagick'
|
|
75
|
-
im_identify_command = RubyWhich.new.which('identify').select{|dir| dir =~ /ImageMagick/}[0]
|
|
76
|
-
# "d:\\installs\\ImageMagick-6.6.2-Q16\\identify.EXE",
|
|
77
|
-
Dir["#{File.dirname im_identify_command}/*"].each{|file|
|
|
78
|
-
FileUtils.cp_r(file, 'imagemagick') rescue nil # some fail for some odd reason
|
|
79
|
-
}
|
|
80
72
|
puts 'downloading in jruby-complete.jar file'
|
|
81
73
|
# jruby complete .jar file
|
|
82
74
|
Net::HTTP.start("jruby.org.s3.amazonaws.com") { |http|
|
|
83
75
|
resp = http.get("/downloads/1.5.5/jruby-complete-1.5.5.jar")
|
|
84
|
-
puts 'copying... '
|
|
76
|
+
puts 'copying it... '
|
|
85
77
|
open("jruby-complete-1.5.5.jar", "wb") { |file|
|
|
86
78
|
file.write(resp.body)
|
|
87
79
|
}
|
|
@@ -107,6 +99,11 @@ task 'create_distro_dir' do
|
|
|
107
99
|
FileUtils.mkdir_p dir_out
|
|
108
100
|
FileUtils.cp_r(existing, dir_out)
|
|
109
101
|
# this one belongs in the trunk
|
|
110
|
-
FileUtils.cp("#{dir_out}
|
|
102
|
+
FileUtils.cp(Dir["#{dir_out}/*.bat"], "#{dir_out}/..")
|
|
111
103
|
p 'created (still need to zip it) ' + dir_out
|
|
112
104
|
end
|
|
105
|
+
|
|
106
|
+
desc 'j -S rake bundle_dependencies create_distro_dir ...'
|
|
107
|
+
task 'full_release' => [:bundle_dependencies, :create_distro_dir, :build] do # :release
|
|
108
|
+
system("#{Gem.ruby} -S gem push pkg/*.gem")
|
|
109
|
+
end
|
data/TODO
CHANGED
|
@@ -1,107 +1,104 @@
|
|
|
1
1
|
== medium ==
|
|
2
|
-
|
|
3
2
|
|
|
4
3
|
== probably next up+low prio ==
|
|
5
4
|
|
|
6
|
-
use mencoder from the gui
|
|
7
|
-
use mencoder + ffmpeg
|
|
8
|
-
re-do various EDL's I have :P
|
|
9
|
-
split the two projects somehow (project + distribution)
|
|
10
|
-
two releases: experimental, normal (no imagemagick)
|
|
11
|
-
preferences merger...hmm...;
|
|
12
5
|
compare computer DVD playback with physical player...
|
|
6
|
+
release .zip
|
|
13
7
|
|
|
14
8
|
== slightly lower than that ==
|
|
15
9
|
|
|
10
|
+
make sure no subtitles on national treasure...
|
|
11
|
+
partner for filters (Jon, Karlie if interested...give beta)
|
|
12
|
+
lotsa filters somehow
|
|
13
|
+
beta release/rinse and repeat with various ppl (once it's releasable...)
|
|
14
|
+
can generate mplayer EDL's and play them...hmm...smplayer them?
|
|
15
|
+
update license too...
|
|
16
|
+
a real'ish website
|
|
17
|
+
"run create mode" button (?)
|
|
18
|
+
license the first time they run it (gplv3)
|
|
19
|
+
bring that window to the top! (before done dialog...)
|
|
20
|
+
|
|
21
|
+
== DVD backlog (unordered, some very low prio) ==
|
|
22
|
+
|
|
23
|
+
DRY up dependency installation code
|
|
24
|
+
install them to cache2 or something...so I can cleanup..
|
|
25
|
+
using+burning screencast
|
|
26
|
+
editing screencast
|
|
27
|
+
instructions on how to do their own (private) EDL or do one and submit it (public), or email their friends :P
|
|
28
|
+
note how to get the title number
|
|
29
|
+
add a way to get the label rather easily...
|
|
30
|
+
add an option "just save full disk (unedited) to hard drive..."
|
|
31
|
+
note to people: can edit those to your liking
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
advertise urug, ruby flow :)
|
|
35
|
+
"Re-run most recent" disabled when there isn't one [?]
|
|
36
|
+
unit test the GUI
|
|
37
|
+
re-do DVD EDL's that need it :P
|
|
38
|
+
all dogs go to heaven...finish EDL
|
|
39
|
+
warn when labels exist and don't match...
|
|
40
|
+
kill old mencoder instances more often...
|
|
41
|
+
auto-download imagemagick, too
|
|
42
|
+
check all the various options to see if there's a "cross platform way to split files accurately" besides my hacky kludge.
|
|
43
|
+
popup "you may now watch": bring it to the front...
|
|
44
|
+
can rip from a DVD-like folder (?)
|
|
16
45
|
ripping "redoes" a large last section, for combining. Can I avoid this?
|
|
17
46
|
plus I do some copy, some ac3?
|
|
18
|
-
|
|
19
|
-
unit test the GUI
|
|
20
|
-
no subtitles on national treasure...
|
|
21
|
-
|
|
22
|
-
ask if there's a "cross platform way to split files accurately" besides my hacky kludge.
|
|
23
|
-
|
|
24
|
-
popup "you may now watch": bring it to the front...
|
|
25
|
-
|
|
26
|
-
easy editor for this style of edit
|
|
27
|
-
partner (Jon, Karlie if interested...give beta)
|
|
28
|
-
create lotsa filters
|
|
29
|
-
beta release
|
|
30
|
-
some better ripper...
|
|
31
|
-
maybe vlc is bound by the same constrains mplayer is?
|
|
32
|
-
maybe rip it to a more precise encoding, then edit it?
|
|
33
|
-
|
|
34
|
-
== DVD monetary backlog (unordered) ==
|
|
35
|
-
|
|
36
|
-
@mencoder.exe distributor: OCI plz? puh-lease?
|
|
37
|
-
@dvd flick do you need that frequent i-frames?
|
|
47
|
+
@dvd flick do you need that frequent of i-frames?
|
|
38
48
|
rename bat as template.bat
|
|
39
49
|
can parse IMDB (require they put in the URL by hand fer now)
|
|
40
50
|
add stuffs to imdb hmmm
|
|
41
51
|
IMDB easy mapping
|
|
42
|
-
all dogs go to heaven...
|
|
43
52
|
can blank out the video, with audio continuing through...
|
|
44
|
-
add an option "just save full disk (unedited) to hard drive..."
|
|
45
53
|
add an option "just save full disk (edited) to hard drive...well compressed"
|
|
46
|
-
or do we want to do that by default anyway? (does it help burning?
|
|
54
|
+
or do we want to do that by default anyway? (does it help burning? file size...hmm...)
|
|
47
55
|
@VLC: hard crash when ripping that one DVD...long one, about the constitution...
|
|
48
|
-
|
|
49
|
-
check DVD patent expiration date
|
|
50
|
-
better burning screencast
|
|
56
|
+
in general, fine tune burning with various things...
|
|
51
57
|
|
|
52
58
|
make sure can work with very large DVD's...
|
|
53
59
|
can use a fast temp drive, save through to other :P
|
|
54
60
|
only prompt if have two...
|
|
55
|
-
pass a better title through when ripping so it doesn't just say dvd://1 always
|
|
56
61
|
can have collaborators re-selling EDL's
|
|
57
62
|
good license for their stuff like "public domain" or what not :P Can't be a hypocrite now, can I?
|
|
58
|
-
|
|
59
|
-
.ts doesn't seem too awesome....
|
|
60
|
-
|
|
63
|
+
a real website
|
|
61
64
|
k9 might preserve/shrink well...hmm...auto calculation may be possible...hmm...
|
|
62
|
-
better icon...
|
|
65
|
+
better .exe icon...
|
|
63
66
|
ensure file exists after we created it...and has a reasonable size, before declaring success
|
|
64
67
|
148 cars_widescreen_2006_edited.ps
|
|
68
|
+
blu-ray support somehow (real-time? rip?)
|
|
65
69
|
use DVD navigator ?
|
|
66
70
|
http://msdn.microsoft.com/en-us/library/dd388584(v=VS.85).aspx
|
|
67
71
|
with an avi file sink?
|
|
68
|
-
authorize.net instead of paypal?
|
|
69
|
-
blu-ray support somehow (real-time? rip?)
|
|
70
|
-
legal shtuff (LICENSE)
|
|
71
|
-
some type of installer that can setup the registry...
|
|
72
|
-
auto-assignment of EDL's to media:
|
|
73
|
-
DVD's (right click on DVD player, rip with SC?)
|
|
74
|
-
a real website
|
|
75
|
-
instructions on how to do their own (private) EDL or do one and submit it (public), or email their friends :P
|
|
76
72
|
double buffering hard drive/incoming copying from DVD might speed things, if your HD is fast.
|
|
77
|
-
personalized copier might be faster than the "type" command.
|
|
78
|
-
merge with preferences
|
|
79
|
-
For the monetized version: nothing but cut and paste, no merging et al
|
|
80
|
-
mplayer EDL's
|
|
81
|
-
add option to "just rip a DVD of your own straight full thing"
|
|
82
|
-
avisynth?
|
|
83
73
|
make the progress bar map "better" to the size of the various sections...
|
|
84
|
-
detect occurrence of these type errors: dvdnav warning: cannot get next block (Error reading from DVD.) somehow (file size...)
|
|
85
|
-
per movie,
|
|
74
|
+
detect occurrence of these type errors (DVD read failure): dvdnav warning: cannot get next block (Error reading from DVD.) somehow (file size...)
|
|
75
|
+
per movie, several EDL's, one includes profanity, one just violence, one paranoid, etc.
|
|
86
76
|
when there are several, it lets you just choose between the ones that are valid (?)
|
|
87
77
|
|
|
88
|
-
ask VLC is "adding 0.23 expected?" "do you have the same constraints as mplayer?"
|
|
89
|
-
ask VLC "fuzzy menus on the happiest baby dvd expected?"
|
|
90
|
-
slightly faster copying possible (664 versus 887 seconds to combine them all together.)
|
|
91
|
-
@mplayer "when it says nearest keyframe, that could be in the future?"
|
|
92
|
-
@mplayer "when I say play for 3.2, and the keyframe is 0.5 before, does it end up playing for 3.2 or 3.7?"
|
|
93
78
|
burnable to DVD/CD/multi DVD automagically... (auto-burn insert your new disk!)
|
|
94
79
|
can *re-use* original navigation stuffs, less the profanity (is that possible? VobBlanker help, perhaps?)
|
|
95
80
|
can lop off sections to save space (?)
|
|
96
81
|
can burn extras from the DVD, too?
|
|
97
82
|
optionally ?
|
|
98
|
-
transcode to condense
|
|
83
|
+
transcode to condense..?
|
|
99
84
|
split to allow?
|
|
100
|
-
@smplayer: playing DVD's doesn't work currently
|
|
101
85
|
try to compile transcode in cygwin (yipes)
|
|
102
|
-
|
|
86
|
+
legal shtuff (LICENSE)
|
|
103
87
|
|
|
104
|
-
== random backlog ... note: just plow forward, to "grab" available ideas...except that for now, just what *I* plan on needing for myself (filters for what I need/want). ==
|
|
88
|
+
== random non-DVD backlog ... note: just plow forward, to "grab" available ideas...except that for now, just what *I* plan on needing for myself (filters for what I need/want). ==
|
|
89
|
+
|
|
90
|
+
the ac3 thing
|
|
91
|
+
ask VLC "fuzzy menus on the happiest baby dvd expected?"
|
|
92
|
+
right click on DVD player, rip edited with SC?
|
|
93
|
+
auto-zip it with my rake task :)
|
|
94
|
+
split the two projects somehow (project + distribution)
|
|
95
|
+
two releases: experimental, developer/experimental
|
|
96
|
+
bring back the old :)
|
|
97
|
+
button for "suck in EDL's"
|
|
98
|
+
split out the EDL's to a separate project (?)
|
|
99
|
+
make the other stuff work again, since I no longer use YAML...
|
|
100
|
+
advertise my "splitting joining" google doc page. also test the various options there for accurateness :)
|
|
101
|
+
also note that mencoder doesn't do splitting very well, for some reason.
|
|
105
102
|
|
|
106
103
|
pass unit tests again jruby
|
|
107
104
|
|
|
@@ -137,9 +134,6 @@ a descriptor for some closed source app player...
|
|
|
137
134
|
|
|
138
135
|
can "overlay-audio/video"
|
|
139
136
|
|
|
140
|
-
GUI:
|
|
141
|
-
preferences for levels, etc.
|
|
142
|
-
|
|
143
137
|
blanker: allow for one side of the screen or another...
|
|
144
138
|
|
|
145
139
|
PISH
|
|
@@ -280,6 +274,6 @@ create a "book edit list" (word x is at position y...)
|
|
|
280
274
|
are your highest settings optimal?
|
|
281
275
|
accept subtitled video...
|
|
282
276
|
|
|
283
|
-
|
|
277
|
+
@smplayer: your CD config is awful.
|
|
284
278
|
@mencoder: can't split
|
|
285
279
|
something like you watch it *with* you friends and can all chat together...hmm...
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.16.1
|
data/bin/sensible-cinema
CHANGED
|
@@ -5,21 +5,20 @@ puts 'Loading Sensible Cinema...'
|
|
|
5
5
|
require File.dirname(__FILE__) + "/../lib/add_any_bundled_gems_to_load_path.rb"
|
|
6
6
|
require 'sane'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
require_relative '../lib/mencoder_wrapper'
|
|
9
|
+
require_relative '../lib/storage'
|
|
10
|
+
require_relative '../lib/edl_parser'
|
|
11
11
|
|
|
12
|
-
require 'ruby-wmi'
|
|
13
12
|
require 'tmpdir'
|
|
14
13
|
require_relative '../lib/swing_helpers'
|
|
15
14
|
require_relative '../lib/drive_info'
|
|
15
|
+
require 'whichr'
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
# lodo use the registry to pull out the 'right' path...
|
|
19
|
-
ENV['PATH'] = ENV['PATH'] + ";C:\\Program Files\\VideoLAN\\VLC"+ ";D:\\Program Files\\VideoLAN\\VLC" + ";E:\\Program Files\\VideoLAN\\VLC"
|
|
17
|
+
ENV['PATH'] = ENV['PATH'] + ';' + File.expand_path(File.dirname(__FILE__)) + '/../vendor/cache/mencoder'.to_filename
|
|
20
18
|
|
|
21
19
|
module SensibleSwing
|
|
22
20
|
class MainWindow < JFrame
|
|
21
|
+
Storage = Storage.new("sc")
|
|
23
22
|
def initialize
|
|
24
23
|
super "Sensible-Cinema"
|
|
25
24
|
setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
|
|
@@ -28,136 +27,214 @@ module SensibleSwing
|
|
|
28
27
|
setSize 350,400
|
|
29
28
|
add panel # why can't I just slap these down?
|
|
30
29
|
|
|
31
|
-
jlabel = JLabel.new 'Welcome to Sensible Cinema'
|
|
30
|
+
jlabel = JLabel.new 'Welcome to Sensible Cinema!'
|
|
32
31
|
happy = Font.new("Tahoma", Font::PLAIN, 11)
|
|
33
32
|
jlabel.setFont(happy)
|
|
34
33
|
jlabel.set_bounds(44,44,136,14)
|
|
35
34
|
panel.add jlabel
|
|
36
|
-
b = JButton.new( "Play Hulu, Youtube, or a DVD (Tracking)" ).on_clicked {
|
|
37
|
-
load File.dirname(__FILE__) + '/sensible-cinema-cli'
|
|
38
|
-
Thread.new { go_sc([]) } # needs to be in its own thread becuase it blocks,
|
|
39
|
-
# so "this thread" is the uni-swing thread, gets blocked, and the overlayer can't repaint
|
|
40
|
-
self.close
|
|
41
|
-
}
|
|
42
|
-
button_width = 230
|
|
43
|
-
b.set_bounds(44,120,button_width,23)
|
|
44
|
-
panel.add b
|
|
45
35
|
|
|
46
|
-
|
|
36
|
+
button_width = 270
|
|
37
|
+
|
|
38
|
+
c = JButton.new( "Create edited copy of DVD on Your Hard Drive" )
|
|
47
39
|
c.on_clicked {
|
|
48
|
-
do_copy_dvd_to_hard_drive
|
|
40
|
+
do_copy_dvd_to_hard_drive false
|
|
49
41
|
}
|
|
50
|
-
c.set_bounds(44,
|
|
51
|
-
panel.add c
|
|
42
|
+
c.set_bounds(44,120,button_width,23)
|
|
43
|
+
panel.add c
|
|
52
44
|
|
|
53
|
-
|
|
45
|
+
b = JButton.new("Watch current DVD unedited")
|
|
46
|
+
b.on_clicked {
|
|
47
|
+
ENV['PATH'] = ENV['PATH'] + ";d:\\Program Files\\SMPlayer;c:\\Program Files\\SMPlayer"
|
|
48
|
+
path = RubyWhich.new.which('smplayer')
|
|
49
|
+
if(path.length == 0)
|
|
50
|
+
JOptionPane.showMessageDialog(self, "It appears that you need to install a dependency: SMPlayer.\n
|
|
51
|
+
Click ok to be directed to its download website.
|
|
52
|
+
Also note that if it ever hangs, kill the process, and then use VLC instead
|
|
53
|
+
(though VLC only has approximate timings).", "Lacking dependency", JOptionPane::ERROR_MESSAGE)
|
|
54
|
+
system("start http://smplayer.sourceforge.net/downloads.php")
|
|
55
|
+
else
|
|
56
|
+
drive, volume, md5 = choose_dvd_drive
|
|
57
|
+
system("smplayer dvd:// -dvd-device #{drive}")
|
|
58
|
+
end
|
|
59
|
+
}
|
|
60
|
+
b.set_bounds(44,150,button_width,23)
|
|
61
|
+
panel.add b
|
|
62
|
+
|
|
63
|
+
d = JButton.new( "Preview edited section of current DVD" )
|
|
54
64
|
d.on_clicked {
|
|
55
|
-
do_copy_dvd_to_hard_drive
|
|
65
|
+
do_copy_dvd_to_hard_drive true
|
|
56
66
|
}
|
|
57
67
|
|
|
58
68
|
d.set_bounds(44,180,button_width,23)
|
|
59
|
-
panel.add d
|
|
69
|
+
panel.add d if ARGV.index("--create-mode")
|
|
70
|
+
|
|
71
|
+
f = JButton.new("Open/Edit an Edit Decision List")
|
|
72
|
+
f.on_clicked {
|
|
73
|
+
dialog = FileDialog.new(self, "Pick file to edit")
|
|
74
|
+
dialog.set_directory EDL_DIR
|
|
75
|
+
filename = dialog.go
|
|
76
|
+
system("notepad \"#{filename}\"") if filename
|
|
77
|
+
}
|
|
78
|
+
f.set_bounds(44,260,button_width,23)
|
|
79
|
+
panel.add f if ARGV.index("--create-mode")
|
|
80
|
+
|
|
81
|
+
e = JButton.new( "Re-run most recent preview segment" )
|
|
82
|
+
e.on_clicked {
|
|
83
|
+
repeat_last_copy_dvd_to_hard_drive
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
e.set_bounds(44,220,button_width,23)
|
|
87
|
+
panel.add e if ARGV.index("--create-mode")
|
|
88
|
+
|
|
89
|
+
reload = JButton.new( "Get a disk's unique ID" ).on_clicked {
|
|
90
|
+
drive, volume, md5 = choose_dvd_drive
|
|
91
|
+
# display it, allow them to copy and paste it out
|
|
92
|
+
JOptionPane.showInputDialog("#{drive} #{volume} for your copying+pasting pleasure (highlight, then ctrl+c to copy) \n
|
|
93
|
+
This is used to identify a disk to match it to its EDL, later.", "\"disk_unique_id\" => \"#{md5}\",")
|
|
94
|
+
}
|
|
60
95
|
|
|
96
|
+
reload.set_bounds(44,290,button_width,20)
|
|
97
|
+
panel.add reload if ARGV.index("--create-mode")
|
|
98
|
+
|
|
61
99
|
@exit = JButton.new("Exit").on_clicked {
|
|
62
100
|
self.close
|
|
63
101
|
}
|
|
64
102
|
@exit.set_bounds(44,320,button_width,23)
|
|
65
|
-
panel.add @exit
|
|
66
|
-
|
|
67
|
-
if ARGV.find{|a| a == '--test'}
|
|
68
|
-
reload = JButton.new( "reload code" ).on_clicked {
|
|
69
|
-
eval File.read(__FILE__), nil, __FILE__
|
|
70
|
-
p 're-evaled the code ...'
|
|
71
|
-
}
|
|
72
|
-
reload.set_bounds(20,300,20,20)
|
|
73
|
-
panel.add reload
|
|
74
|
-
end
|
|
103
|
+
panel.add @exit
|
|
75
104
|
|
|
76
105
|
@progress_bar = JProgressBar.new(0, 100)
|
|
77
106
|
@progress_bar.set_bounds(44,280,button_width,23)
|
|
78
|
-
@progress_bar.visible=false
|
|
107
|
+
@progress_bar.visible = false
|
|
79
108
|
panel.add @progress_bar
|
|
80
|
-
@buttons = [b,c,d,@exit]
|
|
109
|
+
@buttons = [b,c,d,e,reload,@exit]
|
|
110
|
+
check_for_dependencies
|
|
81
111
|
end
|
|
82
112
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
true
|
|
90
|
-
end
|
|
91
|
-
end
|
|
113
|
+
def download full_url, to_here
|
|
114
|
+
require 'open-uri'
|
|
115
|
+
writeOut = open(to_here, "wb")
|
|
116
|
+
writeOut.write(open(full_url).read)
|
|
117
|
+
writeOut.close
|
|
118
|
+
end
|
|
92
119
|
|
|
93
|
-
def
|
|
120
|
+
def check_for_dependencies
|
|
121
|
+
ffmpeg = RubyWhich.new.which('ffmpeg')
|
|
122
|
+
if ffmpeg.length == 0
|
|
123
|
+
JOptionPane.showMessageDialog(self, "It appears that you need to install a dependency: imagemagick.\n
|
|
124
|
+
Click ok to be directed to its download website.\nYou'll probably want to download and install the \"windows-dll.exe\" package.\n
|
|
125
|
+
Then restart Sensible-Cinema.", "Lacking dependency", JOptionPane::ERROR_MESSAGE)
|
|
126
|
+
system("start http://www.imagemagick.org/script/binary-releases.php#windows")
|
|
127
|
+
java.lang.System.exit(1)
|
|
128
|
+
end
|
|
129
|
+
mencoder = RubyWhich.new.which('mencoder')
|
|
130
|
+
if mencoder.length == 0
|
|
131
|
+
answer = JOptionPane.showConfirmDialog(nil, "Appears that you need to install a dependency: mencoder.
|
|
132
|
+
Its license is at: http://www.gnu.org/licenses/gpl-2.0.html.
|
|
133
|
+
Also this will download 7z locally (license: http://www.7-zip.org/license.txt).
|
|
134
|
+
Click yes if you accept the terms of the several license agreements. They will then be installed automatically.
|
|
135
|
+
Or click no to cancel.", "Lacking dependency", JOptionPane::YES_NO_OPTION)
|
|
136
|
+
if answer == 1
|
|
137
|
+
p 'exiting, no mencoder...'
|
|
138
|
+
sleep 10
|
|
139
|
+
java.lang.System.exit(1)
|
|
140
|
+
end
|
|
141
|
+
vendor_cache = File.expand_path(File.dirname(__FILE__)) + "/../vendor/cache/"
|
|
142
|
+
ENV['PATH'] = ENV['PATH'] + ';' + vendor_cache + '\\..;' + vendor_cache
|
|
143
|
+
Dir.chdir(vendor_cache) do
|
|
144
|
+
Kernel.print 'downloading unzip utility...'
|
|
145
|
+
download("http://downloads.sourceforge.net/project/sevenzip/7-Zip/9.20/7za920.zip", "7za920.zip")
|
|
146
|
+
system("unzip -o 7za920.zip") # -o means "overwrite" without prompting
|
|
147
|
+
# now we have 7za.exe
|
|
148
|
+
Kernel.print 'downloading mencoder'
|
|
149
|
+
download("http://downloads.sourceforge.net/project/mplayer-win32/MPlayer%20and%20MEncoder/revision%2032492/MPlayer-rtm-svn-32492.7z", "mencoder.7z")
|
|
150
|
+
system("7za e mencoder.7z -y -omencoder")
|
|
151
|
+
Kernel.puts 'done'
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def single_edit_list_matches_dvd md5
|
|
157
|
+
return unless md5 # ignore nil searches, where it wasn't set in the .txt file
|
|
94
158
|
matching = Dir[EDL_DIR + '/*.txt'].select{|file|
|
|
95
|
-
|
|
159
|
+
EdlParser.parse_file(file)["disk_unique_id"] == md5
|
|
96
160
|
}
|
|
97
161
|
if matching.length == 1
|
|
98
162
|
file = matching[0]
|
|
99
|
-
p "selecting
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
163
|
+
p "selecting the one matching file #{file}"
|
|
164
|
+
file
|
|
165
|
+
else
|
|
166
|
+
nil
|
|
167
|
+
end
|
|
103
168
|
end
|
|
104
169
|
|
|
105
|
-
EDL_DIR = __dir__ + "/../zamples/edit_decision_lists/dvds"
|
|
170
|
+
EDL_DIR = File.expand_path(__dir__ + "/../zamples/edit_decision_lists/dvds").to_filename
|
|
171
|
+
|
|
172
|
+
def repeat_last_copy_dvd_to_hard_drive
|
|
173
|
+
generate_and_run_bat_file *Storage['last_params']
|
|
174
|
+
end
|
|
106
175
|
|
|
107
|
-
def do_copy_dvd_to_hard_drive
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if !
|
|
111
|
-
fc =
|
|
112
|
-
fc.
|
|
113
|
-
fc.
|
|
114
|
-
fc.set_current_directory(JFile.new EDL_DIR)
|
|
176
|
+
def do_copy_dvd_to_hard_drive should_prompt_for_start_and_end_times
|
|
177
|
+
drive, dvd_volume_name, md5sum = choose_dvd_drive
|
|
178
|
+
edit_list_path = single_edit_list_matches_dvd(md5sum)
|
|
179
|
+
if !edit_list_path
|
|
180
|
+
fc = FileDialog.new(self)
|
|
181
|
+
fc.set_title "Please pick a DVD Edit List File"
|
|
182
|
+
fc.set_directory EDL_DIR
|
|
115
183
|
edit_list_path = fc.go
|
|
116
184
|
end
|
|
117
|
-
descriptors =
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
185
|
+
descriptors = EdlParser.parse_file edit_list_path
|
|
186
|
+
|
|
187
|
+
dvd_title = descriptors['title'] || dvd_volume_name
|
|
188
|
+
|
|
189
|
+
fc = JFileChooser.new
|
|
190
|
+
# LODO allow for spaces in the save to filename
|
|
191
|
+
|
|
192
|
+
if should_prompt_for_start_and_end_times
|
|
193
|
+
JOptionPane.showMessageDialog(nil, "Ok, let's preview just a portion of it. \nNote that you'll want to preview a section that wholly includes an edit decision in it\n For example, if it mutes from second 1 to second 10, you'll want to play from 00:00 to 00:12 or what not.\nAlso note that the first time you preview a section of a video, it will take like 20 minutes as it sets up the video for previewing.\nSubsequent previews will be faster, though, as long as you use the same filename.", "Preview!", JOptionPane::INFORMATION_MESSAGE)
|
|
194
|
+
start_time = JOptionPane.showInputDialog("At what point in the video would you like to start your preview? (like 01:00 for starting at 1 minute)", Storage['start_time'])
|
|
195
|
+
Storage['start_time'] = start_time
|
|
196
|
+
end_time = JOptionPane.showInputDialog("At what point in the video would you like to finish your preview? (like 02:00 for ending at the 2 minute mark)", Storage['end_time'])
|
|
197
|
+
Storage['end_time'] = end_time
|
|
198
|
+
unless start_time and end_time
|
|
199
|
+
JOptionPane.showMessageDialog(nil, " Please choose start and end", "Failed", JOptionPane::ERROR_MESSAGE)
|
|
200
|
+
return
|
|
201
|
+
end
|
|
128
202
|
end
|
|
203
|
+
|
|
204
|
+
fc.set_title "Pick where to save #{dvd_title} edited to"
|
|
205
|
+
|
|
206
|
+
save_to_file_name = dvd_title + ' edited copy'
|
|
207
|
+
save_to_file_name += ' single segment' if should_prompt_for_start_and_end_times
|
|
208
|
+
save_to_file_name=save_to_file_name.gsub(' ', '_').gsub( /\W/, '') # no punctuation for now...
|
|
209
|
+
fc.setFile(DriveInfo.get_drive_with_most_space_with_slash + save_to_file_name)
|
|
210
|
+
save_to = fc.go
|
|
129
211
|
dvd_title_track = descriptors["dvd_title_track"]
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
temp_dir = Dir.tmpdir
|
|
133
|
-
temp_file = temp_dir + '/' + 'vlc.temp.xspf'
|
|
134
|
-
File.write(temp_file, bat_file_or_xspf)
|
|
135
|
-
puts bat_file_or_xspf
|
|
136
|
-
if should_save_file
|
|
137
|
-
popup = ModeLessDialog.new( "Copying to #{save_to}.\n" +
|
|
138
|
-
"Running edit list #{File.basename edit_list_path} against \n" +
|
|
139
|
-
" #{drive} (#{dvd_title})...\n" +
|
|
140
|
-
"This could take quite awhile, and will prompt you when it is done.\n" +
|
|
141
|
-
"It may also cause small popup ballon dialogs to appear.\n" +
|
|
142
|
-
"You can close this window and continue working while it runs.",
|
|
143
|
-
"OK")
|
|
144
|
-
|
|
145
|
-
# this allows our popups to still be serviced while it is running
|
|
146
|
-
Thread.new {
|
|
147
|
-
run_copy_commands bat_file_or_xspf, save_to
|
|
148
|
-
popup.dispose
|
|
149
|
-
}
|
|
150
|
-
else
|
|
151
|
-
command = "vlc \"#{temp_file.to_filename}\" vlc://quit"
|
|
152
|
-
puts 'running playlist for DVD: ', command
|
|
153
|
-
system(command) # blocks the current window while running...
|
|
154
|
-
p 'done playing DVD'
|
|
155
|
-
end
|
|
156
|
-
# LODO warn if they will overwrite a file in the end
|
|
212
|
+
generate_and_run_bat_file save_to, edit_list_path, descriptors, drive, dvd_title, start_time, end_time, dvd_title_track
|
|
157
213
|
end
|
|
158
214
|
|
|
159
|
-
|
|
160
|
-
|
|
215
|
+
def generate_and_run_bat_file save_to, edit_list_path, descriptors, drive, dvd_title, start_time, end_time, dvd_title_track
|
|
216
|
+
Storage['last_params'] = [save_to, edit_list_path, descriptors, drive, dvd_title, start_time, end_time, dvd_title_track]
|
|
217
|
+
bat_file = MencoderWrapper.get_bat_commands descriptors, drive, save_to, start_time, end_time, dvd_title_track
|
|
218
|
+
temp_dir = Dir.tmpdir
|
|
219
|
+
temp_file = temp_dir + '/vlc.temp.bat'
|
|
220
|
+
File.write(temp_file, bat_file)
|
|
221
|
+
puts 'commands located for debugging purposes at: ' + bat_file
|
|
222
|
+
popup = ModeLessDialog.new( "Copying to #{save_to}.\n" +
|
|
223
|
+
"Running #{File.basename edit_list_path} against #{drive} (#{dvd_title}).\n" +
|
|
224
|
+
"This could take quite awhile, and will prompt you when it is done.\n" +
|
|
225
|
+
"You can close this window and continue working while it runs.\n" +
|
|
226
|
+
"NB that the created file will be playable with SMplayer or VLC player.",
|
|
227
|
+
"OK")
|
|
228
|
+
|
|
229
|
+
# allow our popups to still be serviced while it is running
|
|
230
|
+
Thread.new {
|
|
231
|
+
run_create_commands bat_file, save_to
|
|
232
|
+
popup.dispose
|
|
233
|
+
}
|
|
234
|
+
# LODO warn if they will overwrite a file in the end...
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def run_create_commands batch_commands, save_to
|
|
161
238
|
@buttons.each{|b| b.set_enabled false}
|
|
162
239
|
success = true
|
|
163
240
|
lines = batch_commands.lines.to_a
|
|
@@ -166,26 +243,32 @@ module SensibleSwing
|
|
|
166
243
|
@progress_bar.set_value(10) # start at 10% always, so they can see something.
|
|
167
244
|
lines.each_with_index{|l, idx|
|
|
168
245
|
if success
|
|
169
|
-
success = system(l) unless ARGV.find{|a| a == '--test'} # this
|
|
170
|
-
|
|
246
|
+
success = system(l) unless ARGV.find{|a| a == '--test'} # this might not actually cancel out early for some reason...
|
|
247
|
+
if l =~ /@rem /
|
|
248
|
+
success = true # these fail fof some reason?
|
|
249
|
+
else
|
|
250
|
+
p 'line failed ' + l unless success
|
|
251
|
+
end
|
|
171
252
|
end
|
|
253
|
+
@progress_bar.set_value(10 + idx/total_size*90)
|
|
172
254
|
}
|
|
173
255
|
@progress_bar.visible=false
|
|
174
256
|
@buttons.each{|b| b.set_enabled true}
|
|
175
257
|
if success
|
|
176
|
-
|
|
177
|
-
|
|
258
|
+
saved_to = save_to + '.avi' # LODO pass this out?
|
|
259
|
+
JOptionPane.showMessageDialog(nil, " Done--you may now watch file #{saved_to} in SMPlayer or VLC player", "Done!", JOptionPane::INFORMATION_MESSAGE)
|
|
260
|
+
show_file = "explorer /e,/select,\"#{File.expand_path(saved_to).to_filename}\""
|
|
178
261
|
system show_file
|
|
179
|
-
self.close
|
|
262
|
+
#self.close # ?
|
|
180
263
|
else
|
|
181
264
|
JOptionPane.showMessageDialog(nil, " Failed--please examine screen output and report back!", "Failed", JOptionPane::ERROR_MESSAGE)
|
|
182
265
|
end
|
|
183
266
|
end
|
|
184
267
|
|
|
185
|
-
# returns e:\,
|
|
268
|
+
# returns e:\, volume, md5sum
|
|
186
269
|
def choose_dvd_drive
|
|
187
270
|
opticals = DriveInfo.get_dvd_drives_as_win32ole
|
|
188
|
-
names = opticals.map{|d| d.Name + "\\" + " (" + (d.VolumeName || '
|
|
271
|
+
names = opticals.map{|d| d.Name + "\\" + " (" + (d.VolumeName || 'please insert DVD before proceeding if you want to use this drive') + ")"}
|
|
189
272
|
|
|
190
273
|
if opticals.length != 1
|
|
191
274
|
dialog = GetDisk.new(self, names)
|
|
@@ -194,13 +277,14 @@ module SensibleSwing
|
|
|
194
277
|
selected_idx = dialog.selected_idx
|
|
195
278
|
else
|
|
196
279
|
selected_idx = 0
|
|
197
|
-
p 'selecting only disk drive ' + names[0]
|
|
198
|
-
end
|
|
280
|
+
p 'selecting user\'s only disk drive ' + names[0]
|
|
281
|
+
end
|
|
282
|
+
|
|
199
283
|
if selected_idx
|
|
200
284
|
disk = opticals[selected_idx]
|
|
201
|
-
return names[selected_idx][0..2], opticals[selected_idx].VolumeName
|
|
285
|
+
return names[selected_idx][0..2], opticals[selected_idx].VolumeName, DriveInfo.md5sum_disk(opticals[selected_idx].Name)
|
|
202
286
|
else
|
|
203
|
-
puts 'did not select a drive'
|
|
287
|
+
puts 'did not select a drive...exiting'
|
|
204
288
|
java.lang.System.exit 1
|
|
205
289
|
end
|
|
206
290
|
end
|
|
@@ -229,9 +313,7 @@ module SensibleSwing
|
|
|
229
313
|
add box
|
|
230
314
|
pack
|
|
231
315
|
end
|
|
232
|
-
|
|
233
316
|
end
|
|
234
|
-
|
|
235
317
|
end
|
|
236
318
|
|
|
237
319
|
if $0 == __FILE__
|