titlekit 1.2.1 → 1.2.2

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: 0712580169800d43e8659c12cbff9e28cd2a26a1
4
- data.tar.gz: 299896ab06f51dfd0b923285dabfd433cf428eb9
3
+ metadata.gz: 7b9b35e1b03b4b9643a8c75982aec3d425fb5b84
4
+ data.tar.gz: 40794f1843dd4cfbc18895dd5bffbd0a8bde6546
5
5
  SHA512:
6
- metadata.gz: 99604a85977b71bcf1a5d78b604a7b96f90984ab74fece142a78bab8c035a2bcde426d61d4d9812e3a46d7e22016c7da6b22cf6284e1efdcabac3ebfe2beeb16
7
- data.tar.gz: c28344d352367d68646fe3aa9cbede0c803f52385b163fff49bf224c072e3fa7e84454fa3bafa09b64191fe3649203f8d74ed952b9d677588e693b8a443f6a98
6
+ metadata.gz: 325f6862335038d5a8ecc03454ec35559b28aa113cdbef9b2183d5d84723e4b83cb6d15abcbee9cfa4541f1e35ab545b3a0a64fb4ef3640dee764d006ea53480
7
+ data.tar.gz: d300e60449e00888d1799d2e1e3c127bb4975f32c9f502869d609e1b62f5b9e98935800bcbdbfef1f6e9debb3a32edfc047457a627c9070d5a0f0ec3298f9c89
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  .rspec
8
8
  *.sublime-project
9
9
  *.sublime-workspace
10
+ .tags*
10
11
  .yardoc
11
12
  Gemfile.lock
12
13
  doc/
data/.travis.yml CHANGED
@@ -1,3 +1,3 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.0
3
+ - 2.2.2
data/Rakefile CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
3
-
2
+ require 'bundler/gem_tasks'
4
3
  require 'rspec/core/rake_task'
4
+
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
- task :test => :spec
8
- task :default => :spec
7
+ task test: :spec
8
+ task default: :spec
data/bin/titlekit CHANGED
@@ -7,7 +7,7 @@ if ARGV.length > 0 && (ARGV[0] == 'template' || ARGV[0] == 'templates')
7
7
  filenames += Dir.glob('**/*.ssa')
8
8
  filenames += Dir.glob('**/*.ass')
9
9
  filenames += ['generic.srt'] if filenames.empty?
10
-
10
+
11
11
  filenames.each do |filename|
12
12
 
13
13
  content = <<HERETEMPLATE
data/lib/titlekit/have.rb CHANGED
@@ -14,7 +14,7 @@ module Titlekit
14
14
  # :rchardet19 or :charlock_holmes if you have installed an additional
15
15
  # detection library and want to specifically use one or the other.
16
16
  #
17
- # @return If you omit the argument, it returns the already specified encoding
17
+ # @return If you omit the argument it returns the already specified encoding
18
18
  def encoding(*args)
19
19
  if args.empty?
20
20
  return @encoding
@@ -37,7 +37,7 @@ module Titlekit
37
37
  #
38
38
  # @example Referencing a subtitle index (ZERO-INDEXED! First subtitle is 0)
39
39
  # have.reference('Earl grey, hot', subtitle: 645)
40
- #
40
+ #
41
41
  # @example Referencing a timecode by seconds
42
42
  # have.reference('In a galaxy ...', seconds: 14.2)
43
43
  #
@@ -60,7 +60,7 @@ module Titlekit
60
60
  # @param seconds [Float]
61
61
  # @param milliseconds [Float]
62
62
  def reference(name,
63
- *args,
63
+ *_args,
64
64
  subtitle: nil,
65
65
  hours: nil,
66
66
  minutes: nil,
@@ -83,7 +83,7 @@ module Titlekit
83
83
  ass_timecode: ass_timecode)
84
84
  end
85
85
 
86
- return self
86
+ self
87
87
  end
88
88
  end
89
- end
89
+ end
data/lib/titlekit/job.rb CHANGED
@@ -18,7 +18,7 @@ module Titlekit
18
18
  # and any other unusual events that occur on the job. (regardless if it
19
19
  # failed or succeeded)
20
20
  #
21
- # @return [Array<String>] All reported messages
21
+ # @return [Array<String>] All reported messages
22
22
  attr_reader :report
