🎬 MoviePy Cheat Sheet

🎬 MoviePy Cheat Sheet #

πŸš€ Installation & Setup #

# Basic installation
pip install moviepy

# With optional dependencies
pip install moviepy[optional]

# Using uv (recommended)
uv add moviepy

πŸ“š Core Concepts #

Import Structure #

from moviepy.editor import *
# Or specific imports
from moviepy.video.io.VideoFileClip import VideoFileClip
from moviepy.audio.io.AudioFileClip import AudioFileClip
from moviepy.video.VideoClip import TextClip, ImageClip
from moviepy.video.compositing.CompositeVideoClip import CompositeVideoClip

Clip Types #

  • VideoFileClip: Load video files
  • AudioFileClip: Load audio files
  • ImageClip: Static images as video
  • TextClip: Text overlays
  • ColorClip: Solid color backgrounds
  • CompositeVideoClip: Layer multiple clips

πŸŽ₯ Video Operations #

Loading & Basic Operations #

# Load video
clip = VideoFileClip("input.mp4")

# Basic properties
print(f"Duration: {clip.duration}")
print(f"FPS: {clip.fps}")
print(f"Size: {clip.size}")  # (width, height)

# Subclipping (trim)
trimmed = clip.subclip(10, 30)  # seconds 10-30
trimmed = clip.subclip(t_start=10)  # from 10s to end
trimmed = clip.subclip(t_end=30)   # from start to 30s

Transformations #

# Resize
resized = clip.resize(0.5)  # 50% scale
resized = clip.resize((640, 480))  # specific size
resized = clip.resize(width=640)  # maintain aspect ratio

# Rotation
rotated = clip.rotate(90)  # degrees

# Position
positioned = clip.set_position(('center', 'center'))
positioned = clip.set_position((50, 100))  # x, y pixels

# Speed/Duration
faster = clip.fx(speedx, 2)  # 2x speed
slower = clip.fx(speedx, 0.5)  # 0.5x speed
extended = clip.set_duration(10)  # force duration

Effects & Filters #

# Built-in effects
from moviepy.video.fx import *

blurred = clip.fx(blur, 2)
faded_in = clip.fx(fadein, 1)  # 1 second fade in
faded_out = clip.fx(fadeout, 1)  # 1 second fade out
mirrored = clip.fx(mirror_x)
inverted = clip.fx(invert_colors)

# Custom effects with lambda
brightened = clip.fl_image(lambda img: img * 1.2)  # 20% brighter

🎡 Audio Operations #

Audio Extraction & Manipulation #

# Extract audio from video
audio = video_clip.audio
audio.write_audiofile("extracted.mp3")

# Load audio file
audio = AudioFileClip("music.mp3")

# Audio operations
louder = audio.fx(volumex, 1.5)  # 50% louder
quieter = audio.fx(volumex, 0.5)  # 50% quieter
faded = audio.fx(audio_fadein, 2).fx(audio_fadeout, 2)

# Set audio to video
video_with_audio = video_clip.set_audio(audio)

# Remove audio
silent_video = video_clip.without_audio()

Audio Concatenation & Mixing #

from moviepy.audio.AudioClip import concatenate_audioclips, CompositeAudioClip

# Concatenate audio clips
combined_audio = concatenate_audioclips([audio1, audio2, audio3])

# Mix multiple audio tracks
mixed_audio = CompositeAudioClip([background_music, voice_over])

πŸ“ Text & Graphics #

Text Clips #

# Basic text
text = TextClip("Hello World!", 
                fontsize=50, 
                color='white',
                font='Arial-Bold')

# Advanced text styling
text = TextClip("Styled Text",
                fontsize=60,
                color='white',
                stroke_color='black',
                stroke_width=2,
                method='caption',
                size=(640, None))  # wrap text

# Position and duration
text = text.set_position('center').set_duration(5)

Image Clips #

# Static image
img = ImageClip("image.jpg").set_duration(5)

# Animated image sequence
from moviepy.video.io.ImageSequenceClip import ImageSequenceClip
sequence = ImageSequenceClip(['frame1.jpg', 'frame2.jpg'], fps=24)

# Color background
background = ColorClip(size=(1920, 1080), color=(255, 0, 0)).set_duration(10)

🎭 Compositing & Layering #

CompositeVideoClip #

# Layer multiple clips
composite = CompositeVideoClip([
    background_clip,
    video_clip.set_position('center'),
    text_clip.set_position(('right', 'top')),
    logo.set_position((50, 50))
])

# With transparency/masking
composite = CompositeVideoClip([
    background,
    overlay.set_opacity(0.7)  # 70% opacity
])

Concatenation #

from moviepy.video.VideoClip import concatenate_videoclips

# Join clips end-to-end
final_video = concatenate_videoclips([clip1, clip2, clip3])

