Class: SubtitleShifter
- Inherits:
-
Object
- Object
- SubtitleShifter
- Defined in:
- lib/subtitle_shifter.rb
Overview
Defined Under Namespace
Modules: Version
Constant Summary collapse
- TIME_SEPERATOR =
The delimiter used for separating SubRip time stamps
'-->'
Instance Attribute Summary collapse
-
#parsed_ok ⇒ Object
readonly
A boolean flag highlighting whether or not subtitles have been parsed yet.
-
#subtitles ⇒ Object
readonly
A hash of the parsed subtitles.
Instance Method Summary collapse
-
#initialize(file, linebreak = "\r\n") ⇒ SubtitleShifter
constructor
A new instance of SubtitleShifter.
-
#parse ⇒ Object
Parses the subtitles.
-
#shift(args) ⇒ Object
Shifts subtitles forward (or backward) by a number of ms from an index.
-
#to_s ⇒ Object
Outputs parsed subtitles.
Constructor Details
#initialize(file, linebreak = "\r\n") ⇒ SubtitleShifter
Returns a new instance of SubtitleShifter.
56 57 58 59 60 |
# File 'lib/subtitle_shifter.rb', line 56 def initialize(file, linebreak = "\r\n") @sub_file = file @linebreak = linebreak @parsed_ok = false end |
Instance Attribute Details
#parsed_ok ⇒ Object (readonly)
A boolean flag highlighting whether or not subtitles have been parsed yet
34 35 36 |
# File 'lib/subtitle_shifter.rb', line 34 def parsed_ok @parsed_ok end |
#subtitles ⇒ Object (readonly)
I chose to implement internal representation of subtitle files as a hash and not an array, which would’ve been more efficient, as subtitles cannot be guaranteed to start at index 1 That being said, I can already think of a way to do this using an array and offset attribute
A hash of the parsed subtitles. You normally wouldn’t need to access this directly
49 50 51 |
# File 'lib/subtitle_shifter.rb', line 49 def subtitles @subtitles end |
Instance Method Details
#parse ⇒ Object
Always call only after initialising.
If your subtitle file is UTF-8 encoded, and has a Byte Order Mark as its first few bytes, the BOM will not be preserved when outputing the parsed and shifted subtitles. You probably don’t need it anyway
Parses the subtitles
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/subtitle_shifter.rb', line 70 def parse raw_text = File.open(@sub_file, 'r').read.force_encoding('UTF-8') raw_text.gsub!("\xEF\xBB\xBF".force_encoding("UTF-8"), '') #Remove stupid BOM that was causing me so much grief! #raw_text = IO.read @sub_file subtitle_parts = raw_text.split "#{@linebreak}#{@linebreak}" @subtitles = {} subtitle_parts.each do |subtitle| @subtitles.update extract_sub_data subtitle end # No longer needed due to removal of BOM #fix_first_index # What a hack :( @parsed_ok = true # Not very useful, but will help when error checking is added end |
#shift(args) ⇒ Object
Shifts subtitles forward (or backward) by a number of ms from an index
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/subtitle_shifter.rb', line 93 def shift(args) first = args[:index] # used for checking first go round. index = first shift = args[:time] if shift < 0 # backward shift check time1 = @subtitles[first][:start] + shift time2 = @subtitles[first-1][:end] raise RuntimeError, 'Cannot overlap backward shift' if time2 > time1 end loop do break unless @subtitles.has_key?(index) @subtitles[index][:start] += shift @subtitles[index][:end] += shift index += 1 end end |
#to_s ⇒ Object
Outputs parsed subtitles
117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/subtitle_shifter.rb', line 117 def to_s raise RuntimeError, 'File has not been parsed yet' unless @parsed_ok output = '' @subtitles.sort.map do |index, sub| start = ms_to_srt_time sub[:start] fin = ms_to_srt_time sub[:end] output += "#{index}#{@linebreak}#{start} #{TIME_SEPERATOR} #{fin}#{@linebreak}#{sub[:subtitle]}#{@linebreak}#{@linebreak}" end output.chomp end |