Create a gist now

Instantly share code, notes, and snippets.

anonymous /rosas.rb Secret
Created Oct 5, 2009

What would you like to do?
require 'optparse'
optparse = do |opts|
opts.banner = 'Usage: shift_subtitle.rb --operation add|sub --time ss,mmm input_file output_file'
opts.on('--operation OPERATION', /^add|sub$/, 'OPERATION must be add or sub'){|o| @operation=o}
opts.on('--time TIME_SHIFT', /^\d{2},\d{3}$/,
'TIME_SHIFT must be in format ss,mmm, where ss are the seconds and mmm are the milliseconds to shift') do |o|
@time_shift = o.sub(',', '.').to_f
opts.on('-f', '--force', 'Forces overwrite of output file without prompt'){|o| @force=true}
rescue OptionParser::ParseError => e
puts "\n", e, "\n"
def exit_with_msg(msg); puts msg; exit(1); end
exit_with_msg unless ARGV.size==2 and @operation and @time_shift
exit_with_msg "Input file '#{ARGV[0]}' doesn't exist." unless File.exists?(ARGV[0])
exit_with_msg "Output file '#{ARGV[1]}' already exists. Use --force switch to overwrite it." unless @force or not File.exists?(ARGV[1])
TIME_FORMAT = '\d{2}:\d{2}:\d{2},\d{3}'
TIME_FORMAT_REGEXP = /(\d{2}):(\d{2}):(\d{2}),(\d{3})/
def shift_time(time)
h, m, s, ms = TIME_FORMAT_REGEXP.match(time)[1..-1].collect{|v| v.to_i}*60**2+m*60+s, ms*1000) + @time_shift*(@operation == 'add' ? 1 : -1)
t.strftime('%H:%M:%S,')+ "%03d" % (t.usec/1000).to_s
input =[0])
new_line = input.readline[-2] == "\r"[0] ? "\r\n" : "\n" # \r == 13
empty_line = new_line*2
input.rewind[1], 'w') do |output|
while (subtitle=input.gets(empty_line))
matched, start_time, end_time = /\A\d*#{new_line}(#{TIME_FORMAT}) --> (#{TIME_FORMAT}).*/m.match(subtitle).to_a
exit_with_msg "Invalid file format. Output file is truncated. Context: \n#{subtitle}" unless matched
output < #{TIME_FORMAT}/, "#{shift_time(start_time)} --> #{shift_time(end_time)}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment