Search code examples
pythonnumpymoviepy

Moviepy - avoid writing to disk with ImageSequenceClip?


I am generating a significant number of images and writing them to disk. I then pass an array of the filenames to ImageSequenceClip. A major bottleneck is writing the images down to disk; is there a way to keep the images in memory then pass that to ImageSequenceClip, subsequently avoiding the time necessary to write/read to disk?

filenames = []
for i in range(0, FRAMES):
    filename = "tmp/frame_%s.png" % (i)
    filenames.append(filename)
    center_x = IMG_WIDTH / 2
    center_y = IMG_HEIGHT - ((IMG_HEIGHT - i * HEIGHT_INC) / 2) 
    width = IMG_WIDTH - i * WIDTH_INC
    height = IMG_HEIGHT - i * HEIGHT_INC
    img = vfx.crop(img_w_usr_img, x_center=center_x, y_center=center_y, width=width, height=height)
    img = img.resize( (VID_WIDTH, VID_HEIGHT) )
    img.save_frame(filename)
    print "Proccessed: %s" % (filename)

seq = ImageSequenceClip(filenames, fps=FPS)

Solution

  • Have a look at this section of the docs.

    Here is how you flip a video with moviepy

    from moviepy.editor import VideoFileClip
    def flip(image):
        """Flips an image vertically """
        return image[::-1] # remember that image is a numpy array
    
    clip = VideoFileClip("my_original_video.mp4")
    new_clip = clip.fl_image( flip )
    new_clip.write_videofile("my_new_clip", some other parameters)
    

    note that there is also a predefined FX function mirror_y in moviepy so you can simply do:

    from moviepy.editor import *
    clip = VideoFileClip("my_original_video.mp4")
    new_clip = clip.fx(vfx.mirror_y)
    new_clip.write_videofile("my_new_clip", some other parameters)
    

    But if really you want to make a list of (transformed) numpy arrays first, here is how you could do:

    from moviepy.editor import *
    clip  = VideoFileClip("original_file.mp4")
    new_frames = [ some_effect(frame) for frame in clip.iter_frames()]
    new_clip = ImageSequenceClip(new_frames, fps=clip.fps)
    new_clip.write_videofile("new_file.mp4")