timecode 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/History.txt +4 -0
  2. data/lib/timecode.rb +24 -10
  3. data/test/test_timecode.rb +13 -5
  4. metadata +2 -2
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 0.1.3 / 2008-12-25
2
+
3
+ * Implement the format FFmpeg uses
4
+
1
5
  === 0.1.2 / 2008-12-25
2
6
 
3
7
  * Fix to_uint
data/lib/timecode.rb CHANGED
@@ -12,7 +12,7 @@
12
12
  # :mapping => [%w(source_tc_frames total), %w(tape_fps fps)]
13
13
 
14
14
  class Timecode
15
- VERSION = '0.1.2'
15
+ VERSION = '0.1.3'
16
16
 
17
17
  include Comparable
18
18
 
@@ -80,6 +80,10 @@ class Timecode
80
80
  end
81
81
 
82
82
  # Parse timecode entered by the user. Will raise if the string cannot be parsed.
83
+ # The following formats are supported:
84
+ # * 10h 20m 10s 1f (or any combination thereof) - will be disassembled to hours, frames, seconds and so on automatically
85
+ # * 123 - will be parsed as 00:00:01:23
86
+ # * 00:00:00:00 - will be parsed as zero TC
83
87
  def parse(input, with_fps = DEFAULT_FPS)
84
88
  # Drop frame goodbye
85
89
  raise TimecodeLibError, "We do not support drop frame" if (input =~ /\;/)
@@ -141,6 +145,8 @@ class Timecode
141
145
  new(total, with_fps)
142
146
  end
143
147
 
148
+ # Parse a timecode with fractional seconds instead of frames. This is how ffmpeg reports
149
+ # a timecode
144
150
  def parse_with_fractional_seconds(tc_with_fractions_of_second, fps = DEFAULT_FPS)
145
151
  fraction_expr = /\.(\d+)$/
146
152
  fraction_part = ('.' + tc_with_fractions_of_second.scan(fraction_expr)[0][0]).to_f
@@ -153,22 +159,20 @@ class Timecode
153
159
  parse(tc_with_frameno, fps)
154
160
  end
155
161
 
156
- # create a timecode from seconds. Seconds can be float (this is how current time is supplied by
157
- # QuickTime and other systems which have non-frame-based timescales)
162
+ # create a timecode from the number of seconds. This is how current time is supplied by
163
+ # QuickTime and other systems which have non-frame-based timescales
158
164
  def from_seconds(seconds_float, the_fps = DEFAULT_FPS)
159
165
  total_frames = (seconds_float.to_f * the_fps.to_f).ceil
160
166
  new(total_frames, the_fps)
161
167
  end
162
168
 
163
-
164
- # Some systems (like SGIs) and DPX format store timecode as unsigned integer, bit-packed
169
+ # Some systems (like SGIs) and DPX format store timecode as unsigned integer, bit-packed. This method
170
+ # unpacks such an integer into a timecode.
165
171
  def from_uint(uint, fps = DEFAULT_FPS)
166
- shift = 4 * TIME_FIELDS
167
- tc_elements = (0..TIME_FIELDS).map do
168
- part = ((uint >> shift) & 0x0F)
169
- shift -= 4
170
- part
172
+ tc_elements = (0..7).to_a.reverse.map do | multiplier |
173
+ ((uint >> (multiplier * 4)) & 0x0F)
171
174
  end.join.scan(/(\d{2})/).flatten.map{|e| e.to_i}
175
+
172
176
  tc_elements << fps
173
177
  at(*tc_elements)
174
178
  end
@@ -296,6 +300,16 @@ class Timecode
296
300
  end
297
301
  end
298
302
 
303
+ # FFmpeg expects a fraction of a second as the last element instead of number of frames. Use this
304
+ # method to get the timecode that adheres to that expectation. The return of this method can be fed
305
+ # to ffmpeg directly.
306
+ # Timecode.parse("00:00:10:24", 25).with_frames_as_fraction #=> "00:00:10.96"
307
+ def with_frames_as_fraction
308
+ vp = value_parts.dup
309
+ vp[-1] = (100.0 / @fps) * vp[-1]
310
+ "%02d:%02d:%02d.%02d" % vp
311
+ end
312
+ alias_method :with_fractional_seconds, :with_frames_as_fraction
299
313
 
300
314
  # Validate that framerates are within a small delta deviation considerable for floats
301
315
  def framerate_in_delta(one, two)
@@ -88,6 +88,19 @@ class TimecodeTest < Test::Unit::TestCase
88
88
  a, b = Timecode.new(24, 25.000000000000001), Timecode.new(22, 25.000000000000002)
89
89
  assert_equal Timecode.new(24 + 22, 25.000000000000001), (a + b)
90
90
  end
91
+
92
+ def test_tc_with_frames_as_fraction
93
+ tc = Timecode.new(100 -1, fps = 25)
94
+ assert_equal 24, tc.frames
95
+ assert_equal "00:00:03.96", tc.with_frames_as_fraction
96
+ assert_equal "00:00:03.96", tc.with_fractional_seconds
97
+ end
98
+
99
+ def test_float_framerate
100
+ tc = Timecode.new(25, 12.5)
101
+ assert_equal "00:00:02:00", tc.to_s
102
+ end
103
+
91
104
  end
92
105
 
93
106
  class TestParsing < Test::Unit::TestCase
@@ -142,11 +155,6 @@ class TestParsing < Test::Unit::TestCase
142
155
  assert_equal '01:00:01:04', Timecode.parse("29f 1h").to_s
143
156
  end
144
157
 
145
- def test_float_framerate
146
- tc = Timecode.new(25, 12.5)
147
- assert_equal "00:00:02:00", tc.to_s
148
- end
149
-
150
158
  def test_parse_fractional_tc
151
159
  fraction = "00:00:07.1"
152
160
  tc = Timecode.parse_with_fractional_seconds(fraction, 10)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timecode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-12-25 00:00:00 +01:00
12
+ date: 2008-12-28 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency