srt 0.0.2 → 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.
data/README.md CHANGED
@@ -27,6 +27,22 @@ You can parse an SRT file with the following code:
27
27
  end
28
28
  ```
29
29
 
30
+ `timeshift` let's you constantly shift all subtitle timecodes:
31
+
32
+ ```ruby
33
+ file.timeshift(-2.5) # resynchronize subtitles so they show up 2.5 seconds earlier
34
+ ```
35
+
36
+ `linear_progressive_timeshift` allows progressive timeshifting, e.g. to account for time-drift
37
+ caused by subtitles that were created for a video version with a different framerate:
38
+
39
+ ```ruby
40
+ file.linear_progressive_timeshift(60, 70, 2700, 2760)
41
+ ```
42
+
43
+ This applies a timeshift of 10 seconds at minute #1 (60 => 70),
44
+ then progressively more towards a 60 second shift by minute #45 (2700 => 2760)
45
+
30
46
  ## Contributing
31
47
 
32
48
  1. Fork it
data/lib/srt.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  require "srt/file"
2
2
  require "srt/line"
3
- require "srt/version"
3
+ require "srt/version"
@@ -17,10 +17,10 @@ module SRT
17
17
  elsif line.sequence.nil?
18
18
  line.sequence = str.to_i
19
19
  elsif line.start_time.nil?
20
- matcher = str.match(/(.*) -+> (.*)/)
21
- if matcher
22
- line.start_time = DateTime.strptime(matcher[1].strip, "%H:%M:%S,%L")
23
- line.end_time = DateTime.strptime(matcher[2].strip, "%H:%M:%S,%L")
20
+ mres = str.match(/(\d+):(\d+):(\d+),(\d+) -+> (\d+):(\d+):(\d+),(\d+)/)
21
+ if mres
22
+ line.start_time = "#{mres[1].to_i * 3600 + mres[2].to_i * 60 + mres[3].to_i}.#{mres[4]}".to_f
23
+ line.end_time = "#{mres[5].to_i * 3600 + mres[6].to_i * 60 + mres[7].to_i}.#{mres[8]}".to_f
24
24
  else
25
25
  line.error = "#{line}, Invalid Time String, [#{str}]"
26
26
  end
@@ -36,18 +36,31 @@ module SRT
36
36
  result
37
37
  end
38
38
 
39
- def to_s
40
- result = []
39
+ def timeshift(seconds)
40
+ lines.each do |line|
41
+ line.start_time += seconds unless line.start_time + seconds < 0
42
+ line.end_time += seconds unless line.end_time + seconds < 0
43
+ end
44
+ end
45
+
46
+ def linear_progressive_timeshift(reference_time_a, target_time_a, reference_time_b, target_time_b)
47
+ time_rescale_factor = (target_time_b - target_time_a) / (reference_time_b - reference_time_a)
48
+ time_rebase_shift = target_time_a - reference_time_a * time_rescale_factor
49
+
41
50
  lines.each do |line|
42
- result << line.sequence
43
- result << line.time_str
44
- result += line.text
45
- result << ""
51
+ line.start_time *= time_rescale_factor
52
+ line.start_time += time_rebase_shift
53
+ line.end_time *= time_rescale_factor
54
+ line.end_time += time_rebase_shift
46
55
  end
47
- result.join("\n")
56
+ end
57
+
58
+ def to_s
59
+ lines.map{ |l| [l.sequence, l.time_str, l.text, ""] }.flatten.join("\n")
48
60
  end
49
61
 
50
62
  attr_writer :lines
63
+
51
64
  def lines
52
65
  @lines ||= []
53
66
  end
@@ -56,4 +69,4 @@ module SRT
56
69
  lines.collect { |l| l.error if l.error }.compact
57
70
  end
58
71
  end
59
- end
72
+ end
@@ -5,6 +5,7 @@ module SRT
5
5
  attr_accessor :end_time
6
6
  attr_accessor :error
7
7
  attr_writer :text
8
+
8
9
  def text
9
10
  @text ||= []
10
11
  end
@@ -20,9 +21,7 @@ module SRT
20
21
  end
21
22
 
22
23
  def time_str
23
- s = start_time ? start_time.strftime("%H:%M:%S,%L") : ""
24
- e = end_time ? end_time.strftime("%H:%M:%S,%L") : ""
25
- "#{s} --> #{e}"
24
+ [@start_time, @end_time].map { |t| sprintf("%02d:%02d:%02d,%s", t / 3600, (t % 3600) / 60, t % 60, sprintf("%.3f", t)[-3, 3]) }.join(" --> ")
26
25
  end
27
26
  end
28
27
  end
@@ -1,3 +1,3 @@
1
1
  module SRT
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -3,23 +3,23 @@ require 'srt'
3
3
  describe SRT do
4
4
  context "A single line" do
5
5
  let(:line) { SRT::Line.new }
6
- it "should be empty" do
6
+ it "should initially be empty" do
7
7
  line.should be_empty
8
8
  end
9
9
 
10
- it "should not be empty" do
11
- line.text = "This is a test"
10
+ it "should not be empty after inserting text" do
11
+ line.text = ["This is a test"]
12
12
  line.should_not be_empty
13
13
  end
14
14
 
15
- it "should have the correct time string" do
16
- line.start_time = DateTime.strptime("00:00:02,110", "%H:%M:%S,%L")
17
- line.end_time = DateTime.strptime("00:00:04,578", "%H:%M:%S,%L")
15
+ it "should print a time string that corresponds to its internal time values" do
16
+ line.start_time = 2.110
17
+ line.end_time = 4.578
18
18
  line.time_str.should == "00:00:02,110 --> 00:00:04,578"
19
19
  end
20
20
  end
21
21
 
22
- context "A properly formatted SRT file" do
22
+ context "This given, properly formatted BSG SRT file" do
23
23
  let(:file) { SRT::File.parse(File.open("./spec/bsg-s01e01.srt")) }
24
24
 
25
25
  it "should parse" do
@@ -34,46 +34,31 @@ describe SRT do
34
34
  file.errors.should be_empty
35
35
  end
36
36
 
37
- context "the first line" do
38
- let(:line) { file.lines.first }
39
-
40
- it "should have the proper text" do
41
- line.text.should == ["<i>(male narrator) Previously", "on Battlestar Galactica.</i>"]
42
- end
43
-
44
- it "should have the proper sequence" do
45
- line.sequence.should == 1
46
- end
47
-
48
- it "should have the proper start time" do
49
- line.start_time.strftime("%H:%M:%S,%L").should == "00:00:02,110"
50
- end
51
-
52
- it "should have the proper end time" do
53
- line.end_time.strftime("%H:%M:%S,%L").should == "00:00:04,578"
54
- end
37
+ it "should have the expected data on the first line" do
38
+ file.lines.first.sequence.should == 1
39
+ file.lines.first.time_str.should == "00:00:02,110 --> 00:00:04,578"
40
+ file.lines.first.text.should == ["<i>(male narrator) Previously", "on Battlestar Galactica.</i>"]
55
41
  end
56
-
57
- context "the last line" do
58
- let(:line) { file.lines.last }
59
42
 
60
- it "should have the proper text" do
61
- line.text.should == ["Thank you."]
62
- end
63
-
64
- it "should have the proper sequence" do
65
- line.sequence.should == 600
66
- end
43
+ it "should have the expected data on the last line" do
44
+ file.lines.last.sequence.should == 600
45
+ file.lines.last.time_str.should == "00:43:26,808 --> 00:43:28,139"
46
+ file.lines.last.text.should == ["Thank you."]
47
+ end
67
48
 
68
- it "should have the proper start time" do
69
- line.start_time.strftime("%H:%M:%S,%L").should == "00:43:26,808"
70
- end
49
+ it "should have equally shifted time strings on every line after a timeshift" do
50
+ file.timeshift(2.5)
51
+ file.lines[23].time_str.should == "00:01:59,291 --> 00:02:00,815"
52
+ file.lines[42].time_str.should == "00:03:46,164 --> 00:03:47,631"
53
+ end
71
54
 
72
- it "should have the proper end time" do
73
- line.end_time.strftime("%H:%M:%S,%L").should == "00:43:28,139"
74
- end
55
+ it "should have inequally shifted time strings on every line after a linear progressive timeshift" do
56
+ file.linear_progressive_timeshift(116.791, 233.582, 223.664, 894.656)
57
+ file.lines[23].time_str.should == "00:03:53,582 --> 00:04:03,009"
58
+ file.lines[42].time_str.should == "00:14:54,656 --> 00:15:03,730"
75
59
  end
76
60
  end
61
+
77
62
  context "A short SRT file" do
78
63
  let(:file) {
79
64
  file = SRT::File.parse(File.open("./spec/bsg-s01e01.srt"))
@@ -100,4 +85,4 @@ END
100
85
  file.to_s.should == OUTPUT
101
86
  end
102
87
  end
103
- end
88
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: srt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-24 00:00:00.000000000 Z
12
+ date: 2013-03-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -78,7 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
78
78
  version: '0'
79
79
  segments:
80
80
  - 0
81
- hash: -853641562359327815
81
+ hash: 1537061197580400019
82
82
  required_rubygems_version: !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
@@ -87,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
87
  version: '0'
88
88
  segments:
89
89
  - 0
90
- hash: -853641562359327815
90
+ hash: 1537061197580400019
91
91
  requirements: []
92
92
  rubyforge_project:
93
93
  rubygems_version: 1.8.24