offset-fixer.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #!/usr/bin/env python
  2. import re
  3. from datetime import timedelta
  4. import argparse
  5. import locale
  6. import math
  7. class SubtitleEntry:
  8. def __init__(self, entryNumber, text, startTime, endTime):
  9. # dd:dd:dd,ddd --> dd:dd:dd,ddd
  10. self.entryNumber = entryNumber
  11. self.text = text
  12. sH, sM, sS = startTime.replace(',', '.').split(':')
  13. self.startTime = int(sH) * 3600 + int(sM) * 60 + float(sS)
  14. sH, sM, sS = endTime.replace(',', '.').split(':')
  15. self.endTime = int(sH) * 3600 + int(sM) * 60 + float(sS)
  16. def formatEntry(self):
  17. entry = ""
  18. entry += "{}\n".format(self.entryNumber)
  19. entry += self.formatTimeString() + "\n"
  20. entry += "{}".format(self.text)
  21. return entry
  22. def formatTimeString(self):
  23. s = self.startTime
  24. startHours = s // 3600
  25. s = s - (startHours * 3600)
  26. startMinutes = s // 60
  27. s = s - (startMinutes * 60)
  28. startSeconds = s
  29. e = self.endTime
  30. endHours = e // 3600
  31. e = e - (endHours * 3600)
  32. endMinutes = e // 60
  33. e = e - (endMinutes * 60)
  34. endSeconds = e
  35. 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 )
  36. def shift(self, seconds):
  37. self.startTime = self.startTime + seconds
  38. self.endTime = self.endTime + seconds
  39. def main():
  40. Subtitles = []
  41. parser = argparse.ArgumentParser()
  42. parser.add_argument("--seconds", help="Decimal formatted seconds to adjust offsets by", type=float)
  43. parser.add_argument("--file", help="Subtitle file to shift", type=str)
  44. parser.add_argument("--outfile", required=False, help="Subtitle file to shift", type=str)
  45. args = parser.parse_args()
  46. if args.outfile == None:
  47. args.outfile = str(args.file + ".new")
  48. print("Opening subtitle file: {}".format(args.file))
  49. with open(args.file, "r+") as file:
  50. entryNumber = 0
  51. text = ""
  52. timestamp = ""
  53. for line in file:
  54. 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)
  55. if line == "\n":
  56. #print("blank line")
  57. if (entryNumber > 0) and (timestamp is not None):
  58. #print("new entry")
  59. s = SubtitleEntry(entryNumber, text, timestamp.groups()[0], timestamp.groups()[1])
  60. Subtitles.append(s)
  61. #print(s.entryNumber, s.startTime, s.endTime, s.text)
  62. text = ""
  63. timestamp = ""
  64. entryNumber = 0
  65. elif re.match(r"^[0-9]+$", line):
  66. #print("Added entryNumber")
  67. entryNumber = int(line.rstrip())
  68. #print(entryNumber)
  69. elif m1:
  70. #print("Added timestamp")
  71. timestamp = m1
  72. #print(m1.groups()[0])
  73. #print(m1.groups()[1])
  74. else:
  75. #print("Added text:" + line)
  76. text += line
  77. print("Writing to file: {}".format(args.outfile))
  78. with open(args.outfile, 'w') as o:
  79. print("Shifting all entries by {} seconds".format(args.seconds))
  80. for entry in Subtitles:
  81. #print("\n\n\n\n")
  82. #print(entry.entryNumber)
  83. entry.shift(args.seconds)
  84. #print(entry.formatEntry())
  85. print(entry.formatEntry(), file=o)
  86. if __name__ == "__main__":
  87. main()