Skip to main content

Your First Video

Let’s create a simple video to get you started with MovieLite. This guide will walk you through loading a video, applying effects, and rendering the output.
1

Import MovieLite

Start by importing the necessary modules:
from movielite import VideoClip, VideoWriter, vfx
2

Load a video clip

Load your input video:
clip = VideoClip("input.mp4")
3

Apply effects

Add fade in and fade out effects:
clip.add_effect(vfx.FadeIn(duration=1.0))
clip.add_effect(vfx.FadeOut(duration=1.5))
4

Create a writer and render

Set up the writer and render your video:
writer = VideoWriter("output.mp4", fps=clip.fps, size=clip.size)
writer.add_clip(clip)
writer.write()
5

Clean up

Close the clip to release resources:
clip.close()

Complete Example

Here’s the complete code:
from movielite import VideoClip, VideoWriter, vfx

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

# Apply effects
clip.add_effect(vfx.FadeIn(duration=1.0))
clip.add_effect(vfx.FadeOut(duration=1.5))

# Render
writer = VideoWriter("output.mp4", fps=clip.fps, size=clip.size)
writer.add_clip(clip)
writer.write()

# Clean up
clip.close()
The writer.write() method will display a progress bar showing rendering progress.

Common Operations

Extract a Subclip

Extract a specific segment from a video:
from movielite import VideoClip, VideoWriter

clip = VideoClip("input.mp4")
segment = clip.subclip(5, 15)  # Extract seconds 5-15

writer = VideoWriter("output_subclip.mp4", fps=clip.fps, size=clip.size)
writer.add_clip(segment)
writer.write()

clip.close()

Resize Video

Resize a video to specific dimensions:
from movielite import VideoClip, VideoWriter

clip = VideoClip("input.mp4")
clip.set_size(width=1280, height=720)  # Resize to 720p

writer = VideoWriter("output_720p.mp4", fps=clip.fps, size=(1280, 720))
writer.add_clip(clip)
writer.write()

clip.close()

Concatenate Videos

Join multiple videos sequentially:
from movielite import VideoClip, VideoWriter

clip1 = VideoClip("intro.mp4", start=0)
clip2 = VideoClip("main.mp4", start=clip1.duration)
clip3 = VideoClip("outro.mp4", start=clip1.duration + clip2.duration)

total_duration = clip1.duration + clip2.duration + clip3.duration

writer = VideoWriter(
    "final.mp4",
    fps=clip1.fps,
    size=clip1.size,
    duration=total_duration
)
writer.add_clips([clip1, clip2, clip3])
writer.write()

clip1.close()
clip2.close()
clip3.close()

Adding Text Overlays

Create professional text overlays using the pictex library:
1

Import required modules

from movielite import VideoClip, TextClip, VideoWriter, vfx
from pictex import Canvas, LinearGradient, Shadow
2

Create styled text

Create a canvas with custom styling:
canvas = (
    Canvas()
    .font_family("Arial")
    .font_size(80)
    .color("white")
    .padding(30)
    .background_color(LinearGradient(["#FF6B6B", "#4ECDC4"]))
    .border_radius(15)
    .text_shadows(Shadow(offset=(3, 3), blur_radius=5, color="black"))
)
3

Create text clip