23
23
 
24
24
  # Starts a new job.
@@ -39,7 +39,7 @@ module Titlekit
39
39
  require 'charlock_holmes'
40
40
  end
41
41
  rescue Gem::LoadError
42
- end
42
+ end
43
43
  end
44
44
 
45
45
  # Runs the job.
@@ -74,14 +74,14 @@ module Titlekit
74
74
  # file('path/to/my/input.srt')
75
75
  # fps(25)
76
76
  # end
77
- #
77
+ #
78
78
  # @example Using a block and providing a variable
79
79
  # job.have do |have|
80
80
  # have.encoding('utf-8')
81
81
  # have.file('path/to/my/input.srt')
82
82
  # have.fps(25)
83
83
  # end
84
- #
84
+ #
85
85
  # @example Catching the reference and assigning things at any later point
86
86
  # have = job.have
87
87
  # have.encoding('utf-8')
@@ -93,10 +93,10 @@ module Titlekit
93
93
  # have2.encoding('ISO-8859-1')
94
94
  # have2.file('path/to/my/input2.srt')
95
95
  #
96
- # @param template [Have] optionally you can specify another {Have} as a
96
+ # @param template [Have] optionally you can specify another {Have} as a
97
97
  # template, from which all properties but the file path are cloned
98
98
  # @return [Have] a reference to the newly assigned {Have}
99
- def have(*args, template: nil, &block)
99
+ def have(*_args, template: nil, &block)
100
100
  specification = Have.new
101
101
 
102
102
  if template
@@ -114,7 +114,7 @@ module Titlekit
114
114
 
115
115
  @haves << specification
116
116
 
117
- return specification
117
+ specification
118
118
  end
119
119
 
120
120
  # Adds a new {Want} specification to your job.
@@ -125,14 +125,14 @@ module Titlekit
125
125
  # file('path/to/my/output.srt')
126
126
  # fps(23.976)
127
127
  # end
128
- #
128
+ #
129
129
  # @example Using a block and providing a variable
130
130
  # job.want do |want|
131
131
  # want.encoding('utf-8')
132
132
  # want.file('path/to/my/output.srt')
133
133
  # want.fps((23.976)
134
134
  # end
135
- #
135
+ #
136
136
  # @example Catching the reference and assigning things at any later point
137
137
  # want = job.want
138
138
  # want.encoding('utf-8')
@@ -144,7 +144,7 @@ module Titlekit
144
144
  # want2.encoding('ISO-8859-1')
145
145
  # want2.file('path/to/my/output.ass')
146
146
  #
147
- # @param template [Want] optionally you can specify another {Want} as a
147
+ # @param template [Want] optionally you can specify another {Want} as a
148
148
  # template, from which all properties but the file path are cloned
149
149
  # @return [Want] a reference to the newly assigned {Want}
150
150
  def want(*args, template: nil, &block)
@@ -165,7 +165,7 @@ module Titlekit
165
165
 
166
166
  @wants << specification
167
167
 
168
- return specification
168
+ specification
169
169
  end
170
170
 
171
171
  private
@@ -188,7 +188,7 @@ module Titlekit
188
188
  data.force_encoding(detection[:encoding])
189
189
  elsif [:detect, :rchardet19].include?(have.encoding) && defined?(CharDet)
190
190
  detection = CharDet.detect(data)
191
- @report << "Assuming #{detection.encoding} for #{have.file} (detected by rchardet19 with #{(detection.confidence*100).to_i}% confidence)"
191
+ @report << "Assuming #{detection.encoding} for #{have.file} (detected by rchardet19 with #{(detection.confidence * 100).to_i}% confidence)"
192
192
  data.force_encoding(detection.encoding)
193
193
  else
194
194
  @report << "Assuming #{have.encoding} for #{have.file} (user-supplied)"
@@ -207,18 +207,19 @@ module Titlekit
207
207
  end
208
208
 
209
209
  begin
