| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 | #!/usr/bin/env pythonimport refrom datetime import timedeltaimport argparseimport localeimport mathclass SubtitleEntry:  def __init__(self, entryNumber, text, startTime, endTime):    # dd:dd:dd,ddd --> dd:dd:dd,ddd    self.entryNumber = entryNumber    self.text = text    sH, sM, sS = startTime.replace(',', '.').split(':')    self.startTime = int(sH) * 3600 + int(sM) * 60 + float(sS)    sH, sM, sS = endTime.replace(',', '.').split(':')    self.endTime = int(sH) * 3600 + int(sM) * 60 + float(sS)  def formatEntry(self):    entry = ""    entry += "{}\n".format(self.entryNumber)    entry += self.formatTimeString() + "\n"    entry += "{}".format(self.text)    return entry  def formatTimeString(self):    s = self.startTime    startHours = s // 3600    s = s - (startHours * 3600)    startMinutes = s // 60    s = s - (startMinutes * 60)    startSeconds = s    e = self.endTime    endHours = e // 3600    e = e - (endHours * 3600)    endMinutes = e // 60    e = e - (endMinutes * 60)    endSeconds = e    return '{:02.0f}:{:02.0f}:{:02.0f},{:03.0f} --> {:02.0f}:{:02.0f}:{:02.0f},{:03.0f}'.format(startHours, startMinutes, math.floor(startSeconds), (startSeconds % 1) * 1000 , endHours, endMinutes, math.floor(endSeconds), (endSeconds % 1) * 1000 )  def shift(self, seconds):    self.startTime = self.startTime + seconds        self.endTime = self.endTime + secondsdef main():  Subtitles = []  parser = argparse.ArgumentParser()  parser.add_argument("--seconds", help="Decimal formatted seconds to adjust offsets by", type=float, required=True)  parser.add_argument("--file", help="Subtitle file to shift", type=str, required=True)  parser.add_argument("--inplace", required=False, help="Shift file in place, creating a backup", action='store_true')  parser.add_argument("--outfile", required=False, help="New subtitle filename", type=str)  args = parser.parse_args()  if args.inplace is True:      if args.outfile == None:        args.outfile = str(args.file + ".backup")      else:        sys.exit(1)  if args.outfile == None:      args.outfile = str(args.file + ".new")  print("Opening subtitle file: {}".format(args.file))  with open(args.file, "r+") as file:    entryNumber = 0    text = ""    timestamp = ""    for line in file:      m1 = re.match(r"^([0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}) --> ([0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3})", line)      if line == "\n":        if (entryNumber > 0) and (timestamp is not None):          s = SubtitleEntry(entryNumber, text, timestamp.groups()[0], timestamp.groups()[1])          Subtitles.append(s)          text = ""          timestamp = ""          entryNumber = 0      elif re.match(r"^[0-9]+$", line):        entryNumber = int(line.rstrip())      elif m1:        timestamp = m1      else:        text += line  if args.inplace == True:    args.outfile = args.file    args.file = args.file + ".backup"    with open(args.file, 'w') as o:      print("Writing backup to " + args.file)      for entry in Subtitles:        print(entry.formatEntry(), file=o)  print("Updating subtitle file: " + args.outfile)  with open(args.outfile, 'w') as o:    print("Shifting all entries by {} seconds".format(args.seconds))    for entry in Subtitles:      entry.shift(args.seconds)      print(entry.formatEntry(), file=o)if __name__ == "__main__":  main()
 |