# With transitions
final_video = concatenate_videoclips([clip1, clip2], method="compose")

πŸ”„ Transitions & Advanced Effects #

Crossfade Transition #

# Simple crossfade
clip1_faded = clip1.fx(fadeout, 1)
clip2_faded = clip2.fx(fadein, 1)
transition = CompositeVideoClip([
    clip1_faded,
    clip2_faded.set_start(clip1.duration - 1)
])

Custom Transitions #

def slide_in(clip, direction='left'):
    w, h = clip.size
    if direction == 'left':
        return clip.set_position(lambda t: (w * (t/clip.duration - 1), 'center'))
    elif direction == 'right':
        return clip.set_position(lambda t: (w * (1 - t/clip.duration), 'center'))

sliding_clip = slide_in(my_clip, 'left')

🎬 Rendering & Export #

Basic Export #

# Standard export
clip.write_videofile("output.mp4")

# With specific codec settings
clip.write_videofile("output.mp4",
                     codec='libx264',
                     audio_codec='aac',
                     temp_audiofile='temp-audio.m4a',
                     remove_temp=True)

Performance Optimization #

# Multi-threading
clip.write_videofile("output.mp4", 
                     threads=4,
                     preset='medium')  # ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow

# Custom ffmpeg parameters
clip.write_videofile("output.mp4",
                     ffmpeg_params=['-crf', '18', '-preset', 'slow'])

# Progress callback
def progress_callback(t):
    print(f"Progress: {t:.2f}s")

clip.write_videofile("output.mp4", verbose=False, logger=progress_callback)

Format-Specific Exports #

# GIF export
clip.write_gif("output.gif", fps=15)

# Image sequence
clip.write_images_sequence("frame_%04d.png")

# Audio only
clip.audio.write_audiofile("audio.mp3")

πŸ”§ Advanced Techniques #

Memory Management #

# For large videos - process in chunks
def process_large_video(input_path, output_path, chunk_duration=60):
    clip = VideoFileClip(input_path)
    chunks = []
    
    for i in range(0, int(clip.duration), chunk_duration):
        chunk = clip.subclip(i, min(i + chunk_duration, clip.duration))
        processed_chunk = chunk.fx(some_effect)  # Apply effects
        chunks.append(processed_chunk)
        chunk.close()  # Free memory
    
    final = concatenate_videoclips(chunks)
    final.write_videofile(output_path)
    
    # Cleanup
    for chunk in chunks:
        chunk.close()
    clip.close()

Custom Effects with NumPy #

import numpy as np

def custom_color_effect(get_frame, t):
    frame = get_frame(t)
    # Apply custom NumPy operations
    frame[:, :, 0] = np.clip(frame[:, :, 0] * 1.2, 0, 255)  # Boost red channel
    return frame

modified_clip = clip.fl(custom_color_effect)

Masking & Alpha Channels #

# Create mask from image
mask = ImageClip("mask.png", ismask=True)
masked_clip = clip.set_mask(mask)

