import subprocess import os import shutil import datetime import time import numpy as np from sortedcontainers import SortedDict import tqdm path_to_images = r"..\composite\goes16" temp_path = r"..\vid" output_file = r"..\goes16.mp4" starttime = time.mktime(datetime.datetime(2024, 1, 1).timetuple()) stoptime = time.mktime(datetime.datetime(2099, 1, 1).timetuple()) min_file_size = 200000 # Detect and remove corrupted files by filtering by file size max_file_size = 500000 os.makedirs(temp_path, exist_ok = True) files_by_time = SortedDict() for root, dirs, files in tqdm.tqdm(os.walk(path_to_images), desc="Finding and filtering files."): for f in files: if f.endswith('.jpg'): fpath = os.path.join(root, f) fsize = os.path.getsize(fpath) ftime = int(f.replace('-', '.').split('.')[-2]) if (fsize > min_file_size) and (fsize < max_file_size) and (ftime > starttime) and (ftime < stoptime): files_by_time[ftime] = fpath difftimes = np.diff(files_by_time.keys()) unique, counts = np.unique(difftimes, return_counts=True) interval = unique[0] assert np.sum((unique % interval) > 0) == 0 # Ensure all our timestamps align perfectly with our interval prevtime = files_by_time.peekitem(0)[0] - interval index = 0 newfpath = "" for t, f in tqdm.tqdm(files_by_time.items(), desc="Copying files to transcode dir", total = len(files_by_time)): framejump = (t - prevtime) // interval if framejump < 60: for i in range(framejump - 1): # Repeat old frame to fill gaps shutil.copy(newfpath, f"{os.path.join(temp_path, f"{index+1:06d}.jpg")}") index += 1 else: # Skip past intervals that are too large to fill reasonably print(f"Detected a frame gap of: {framejump}!") newfpath = f"{os.path.join(temp_path, f"{index+1:06d}.jpg")}" shutil.copy(f, newfpath) prevtime = t index += 1 command_line = f'ffmpeg -framerate 60 -pattern_type sequence -i "{os.path.join(temp_path, r"%06d.jpg")}" -c:v libx264 -crf 18 -preset veryfast {output_file}' print(command_line) pipe = subprocess.Popen(command_line, shell=True, stdout=subprocess.PIPE).stdout output = pipe.read().decode() pipe.close() shutil.rmtree(temp_path)