I'm trying to export videos programmatically using Moviepy. The code below generates a video from input in the form of audio and image, and adds a zoom-out effect. I'm using this program to generate very long (2.5+ h) videos and I'm looking to speed up the export. What are some ideas for achieving this? Thanks! Moviepy version is 2.1.2 Pillow version is 9.5.0 # import import math import numpy from PIL import Image from moviepy import AudioFileClip, ImageClip, CompositeVideoClip from moviepy.audio.fx import MultiplyVolume from moviepy.video.fx import FadeOut def generate_video(video_folder_path, audio_file_path, image_file_path, temp_path): # define zoom effect function def zoom_effect(clip, zoom_ratio=1.2): def effect(get_frame, t): img = Image.fromarray(get_frame(t)) base_size = img.size new_size = [ math.ceil(img.size[0] * zoom_ratio * 1 / (1 - (t / clip.duration) * (1 - zoom_ratio))), math.ceil(img.size[1] * zoom_ratio * 1 / (1 - (t / clip.duration) * (1 - zoom_ratio))) ] img = img.resize(new_size, Image.LANCZOS) x = math.ceil((new_size[0] - base_size[0]) / 2) y = math.ceil((new_size[1] - base_size[1]) / 2) img = img.crop([ x, y, new_size[0] - x, new_size[1] - y ]).resize(base_size, Image.LANCZOS) result = numpy.array(img) img.close() return result return clip.transform(effect) # define export settings audio_volume = 1 aspect_ratio = 16 / 9 z_ratio = 1.18 fade_out_duration = 1.15 export_fps = 24 # create clips audio_clip = AudioFileClip(audio_file_path).with_effects([MultiplyVolume(audio_volume)]) image_clip = ImageClip(image_file_path, duration=audio_clip.duration).with_position(('center', 'center')) # set dimensions height = image_clip.size[1] width = int(height * aspect_ratio) # apply zoom effect image_clip = zoom_effect(image_clip, z_ratio) # compose video_clip = CompositeVideoClip([image_clip], size=(width, height)).with_effects([FadeOut(fade_out_duration)]) # set audio video_clip.audio = audio_clip # write video_clip.write_videofile( video_folder_path + '/main_video.mp4', fps=export_fps, temp_audiofile_path=temp_path, preset='ultrafast', threads=18) Then, the function runs inside a for loop for every subdirectory in a directory: for video_folder in sorted([f for f in os.scandir('path/to/directory') if os.path.isdir(f)], key=lambda x: id_to_num(x.name)): generate_video(video_folder.path) I have tried different options for the parameters "preset" and "threads" in write_videofile. I'm guessing there is room for improvement with the zoom effect. Disabling the zoom effect results in circa 23 it/s increase. The rate is about 24 it/s with the zoom enabled. Continue reading...