Skip to content

Instantly share code, notes, and snippets.

@xcv58
Created May 31, 2025 02:07
Show Gist options
  • Select an option

  • Save xcv58/7984c0dbfc4bd9f1e42615419c4449a0 to your computer and use it in GitHub Desktop.

Select an option

Save xcv58/7984c0dbfc4bd9f1e42615419c4449a0 to your computer and use it in GitHub Desktop.
Combine multiple SRT files and shift the timeline by video content length
#!/usr/bin/env python3
import os
import re
import subprocess
from natsort import natsorted
import pysrt
def get_video_duration(video_path):
"""Get video duration in milliseconds using ffprobe"""
cmd = [
'ffprobe', '-v', 'error',
'-show_entries', 'format=duration',
'-of', 'default=noprint_wrappers=1:nokey=1',
video_path
]
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
duration_sec = float(result.stdout.decode().strip())
return int(duration_sec * 1000) # Convert to milliseconds
def merge_srt_files(directory, output_file):
# Find all srt and mov files with numeric prefixes
files = [f for f in os.listdir(directory) if re.match(r'^\d+', f)]
paired_files = []
for f in files:
base = re.match(r'^(\d+)', f).group(1)
ext = os.path.splitext(f)[1]
if ext == '.srt':
mov_file = f"{base}{os.path.splitext(f)[0][len(base):]}.mov"
if mov_file in files:
paired_files.append((
int(base),
os.path.join(directory, f),
os.path.join(directory, mov_file)
))
# Sort files by numeric prefix
paired_files = natsorted(paired_files, key=lambda x: x[0])
merged_subs = pysrt.SubRipFile()
cumulative_duration = 0
for idx, (num, srt_path, mov_path) in enumerate(paired_files):
print(f"Processing {srt_path} and {mov_path}")
# Get duration of previous video segments
if idx > 0:
cumulative_duration += get_video_duration(paired_files[idx-1][2])
# Load current SRT file
subs = pysrt.open(srt_path)
# Shift timestamps for subsequent files
if idx > 0:
for sub in subs:
sub.start += cumulative_duration
sub.end += cumulative_duration
# Add to merged list
merged_subs += subs
# Clean indexes and save
merged_subs.clean_indexes()
merged_subs.save(output_file, encoding='utf-8')
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Merge sequential SRT files with video duration compensation')
parser.add_argument('input_dir', help='Directory containing numbered SRT/MOV files')
parser.add_argument('output_file', help='Path for merged SRT file')
args = parser.parse_args()
merge_srt_files(args.input_dir, args.output_file)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment