def develop_drawn_clip(org_clip: VideoFileClip, sq_frames: List[float], all_frames: List[np.ndarray], buffer_s: float = 1) -> VideoClip: """Calculates subclip start and end time, creates a subclip to reference. Combines the drawn frames (with buffer) before transforming into a video clip Adds original clip's audio to the video containing drawn frames. Args: org_clip: the original clip to leverage audio, duration data from sq_frames: the sequence of frames that have motion annotations draw in them all_frames: the full list of frames that we'll be slicing buffer_s: the seconds of buffer to add before and after the motion area """ duration = org_clip.duration tot_frames = len(all_frames) # Calculate number of frames to buffer before and after motion areas buffer_fr = int(org_clip.fps * buffer_s) # Calculate the start and end frames with the buffers st_with_buffer = sq_frames[0] end_with_buffer = sq_frames[-1] + buffer_fr start_frame_pos = st_with_buffer if st_with_buffer > 0 else 0 end_frame_pos = end_with_buffer if end_with_buffer < tot_frames else tot_frames - 1 # Calculate the start and end times for the start and end frames start_t = ((start_frame_pos / tot_frames) * duration) end_t = ((end_frame_pos / tot_frames) * duration) # Cut the original clip to fit the buffer cut_clip = org_clip.subclip(start_t, end_t) # Generate the sequence of drawn clips drawn_clip = ImageSequenceClip(all_frames[start_frame_pos:end_frame_pos], fps=org_clip.fps) if drawn_clip.duration != cut_clip.duration: # Cut the tail off the drawn clip to match the cut_clip. drawn_clip = drawn_clip.subclip(0, end_t - start_t) # Make the drawn clip a VideoClip by concatenating it with only itself. Add original clip's audio drawn_clip = concatenate_videoclips([drawn_clip]) drawn_clip.audio = cut_clip.audio return drawn_clip