210
- have.subtitles = case File.extname(have.file)
211
- when '.ass'
212
- ASS.import(data)
213
- when '.ssa'
214
- SSA.import(data)
215
- when '.srt'
216
- SRT.import(data)
217
- when '.yt'
218
- YT.import(data)
219
- else
220
- raise 'Not supported'
221
- end
210
+ have.subtitles =
211
+ case File.extname(have.file)
212
+ when '.ass'
213
+ ASS.import(data)
214
+ when '.ssa'
215
+ SSA.import(data)
216
+ when '.srt'
217
+ SRT.import(data)
218
+ when '.yt'
219
+ YT.import(data)
220
+ else
221
+ fail 'Not supported'
222
+ end
222
223
  rescue
223
224
  @report << "Failure while importing #{File.extname(have.file)[1..3].upcase} from #{have.file}"
224
225
  raise AbortJob
@@ -240,13 +241,13 @@ module Titlekit
240
241
  end
241
242
 
242
243
  case matching_references.length
243
- when 3..(infinity = 1.0/0)
244
+ when 3..(_infinity = 1.0 / 0)
244
245
  # "synchronization jitter" correction by interpolating ? Consider !
245
246
  when 2
246
247
  retime_by_double_reference(have,
247
- want,
248
- matching_references[0],
249
- matching_references[1])
248
+ want,
249
+ matching_references[0],
250
+ matching_references[1])
250
251
  when 1
251
252
  if have.fps && want.fps
252
253
  retime_by_framerate_plus_reference(have, want, matching_references[0])
@@ -254,15 +255,13 @@ module Titlekit
254
255
  retime_by_single_reference(have, want, matching_references[0])
255
256
  end
256
257
  when 0
257
- if have.fps && want.fps
258
- retime_by_framerate(have, want)
259
- end
258
+ retime_by_framerate(have, want) if have.fps && want.fps
260
259
  end
261
260
  end
262
261
 
263
262
  # Cleans out subtitles that fell out of the usable time range
264
263
  #
265
- # @params have [Have] What we {Have}
264
+ # @params have [Have] What we {Have}
266
265
  def cull(have)
267
266
  have.subtitles.reject! { |subtitle| subtitle[:end] < 0 }
268
267
  have.subtitles.each do |subtitle|
@@ -273,7 +272,7 @@ module Titlekit
273
272
  # Assigns track identification fields for distinguishing
274
273
  # between continuous/simultaneous subtitles
275
274
  #
276
- # @params have [Have] What we {Have}
275
+ # @params have [Have] What we {Have}
277
276
  def group(have)
278
277
  if have.track
279
278
  # Assign a custom track identifier if one was supplied
@@ -332,9 +331,9 @@ module Titlekit
332
331
  # Glue subtitles ends
333
332
  want.subtitles.sort_by! { |subtitle| subtitle[:end] }
334
333
  want.subtitles.each_cons(2) do |pair|
335
- if pair[1][:end]-pair[0][:end] < want.glue_treshold
336
- pair[0][:end] += (pair[1][:end]-pair[0][:end]) / 2
337
- pair[1][:end] -= (pair[1][:end]-pair[0][:end]) / 2
334
+ if pair[1][:end] - pair[0][:end] < want.glue_treshold
335
+ pair[0][:end] += (pair[1][:end] - pair[0][:end]) / 2
336
+ pair[1][:end] -= (pair[1][:end] - pair[0][:end]) / 2
338
337
  end
339
338
  end
340
339
  end
@@ -344,22 +343,23 @@ module Titlekit
344
343
  # @param want [Want] What we {Want}
345
344
  def export(want)
346
345
  begin
347
- data = case File.extname(want.file)
348
- when '.ass'
349
- ASS.master(want.subtitles)
350
- ASS.export(want.subtitles)
351
- when '.ssa'
352
- SSA.master(want.subtitles)
353
- SSA.export(want.subtitles)
354
- when '.srt'
355
- SRT.master(want.subtitles)
356
- SRT.export(want.subtitles)
357
- when '.yt'
358
- YT.master(want.subtitles)
359
- YT.export(want.subtitles)
360
- else
361
- raise 'Not supported'
362
- end
346
+ data =
347
+ case File.extname(want.file)
348
+ when '.ass'
349
+ ASS.master(want.subtitles)
350
+ ASS.export(want.subtitles)
351
+ when '.ssa'
352
+ SSA.master(want.subtitles)
353
+ SSA.export(want.subtitles)
354
+ when '.srt'
355
+ SRT.master(want.subtitles)
356
+ SRT.export(want.subtitles)
357
+ when '.yt'
358
+ YT.master(want.subtitles)
359
+ YT.export(want.subtitles)
360
+ else
361
+ fail 'Not supported'
362
+ end
363
363
  rescue
