fps-timecode 0.0.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.
- checksums.yaml +7 -0
- data/doc/FPS/Timecode.html +600 -0
- data/doc/FPS.html +100 -0
- data/doc/TestFpsTimecode.html +700 -0
- data/doc/created.rid +5 -0
- data/doc/css/fonts.css +167 -0
- data/doc/css/rdoc.css +590 -0
- data/doc/fonts/Lato-Light.ttf +0 -0
- data/doc/fonts/Lato-LightItalic.ttf +0 -0
- data/doc/fonts/Lato-Regular.ttf +0 -0
- data/doc/fonts/Lato-RegularItalic.ttf +0 -0
- data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
- data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
- data/doc/fps-timecode_gemspec.html +98 -0
- data/doc/images/add.png +0 -0
- data/doc/images/arrow_up.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +93 -0
- data/doc/js/darkfish.js +161 -0
- data/doc/js/jquery.js +4 -0
- data/doc/js/navigation.js +142 -0
- data/doc/js/navigation.js.gz +0 -0
- data/doc/js/search.js +109 -0
- data/doc/js/search_index.js +1 -0
- data/doc/js/search_index.js.gz +0 -0
- data/doc/js/searcher.js +228 -0
- data/doc/js/searcher.js.gz +0 -0
- data/doc/rdoc.css +543 -0
- data/doc/table_of_contents.html +177 -0
- data/lib/fps-timecode.rb +200 -0
- data/test/test_fps-timecode.rb +130 -0
- metadata +95 -0
data/lib/fps-timecode.rb
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
# Timecode library
|
2
|
+
# Implements Timecode class
|
3
|
+
# Version 0.0.2
|
4
|
+
#
|
5
|
+
# Author: Loran Kary
|
6
|
+
# Copyright 2013 Focal Point Software, all rights reserved
|
7
|
+
|
8
|
+
module FPS # Focal Point Software
|
9
|
+
|
10
|
+
# A timecode library has two main purposes.
|
11
|
+
# 1.) Given the timecode address of the first frame of a sequence of frames,
|
12
|
+
# and given n, what is the timecode address of the nth frame of a sequence?
|
13
|
+
# 2.) Given the timecode address of the first frame of a sequence, and
|
14
|
+
# given the timecode address for the nth frame of the sequence, what is n?
|
15
|
+
|
16
|
+
# Example 1. A non-drop-frame 30 fps sequence starts at 00:01:00:00. What is
|
17
|
+
# the timecode address of the 100th frame of the sequence?
|
18
|
+
# FPS::Timecode.count_to_string(:fps_30_ndf,
|
19
|
+
# FPS::Timecode.string_to_count(:fps_30_ndf,"00:01:00:00") + 100)
|
20
|
+
# => "00:01:03:10"
|
21
|
+
|
22
|
+
# Example 2. A non-drop-frame 30 fps sequence starts at 00:01:00:00. What is n
|
23
|
+
# for the frame with the address 00:01:03:10?
|
24
|
+
# FPS::Timecode.string_to_count(:fps_30_ndf,"00:01:03:10") -
|
25
|
+
# FPS::Timecode.string_to_count(:fps_30_ndf,"00:01:00:00")
|
26
|
+
# => 100
|
27
|
+
|
28
|
+
# An instance of the Timecode class represents one timecode address.
|
29
|
+
# A timecode mode is always required to be given. The mode determines the frame
|
30
|
+
# rate and the dropness (drop-frame or non-drop-frame) of the timecode address.
|
31
|
+
# The mode must be one of Timecode::Counts.keys. E.g. :fps_24, :fps_25.
|
32
|
+
# Create an instance of a Timecode using either a string in the format "xx:xx:xx:xx"
|
33
|
+
# or a frame count. The frame count represents n for the nth frame of a sequence
|
34
|
+
# that begins with timecode address "00:00:00:00" (the zeroeth frame of the sequence).
|
35
|
+
# When creating a timecode instance, default to using the string argument
|
36
|
+
# and fall back to using the frame count argument if the string is invalid.
|
37
|
+
|
38
|
+
# Since there are many class methods, often there is no need to create
|
39
|
+
# an instance of class Timecode.
|
40
|
+
|
41
|
+
class Timecode
|
42
|
+
|
43
|
+
attr_reader :tc_count, :tc_string, :tc_mode
|
44
|
+
|
45
|
+
Counts = { fps_24: { fp24h: 2073600, fph: 86400, fptm: 14400, fpm: 1440, fps: 24 },
|
46
|
+
fps_25: { fp24h: 2160000, fph: 90000, fptm: 15000, fpm: 1500, fps: 25 },
|
47
|
+
fps_30_df: { fp24h: 2589408, fph: 107892, fptm: 17982, fpm: 1798, fps: 30 },
|
48
|
+
fps_30_ndf: { fp24h: 2592000, fph: 108000, fptm: 18000, fpm: 1800, fps: 30 },
|
49
|
+
fps_48: { fp24h: 4147200, fph: 172800, fptm: 28800, fpm: 2880, fps: 48 },
|
50
|
+
fps_50: { fp24h: 4320000, fph: 180000, fptm: 30000, fpm: 3000, fps: 50 },
|
51
|
+
fps_60_df: { fp24h: 5178816, fph: 215784, fptm: 35964, fpm: 3596, fps: 60 },
|
52
|
+
fps_60_ndf: { fp24h: 5184000, fph: 216000, fptm: 36000, fpm: 3600, fps: 60 },
|
53
|
+
}
|
54
|
+
|
55
|
+
# count_to_string
|
56
|
+
# Class method to compute a string from a frame count
|
57
|
+
def self.count_to_string(tc_mode, tc_count, duration = false)
|
58
|
+
tc_count = Timecode.normalize(tc_mode, tc_count)
|
59
|
+
|
60
|
+
counts = Counts[tc_mode]
|
61
|
+
hours = tc_count / counts[:fph]
|
62
|
+
rem = tc_count % counts[:fph]
|
63
|
+
tens_mins = rem / counts[:fptm]
|
64
|
+
rem = rem % counts[:fptm]
|
65
|
+
units_mins = rem / counts[:fpm]
|
66
|
+
rem = rem % counts[:fpm]
|
67
|
+
|
68
|
+
if(duration == false) # not a duration, do drop-frame processing
|
69
|
+
# handle 30 fps drop frame
|
70
|
+
if(tc_mode == :fps_30_df && units_mins > 0 && rem <= 1)
|
71
|
+
units_mins -= 1
|
72
|
+
rem += counts[:fpm]
|
73
|
+
end
|
74
|
+
# handle 60 fps drop frame
|
75
|
+
if(tc_mode == :fps_60_df && units_mins > 0 && rem <= 3)
|
76
|
+
units_mins -= 1
|
77
|
+
rem += counts[:fpm]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
secs = rem / counts[:fps]
|
82
|
+
frms = rem % counts[:fps]
|
83
|
+
|
84
|
+
"%02d:%d%d:%02d:%02d" % [hours, tens_mins, units_mins, secs, frms]
|
85
|
+
end
|
86
|
+
|
87
|
+
# string_to_count
|
88
|
+
# Class method to compute a count from a string
|
89
|
+
def self.string_to_count(tc_mode, tc_string)
|
90
|
+
unless Counts.include?(tc_mode)
|
91
|
+
raise ArgumentError, "invalid timecode mode"
|
92
|
+
end
|
93
|
+
unless tc_string.is_a? String
|
94
|
+
raise ArgumentError, "invalid timecode string"
|
95
|
+
end
|
96
|
+
unless tc_string =~ /\A(\d{2})[:;.](\d{2})[:;.](\d{2})[:;.](\d{2})\Z/
|
97
|
+
raise ArgumentError, "invalid timecode string"
|
98
|
+
end
|
99
|
+
if($1.to_i >= 24 || $2.to_i >= 60 || $3.to_i >= 60 || $4.to_i >= Counts[tc_mode][:fps])
|
100
|
+
raise ArgumentError, "invalid timecode string"
|
101
|
+
end
|
102
|
+
|
103
|
+
counts = Counts[tc_mode]
|
104
|
+
tc_string =~ /\A(\d{2})[:;.](\d)(\d)[:;.](\d{2})[:;.](\d{2})\Z/
|
105
|
+
$1.to_i * counts[:fph] +
|
106
|
+
$2.to_i * counts[:fptm] +
|
107
|
+
$3.to_i * counts[:fpm] +
|
108
|
+
$4.to_i * counts[:fps] + $5.to_i
|
109
|
+
end
|
110
|
+
|
111
|
+
# Class method to normalize a frame count >= 0 and < 24h
|
112
|
+
# Correct 24 hour overflow or underflow
|
113
|
+
def self.normalize(tc_mode, tc_count)
|
114
|
+
# tc_mode must be given and must be one of the known tc modes
|
115
|
+
unless Counts.include?(tc_mode)
|
116
|
+
raise ArgumentError, "invalid timecode mode"
|
117
|
+
end
|
118
|
+
|
119
|
+
unless tc_count.is_a? Fixnum
|
120
|
+
raise ArgumentError, "invalid frame count #{tc_count}"
|
121
|
+
end
|
122
|
+
# normalize to 24 hours
|
123
|
+
_24h = Counts[tc_mode][:fp24h]
|
124
|
+
while tc_count < 0 do tc_count += _24h end
|
125
|
+
while tc_count >= _24h do tc_count -= _24h end
|
126
|
+
tc_count
|
127
|
+
end
|
128
|
+
|
129
|
+
# Class method to compute a string as a duration from a frame count_to_string
|
130
|
+
def self.string_as_duration(tc_mode, tc_count)
|
131
|
+
Timecode.count_to_string(tc_mode, tc_count, true)
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
# initialize
|
137
|
+
# Construct a new instance of Timecode, given a mode and either a
|
138
|
+
# timecode string or a frame count.
|
139
|
+
# Raises ArgumentError
|
140
|
+
def initialize(tc_mode, tc_string, tc_count = nil)
|
141
|
+
# tc_string and tc_count cannot both be nil
|
142
|
+
if(tc_string === nil && tc_count === nil)
|
143
|
+
raise ArgumentError, "string and count both nil"
|
144
|
+
end
|
145
|
+
# tc_mode must be given and must be one of the known tc modes
|
146
|
+
unless Counts.include?(tc_mode)
|
147
|
+
raise ArgumentError, "invalid timecode mode"
|
148
|
+
end
|
149
|
+
|
150
|
+
@tc_mode = tc_mode
|
151
|
+
|
152
|
+
# Try to use the string to construct the instance and fall back
|
153
|
+
# to the count if an exception is raised
|
154
|
+
begin
|
155
|
+
@tc_count = Timecode.string_to_count(@tc_mode, tc_string)
|
156
|
+
# always convert back to string because given string may not be drop-frame legal
|
157
|
+
@tc_string = Timecode.count_to_string(@tc_mode, @tc_count)
|
158
|
+
rescue
|
159
|
+
@tc_count = Timecode.normalize(@tc_mode, tc_count)
|
160
|
+
@tc_string = Timecode.count_to_string(@tc_mode, @tc_count)
|
161
|
+
end
|
162
|
+
|
163
|
+
end #initialize
|
164
|
+
|
165
|
+
# string_as_duration
|
166
|
+
# The difference of two timecodes might be used as a duration.
|
167
|
+
# For non-drop frame, the duration string does not differ from the
|
168
|
+
# string as a timecode address. But for drop-frame, timecodes
|
169
|
+
# that don't exist as an address can exist as a duration.
|
170
|
+
# One minute in drop frame is 1798 frames or 00:00:59:28.
|
171
|
+
# "00:01:00:00" as a drop-frame timecode address does not exist.
|
172
|
+
# But the difference between 00:01:59:28 and 00:00:59:28
|
173
|
+
# should be displayed as "00:01:00:00" -- one minute.
|
174
|
+
#
|
175
|
+
def string_as_duration
|
176
|
+
Timecode.string_as_duration(@tc_mode, @tc_count)
|
177
|
+
end
|
178
|
+
|
179
|
+
# succ
|
180
|
+
# return the next timecode address in the sequence
|
181
|
+
def succ
|
182
|
+
Timecode.new(@tc_mode, nil, @tc_count+1)
|
183
|
+
end
|
184
|
+
|
185
|
+
# compare two timecodes for equality
|
186
|
+
# equality operator does string compare
|
187
|
+
# two timecodes may be considered equal even though their modes and counts
|
188
|
+
# may be different.
|
189
|
+
def ==(other)
|
190
|
+
@tc_string == other.tc_string
|
191
|
+
end
|
192
|
+
|
193
|
+
# compare two timecodes
|
194
|
+
# comparison (spaceship) operator does string compare
|
195
|
+
def <=>(other)
|
196
|
+
@tc_string <=> other.tc_string
|
197
|
+
end
|
198
|
+
|
199
|
+
end #class
|
200
|
+
end #module
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# Timecode test suite for Timecode class
|
2
|
+
# Author: Loran Kary, Focal Point Software
|
3
|
+
# to run from parent directory, "ruby -I lib test/test_fps-timecode.rb"
|
4
|
+
|
5
|
+
|
6
|
+
require 'fps-timecode'
|
7
|
+
|
8
|
+
require 'test/unit'
|
9
|
+
|
10
|
+
class TestFpsTimecode < Test::Unit::TestCase
|
11
|
+
|
12
|
+
def test_create_legally_doesnt_fail
|
13
|
+
assert_nothing_raised do
|
14
|
+
FPS::Timecode.new(:fps_24, nil, 1000)
|
15
|
+
FPS::Timecode.new(:fps_30_ndf, "00:01:00:00", nil)
|
16
|
+
FPS::Timecode.new(:fps_25, "00:01:00:00")
|
17
|
+
FPS::Timecode.new(:fps_30_df, "00:02:00:00", 1798*2)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_create_must_have_valid_tc_mode
|
22
|
+
assert_raises(ArgumentError) do
|
23
|
+
FPS::Timecode.new(:not_a_valid_tc_mode, nil, 1000)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_create_string_and_count_cannot_both_be_nil
|
28
|
+
assert_raises(ArgumentError) do
|
29
|
+
FPS::Timecode.new(:fps_30_ndf, nil, nil)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_create_use_string_by_default
|
34
|
+
assert_equal "00:01:00:00", FPS::Timecode.new(:fps_30_ndf, "00:01:00:00", 0).tc_string
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_create_fall_back_to_count_when_string_is_invalid
|
38
|
+
assert_equal "00:01:00:00", FPS::Timecode.new(:fps_30_ndf, "invalid", 1800).tc_string
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_create_count_if_given_must_be_fixnum
|
42
|
+
assert_raises(ArgumentError) do
|
43
|
+
FPS::Timecode.new(:fps_30_ndf, nil, "1800")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_create_negative_counts_will_be_normalized
|
48
|
+
assert_equal "23:59:00:00", FPS::Timecode.new(:fps_30_ndf, nil, -1800).tc_string
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_create_counts_greater_than_24_hours_will_be_normalized
|
52
|
+
assert_equal "00:01:00:00",
|
53
|
+
FPS::Timecode.new(:fps_30_ndf, nil, FPS::Timecode::Counts[:fps_30_ndf][:fp24h] + 1800).tc_string
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_create_string_must_be_valid_if_no_count_given
|
57
|
+
assert_raises(ArgumentError) do
|
58
|
+
FPS::Timecode.new(:fps_30_ndf, "invalid", nil)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_create_string_all_fields_must_be_within_bounds # e.g. 24:60:60:30 for fps 30
|
63
|
+
assert_nothing_raised do
|
64
|
+
FPS::Timecode.new(:fps_30_ndf, "23:59:59:29", nil)
|
65
|
+
end
|
66
|
+
assert_raises(ArgumentError) do
|
67
|
+
FPS::Timecode.new(:fps_30_ndf, "23:59:59:30", nil)
|
68
|
+
end
|
69
|
+
assert_raises(ArgumentError) do
|
70
|
+
FPS::Timecode.new(:fps_30_ndf, "24:00:00:00", nil)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_create_nonexistent_drop_frame_times_will_be_corrected
|
75
|
+
# "00:01:00:00" doesn't exist in drop-frame
|
76
|
+
assert_equal("00:00:59:28",
|
77
|
+
FPS::Timecode.new(:fps_30_df, "00:01:00:00", nil).tc_string)
|
78
|
+
# "00:10:00:00" does exist in drop-frame
|
79
|
+
assert_equal("00:10:00:00",
|
80
|
+
FPS::Timecode.new(:fps_30_df, "00:10:00:00", nil).tc_string)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_comparison_works_on_strings_regardless_of_counts
|
84
|
+
# 00:10:00:00 drop-frame is equal to 00:10:00:00 non-drop
|
85
|
+
# despite different frame counts
|
86
|
+
assert_equal true,
|
87
|
+
FPS::Timecode.new(:fps_30_ndf, nil, FPS::Timecode::Counts[:fps_30_ndf][:fptm]) ==
|
88
|
+
FPS::Timecode.new(:fps_30_df, nil, FPS::Timecode::Counts[:fps_30_df][:fptm])
|
89
|
+
assert_equal 0,
|
90
|
+
FPS::Timecode.new(:fps_30_ndf, nil, FPS::Timecode::Counts[:fps_30_ndf][:fptm]) <=>
|
91
|
+
FPS::Timecode.new(:fps_30_df, nil, FPS::Timecode::Counts[:fps_30_df][:fptm])
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_dropframe_string_as_duration
|
95
|
+
a = FPS::Timecode.new(:fps_30_df, "00:01:59:28", nil)
|
96
|
+
b = FPS::Timecode.new(:fps_30_df, "00:00:59:28", nil)
|
97
|
+
difference = a.tc_count - b.tc_count
|
98
|
+
assert_equal 1798, difference
|
99
|
+
assert_equal "00:01:00:00",
|
100
|
+
FPS::Timecode.new(:fps_30_df, nil, difference).string_as_duration
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_succ
|
104
|
+
a = []
|
105
|
+
b = FPS::Timecode.new(:fps_30_df, "00:01:00:00", nil)
|
106
|
+
4.times do
|
107
|
+
a << b.tc_string
|
108
|
+
b = b.succ
|
109
|
+
end
|
110
|
+
assert_equal ["00:00:59:28", "00:00:59:29", "00:01:00:02", "00:01:00:03"], a
|
111
|
+
a.clear
|
112
|
+
b = FPS::Timecode.new(:fps_60_df, "00:01:00:00", nil)
|
113
|
+
6.times do
|
114
|
+
a << b.tc_string
|
115
|
+
b = b.succ
|
116
|
+
end
|
117
|
+
assert_equal ["00:00:59:56", "00:00:59:57", "00:00:59:58", "00:00:59:59",
|
118
|
+
"00:01:00:04", "00:01:00:05"], a
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_class_methods
|
122
|
+
assert_equal "00:01:00:00", FPS::Timecode.count_to_string(:fps_30_ndf, 1800)
|
123
|
+
assert_equal 1800, FPS::Timecode.string_to_count(:fps_30_ndf, "00:01:00:00")
|
124
|
+
assert_equal 1800, FPS::Timecode.normalize(:fps_30_ndf, FPS::Timecode::Counts[:fps_30_ndf][:fp24h] + 1800)
|
125
|
+
assert_equal FPS::Timecode::Counts[:fps_30_ndf][:fp24h] - 1800, FPS::Timecode.normalize(:fps_30_ndf, -1800)
|
126
|
+
assert_equal "00:01:00:00", FPS::Timecode.string_as_duration(:fps_30_df, 1798)
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fps-timecode
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Loran Kary
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-29 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A library to support drop-frame and non-drop-frame timecodes
|
14
|
+
email: lkary@focalpnt.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- doc/FPS.html
|
20
|
+
- doc/FPS/Timecode.html
|
21
|
+
- doc/TestFpsTimecode.html
|
22
|
+
- doc/created.rid
|
23
|
+
- doc/css/fonts.css
|
24
|
+
- doc/css/rdoc.css
|
25
|
+
- doc/fonts/Lato-Light.ttf
|
26
|
+
- doc/fonts/Lato-LightItalic.ttf
|
27
|
+
- doc/fonts/Lato-Regular.ttf
|
28
|
+
- doc/fonts/Lato-RegularItalic.ttf
|
29
|
+
- doc/fonts/SourceCodePro-Bold.ttf
|
30
|
+
- doc/fonts/SourceCodePro-Regular.ttf
|
31
|
+
- doc/fps-timecode_gemspec.html
|
32
|
+
- doc/images/add.png
|
33
|
+
- doc/images/arrow_up.png
|
34
|
+
- doc/images/brick.png
|
35
|
+
- doc/images/brick_link.png
|
36
|
+
- doc/images/bug.png
|
37
|
+
- doc/images/bullet_black.png
|
38
|
+
- doc/images/bullet_toggle_minus.png
|
39
|
+
- doc/images/bullet_toggle_plus.png
|
40
|
+
- doc/images/date.png
|
41
|
+
- doc/images/delete.png
|
42
|
+
- doc/images/find.png
|
43
|
+
- doc/images/loadingAnimation.gif
|
44
|
+
- doc/images/macFFBgHack.png
|
45
|
+
- doc/images/package.png
|
46
|
+
- doc/images/page_green.png
|
47
|
+
- doc/images/page_white_text.png
|
48
|
+
- doc/images/page_white_width.png
|
49
|
+
- doc/images/plugin.png
|
50
|
+
- doc/images/ruby.png
|
51
|
+
- doc/images/tag_blue.png
|
52
|
+
- doc/images/tag_green.png
|
53
|
+
- doc/images/transparent.png
|
54
|
+
- doc/images/wrench.png
|
55
|
+
- doc/images/wrench_orange.png
|
56
|
+
- doc/images/zoom.png
|
57
|
+
- doc/index.html
|
58
|
+
- doc/js/darkfish.js
|
59
|
+
- doc/js/jquery.js
|
60
|
+
- doc/js/navigation.js
|
61
|
+
- doc/js/navigation.js.gz
|
62
|
+
- doc/js/search.js
|
63
|
+
- doc/js/search_index.js
|
64
|
+
- doc/js/search_index.js.gz
|
65
|
+
- doc/js/searcher.js
|
66
|
+
- doc/js/searcher.js.gz
|
67
|
+
- doc/rdoc.css
|
68
|
+
- doc/table_of_contents.html
|
69
|
+
- lib/fps-timecode.rb
|
70
|
+
- test/test_fps-timecode.rb
|
71
|
+
homepage: http://focalpnt.com
|
72
|
+
licenses: []
|
73
|
+
metadata: {}
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.9'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubyforge_project:
|
90
|
+
rubygems_version: 2.7.4
|
91
|
+
signing_key:
|
92
|
+
specification_version: 4
|
93
|
+
summary: Implements timecode class
|
94
|
+
test_files:
|
95
|
+
- test/test_fps-timecode.rb
|