-
-
Save anonymous/f776754f514f54bbeb26 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'optparse' | |
# create an empty hash to hold the options | |
options = {} | |
optparse = OptionParser.new do|opts| | |
opts.banner = "Usage: shift_subtitle [options] infile outfile" | |
opts.on('-h', '--help', 'Display this screen') do | |
puts opts | |
exit | |
end | |
opts.on('-o', '--operation [add|sub]', 'What type of operation to use') do|o| | |
if o == 'add' or o == 'sub' | |
options[:operation] = o | |
else | |
puts "operation must be 'add' or 'sub'." | |
exit | |
end | |
end | |
opts.on('-t', '--time [HH:[MM:[SS,[mmm]]]]', 'Amount of time to shift') do|t| | |
options[:time] = t | |
end | |
end | |
optparse.parse! | |
# make sure the files exist... | |
ARGV[0] ? options[:file1] = ARGV[0] : exit | |
ARGV[1] ? options[:file2] = ARGV[1] : exit | |
class SubtitleTime | |
attr_accessor :hours, :minutes, :seconds, :milliseconds | |
# reverse char by char block | |
# at first comma, set milli | |
# at first : set seconds, etc. | |
def initialize(time, modifier='add') | |
num = '' | |
set_sec,set_min,set_hour= false | |
time.reverse.each_char do|char| | |
if num =~ /\d\d\d/ | |
@milliseconds = num.to_i | |
num = '' | |
set_sec = true | |
elsif char == ':' and set_sec | |
@seconds = num.to_i | |
num = '' | |
set_sec = false | |
set_min = true | |
elsif char == ':' and set_min | |
@minutes = num.to_i | |
num = '' | |
set_min = false | |
set_hour = true | |
elsif char == ':' and set_hour | |
@hours = num.to_i | |
num = '' | |
else | |
num = char + num | |
end | |
end | |
if set_sec | |
@seconds = num.to_i | |
elsif set_min | |
@minutes = num.to_i | |
elsif set_hour | |
@hours = num.to_i | |
end | |
@milliseconds = @milliseconds || 0 | |
@seconds = @seconds || 0 | |
@minutes = @minutes || 0 | |
@hours = @hours || 0 | |
@modifier = modifier | |
end | |
def change_hour(hours) | |
if @modifier == 'add' | |
@hours += hours | |
else | |
@hours -= hours | |
if @hours < 0 | |
@hours = 0 | |
end | |
end | |
end | |
def change_min(minutes) | |
if @modifier == 'add' | |
@minutes += minutes | |
if @minutes >= 60 | |
hours = @minutes/60 | |
change_hour(hours) | |
@minutes %= 60 | |
end | |
else | |
@minutes -= minutes | |
if @minutes < 0 | |
change_hour(1) | |
@minutes += 60 | |
end | |
end | |
end | |
def change_sec(seconds) | |
if @modifier == 'add' | |
@seconds += seconds | |
if @seconds >= 60 | |
minutes = @seconds/60 | |
change_min(minutes) | |
@seconds %= 60 | |
end | |
else | |
@seconds -= seconds | |
if @seconds < 0 | |
change_min(1) | |
@seconds += 60 | |
end | |
end | |
end | |
def change_milli(milli) | |
if @modifier == 'add' | |
@milliseconds += milli | |
if @milliseconds >= 1000 | |
seconds = @milliseconds/1000 | |
change_sec(seconds) | |
@milliseconds %= 1000 | |
end | |
else | |
@milliseconds -= milli | |
if @milliseconds < 0 | |
change_sec(1) | |
@milliseconds += 1000 | |
end | |
end | |
end | |
def to_s | |
return sprintf("%02d:%02d:%02d,%03d", @hours, @minutes, @seconds, @milliseconds) | |
end | |
end | |
# turn the input time into a SubtitleTime object | |
time_mod = SubtitleTime.new(options[:time]) | |
out_file = File.new(options[:file2], "w") | |
# every line that has timestamps | |
# take each time stamp split into h/m/s/ms | |
# apply the operation | |
# how to deal with carry overs? | |
IO.foreach(options[:file1]) do|line| | |
if (line =~ /-->/) | |
first = SubtitleTime.new(line.split(/ --> /)[0], options[:operation]) | |
second = SubtitleTime.new(line.split(/ --> /)[1], options[:operation]) | |
first.change_hour(time_mod.hours) | |
first.change_min(time_mod.minutes) | |
first.change_sec(time_mod.seconds) | |
first.change_milli(time_mod.milliseconds) | |
second.change_hour(time_mod.hours) | |
second.change_min(time_mod.minutes) | |
second.change_sec(time_mod.seconds) | |
second.change_milli(time_mod.milliseconds) | |
out_file.syswrite("#{first.to_s} --> #{second.to_s}\n") | |
else | |
out_file.syswrite(line) | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment