titlekit 1.0.0

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.
Files changed (119) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +22 -0
  6. data/README.md +335 -0
  7. data/Rakefile +8 -0
  8. data/lib/titlekit/have.rb +90 -0
  9. data/lib/titlekit/job.rb +446 -0
  10. data/lib/titlekit/parsers/ass.rb +175 -0
  11. data/lib/titlekit/parsers/ass.treetop +72 -0
  12. data/lib/titlekit/parsers/srt.rb +139 -0
  13. data/lib/titlekit/parsers/srt.treetop +73 -0
  14. data/lib/titlekit/parsers/ssa.rb +201 -0
  15. data/lib/titlekit/parsers/ssa.treetop +72 -0
  16. data/lib/titlekit/specification.rb +131 -0
  17. data/lib/titlekit/utilities.rb +3 -0
  18. data/lib/titlekit/version.rb +3 -0
  19. data/lib/titlekit/want.rb +24 -0
  20. data/lib/titlekit.rb +9 -0
  21. data/spec/ass_spec.rb +113 -0
  22. data/spec/automatic_grouping/automatic_grouping_spec.rb +55 -0
  23. data/spec/automatic_grouping/dual_tracks/expected.srt +15 -0
  24. data/spec/automatic_grouping/dual_tracks/one.srt +11 -0
  25. data/spec/automatic_grouping/dual_tracks/out.srt +15 -0
  26. data/spec/automatic_grouping/dual_tracks/two.srt +11 -0
  27. data/spec/automatic_grouping/single_track/expected.srt +24 -0
  28. data/spec/automatic_grouping/single_track/one.srt +11 -0
  29. data/spec/automatic_grouping/single_track/out.srt +24 -0
  30. data/spec/automatic_grouping/single_track/two.srt +11 -0
  31. data/spec/encoding_detection/a/in.ass +0 -0
  32. data/spec/encoding_detection/b/in.srt +2389 -0
  33. data/spec/encoding_detection/b/out.srt +2389 -0
  34. data/spec/encoding_detection/c/in.srt +5320 -0
  35. data/spec/encoding_detection/c/out.srt +5320 -0
  36. data/spec/encoding_detection/encoding_detection_spec.rb +81 -0
  37. data/spec/files/ass/authentic.ass +0 -0
  38. data/spec/files/ass/hard.ass +37 -0
  39. data/spec/files/ass/simple.ass +28 -0
  40. data/spec/files/srt/authentic.srt +2708 -0
  41. data/spec/files/srt/coordinates.srt +13 -0
  42. data/spec/files/srt/simple.srt +12 -0
  43. data/spec/files/ssa/simple.ssa +26 -0
  44. data/spec/files/try/unsupported-output.try +0 -0
  45. data/spec/files/try/unsupported.try +7 -0
  46. data/spec/format_conversion/ass_srt/expected.srt +2327 -0
  47. data/spec/format_conversion/ass_srt/in.ass +485 -0
  48. data/spec/format_conversion/ass_srt/out.srt +2327 -0
  49. data/spec/format_conversion/format_conversion_spec.rb +112 -0
  50. data/spec/format_conversion/srt_ass/expected.ass +19 -0
  51. data/spec/format_conversion/srt_ass/in.srt +12 -0
  52. data/spec/format_conversion/srt_ass/out.ass +19 -0
  53. data/spec/format_conversion/srt_ssa/expected.ssa +19 -0
  54. data/spec/format_conversion/srt_ssa/in.srt +12 -0
  55. data/spec/format_conversion/srt_ssa/out.ssa +19 -0
  56. data/spec/format_conversion/ssa_srt/expected.srt +9 -0
  57. data/spec/format_conversion/ssa_srt/in.ssa +26 -0
  58. data/spec/format_conversion/ssa_srt/out.srt +9 -0
  59. data/spec/job_spec.rb +162 -0
  60. data/spec/simultaneous_subtitles/dual/ass/expected.ass +22 -0
  61. data/spec/simultaneous_subtitles/dual/ass/out.ass +22 -0
  62. data/spec/simultaneous_subtitles/dual/one.srt +11 -0
  63. data/spec/simultaneous_subtitles/dual/srt/expected.srt +27 -0
  64. data/spec/simultaneous_subtitles/dual/srt/out.srt +27 -0
  65. data/spec/simultaneous_subtitles/dual/ssa/expected.ssa +22 -0
  66. data/spec/simultaneous_subtitles/dual/ssa/out.ssa +22 -0
  67. data/spec/simultaneous_subtitles/dual/two.srt +11 -0
  68. data/spec/simultaneous_subtitles/simultaneous_subtitles_spec.rb +220 -0
  69. data/spec/simultaneous_subtitles/triple/ass/expected.ass +25 -0
  70. data/spec/simultaneous_subtitles/triple/ass/out.ass +25 -0
  71. data/spec/simultaneous_subtitles/triple/one.srt +11 -0
  72. data/spec/simultaneous_subtitles/triple/srt/expected.srt +55 -0
  73. data/spec/simultaneous_subtitles/triple/srt/out.srt +55 -0
  74. data/spec/simultaneous_subtitles/triple/ssa/expected.ssa +25 -0
  75. data/spec/simultaneous_subtitles/triple/ssa/out.ssa +25 -0
  76. data/spec/simultaneous_subtitles/triple/three.srt +11 -0
  77. data/spec/simultaneous_subtitles/triple/two.srt +11 -0
  78. data/spec/simultaneous_subtitles/triple_plus/ass/expected.ass +93 -0
  79. data/spec/simultaneous_subtitles/triple_plus/ass/out.ass +93 -0
  80. data/spec/simultaneous_subtitles/triple_plus/five.srt +11 -0
  81. data/spec/simultaneous_subtitles/triple_plus/four.srt +11 -0
  82. data/spec/simultaneous_subtitles/triple_plus/one.srt +11 -0
  83. data/spec/simultaneous_subtitles/triple_plus/six.srt +11 -0
  84. data/spec/simultaneous_subtitles/triple_plus/srt/expected.srt +149 -0
  85. data/spec/simultaneous_subtitles/triple_plus/srt/out.srt +149 -0
  86. data/spec/simultaneous_subtitles/triple_plus/ssa/expected.ssa +93 -0
  87. data/spec/simultaneous_subtitles/triple_plus/ssa/out.ssa +93 -0
  88. data/spec/simultaneous_subtitles/triple_plus/three.srt +11 -0
  89. data/spec/simultaneous_subtitles/triple_plus/two.srt +11 -0
  90. data/spec/spec_helper.rb +7 -0
  91. data/spec/specifications_spec.rb +138 -0
  92. data/spec/srt_spec.rb +134 -0
  93. data/spec/ssa_spec.rb +90 -0
  94. data/spec/timecode_correction/double_reference/expected.srt +13 -0
  95. data/spec/timecode_correction/double_reference/in.srt +12 -0
  96. data/spec/timecode_correction/double_reference/out.srt +13 -0
  97. data/spec/timecode_correction/framerate/expected.srt +5 -0
  98. data/spec/timecode_correction/framerate/in.srt +4 -0
  99. data/spec/timecode_correction/framerate/out.srt +5 -0
  100. data/spec/timecode_correction/framerate_plus_reference/expected.srt +13 -0
  101. data/spec/timecode_correction/framerate_plus_reference/in.srt +12 -0
  102. data/spec/timecode_correction/framerate_plus_reference/out.srt +13 -0
  103. data/spec/timecode_correction/single_reference/expected.srt +13 -0
  104. data/spec/timecode_correction/single_reference/in.srt +12 -0
  105. data/spec/timecode_correction/single_reference/out.srt +13 -0
  106. data/spec/timecode_correction/timecode_correction_spec.rb +124 -0
  107. data/spec/transcoding/gb2312-ascii/in.srt +12 -0
  108. data/spec/transcoding/iso-8859-1_utf-8/expected.srt +12 -0
  109. data/spec/transcoding/iso-8859-1_utf-8/in.srt +11 -0
  110. data/spec/transcoding/iso-8859-1_utf-8/out.srt +12 -0
  111. data/spec/transcoding/transcoding_spec.rb +116 -0
  112. data/spec/transcoding/utf-8_gbk/expected.srt +12 -0
  113. data/spec/transcoding/utf-8_gbk/in.srt +11 -0
  114. data/spec/transcoding/utf-8_gbk/out.srt +12 -0
  115. data/spec/transcoding/windows-1252_utf-8/expected.srt +12 -0
  116. data/spec/transcoding/windows-1252_utf-8/in.srt +11 -0
  117. data/spec/transcoding/windows-1252_utf-8/out.srt +12 -0
  118. data/titlekit.gemspec +28 -0
  119. metadata +313 -0
