vtt2ass 0.3.2 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,48 +0,0 @@
1
- # Relative imports
2
- require_relative 'ASSStyleParams'
3
- require_relative 'Validator'
4
- require 'redgreenblue'
5
-
6
- ##
7
- # This class defines an ASS style that can be applied on a subtitle line.
8
- class ASSStyle
9
- attr_reader :style_name
10
-
11
- ##
12
- # This method creates and instance of an ASSStyle.
13
- #
14
- # * Requires +style_name+, a string name for the style as input.
15
- # * Requires +params+, a string of VTT styling as input.
16
- # * Requires a video +width+ as input.
17
- # * Requires a video +height+ as input.
18
- def initialize(style_name, params, font_family, font_size, font_color, is_bold, is_italic, line_offset, width, height)
19
- @width = width
20
- @height = height
21
- @font_family = font_family
22
- @font_size = font_size
23
- @font_color = font_color
24
- @style_name = style_name
25
- @s_params = ASSStyleParams.new(params, width, height)
26
- if style_name.eql? 'MainTop' then
27
- @s_params.vertical_margin = 50
28
- end
29
- if style_name.include? 'Subtitle' then
30
- @s_params.vertical_margin -= line_offset
31
- end
32
- @is_italic = is_italic
33
- @is_bold = is_bold
34
- end
35
-
36
- ##
37
- # This method assigns the object values to an ASS style line and outputs it.
38
- def to_s
39
- # Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
40
- return "Style: #{@style_name},#{@font_family},#{@font_size},#{@font_color},&H000000FF,&H00020713,&H00000000,#{@is_bold ? '-1' : '0'},#{@is_italic ? '-1' : '0'},0,0,100,100,0,0,1,2.0,2.0,#{@s_params.alignment},#{@s_params.horizontal_margin},0,#{@s_params.vertical_margin},1"
41
- end
42
-
43
- def self.convert_color(color_value)
44
- color_value.gsub!('#', '')
45
- color = Validator.hex?(color_value) ? RGB.hex(color_value) : RGB.css(color_value)
46
- return ("&H00%02x%02x%02x" % [color.b, color.g, color.r]).upcase
47
- end
48
- end
@@ -1,87 +0,0 @@
1
- ##
2
- # This class defines the ASS style parameters from VTT cue settings.
3
- class ASSStyleParams
4
- attr_accessor :horizontal_margin, :vertical_margin, :alignment, :align
5
-
6
- ##
7
- # Creates an instance of ASSStyleParams
8
- # It takes VTT style arguments and assign them to their respectful instance variable.
9
- # It calls methods to create ASS values from the VTT cue settings.
10
- def initialize(params, width, height)
11
- (params.split(' ').map { |p| p.split(':') }).each do |p|
12
- case p[0]
13
- when 'position'
14
- @position = p[1].gsub(/%/, '').to_i
15
- when 'line'
16
- @line = p[1].gsub(/%/, '').to_i
17
- @line = @line == -1 ? 100 : @line;
18
- when 'align'
19
- @align = p[1].chomp
20
- end
21
- end
22
- createAlignment()
23
- createHorizontalMargin(width)
24
- createVerticalMargin(height)
25
- end
26
-
27
- ##
28
- # This method decides the alignement value in a 9 position grid based of the
29
- # values in cue settings "align" and "line".
30
- def createAlignment()
31
- if (defined?(@line) and not defined?(@position)) then
32
- if (defined?(@align)) then
33
- case @align
34
- when 'left', 'start'
35
- @alignment = @line >= 50 ? 1 : 7
36
- when 'right', 'end'
37
- @alignment = @line >= 50 ? 3 : 9
38
- when 'center', 'middle'
39
- @alignment = @line >= 50 ? 2 : 8
40
- end
41
- else
42
- @alignment = @line >= 50 ? 2 : 8 # If position is higher than 50% align to bottom center, else align to top center
43
- end
44
- elsif (defined?(@line) and defined?(@position)) then
45
- @alignment = 1
46
- else
47
- case @align
48
- when 'left', 'start'
49
- @alignment = 1
50
- when 'right', 'end'
51
- @alignment = 3
52
- when 'center', 'middle'
53
- @alignment = 2
54
- else
55
- @alignment = 2
56
- end
57
- end
58
- end
59
-
60
- ##
61
- # This method calculates the horizontal margin in px between the alignement position and
62
- # and the content displayed by using the "position" cue setting.
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
-
72
- ##
73
- # This method calculates the vertical margin in px between the alignement position and
74
- # and the content displayed by using the "line" cue setting.
75
- def createVerticalMargin(height)
76
- steps = (height / 100).to_i
77
- if defined?(@line) then
78
- if (@alignment == 1) then
79
- @vertical_margin = (100 - @line) * steps
80
- else
81
- @vertical_margin = @line >= 50 ? (100 - @line) * steps : @line * steps
82
- end
83
- else
84
- @vertical_margin = 50
85
- end
86
- end
87
- end
@@ -1,68 +0,0 @@
1
- # Relative imports
2
- require_relative 'VTTFile'
3
- require_relative 'ASSFile'
4
-
5
- ##
6
- # Main application class that manages all the operations.
7
- class Application
8
-
9
- ##
10
- # Creates a new Application instance.
11
- # It receives +options+ that can define the input and output directories.
12
- def initialize(input, options)
13
- @input = input ? input.gsub('\\', '/').delete_suffix('/') : "."
14
- @output = options[:output] ? options[:output].gsub('\\', '/').delete_suffix('/') : nil
15
- @width = 1920
16
- @height = 1080
17
- @font_family = options[:font_family] ? options[:font_family] : 'Open Sans Semibold'
18
- @font_size = options[:font_size] ? options[:font_size] : 52
19
- if options[:title] then
20
- @title = options[:title]
21
- end
22
- @quiet = options[:quiet]
23
- if options[:css] then
24
- @css = options[:css].gsub('\\', '/')
25
- end
26
- @line_offset = options[:line_offset]
27
- end
28
-
29
- ##
30
- # This method starts the application process.
31
- # It sends the file_paths of VTT files in the input directory to convertFileToASS method
32
- # and outputs the resulting ASS format to a new file.
33
- def start
34
- if File.directory?(@input) then
35
- Dir["#{@input}/*.vtt"].each do |file_path|
36
- convert(file_path)
37
- end
38
- elsif File.file?(@input) then
39
- convert(@input)
40
- else
41
- puts 'Error: input file or directory does not exist.'
42
- end
43
- end
44
-
45
- def convert(input_path)
46
- ass_file = vtt_to_ass(input_path)
47
- if (not @output.nil?) then
48
- ass_file.writeToFile(@output + '/' + File.basename(input_path).gsub('.vtt', '.ass'))
49
- end
50
- puts ass_file.to_s unless @quiet
51
- end
52
-
53
- ##
54
- # This method creates a new VTTFile object from the file path provided and convert its content
55
- # inside a new ASSFile object.
56
- def vtt_to_ass(file_path)
57
- vtt_file = VTTFile.new(file_path, @width, @height)
58
- ass_file = ASSFile.new(
59
- (defined?(@title) ? @title : File.basename(file_path).gsub('.vtt', '')),
60
- @width,
61
- @height,
62
- defined?(@css) ? @css : nil
63
- )
64
- ass_file.convertVTTtoASS(vtt_file, @font_family, @font_size, @line_offset)
65
- return ass_file
66
- end
67
-
68
- end
@@ -1,36 +0,0 @@
1
- require 'css_parser'
2
- require_relative 'CSSRule'
3
-
4
- class CSSFile
5
- attr_reader :rules
6
- include CssParser
7
-
8
- def initialize(file_path)
9
- @file_path = file_path
10
- parser = CssParser::Parser.new
11
- parser.load_file!(file_path)
12
- @rules = []
13
- parser.each_selector do |selector, declarations, specificity|
14
- css_obj = CSSRule.new(selector, declarations)
15
- if not css_obj.name.empty? then
16
- @rules.push(css_obj)
17
- end
18
- end
19
- end
20
-
21
- def find_rule(value)
22
- return_rule = nil
23
- @rules.each do |rule|
24
- if rule.name == value then
25
- return_rule = rule
26
- break
27
- end
28
- end
29
- return return_rule
30
- end
31
-
32
- def to_s
33
- return @file_path
34
- end
35
-
36
- end
@@ -1,22 +0,0 @@
1
- class CSSRule
2
- attr_reader :name, :properties
3
-
4
- def initialize(selector, declarations)
5
- @name = reduce_selector(selector)
6
- @properties = []
7
- declarations.split(/;\s?/).each do |dec|
8
- temp = dec.split(/:\s?/)
9
- @properties.push(
10
- { key: temp.first, value: temp.last}
11
- )
12
- end
13
- end
14
-
15
- def to_s
16
- return "#{@name} #{@properties}"
17
- end
18
-
19
- def reduce_selector(selector)
20
- return selector.to_s.gsub(/\.rmp-container>\.rmp-content>\.rmp-cc-area>\.rmp-cc-container>\.rmp-cc-display>\.rmp-cc-cue\s?\.?/, '')
21
- end
22
- end
@@ -1,58 +0,0 @@
1
- # Relative imports
2
- require_relative 'VTTLine'
3
-
4
- ##
5
- # This class defines a VTT subtile file.
6
- class VTTFile
7
- attr_accessor :lines
8
-
9
- ##
10
- # Creates a new VTTFile instance and assigns the default values of instance variables.
11
- def initialize(file_path, width, height)
12
- @title = File.basename(file_path).gsub('.vtt', '')
13
- @lines = []
14
- separator = determine_line_ending(file_path) ? "\n\n" : "\r\n\r\n"
15
- count = 0
16
- style_count = 1
17
- File.foreach(file_path, separator) do |paragraph|
18
- paragraph = paragraph.rstrip.gsub(/[\r\n]/, "\n")
19
- if not paragraph.eql? "" then
20
- vtt_line = VTTLine.new(paragraph, width, height)
21
- if vtt_line.style.eql? 'Main' and
22
- not vtt_line.params.to_s.empty? and
23
- (not vtt_line.params.to_s.eql? 'align:middle' and
24
- not vtt_line.params.to_s.eql? 'align:center') then
25
- vtt_line.style = "Style#{style_count}"
26
- style_count += 1
27
- end
28
- @lines.push(vtt_line)
29
- count += 1
30
- end
31
- end
32
- @lines.shift
33
- end
34
-
35
- ##
36
- # This method determines the line ending character to use as a separator.
37
- def determine_line_ending(file_path)
38
- File.open(file_path, 'r') do |file|
39
- return file.readline[/\r?\n$/] == "\n"
40
- end
41
- end
42
-
43
- ##
44
- # This method writes the content of the VTTFile object into a file path that is provided.
45
- def writeToFile(file_path)
46
- File.open(file_path, 'w') do |line|
47
- line.print "\ufeff"
48
- line.puts self.to_s
49
- end
50
- end
51
-
52
- ##
53
- # This method concatenates the object data in the right order for a string output.
54
- def to_s
55
- return "WEBVTT\n\n\n" + @lines
56
- end
57
-
58
- end
@@ -1,44 +0,0 @@
1
- ##
2
- # This class defines a VTT subtile line.
3
- class VTTLine
4
- attr_accessor :style
5
- attr_reader :time_start, :time_end, :params, :text
6
-
7
- ##
8
- # This method creates an instance of an VTTLine.
9
- #
10
- # * Requires +paragraph+, a VTT formatted string as input.
11
- def initialize(paragraph, width, height)
12
- lines = paragraph.split("\n")
13
- rx = /^([\d:.]*) --> ([\d:.]*)\s?(.*?)\s*$/
14
- @style = "Main"
15
- @text, @time_start, @time_end, @params = ""
16
- count = 0
17
-
18
- lines.each do |line|
19
- m = line.match(rx)
20
- if not m and count == 0 then
21
- @style = line
22
- elsif m then
23
- @time_start = m[1]
24
- @time_end = m[2]
25
- @params = m[3]
26
- ass_style = ASSStyleParams.new(@params, width, height)
27
- if @style.eql? 'Main' and ass_style.alignment == 8 then
28
- @style = 'MainTop'
29
- end
30
- else
31
- @text += line + "\n"
32
- end
33
- count += 1;
34
- end
35
-
36
- @text = @text.lstrip
37
- end
38
-
39
- ##
40
- # This method assigns the object values and outputs a VTT dialogue line.
41
- def to_s
42
- return "#{@style} \n#{@time_start} --> #{@time_end} #{@params}\n#{@text}"
43
- end
44
- end
@@ -1,10 +0,0 @@
1
- class Validator
2
- def self.hex?(value)
3
- hex = true
4
- value.gsub!('#', '')
5
- value.chars.each do |digit|
6
- hex = false unless digit.match(/\h/)
7
- end
8
- return hex
9
- end
10
- end