Skip to content

Instantly share code, notes, and snippets.

@PlethoraChutney
Last active November 20, 2024 18:43
Show Gist options
  • Save PlethoraChutney/a5b1b455e1a9827ecf87edd05aff1406 to your computer and use it in GitHub Desktop.
Save PlethoraChutney/a5b1b455e1a9827ecf87edd05aff1406 to your computer and use it in GitHub Desktop.
Offset timestamps in an .srt file
#!/usr/bin/env python
from pathlib import Path
import re
srt_timestamp_pattern = r"^(\d{2}):(\d{2}):(\d{2}),(\d{3}) --> (\d{2}):(\d{2}):(\d{2}),(\d{3})$"
def seconds_to_minsec(full_seconds:float) -> list[int, int, int, int]:
hours = full_seconds // 3600
full_seconds -= hours * 3600
minutes = full_seconds // 60
full_seconds -= minutes * 60
seconds = int(full_seconds)
ms = int((full_seconds - seconds) * 1000)
return [int(x) for x in [hours, minutes, seconds, ms]]
def minsec_to_seconds(minsec:list[int, int, int, int]) -> float:
return minsec[0] * 3600 + minsec[1] * 60 + minsec[2] + minsec[3] / 1000
def format_hms(hour, min, sec, ms) -> str:
return f"{hour:0>2}:{min:0>2}:{sec:0>2},{ms:0>3}"
framerate = 25
out_points = [
[1, 36, 22, 1000 * (7 / framerate)],
[3, 7, 38, 1000 * (20 / framerate)],
[4, 27, 54, 1000 * (22 / framerate)],
]
videos = list(Path().glob("*.mp4"))
videos.sort()
for i, video in enumerate(videos):
if i == 0:
continue
duration_to_remove = minsec_to_seconds(out_points[i - 1])
print(f"Removing {duration_to_remove} seconds from {video}")
srt_filename = video.name.replace("mp4", "srt")
with open(srt_filename, "r") as unfixed, open(srt_filename.replace(".srt", "_fixed.srt"), "w") as fixed:
for line in unfixed:
if "-->" not in line:
fixed.write(line)
continue
matched_line = re.match(srt_timestamp_pattern, line)
assert matched_line is not None, f"Matched line failed on this line: {line}"
start = [int(matched_line.group(x)) for x in [1, 2, 3, 4]]
end = [int(matched_line.group(x)) for x in [5, 6, 7, 8]]
start = minsec_to_seconds(start)
end = minsec_to_seconds(end)
start -= duration_to_remove
end -= duration_to_remove
start = seconds_to_minsec(start)
end = seconds_to_minsec(end)
fixed.write(f"{format_hms(*start)} --> {format_hms(*end)}\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment