srt 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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