secret
anonymous / dominikhonnef.rb
Last active

  • Download Gist
dominikhonnef.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
require 'optparse'
require 'ostruct'
 
class Entry < OpenStruct
end
 
class Offset
def initialize(seconds, milliseconds)
@time = Time.at(seconds, milliseconds*1000).getutc
end
 
def shift(mode, seconds, milliseconds)
offset = seconds + milliseconds/1000.0
case mode
when &#039;add&#039;
@time + offset
when &#039;sub&#039;
@time - offset
end
end
 
def shift!(mode, seconds, milliseconds)
@time = self.shift(mode, seconds, milliseconds)
end
 
def to_s
format = &quot;%02d&quot;
 
hour = sprintf(format, @time.hour)
minute = sprintf(format, @time.min)
second = sprintf(format, @time.sec)
millisecond = sprintf(format, @time.usec/1000)
 
&quot;#{hour}:#{minute}:#{second},#{millisecond}&quot;
end
 
def self.from(s)
s =~ /(\d+):(\d+):(\d+),(\d+)/
hours, minutes, seconds, milliseconds = $1.to_i, $2.to_i, $3.to_i, $4.to_i
self.new(hours*60*60+minutes*60+seconds, milliseconds)
end
end
 
class Subtitle
@@parsers = {}
def initialize
@entries = []
end
 
def shift!(mode, seconds, milliseconds)
@entries.each do |entry|
entry.start_offset.shift! mode, seconds, milliseconds
entry.end_offset.shift! mode, seconds, milliseconds
end
end
 
def shift(mode, seconds, milliseconds)
new_subtitle = self.clone
new_subtitle.shift!(mode, seconds, milliseconds)
new_subtitle
end
 
def self.get_parser(name)
@@parsers[name.downcase]
end
 
def self.parse(text)
instance = self.new
instance.parse!(text)
instance
end
 
def self.parse_file(file)
self.parse(File.read(file))
end
 
def self.inherited(by)
@@parsers[by.name.downcase] = by
end
end
 
class Subrip (\d+:\d+:\d+,\d+)\n(.+?)(?:\n\n|\Z)/m).each do |id, start_offset, end_offset, sub|
@entries &lt; id,
:start_offset =&gt; Offset.from(start_offset),
:end_offset =&gt; Offset.from(end_offset),
:sub =&gt; sub)
end
end
 
def to_s
s = ""
@entries.each do |entry|
a = [entry.entry_id.to_s, "#{entry.start_offset.to_s} --&gt; #{entry.end_offset.to_s}", entry.sub]
s &lt;&lt; a.join(&quot;\n&quot;) &lt; "subrip"}
 
OptionParser.new do |opts|
opts.on('-o', '--operation MODE', 'Whether to add or subtract an offset') do |mode|
options[:mode] = mode
end
 
opts.on('-t', '--time TIME', 'The offset, formatted as "seconds,milliseconds"') do |time|
options[:offset] = time.split(",").map{|i|i.to_i}
end
 
opts.on('-f', '--format FORMAT', 'The format of the subtitles file (e.g. "subrip")') do |format|
options[:type] = format.downcase
end
 
end.parse!(args)
 
input_file, output_file = args
 
parser = Subtitle.get_parser(options[:type])
 
subs = parser.parse_file(input_file)
subs.shift!(options[:mode], *options[:offset])
 
File.open(output_file, 'w') do |f|
f.write subs.to_s
end
end
end
 
Application.new.run(ARGV.clone)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.