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.
- data/History.txt +4 -0
- data/lib/timecode.rb +24 -10
- data/test/test_timecode.rb +13 -5
- metadata +2 -2
data/History.txt
CHANGED
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.
|
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
|
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
|
-
#
|
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
|
-
|
167
|
-
|
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)
|
data/test/test_timecode.rb
CHANGED
@@ -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.
|
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-
|
12
|
+
date: 2008-12-28 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|