edl 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8229f60333ce6d40281980eb5dfb8188f5283882
4
- data.tar.gz: 24b0c0eb16e8563a228543213142d06104876312
3
+ metadata.gz: 92c9e98e3aae5318b201b581548227410c0add31
4
+ data.tar.gz: 775136de2ed133788783aabb995674b68bf610bf
5
5
  SHA512:
6
- metadata.gz: 895259b1cf0bc020766d6dc6b075a3cb1b5853ab2775f65c385544d0113cb0b3d74a34fe2f2d4082f53d0381e1ab09368d2cb5670bae1479b61a196d72567438
7
- data.tar.gz: 7bd9cfccbd517a5a1f2c5ccc9541c5552d7a529409d11cd9dc89377ea6970c9eb352b015839e7f323af8c684101e4a571d3d70ba4451031d2e8b0c765317b0b6
6
+ metadata.gz: 64487e6d8b2558e74ae04781a347c2ed91d1c5ad362b764b0af479628077fd70ea831e1df7d1403afabcf794aa10deb1087fa484d7e46f23e70e555b07802ba7
7
+ data.tar.gz: 6eb2449c27c2188dcfe11df99b4a987d78436f938fdf7795bc996e7c22dc1d7c3f6b9c42a815f07b79238ae626e8e7b9a3d77576b393c8ed17bdc7151b4835c7
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ pkg
3
+ .DS_Store
4
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation --color
2
+ --require spec_helper
@@ -0,0 +1 @@
1
+ edl
@@ -0,0 +1 @@
1
+ 2.4.1
@@ -0,0 +1,9 @@
1
+ sudo: false
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.1.5
5
+ - 2.2.5
6
+ - 2.3.3
7
+ - 2.4.1
8
+ - jruby
9
+ - ruby-head
data/Gemfile CHANGED
@@ -1,13 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # -*- ruby -*-
2
4
  source 'https://rubygems.org'
3
5
 
4
- gem "timecode"
5
-
6
- group :development do
7
- gem 'shoulda-context'
8
- gem "test-unit", :require => "test/unit"
9
- gem "jeweler"
10
- gem "rake"
11
- flexmock_ver = (RUBY_VERSION > "1.8") ? "~> 1.3.2" : "~> 0.8"
12
- gem "flexmock", flexmock_ver, :require => %w( flexmock flexmock/test_unit )
13
- end
6
+ gemspec
data/Rakefile CHANGED
@@ -1,27 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubygems'
2
- require './lib/edl.rb'
3
- require 'jeweler'
4
+ require 'bundler/gem_tasks'
5
+ require 'rake/testtask'
4
6
 
5
- Jeweler::Tasks.new do |gem|
6
- gem.version = EDL::VERSION
7
- gem.name = "edl"
8
- gem.summary = "Parser for EDL (Edit Decision List) files"
9
- gem.email = "me@julik.nl"
10
- gem.homepage = "http://guerilla-di.org/edl"
11
- gem.authors = ["Julik Tarkhanov"]
12
-
13
- # Do not package invisibles
14
- gem.files.exclude ".*"
15
- end
7
+ begin
8
+ require 'rspec/core/rake_task'
16
9
 
17
- Jeweler::RubygemsDotOrgTasks.new
10
+ RSpec::Core::RakeTask.new(:spec)
18
11
 
19
- require 'rake/testtask'
20
- desc "Run all tests"
21
- Rake::TestTask.new("test") do |t|
22
- t.libs << "test"
23
- t.pattern = 'test/**/test_*.rb'
24
- t.verbose = true
12
+ task default: :spec
13
+ rescue LoadError
14
+ # no rspec available
25
15
  end
26
-
27
- task :default => [ :test ]
@@ -1,80 +1,45 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
4
+
5
+ # Maintain your gem's version:
6
+ require 'edl/version'
5
7
 
6
8
  Gem::Specification.new do |s|
7
- s.name = "edl"
8
- s.version = "0.1.5"
9
+ s.name = 'edl'
10
+ s.version = EDL::VERSION
9
11
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Julik Tarkhanov"]
12
- s.date = "2014-03-24"
13
- s.email = "me@julik.nl"
12
+ s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
13
+ s.authors = ['Julik Tarkhanov']
14
+ s.date = '2014-03-24'
15
+ s.email = 'me@julik.nl'
14
16
  s.extra_rdoc_files = [
15
- "README.rdoc"
16
- ]
17
- s.files = [
18
- "Gemfile",
19
- "History.txt",
20
- "README.rdoc",
21
- "Rakefile",
22
- "edl.gemspec",
23
- "illustr/edl-explain.ai",
24
- "lib/edl.rb",
25
- "lib/edl/cutter.rb",
26
- "lib/edl/event.rb",
27
- "lib/edl/grabber.rb",
28
- "lib/edl/linebreak_magician.rb",
29
- "lib/edl/parser.rb",
30
- "lib/edl/timewarp.rb",
31
- "lib/edl/transition.rb",
32
- "test/samples/45S_SAMPLE.EDL",
33
- "test/samples/FCP_REVERSE.EDL",
34
- "test/samples/KEY_TRANSITION.EDL",
35
- "test/samples/PLATES.EDL",
36
- "test/samples/REEL_IS_CLIP.txt",
37
- "test/samples/REVERSE.EDL",
38
- "test/samples/SIMPLE_DISSOLVE.EDL",
39
- "test/samples/SPEEDUP_AND_FADEOUT.EDL",
40
- "test/samples/SPEEDUP_REVERSE_AND_FADEOUT.EDL",
41
- "test/samples/SPLICEME.EDL",
42
- "test/samples/TIMEWARP.EDL",
43
- "test/samples/TIMEWARP_HALF.EDL",
44
- "test/samples/TRAILER_EDL.edl",
45
- "test/samples/edl_mixed_line_endings.edl",
46
- "test/test_edl.rb"
17
+ 'README.rdoc'
47
18
  ]
48
- s.homepage = "http://guerilla-di.org/edl"
49
- s.require_paths = ["lib"]
50
- s.rubygems_version = "2.0.3"
51
- s.summary = "Parser for EDL (Edit Decision List) files"
52
19
 
53
- if s.respond_to? :specification_version then
20
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ s.bindir = 'exe'
22
+ s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ s.require_paths = ['lib']
24
+
25
+ s.homepage = 'http://guerilla-di.org/edl'
26
+ s.require_paths = ['lib']
27
+ s.rubygems_version = '2.0.3'
28
+ s.summary = 'Parser for EDL (Edit Decision List) files'
29
+
30
+ if s.respond_to? :specification_version
54
31
  s.specification_version = 4
55
32
 
56
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
57
- s.add_runtime_dependency(%q<timecode>, [">= 0"])
58
- s.add_development_dependency(%q<shoulda-context>, [">= 0"])
59
- s.add_development_dependency(%q<test-unit>, [">= 0"])
60
- s.add_development_dependency(%q<jeweler>, [">= 0"])
61
- s.add_development_dependency(%q<rake>, [">= 0"])
62
- s.add_development_dependency(%q<flexmock>, ["~> 1.3.2"])
33
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0')
34
+ s.add_runtime_dependency 'timecode', '>= 0'
35
+ s.add_development_dependency 'rake', '>= 0'
36
+ s.add_development_dependency 'rspec', '~> 3.5'
63
37
  else
64
- s.add_dependency(%q<timecode>, [">= 0"])
65
- s.add_dependency(%q<shoulda-context>, [">= 0"])
66
- s.add_dependency(%q<test-unit>, [">= 0"])
67
- s.add_dependency(%q<jeweler>, [">= 0"])
68
- s.add_dependency(%q<rake>, [">= 0"])
69
- s.add_dependency(%q<flexmock>, ["~> 1.3.2"])
38
+ s.add_dependency 'timecode', '>= 0'
39
+ s.add_dependency 'rake', '>= 0'
70
40
  end
71
41
  else
72
- s.add_dependency(%q<timecode>, [">= 0"])
73
- s.add_dependency(%q<shoulda-context>, [">= 0"])
74
- s.add_dependency(%q<test-unit>, [">= 0"])
75
- s.add_dependency(%q<jeweler>, [">= 0"])
76
- s.add_dependency(%q<rake>, [">= 0"])
77
- s.add_dependency(%q<flexmock>, ["~> 1.3.2"])
42
+ s.add_dependency 'timecode', '>= 0'
43
+ s.add_dependency 'rake', '>= 0'
78
44
  end
