vtt2ass 0.2.4 → 0.2.5

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.
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