364
364
  @report << "Failure while exporting #{File.extname(want.file)[1..3].upcase} for #{want.file}"
365
365
  raise AbortJob
@@ -389,7 +389,7 @@ module Titlekit
389
389
  #
390
390
  # @param have [Have] the subtitles we {Have}
391
391
  # @param want [Want] the subtitles we {Want}
392
- # @param reference [Symbol, String] the key of the reference
392
+ # @param reference [Symbol, String] the key of the reference
393
393
  def retime_by_single_reference(have, want, reference)
394
394
  amount = want.references[reference][:timecode] -
395
395
  have.references[reference][:timecode]
@@ -420,7 +420,7 @@ module Titlekit
420
420
  have.subtitles.each do |subtitle|
421
421
  subtitle[:start] += amount
422
422
  subtitle[:end] += amount
423
- end
423
+ end
424
424
  end
425
425
 
426
426
  # Applies a progressive timeshift on the subtitles we {Have}
@@ -435,11 +435,15 @@ module Titlekit
435
435
  # @param [Array<Float>] targets the two amounts of time by which to shift
436
436
  # either of the two points that shall be shifted
437
437
  def retime_by_double_reference(have, want, reference_a, reference_b)
438
- origins = [ have.references[reference_a][:timecode],
439
- have.references[reference_b][:timecode] ]
438
+ origins = [
439
+ have.references[reference_a][:timecode],
440
+ have.references[reference_b][:timecode]
441
+ ]
440
442
 
441
- targets = [ want.references[reference_a][:timecode],
442
- want.references[reference_b][:timecode] ]
443
+ targets = [
444
+ want.references[reference_a][:timecode],
445
+ want.references[reference_b][:timecode]
446
+ ]
443
447
 
444
448
  rescale_factor = (targets[1] - targets[0]) / (origins[1] - origins[0])
445
449
  rebase_shift = targets[0] - origins[0] * rescale_factor
@@ -462,4 +466,4 @@ module Titlekit
462
466
  end
463
467
  end
464
468
  end
465
- end
469
+ end
@@ -31,7 +31,7 @@ module Titlekit
31
31
  subtitle = {}
32
32
 
33
33
  fields = line.text_value.split(',')
34
-
34
+
35
35
  subtitle[:id] = elements.index(line) + 1
36
36
  subtitle[:start] = SSA.parse_timecode(fields[1])
37
37
  subtitle[:end] = SSA.parse_timecode(fields[2])
@@ -59,8 +59,8 @@ module Titlekit
59
59
  failure += "failure_column #{parser.failure_column}\n"
60
60
  failure += "failure_reason #{parser.failure_reason}\n"
61
61
 
62
- raise failure
63
- end
62
+ fail failure
63
+ end
64
64
  end
65
65
 
66
66
  # Master the subtitles for best possible usage of the format's features.
@@ -70,8 +70,8 @@ module Titlekit
70
70
  tracks = subtitles.map { |subtitle| subtitle[:track] }.uniq
71
71
 
72
72
  if tracks.length == 1
73
-
74
- # maybe styling? aside that: nada más!
73
+
74
+ # maybe styling? aside that: nothing more!
75
75
 
76
76
  elsif tracks.length == 2 || tracks.length == 3
77
77
 
@@ -99,21 +99,23 @@ module Titlekit
99
99
 
100
100
  frames.each do |frame|
101
101
  intersecting = subtitles.select do |subtitle|
102
- (subtitle[:end] == frame[:end] || subtitle[:start] == frame[:start] ||
103
- (subtitle[:start] < frame[:start] && subtitle[:end] > frame[:end]))
102
+ subtitle[:end] == frame[:end] ||
103
+ subtitle[:start] == frame[:start] ||
104
+ (subtitle[:start] < frame[:start] && subtitle[:end] > frame[:end])
104
105
  end
105
106
 
106
107
  if intersecting.any?
107
108
  intersecting.sort_by! { |subtitle| tracks.index(subtitle[:track]) }