79
45
  end
80
-
data/lib/edl.rb CHANGED
@@ -1,48 +1,50 @@
1
- require "rubygems"
2
- require "timecode"
3
- require "stringio"
1
+ # frozen_string_literal: true
4
2
 
5
- require File.dirname(__FILE__) + '/edl/event'
6
- require File.dirname(__FILE__) + '/edl/transition'
7
- require File.dirname(__FILE__) + '/edl/timewarp'
8
- require File.dirname(__FILE__) + '/edl/parser'
9
- require File.dirname(__FILE__) + '/edl/linebreak_magician'
3
+ require 'timecode'
4
+ require 'pp'
5
+ require 'stringio'
6
+ require 'edl/cutter'
7
+ require 'edl/event'
8
+ require 'edl/grabber'
9
+ require 'edl/linebreak_magician'
10
+ require 'edl/parser'
11
+ require 'edl/timewarp'
12
+ require 'edl/transition'
13
+ require 'edl/version'
10
14
 
11
15
  # A simplistic EDL parser
12
16
  module EDL
13
- VERSION = "0.1.5"
14
17
  DEFAULT_FPS = 25.0
15
-
18
+
16
19
  # Represents an EDL, is returned from the parser. Traditional operation is functional style, i.e.
17
20
  # edl.renumbered.without_transitions.without_generators
18
21
  class List < Array
19
-
20
22
  def events #:nodoc:
21
- STDERR.puts "EDL::List#events is deprecated and will be removed, use EDL::List as an array instead"
23
+ STDERR.puts 'EDL::List#events is deprecated and will be removed, use EDL::List as an array instead'
22
24
  self
23
25
  end
24
-
26
+
25
27
  # Return the same EDL with all dissolves stripped and replaced by the clips underneath
26
28
  def without_transitions
27
29
  # Find dissolves
28
30
  cpy = []
29
- each_with_index do | e, i |
31
+ each_with_index do |e, i|
30
32
  # A dissolve always FOLLOWS the incoming clip
31
33
  if e.ends_with_transition?
32
- dissolve = self[i+1]
34
+ dissolve = self[i + 1]
33
35
  len = dissolve.transition.duration.to_i
34
-
36
+
35
37
  # The dissolve contains the OUTGOING clip, we are the INCOMING. Extend the
36
38
  # incoming clip by the length of the dissolve, that's the whole mission actually
37
39
  incoming = e.copy_properties_to(e.class.new)
38
40
  incoming.src_end_tc += len
39
41
  incoming.rec_end_tc += len
40
-
42
+
41
43
  outgoing = dissolve.copy_properties_to(Event.new)
42
-
44
+
43
45
  # Add the A suffix to the ex-dissolve
44
46
  outgoing.num += 'A'
45
-
47
+
46
48
  # Take care to join the two if they overlap - TODO
47
49
  cpy << incoming
48
50
  cpy << outgoing
@@ -56,27 +58,30 @@ module EDL
56
58
  # (0...cpy.length).map{|e| cpy[e].num = "%03d" % e }
57
59
  self.class.new(cpy)
58
60
  end
59
-
61
+
60
62
  # Return the same EDL, with events renumbered starting from 001
61
63
  def renumbered
62
- renumed = self.dup
64
+ renumed = dup
63
65
  pad = renumed.length.to_s.length
64
66
  pad = 3 if pad < 3
65
-
66
- (0...renumed.length).map{|e| renumed[e].num = "%0#{pad}d" % (e+1) }
67
+
68
+ (0...renumed.length).map { |e| renumed[e].num = "%0#{pad}d" % (e + 1) }
67
69
  self.class.new(renumed)
68
70
  end
69
-
71
+
70
72
  # Return the same EDL with all timewarps expanded to native length. Clip length
71
73
  # changes have rippling effect on footage that comes after the timewarped clip
72
74
  # (so this is best used in concert with the original EDL where record TC is pristine)
73
75
  def without_timewarps
