titlekit 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +3 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +335 -0
- data/Rakefile +8 -0
- data/lib/titlekit/have.rb +90 -0
- data/lib/titlekit/job.rb +446 -0
- data/lib/titlekit/parsers/ass.rb +175 -0
- data/lib/titlekit/parsers/ass.treetop +72 -0
- data/lib/titlekit/parsers/srt.rb +139 -0
- data/lib/titlekit/parsers/srt.treetop +73 -0
- data/lib/titlekit/parsers/ssa.rb +201 -0
- data/lib/titlekit/parsers/ssa.treetop +72 -0
- data/lib/titlekit/specification.rb +131 -0
- data/lib/titlekit/utilities.rb +3 -0
- data/lib/titlekit/version.rb +3 -0
- data/lib/titlekit/want.rb +24 -0
- data/lib/titlekit.rb +9 -0
- data/spec/ass_spec.rb +113 -0
- data/spec/automatic_grouping/automatic_grouping_spec.rb +55 -0
- data/spec/automatic_grouping/dual_tracks/expected.srt +15 -0
- data/spec/automatic_grouping/dual_tracks/one.srt +11 -0
- data/spec/automatic_grouping/dual_tracks/out.srt +15 -0
- data/spec/automatic_grouping/dual_tracks/two.srt +11 -0
- data/spec/automatic_grouping/single_track/expected.srt +24 -0
- data/spec/automatic_grouping/single_track/one.srt +11 -0
- data/spec/automatic_grouping/single_track/out.srt +24 -0
- data/spec/automatic_grouping/single_track/two.srt +11 -0
- data/spec/encoding_detection/a/in.ass +0 -0
- data/spec/encoding_detection/b/in.srt +2389 -0
- data/spec/encoding_detection/b/out.srt +2389 -0
- data/spec/encoding_detection/c/in.srt +5320 -0
- data/spec/encoding_detection/c/out.srt +5320 -0
- data/spec/encoding_detection/encoding_detection_spec.rb +81 -0
- data/spec/files/ass/authentic.ass +0 -0
- data/spec/files/ass/hard.ass +37 -0
- data/spec/files/ass/simple.ass +28 -0
- data/spec/files/srt/authentic.srt +2708 -0
- data/spec/files/srt/coordinates.srt +13 -0
- data/spec/files/srt/simple.srt +12 -0
- data/spec/files/ssa/simple.ssa +26 -0
- data/spec/files/try/unsupported-output.try +0 -0
- data/spec/files/try/unsupported.try +7 -0
- data/spec/format_conversion/ass_srt/expected.srt +2327 -0
- data/spec/format_conversion/ass_srt/in.ass +485 -0
- data/spec/format_conversion/ass_srt/out.srt +2327 -0
- data/spec/format_conversion/format_conversion_spec.rb +112 -0
- data/spec/format_conversion/srt_ass/expected.ass +19 -0
- data/spec/format_conversion/srt_ass/in.srt +12 -0
- data/spec/format_conversion/srt_ass/out.ass +19 -0
- data/spec/format_conversion/srt_ssa/expected.ssa +19 -0
- data/spec/format_conversion/srt_ssa/in.srt +12 -0
- data/spec/format_conversion/srt_ssa/out.ssa +19 -0
- data/spec/format_conversion/ssa_srt/expected.srt +9 -0
- data/spec/format_conversion/ssa_srt/in.ssa +26 -0
- data/spec/format_conversion/ssa_srt/out.srt +9 -0
- data/spec/job_spec.rb +162 -0
- data/spec/simultaneous_subtitles/dual/ass/expected.ass +22 -0
- data/spec/simultaneous_subtitles/dual/ass/out.ass +22 -0
- data/spec/simultaneous_subtitles/dual/one.srt +11 -0
- data/spec/simultaneous_subtitles/dual/srt/expected.srt +27 -0
- data/spec/simultaneous_subtitles/dual/srt/out.srt +27 -0
- data/spec/simultaneous_subtitles/dual/ssa/expected.ssa +22 -0
- data/spec/simultaneous_subtitles/dual/ssa/out.ssa +22 -0
- data/spec/simultaneous_subtitles/dual/two.srt +11 -0
- data/spec/simultaneous_subtitles/simultaneous_subtitles_spec.rb +220 -0
- data/spec/simultaneous_subtitles/triple/ass/expected.ass +25 -0
- data/spec/simultaneous_subtitles/triple/ass/out.ass +25 -0
- data/spec/simultaneous_subtitles/triple/one.srt +11 -0
- data/spec/simultaneous_subtitles/triple/srt/expected.srt +55 -0
- data/spec/simultaneous_subtitles/triple/srt/out.srt +55 -0
- data/spec/simultaneous_subtitles/triple/ssa/expected.ssa +25 -0
- data/spec/simultaneous_subtitles/triple/ssa/out.ssa +25 -0
- data/spec/simultaneous_subtitles/triple/three.srt +11 -0
- data/spec/simultaneous_subtitles/triple/two.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/ass/expected.ass +93 -0
- data/spec/simultaneous_subtitles/triple_plus/ass/out.ass +93 -0
- data/spec/simultaneous_subtitles/triple_plus/five.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/four.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/one.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/six.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/srt/expected.srt +149 -0
- data/spec/simultaneous_subtitles/triple_plus/srt/out.srt +149 -0
- data/spec/simultaneous_subtitles/triple_plus/ssa/expected.ssa +93 -0
- data/spec/simultaneous_subtitles/triple_plus/ssa/out.ssa +93 -0
- data/spec/simultaneous_subtitles/triple_plus/three.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/two.srt +11 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/specifications_spec.rb +138 -0
- data/spec/srt_spec.rb +134 -0
- data/spec/ssa_spec.rb +90 -0
- data/spec/timecode_correction/double_reference/expected.srt +13 -0
- data/spec/timecode_correction/double_reference/in.srt +12 -0
- data/spec/timecode_correction/double_reference/out.srt +13 -0
- data/spec/timecode_correction/framerate/expected.srt +5 -0
- data/spec/timecode_correction/framerate/in.srt +4 -0
- data/spec/timecode_correction/framerate/out.srt +5 -0
- data/spec/timecode_correction/framerate_plus_reference/expected.srt +13 -0
- data/spec/timecode_correction/framerate_plus_reference/in.srt +12 -0
- data/spec/timecode_correction/framerate_plus_reference/out.srt +13 -0
- data/spec/timecode_correction/single_reference/expected.srt +13 -0
- data/spec/timecode_correction/single_reference/in.srt +12 -0
- data/spec/timecode_correction/single_reference/out.srt +13 -0
- data/spec/timecode_correction/timecode_correction_spec.rb +124 -0
- data/spec/transcoding/gb2312-ascii/in.srt +12 -0
- data/spec/transcoding/iso-8859-1_utf-8/expected.srt +12 -0
- data/spec/transcoding/iso-8859-1_utf-8/in.srt +11 -0
- data/spec/transcoding/iso-8859-1_utf-8/out.srt +12 -0
- data/spec/transcoding/transcoding_spec.rb +116 -0
- data/spec/transcoding/utf-8_gbk/expected.srt +12 -0
- data/spec/transcoding/utf-8_gbk/in.srt +11 -0
- data/spec/transcoding/utf-8_gbk/out.srt +12 -0
- data/spec/transcoding/windows-1252_utf-8/expected.srt +12 -0
- data/spec/transcoding/windows-1252_utf-8/in.srt +11 -0
- data/spec/transcoding/windows-1252_utf-8/out.srt +12 -0
- data/titlekit.gemspec +28 -0
- metadata +313 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
require File.join(File.expand_path(__dir__), 'spec_helper')
|
2
|
+
|
3
|
+
shared_examples 'a specification' do
|
4
|
+
|
5
|
+
describe '#new' do
|
6
|
+
it 'creates a new specification' do
|
7
|
+
expect(described_class.new).to be_a_kind_of(described_class)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#encoding' do
|
12
|
+
let(:specification) do
|
13
|
+
described_class.new.encoding('utf-8')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'returns the specification' do
|
17
|
+
expect(specification).to be_a_kind_of(described_class)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns the set encoding' do
|
21
|
+
expect(specification.encoding).to eq('utf-8')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#file' do
|
26
|
+
let(:specification) do
|
27
|
+
described_class.new.file('the/path.srt')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns the specification' do
|
31
|
+
expect(specification).to be_a_kind_of(described_class)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns the set path' do
|
35
|
+
expect(specification.file).to eq('the/path.srt')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#fps' do
|
40
|
+
let(:specification) do
|
41
|
+
described_class.new.fps(25)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns the specification' do
|
45
|
+
expect(specification).to be_a_kind_of(described_class)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns the set framerate' do
|
49
|
+
expect(specification.fps).to eq(25)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#reference' do
|
54
|
+
context 'specifying a minute' do
|
55
|
+
let(:specification) do
|
56
|
+
described_class.new.reference(:some_point, minutes: 3.5)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'returns the specification' do
|
60
|
+
expect(specification).to be_a_kind_of(described_class)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'returns the set named reference for a timecode' do
|
64
|
+
expect(specification.references[:some_point][:timecode]).to eq(210)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'specifying an SRT timecode' do
|
69
|
+
let(:specification) do
|
70
|
+
described_class.new.reference(:some_point, srt_timecode: '00:03:30,000')
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns the specification' do
|
74
|
+
expect(specification).to be_a_kind_of(described_class)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'returns the set named reference for a timecode' do
|
78
|
+
expect(specification.references[:some_point][:timecode]).to eq(210)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'specifying an ASS timecode' do
|
83
|
+
let(:specification) do
|
84
|
+
described_class.new.reference(:some_point, ass_timecode: '0:03:30.00')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns the specification' do
|
88
|
+
expect(specification).to be_a_kind_of(described_class)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'returns the set named reference for a timecode' do
|
92
|
+
expect(specification.references[:some_point][:timecode]).to eq(210)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'specifying an SSA timecode' do
|
97
|
+
let(:specification) do
|
98
|
+
described_class.new.reference(:some_point, ssa_timecode: '0:03:30.00')
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'returns the specification' do
|
102
|
+
expect(specification).to be_a_kind_of(described_class)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'returns the set named reference for a timecode' do
|
106
|
+
expect(specification.references[:some_point][:timecode]).to eq(210)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe Titlekit::Specification do
|
113
|
+
it_behaves_like 'a specification'
|
114
|
+
end
|
115
|
+
|
116
|
+
describe Titlekit::Have do
|
117
|
+
it_behaves_like 'a specification'
|
118
|
+
|
119
|
+
describe '#reference' do
|
120
|
+
context 'specifying a subtitle' do
|
121
|
+
let(:specification) do
|
122
|
+
described_class.new.reference(:some_point, subtitle: 23)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'returns the specification' do
|
126
|
+
expect(specification).to be_a_kind_of(described_class)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'returns the set named reference for a subtitle' do
|
130
|
+
expect(specification.references[:some_point][:subtitle]).to eq(23)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe Titlekit::Want do
|
137
|
+
it_behaves_like 'a specification'
|
138
|
+
end
|
data/spec/srt_spec.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
require File.join(File.expand_path(__dir__), 'spec_helper')
|
2
|
+
|
3
|
+
describe Titlekit::SRT do
|
4
|
+
|
5
|
+
describe '.import' do
|
6
|
+
|
7
|
+
context 'with a simple file' do
|
8
|
+
let(:subtitles) do
|
9
|
+
Titlekit::SRT.import(File.read('spec/files/srt/simple.srt'))
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'parses and builds 3 subtitles' do
|
13
|
+
expect(subtitles.length).to eq(3)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'parses and builds correct ids' do
|
17
|
+
expect(subtitles[0][:id]).to eq(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'parses and builds correct timecodes' do
|
21
|
+
expect(subtitles[1][:start]).to eq(24)
|
22
|
+
expect(subtitles[1][:end]).to eq(37.8)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'parses and builds correct lines' do
|
26
|
+
expect(subtitles[2][:lines]).to eq("- I ...\n- Enough!!!")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with an authentic file' do
|
31
|
+
let(:subtitles) do
|
32
|
+
Titlekit::SRT.import(File.read('spec/files/srt/authentic.srt'))
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'parses and builds 600 subtitles' do
|
36
|
+
expect(subtitles.length).to eq(600)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'parses and builds correct ids' do
|
40
|
+
expect(subtitles[599][:id]).to eq(600)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'parses and builds correct timecodes' do
|
44
|
+
expect(subtitles[299][:start]).to eq(1426.564)
|
45
|
+
expect(subtitles[299][:end]).to eq(1428.759)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'parses and builds correct lines' do
|
49
|
+
expect(subtitles[0][:lines]).to eq("<i>(male narrator) Previously\r\non Battlestar Galactica.</i>")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'with a file that contains coordinates' do
|
54
|
+
let(:subtitles) do
|
55
|
+
Titlekit::SRT.import(File.read('spec/files/srt/coordinates.srt'))
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'parses and builds 3 subtitles' do
|
59
|
+
expect(subtitles.length).to eq(3)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'parses and builds correct ids' do
|
63
|
+
expect(subtitles[0][:id]).to eq(1)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'parses and builds correct timecodes' do
|
67
|
+
expect(subtitles[1][:start]).to eq(16)
|
68
|
+
expect(subtitles[1][:end]).to eq(32)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'parses and builds correct lines' do
|
72
|
+
expect(subtitles[2][:lines]).to eq("A: Still I'm implementing them; Whatevs.")
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'ignores the display coordinates' do
|
76
|
+
# just fyi
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '.export' do
|
82
|
+
it 'should export valid SRT' do
|
83
|
+
subtitles = [
|
84
|
+
{
|
85
|
+
id: 1,
|
86
|
+
start: 1.5,
|
87
|
+
end: 3.7,
|
88
|
+
lines: 'Eine feine Testung haben sie da!'
|
89
|
+
},
|
90
|
+
{
|
91
|
+
id: 2,
|
92
|
+
start: 1.5,
|
93
|
+
end: 3.7,
|
94
|
+
lines: '¡Sí claro! Pero que lastima que no es 100% español ...'
|
95
|
+
},
|
96
|
+
{
|
97
|
+
id: 3,
|
98
|
+
start: 1.5,
|
99
|
+
end: 3.7,
|
100
|
+
lines: 'Oh yeah ... 寧為太平犬,不做亂世人'
|
101
|
+
}
|
102
|
+
]
|
103
|
+
|
104
|
+
expected = <<-EXPECTED
|
105
|
+
1
|
106
|
+
00:00:01,500 --> 00:00:03,700
|
107
|
+
Eine feine Testung haben sie da!
|
108
|
+
|
109
|
+
2
|
110
|
+
00:00:01,500 --> 00:00:03,700
|
111
|
+
¡Sí claro! Pero que lastima que no es 100% español ...
|
112
|
+
|
113
|
+
3
|
114
|
+
00:00:01,500 --> 00:00:03,700
|
115
|
+
Oh yeah ... 寧為太平犬,不做亂世人
|
116
|
+
|
117
|
+
EXPECTED
|
118
|
+
|
119
|
+
expect(Titlekit::SRT.export(subtitles)).to eq(expected)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe '.build_timecode' do
|
124
|
+
it 'builds an SRT timecode from a float timecode value' do
|
125
|
+
expect(Titlekit::SRT.build_timecode(35.9678)).to eq('00:00:35,968')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '.parse_timecode' do
|
130
|
+
it 'obtains a float timecode value from an SRT timecode' do
|
131
|
+
expect(Titlekit::SRT.parse_timecode('00:00:35,968')).to eq(35.968)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/spec/ssa_spec.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.join(File.expand_path(__dir__), 'spec_helper')
|
2
|
+
|
3
|
+
describe Titlekit::SSA do
|
4
|
+
|
5
|
+
describe '.import' do
|
6
|
+
|
7
|
+
context 'with a simple file' do
|
8
|
+
let(:subtitles) do
|
9
|
+
Titlekit::SSA.import(File.read('spec/files/ssa/simple.ssa'))
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'parses and builds 3 subtitles' do
|
13
|
+
expect(subtitles.length).to eq(2)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'parses and builds correct ids' do
|
17
|
+
expect(subtitles[0][:id]).to eq(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'parses and builds correct timecodes' do
|
21
|
+
expect(subtitles[1][:start]).to eq(11.84)
|
22
|
+
expect(subtitles[1][:end]).to eq(14.74)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'parses and builds correct lines' do
|
26
|
+
expect(subtitles[1][:lines]).to eq("{\\a2}Story Script & Direction - MIYAZAKI Hayao")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.export' do
|
32
|
+
it 'should export valid SSA' do
|
33
|
+
subtitles = [
|
34
|
+
{
|
35
|
+
start: 1.5,
|
36
|
+
end: 3.7,
|
37
|
+
lines: 'Eine feine Testung haben sie da!'
|
38
|
+
},
|
39
|
+
{
|
40
|
+
id: 2,
|
41
|
+
start: 1.5,
|
42
|
+
end: 3.7,
|
43
|
+
lines: '¡Sí claro! Pero que lastima que no es 100% español ...'
|
44
|
+
},
|
45
|
+
{
|
46
|
+
id: 3,
|
47
|
+
start: 1.5,
|
48
|
+
end: 3.7,
|
49
|
+
lines: 'Oh yeah ... 寧為太平犬,不做亂世人'
|
50
|
+
}
|
51
|
+
]
|
52
|
+
|
53
|
+
expected = <<-EXPECTED
|
54
|
+
[Script Info]
|
55
|
+
ScriptType: v4.00
|
56
|
+
|
57
|
+
[V4 Styles]
|
58
|
+
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding
|
59
|
+
Style: Default,Arial,16,16777215,16777215,16777215,-2147483640,0,0,1,3,0,2,70,70,40,0,0
|
60
|
+
Style: Middle,Arial,16,16777215,16777215,16777215,-2147483640,0,0,1,3,0,10,70,70,40,0,0
|
61
|
+
Style: Top,Arial,16,16777215,16777215,16777215,-2147483640,0,0,1,3,0,6,70,70,40,0,0
|
62
|
+
Style: EDF393,Arial,16,9696237,9696237,9696237,-2147483640,0,0,1,3,0,2,70,70,40,0,0
|
63
|
+
Style: F5E665,Arial,16,6678261,6678261,6678261,-2147483640,0,0,1,3,0,2,70,70,40,0,0
|
64
|
+
Style: FFC472,Arial,16,7521535,7521535,7521535,-2147483640,0,0,1,3,0,2,70,70,40,0,0
|
65
|
+
Style: FFA891,Arial,16,9545983,9545983,9545983,-2147483640,0,0,1,3,0,2,70,70,40,0,0
|
66
|
+
Style: 89BABE,Arial,16,12499593,12499593,12499593,-2147483640,0,0,1,3,0,2,70,70,40,0,0
|
67
|
+
|
68
|
+
[Events]
|
69
|
+
Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
|
70
|
+
Dialogue: 0,0:00:01.50,0:00:03.70,Default,,0000,0000,0000,,Eine feine Testung haben sie da!
|
71
|
+
Dialogue: 0,0:00:01.50,0:00:03.70,Default,,0000,0000,0000,,¡Sí claro! Pero que lastima que no es 100% español ...
|
72
|
+
Dialogue: 0,0:00:01.50,0:00:03.70,Default,,0000,0000,0000,,Oh yeah ... 寧為太平犬,不做亂世人
|
73
|
+
EXPECTED
|
74
|
+
|
75
|
+
expect(Titlekit::SSA.export(subtitles)).to eq(expected)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '.build_timecode' do
|
80
|
+
it 'builds an SSA timecode from a float timecode value' do
|
81
|
+
expect(Titlekit::SSA.build_timecode(35.9678)).to eq('0:00:35.97')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '.parse_timecode' do
|
86
|
+
it 'obtains a float timecode value from an SSA timecode' do
|
87
|
+
expect(Titlekit::SSA.parse_timecode('0:00:35.96')).to eq(35.96)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require File.join(File.expand_path(__dir__), '../spec_helper')
|
2
|
+
|
3
|
+
describe Titlekit::Job do
|
4
|
+
|
5
|
+
describe 'Timecode correction' do
|
6
|
+
|
7
|
+
context 'Based on differing framerates' do
|
8
|
+
before(:all) do
|
9
|
+
@in = File.join(__dir__, 'framerate', 'in.srt')
|
10
|
+
@out = File.join(__dir__, 'framerate', 'out.srt')
|
11
|
+
@expected = File.join(__dir__, 'framerate', 'expected.srt')
|
12
|
+
|
13
|
+
File.delete(@out) if File.exist?(@out)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'runs the job' do
|
17
|
+
job = Titlekit::Job.new
|
18
|
+
|
19
|
+
have = job.have
|
20
|
+
have.file(@in)
|
21
|
+
have.fps(25)
|
22
|
+
|
23
|
+
want = job.want
|
24
|
+
want.file(@out)
|
25
|
+
want.fps(30)
|
26
|
+
|
27
|
+
expect(job.run).to be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'delivers the expected output' do
|
31
|
+
expect(FileUtils.compare_file(@out, @expected)).to be_true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'Based on a single reference' do
|
36
|
+
before(:all) do
|
37
|
+
@in = File.join(__dir__, 'single_reference', 'in.srt')
|
38
|
+
@out = File.join(__dir__, 'single_reference', 'out.srt')
|
39
|
+
@expected = File.join(__dir__, 'single_reference', 'expected.srt')
|
40
|
+
|
41
|
+
File.delete(@out) if File.exist?(@out)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'runs the job' do
|
45
|
+
job = Titlekit::Job.new
|
46
|
+
|
47
|
+
have = job.have
|
48
|
+
have.file(@in)
|
49
|
+
have.reference('first subtitle', seconds: 2)
|
50
|
+
|
51
|
+
want = job.want
|
52
|
+
want.file(@out)
|
53
|
+
want.reference('first subtitle', seconds: 3.5)
|
54
|
+
|
55
|
+
expect(job.run).to be_true
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'delivers the expected output' do
|
59
|
+
expect(FileUtils.compare_file(@out, @expected)).to be_true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'Based on differing framerates plus a reference' do
|
64
|
+
before(:all) do
|
65
|
+
@in = File.join(__dir__, 'framerate_plus_reference', 'in.srt')
|
66
|
+
@out = File.join(__dir__, 'framerate_plus_reference', 'out.srt')
|
67
|
+
@expected = File.join(__dir__, 'framerate_plus_reference', 'expected.srt')
|
68
|
+
|
69
|
+
File.delete(@out) if File.exist?(@out)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'runs the job' do
|
73
|
+
job = Titlekit::Job.new
|
74
|
+
|
75
|
+
have = job.have
|
76
|
+
have.file(@in)
|
77
|
+
have.fps(25)
|
78
|
+
have.reference('first subtitle', subtitle: 0)
|
79
|
+
|
80
|
+
want = job.want
|
81
|
+
want.file(@out)
|
82
|
+
have.fps(23.976)
|
83
|
+
want.reference('first subtitle', seconds: 3.5)
|
84
|
+
|
85
|
+
expect(job.run).to be_true
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'delivers the expected output' do
|
89
|
+
expect(FileUtils.compare_file(@out, @expected)).to be_true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'Based on two references' do
|
94
|
+
before(:all) do
|
95
|
+
@in = File.join(__dir__, 'double_reference', 'in.srt')
|
96
|
+
@out = File.join(__dir__, 'double_reference', 'out.srt')
|
97
|
+
@expected = File.join(__dir__, 'double_reference', 'expected.srt')
|
98
|
+
|
99
|
+
File.delete(@out) if File.exist?(@out)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'runs the job' do
|
103
|
+
job = Titlekit::Job.new
|
104
|
+
|
105
|
+
have = job.have
|
106
|
+
have.file(@in)
|
107
|
+
have.reference('first subtitle', seconds: 2.364)
|
108
|
+
have.reference('last subtitle', seconds: 24)
|
109
|
+
|
110
|
+
want = job.want
|
111
|
+
want.file(@out)
|
112
|
+
want.reference('first subtitle', seconds: 2.4)
|
113
|
+
want.reference('last subtitle', seconds: 32)
|
114
|
+
|
115
|
+
expect(job.run).to be_true
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'delivers the expected output' do
|
119
|
+
expect(FileUtils.compare_file(@out, @expected)).to be_true
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|