# Circular mask
def make_circular_mask(clip):
    h, w = clip.size
    center = (w//2, h//2)
    radius = min(w, h) // 2
    
    def mask_function(t):
        frame = np.zeros((h, w))
        y, x = np.ogrid[:h, :w]
        mask_area = (x - center[0])**2 + (y - center[1])**2 <= radius**2
        frame[mask_area] = 1
        return frame
    
    return clip.set_mask(lambda t: mask_function(t))

πŸ“Š Performance Tips #

Optimization Strategies #

# 1. Use subclips to work with smaller portions
working_clip = large_clip.subclip(0, 30)

# 2. Resize before processing heavy effects
clip = clip.resize(0.5).fx(heavy_effect).resize(2.0)

# 3. Set fps early for consistency
clip = clip.set_fps(24)

# 4. Use write_videofile parameters efficiently
clip.write_videofile("output.mp4",
                     preset='fast',        # Faster encoding
                     threads=os.cpu_count(),  # Use all CPU cores
                     verbose=False)        # Reduce console output

Memory Management #

# Always close clips when done
clip.close()

# Use context managers for automatic cleanup
from contextlib import contextmanager

@contextmanager
def video_clip(path):
    clip = VideoFileClip(path)
    try:
        yield clip
    finally:
        clip.close()

# Usage
with video_clip("input.mp4") as clip:
    processed = clip.fx(some_effect)
    processed.write_videofile("output.mp4")

🎯 Common Use Cases #

1. Social Media Content #

# Instagram square format
def make_instagram_video(clip):
    return clip.resize((1080, 1080)).set_position('center')

# TikTok vertical format  
def make_tiktok_video(clip):
    return clip.resize((1080, 1920)).set_position('center')

2. Slideshow Creation #

def create_slideshow(image_paths, duration_per_image=3):
    clips = []
    for path in image_paths:
        img_clip = ImageClip(path).set_duration(duration_per_image)
        clips.append(img_clip)
    
    return concatenate_videoclips(clips, method="compose")

3. Audio Visualization #

def create_audio_visualizer(audio_path, video_size=(1280, 720)):
    # This is a simplified version - real implementation would use librosa
    audio = AudioFileClip(audio_path)
    
    # Create visualizer frames (placeholder)
    background = ColorClip(size=video_size, color=(0, 0, 0))
    background = background.set_duration(audio.duration)
    
    # Add audio
    final = background.set_audio(audio)
    return final

πŸ› Troubleshooting #

Common Issues #

# Issue: "FFMPEG not found"
# Solution: Install ffmpeg separately or use imageio-ffmpeg
pip install imageio-ffmpeg

# Issue: Memory errors with large files
# Solution: Process in chunks or reduce resolution first

# Issue: Audio sync problems
# Solution: Ensure consistent fps and use audio_fps parameter
clip.write_videofile("output.mp4", audio_fps=44100)

# Issue: Slow rendering
# Solution: Use appropriate presets and threading
clip.write_videofile("output.mp4", preset='fast', threads=4)

Debugging Tips #

# Preview without rendering
clip.preview()  # Opens preview window

# Check clip properties
print(f"Duration: {clip.duration}")
print(f"FPS: {clip.fps}")
print(f"Size: {clip.size}")

# Save single frame for testing
clip.save_frame("test_frame.png", t=10)  # Frame at 10 seconds

πŸ”— Integration Examples #

With OpenCV #

import cv2

def opencv_effect(frame):
    # Convert MoviePy frame to OpenCV format
    cv_frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
    
    # Apply OpenCV operations
    blurred = cv2.GaussianBlur(cv_frame, (15, 15), 0)
    
    # Convert back to MoviePy format
    return cv2.cvtColor(blurred, cv2.COLOR_BGR2RGB)

processed_clip = clip.fl_image(opencv_effect)

With Librosa (Audio Analysis) #

import librosa
import numpy as np

def sync_video_to_beats(video_clip, audio_path):
    # Analyze audio for beats
    y, sr = librosa.load(audio_path)
    tempo, beats = librosa.beat.beat_track(y=y, sr=sr)
    
    # Create beat-synced effects
    beat_times = librosa.frames_to_time(beats, sr=sr)
    
    clips = []
    for i, beat_time in enumerate(beat_times[:-1]):
        duration = beat_times[i+1] - beat_time
        segment = video_clip.subclip(beat_time, beat_times[i+1])
        
        # Apply beat-synced effect
        if i % 2 == 0:
            segment = segment.fx(invert_colors)
        
        clips.append(segment)
    
    return concatenate_videoclips(clips)

πŸ“‹ Best Practices #

Code Organization #

class VideoProcessor:
    def __init__(self, input_path):
        self.clip = VideoFileClip(input_path)
    
    def add_intro(self, intro_text, duration=3):
        intro = TextClip(intro_text, fontsize=50, color='white')
        intro = intro.set_duration(duration).set_position('center')
        self.clip = concatenate_videoclips([intro, self.clip])
        return self
    
    def add_background_music(self, music_path, volume=0.3):
        music = AudioFileClip(music_path).fx(volumex, volume)
        music = music.set_duration(self.clip.duration)
        self.clip = self.clip.set_audio(CompositeAudioClip([self.clip.audio, music]))
        return self
    
    def export(self, output_path, **kwargs):
        self.clip.write_videofile(output_path, **kwargs)
        return self
    
    def __enter__(self):
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.clip.close()

# Usage
with VideoProcessor("input.mp4") as processor:
    processor.add_intro("Welcome!").add_background_music("bg.mp3").export("output.mp4")

Error Handling #

def safe_video_processing(input_path, output_path):
    clip = None
    try:
        clip = VideoFileClip(input_path)
        
        # Processing steps
        processed = clip.fx(some_effect)
        processed.write_videofile(output_path)
        
        return True
        
    except Exception as e:
        print(f"Error processing video: {e}")
        return False
        
    finally:
        if clip:
            clip.close()

πŸš€ MoviePy v2.0 Updates #

Breaking Changes #

  • Import structure changes
  • Some method names updated
  • Performance improvements
  • Better memory management

New Features #

  • Enhanced audio processing
  • Improved text rendering
  • Better codec support
  • Streamlined API

Migration Tips #

# v1.x style (deprecated)
from moviepy.editor import VideoFileClip

# v2.x style (recommended)
from moviepy.video.io.VideoFileClip import VideoFileClip

πŸ’‘ Pro Tip: Always close your clips with clip.close() to free memory, especially when processing multiple videos in a loop!

🎬 MoviePy is perfect for programmatic video editing, automation, and creating dynamic content. Combine it with other Python libraries like OpenCV, librosa, and NumPy for powerful multimedia applications!