74
76
  self.class.new(
75
- map do | e |
77
+ map do |e|
76
78
  if e.has_timewarp?
77
79
  repl = e.copy_properties_to(e.class.new)
78
- from, to = e.timewarp.actual_src_start_tc, e.timewarp.actual_src_end_tc
79
- repl.src_start_tc, repl.src_end_tc, repl.timewarp = from, to, nil
80
+ from = e.timewarp.actual_src_start_tc
81
+ to = e.timewarp.actual_src_end_tc
82
+ repl.src_start_tc = from
83
+ repl.src_end_tc = to
84
+ repl.timewarp = nil
80
85
  repl
81
86
  else
82
87
  e
@@ -84,36 +89,36 @@ module EDL
84
89
  end
85
90
  )
86
91
  end
87
-
92
+
88
93
  # Return the same EDL without AX, BL and other GEN events (like slug, text and solids).
89
94
  # Usually used in concert with "without_transitions"
90
95
  def without_generators
91
- self.class.new(self.reject{|e| e.generator? })
96
+ self.class.new(reject(&:generator?))
92
97
  end
93
-
98
+
94
99
  # Return the list of clips used by this EDL at full capture length
95
100
  def capture_list
96
101
  without_generators.without_timewarps.spliced.from_zero
97
102
  end
98
-
103
+
99
104
  # Return the same EDL with the first event starting at 00:00:00:00 and all subsequent events
100
105
  # shifted accordingly
101
106
  def from_zero
102
107
  shift_by = self[0].rec_start_tc
103
108
  self.class.new(
104
- map do | original |
109
+ map do |original|
105
110
  e = original.dup
106
- e.rec_start_tc = (e.rec_start_tc - shift_by)
107
- e.rec_end_tc = (e.rec_end_tc - shift_by)
111
+ e.rec_start_tc = (e.rec_start_tc - shift_by)
112
+ e.rec_end_tc = (e.rec_end_tc - shift_by)
108
113
  e
109
114
  end
110
115
  )
111
116
  end
112
-
117
+
113
118
  # Return the same EDL with neighbouring clips joined at cuts where applicable (if a clip
114
119
  # is divided in two pieces it will be spliced). Most useful in combination with without_timewarps
115
120
  def spliced
116
- spliced_edl = inject([]) do | spliced, cur |
121
+ spliced_edl = each_with_object([]) do |cur, spliced|
117
122
  latest = spliced[-1]
118
123
  # Append to latest if splicable
119
124
  if latest && (latest.reel == cur.reel) && (cur.src_start_tc == (latest.src_end_tc + 1))
@@ -122,140 +127,135 @@ module EDL
122
127
  else
123
128
  spliced << cur.dup
124
129
  end
125
- spliced
126
130
  end
127
131
  self.class.new(spliced_edl)
128
132
  end
129
133
  end
130
-
134
+
131
135
  #:stopdoc:
132
-
136
+
133
137
  # A generic matcher
134
138
  class Matcher
135
139
  class ApplyError < RuntimeError
136
140
  def initialize(msg, line)
137
- super("%s - offending line was %s" % [msg, line.inspect])
141
+ super('%s - offending line was %s' % [msg, line.inspect])
138
142
  end
139
143
  end
140
-
144
+
141
145
  def initialize(with_regexp)
142
146
  @regexp = with_regexp
143
147
  end
144
-
148
+
145
149
  def matches?(line)
146
- !!(line =~ @regexp)
150
+ line =~ @regexp
147
151
  end
148
-
149
- def apply(stack, line)
152
+
153
+ def apply(_stack, line)
150
154
  STDERR.puts "Skipping #{line}"
151
155
  end
152
156
  end
153
-
157
+
154
158
  # EDL clip comment matcher, a generic one
155
159
  class CommentMatcher < Matcher
156
160
  def initialize
157
- super(/\*(.+)/)
161
+ super(/^\*(.+)/)
158
162
  end
159
-
163
+
160
164
  def apply(stack, line)
161
- raise ApplyError.new("No event to attach a comment to", line) if stack.empty?
165
+ raise ApplyError.new('No event to attach a comment to', line) if stack.empty?
162
166
  # TODO: we should really remove "* " prefixes from comments
163
- stack[-1].comments.push("* %s" % line.scan(@regexp).flatten.pop.strip)
167
+ stack[-1].comments.push('* %s' % line.scan(@regexp).flatten.pop.strip)
164
168
  end
165
169
  end
166
-
170
+
167
171
  # Fallback matcher for things like FINAL CUT PRO REEL
168
172
  class FallbackMatcher < Matcher
169
173
  def initialize
170
174
  super(/^(\w)(.+)/)
171
175
  end
172
-
176
+
173
177
  def apply(stack, line)
174
- begin
175
- stack[-1].comments << line.scan(@regexp).flatten.join.strip
176
- rescue NoMethodError
177
- raise ApplyError.new("Line can only be a comment but no event was on the stack", line)
178
- end
178
+ stack[-1].comments << line.scan(@regexp).flatten.join.strip
179
+ rescue NoMethodError
180
+ raise ApplyError.new('Line can only be a comment but no event was on the stack', line)
179
181
  end
180
182
  end
181
183
 
182
184
  # Clip name matcher
183
185
  class NameMatcher < Matcher
184
186
  def initialize
185
- super(/\*\s*FROM CLIP NAME:(\s+)(.+)/)
187
+ super(/^\*\s*FROM CLIP NAME:(\s+)(.+)/)
186
188
  end
187
-
189
+
188
190
  def apply(stack, line)
189
191
  stack[-1].clip_name = line.scan(@regexp).flatten.pop.strip
190
192
  CommentMatcher.new.apply(stack, line)
191
193
  end
192
194
  end
193
-
195
+
194
196
  class EffectMatcher < Matcher
195
197
  def initialize
196
- super(/\*\s*EFFECT NAME:(\s+)(.+)/)
198
+ super(/^\*\s*EFFECT NAME:(\s+)(.+)/)
197
199
  end
198
-
200
+
199
201
  def apply(stack, line)
200
202
  stack[-1].transition.effect = line.scan(@regexp).flatten.pop.strip
201
203
  CommentMatcher.new.apply(stack, line)
202
204
  end
203
205
  end
204
-
206
+
205
207
  class TimewarpMatcher < Matcher
206
-
207
208
  attr_reader :fps
208
-
209
+
209
210
  def initialize(fps)
210
211
  @fps = fps
211
212
  @regexp = /M2(\s+)(\w+)(\s+)(\-?\d+\.\d+)(\s+)(\d{1,2}):(\d{1,2}):(\d{1,2}):(\d{1,2})/
212
213
  end
213
-
214
+
214
215
  def apply(stack, line)
215
- matches = line.scan(@regexp).flatten.map{|e| e.strip}.reject{|e| e.nil? || e.empty?}
216
-
216
+ matches = line.scan(@regexp).flatten.map(&:strip).reject { |e| e.nil? || e.empty? }
217
+
217
218
  from_reel = matches.shift
218
219
  fps = matches.shift
219
-
220
+
220
221
  begin
221
222
  # FIXME
222
223
  tw_start_source_tc = Parser.timecode_from_line_elements(matches, @fps)
223
224
  rescue Timecode::Error => e
224
- raise ApplyError, "Invalid TC in timewarp (#{e})", line
225
+ raise ApplyError.new("Invalid TC in timewarp (#{e})", line)
225
226
  end
226
-
227
- evt_with_tw = stack.reverse.find{|e| e.src_start_tc == tw_start_source_tc && e.reel == from_reel }
228
-
229
- unless evt_with_tw
230
- raise ApplyError, "Cannot find event marked by timewarp", line
231
- else
227
+
228
+ evt_with_tw = stack.reverse.find { |e| e.src_start_tc == tw_start_source_tc && e.reel == from_reel }
229
+
230
+ if evt_with_tw
232
231
  tw = Timewarp.new
233
- tw.actual_framerate, tw.clip = fps.to_f, evt_with_tw
232
+ tw.actual_framerate = fps.to_f
233
+ tw.clip = evt_with_tw
234
234
  evt_with_tw.timewarp = tw
235
+ else
236
+ raise ApplyError.new('Cannot find event marked by timewarp', line)
235
237
  end
236
238
  end
237
239
  end
238
-
240
+
239
241
  # Drop frame goodbye
240
242
  TC = /(\d{1,2}):(\d{1,2}):(\d{1,2}):(\d{1,2})/
241
-
242
- class EventMatcher < Matcher
243
243
 
