edl 0.1.5 → 0.1.6
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.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +3 -10
- data/Rakefile +10 -22
- data/edl.gemspec +32 -67
- data/lib/edl.rb +115 -116
- data/lib/edl/cutter.rb +15 -12
- data/lib/edl/event.rb +42 -32
- data/lib/edl/grabber.rb +10 -8
- data/lib/edl/linebreak_magician.rb +3 -1
- data/lib/edl/parser.rb +24 -19
- data/lib/edl/timewarp.rb +10 -9
- data/lib/edl/transition.rb +5 -5
- data/lib/edl/version.rb +5 -0
- metadata +20 -71
- data/test/samples/45S_SAMPLE.EDL +0 -48
- data/test/samples/FCP_REVERSE.EDL +0 -9
- data/test/samples/KEY_TRANSITION.EDL +0 -9
- data/test/samples/PLATES.EDL +0 -1
- data/test/samples/REEL_IS_CLIP.txt +0 -8
- data/test/samples/REVERSE.EDL +0 -3
- data/test/samples/SIMPLE_DISSOLVE.EDL +0 -9
- data/test/samples/SPEEDUP_AND_FADEOUT.EDL +0 -11
- data/test/samples/SPEEDUP_REVERSE_AND_FADEOUT.EDL +0 -11
- data/test/samples/SPLICEME.EDL +0 -5
- data/test/samples/TIMEWARP.EDL +0 -5
- data/test/samples/TIMEWARP_HALF.EDL +0 -5
- data/test/samples/TRAILER_EDL.edl +0 -0
- data/test/samples/edl_mixed_line_endings.edl +0 -12
- data/test/test_edl.rb +0 -721
data/test/samples/45S_SAMPLE.EDL
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
TITLE: EDIT 15 [14-11-08] 45 SEC EDL
|
2
|
-
001 106771 V C 04:00:57:05 04:00:58:10 10:00:00:00 10:00:01:05
|
3
|
-
002 106771 V C 04:03:44:06 04:03:45:08 10:00:01:05 10:00:02:07
|
4
|
-
003 106770 V C 00:06:55:13 00:06:57:01 10:00:02:07 10:00:03:20
|
5
|
-
004 106771 V C 03:16:35:05 03:16:36:05 10:00:03:20 10:00:04:20
|
6
|
-
005 106770 V C 00:13:03:17 00:13:04:20 10:00:04:20 10:00:05:23
|
7
|
-
006 106771 V C 03:11:43:02 03:11:44:04 10:00:05:23 10:00:07:00
|
8
|
-
007 106857 V C 07:18:40:24 07:18:41:17 10:00:07:00 10:00:07:18
|
9
|
-
008 106857 V C 07:22:25:19 07:22:27:02 10:00:07:18 10:00:09:01
|
10
|
-
009 106863 V C 13:12:46:23 13:12:48:11 10:00:09:01 10:00:10:14
|
11
|
-
010 106857 V C 08:00:32:00 08:00:33:10 10:00:10:14 10:00:11:24
|
12
|
-
011 106857 V C 08:05:36:18 08:05:37:19 10:00:11:24 10:00:13:00
|
13
|
-
012 106857 V C 07:04:47:06 07:04:50:13 10:00:13:00 10:00:16:07
|
14
|
-
M2 106857 012.5 07:04:47:06
|
15
|
-
013 106863 V C 10:11:06:07 10:11:08:00 10:00:16:07 10:00:18:00
|
16
|
-
014 106863 V C 10:09:16:21 10:09:18:11 10:00:18:00 10:00:19:15
|
17
|
-
015 106857 V C 07:06:02:17 07:06:04:07 10:00:19:15 10:00:21:05
|
18
|
-
016 106857 V C 09:07:18:07 09:07:20:16 10:00:21:05 10:00:23:14
|
19
|
-
M2 106857 002.5 09:07:18:07
|
20
|
-
017 106863 V C 11:02:46:06 11:02:47:06 10:00:23:14 10:00:24:14
|
21
|
-
018 106863 V C 11:10:17:04 11:10:17:20 10:00:24:14 10:00:25:05
|
22
|
-
019 106863 V C 12:06:09:18 12:06:10:16 10:00:25:05 10:00:26:03
|
23
|
-
020 106863 V C 12:10:49:17 12:10:51:02 10:00:26:03 10:00:27:13
|
24
|
-
021 106815 V C 05:01:22:21 05:01:24:05 10:00:27:13 10:00:28:22
|
25
|
-
022 106815 V C 06:01:35:03 06:01:36:18 10:00:28:22 10:00:30:12
|
26
|
-
023 106815 V C 05:13:38:19 05:13:40:10 10:00:30:12 10:00:32:03
|
27
|
-
M2 106815 -025.0 05:13:38:19
|
28
|
-
024 106857 V C 09:13:03:09 09:13:05:11 10:00:32:03 10:00:34:05
|
29
|
-
M2 106857 -025.0 09:13:03:09
|
30
|
-
025 106857 V C 09:13:01:07 09:13:01:07 10:00:34:05 10:00:34:05
|
31
|
-
025 106771 V D 022 03:11:55:00 03:11:56:17 10:00:34:05 10:00:35:22
|
32
|
-
M2 106857 -025.0 09:13:01:07
|
33
|
-
* BLEND, DISSOLVE
|
34
|
-
026 106771 V C 03:11:56:17 03:11:56:17 10:00:35:22 10:00:35:22
|
35
|
-
026 106771 V D 012 03:06:30:09 03:06:31:19 10:00:35:22 10:00:37:07
|
36
|
-
* BLEND, DISSOLVE
|
37
|
-
027 106863 V C 13:15:29:20 13:15:31:02 10:00:37:07 10:00:38:14
|
38
|
-
028 106771 V C 03:15:40:22 03:15:42:11 10:00:38:14 10:00:40:03
|
39
|
-
029 106863 V C 13:15:51:02 13:15:52:08 10:00:40:03 10:00:41:09
|
40
|
-
030 106863 V C 13:15:52:08 13:15:52:08 10:00:41:09 10:00:41:09
|
41
|
-
030 BL V D 032 00:00:00:00 00:00:01:07 10:00:41:09 10:00:42:16
|
42
|
-
* BLEND, DISSOLVE
|
43
|
-
>>> SOURCE 106770 106770 4919975f.793b8d33
|
44
|
-
>>> SOURCE 106771 106771 4919a179.79630563
|
45
|
-
>>> SOURCE 106815 106815 4919b521.79afcb70
|
46
|
-
>>> SOURCE 106857 106857 4919cbb9.7a080d9d
|
47
|
-
>>> SOURCE 106863 106863 4919e0c3.7a5a3cfc
|
48
|
-
|
@@ -1,9 +0,0 @@
|
|
1
|
-
TITLE: FOR_TEST
|
2
|
-
FCM: DROP FRAME
|
3
|
-
|
4
|
-
002 AX V K B 00:01:06:06 00:01:08:03 01:00:04:10 01:00:06:07
|
5
|
-
002 AX V K 000 00:00:03:08 00:00:03:08 01:00:04:10 01:00:04:10
|
6
|
-
* FROM CLIP NAME: foobarz_0118_023-APPLE PRORES WITH ALPHA.MOV
|
7
|
-
* COMMENT:
|
8
|
-
* KEY CLIP NAME: foobarz_0118_026-APPLE PRORES WITH ALPHA.MOV
|
9
|
-
* CLIP FILTER: COLOR CORRECTOR 3-WAY
|
data/test/samples/PLATES.EDL
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
TITLE: PLATES.
|
@@ -1,8 +0,0 @@
|
|
1
|
-
0001 KASS1 A1234V C 00:00:00:00 00:00:12:24 10:00:00:00 10:00:12:24
|
2
|
-
* REEL RC100009 IS CLIP 28661.mov
|
3
|
-
0002 KASS1 A1234V C 00:00:00:00 00:00:13:03 10:00:12:24 10:00:26:02
|
4
|
-
* REEL RC100003 IS CLIP 28655.mov
|
5
|
-
0003 KASS1 A1234V C 00:00:00:00 00:00:15:06 10:00:26:02 10:00:41:08
|
6
|
-
* REEL RC100005 IS CLIP 28657.mov
|
7
|
-
0004 KASS1 A1234V C 00:00:00:00 00:00:16:06 10:00:41:08 10:00:57:14
|
8
|
-
* REEL RC100010 IS CLIP 28662.mov
|
data/test/samples/REVERSE.EDL
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
TITLE: SPEEDUP_AND_FADEOUT
|
2
|
-
FCM: NON-DROP FRAME
|
3
|
-
|
4
|
-
001 FOO V C 01:00:00:00 01:00:27:14 01:00:00:00 01:00:27:14
|
5
|
-
001 BL V D 025 00:00:00:00 00:00:01:00 01:00:27:14 01:00:28:14
|
6
|
-
* EFFECT NAME: CROSS DISSOLVE
|
7
|
-
* FROM CLIP NAME: BARS_40S.MOV
|
8
|
-
* COMMENT:
|
9
|
-
M2 FOO 035.0 01:00:00:00
|
10
|
-
|
11
|
-
|
@@ -1,11 +0,0 @@
|
|
1
|
-
TITLE: TESTREV
|
2
|
-
FCM: NON-DROP FRAME
|
3
|
-
|
4
|
-
001 FOO V C 01:00:39:23 01:01:07:12 01:00:00:00 01:00:27:14
|
5
|
-
001 BL V D 025 00:00:00:00 00:00:01:00 01:00:27:14 01:00:28:14
|
6
|
-
* EFFECT NAME: CROSS DISSOLVE
|
7
|
-
* FROM CLIP NAME: BARS_40S.MOV
|
8
|
-
* COMMENT:
|
9
|
-
M2 FOO -035.0 01:00:39:23
|
10
|
-
|
11
|
-
|
data/test/samples/SPLICEME.EDL
DELETED
data/test/samples/TIMEWARP.EDL
DELETED
Binary file
|
data/test/test_edl.rb
DELETED
@@ -1,721 +0,0 @@
|
|
1
|
-
require "rubygems"
|
2
|
-
require "bundler"
|
3
|
-
Bundler.require(:default, :development)
|
4
|
-
require 'flexmock/test_unit'
|
5
|
-
|
6
|
-
|
7
|
-
require File.dirname(__FILE__) + '/../lib/edl'
|
8
|
-
require File.dirname(__FILE__) + '/../lib/edl/cutter'
|
9
|
-
require File.dirname(__FILE__) + '/../lib/edl/grabber'
|
10
|
-
|
11
|
-
TRAILER_EDL = File.dirname(__FILE__) + '/samples/TRAILER_EDL.edl'
|
12
|
-
SIMPLE_DISSOLVE = File.dirname(__FILE__) + '/samples/SIMPLE_DISSOLVE.EDL'
|
13
|
-
SPLICEME = File.dirname(__FILE__) + '/samples/SPLICEME.EDL'
|
14
|
-
SIMPLE_TIMEWARP = File.dirname(__FILE__) + '/samples/TIMEWARP.EDL'
|
15
|
-
SLOMO_TIMEWARP = File.dirname(__FILE__) + '/samples/TIMEWARP_HALF.EDL'
|
16
|
-
FORTY_FIVER = File.dirname(__FILE__) + '/samples/45S_SAMPLE.EDL'
|
17
|
-
AVID_REVERSE = File.dirname(__FILE__) + '/samples/REVERSE.EDL'
|
18
|
-
SPEEDUP_AND_FADEOUT = File.dirname(__FILE__) + '/samples/SPEEDUP_AND_FADEOUT.EDL'
|
19
|
-
SPEEDUP_REVERSE_AND_FADEOUT = File.dirname(__FILE__) + '/samples/SPEEDUP_REVERSE_AND_FADEOUT.EDL'
|
20
|
-
FCP_REVERSE = File.dirname(__FILE__) + '/samples/FCP_REVERSE.EDL'
|
21
|
-
PLATES = File.dirname(__FILE__) + '/samples/PLATES.EDL'
|
22
|
-
KEY = File.dirname(__FILE__) + '/samples/KEY_TRANSITION.EDL'
|
23
|
-
CLIP_NAMES = File.dirname(__FILE__) + '/samples/REEL_IS_CLIP.txt'
|
24
|
-
MIXED_LINEBREAKS = File.dirname(__FILE__) + '/samples/edl_mixed_line_endings.edl'
|
25
|
-
|
26
|
-
class String
|
27
|
-
def tc(fps = Timecode::DEFAULT_FPS)
|
28
|
-
Timecode.parse(self, fps)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class EDLTest < Test::Unit::TestCase
|
33
|
-
|
34
|
-
def assert_zero(v, message = "Should be zero")
|
35
|
-
assert v.zero?, message
|
36
|
-
end
|
37
|
-
|
38
|
-
context "An Event" do
|
39
|
-
should "support hash initialization" do
|
40
|
-
evt = EDL::Event.new(:src_start_tc => "01:00:00:00".tc)
|
41
|
-
assert_equal "01:00:00:00".tc, evt.src_start_tc
|
42
|
-
end
|
43
|
-
|
44
|
-
should "support block initialization" do
|
45
|
-
evt = EDL::Event.new do | e |
|
46
|
-
e.src_start_tc = "01:00:00:04".tc
|
47
|
-
end
|
48
|
-
assert_equal "01:00:00:04".tc, evt.src_start_tc
|
49
|
-
end
|
50
|
-
|
51
|
-
should "respond to ends_with_transition? with false if outgoing_transition_duration is zero" do
|
52
|
-
evt = EDL::Event.new
|
53
|
-
evt.outgoing_transition_duration = 0
|
54
|
-
assert !evt.ends_with_transition?
|
55
|
-
end
|
56
|
-
|
57
|
-
should "respond to ends_with_transition? with true if outgoing_transition_duration set above zero" do
|
58
|
-
evt = EDL::Event.new
|
59
|
-
evt.outgoing_transition_duration = 24
|
60
|
-
assert evt.ends_with_transition?
|
61
|
-
end
|
62
|
-
|
63
|
-
should "respond to has_timewarp? with false if no timewarp assigned" do
|
64
|
-
evt = EDL::Event.new(:timewarp => nil)
|
65
|
-
assert !evt.has_timewarp?
|
66
|
-
end
|
67
|
-
|
68
|
-
should "respond to has_timewarp? with true if a timewarp is assigned" do
|
69
|
-
evt = EDL::Event.new(:timewarp => true)
|
70
|
-
assert evt.has_timewarp?
|
71
|
-
end
|
72
|
-
|
73
|
-
should "report rec_length as a difference of record timecodes" do
|
74
|
-
evt = EDL::Event.new(:rec_start_tc => "1h".tc, :rec_end_tc => "1h 10s 2f".tc )
|
75
|
-
assert_equal "10s 2f".tc.to_i, evt.rec_length
|
76
|
-
end
|
77
|
-
|
78
|
-
should "report rec_length_with_transition as a difference of record timecodes if no transition set" do
|
79
|
-
evt = EDL::Event.new(:rec_start_tc => "1h".tc, :rec_end_tc => "1h 10s 2f".tc, :outgoing_transition_duration => 0)
|
80
|
-
assert_equal "10s 2f".tc.to_i, evt.rec_length_with_transition
|
81
|
-
end
|
82
|
-
|
83
|
-
should "add transition length to rec_length_with_transition if a transition is set" do
|
84
|
-
evt = EDL::Event.new(:rec_start_tc => "1h".tc, :rec_end_tc => "1h 10s 2f".tc, :outgoing_transition_duration => 10)
|
85
|
-
assert_equal "10s 2f".tc.to_i + 10, evt.rec_length_with_transition
|
86
|
-
end
|
87
|
-
|
88
|
-
should "return a default array for comments" do
|
89
|
-
assert_kind_of Enumerable, EDL::Event.new.comments
|
90
|
-
end
|
91
|
-
|
92
|
-
should "respond false to has_transition? if incoming transition is set" do
|
93
|
-
assert !EDL::Event.new(:transition => nil).has_transition?
|
94
|
-
end
|
95
|
-
|
96
|
-
should "respond true to has_transition? if incoming transition is set" do
|
97
|
-
assert EDL::Event.new(:transition => true).has_transition?
|
98
|
-
end
|
99
|
-
|
100
|
-
should "respond true to black? if reel is BL" do
|
101
|
-
assert EDL::Event.new(:reel => "BL").black?
|
102
|
-
assert !EDL::Event.new(:reel => "001").black?
|
103
|
-
end
|
104
|
-
|
105
|
-
should "respond true to generator? if reel is BL or AX" do
|
106
|
-
assert EDL::Event.new(:reel => "BL").generator?
|
107
|
-
assert EDL::Event.new(:reel => "AX").generator?
|
108
|
-
assert !EDL::Event.new(:reel => "001").generator?
|
109
|
-
end
|
110
|
-
|
111
|
-
should "report src_length as rec_length_with_transition" do
|
112
|
-
e = EDL::Event.new(:rec_start_tc => "2h".tc, :rec_end_tc => "2h 2s".tc)
|
113
|
-
assert_equal "2s".tc.to_i, e.src_length
|
114
|
-
end
|
115
|
-
|
116
|
-
should "support line_number" do
|
117
|
-
assert_nil EDL::Event.new.line_number
|
118
|
-
assert_equal 3, EDL::Event.new(:line_number => 3).line_number
|
119
|
-
end
|
120
|
-
|
121
|
-
should "support capture_length as an alias to src_length" do
|
122
|
-
tw = flexmock
|
123
|
-
tw.should_receive(:actual_length_of_source).and_return(:something)
|
124
|
-
e = EDL::Event.new(:timewarp => tw)
|
125
|
-
assert_equal e.capture_length, e.src_length
|
126
|
-
end
|
127
|
-
|
128
|
-
should "delegate src_length to the timewarp if it is there" do
|
129
|
-
tw = flexmock
|
130
|
-
tw.should_receive(:actual_length_of_source).and_return(:something).once
|
131
|
-
e = EDL::Event.new(:timewarp => tw)
|
132
|
-
assert_equal :something, e.src_length
|
133
|
-
end
|
134
|
-
|
135
|
-
should "report reverse? and reversed? based on the timewarp" do
|
136
|
-
e = EDL::Event.new(:timewarp => nil)
|
137
|
-
assert !e.reverse?
|
138
|
-
assert !e.reversed?
|
139
|
-
|
140
|
-
tw = flexmock
|
141
|
-
tw.should_receive(:reverse?).and_return(true)
|
142
|
-
|
143
|
-
e = EDL::Event.new(:timewarp => tw)
|
144
|
-
assert e.reverse?
|
145
|
-
assert e.reversed?
|
146
|
-
end
|
147
|
-
|
148
|
-
should "report speed as 100 percent without a timewarp" do
|
149
|
-
e = EDL::Event.new
|
150
|
-
assert_equal 100.0, e.speed
|
151
|
-
end
|
152
|
-
|
153
|
-
should "consult the timewarp for speed" do
|
154
|
-
tw = flexmock
|
155
|
-
tw.should_receive(:speed).and_return(:something)
|
156
|
-
|
157
|
-
e = EDL::Event.new(:timewarp => tw)
|
158
|
-
assert_equal :something, e.speed
|
159
|
-
end
|
160
|
-
|
161
|
-
should "report false for starts_with_transition? if transision is nil" do
|
162
|
-
assert !EDL::Event.new.starts_with_transition?
|
163
|
-
end
|
164
|
-
|
165
|
-
should "report zero for incoming_transition_duration if transision is nil" do
|
166
|
-
assert_zero EDL::Event.new.incoming_transition_duration
|
167
|
-
end
|
168
|
-
|
169
|
-
should "report true for starts_with_transition? if transision is not nil" do
|
170
|
-
e = EDL::Event.new :transition => true
|
171
|
-
assert e.starts_with_transition?
|
172
|
-
end
|
173
|
-
|
174
|
-
should "consult the transition for incoming_transition_duration if it's present" do
|
175
|
-
tr = flexmock
|
176
|
-
tr.should_receive(:duration).and_return(:something)
|
177
|
-
|
178
|
-
e = EDL::Event.new(:transition => tr)
|
179
|
-
assert_equal :something, e.incoming_transition_duration
|
180
|
-
end
|
181
|
-
|
182
|
-
should "report capture_from_tc as the source start without a timewarp" do
|
183
|
-
e = EDL::Event.new(:src_start_tc => "1h".tc)
|
184
|
-
assert_equal "1h".tc, e.capture_from_tc
|
185
|
-
end
|
186
|
-
|
187
|
-
should "consult the timewarp for capture_from_tc if a timewarp is there" do
|
188
|
-
tw = flexmock
|
189
|
-
tw.should_receive(:source_used_from).and_return(:something)
|
190
|
-
|
191
|
-
e = EDL::Event.new(:timewarp => tw)
|
192
|
-
assert_equal :something, e.capture_from_tc
|
193
|
-
end
|
194
|
-
|
195
|
-
should "report capture_to_tc as record length plus transition when no timewarp present" do
|
196
|
-
e = EDL::Event.new(:src_end_tc => "1h 10s".tc, :outgoing_transition_duration => 2 )
|
197
|
-
assert_equal "1h 10s 2f".tc, e.capture_to_tc
|
198
|
-
end
|
199
|
-
|
200
|
-
should "report capture_to_and_including_tc as record length plus transition when no timewarp present" do
|
201
|
-
e = EDL::Event.new(:src_end_tc => "1h 10s".tc, :outgoing_transition_duration => 2 )
|
202
|
-
assert_equal "1h 10s 1f".tc, e.capture_to_and_including_tc
|
203
|
-
end
|
204
|
-
|
205
|
-
should "consult the timewarp for capture_to_tc if timewarp is present" do
|
206
|
-
tw = flexmock
|
207
|
-
tw.should_receive(:source_used_upto).and_return(:something)
|
208
|
-
|
209
|
-
e = EDL::Event.new(:timewarp => tw)
|
210
|
-
assert_equal :something, e.capture_to_tc
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
context "A Parser" do
|
215
|
-
should "store the passed framerate" do
|
216
|
-
p = EDL::Parser.new(45)
|
217
|
-
assert_equal 45, p.fps
|
218
|
-
end
|
219
|
-
|
220
|
-
should "return matchers tuned with the passed framerate" do
|
221
|
-
p = EDL::Parser.new(30)
|
222
|
-
matchers = p.get_matchers
|
223
|
-
event_matcher = matchers.find{|e| e.is_a?(EDL::EventMatcher) }
|
224
|
-
assert_equal 30, event_matcher.fps
|
225
|
-
end
|
226
|
-
|
227
|
-
should "create a Timecode from stringified elements" do
|
228
|
-
elems = ["08", "04", "24", "24"]
|
229
|
-
assert_nothing_raised do
|
230
|
-
@tc = EDL::Parser.timecode_from_line_elements(elems, 30)
|
231
|
-
end
|
232
|
-
|
233
|
-
assert_kind_of Timecode, @tc
|
234
|
-
assert_equal "08:04:24:24".tc(30), @tc
|
235
|
-
|
236
|
-
assert_zero elems.length
|
237
|
-
end
|
238
|
-
|
239
|
-
should "parse from a String" do
|
240
|
-
p = EDL::Parser.new
|
241
|
-
assert_nothing_raised do
|
242
|
-
@edl = p.parse File.read(SIMPLE_DISSOLVE)
|
243
|
-
end
|
244
|
-
|
245
|
-
assert_kind_of EDL::List, @edl
|
246
|
-
assert_equal 2, @edl.length
|
247
|
-
end
|
248
|
-
|
249
|
-
should "parse from a File/IOish" do
|
250
|
-
p = EDL::Parser.new
|
251
|
-
assert_nothing_raised do
|
252
|
-
@edl = p.parse File.open(SIMPLE_DISSOLVE)
|
253
|
-
end
|
254
|
-
|
255
|
-
assert_kind_of EDL::List, @edl
|
256
|
-
assert_equal 2, @edl.length
|
257
|
-
end
|
258
|
-
|
259
|
-
should "properly parse a dissolve" do
|
260
|
-
# TODO: reformulate
|
261
|
-
p = EDL::Parser.new
|
262
|
-
@edl = p.parse File.open(SIMPLE_DISSOLVE)
|
263
|
-
|
264
|
-
first, second = @edl
|
265
|
-
|
266
|
-
assert_kind_of EDL::Event, first
|
267
|
-
assert_kind_of EDL::Event, second
|
268
|
-
|
269
|
-
assert second.has_transition?
|
270
|
-
assert first.ends_with_transition?
|
271
|
-
assert !second.ends_with_transition?
|
272
|
-
|
273
|
-
no_trans = @edl.without_transitions
|
274
|
-
|
275
|
-
assert_equal 2, no_trans.length
|
276
|
-
target_tc = (Timecode.parse('01:00:00:00') + 43)
|
277
|
-
assert_equal target_tc, no_trans[0].rec_end_tc,
|
278
|
-
"The incoming clip should have been extended by the length of the dissolve"
|
279
|
-
|
280
|
-
target_tc = Timecode.parse('01:00:00:00')
|
281
|
-
assert_equal target_tc, no_trans[1].rec_start_tc
|
282
|
-
"The outgoing clip should have been left in place"
|
283
|
-
end
|
284
|
-
|
285
|
-
should "return a spliced EDL if the sources allow" do
|
286
|
-
@spliced = EDL::Parser.new.parse(File.open(SPLICEME)).spliced
|
287
|
-
|
288
|
-
assert_equal 1, @spliced.length
|
289
|
-
evt = @spliced[0]
|
290
|
-
|
291
|
-
assert_equal '06:42:50:18'.tc, evt.src_start_tc
|
292
|
-
assert_equal '06:42:52:16'.tc, evt.src_end_tc
|
293
|
-
end
|
294
|
-
|
295
|
-
should "not apply any Matchers if a match is found" do
|
296
|
-
p = EDL::Parser.new
|
297
|
-
m1 = flexmock
|
298
|
-
m1.should_receive(:matches?).with("plop").once.and_return(true)
|
299
|
-
m1.should_receive(:apply).once
|
300
|
-
|
301
|
-
flexmock(p).should_receive(:get_matchers).once.and_return([m1, m1])
|
302
|
-
result = p.parse("plop")
|
303
|
-
assert result.empty?
|
304
|
-
end
|
305
|
-
|
306
|
-
should "register line numbers of the detected events" do
|
307
|
-
p = EDL::Parser.new
|
308
|
-
events = p.parse(File.open(SPLICEME))
|
309
|
-
|
310
|
-
assert_equal 4, events[0].line_number
|
311
|
-
assert_equal 5, events[1].line_number
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
context "A TimewarpMatcher" do
|
316
|
-
|
317
|
-
should "not create any extra events when used within a Parser" do
|
318
|
-
@edl = EDL::Parser.new.parse(File.open(SIMPLE_TIMEWARP))
|
319
|
-
assert_equal 1, @edl.length
|
320
|
-
end
|
321
|
-
|
322
|
-
should "properly describe a speedup" do
|
323
|
-
clip = EDL::Parser.new.parse(File.open(SIMPLE_TIMEWARP)).pop
|
324
|
-
|
325
|
-
tw = clip.timewarp
|
326
|
-
|
327
|
-
assert_kind_of EDL::Timewarp, tw
|
328
|
-
assert_operator tw.source_used_upto, :>, clip.src_end_tc
|
329
|
-
|
330
|
-
assert_equal clip.src_start_tc, tw.source_used_from
|
331
|
-
assert_equal 124, clip.timewarp.actual_length_of_source
|
332
|
-
assert !tw.reverse?
|
333
|
-
end
|
334
|
-
|
335
|
-
should "properly describe a slomo" do
|
336
|
-
clip = EDL::Parser.new.parse(File.open(SLOMO_TIMEWARP)).pop
|
337
|
-
|
338
|
-
assert_equal 10, clip.rec_length
|
339
|
-
assert_equal 5, clip.src_length
|
340
|
-
|
341
|
-
tw = clip.timewarp
|
342
|
-
|
343
|
-
assert_operator tw.source_used_upto, :<, clip.src_end_tc
|
344
|
-
|
345
|
-
assert_equal "03:03:19:24".tc, tw.source_used_upto
|
346
|
-
|
347
|
-
assert_equal 50, tw.speed_in_percent.to_i
|
348
|
-
assert_equal 5, tw.actual_length_of_source
|
349
|
-
assert !tw.reverse?
|
350
|
-
end
|
351
|
-
|
352
|
-
end
|
353
|
-
|
354
|
-
context "A reverse timewarp EDL coming from Avid" do
|
355
|
-
|
356
|
-
should "be parsed properly" do
|
357
|
-
|
358
|
-
clip = EDL::Parser.new.parse(File.open(AVID_REVERSE)).pop
|
359
|
-
|
360
|
-
assert_equal 52, clip.rec_length
|
361
|
-
|
362
|
-
tw = clip.timewarp
|
363
|
-
|
364
|
-
assert_equal -25, tw.actual_framerate.to_i
|
365
|
-
assert tw.reverse?
|
366
|
-
assert_equal 52, tw.actual_length_of_source
|
367
|
-
|
368
|
-
assert_equal 52, clip.src_length, "The src length should be computed the same as its just a reverse"
|
369
|
-
assert_equal -100.0, clip.timewarp.speed
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
context "EDL with clip reels in comments" do
|
374
|
-
should "parse clip names into the reel field" do
|
375
|
-
clips = EDL::Parser.new.parse(File.open(CLIP_NAMES))
|
376
|
-
# flunk "This still has to be finalized"
|
377
|
-
end
|
378
|
-
end
|
379
|
-
|
380
|
-
context "A Final Cut Pro originating reverse" do
|
381
|
-
|
382
|
-
should "be interpreted properly" do
|
383
|
-
e = EDL::Parser.new.parse(File.open(FCP_REVERSE)).pop
|
384
|
-
|
385
|
-
assert_equal 1000, e.rec_length
|
386
|
-
assert_equal 1000, e.src_length
|
387
|
-
|
388
|
-
assert_equal "1h".tc, e.rec_start_tc
|
389
|
-
assert_equal "1h 40s".tc, e.rec_end_tc
|
390
|
-
|
391
|
-
assert e.reverse?
|
392
|
-
assert_not_nil e.timewarp
|
393
|
-
|
394
|
-
tw = e.timewarp
|
395
|
-
|
396
|
-
assert_equal -100, tw.speed
|
397
|
-
assert_equal e.speed, tw.speed
|
398
|
-
|
399
|
-
assert_equal "1h".tc, tw.source_used_from
|
400
|
-
assert_equal "1h 40s".tc, tw.source_used_upto
|
401
|
-
end
|
402
|
-
end
|
403
|
-
|
404
|
-
# context "An edit with keyer transition" do
|
405
|
-
# should "parse correctly" do
|
406
|
-
# events = EDL::Parser.new.parse(File.open(KEY))
|
407
|
-
# assert_equal 2, events.length
|
408
|
-
# flunk "Key transition processing is not reliable yet - no reference"
|
409
|
-
# end
|
410
|
-
# end
|
411
|
-
|
412
|
-
context "EventMatcher" do
|
413
|
-
|
414
|
-
EVT_PATTERNS = [
|
415
|
-
'020 008C V C 08:04:24:24 08:04:25:19 01:00:25:22 01:00:26:17',
|
416
|
-
'021 009 V C 00:39:04:21 00:39:05:09 01:00:26:17 01:00:27:05',
|
417
|
-
'022 008C V C 08:08:01:23 08:08:02:18 01:00:27:05 01:00:28:00',
|
418
|
-
'023 008C V C 08:07:30:02 08:07:30:21 01:00:28:00 01:00:28:19',
|
419
|
-
'024 AX V C 00:00:00:00 00:00:01:00 01:00:28:19 01:00:29:19',
|
420
|
-
'025 BL V C 00:00:00:00 00:00:00:00 01:00:29:19 01:00:29:19',
|
421
|
-
'025 GEN V D 025 00:00:55:10 00:00:58:11 01:00:29:19 01:00:32:20',
|
422
|
-
'002 REDACTED V C 03:09:00:13 03:09:55:19 01:00:43:12 01:01:38:18',
|
423
|
-
# '0004 KASS1 A1234V C 00:00:00:00 00:00:16:06 10:00:41:08 10:00:57:14'
|
424
|
-
]
|
425
|
-
|
426
|
-
# should 'handle the event with multiple audio tracks' do
|
427
|
-
# m = EDL::EventMatcher.new(25)
|
428
|
-
#
|
429
|
-
# clip = m.apply([],
|
430
|
-
# '0004 KASS1 A1234V C 00:00:00:00 00:00:16:06 10:00:41:08 10:00:57:14'
|
431
|
-
# )
|
432
|
-
# assert_kind_of EDL::Event, clip
|
433
|
-
# assert_equal "A1234", clip.track
|
434
|
-
# end
|
435
|
-
|
436
|
-
should "produce an Event" do
|
437
|
-
m = EDL::EventMatcher.new(25)
|
438
|
-
|
439
|
-
clip = m.apply([],
|
440
|
-
'020 008C V C 08:04:24:24 08:04:25:19 01:00:25:22 01:00:26:17'
|
441
|
-
)
|
442
|
-
|
443
|
-
assert_kind_of EDL::Event, clip
|
444
|
-
|
445
|
-
assert_equal "020", clip.num
|
446
|
-
assert_equal "008C", clip.reel
|
447
|
-
assert_equal "V", clip.track
|
448
|
-
|
449
|
-
assert_equal '08:04:24:24'.tc, clip.src_start_tc
|
450
|
-
|
451
|
-
assert_equal '08:04:25:19'.tc, clip.src_end_tc
|
452
|
-
assert_equal '01:00:25:22'.tc, clip.rec_start_tc
|
453
|
-
assert_equal '01:00:26:17'.tc, clip.rec_end_tc
|
454
|
-
|
455
|
-
assert_nil clip.transition
|
456
|
-
assert_nil clip.timewarp
|
457
|
-
assert_zero clip.outgoing_transition_duration
|
458
|
-
end
|
459
|
-
|
460
|
-
should "produce an Event with dissolve" do
|
461
|
-
m = EDL::EventMatcher.new(25)
|
462
|
-
|
463
|
-
dissolve = m.apply([],
|
464
|
-
'025 GEN V D 025 00:00:55:10 00:00:58:11 01:00:29:19 01:00:32:20'
|
465
|
-
)
|
466
|
-
assert_kind_of EDL::Event, dissolve
|
467
|
-
|
468
|
-
assert_equal "025", dissolve.num
|
469
|
-
assert_equal 'GEN', dissolve.reel
|
470
|
-
assert_equal 'V', dissolve.track
|
471
|
-
assert dissolve.has_transition?
|
472
|
-
|
473
|
-
tr = dissolve.transition
|
474
|
-
|
475
|
-
assert_kind_of EDL::Dissolve, tr
|
476
|
-
assert_equal 25, tr.duration
|
477
|
-
end
|
478
|
-
|
479
|
-
should "produce a vanilla Event with proper source length" do
|
480
|
-
# This one has EXACTLY 4 frames of source
|
481
|
-
m = EDL::EventMatcher.new(25)
|
482
|
-
clip = m.apply([], '001 GEN V C 00:01:00:00 00:01:00:04 01:00:00:00 01:00:00:04')
|
483
|
-
assert_kind_of EDL::Event, clip
|
484
|
-
assert_equal 4, clip.src_length
|
485
|
-
end
|
486
|
-
|
487
|
-
should "set flag on the previous event in the stack when a dissolve is encountered" do
|
488
|
-
m = EDL::EventMatcher.new(25)
|
489
|
-
previous_evt = flexmock
|
490
|
-
previous_evt.should_receive(:outgoing_transition_duration=).with(25).once
|
491
|
-
|
492
|
-
m.apply([previous_evt],
|
493
|
-
'025 GEN V D 025 00:00:55:10 00:00:58:11 01:00:29:19 01:00:32:20'
|
494
|
-
)
|
495
|
-
end
|
496
|
-
|
497
|
-
should "generate a Wipe" do
|
498
|
-
m = EDL::EventMatcher.new(25)
|
499
|
-
wipe = m.apply([],
|
500
|
-
'025 GEN V W001 025 00:00:55:10 00:00:58:11 01:00:29:19 01:00:32:20'
|
501
|
-
)
|
502
|
-
|
503
|
-
tr = wipe.transition
|
504
|
-
assert_kind_of EDL::Wipe, tr
|
505
|
-
assert_equal 25, tr.duration
|
506
|
-
assert_equal '001', tr.smpte_wipe_index
|
507
|
-
end
|
508
|
-
|
509
|
-
EVT_PATTERNS.each do | pat |
|
510
|
-
should "match #{pat.inspect}" do
|
511
|
-
assert EDL::EventMatcher.new(25).matches?(pat)
|
512
|
-
end
|
513
|
-
end
|
514
|
-
|
515
|
-
should "pass the framerate that it received upon instantiation to the Timecodes being created" do
|
516
|
-
|
517
|
-
m = EDL::EventMatcher.new(30)
|
518
|
-
clip = m.apply([],
|
519
|
-
'020 008C V C 08:04:24:24 08:04:25:19 01:00:25:22 01:00:26:17'
|
520
|
-
)
|
521
|
-
assert_equal 30, clip.rec_start_tc.fps
|
522
|
-
assert_equal 30, clip.rec_end_tc.fps
|
523
|
-
assert_equal 30, clip.src_start_tc.fps
|
524
|
-
assert_equal 30, clip.src_end_tc.fps
|
525
|
-
end
|
526
|
-
end
|
527
|
-
|
528
|
-
context "CommentMatcher" do
|
529
|
-
should "match a comment" do
|
530
|
-
line = "* COMMENT: PURE BULLSHIT"
|
531
|
-
assert EDL::CommentMatcher.new.matches?(line)
|
532
|
-
end
|
533
|
-
|
534
|
-
should "apply the comment to the last clip on the stack" do
|
535
|
-
line = "* COMMENT: PURE BULLSHIT"
|
536
|
-
|
537
|
-
comments = []
|
538
|
-
mok_evt = flexmock
|
539
|
-
|
540
|
-
2.times { mok_evt.should_receive(:comments).and_return(comments) }
|
541
|
-
2.times { EDL::CommentMatcher.new.apply([mok_evt], line) }
|
542
|
-
|
543
|
-
assert_equal ["* COMMENT: PURE BULLSHIT", "* COMMENT: PURE BULLSHIT"], mok_evt.comments
|
544
|
-
end
|
545
|
-
end
|
546
|
-
|
547
|
-
context "FallbackMatcher" do
|
548
|
-
should "match anything" do
|
549
|
-
line = "SOME"
|
550
|
-
assert EDL::FallbackMatcher.new.matches?(line)
|
551
|
-
|
552
|
-
line = "OR ANOTHER "
|
553
|
-
assert EDL::FallbackMatcher.new.matches?(line)
|
554
|
-
end
|
555
|
-
|
556
|
-
should "not match whitespace" do
|
557
|
-
line = "\s\s\s\r\n\r"
|
558
|
-
assert !EDL::FallbackMatcher.new.matches?(line)
|
559
|
-
end
|
560
|
-
|
561
|
-
should "append the matched content to comments" do
|
562
|
-
e = flexmock
|
563
|
-
cmts = []
|
564
|
-
e.should_receive(:comments).and_return(cmts)
|
565
|
-
|
566
|
-
EDL::FallbackMatcher.new.apply([e], "FOOBAR")
|
567
|
-
assert_equal ["FOOBAR"], cmts
|
568
|
-
|
569
|
-
EDL::FallbackMatcher.new.apply([e], "FINAL CUT PRO REEL: 006-I REPLACED BY: 006I")
|
570
|
-
assert_equal ["FOOBAR", "FINAL CUT PRO REEL: 006-I REPLACED BY: 006I"], cmts
|
571
|
-
end
|
572
|
-
|
573
|
-
should "raise an ApplyError if no clip is on the stack" do
|
574
|
-
assert_raise(EDL::Matcher::ApplyError) do
|
575
|
-
EDL::FallbackMatcher.new.apply([], "FINAL CUT PRO REEL: 006-I REPLACED BY: 006I")
|
576
|
-
end
|
577
|
-
end
|
578
|
-
|
579
|
-
end
|
580
|
-
|
581
|
-
context "ClipNameMatcher" do
|
582
|
-
should "match a clip name" do
|
583
|
-
line = "* FROM CLIP NAME: TAPE_6-10.MOV"
|
584
|
-
assert EDL::NameMatcher.new.matches?(line)
|
585
|
-
end
|
586
|
-
|
587
|
-
should "match a clip name without space after star" do
|
588
|
-
line = "*FROM CLIP NAME: TAPE_6-10.MOV"
|
589
|
-
assert EDL::NameMatcher.new.matches?(line)
|
590
|
-
end
|
591
|
-
|
592
|
-
should "not match a simple comment" do
|
593
|
-
line = "* CRAP"
|
594
|
-
assert !EDL::NameMatcher.new.matches?(line)
|
595
|
-
end
|
596
|
-
|
597
|
-
should "apply the name to the last event on the stack" do
|
598
|
-
line = "* FROM CLIP NAME: TAPE_6-10.MOV"
|
599
|
-
|
600
|
-
mok_evt = flexmock
|
601
|
-
comments = []
|
602
|
-
mok_evt.should_receive(:clip_name=).with('TAPE_6-10.MOV').once
|
603
|
-
mok_evt.should_receive(:comments).and_return(comments).once
|
604
|
-
|
605
|
-
EDL::NameMatcher.new.apply([mok_evt], line)
|
606
|
-
assert_equal ["* FROM CLIP NAME: TAPE_6-10.MOV"], comments
|
607
|
-
end
|
608
|
-
|
609
|
-
end
|
610
|
-
|
611
|
-
context "EffectMatcher" do
|
612
|
-
should "not match a simple comment" do
|
613
|
-
line = "* STUFF"
|
614
|
-
assert !EDL::EffectMatcher.new.matches?(line)
|
615
|
-
end
|
616
|
-
|
617
|
-
should "match a dissolve name" do
|
618
|
-
line = "* EFFECT NAME: CROSS DISSOLVE"
|
619
|
-
assert EDL::EffectMatcher.new.matches?(line)
|
620
|
-
end
|
621
|
-
|
622
|
-
should "match a dissolve name without space after the asterisk" do
|
623
|
-
line = "*EFFECT NAME: CROSS DISSOLVE"
|
624
|
-
assert EDL::EffectMatcher.new.matches?(line)
|
625
|
-
end
|
626
|
-
|
627
|
-
should "apply the effect name to the transition of the last event on the stack" do
|
628
|
-
line = "* EFFECT NAME: CROSS DISSOLVE"
|
629
|
-
mok_evt, mok_transition = flexmock, flexmock
|
630
|
-
cmt = []
|
631
|
-
|
632
|
-
mok_evt.should_receive(:transition).once.and_return(mok_transition)
|
633
|
-
mok_evt.should_receive(:comments).once.and_return(cmt)
|
634
|
-
|
635
|
-
mok_transition.should_receive(:effect=).with("CROSS DISSOLVE").once
|
636
|
-
|
637
|
-
EDL::EffectMatcher.new.apply([mok_evt], line)
|
638
|
-
|
639
|
-
assert_equal ["* EFFECT NAME: CROSS DISSOLVE"], cmt
|
640
|
-
end
|
641
|
-
|
642
|
-
end
|
643
|
-
|
644
|
-
context "An EDL with mixed line breaks" do
|
645
|
-
should 'parse without errors' do
|
646
|
-
list = EDL::Parser.new.parse(File.open(MIXED_LINEBREAKS))
|
647
|
-
assert_equal ["* A", "* B", "* C", "* D", "* E", "* F", "* G"], list[0].comments
|
648
|
-
end
|
649
|
-
end
|
650
|
-
|
651
|
-
context "A complex EDL passed via Parser" do
|
652
|
-
should "parse without errors" do
|
653
|
-
assert_nothing_raised { EDL::Parser.new.parse(File.open(FORTY_FIVER)) }
|
654
|
-
end
|
655
|
-
|
656
|
-
should "parse the EDL with \\r line breaks properly" do
|
657
|
-
evts = EDL::Parser.new.parse(File.read(PLATES))
|
658
|
-
assert_equal 3, evts.length
|
659
|
-
end
|
660
|
-
|
661
|
-
# TODO: this does not belong here
|
662
|
-
should "be properly rewritten from zero" do
|
663
|
-
complex = EDL::Parser.new.parse(File.open(FORTY_FIVER))
|
664
|
-
from_zero = complex.from_zero
|
665
|
-
|
666
|
-
assert_equal complex.length, from_zero.length, "Should have the same number of events"
|
667
|
-
|
668
|
-
assert_zero from_zero[0].rec_start_tc
|
669
|
-
assert_equal '00:00:42:16'.tc, from_zero[-1].rec_end_tc
|
670
|
-
end
|
671
|
-
end
|
672
|
-
|
673
|
-
context "A FinalCutPro speedup with fade at the end" do
|
674
|
-
should "be parsed cleanly" do
|
675
|
-
list = EDL::Parser.new.parse(File.open(SPEEDUP_AND_FADEOUT))
|
676
|
-
|
677
|
-
assert_equal 2, list.length
|
678
|
-
|
679
|
-
first_evt = list[0]
|
680
|
-
|
681
|
-
tw = first_evt.timewarp
|
682
|
-
assert_kind_of EDL::Timewarp, tw
|
683
|
-
|
684
|
-
assert_equal 689, first_evt.rec_length
|
685
|
-
assert_equal 714, first_evt.rec_length_with_transition
|
686
|
-
|
687
|
-
assert_equal 1000, tw.actual_length_of_source
|
688
|
-
assert_equal 140, tw.speed
|
689
|
-
|
690
|
-
assert_equal 1000, first_evt.src_length
|
691
|
-
|
692
|
-
assert_equal "01:00:00:00", first_evt.capture_from_tc.to_s
|
693
|
-
assert_equal "01:00:40:00", first_evt.capture_to_tc.to_s
|
694
|
-
end
|
695
|
-
end
|
696
|
-
|
697
|
-
context "In the trailer EDL the event 4" do
|
698
|
-
should "not have too many comments" do
|
699
|
-
evts = EDL::Parser.new.parse(File.open(TRAILER_EDL))
|
700
|
-
evt = evts[6]
|
701
|
-
assert_equal 5, evt.comments.length
|
702
|
-
end
|
703
|
-
end
|
704
|
-
|
705
|
-
context "A FinalCutPro speedup and reverse with fade at the end" do
|
706
|
-
should "parse cleanly" do
|
707
|
-
first_evt = EDL::Parser.new.parse(File.open(SPEEDUP_REVERSE_AND_FADEOUT)).shift
|
708
|
-
|
709
|
-
assert first_evt.reverse?
|
710
|
-
|
711
|
-
assert_equal 689, first_evt.rec_length
|
712
|
-
assert_equal 714, first_evt.rec_length_with_transition
|
713
|
-
|
714
|
-
tw = first_evt.timewarp
|
715
|
-
|
716
|
-
assert_equal "1h 1f".tc, tw.source_used_from
|
717
|
-
assert_equal "1h 40s".tc, tw.source_used_upto
|
718
|
-
end
|
719
|
-
end
|
720
|
-
|
721
|
-
end
|