@@ -0,0 +1,11 @@
1
+ 1
2
+ 00:00:02,000 --> 00:00:10,000
3
+ Somos utilizando seis subtítulos simultáneamente
4
+
5
+ 2
6
+ 00:00:12,000 --> 00:00:20,000
7
+ Esto es correcto
8
+
9
+ 3
10
+ 00:00:23,000 --> 00:00:31,000
11
+ No son alineado sin embargo
@@ -0,0 +1,7 @@
1
+ require 'titlekit'
2
+
3
+ RSpec.configure do |config|
4
+ config.expect_with :rspec do |c|
5
+ c.syntax = :expect
6
+ end
7
+ end
@@ -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,13 @@
1
+ 1
2
+ 00:00:02,400 --> 00:00:09,153
3
+ Commencing shaving the yak.
4
+
5
+ 2
6
+ 00:00:32,000 --> 00:00:50,880
7
+ WAT?
8
+
9
+ 3
10
+ 00:00:32,000 --> 00:00:50,880
11
+ - I ...
12
+ - Enough!!!
13
+
@@ -0,0 +1,12 @@
1
+ 1
2
+ 00:00:02,364 --> 00:00:07,300
3
+ Commencing shaving the yak.
4
+
5
+ 2
6
+ 00:00:24,000 --> 00:00:37,800
7
+ WAT?
8
+
9
+ 3
10
+ 00:00:24,000 --> 00:00:37,800
11
+ - I ...
12
+ - Enough!!!
@@ -0,0 +1,13 @@
1
+ 1
2
+ 00:00:02,400 --> 00:00:09,153
3
+ Commencing shaving the yak.
4
+
5
+ 2
6
+ 00:00:32,000 --> 00:00:50,880
7
+ WAT?
8
+
9
+ 3
10
+ 00:00:32,000 --> 00:00:50,880
11
+ - I ...
12
+ - Enough!!!
13
+
@@ -0,0 +1,5 @@
1
+ 1
2
+ 00:00:30,000 --> 00:00:33,600
3
+ If this subtitle represents timecodes for a 25fps movie
4
+ Then it would have to start at 00:00:30,000 in a 30fps movie
5
+
@@ -0,0 +1,4 @@
1
+ 1
2
+ 00:00:25,000 --> 00:00:28,000
3
+ If this subtitle represents timecodes for a 25fps movie
4
+ Then it would have to start at 00:00:30,000 in a 30fps movie
@@ -0,0 +1,5 @@
1
+ 1
2
+ 00:00:30,000 --> 00:00:33,600
3
+ If this subtitle represents timecodes for a 25fps movie
4
+ Then it would have to start at 00:00:30,000 in a 30fps movie
5
+
@@ -0,0 +1,13 @@
1
+ 1
2
+ 00:00:03,500 --> 00:00:08,436
3
+ Commencing shaving the yak.
4
+
5
+ 2
6
+ 00:00:25,136 --> 00:00:38,936
7
+ WAT?
8
+
9
+ 3
10
+ 00:00:25,136 --> 00:00:38,936
11
+ - I ...
12
+ - Enough!!!
13
+
@@ -0,0 +1,12 @@
1
+ 1
2
+ 00:00:02,364 --> 00:00:07,300
3
+ Commencing shaving the yak.
4
+
5
+ 2
6
+ 00:00:24,000 --> 00:00:37,800
7
+ WAT?
8
+
9
+ 3
10
+ 00:00:24,000 --> 00:00:37,800
11
+ - I ...
12
+ - Enough!!!
@@ -0,0 +1,13 @@
1
+ 1
2
+ 00:00:03,500 --> 00:00:08,436
3
+ Commencing shaving the yak.
4
+
5
+ 2
6
+ 00:00:25,136 --> 00:00:38,936
7
+ WAT?
8
+
9
+ 3
10
+ 00:00:25,136 --> 00:00:38,936
11
+ - I ...
12
+ - Enough!!!
13
+
@@ -0,0 +1,13 @@
1
+ 1
2
+ 00:00:03,864 --> 00:00:08,800
3
+ Commencing shaving the yak.
4
+
5
+ 2
6
+ 00:00:25,500 --> 00:00:39,300
7
+ WAT?
8
+
9
+ 3
10
+ 00:00:25,500 --> 00:00:39,300
11
+ - I ...
12
+ - Enough!!!
13
+
@@ -0,0 +1,12 @@
1
+ 1
2
+ 00:00:02,364 --> 00:00:07,300
3
+ Commencing shaving the yak.
4
+
5
+ 2
6
+ 00:00:24,000 --> 00:00:37,800
7
+ WAT?
8
+
9
+ 3
10
+ 00:00:24,000 --> 00:00:37,800
11
+ - I ...
12
+ - Enough!!!
@@ -0,0 +1,13 @@
1
+ 1
2
+ 00:00:03,864 --> 00:00:08,800
3
+ Commencing shaving the yak.
4
+
5
+ 2
6
+ 00:00:25,500 --> 00:00:39,300
7
+ WAT?
8
+
9
+ 3
10
+ 00:00:25,500 --> 00:00:39,300
11
+ - I ...
12
+ - Enough!!!
13
+
@@ -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
@@ -0,0 +1,12 @@
1
+ 1
2
+ 00:00:02,364 --> 00:00:07,300
3
+ ����̫ƽȮ�������y����
4
+
5
+ 2
6
+ 00:00:24,000 --> 00:00:37,800
7
+ ����̫ƽȮ�������y����
8
+
9
+ 3
10
+ 00:00:34,000 --> 00:00:47,800
11
+ No chinese skills here, just copy and paste :(
12
+
@@ -0,0 +1,12 @@
1
+ 1
2
+ 00:00:02,364 --> 00:00:07,300
3
+ ¿Cifrado con ISO-8859-1?
4
+
5
+ 2
6
+ 00:00:24,000 --> 00:00:37,800
7
+ ¡Sí claro!
8
+
9
+ 3
10
+ 00:00:34,000 --> 00:00:47,800
11
+ Pues ... ¡Vamos a ver!
12
+
@@ -0,0 +1,11 @@
1
+ 1
2
+ 00:00:02,364 --> 00:00:07,300
3
+ �Cifrado con ISO-8859-1?
4
+
5
+ 2
6
+ 00:00:24,000 --> 00:00:37,800
7
+ �S� claro!
8
+
9
+ 3
10
+ 00:00:34,000 --> 00:00:47,800
11
+ Pues ... �Vamos a ver!