108
109
  intersecting.each do |subtitle|
109
- new_subtitle = {}
110
- new_subtitle[:id] = mastered_subtitles.length+1
111
- new_subtitle[:start] = frame[:start]
112
- new_subtitle[:end] = frame[:end]
110
+ color = tracks.index(subtitle[:track]) % DEFAULT_PALETTE.length
113
111
 
114
- color = DEFAULT_PALETTE[tracks.index(subtitle[:track]) % DEFAULT_PALETTE.length]
115
- new_subtitle[:style] = color
116
- new_subtitle[:lines] = subtitle[:lines]
112
+ new_subtitle = {
113
+ id: mastered_subtitles.length + 1,
114
+ start: frame[:start],
115
+ end: frame[:end],
116
+ style: DEFAULT_PALETTE[color],
117
+ lines: subtitle[:lines]
118
+ }
117
119
 
118
120
  mastered_subtitles << new_subtitle
119
121
  end
@@ -143,9 +145,9 @@ module Titlekit
143
145
  end
144
146
 
145
147
  result << "\n" # Close styles section
146
-
148
+
147
149
  result << "[Events]\nFormat: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text\n"
148
-
150
+
149
151
  subtitles.each do |subtitle|
150
152
  fields = [
151
153
  'Dialogue: 0', # Format: Marked
@@ -156,14 +158,14 @@ module Titlekit
156
158
  '0000', # MarginL
157
159
  '0000', # MarginR
158
160
  '0000', # MarginV
159
- '',# Effect
161
+ '', # Effect
160
162
  subtitle[:lines].gsub("\n", '\N') # Text
161
163
  ]
162
164
 
163
165
  result << fields.join(',') + "\n"
164
166
  end
165
167
 
166
- return result
168
+ result
167
169
  end
168
170
 
169
171
  protected
@@ -173,11 +175,11 @@ module Titlekit
173
175
  # @param seconds [Float] an amount of seconds
174
176
  # @return [String] An ASS-formatted timecode ('h:mm:ss.ms')
175
177
  def self.build_timecode(seconds)
176
- sprintf("%01d:%02d:%02d.%s",
177
- seconds / 3600,
178
- (seconds%3600) / 60,
179
- seconds % 60,
180
- sprintf("%.2f", seconds)[-2, 3])
178
+ format('%01d:%02d:%02d.%s',
179
+ seconds / 3600,
180
+ (seconds % 3600) / 60,
181
+ seconds % 60,
182
+ format('%.2f', seconds)[-2, 3])
181
183
  end
182
184
 
183
185
  # Parses an ASS-formatted timecode into a float representing seconds
@@ -185,8 +187,8 @@ module Titlekit
185
187
  # @param timecode [String] An ASS-formatted timecode ('h:mm:ss.ms')
186
188
  # @param [Float] an amount of seconds
187
189
  def self.parse_timecode(timecode)
188
- mres = timecode.match(/(?<h>\d):(?<m>\d{2}):(?<s>\d{2})[:|\.](?<ms>\d+)/)
189
- return "#{mres["h"].to_i * 3600 + mres["m"].to_i * 60 + mres["s"].to_i}.#{mres["ms"]}".to_f
190
- end
190
+ m = timecode.match(/(?<h>\d):(?<m>\d{2}):(?<s>\d{2})[:|\.](?<ms>\d+)/)
191
+ m['h'].to_i * 3600 + m['m'].to_i * 60 + m['s'].to_i + "0.#{m['ms']}".to_f
192
+ end
191
193
  end
192
- end
194
+ end
@@ -1,5 +1,6 @@
1
1
  grammar ASS
2
2
  rule subtitles
3
+ utf8_bom?
3
4
  info?
4
5
  styles?
5
6
  event_section
@@ -10,6 +11,10 @@ grammar ASS
10
11
  <Titlekit::ASS::Subtitles>
11
12
  end
12
13
 
14
+ rule utf8_bom
15
+ "\xEF\xBB\xBF"
16
+ end
17
+
13
18
  rule info
14
19
  '[Script Info]' end_of_line lines* end_of_section <Titlekit::ASS::ScriptInfo>
15
20
  end
@@ -49,7 +54,7 @@ grammar ASS
49
54
  rule end_of_section
