vtt2ass 0.3.1 → 0.3.4

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: 4ffa12943bef7e38d2fb319e2f496d32f43119fc5a7c5e65312140d62f3515d2
4
- data.tar.gz: 044ad9174d1964b6f131b61f38691e4a58daa1b0fc7eab2eac19788a12e94af9
3
+ metadata.gz: 3a864637934d7b15e7f459c532cd5f521e21e3445e0408cea0a0a7b3c966f550
4
+ data.tar.gz: 5a58b036d877c8529accd0ccc21fe5568d0bdbd686d994ba119ebc894c906e3b
5
5
  SHA512:
6
- metadata.gz: 2b74ac18f31d97823f8ffac84a9f2b0ff0ebeade0909b7c578ad03a50545dce62af3fc9eeb9d963d0943f6b3849a742590227479127ce3c160f0f8a72d7b4d00
7
- data.tar.gz: 522c37cb7f95263b064d8b6b36188b4e91cd3ebc496a6629e3e893a7943705bd303efeecd334b4b6a896e8fee070f776640080daf9d0381f385817aee0fbb4f7
6
+ metadata.gz: e46d22748e6e8b64ec2d0486ce42cce993bcdb00b88be35db80c234bbcdf0ddad0b869e35f2b880a30a451b0a81ce99f48dfb5d671cfa40ad284b4eece17f1d3
7
+ data.tar.gz: 3bbe4b767f309e820d4c44bf8c351090cbe0810219069970c4ac131e50453eeb7b593e9f4793987a69dc9596ab8d6f35815d2d9bbc6785afe755551bcec7c49d
data/README.md CHANGED
@@ -2,35 +2,54 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/vtt2ass.svg)](https://badge.fury.io/rb/vtt2ass)
4
4
 
5
- This is a simple application to convert VTT files to ASS subtitles.
5
+ ## Description
6
+
7
+ This is a simple CLI (Command Line Interface) application to convert VTT files to ASS subtitles.
8
+
9
+ This application is originally based on the `vttconvert` module of [anidl/hidive-downloader-nx](https://github.com/anidl/hidive-downloader-nx) repository. The [maxwbot/maxwhidive](https://github.com/maxwbot/maxwhidive) repository was also used as inspiration for handling the positionning of subs.
10
+
11
+ Those two tools were missing features and didn't work well on a lot of more complex subtitles files. For that reason, I wrote a new tool that can handle everything.
12
+
13
+ ### Features
14
+
15
+ - Convert simple VTT files
16
+ - Convert complex VTT files with positioning
17
+ - Convert Hidive VTT files with CSS styling
18
+ - Convert subtitles in batches by specifying the input directory
19
+ - Handles subtitles made for lower resolution video
20
+ - Can add offset to subtitle lines
21
+ - Can output result to the CLI
22
+ - Can output to the specifed directory
23
+ - Can change the base font size
24
+ - Can specify a custom font family for non-styled lines
25
+ - Can add a title to the converted files
6
26
 
7
27
  ## Requirements
28
+
8
29
  - ruby 2.7.2 or newer
9
30
 
10
- It might work with older versions of ruby, but it hasn't been tested
31
+ Development is currently done on ruby 3.0+, but the Gitlab runner for builds works with ruby version 2.7.2. Older versions of ruby may be compatible, but they won't be tested.
11
32
 
12
33
  ## Installation
13
34
 
14
35
  To install:
15
36
  ```bash
16
- gem install vtt2ass
17
- ```
18
-
19
- # Build
20
-
21
- ```bash
22
- gem build vtt2ass.gemspec
37
+ $ gem install vtt2ass
23
38
  ```
24
39
 
25
40
  ## Usage
26
41
 
42
+ - Empty arguments lists the available commands
27
43
  ```bash
28
44
  $ vtt2ass
29
45
  Commands:
30
46
  vtt2ass convert INPUT # Run the VTT to ASS conversion for the specified file(s)
31
47
  vtt2ass help [COMMAND] # Describe available commands or one specific command
32
48
  vtt2ass version # Show version
49
+ ```
33
50
 
51
+ - Help command shows available options of the specified command
52
+ ```bash
34
53
  $ vtt2ass help convert
35
54
  Usage:
36
55
  vtt2ass convert INPUT
@@ -43,12 +62,51 @@ Options:
43
62
  -f, [--font-family=FONT_FAMILY] # Specify a font family for the subtitles
44
63
  # Default: Open Sans Semibold
45
64
  -c, [--css=CSS] # Specify a CSS file path for Hidive subs
65
+ -l, [--line-offset=N] # Specify a line offset for the main dialog (e.g. 50 lowers the text line by 50px of the total height)
66
+ # Default: 0
46
67
  -q, [--quiet], [--no-quiet] # Don't output to the console
47
68
 
48
69
  Run the VTT to ASS conversion for the specified file(s)
49
70
  ```
50
71
 
51
- # Donate
72
+ - Convert command
73
+ ```bash
74
+ $ vtt2ass convert ./path/to/input/ -o ./path/to/output/ -l 50 -q
75
+ ```
76
+
77
+ - Version command shows the application version
78
+ ```bash
79
+ $ vtt2ass version
80
+ 0.3.3
81
+ ```
82
+
83
+ ## Contributing
84
+
85
+ Contributions are welcome. Create an *Issue* on Gitlab and link it with a *Pull Request* of the changes made. The changes needs to pass the ruby tests.
86
+
87
+ ```
88
+ $ rake test
89
+ ```
90
+
91
+ ## Build
92
+
93
+ To build a gem file for local installation:
94
+ ```bash
95
+ $ git clone https://gitlab.com/dkb-weeblets/vtt2ass.git
96
+ $ cd vtt2ass/
97
+ $ gem build vtt2ass.gemspec
98
+ ```
99
+
100
+ To install the gem file:
101
+ ```bash
102
+ $ gem install ./vtt2ass-0.3.3.gem
103
+ ```
104
+
105
+ ## License
106
+
107
+ Licensed under the **MIT** Licence. For more information read the `LICENSE.txt` file.
108
+
109
+ ## Donate
52
110
 
53
111
  If you want to support me, consider buying me a coffee.
54
112
 
@@ -1,6 +1,6 @@
1
1
  # Relative imports
2
- require_relative 'VTTFile'
3
- require_relative 'ASSFile'
2
+ require_relative 'vtt_file'
3
+ require_relative 'ass_file'
4
4
 
5
5
  ##
6
6
  # Main application class that manages all the operations.
@@ -21,8 +21,9 @@ class Application
21
21
  end
22
22
  @quiet = options[:quiet]
23
23
  if options[:css] then
24
- @css = options[:css].gsub('\\', '/')
24
+ @css = options[:css].gsub('\\', '/').delete_suffix('/')
25
25
  end
26
+ @line_offset = options[:line_offset]
26
27
  end
27
28
 
28
29
  ##
@@ -44,7 +45,7 @@ class Application
44
45
  def convert(input_path)
45
46
  ass_file = vtt_to_ass(input_path)
46
47
  if (not @output.nil?) then
47
- ass_file.writeToFile(@output + '/' + File.basename(input_path).gsub('.vtt', '.ass'))
48
+ ass_file.write_to_file(@output + '/' + File.basename(input_path).gsub('.vtt', '.ass'))
48
49
  end
49
50
  puts ass_file.to_s unless @quiet
50
51
  end
@@ -53,14 +54,23 @@ class Application
53
54
  # This method creates a new VTTFile object from the file path provided and convert its content
54
55
  # inside a new ASSFile object.
55
56
  def vtt_to_ass(file_path)
57
+ base_file_name = File.basename(file_path).gsub('.vtt', '')
58
+ css_file = nil
59
+ if defined?(@css) and File.directory?(@css) then
60
+ css_file = "#{@css}/#{base_file_name}.css"
61
+ elsif File.file?("#{file_path.gsub('.vtt', '')}.css") then
62
+ css_file = "#{file_path.gsub('.vtt', '')}.css"
63
+ else
64
+ css_file = @css
65
+ end
56
66
  vtt_file = VTTFile.new(file_path, @width, @height)
57
67
  ass_file = ASSFile.new(
58
- (defined?(@title) ? @title : File.basename(file_path).gsub('.vtt', '')),
68
+ (defined?(@title) ? @title : base_file_name),
59
69
  @width,
60
70
  @height,
61
- defined?(@css) ? @css : nil
71
+ css_file
62
72
  )
63
- ass_file.convertVTTtoASS(vtt_file, @font_family, @font_size)
73
+ ass_file.convert_vtt_to_ass(vtt_file, @font_family, @font_size, @line_offset)
64
74
  return ass_file
65
75
  end
66
76
 
@@ -1,8 +1,8 @@
1
1
  # Relative imports
2
- require_relative 'ASSLine'
3
- require_relative 'ASSStyle'
4
- require_relative 'CSSFile'
5
- require_relative 'CSSRule'
2
+ require_relative 'ass_line'
3
+ require_relative 'ass_style'
4
+ require_relative 'css_file'
5
+ require_relative 'css_rule'
6
6
 
7
7
  ##
8
8
  # This class defines an ASS subtitle file.
@@ -45,12 +45,12 @@ class ASSFile
45
45
  # This method receives a VTTFile object and font arguments creates new ASSLine with the params of
46
46
  # each VTTLine. All those ASSLine are stored in an array. It also creates an array of ASSStyle that
47
47
  # will be used in the ASS style list.
48
- def convertVTTtoASS(vtt_file, font_family, font_size)
48
+ def convert_vtt_to_ass(vtt_file, font_family, font_size, line_offset = 0)
49
49
  fs = font_size
50
- font_color = '&H00FFFFFF'
51
- is_italic = false
52
- is_bold = false
53
50
  vtt_file.lines.each do |line|
51
+ font_color = '&H00FFFFFF'
52
+ is_italic = false
53
+ is_bold = false
54
54
  @ass_lines.push(ASSLine.new(line.style, line.time_start, line.time_end, line.text))
55
55
  style_exists = false
56
56
  @ass_styles.each do |style|
@@ -88,14 +88,14 @@ class ASSFile
88
88
  end
89
89
  end
90
90
  end
91
- @ass_styles.push(ASSStyle.new(line.style, line.params, font_family, font_size, font_color, is_bold, is_italic, @width, @height))
91
+ @ass_styles.push(ASSStyle.new(line.style, line.params, font_family, font_size, font_color, is_bold, is_italic, line_offset, @width, @height))
92
92
  end
93
93
  end
94
94
  end
95
95
 
96
96
  ##
97
97
  # This method writes the content of the ASSFile object into a file path that is provided.
98
- def writeToFile(file_path)
98
+ def write_to_file(file_path)
99
99
  File.open(file_path, 'w') do |line|
100
100
  line.print "\ufeff"
101
101
  line.puts self.to_s
@@ -14,9 +14,9 @@ class ASSLine
14
14
  # * Requires +text+, a VTT formatted string as input.
15
15
  def initialize(style, time_start, time_end, text)
16
16
  @style = style
17
- @time_start = convertTime(time_start)
18
- @time_end = convertTime(time_end)
19
- @text = convertToAssText(text)
17
+ @time_start = convert_time(time_start)
18
+ @time_end = convert_time(time_end)
19
+ @text = convert_to_ass_text(text)
20
20
  end
21
21
 
22
22
  ##
@@ -29,7 +29,7 @@ class ASSLine
29
29
  # This method replaces characters and tags to ASS compatible characters and tags.
30
30
  #
31
31
  # * Requires +text+, a string of VTT formated text as input.
32
- def convertToAssText(text)
32
+ def convert_to_ass_text(text)
33
33
  decoder = HTMLEntities.new()
34
34
  text = text
35
35
  .gsub(/\r/, '')
@@ -52,16 +52,16 @@ class ASSLine
52
52
  # This method validates the time format and sends the matching time to be converted
53
53
  #
54
54
  # * Requires +str+, a VTT formatted time string.
55
- def convertTime(time)
55
+ def convert_time(time)
56
56
  mTime = time.match(/([\d:]*)\.?(\d*)/)
57
- return toSubsTime(mTime[0])
57
+ return to_subs_time(mTime[0])
58
58
  end
59
59
 
60
60
  ##
61
61
  # This method converts time from VTT format to the ASS format.
62
62
  #
63
63
  # * Requires +str+, a VTT formatted time string.
64
- def toSubsTime(str)
64
+ def to_subs_time(str)
65
65
  n = []
66
66
  x = str.split(/[:.]/).map { |x| x.to_i }
67
67
 
@@ -72,12 +72,12 @@ class ASSLine
72
72
  sx = x[0]*60*60 + x[1]*60 + x[2] + x[3].to_f
73
73
  sx = ("%.2f" % sx).split('.')
74
74
 
75
- n.unshift(padTimeNum('.', sx[1], msLen))
75
+ n.unshift(pad_time_num('.', sx[1], msLen))
76
76
  sx = sx[0].to_f
77
77
 
78
- n.unshift(padTimeNum(':', (sx % 60).to_i, 2))
79
- n.unshift(padTimeNum(':', (sx / 60).floor % 60, 2))
80
- n.unshift(padTimeNum('', (sx / 3600).floor % 60, hLen))
78
+ n.unshift(pad_time_num(':', (sx % 60).to_i, 2))
79
+ n.unshift(pad_time_num(':', (sx / 60).floor % 60, 2))
80
+ n.unshift(pad_time_num('', (sx / 3600).floor % 60, hLen))
81
81
 
82
82
  return n.join('')
83
83
  end
@@ -88,7 +88,7 @@ class ASSLine
88
88
  # * Requires +sep+, a string separator.
89
89
  # * Requires +input+, an integer.
90
90
  # * Requires +pad+, an integer for the number of digits to be padded.
91
- def padTimeNum(sep, input, pad)
91
+ def pad_time_num(sep, input, pad)
92
92
  return sep + (input.to_s).rjust(pad, '0')
93
93
  end
94
94
  end
@@ -1,6 +1,6 @@
1
1
  # Relative imports
2
- require_relative 'ASSStyleParams'
3
- require_relative 'Validator'
2
+ require_relative 'ass_style_params'
3
+ require_relative 'validator'
4
4
  require 'redgreenblue'
5
5
 
6
6
  ##
@@ -15,7 +15,7 @@ class ASSStyle
15
15
  # * Requires +params+, a string of VTT styling as input.
16
16
  # * Requires a video +width+ as input.
17
17
  # * Requires a video +height+ as input.
18
- def initialize(style_name, params, font_family, font_size, font_color, is_bold, is_italic, width, height)
18
+ def initialize(style_name, params, font_family, font_size, font_color, is_bold, is_italic, line_offset, width, height)
19
19
  @width = width
20
20
  @height = height
21
21
  @font_family = font_family
@@ -26,6 +26,9 @@ class ASSStyle
26
26
  if style_name.eql? 'MainTop' then
27
27
  @s_params.vertical_margin = 50
28
28
  end
29
+ if style_name.include? 'Subtitle' then
30
+ @s_params.vertical_margin -= line_offset
31
+ end
29
32
  @is_italic = is_italic
30
33
  @is_bold = is_bold
31
34
  end
@@ -19,15 +19,15 @@ class ASSStyleParams
19
19
  @align = p[1].chomp
20
20
  end
21
21
  end
22
- createAlignment()
23
- createHorizontalMargin(width)
24
- createVerticalMargin(height)
22
+ create_alignment()
23
+ create_horizontal_margin(width)
24
+ create_vertical_margin(height)
25
25
  end
26
26
 
27
27
  ##
28
28
  # This method decides the alignement value in a 9 position grid based of the
29
29
  # values in cue settings "align" and "line".
30
- def createAlignment()
30
+ def create_alignment()
31
31
  if (defined?(@line) and not defined?(@position)) then
32
32
  if (defined?(@align)) then
33
33
  case @align
@@ -60,7 +60,7 @@ class ASSStyleParams
60
60
  ##
61
61
  # This method calculates the horizontal margin in px between the alignement position and
62
62
  # and the content displayed by using the "position" cue setting.
63
- def createHorizontalMargin(width)
63
+ def create_horizontal_margin(width)
64
64
  steps = (width / 100).to_i
65
65
  if defined?(@position) then
66
66
  @horizontal_margin = @position * steps
@@ -72,7 +72,7 @@ class ASSStyleParams
72
72
  ##
73
73
  # This method calculates the vertical margin in px between the alignement position and
74
74
  # and the content displayed by using the "line" cue setting.
75
- def createVerticalMargin(height)
75
+ def create_vertical_margin(height)
76
76
  steps = (height / 100).to_i
77
77
  if defined?(@line) then
78
78
  if (@alignment == 1) then
@@ -1,5 +1,5 @@
1
1
  require 'css_parser'
2
- require_relative 'CSSRule'
2
+ require_relative 'css_rule'
3
3
 
4
4
  class CSSFile
5
5
  attr_reader :rules
File without changes
File without changes
@@ -4,5 +4,5 @@ module Vtt2ass
4
4
  ##
5
5
  # This is the version of the application.
6
6
  # This needs to be changed for each gem release.
7
- VERSION = "0.3.1"
7
+ VERSION = "0.3.4"
8
8
  end
@@ -1,5 +1,5 @@
1
1
  # Relative imports
2
- require_relative 'VTTLine'
2
+ require_relative 'vtt_line'
3
3
 
4
4
  ##
5
5
  # This class defines a VTT subtile file.
@@ -42,7 +42,7 @@ class VTTFile
42
42
 
43
43
  ##
44
44
  # This method writes the content of the VTTFile object into a file path that is provided.
45
- def writeToFile(file_path)
45
+ def write_to_file(file_path)
46
46
  File.open(file_path, 'w') do |line|
47
47
  line.print "\ufeff"
48
48
  line.puts self.to_s
File without changes
data/lib/vtt2ass.rb CHANGED
@@ -3,7 +3,7 @@ require 'thor'
3
3
 
4
4
  # Relative imports
5
5
  require_relative 'vtt2ass/version'
6
- require_relative 'vtt2ass/Application'
6
+ require_relative 'vtt2ass/application'
7
7
 
8
8
  class MainCommand < Thor
9
9
  def self.exit_on_failure?
@@ -16,6 +16,7 @@ class MainCommand < Thor
16
16
  method_option :font_size, :aliases => '-s', :desc => 'Specify a font size for the subtitles', :default => 52, :type => :numeric
17
17
  method_option :font_family, :aliases => '-f', :desc => 'Specify a font family for the subtitles', :default => 'Open Sans Semibold', :type => :string
18
18
  method_option :css, :aliases => '-c', :desc => 'Specify a CSS file path for Hidive subs', :type => :string
19
+ method_option :line_offset, :aliases => '-l', :desc => 'Specify a line offset for the main dialog (e.g. 50 lowers the text line by 50px of the total height)', :default => 0, :type => :numeric
19
20
  method_option :quiet, :aliases => '-q', :desc => 'Don\'t output to the console', :type => :boolean
20
21
  def convert(input)
21
22
  app = Application.new(input, options)
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.3.1
4
+ version: 0.3.4
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: 2022-04-30 00:00:00.000000000 Z
11
+ date: 2022-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: htmlentities
@@ -153,17 +153,17 @@ files:
153
153
  - doc/top-level-namespace.html
154
154
  - exe/vtt2ass
155
155
  - lib/vtt2ass.rb
156
- - lib/vtt2ass/ASSFile.rb
157
- - lib/vtt2ass/ASSLine.rb
158
- - lib/vtt2ass/ASSStyle.rb
159
- - lib/vtt2ass/ASSStyleParams.rb
160
- - lib/vtt2ass/Application.rb
161
- - lib/vtt2ass/CSSFile.rb
162
- - lib/vtt2ass/CSSRule.rb
163
- - lib/vtt2ass/VTTFile.rb
164
- - lib/vtt2ass/VTTLine.rb
165
- - lib/vtt2ass/Validator.rb
156
+ - lib/vtt2ass/application.rb
157
+ - lib/vtt2ass/ass_file.rb
158
+ - lib/vtt2ass/ass_line.rb
159
+ - lib/vtt2ass/ass_style.rb
160
+ - lib/vtt2ass/ass_style_params.rb
161
+ - lib/vtt2ass/css_file.rb
162
+ - lib/vtt2ass/css_rule.rb
163
+ - lib/vtt2ass/validator.rb
166
164
  - lib/vtt2ass/version.rb
165
+ - lib/vtt2ass/vtt_file.rb
166
+ - lib/vtt2ass/vtt_line.rb
167
167
  - vtt2ass.gemspec
168
168
  homepage: https://gitlab.com/dkb-weeblets/vtt2ass
169
169
  licenses: