Created
May 31, 2025 02:07
-
-
Save xcv58/7984c0dbfc4bd9f1e42615419c4449a0 to your computer and use it in GitHub Desktop.
Combine multiple SRT files and shift the timeline by video content length
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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