timecode 0.1.2 → 0.1.3

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.
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