50
55
  end_of_line+ / end_of_file
51
56
  end
52
-
57
+
53
58
  rule end_of_line
54
59
  "\r\n" / "\n" / "\r"
55
60
  end
@@ -61,7 +66,7 @@ grammar ASS
61
66
  rule end_of_file
62
67
  !.
63
68
  end
64
-
69
+
65
70
  rule number
66
71
  [0-9]+
67
72
  end
@@ -69,4 +74,4 @@ grammar ASS
69
74
  rule string
70
75
  (!end_of_line .)+
71
76
  end
72
- end
77
+ end
@@ -6,7 +6,7 @@ module Titlekit
6
6
  # Internal intermediate class used for parsing with treetop
7
7
  class Subtitles < Treetop::Runtime::SyntaxNode
8
8
  def build
9
- elements.map { |subtitle| subtitle.build }
9
+ elements.map(&:build)
10
10
  end
11
11
  end
12
12
 
@@ -51,8 +51,8 @@ module Titlekit
51
51
  failure += "failure_column #{parser.failure_column}\n"
52
52
  failure += "failure_reason #{parser.failure_reason}\n"
53
53
 
54
- raise failure
55
- end
54
+ fail failure
55
+ end
56
56
  end
57
57
 
58
58
  # Master the subtitles for best possible usage of the format's features.
@@ -62,8 +62,8 @@ module Titlekit
62
62
  tracks = subtitles.map { |subtitle| subtitle[:track] }.uniq
63
63
 
64
64
  if tracks.length == 1
65
-
66
- # maybe styling? aside that: nada más!
65
+
66
+ # maybe styling? aside that: nothing more!
67
67
 
68
68
  elsif tracks.length >= 2
69
69
 
@@ -86,7 +86,7 @@ module Titlekit
86
86
  intersecting.sort_by! { |subtitle| tracks.index(subtitle[:track]) }
87
87
 
88
88
  subtitle = {}
89
- subtitle[:id] = mastered_subtitles.length+1
89
+ subtitle[:id] = mastered_subtitles.length + 1
90
90
  subtitle[:start] = frame[:start]
91
91
  subtitle[:end] = frame[:end]
92
92
 
@@ -116,7 +116,7 @@ module Titlekit
116
116
  result = ''
117
117
 
118
118
  subtitles.each_with_index do |subtitle, index|
119
- result << (index+1).to_s
119
+ result << (index + 1).to_s
120
120
  result << "\n"
121
121
  result << SRT.build_timecode(subtitle[:start])
122
122
  result << ' --> '
@@ -126,7 +126,7 @@ module Titlekit
126
126
  result << "\n\n"
127
127
  end
128
128
 
129
- return result
129
+ result
130
130
  end
131
131
 
132
132
  protected
@@ -136,11 +136,11 @@ module Titlekit
136
136
  # @param seconds [Float] an amount of seconds
137
137
  # @return [String] An SRT-formatted timecode ('hh:mm:ss,ms')
138
138
  def self.build_timecode(seconds)
139
- sprintf("%02d:%02d:%02d,%s",
140
- seconds / 3600,
141
- (seconds%3600) / 60,
142
- seconds % 60,
143
- sprintf("%.3f", seconds)[-3, 3])
139
+ format('%02d:%02d:%02d,%s',
140
+ seconds / 3600,
141
+ (seconds % 3600) / 60,
142
+ seconds % 60,
143
+ format('%.3f', seconds)[-3, 3])
144
144
  end
145
145
 
146
146
  # Parses an SRT-formatted timecode into a float representing seconds
@@ -149,7 +149,7 @@ module Titlekit
149
149
  # @param [Float] an amount of seconds
150
150
  def self.parse_timecode(timecode)
151
151
  mres = timecode.match(/(?<h>\d+):(?<m>\d+):(?<s>\d+),(?<ms>\d+)/)
152
- "#{mres["h"].to_i * 3600 + mres["m"].to_i * 60 + mres["s"].to_i}.#{mres["ms"]}".to_f
152
+ "#{mres['h'].to_i * 3600 + mres['m'].to_i * 60 + mres['s'].to_i}.#{mres['ms']}".to_f
153
153
  end
154
154
  end
155
- end
155
+ end