Skip to content

Instantly share code, notes, and snippets.

@meinside
Last active May 3, 2022 08:16
Show Gist options
  • Save meinside/41f9849e8c72d1be376bf4dafa4b48c7 to your computer and use it in GitHub Desktop.
Save meinside/41f9849e8c72d1be376bf4dafa4b48c7 to your computer and use it in GitHub Desktop.
Shift times in a .srt file
#!/usr/bin/env ruby
# frozen_string_literal: false
# Shift times in given .srt file
#
# ./shift_srt.rb [SRT_FILEPATH] [MSECS_TO_SHIFT]
#
# ex: ./shift_srt.rb some_srt_file.srt 420
#
# created by [email protected]
# last update: 2021.07.21.
TIMELINE_REGEX = /(\d\d):(\d\d):(\d\d),(\d\d\d) --> (\d\d):(\d\d):(\d\d),(\d\d\d)/.freeze
def msecs_to_str(msecs)
s = (msecs / 1000).to_i
h = (s / 3600).to_i
m = (s / 60).to_i
s = s % 60
ms = msecs % 1000
format('%<h>02d:%<m>02d:%<s>02d,%<ms>03d', { h: h, m: m, s: s, ms: ms })
end
# shift all occurrences of time with given delta (in msecs)
def shift_all(original, delta)
original.gsub(TIMELINE_REGEX) do |_|
from_hours = Regexp.last_match(1).to_i
from_minutes = Regexp.last_match(2).to_i
from_seconds = Regexp.last_match(3).to_i
from_msecs = Regexp.last_match(4).to_i
from = (from_hours * 60 * 60 + from_minutes * 60 + from_seconds) * 1000 + from_msecs
to_hours = Regexp.last_match(5).to_i
to_minutes = Regexp.last_match(6).to_i
to_seconds = Regexp.last_match(7).to_i
to_msecs = Regexp.last_match(8).to_i
to = (to_hours * 60 * 60 + to_minutes * 60 + to_seconds) * 1000 + to_msecs
# shift
from += delta
to += delta
"#{msecs_to_str(from)} --> #{msecs_to_str(to)}"
end
end
if __FILE__ == $PROGRAM_NAME
if ARGV.count < 2
puts "* usage: #{$PROGRAM_NAME} [SRT_FILEPATH] [MSECS_TO_SHIFT]"
exit 1
end
filepath = File.expand_path(ARGV[0])
if File.exist? filepath
msecs = ARGV[1].to_i
puts "> shifting #{msecs} msecs: #{filepath}"
original = File.open(filepath, 'r').read
converted = shift_all(original, msecs)
converted_filepath = filepath.gsub('.srt', '_shifted.srt')
File.open(converted_filepath, 'w') do |file|
file.write converted
end
puts "> saved to: #{converted_filepath}"
else
puts "* file not found: #{filepath}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment