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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84bd1994e916924d34b397b785492675e5403fb9d3c9863c9c2bf0d7aabfc7d8
4
- data.tar.gz: 300b7640c078c7e180be5504dae5f7c41c0742c274bae5427476c6ff6495fbce
3
+ metadata.gz: 1014d192c3fa05ac8c39f15c2e06ca27d203d7a0cb6d2cb7500acf1a27df80b3
4
+ data.tar.gz: e455ca13c6b27784801c1e3e1091e0df1eca05c6f8547c5a9c4b0cc0c5dccdee
5
5
  SHA512:
6
- metadata.gz: 3a6bf3fc3b1e18102d07561585db6d4ed8f5f2f816693ee407b0dd63d31a969f513be8ffb091407bb0724f2eb4009da8a98163d0c2e577ba47970498b3eab579
7
- data.tar.gz: 85e7b794c2b6f7b251657bf0842216bc519bfedadd6fb8d775d3bae579944da97c8b8c62fb9f68c0d4659771b3b0db50675e39e36da86cbd926b3e0ce9e18c3a
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 SIZE Specify a font family for the subtitles (default: 'Open Sans Semibold')
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 |dir|
21
- options[:input] = dir
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 |dir|
24
- options[:output] = dir
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 SIZE", String, "Specify a font family for the subtitles (default: 'Open Sans Semibold')") do |size|
27
- options[:font_family] = size
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 |size|
30
- options[:font_size] = 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
@@ -1,15 +1,14 @@
1
+ # Relative imports
2
+ require_relative 'ASSLine'
3
+ require_relative 'ASSStyle'
4
+
1
5
  ##
2
- # This class defines the ASS File that will be created from the conversion.
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
- @ass_subs = ass_subs
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 + @ass_subs
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 ASSSubtitle
4
- attr_reader :style, :time_start, :time_end, :params, :text
3
+ class ASSLine
4
+ attr_reader :style, :time_start, :time_end, :text
5
5
 
6
6
  ##
7
- # This method creates an instance of an ASSSubtitle.
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, params, text)
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
 
@@ -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 = StyleParams.new(params, width, height)
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
@@ -2,9 +2,7 @@
2
2
  require 'os'
3
3
 
4
4
  # Relative imports
5
- require_relative 'VTTSubtitle'
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
- writeFile(file_path)
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
- writeFile(@input)
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 writeFile(file_path)
43
- file_name = File.basename(file_path).gsub('.vtt', '.ass')
44
- File.open("#{@output}/" + file_name, 'w') do |line|
45
- line.print "\ufeff"
46
- line.puts convertFileToASS(file_path)
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 VTTSubtitle
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 VTTSubtitle.
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)
@@ -1,3 +1,3 @@
1
1
  module Vtt2ass
2
- VERSION = "0.2.4"
2
+ VERSION = "0.2.5"
3
3
  end
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
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-02-26 00:00:00.000000000 Z
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/ASSSubtitle.rb
55
+ - lib/vtt2ass/ASSStyleParams.rb
55
56
  - lib/vtt2ass/Application.rb
56
- - lib/vtt2ass/VTTSubtitle.rb
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