Let there exist some function process_frame that takes in the current frame from a video and crops it to some new dimensions X2 x Y2. This can be accomplished by slicing the frame to the new dimensions:
I can return this value and blit it to the screen with SDL2, but I want to just export the cropped frames to a new mp4 file. This can be accomplished with cv2, but it is blurry, choppy, no audio, and the export is 2x slower than the FPS specified. I want to maintain as clean of a resolution as possible, maintain audio, speed, encoding (HEVC.265 preferably), but I have no clue how this is done iteratively with FFMPEG.
I've seen video exports done in one Terminal function, but the nuance here is that each cropped frame location will be different, so it is necessary to do this iteratively.
How is this done, and more specifically, how can I keep quality?
Code for reference:
import cv2 import sdl2 import sdl2.ext import numpy as np import time, sys, os from display import Display # auto-reframe new feature resolution W, H = 1920//2, 1080//2 prev_x = 0 new_W_ratio = int((9*H) / 16) cropped_frames =  disp = Display(new_W_ratio, H) def BlurValue(W, H): """ The blur value is the dimension average divided by 10 """ avg = (W + H) // 2 return int(avg//10) def process_frame(img, firstFrame=None): global prev_x img = cv2.resize(img, (W, H)) # take note of crop ratio (16:9) new_W_ratio = int((9*H) / 16) # ... cnts, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Loop through all contours and find the average nearest neighbor for c in cnts: (x, y, w, h) = cv2.boundingRect(c) if prev_x == 0: prev_x = x avg_x = (x+prev_x)/2 if prev_x == 0: prev_x = x if abs(x - prev_x) < 25 and abs(prev_x - avg_x) < 50 and x != 0: prev_x = x cropped_frame = img[0:H, x:x+new_W_ratio] cropped_frames.append(cropped_frame) elif x != 0: cropped_frame = img[0:H, prev_x:prev_x+new_W_ratio] cropped_frames.append(cropped_frame) else: cropped_frame = img[0:H, prev_x:prev_x+new_W_ratio] cropped_frames.append(cropped_frame) disp.paint(cropped_frame) if __name__ == "__main__": cap = cv2.VideoCapture("TESTAUTOREFRAME.mov") previousFrame = None # save the auto reframe as a new file fourcc = cv2.VideoWriter_fourcc(*'mp4v') output_video = cv2.VideoWriter('output_auto_reframe.mp4', fourcc, 120, (new_W_ratio, H)) while cap.isOpened(): ret, frame = cap.read() if ret == True: process_frame(frame) else: break for f in cropped_frames: output_video.write(f) output_video.release() cap.release() cv2.destroyAllWindows()