diff --git a/ffmpeg_video.py b/ffmpeg_video.py index 52c38f8..c455226 100644 --- a/ffmpeg_video.py +++ b/ffmpeg_video.py @@ -7,17 +7,23 @@ import time import numpy as np from sortedcontainers import SortedDict import tqdm +from PIL import Image -path_to_images = r"..\composite\goes16" +path_to_images = r"..\composite\goes18" temp_path = r"..\vid" -output_file = r"..\goes16_2023.mp4" +output_file = r"..\goes18_2024.mp4" +interp_file = r"..\goes18_2024_interp.mp4" ffmpeg_path = r"..\ffmpeg.exe" -starttime = time.mktime(datetime.datetime(2023, 1, 1).timetuple()) -stoptime = time.mktime(datetime.datetime(2024, 1, 1).timetuple()) -min_file_size = 200000 # Detect and remove corrupted files by filtering by file size -max_file_size = 500000 +starttime = time.mktime(datetime.datetime(2024, 1, 1, tzinfo=datetime.timezone.utc).timetuple()) +stoptime = time.mktime(datetime.datetime(2025, 1, 1, tzinfo=datetime.timezone.utc).timetuple()) +min_file_size = 350000 # Detect and remove corrupted files by filtering by file size +max_file_size = 450000 +encoding_crf = 16 +max_frame_interp = 1000 + os.makedirs(temp_path, exist_ok = True) +black_image = Image.fromarray(np.zeros((1080, 1920, 3), dtype='uint8')) files_by_time = SortedDict() for root, dirs, files in tqdm.tqdm(os.walk(path_to_images), desc="Finding and filtering files."): @@ -25,7 +31,8 @@ for root, dirs, files in tqdm.tqdm(os.walk(path_to_images), desc="Finding and fi if f.endswith('.jpg'): fpath = os.path.join(root, f) fsize = os.path.getsize(fpath) - ftime = int(f.replace('-', '.').split('.')[-2]) + time_chunk = f.replace('-', '.').replace('_', '.').split('.')[1] + ftime = int(time_chunk) if (fsize > min_file_size) and (fsize < max_file_size) and (ftime > starttime) and (ftime < stoptime): files_by_time[ftime] = fpath @@ -39,22 +46,30 @@ 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")}") + if framejump < max_frame_interp: + for i in range(framejump - 1): # Fill black frames to fill gaps, these will later be interpolated with ffmpeg + black_image.save(f"{os.path.join(temp_path, f"{index+1:06d}.jpg")}", quality = 95) index += 1 else: # Skip past intervals that are too large to fill reasonably + # This should never happen now that merger_FITS.py inserts black frames 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_path} -framerate 60 -pattern_type sequence -i "{os.path.join(temp_path, r"%06d.jpg")}" -c:v libx264 -crf 18 -preset veryfast {output_file}' +command_line = f'{ffmpeg_path} -framerate 60 -pattern_type sequence -i "{os.path.join(temp_path, r"%06d.jpg")}" -c:v libx264 -crf {encoding_crf} -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) \ No newline at end of file +shutil.rmtree(temp_path) + +command_line = f'{ffmpeg_path} -i {output_file} -vf blackframe=0,metadata=select:key=lavfi.blackframe.pblack:value=95:function=less,minterpolate=mi_mode=mci:mc_mode=aobmc:me_mode=bidir:vsbmc=1:me=fss -c:a copy -c:v libx264 -crf {encoding_crf} -preset veryfast {interp_file}' +print(command_line) + +pipe = subprocess.Popen(command_line, shell=True, stdout=subprocess.PIPE).stdout +output = pipe.read().decode() +pipe.close() \ No newline at end of file