vtt2ass 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/vtt2ass.rb +8 -8
- data/lib/vtt2ass/ASSFile.rb +34 -12
- data/lib/vtt2ass/{ASSSubtitle.rb → ASSLine.rb} +4 -5
- data/lib/vtt2ass/ASSStyle.rb +4 -64
- data/lib/vtt2ass/ASSStyleParams.rb +74 -0
- data/lib/vtt2ass/Application.rb +8 -52
- data/lib/vtt2ass/VTTFile.rb +36 -0
- data/lib/vtt2ass/{VTTSubtitle.rb → VTTLine.rb} +2 -2
- data/lib/vtt2ass/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1014d192c3fa05ac8c39f15c2e06ca27d203d7a0cb6d2cb7500acf1a27df80b3
|
4
|
+
data.tar.gz: e455ca13c6b27784801c1e3e1091e0df1eca05c6f8547c5a9c4b0cc0c5dccdee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f4aa749a1f35195a847bc2a0abefaad1d5b644e4987f2cd8742d575125171fea84aa0cc618c9da488ba9f94a277f0208be910b0641554cb438546622cc285f9
|
7
|
+
data.tar.gz: 0f846550b79f10d0a933d29fd04cc6371248059f5a38a63d2540f707b601c72a9b682e195a3eac15bdd93168cb2d1c90e5c3e0ece8598bfdf4b749905f868455
|
data/README.md
CHANGED
@@ -40,7 +40,7 @@ Usage: vtt2ass [options]
|
|
40
40
|
Specific options:
|
41
41
|
-i, --input PATH Specify a custom input file or directory (default: './')
|
42
42
|
-o, --output PATH Specify a custom output directory (default: './')
|
43
|
-
-f, --font-family
|
43
|
+
-f, --font-family FONT Specify a font family for the subtitles (default: 'Open Sans Semibold')
|
44
44
|
-s, --font-size SIZE Specify a font size for the subtitles (default: 52)
|
45
45
|
-v, --version Show version
|
46
46
|
```
|
data/lib/vtt2ass.rb
CHANGED
@@ -17,17 +17,17 @@ module Vtt2ass
|
|
17
17
|
opts.banner = "Usage: vtt2ass [options]"
|
18
18
|
opts.separator ""
|
19
19
|
opts.separator "Specific options:"
|
20
|
-
opts.on("-i", "--input PATH", "Specify a custom input file or directory (default: './')") do |
|
21
|
-
options[:input] =
|
20
|
+
opts.on("-i", "--input PATH", "Specify a custom input file or directory (default: './')") do |file_path|
|
21
|
+
options[:input] = file_path
|
22
22
|
end
|
23
|
-
opts.on("-o", "--output PATH", "Specify a custom output directory (default: './')") do |
|
24
|
-
options[:output] =
|
23
|
+
opts.on("-o", "--output PATH", "Specify a custom output directory (default: './')") do |file_path|
|
24
|
+
options[:output] = file_path
|
25
25
|
end
|
26
|
-
opts.on("-f", "--font-family
|
27
|
-
options[:font_family] =
|
26
|
+
opts.on("-f", "--font-family FONT", String, "Specify a font family for the subtitles (default: 'Open Sans Semibold')") do |font_family|
|
27
|
+
options[:font_family] = font_family
|
28
28
|
end
|
29
|
-
opts.on("-s", "--font-size SIZE", Integer, "Specify a font size for the subtitles (default: 52)") do |
|
30
|
-
options[:font_size] =
|
29
|
+
opts.on("-s", "--font-size SIZE", Integer, "Specify a font size for the subtitles (default: 52)") do |font_size|
|
30
|
+
options[:font_size] = font_size
|
31
31
|
end
|
32
32
|
opts.on("-v", "--version", "Show version") do
|
33
33
|
puts Vtt2ass::VERSION
|
data/lib/vtt2ass/ASSFile.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
+
# Relative imports
|
2
|
+
require_relative 'ASSLine'
|
3
|
+
require_relative 'ASSStyle'
|
4
|
+
|
1
5
|
##
|
2
|
-
# This class defines
|
6
|
+
# This class defines an ASS subtitle file.
|
3
7
|
class ASSFile
|
8
|
+
attr_reader :title, :width, :height
|
9
|
+
attr_accessor :ass_styles, :ass_lines
|
4
10
|
|
5
|
-
|
6
|
-
# This method creates an instance of the ASSFile.
|
7
|
-
#
|
8
|
-
# * Requires +ass_styles+, a list of ASSStyle as input.
|
9
|
-
# * Requires +ass_subs+, a list of ASSSubtitles as input.
|
10
|
-
# * Requires a video +width+ as input.
|
11
|
-
# * Requires a video +height+ as input.
|
12
|
-
def initialize(title, ass_styles, ass_subs, width, height)
|
11
|
+
def initialize(title, width, height)
|
13
12
|
@width = width
|
14
13
|
@height = height
|
15
14
|
@header = [
|
@@ -26,18 +25,41 @@ class ASSFile
|
|
26
25
|
'[V4+ Styles]',
|
27
26
|
'Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding'
|
28
27
|
]
|
29
|
-
@ass_styles = ass_styles
|
30
28
|
@events = [
|
31
29
|
'',
|
32
30
|
'[Events]',
|
33
31
|
'Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text'
|
34
32
|
]
|
35
|
-
@
|
33
|
+
@ass_styles = []
|
34
|
+
@ass_lines = []
|
35
|
+
end
|
36
|
+
|
37
|
+
def convertVTTtoASS(vtt_file, font_family, font_size)
|
38
|
+
vtt_file.lines.each do |line|
|
39
|
+
@ass_lines.push(ASSLine.new(line.style, line.time_start, line.time_end, line.text))
|
40
|
+
style_exists = false
|
41
|
+
@ass_styles.each do |style|
|
42
|
+
if (style.style_name == line.style) then
|
43
|
+
style_exists = true
|
44
|
+
break
|
45
|
+
end
|
46
|
+
end
|
47
|
+
if not style_exists then
|
48
|
+
@ass_styles.push(ASSStyle.new(line.style, line.params, font_family, font_size, @width, @height))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def writeToFile(file_path)
|
54
|
+
File.open(file_path, 'w') do |line|
|
55
|
+
line.print "\ufeff"
|
56
|
+
line.puts self.to_s
|
57
|
+
end
|
36
58
|
end
|
37
59
|
|
38
60
|
##
|
39
61
|
# This method concatenates the object data in the right order for a string output.
|
40
62
|
def to_s
|
41
|
-
return @header + @ass_styles + @events + @
|
63
|
+
return @header + @ass_styles + @events + @ass_lines
|
42
64
|
end
|
43
65
|
end
|
@@ -1,20 +1,19 @@
|
|
1
1
|
##
|
2
2
|
# This class defines an ASS subtile line.
|
3
|
-
class
|
4
|
-
attr_reader :style, :time_start, :time_end, :
|
3
|
+
class ASSLine
|
4
|
+
attr_reader :style, :time_start, :time_end, :text
|
5
5
|
|
6
6
|
##
|
7
|
-
# This method creates an instance of an
|
7
|
+
# This method creates an instance of an ASSLine.
|
8
8
|
#
|
9
9
|
# * Requires a +style+ name as input.
|
10
10
|
# * Requires +time_start+, a VTT formatted timestamp as input.
|
11
11
|
# * Requires +time_start+, a VTT formatted timestamp as input.
|
12
12
|
# * Requires +text+, a VTT formatted string as input.
|
13
|
-
def initialize(style, time_start, time_end,
|
13
|
+
def initialize(style, time_start, time_end, text)
|
14
14
|
@style = style
|
15
15
|
@time_start = convertTime(time_start)
|
16
16
|
@time_end = convertTime(time_end)
|
17
|
-
@params = params
|
18
17
|
@text = convertToAssText(text)
|
19
18
|
end
|
20
19
|
|
data/lib/vtt2ass/ASSStyle.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# Relative imports
|
2
|
+
require_relative 'ASSStyleParams'
|
3
|
+
|
1
4
|
##
|
2
5
|
# This class defines an ASS style that can be applied on a subtitle line.
|
3
6
|
class ASSStyle
|
@@ -16,72 +19,9 @@ class ASSStyle
|
|
16
19
|
@font_family = font_family
|
17
20
|
@font_size = font_size
|
18
21
|
@style_name = style_name
|
19
|
-
@s_params =
|
22
|
+
@s_params = ASSStyleParams.new(params, width, height)
|
20
23
|
end
|
21
24
|
|
22
|
-
class StyleParams
|
23
|
-
attr_reader :horizontal_margin, :vertical_margin, :alignment
|
24
|
-
def initialize(params, width, height)
|
25
|
-
(params.split(' ').map { |p| p.split(':') }).each do |p|
|
26
|
-
case p[0]
|
27
|
-
when 'position'
|
28
|
-
@position = p[1].gsub(/%/, '').to_i
|
29
|
-
when 'line'
|
30
|
-
@line = p[1].gsub(/%/, '').to_i
|
31
|
-
@line = @line == -1 ? 100 : @line;
|
32
|
-
when 'alignment'
|
33
|
-
@align = p[1]
|
34
|
-
end
|
35
|
-
end
|
36
|
-
createAlignment
|
37
|
-
createHorizontalMargin(width)
|
38
|
-
createVerticalMargin(height)
|
39
|
-
end
|
40
|
-
def createAlignment
|
41
|
-
if (defined?(@line) and not defined?(@position)) then
|
42
|
-
if (defined?(@align)) then
|
43
|
-
case @align
|
44
|
-
when 'left'
|
45
|
-
when 'start'
|
46
|
-
@alignment = @line >= 50 ? 1 : 7
|
47
|
-
when 'right'
|
48
|
-
when 'end'
|
49
|
-
@alignment = @line >= 50 ? 3 : 9
|
50
|
-
when 'center'
|
51
|
-
when 'middle'
|
52
|
-
@alignment = @line >= 50 ? 2 : 8
|
53
|
-
end
|
54
|
-
else
|
55
|
-
@alignment = @line >= 50 ? 2 : 8 # If position is higher than 50% align to bottom center, else align to top center
|
56
|
-
end
|
57
|
-
elsif (defined?(@line) and defined?(@position)) then
|
58
|
-
@alignment = 1
|
59
|
-
else
|
60
|
-
@alignment = 2
|
61
|
-
end
|
62
|
-
end
|
63
|
-
def createHorizontalMargin(width)
|
64
|
-
steps = (width / 100).to_i
|
65
|
-
if defined?(@position) then
|
66
|
-
@horizontal_margin = @position * steps
|
67
|
-
else
|
68
|
-
@horizontal_margin = 0
|
69
|
-
end
|
70
|
-
end
|
71
|
-
def createVerticalMargin(height)
|
72
|
-
steps = (height / 100).to_i
|
73
|
-
if defined?(@line) then
|
74
|
-
if (@alignment == 1) then
|
75
|
-
@vertical_margin = (100 - @line) * steps
|
76
|
-
else
|
77
|
-
@vertical_margin = @line >= 50 ? (100 - @line) * steps : @line * steps
|
78
|
-
end
|
79
|
-
else
|
80
|
-
@vertical_margin = 50
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
25
|
##
|
86
26
|
# This method assigns the object values to an ASS style line and outputs it.
|
87
27
|
def to_s
|
@@ -0,0 +1,74 @@
|
|
1
|
+
##
|
2
|
+
# This class defines the ASS style parameters from VTT cue settings.
|
3
|
+
class ASSStyleParams
|
4
|
+
attr_reader :horizontal_margin, :vertical_margin, :alignment, :align
|
5
|
+
|
6
|
+
def initialize(params, width, height)
|
7
|
+
(params.split(' ').map { |p| p.split(':') }).each do |p|
|
8
|
+
case p[0]
|
9
|
+
when 'position'
|
10
|
+
@position = p[1].gsub(/%/, '').to_i
|
11
|
+
when 'line'
|
12
|
+
@line = p[1].gsub(/%/, '').to_i
|
13
|
+
@line = @line == -1 ? 100 : @line;
|
14
|
+
when 'align'
|
15
|
+
@align = p[1].chomp
|
16
|
+
end
|
17
|
+
end
|
18
|
+
createAlignment()
|
19
|
+
createHorizontalMargin(width)
|
20
|
+
createVerticalMargin(height)
|
21
|
+
end
|
22
|
+
|
23
|
+
def createAlignment()
|
24
|
+
if (defined?(@line) and not defined?(@position)) then
|
25
|
+
if (defined?(@align)) then
|
26
|
+
case @align
|
27
|
+
when 'left', 'start'
|
28
|
+
@alignment = @line >= 50 ? 1 : 7
|
29
|
+
when 'right', 'end'
|
30
|
+
@alignment = @line >= 50 ? 3 : 9
|
31
|
+
when 'center', 'middle'
|
32
|
+
@alignment = @line >= 50 ? 2 : 8
|
33
|
+
end
|
34
|
+
else
|
35
|
+
@alignment = @line >= 50 ? 2 : 8 # If position is higher than 50% align to bottom center, else align to top center
|
36
|
+
end
|
37
|
+
elsif (defined?(@line) and defined?(@position)) then
|
38
|
+
@alignment = 1
|
39
|
+
else
|
40
|
+
case @align
|
41
|
+
when 'left', 'start'
|
42
|
+
@alignment = 1
|
43
|
+
when 'right', 'end'
|
44
|
+
@alignment = 3
|
45
|
+
when 'center', 'middle'
|
46
|
+
@alignment = 2
|
47
|
+
else
|
48
|
+
@alignment = 2
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def createHorizontalMargin(width)
|
54
|
+
steps = (width / 100).to_i
|
55
|
+
if defined?(@position) then
|
56
|
+
@horizontal_margin = @position * steps
|
57
|
+
else
|
58
|
+
@horizontal_margin = 0
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def createVerticalMargin(height)
|
63
|
+
steps = (height / 100).to_i
|
64
|
+
if defined?(@line) then
|
65
|
+
if (@alignment == 1) then
|
66
|
+
@vertical_margin = (100 - @line) * steps
|
67
|
+
else
|
68
|
+
@vertical_margin = @line >= 50 ? (100 - @line) * steps : @line * steps
|
69
|
+
end
|
70
|
+
else
|
71
|
+
@vertical_margin = 50
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/vtt2ass/Application.rb
CHANGED
@@ -2,9 +2,7 @@
|
|
2
2
|
require 'os'
|
3
3
|
|
4
4
|
# Relative imports
|
5
|
-
require_relative '
|
6
|
-
require_relative 'ASSSubtitle'
|
7
|
-
require_relative 'ASSStyle'
|
5
|
+
require_relative 'VTTFile'
|
8
6
|
require_relative 'ASSFile'
|
9
7
|
|
10
8
|
##
|
@@ -30,62 +28,20 @@ class Application
|
|
30
28
|
def start
|
31
29
|
if File.directory?(@input) then
|
32
30
|
Dir["#{@input}/*.vtt"].each do |file_path|
|
33
|
-
|
31
|
+
vtt_to_ass(file_path).writeToFile(File.basename(file_path).gsub('.vtt', '.ass'))
|
34
32
|
end
|
35
33
|
elsif File.file?(@input) then
|
36
|
-
|
34
|
+
vtt_to_ass(@input).writeToFile(File.basename(@input).gsub('.vtt', '.ass'))
|
37
35
|
else
|
38
36
|
puts 'Error: input file or directory does not exist.'
|
39
37
|
end
|
40
38
|
end
|
41
39
|
|
42
|
-
def
|
43
|
-
|
44
|
-
File.
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
##
|
51
|
-
# This method reads the VTT file and sends back a list of paragraphs.
|
52
|
-
# It requires a +file_path+ as input.
|
53
|
-
# It outputs a list named list_paragraph.
|
54
|
-
def readVTTFile(file_path)
|
55
|
-
list_parapraph = []
|
56
|
-
separator = OS.posix? ? "\r\n\r\n": "\n\n"
|
57
|
-
File.foreach(file_path, separator) do |paragraph|
|
58
|
-
paragraph = paragraph.rstrip.gsub(/\r\n/, "\n")
|
59
|
-
if not paragraph.eql? "" then
|
60
|
-
list_parapraph.push(VTTSubtitle.new(paragraph))
|
61
|
-
end
|
62
|
-
end
|
63
|
-
list_parapraph.shift
|
64
|
-
return list_parapraph
|
40
|
+
def vtt_to_ass(file_path)
|
41
|
+
vtt_file = VTTFile.new(file_path)
|
42
|
+
ass_file = ASSFile.new(File.basename(file_path).gsub('.vtt', ''), @width, @height)
|
43
|
+
ass_file.convertVTTtoASS(vtt_file, @font_family, @font_size)
|
44
|
+
return ass_file
|
65
45
|
end
|
66
46
|
|
67
|
-
##
|
68
|
-
# This method gets the list of paragraphs from the VTT file and creates lists of ASSSubtitle and ASSStyles objects from them.
|
69
|
-
# Those lists are given a new ASSFile object to generate the file content.
|
70
|
-
# It requires a +file_path+ as input.
|
71
|
-
# It outputs an ASSFile object.
|
72
|
-
def convertFileToASS(file_path)
|
73
|
-
vtt_subs = readVTTFile(file_path)
|
74
|
-
ass_subs = []
|
75
|
-
ass_styles = []
|
76
|
-
vtt_subs.each do |sub|
|
77
|
-
ass_subs.push(ASSSubtitle.new(sub.style, sub.time_start, sub.time_end, sub.params, sub.text))
|
78
|
-
style_exists = false
|
79
|
-
ass_styles.each do |style|
|
80
|
-
if (style.style_name == sub.style) then
|
81
|
-
style_exists = true
|
82
|
-
break
|
83
|
-
end
|
84
|
-
end
|
85
|
-
if not style_exists then
|
86
|
-
ass_styles.push(ASSStyle.new(sub.style, sub.params, @font_family, @font_size, @width, @height))
|
87
|
-
end
|
88
|
-
end
|
89
|
-
return ASSFile.new(File.basename(file_path).gsub('.vtt', ''), ass_styles, ass_subs, @width, @height).to_s
|
90
|
-
end
|
91
47
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Imports
|
2
|
+
require 'os'
|
3
|
+
|
4
|
+
# Relative imports
|
5
|
+
require_relative 'VTTLine'
|
6
|
+
|
7
|
+
##
|
8
|
+
# This class defines a VTT subtile file.
|
9
|
+
class VTTFile
|
10
|
+
attr_accessor :lines
|
11
|
+
|
12
|
+
def initialize(file_path)
|
13
|
+
@title = File.basename(file_path).gsub('.vtt', '')
|
14
|
+
@lines = []
|
15
|
+
separator = OS.posix? ? "\r\n\r\n": "\n\n"
|
16
|
+
File.foreach(file_path, separator) do |paragraph|
|
17
|
+
paragraph = paragraph.rstrip.gsub(/\r\n/, "\n")
|
18
|
+
if not paragraph.eql? "" then
|
19
|
+
@lines.push(VTTLine.new(paragraph))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
@lines.shift
|
23
|
+
end
|
24
|
+
|
25
|
+
def writeToFile(file_path)
|
26
|
+
File.open(file_path, 'w') do |line|
|
27
|
+
line.print "\ufeff"
|
28
|
+
line.puts self.to_s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
return "WEBVTT\n\n\n" + @lines
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
##
|
2
2
|
# This class defines a VTT subtile line.
|
3
|
-
class
|
3
|
+
class VTTLine
|
4
4
|
attr_reader :style, :time_start, :time_end, :params, :text
|
5
5
|
|
6
6
|
##
|
7
|
-
# This method creates an instance of an
|
7
|
+
# This method creates an instance of an VTTLine.
|
8
8
|
#
|
9
9
|
# * Requires +paragraph+, a VTT formatted string as input.
|
10
10
|
def initialize(paragraph)
|
data/lib/vtt2ass/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vtt2ass
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Louis-Philippe Fortin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -50,10 +50,12 @@ files:
|
|
50
50
|
- exe/vtt2ass
|
51
51
|
- lib/vtt2ass.rb
|
52
52
|
- lib/vtt2ass/ASSFile.rb
|
53
|
+
- lib/vtt2ass/ASSLine.rb
|
53
54
|
- lib/vtt2ass/ASSStyle.rb
|
54
|
-
- lib/vtt2ass/
|
55
|
+
- lib/vtt2ass/ASSStyleParams.rb
|
55
56
|
- lib/vtt2ass/Application.rb
|
56
|
-
- lib/vtt2ass/
|
57
|
+
- lib/vtt2ass/VTTFile.rb
|
58
|
+
- lib/vtt2ass/VTTLine.rb
|
57
59
|
- lib/vtt2ass/version.rb
|
58
60
|
- vtt2ass.gemspec
|
59
61
|
homepage: https://gitlab.com/dkb-weeblets/vtt2ass
|