video = VideoClip("background.mp4")
text = TextClip("Hello World", start=2, duration=3, canvas=canvas)
text.set_position((video.size[0] // 2 - text.size[0] // 2, 100))
text.add_effect(vfx.FadeIn(0.5))
text.add_effect(vfx.FadeOut(0.5))
4

Render with overlay

writer = VideoWriter("output.mp4", fps=video.fps, size=video.size)
writer.add_clip(video)
writer.add_clip(text)
writer.write()

video.close()

Complete Text Overlay Example

from movielite import VideoClip, TextClip, VideoWriter, vfx
from pictex import Canvas, LinearGradient, Shadow

# Create styled text canvas
canvas = (
    Canvas()
    .font_family("Arial")
    .font_size(80)
    .color("white")
    .padding(30)
    .background_color(LinearGradient(["#FF6B6B", "#4ECDC4"]))
    .border_radius(15)
    .text_shadows(Shadow(offset=(3, 3), blur_radius=5, color="black"))
)

video = VideoClip("background.mp4")
text = TextClip("Hello World", start=2, duration=3, canvas=canvas)
text.set_position((video.size[0] // 2 - text.size[0] // 2, 100))
text.add_effect(vfx.FadeIn(0.5))
text.add_effect(vfx.FadeOut(0.5))

writer = VideoWriter("output.mp4", fps=video.fps, size=video.size)
writer.add_clip(video)
writer.add_clip(text)
writer.write()

video.close()

Applying Visual Effects

MovieLite includes a comprehensive library of visual effects:

Fade Effects

from movielite import VideoClip, VideoWriter, vfx

clip = VideoClip("input.mp4")
clip.add_effect(vfx.FadeIn(duration=2.0))
clip.add_effect(vfx.FadeOut(duration=1.5))

writer = VideoWriter("output_fade.mp4", fps=clip.fps, size=clip.size)
writer.add_clip(clip)
writer.write()

clip.close()

Color Adjustments

from movielite import VideoClip, VideoWriter, vfx

clip = VideoClip("input.mp4")
clip.add_effect(vfx.Saturation(factor=1.5))  # Increase saturation
clip.add_effect(vfx.Brightness(factor=1.3))  # Increase brightness
clip.add_effect(vfx.Contrast(factor=1.4))    # Increase contrast

writer = VideoWriter("output_enhanced.mp4", fps=clip.fps, size=clip.size)
writer.add_clip(clip)
writer.write()

clip.close()

Zoom Effects

from movielite import VideoClip, VideoWriter, vfx

clip = VideoClip("input.mp4")
clip.add_effect(vfx.ZoomIn(duration=5.0, from_scale=0.5, to_scale=1.0))

writer = VideoWriter("output_zoom.mp4", fps=clip.fps, size=clip.size)
writer.add_clip(clip)
writer.write()

clip.close()

Blur Effects

from movielite import VideoClip, VideoWriter, vfx

clip = VideoClip("input.mp4")
clip.add_effect(vfx.Blur(intensity=7.0))  # Static blur

writer = VideoWriter("output_blur.mp4", fps=clip.fps, size=clip.size)
writer.add_clip(clip)
writer.write()

clip.close()

Combining Multiple Effects

from movielite import VideoClip, VideoWriter, vfx

clip = VideoClip("input.mp4")

# Apply multiple effects in sequence
clip.add_effect(vfx.FadeIn(1.0))
clip.add_effect(vfx.Saturation(1.3))
clip.add_effect(vfx.Contrast(1.2))
clip.add_effect(vfx.Vignette(intensity=0.4, radius=0.8))
clip.add_effect(vfx.FadeOut(1.5))

writer = VideoWriter("output_combined.mp4", fps=clip.fps, size=clip.size)
writer.add_clip(clip)
writer.write()

clip.close()

Working with Transitions

Create smooth transitions between clips:
from movielite import VideoClip, VideoWriter, vtx

# Clips must overlap for transition
clip1 = VideoClip("scene1.mp4", start=0, duration=5)
clip2 = VideoClip("scene2.mp4", start=4.5, duration=5)  # 0.5s overlap

# Apply crossfade during overlap
clip1.add_transition(clip2, vtx.CrossFade(duration=0.5))

total_duration = clip1.duration + clip2.duration - 0.5  # Account for overlap

writer = VideoWriter("output_crossfade.mp4", fps=30, size=clip1.size, duration=total_duration)
writer.add_clips([clip1, clip2])
writer.write()

clip1.close()
clip2.close()
For transitions to work, clips must have overlapping time ranges. The transition duration should match the overlap.

Audio Mixing

Mix multiple audio tracks:
from movielite import VideoClip, AudioClip, VideoWriter, afx

video = VideoClip("video.mp4")

# Background music at 50% volume
music = AudioClip("background.mp3", start=0, volume=0.5)
music.add_effect(afx.FadeIn(2))
music.add_effect(afx.FadeOut(2))

# Sound effect at specific time
sfx = AudioClip("ding.wav", start=5.0, volume=1.0)

writer = VideoWriter("output.mp4", fps=video.fps, size=video.size)
writer.add_clip(video)  # Video includes its own audio track
writer.add_clip(music)
writer.add_clip(sfx)
writer.write()

video.close()

Optimizing Performance

Use Multiprocessing

For faster rendering, use multiple CPU cores:
from movielite import VideoClip, VideoWriter, VideoQuality

clip = VideoClip("input.mp4")

writer = VideoWriter("output.mp4", fps=clip.fps, size=clip.size)
writer.add_clip(clip)

# Use 8 parallel processes for rendering
writer.write(processes=8, video_quality=VideoQuality.HIGH)

clip.close()
The optimal number of processes depends on your CPU cores. Generally, use the number of physical cores minus 1 to leave resources for system operations.

Video Quality Presets

Choose from different quality presets:
from movielite import VideoWriter, VideoQuality

writer = VideoWriter("output.mp4", fps=30, size=(1920, 1080))

# Quality options:
# VideoQuality.LOW      - Faster encoding, lower quality
# VideoQuality.MIDDLE   - Balanced (default)
# VideoQuality.HIGH     - Higher quality, slower encoding
# VideoQuality.VERY_HIGH - Maximum quality, slowest encoding

writer.write(video_quality=VideoQuality.HIGH)

Creating Image Clips

Use static images in your videos:
from movielite import ImageClip, VideoWriter, vfx

# Create a 10-second clip from an image
image = ImageClip("photo.jpg", start=0, duration=10)
image.add_effect(vfx.FadeIn(1.0))
image.add_effect(vfx.FadeOut(1.0))
image.add_effect(vfx.KenBurns(
    start_scale=1.0,
    end_scale=1.3,
    start_position=(0, 0),
    end_position=(-100, -50)
))

writer = VideoWriter("output.mp4", fps=30, size=image.size)
writer.add_clip(image)
writer.write()

Creating a Slideshow

Combine multiple images with transitions:
from movielite import ImageClip, VideoWriter, vtx

# Create image clips
images = [
    ImageClip("photo1.jpg", start=0, duration=3),
    ImageClip("photo2.jpg", start=2.5, duration=3),     # 0.5s overlap
    ImageClip("photo3.jpg", start=5.0, duration=3),     # 0.5s overlap
    ImageClip("photo4.jpg", start=7.5, duration=3),     # 0.5s overlap
]

# Apply crossfade between each
for i in range(len(images) - 1):
    images[i].add_transition(images[i + 1], vtx.CrossFade(duration=0.5))

total_duration = 9.5  # 3 + 3 + 3 + 3 - 0.5 - 0.5 - 0.5

writer = VideoWriter("slideshow.mp4", fps=30, size=images[0].size, duration=total_duration)
writer.add_clips(images)
writer.write()

Custom Frame Transformations

Apply custom pixel-level transformations:
import cv2
import numpy as np
from movielite import VideoClip, VideoWriter

clip = VideoClip("video.mp4")

# Apply custom sepia effect
def sepia_transform(frame: np.ndarray, t: float) -> np.ndarray:
    kernel = np.array([
        [0.131, 0.534, 0.272],
        [0.168, 0.686, 0.349],
        [0.189, 0.769, 0.393]
    ])
    sepia = cv2.transform(frame, kernel)
    return np.clip(sepia, 0, 255).astype(np.uint8)

clip.add_transform(sepia_transform)

writer = VideoWriter("output_sepia.mp4", fps=clip.fps, size=clip.size)
writer.add_clip(clip)
writer.write()

clip.close()
Custom transformations receive each frame as a NumPy array and the current time t in seconds. Return the modified frame.

Next Steps

Now that you’ve learned the basics, explore more advanced features:

API Reference

Detailed documentation of all classes and methods

Examples

More code examples and use cases

Advanced Topics

Custom effects, masking, and performance optimization

GitHub Repository

Source code and issue tracker

Common Patterns

Picture-in-Picture Effect

from movielite import VideoClip, VideoWriter

background = VideoClip("background.mp4", start=0)
small_clip = VideoClip("small.mp4", start=0)

small_clip.set_size(width=320, height=180)
small_clip.set_position((background.size[0] - 340, 20))  # Top-right corner
small_clip.set_opacity(0.9)

writer = VideoWriter("pip_output.mp4", fps=background.fps, size=background.size)
writer.add_clips([background, small_clip])
writer.write()

background.close()
small_clip.close()

Lower Third

from movielite import VideoClip, ImageClip, TextClip, VideoWriter, vfx
from pictex import Canvas

video = VideoClip("input.mp4")

# Semi-transparent background bar
bar = ImageClip.from_color(
    color=(0, 0, 0, 200),
    size=(video.size[0], 120),
    duration=5
)
bar.set_position((0, video.size[1] - 120))
bar.add_effect(vfx.FadeIn(0.5))
bar.add_effect(vfx.FadeOut(0.5))

# Name text
canvas_name = Canvas().font_size(50).color("white").background_color("transparent")
name = TextClip("John Doe", start=0, duration=5, canvas=canvas_name)
name.set_position((40, video.size[1] - 100))
name.add_effect(vfx.FadeIn(0.5))
name.add_effect(vfx.FadeOut(0.5))

# Title text
canvas_title = Canvas().font_size(30).color("#AAAAAA").background_color("transparent")
job_title = TextClip("Software Engineer", start=0, duration=5, canvas=canvas_title)
job_title.set_position((40, video.size[1] - 50))
job_title.add_effect(vfx.FadeIn(0.5))
job_title.add_effect(vfx.FadeOut(0.5))

writer = VideoWriter("lower_third.mp4", fps=video.fps, size=video.size)
writer.add_clips([video, bar, name, job_title])
writer.write()

video.close()
Always remember to call .close() on video clips when you’re done to release file handles and free memory.

Build docs developers (and LLMs) love