244
+ class EventMatcher < Matcher
244
245
  # 021 009 V C 00:39:04:21 00:39:05:09 01:00:26:17 01:00:27:05
245
- EVENT_PAT = /(\d+)(\s+)(\w+)(\s+)(\w+)(\s+)(\w+)(\s+)((\w+\s+)?)#{TC} #{TC} #{TC} #{TC}/
246
-
246
+ EVENT_PAT = /(\d+)(\s+)([^\s]+)(\s+)(\w+)(\s+)(\w+)(\s+)((\w+\s+)?)#{TC} #{TC} #{TC} #{TC}/
247
+
247
248
  attr_reader :fps
248
-
249
+
249
250
  def initialize(some_fps)
250
251
  super(EVENT_PAT)
251
252
  @fps = some_fps
252
253
  end
253
-
254
+
254
255
  def apply(stack, line)
255
-
256
256
  matches = line.scan(@regexp).shift
257
257
  props = {}
258
-
258
+
259
259
  # FIrst one is the event number
260
260
  props[:num] = matches.shift
261
261
  matches.shift
@@ -271,7 +271,7 @@ module EDL
271
271
  # Then the type
272
272
  props[:transition] = matches.shift
273
273
  matches.shift
274
-
274
+
275
275
  # Then the optional generator group - skip for now
276
276
  if props[:transition] != 'C'
277
277
  props[:duration] = matches.shift.strip
@@ -279,50 +279,49 @@ module EDL
279
279
  matches.shift
280
280
  end
281
281
  matches.shift
282
-
282
+
283
283
  # Then the timecodes
284
- [:src_start_tc, :src_end_tc, :rec_start_tc, :rec_end_tc].each do | k |
284
+ [:src_start_tc, :src_end_tc, :rec_start_tc, :rec_end_tc].each do |k|
285
285
  begin
286
286
  props[k] = EDL::Parser.timecode_from_line_elements(matches, @fps)
287
- rescue Timecode::Error => e
288
- raise ApplyError, "Cannot parse timecode - #{e}", line
287
+ rescue Timecode::Error => e
288
+ raise ApplyError.new("Cannot parse timecode - #{e}", line)
289
289
  end
290
290
  end
291
-
291
+
292
292
  evt = Event.new
293
293
  transition_idx = props.delete(:transition)
294
294
  evt.transition = case transition_idx
295
- when 'C'
296
- nil
297
- when 'D'
298
- d = Dissolve.new
299
- d.duration = props.delete(:duration).to_i
300
- d
301
- when /W(\d+)/
302
- w = Wipe.new
303
- w.duration = props.delete(:duration).to_i
304
- w.smpte_wipe_index = transition_idx.gsub(/W/, '')
305
- w
306
- when 'K'
307
- k = Key.new
308
- k.duration = props.delete(:duration).to_i
309
- k
310
- else
311
- raise "Unknown transition type #{transition_idx}"
295
+ when 'C'
296
+ nil
297
+ when 'D'
298
+ d = Dissolve.new
299
+ d.duration = props.delete(:duration).to_i
300
+ d
301
+ when /W(\d+)/
302
+ w = Wipe.new
303
+ w.duration = props.delete(:duration).to_i
304
+ w.smpte_wipe_index = transition_idx.delete('W')
305
+ w
306
+ when 'K'
307
+ k = Key.new
308
+ k.duration = props.delete(:duration).to_i
309
+ k
310
+ else
311
+ raise "Unknown transition type #{transition_idx}"
312
312
  end
313
-
313
+
314
314
  # Give a hint on the incoming clip as well
315
315
  if evt.transition && stack[-1]
316
316
  stack[-1].outgoing_transition_duration = evt.transition.duration
317
317
  end
318
-
319
- props.each_pair { | k, v | evt.send("#{k}=", v) }
320
-
318
+
319
+ props.each_pair { |k, v| evt.send("#{k}=", v) }
320
+
321
321
  stack << evt
322
- evt # FIXME - we dont need to return this is only used by tests
322
+ evt # FIXME: - we dont need to return this is only used by tests
323
323
  end
324
324
  end
325
-
326
- #:startdoc:
327
325
 
326
+ #:startdoc:
328
327
  end