moviepy(1)

MOVIEPY(1) MoviePy MOVIEPY(1)

NAME

moviepy - MoviePy Documentation [image]

Date: Jul 03, 2026 Version: 2.2.1

Useful links: Binary Installers <https://pypi.org/project/moviepy/> | Source Repository <https://github.com/Zulko/moviepy> | Issues & Ideas <https://github.com/Zulko/moviepy> | Q&A Support <https://www.reddit.com/r/moviepy/> |

MoviePy is the Python <https://www.python.org/> reference tool for video editing automation!

It's an open source, MIT-licensed library offering user-friendly video editing and manipulation tools for the Python <https://www.python.org/> programming language. [image: ] [image] Getting started

New to MoviePy? Check out the getting started guides. They contain instructions to install MoviePy as well as introduction concepts and tutorials. To the starting guide <#getting-started> [image: ] [image] User guide

The user guide provides in-depth information on the key concepts of MoviePy with useful background information and explanation. To the user guide <#user-guide> [image: ] [image] API reference

The reference guide contains a detailed description of the MoviePy API. The reference describes how the methods work and which parameters can be used. It assumes that you have an understanding of the key concepts. To the reference guide <#reference-manual> [image: ] [image] Developer guide

Saw a typo in the documentation? Want to improve existing functionalities? The contributing guidelines will guide you through the process of improving MoviePy. To the development guide <#developer-guide>

CONTRIBUTE!

MoviePy is an open source software originally written by Zulko <https://github.com/Zulko/> and released under the MIT licence. It works on Windows, Mac, and Linux.

Getting started with MoviePy

This section explain everything you need to start editing with MoviePy. To go further, have a look at the The MoviePy User Guide <#user-guide> and the Api Reference <#reference-manual>.

Installation

Installation is done with pip. If you don't have pip, take a look at how to install it <https://pip.pypa.io/en/stable/installation/>.

With pip installed, just type this in a terminal:

$ (sudo) pip install moviepy


Installation of Additional Binaries

MoviePy depends on the software ffmpeg <https://www.ffmpeg.org/download.html> for video reading and writing and on ffplay for video previewing.

You don't need to worry about ffmpeg <https://www.ffmpeg.org/download.html>, as it should be automatically downloaded/installed by ImageIO during your first use of MoviePy (it takes a few seconds).

You do need to worry about ffplay if you plan on using video/audio previewing. For these cases, make sure to have ffplay installed (it can usually be found alongside ffmpeg) and ensure it is accessible to Python, or define a custom path (see below).

Define Custom Paths to Binaries

If you want to use a specific version of FFmpeg and FFplay, you can do so using environment variables.

There are a couple of environment variables used by MoviePy that allow you to configure custom paths to the external tools.

To set up any of these variables, the easiest way is to do it in Python before importing objects from MoviePy. For example:

import os
os.environ["FFMPEG_BINARY"] = "/path/to/custom/ffmpeg"
os.environ["FFPLAY_BINARY"] = "/path/to/custom/ffplay"


Alternatively, after installing the optional dependencies, you can create a .env file in your working directory that will be automatically read. For example

FFMPEG_BINARY=/path/to/custom/ffmpeg
FFPLAY_BINARY=/path/to/custom/ffplay


Environment Variables

There are two available environment variables for external binaries:

FFMPEG_BINARY
Normally you can leave it at its default ('ffmpeg-imageio'), in which case imageio will download the correct ffmpeg binary (on first use) and then always use that binary.

The second option is "auto-detect". In this case, ffmpeg will be whatever binary is found on the computer: generally ffmpeg (on Linux/macOS) or ffmpeg.exe (on Windows).

Lastly, you can set it to use a binary at a specific location on your disk by specifying the exact path.

FFPLAY_BINARY
The default is "auto-detect". MoviePy will try to find and use the installed ffplay binary.

You can set it to use a binary at a specific location on your disk. On Windows, this might look like:

os.environ["FFPLAY_BINARY"] = r"C:\Program Files\ffmpeg\ffplay.exe"



Verify if MoviePy Finds Binaries

To test if FFmpeg and FFplay are found by MoviePy, in a Python console, you can run:

from moviepy.config import check
check()


Quick presentation

This section explains when MoviePy can be used and how it works.

Do I need MoviePy?

Here are a few reasons why you may want to edit videos in Python:

  • You have many videos to process or to compose in a complicated way.
  • You want to automate the creation of videos or GIFs on a web server (Django, Flask, etc.)
  • You want to automate tedious tasks, like title insertions tracking objects, cutting scenes, making end credits, subtitles, etc...
  • You want to code your own video effects to do something no existing video editor can.
  • You want to create animations from images generated by another python library (Matplotlib, Mayavi, Gizeh, scikit-images...)

And here are a few uses for which MoviePy is NOT the best solution:

  • You only need to do frame-by-frame video analysis (with face detection or other fancy stuff). This could be done with MoviePy in association with other libraries, but really, just use imageio <https://imageio.github.io/>, OpenCV <http://opencv.org/> or SimpleCV, these are libraries that specialize in these tasks.
  • You only want to convert a video file, or turn a series of image files into a movie. In this case it is better to directly call ffmpeg (or avconv or mencoder...) as it will be faster and more memory-efficient than going through MoviePy.

Advantages and limitations

MoviePy has been developed with the following goals in mind:

  • Simple and intuitive. Basic operations can be done in one line. The code is easy to learn and easy to understand for newcomers.
  • Flexible. You have total control over the frames of the video and audio, and creating your own effects is easy as Py.
  • Portable. The code uses very common software (Numpy and FFmpeg) and can run on (almost) any machine with (almost) any version of Python.

Limitations: - MoviePy cannot stream videos (e.g. reading from a webcam, or rendering a video live on a distant machine). - MoviePy is not really designed for video processing involving many successive frames of a movie (e.g. video stabilization - there is other software better suited for that). - You can also have memory problems if you use many video, audio, and image sources at the same time (>100).

Example code

In a typical MoviePy script, you load video or audio files, modify them, put them together, and write the final result to a new video file. As an example, let us load a video, lower the volume, add a title in the center of the video for the first ten seconds, and write the result in a file:

# Import everything needed to edit video clips
from moviepy import *
# Load file example.mp4 and extract only the subclip from 00:00:10 to 00:00:20
clip = VideoFileClip("long_examples/example2.mp4").subclipped(10, 20)
# Reduce the audio volume to 80% of his original volume
clip = clip.with_volume_scaled(0.8)
# Generate a text clip. You can customize the font, color, etc.
txt_clip = TextClip(

font="example.ttf", text="Big Buck Bunny", font_size=70, color="white" ) # Say that you want it to appear for 10s at the center of the screen txt_clip = txt_clip.with_position("center").with_duration(10) # Overlay the text clip on the first video clip video = CompositeVideoClip([clip, txt_clip]) # Write the result to a file (many options available!) video.write_videofile("result.mp4")


How MoviePy works

MoviePy uses the software ffmpeg to read and to export video and audio files. It also (optionally) uses ffplay to allow for video previewing.

Internally, the representation and manipulation of the different media is done using Python's fast numerical library Numpy. Advanced effects and enhancements also use pillow library. [image]

The central concept, the clips

The central object of MoviePy is the the Clip <#moviepy.Clip.Clip>, with either AudioClip <#moviepy.audio.AudioClip.AudioClip> for any audio element, or VideoClip <#moviepy.video.VideoClip.VideoClip> for any visual element. Clips really are the base unit of MoviePy, everything you do is with and on them.

Clips can be created from more than just videos or audios though. They can also be created from an image, a text, a custom animation, a folder of images, and even a simple lambda function!

To create your final video, what you will do is essentially:

1.
Load different resources as clips (see Loading Resources as Clips <#loading>)
2.
Modify them (see Modifying clips and apply effects <#modifying>)
3.
Mixing them into one final clip (see Compositing Multiple Clips <#compositing>)
4.
Render them into a file (see Previewing and Saving Video Clips <#rendering>)

Of course, MoviePy offer multiple handy solution and tools to facilitate all these steps, and lets you add new ones by writing your own effects (see Creating Your Own Effects <#create-effects>)!

MoviePy in 10 Minutes: Creating a Trailer from "Big Buck Bunny"

Note:

This tutorial aims to be a simple and short introduction for new users wishing to use MoviePy. For a more in-depth exploration of the concepts seen in this tutorial, see The MoviePy User Guide <#user-guide>.


In this tutorial, you will learn the basics of how to use the MoviePy library in just 10 minutes. As an example project for this tutorial, we will create the following trailer for the movie "Big Buck Bunny." <https://peach.blender.org/>

Prerequisites

Before we start, make sure you have MoviePy installed. You can install it using pip:

pip install moviepy


Additionally, we will need to gather a few resources such as the original movie, font files, images, etc. To make it easy, we have prepared a template project you can download directly:

1.
Download the project template and unzip it.
2.
Take a look at the resources inside the folder to familiarize yourself.
3.
Create a Python script file named trailer.py in the project directory.

Now, you are ready to proceed to the next steps.

Step 1: Import MoviePy and Load the Video

Let's start by importing the necessary modules and loading the "Big Buck Bunny" video into our Python program:

# Lets import moviepy, lets also import numpy we will use it a some point
import numpy as np
from moviepy import *
#################
# VIDEO LOADING #
#################
# We load our video


As you can see, loading a video file is really easy, but MoviePy isn't limited to video. It can handle images, audio, text, and even custom animations.

No matter the kind of resources, ultimately any clip will be either a VideoClip <#moviepy.video.VideoClip.VideoClip> for any visual element, and an AudioClip <#moviepy.audio.AudioClip.AudioClip> for any audio element.

In this tutorial, we will only see a few of those, but if you want to explore more, you can find an exhaustive list in the user guide about Loading Resources as Clips <#loading>.

Step 2: Extract the Best Scenes

To create our trailer, we will focus on presenting the main characters, so we need to extract parts of the movie. This is a very classic task, so let's turn our main clip into multiple subclips:

#####################
# SCENES EXTRACTION #
#####################
# We extract the scenes we want to use
# First the characters
intro_clip = video.subclipped(1, 11)
bird_clip = video.subclipped(16, 20)
bunny_clip = video.subclipped(37, 55)
rodents_clip = video.subclipped(

"00:03:34.75", "00:03:56" ) # we can also use string notation with format HH:MM:SS.uS


Here, we use the subclip method to extract specific scenes from the main video. We provide the start and end times (in seconds or as text with the format HH:MM:SS.µS) for each scene. The extracted clips are stored in their respective variables (intro_clip, bird_clip, etc.).

Step 3: Take a First Look with Preview

When editing videos, it's often essential to preview the clips to ensure they meet our vision. This allows you to watch the segment you're working on and make any necessary adjustments for the perfect result.

To do so using MoviePy, you can utilize the preview() function available for each clip (the complementary audio_preview() is also available for AudioClip <#moviepy.audio.AudioClip.AudioClip>).

Note:

Note that you will need ffplay installed and accessible to MoviePy for preview to work. You can check if ffplay is available by running the command python3 -c "from moviepy.config import check; check()". If not, please see install#binaries.


#####################
# SCENES PREVIEWING #
#####################
# Now, lets have a first look at our clips
# Warning: you need ffplay installed for preview to work
# We set a low fps so our machine can render in real time without slowing down
intro_clip.preview(fps=20)
bird_clip.preview(fps=20)
bunny_clip.preview(fps=20)
rodents_clip.preview(fps=20)


By using the preview, you may have noticed that our clips not only contain video but also audio. This is because when loading a video, you not only load the image but also the audio tracks that are turned into AudioClip <#moviepy.audio.AudioClip.AudioClip> and added to your video clip.

Note:

When previewing, you may encounter video slowing or video/audio shifting. This is not a bug; it's due to the fact that your computer cannot render the preview in real-time. In such a case, the best course of action is to set the fps parameter for the preview() at a lower value to make things easier on your machine.


Step 4: Modify a Clip by Cutting Out a Part of It

After previewing the clips, we notice that the rodents' scene is a bit long. Let's modify the clip by removing a specific part. It would be nice to remove parts of the scene that we don't need. This is also quite a common task in video editing. To do so, we are going to use the with_effects method to remove a portion of the clip between 00:06:00 to 00:10:00.

##############################
# CLIPS MODIFICATION CUTTING #
##############################
# Well, looking at the rodent scene it is a bit long isn't?
# Let's see how we modify the clip with one of the many clip manipulation method starting by with_*
# in that case by removing of the clip the part between 00:06:00 to 00:10:00 of the clip, using with_section_cut_out
rodents_clip = rodents_clip.with_section_cut_out(start_time=4, end_time=10)
# Note: You may have noticed that we have reassign rodents_clip, this is because all with_* methods return a modified *copy* of the
# original clip instead of modifying it directly. In MoviePy any function starting by with_* is out-place instead of in-place
# meaning it does not modify the original data, but instead copy it and modify/return the copy
# Lets check the result


In that particular case, we have used the with_effects, but this is only one of the many clip manipulation methods starting with with_. We will see a few others in this tutorial, but we will miss a lot more. If you want an exhaustive list, go see Api Reference <#reference-manual>.

Note:

You may have noticed that we have reassigned the rodents_clip variable instead of just calling a method on it. This is because in MoviePy, any function starting with with_ is out-of-place instead of in-place, meaning it does not modify the original data but instead copies it and modifies/returns the copy. So you need to store the result of the method and, if necessary, reassign the original variable to update your clip.


Step 5: Creating Text/Logo Clips

In addition to videos, we often need to work with images and texts. MoviePy offers some specialized kinds of VideoClip <#moviepy.video.VideoClip.VideoClip> specifically for that purpose: ImageClip and TextClip.

In our case, we want to create text clips to add text overlays between the video clips. We'll define the font, text content, font size, and color for each text clip. We also want to create image clips for the "Big Buck Bunny" logo and the "Made with MoviePy" logo and resize them as needed.

############################
# TEXT/LOGO CLIPS CREATION #
############################
# Lets create the texts to put between our clips
font = "./resources/font/font.ttf"
intro_text = TextClip(

font=font,
text="The Blender Foundation and\nPeach Project presents",
font_size=50,
color="#fff",
text_align="center", ) bird_text = TextClip(font=font, text="An unlucky bird", font_size=50, color="#fff") bunny_text = TextClip(
font=font, text="A (slightly overweight) bunny", font_size=50, color="#fff" ) rodents_text = TextClip(
font=font, text="And three rodent pests", font_size=50, color="#fff" ) revenge_text = TextClip(
font=font, text="Revenge is coming...", font_size=50, color="#fff" ) made_with_text = TextClip(font=font, text="Made with", font_size=50, color="#fff") # We will also need the big buck bunny logo, so lets load it and resize it logo_clip = ImageClip("./resources/logo_bbb.png").resized(width=400)


As you can see, ImageClip is quite simple, but TextClip is a rather complicated object. Don't hesitate to explore the arguments it accepts.

Note:

In our example, we have used the resize method to resize our image clips. This method works just like any with_* method, but because resizing is such a common task, the name has been shortened to resize. The same is true for crop and rotate.


Feel free to experiment with different effects and transitions to achieve the desired trailer effect.

Step 6: Timing the Clips

We have all the clips we need, but if we were to combine all the clips into a single one using composition (we will see that in the next step), all our clips would start at the same time and play on top of each other, which is obviously not what we want. Also, some video clips, like images and texts, have no endpoint/duration at creation (unless you have provided a duration parameter), which means trying to render them will throw an error as it would result in an infinite video.

To fix that, we need to specify when a clip should start and stop in the final clip. So, let's start by indicating when each clip must start and end using the appropriate with_* methods.

################
# CLIPS TIMING #
################
# We have all the clips we need, but if we was to turn all the clips into a single one with composition (we will see that during next step)
# all our clips would start at the same time and play on top of each other, which is obviously not what we want.
# To fix that, we need to say when a clip should start and stop in the final clip.
# So, lets start by telling when each clip must start and end with appropriate with_* methods
intro_text = intro_text.with_duration(6).with_start(

3 ) # Intro for 6 seconds, start after 3 seconds logo_clip = logo_clip.with_start(intro_text.start + 2).with_end(
intro_text.end ) # Logo start 2 second after intro text and stop with it bird_clip = bird_clip.with_start(
intro_clip.end ) # Make bird clip start after intro, duration already known bird_text = bird_text.with_start(bird_clip.start).with_end(
bird_clip.end ) # Make text synchro with clip bunny_clip = bunny_clip.with_start(bird_clip.end) # Make bunny clip follow bird clip bunny_text = bunny_text.with_start(bunny_clip.start + 2).with_duration(7) rodents_clip = rodents_clip.with_start(bunny_clip.end) rodents_text = rodents_text.with_start(rodents_clip.start).with_duration(4) rambo_clip = rambo_clip.with_start(rodents_clip.end - 1.5) revenge_text = revenge_text.with_start(rambo_clip.start + 1.5).with_duration(4) made_with_text = made_with_text.with_start(rambo_clip.end).with_duration(3)


Note:

By default, all clips have a start point at 0. If a clip has no duration but you set the end_time, then the duration will be calculated for you. The reciprocity is also true.

So in our case, we either use duration or end_time, depending on what is more practical for each specific case.



Step 7: Seeing How All Clips Combine

Now that all our clips are timed, let's get a first idea of how our final clip will look. In video editing, the act of assembling multiple videos into a single one is known as composition. So, MoviePy offers a special kind of VideoClip <#moviepy.video.VideoClip.VideoClip> dedicated to the act of combining multiple clips into one, the CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip>.

CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip> takes an array of clips as input and will play them on top of each other at render time, starting and stopping each clip at its start and end points.

Note:

If possible, CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip> will extract endpoint and size from the biggest/last ending clip. If a clip in the list has no duration, then you will have to manually set the duration of CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip> before rendering.


########################
# CLIPS TIMING PREVIEW #
########################
# Lets make a first compositing of the clips into one single clip and do a quick preview to see if everything is synchro
quick_compo = CompositeVideoClip(

[
intro_clip,
intro_text,
logo_clip,
bird_clip,
bird_text,
bunny_clip,
bunny_text,
rodents_clip,
rodents_text,
rambo_clip,
revenge_text,
made_with_text,
moviepy_clip,
] )


Step 8: Positioning Our Clips

By looking at this first preview, we see that our clips are pretty well timed, but that the positions of our texts and logo are not satisfying.

This is because, for now, we have only specified when our clips should appear, and not the position at which they should appear. By default, all clips are positioned from the top left of the video, at (0, 0).

All our clips do not have the same sizes (the texts and images are smaller than the videos), and the CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip> takes the size of the biggest clip (so in our case, the size of the videos), so the texts and images are all in the top left portion of the clip.

To fix this, we simply have to define the position of our clips in the composition with the method with_position.

######################
# CLIPS POSITIONNING #
######################
# Now that we have set the timing of our different clips, we need to make sure they are in the right position
# We will keep things simple, and almost always set center center for every texts
bird_text = bird_text.with_position(("center", "center"))
bunny_text = bunny_text.with_position(("center", "center"))
rodents_text = rodents_text.with_position(("center", "center"))
revenge_text = revenge_text.with_position(("center", "center"))
# For the logos and intro/end, we will use pixel position instead of center
top = intro_clip.h // 2
intro_text = intro_text.with_position(("center", 200))
logo_clip = logo_clip.with_position(("center", top))
made_with_text = made_with_text.with_position(("center", 300))
moviepy_clip = moviepy_clip.with_position(("center", 360))
# Lets take another look to check positions
quick_compo = CompositeVideoClip(

[
intro_clip,
intro_text,
logo_clip,
bird_clip,
bird_text,
bunny_clip,
bunny_text,
rodents_clip,
rodents_text,
rambo_clip,
revenge_text,
made_with_text,
moviepy_clip,
] )


Note:

The position is a tuple with horizontal and vertical position. You can give them as pixels, as strings (top, left, right, bottom, center), and even as a percentage by providing a float and passing the argument relative=True.


Now, all our clips are in the right place and timed as expected.

Step 9: Adding Transitions and Effects

So, our clips are timed and placed, but for now, the result is quite raw. It would be nice to have smoother transitions between the clips. In MoviePy, this is achieved through the use of effects.

Effects play a crucial role in enhancing the visual and auditory appeal of your video clips. Effects are applied to clips to create transitions, transformations, or modifications, resulting in better-looking videos. Whether you want to add smooth transitions between clips, alter visual appearance, or manipulate audio properties, MoviePy comes with many existing effects to help you bring your creative vision to life with ease.

You can find these effects under the namespace vfx for video effects and afx for audio effects.

Note:

You can use audio effects on both audio and video clips because when applying audio effects to a video clip, the effect will actually be applied to the video clip's embedded audio clip instead.


Using an effect is very simple. You just have to call the method with_effects on your clip and pass an array of effect objects to apply.

In our case, we will add simple fade-in/out and cross-fade-in/out transitions between our clips, as well as slow down the rambo_clip.

################################
# CLIPS TRANSITION AND EFFECTS #
################################
# Now that our clip are timed and positionned, lets add some transition to make it more natural
# To do so we use the with_effects method and the video effects in vfx
# We call with_effects on our clip and pass it an array of effect objects to apply
# We'll keep it simple, nothing fancy just cross fading
intro_text = intro_text.with_effects([vfx.CrossFadeIn(1), vfx.CrossFadeOut(1)])
logo_clip = logo_clip.with_effects([vfx.CrossFadeIn(1), vfx.CrossFadeOut(1)])
bird_text = bird_text.with_effects([vfx.CrossFadeIn(0.5), vfx.CrossFadeOut(0.5)])
bunny_text = bunny_text.with_effects([vfx.CrossFadeIn(0.5), vfx.CrossFadeOut(0.5)])
rodents_text = rodents_text.with_effects([vfx.CrossFadeIn(0.5), vfx.CrossFadeOut(0.5)])
# Also add cross fading on video clips and video clips audio
# See how video effects are under vfx and audio ones under afx
intro_clip = intro_clip.with_effects(

[vfx.FadeIn(1), vfx.FadeOut(1), afx.AudioFadeIn(1), afx.AudioFadeOut(1)] ) bird_clip = bird_clip.with_effects(
[vfx.FadeIn(1), vfx.FadeOut(1), afx.AudioFadeIn(1), afx.AudioFadeOut(1)] ) bunny_clip = bunny_clip.with_effects(
[vfx.FadeIn(1), vfx.FadeOut(1), afx.AudioFadeIn(1), afx.AudioFadeOut(1)] ) rodents_clip = rodents_clip.with_effects(
[
vfx.FadeIn(1),
vfx.CrossFadeOut(1.5),
afx.AudioFadeIn(1),
afx.AudioFadeOut(1.5),
] ) # Just fade in, rambo clip will do the cross fade rambo_clip = rambo_clip.with_effects(
[
vfx.CrossFadeIn(1.5),
vfx.FadeOut(1),
afx.AudioFadeIn(1.5),
afx.AudioFadeOut(1),
] ) rambo_clip = rambo_clip.with_effects(
[
vfx.CrossFadeIn(1.5),
vfx.FadeOut(1),
afx.AudioFadeIn(1.5),
afx.AudioFadeOut(1),
] ) # Effects are not only for transition, they can also change a clip timing or appearance # To show that, lets also modify the Rambo-like part of our clip to be in slow motion # PS: We do it for effect, but this is one of the few effects that have a direct shortcut, with_speed_scaled # the others are with_volume_scaled, resized, cropped and rotated rambo_clip = rambo_clip.with_effects([vfx.MultiplySpeed(0.5)]) # Because we modified timing of rambo_clip with our MultiplySpeed effect, we must re-assign the following clips timing made_with_text = made_with_text.with_start(rambo_clip.end).with_duration(3) moviepy_clip = moviepy_clip.with_start(made_with_text.start).with_duration(3) # Let's have a last look at the result to make sure everything is working as expected quick_comp = CompositeVideoClip(
[


Well, this looks a lot nicer! For this tutorial, we want to keep things simple, so we mostly used transitions. However, you can find many different effects and even create your own. For a more in-depth presentation, see moviepy.video.fx <#module-moviepy.video.fx>, moviepy.audio.fx <#module-moviepy.audio.fx>, and Creating Your Own Effects <#create-effects>.

Note:

Looking at the result, you may notice that cross-fading makes clips go from transparent to opaque, and reciprocally, and wonder how it works.

We won't get into details, but know that in MoviePy, you can declare some sections of a video clip to be transparent by using masks. Masks are nothing more than special kinds of video clips that are made of values ranging from 0 for a transparent pixel to 1 for a fully opaque one.

For more info, see Mask Clips <#loading-masks>.



Step 10: Modifying the Appearance of a Clip Using Filters

Finally, to make it more epic, we will apply a custom filter to our Rambo clip to make the image sepia. MoviePy does not come with a sepia effect out of the box, and creating a full custom effect is beyond the scope of this tutorial. However, we will see how we can apply a simple filter to our clip using the image_transform() <#moviepy.video.VideoClip.VideoClip.image_transform> method.

To understand how filters work, you first need to understand that in MoviePy, a clip frame is nothing more than a numpy ndarray of shape HxWx3. This means we can modify how a frame looks like by applying simple math operations. Doing that on all the frames allows us to apply a filter to our clip!

The "apply to all frames" part is done by the image_transform method. This method takes a callback function as an argument, and at render time, it will trigger the callback for each frame of the clip, passing the current frame.

Warning:

This is a bit of an advanced usage, and the example involves matrix multiplication. If this is too much for you, you can simply ignore it until you really need to make custom filters, then go look for a more detailed explanation on how to do filtering (Modify a clip appearance and timing using filters <#modifying-filters>) and create custom effects (Creating Your Own Effects <#create-effects>) in the user guide.

What you need to remember is just that we can apply filters on images. Here we do it mathematically, but you could very well use a library such as Pillow (provided it can understand numpy images) to do the maths for you!




logo_clip,
bird_clip,
bird_text,
bunny_clip,
bunny_text,
rodents_clip,
rodents_text,
rambo_clip,
revenge_text,
made_with_text,
moviepy_clip,
] ) quick_comp.preview(fps=10) ############### # CLIP FILTER # ############### # Lets finish by modifying our rambo clip to make it sepia # We will start by defining a function that turn a numpy image into sepia # It takes the image as numpy array in entry and return the modified image as output def sepia_filter(frame: np.ndarray):
# Sepia filter transformation matrix
# Sepia transform works by applying to each pixel of the image the following rules
# res_R = (R * .393) + (G *.769) + (B * .189)
# res_G = (R * .349) + (G *.686) + (B * .168)
# res_B = (R * .272) + (G *.534) + (B * .131)
#
# With numpy we can do that very efficiently by multiplying the image matrix by a transformation matrix
sepia_matrix = np.array(
[[0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131]]
)
# Convert the image to float32 format for matrix multiplication
frame = frame.astype(np.float32)
# Apply the sepia transformation
# .T is needed because multiplying matrix of shape (n,m) * (m,k) result in a matrix of shape (n,k)
# what we want is (n,m), so we must transpose matrix (m,k) to (k,m)


Step 11: Rendering the Final Clip to a File

So, our final clip is ready, and we have made all the cutting and modifications we want. We are now ready to save the final result into a file. In video editing, this operation is known as rendering.

Again, we will keep things simple and just do video rendering without much tweaking. In most cases, MoviePy and FFmpeg will automatically find the best settings. Take a look at write_videofile() <#moviepy.video.VideoClip.VideoClip.write_videofile> for more info.


# Because final result can be > 255, we limit the result to range [0, 255]
sepia_image = np.clip(sepia_image, 0, 255)
# Convert the image back to uint8 format, because we need integer not float
sepia_image = sepia_image.astype(np.uint8)
return sepia_image # Now, we simply apply the filter to our clip by calling image_transform, which will call our filter on every frame rambo_clip = rambo_clip.image_transform(sepia_filter) # Let's see how our filter look rambo_clip.preview(fps=10) ################## # CLIP RENDERING # ################## # Everything is good and ready, we can finally render our clip into a file final_clip = CompositeVideoClip(
[


Conclusion

Congratulations! You have successfully created a trailer for the movie "Big Buck Bunny" using the MoviePy library. This tutorial covered the basics of MoviePy, including loading videos, trimming scenes, adding effects and transitions, overlaying text, and even a little bit of filtering.

If you want to dig deeper into MoviePy, we encourage you to try and experiment with this base example by using different effects, transitions, and audio elements to make your trailer truly captivating. We also encourage you to go and read the The MoviePy User Guide <#user-guide>, as well as looking directly at the Api Reference <#reference-manual>.

MoviePy Docker

Prerequisites

Docker installed: Docker Engine for Linux <https://docs.docker.com/engine/install/> or Docker Desktop for Windows/Mac/Linux <https://docs.docker.com/desktop/>.

Build the docker

1.
Move into the moviepy root dir
2.
Build the Dockerfile

docker build -t moviepy -f Dockerfile .



How to run the unittests from docker

Run pytest inside the container with the following command

docker run -w /moviepy -it moviepy python -m pytest


Running your own moviepy script from docker

Change directory to where your script is located

If moviepy docker container is already running, you can connect by:

docker exec -it moviepy python myscript.py


If the container isn't running already

docker run -it moviepy bash
python myscript.py


You can also start a container and run a script in one command:

docker run -it -v `pwd`:/code moviepy python myscript.py


Updating from v1.X to v2.X

MoviePy v2.0 has undergone some large changes with the aim of making the API more consistent and intuitive. As a result, multiple breaking changes have been made. Therefore, there is a high likelihood that your pre-v2.0 programs will not run without some changes.

Dropping support for Python 2

Starting with version 2.0, MoviePy no longer supports Python 2, since Python 2 reached its end of life in 2020. Focusing on Python 3.7+ allows MoviePy to take advantage of the latest language features and improvements while maintaining code quality and security.

Users are encouraged to upgrade to a supported version of Python to continue using MoviePy.

Suppression of moviepy.editor and simplified importation

Before v2.0, it was advised to import from moviepy.editor whenever you needed to perform some manual operations, such as previewing or hand editing, because the editor package handled a lot of magic and initialization, making your life easier, at the cost of initializing some complex modules like pygame.

With version 2.0, the moviepy.editor namespace no longer exists. Instead, you should import everything from moviepy like this:

from moviepy import *  # Simple and clean; the __all__ is set in moviepy, so only useful things will be loaded
from moviepy import VideoFileClip  # You can also import only the things you really need


Renaming and API unification

One of the most significant changes is the renaming of all .set_ methods to .with_. More generally, almost all methods that modify a clip now start with with_, indicating that they work 'out-of-place', meaning they do not directly modify the clip, but instead copy it, modify the copy, and return the updated copy, leaving the original clip untouched.

We advise you to check your code for any calls to methods from Clip objects and verify if there is a matching .with_ equivalent.

Massive refactoring of effects

With version 2.0, effects have undergone significant changes and refactoring. Although the logic of when and why to apply effects remains largely the same, the implementation has changed considerably.

If you used any kind of effects, you will need to update your code!

Moving effects from functions to classes

MoviePy version 2.0 introduces a more structured and object-oriented approach to handling effects. Previously, effects were simple Python functions that manipulated video clips or images. However, in version 2.0 and onwards, effects are now represented as classes.

This shift allows for better organization, encapsulation, and reusability of code, as well as more comprehensible code. Each effect is now encapsulated within its own class, making it easier to manage and modify.

All effects now implement the Effect <#moviepy.Effect.Effect> abstract class, so if you ever wrote a custom effect.

If you ever wrote your own effect, you will have to migrate to the new object-based implementation. For more information, see Creating Your Own Effects <#create-effects>.

Moving from clip.fx to with_effects() <#moviepy.Clip.Clip.with_effects>

The move from functions to objects also meant that MoviePy dropped the method Clip.fx previously used to apply effects in favor of the new with_effects() <#moviepy.Clip.Clip.with_effects>.

For more information on how to use effects with v2.0, see Modify a clip using effects <#modifying-effects>.

Removing effects as clip methods

Before version 2.0, when importing from moviepy.editor, effects were added as clip class methods at runtime. This is no longer the case.

If you previously used effects by calling them as clip methods, you must now use with_effects() <#moviepy.Clip.Clip.with_effects>.

Dropping many external dependencies and unifying the environment

With v1.0, MoviePy relied on many optional external dependencies, attempting to gracefully fall back from one library to another in the event one of them was missing, eventually dropping some features when no library was available. This resulted in complex and hard-to-maintain code for the MoviePy team, as well as fragmented and hard-to-understand environments for users.

With v2.0, the MoviePy team aimed to offer a simpler, smaller, and more unified dependency list, focusing on Pillow for all complex image manipulation, and dropping altogether the usage of ImageMagick, PyGame, OpenCV, scipy, scikit, and a few others.

Removed features

Unfortunately, reducing the scope of MoviePy and limiting external libraries means that some features had to be removed. If you used any of the following features, you will have to create your own replacements:

  • moviepy.video.tools.tracking
  • moviepy.video.tools.segmenting
  • moviepy.video.io.sliders

Miscellaneous signature changes

When updating the API and moving from previous libraries to Pillow, some miscellaneous changes also occurred, meaning some method signatures may have changed.

You should check the new signatures if you used any of the following:

  • TextClip: Some argument names have changed, and a path to a font file is now needed at object instantiation.
  • clip.resize is now clip.resized.
  • clip.crop is now clip.cropped.
  • clip.rotate is now clip.rotated.
  • Any previous Clip method not starting with with_ now probably starts with it.

Why all these changes and updating from v1.0 to v2.0?

You might wonder why all these changes were introduced. The answer is: time.

MoviePy has seen many evolutions since its first release and has become a complex project, with ambitions sometimes too large in relation to the available manpower on the development team. Over time, as in any project, inconsistencies were introduced to support new functionalities without breaking the current API, and some initial choices no longer reflected the current state of things.

Due to multiple factors, MoviePy underwent a long period during which the main version distributed through PyPi diverged from the GitHub distributed version, causing confusion and chaos.

In an effort to simplify future development and limit confusion by providing a unified environment, it was decided to release a new major version including the many evolutions that happened over the years, which meant breaking changes, and thus a new major version was required.

For anyone interested in how and why all of these decisions were made, you can find much of the discussion in GitHub issues #1874 <https://github.com/Zulko/moviepy/issues/1874>, #1089 <https://github.com/Zulko/moviepy/issues/1089> and #2012 <https://github.com/Zulko/moviepy/issues/2012>.

FAQ and troubleshooting

This section intend to answer the most common questions and errors.

Common errors that are not bugs

These are very common errors which are not considered as bugs to be solved (but you can still ask for this to change). If these answers don't work for you, please open a bug report on Github <https://github.com/Zulko/moviepy>, or on the dedicated Subreddit <https://www.reddit.com/r/moviepy/>.

MoviePy generated a video that cannot be read by my favorite player.

Known reason: one of the video's dimensions were not even, for instance 720x405, and you used a MPEG4 codec like libx264 (default in MoviePy). In this case the video generated uses a format that is readable only on some readers like VLC.

I can't seem to read any video with MoviePy

Known reason: you have a deprecated version of FFmpeg, install a recent version from the website, not from your OS's repositories! (see Installation <#install>).

Previewing videos make them slower than they are

It means that your computer is not good enough to render the clip in real time. Don't hesitate to play with the options of preview: for instance, lower the fps of the sound (11000 Hz is still fine) and the video. Also, downsizing your video with resize can help.

The MoviePy User Guide

The User Guide covers all of MoviePy's main concepts grouped by tasks (loading, editing, composing, rendering), with a presentation of the different concepts/elements relative to the tasks along with short code examples.

It is a good place for users wishing to understand more precisely one of these aspects and to discover the different MoviePy elements relative to it.

For users wanting to have a quick overview of how to use MoviePy, a better place to start is the Getting started with MoviePy <#getting-started> section, and more specifically the MoviePy in 10 Minutes: Creating a Trailer from "Big Buck Bunny" <#moviepy-10-minutes> tutorial.

For a full overview of MoviePy, see the Api Reference <#reference-manual>.

Loading Resources as Clips

The first step for making a video with MoviePy is to load the resources you wish to include in the final video.

In this section, we present the different types of clips and how to load them. For information on modifying a clip, see Modifying clips and apply effects <#modifying>. For how to put clips together, see Compositing Multiple Clips <#compositing>. And for how to see/save them, see Previewing and Saving Video Clips <#rendering> (we will usually save them in examples, but we won't explain here).

There are many different resources you can use with MoviePy, and you will load different resources with different subtypes of Clip <#moviepy.Clip.Clip>, and more precisely of AudioClip <#moviepy.audio.AudioClip.AudioClip> for any audio element, or VideoClip <#moviepy.video.VideoClip.VideoClip> for any visual element.

The following code summarizes the base clips that you can create with MoviePy:

import numpy as np
from moviepy import (

AudioClip,
AudioFileClip,
ColorClip,
ImageClip,
ImageSequenceClip,
TextClip,
VideoClip,
VideoFileClip, ) # Define some constants for later use black = (255, 255, 255) # RGB for black def frame_function(t):
"""Random noise image of 200x100"""
return np.random.randint(low=0, high=255, size=(100, 200, 3)) def frame_function_audio(t):
"""A note by producing a sinewave of 440 Hz"""
return np.sin(440 * 2 * np.pi * t) # Now lets see how to load different type of resources ! # VIDEO CLIPS # for custom animations, where frame_function is a function returning an image # as numpy array for a given time clip = VideoClip(frame_function, duration=5) clip = VideoFileClip("example.mp4") # for videos # for a list or directory of images to be used as a video sequence clip = ImageSequenceClip("example_img_dir", fps=24) clip = ImageClip("example.png") # For a picture # To create the image of a text clip = TextClip(font="./example.ttf", text="Hello!", font_size=70, color="black") # a clip of a single unified color, where color is a RGB tuple/array/list clip = ColorClip(size=(460, 380), color=black) # AUDIO CLIPS # for audio files, but also videos where you only want the keep the audio track clip = AudioFileClip("example.wav") # for custom audio, where frame_function is a function returning a # float (or tuple for stereo) for a given time clip = AudioClip(frame_function_audio, duration=3)


To understand all these clips more thoroughly, read the full documentation for each in the Api Reference <#reference-manual>.

Releasing Resources by Closing a Clip

When you create certain types of clip instances—e.g., VideoFileClip or AudioFileClip—MoviePy creates a subprocess and locks the file. To release these resources when you are finished, you should call the close() method.

This is more important for more complex applications and is particularly important when running on Windows. While Python's garbage collector should eventually clean up the resources for you, closing them makes them available earlier.

However, if you close a clip too early, methods on the clip (and any clips derived from it) become unsafe.

So, the rules of thumb are:

  • Call close() on any clip that you construct once you have finished using it and have also finished using any clip that was derived from it.
  • Even if you close a CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip> instance, you still need to close the clips it was created from.
  • Otherwise, if you have a clip that was created by deriving it from another clip (e.g., by calling with_mask()), then generally you shouldn't close it. Closing the original clip will also close the copy.

Clips act as context managers <https://docs.python.org/3/reference/datamodel.html#context-managers>. This means you can use them with a with statement, and they will automatically be closed at the end of the block, even if there is an exception.

from moviepy import *
# clip.close() is implicitly called, so the lock on my_audiofile.mp3 file
# is immediately released.
try:

with AudioFileClip("example.wav") as clip:
raise Exception("Let's simulate an exception") except Exception as e:
print("{}".format(e))


Categories of Video Clips

Video clips are the building blocks of longer videos. Technically, they are clips with a clip.get_frame(t) method which outputs a HxWx3 numpy array representing the frame of the clip at time t.

There are two main types of video clips:

  • Animated clips (made with VideoFileClip, VideoClip <#moviepy.video.VideoClip.VideoClip>, and ImageSequenceClip <#moviepy.video.io.ImageSequenceClip.ImageSequenceClip>), which will always have duration.
  • Unanimated clips (made with ImageClip <#moviepy.video.VideoClip.ImageClip>, TextClip <#moviepy.video.VideoClip.TextClip>, and ColorClip <#moviepy.video.VideoClip.ColorClip>), which show the same picture for an a-priori infinite duration.

There are also special video clips called masks, which belong to the categories above but output greyscale frames indicating which parts of another clip are visible or not.

A video clip can carry around an audio clip (AudioClip <#moviepy.audio.AudioClip.AudioClip>) in audio <#moviepy.video.VideoClip.VideoClip.audio> which is its soundtrack, and a mask clip in mask <#moviepy.video.VideoClip.VideoClip.mask>.

Animated Clips

These are clips whose image will change over time, and which have a duration and a number of Frames Per Second.

VideoClip

VideoClip <#moviepy.video.VideoClip.VideoClip> is the base class for all other video clips in MoviePy. If all you want is to edit video files, you will never need it. This class is practical when you want to make animations from frames that are generated by another library.

All you need is to define a function frame_function(t) which returns a HxWx3 numpy array (of 8-bits integers) representing the frame at time t.

Here is an example where we will create a pulsating red circle with the graphical library Pillow <https://pypi.org/project/Pillow/>.

import math
import numpy as np
from PIL import Image, ImageDraw
from moviepy import VideoClip
WIDTH, HEIGHT = (128, 128)
RED = (255, 0, 0)
def frame_function(t):

frequency = 1 # One pulse per second
coef = 0.5 * (1 + math.sin(2 * math.pi * frequency * t)) # radius varies over time
radius = WIDTH * coef
x1 = WIDTH / 2 - radius / 2
y1 = HEIGHT / 2 - radius / 2
x2 = WIDTH / 2 + radius / 2
y2 = HEIGHT / 2 + radius / 2
img = Image.new("RGB", (WIDTH, HEIGHT))
draw = ImageDraw.Draw(img)
draw.ellipse((x1, y1, x2, y2), fill=RED)
return np.array(img) # returns a 8-bit RGB array # we define a 2s duration for the clip to be able to render it later clip = VideoClip(frame_function, duration=2) # we must set a framerate because VideoClip have no framerate by default clip.write_gif("circle.gif", fps=15)


Resulting in this: [image: A pulsating red circle on black background.] [image]

Note:

Clips that are made with a frame_function do not have an explicit frame rate nor duration by default, so you must provide duration at clip creation and a frame rate (fps, frames per second) for write_gif() <#moviepy.video.VideoClip.VideoClip.write_gif> and write_videofile() <#moviepy.video.VideoClip.VideoClip.write_videofile>, and more generally for any methods that require iterating through the frames.


For more, see VideoClip <#moviepy.video.VideoClip.VideoClip>.

VideoFileClip

A VideoFileClip <#moviepy.video.io.VideoFileClip.VideoFileClip> is a clip read from a video file (most formats are supported) or a GIF file. This is probably one of the most used objects! You load the video as follows:

from moviepy import VideoFileClip
myclip = VideoFileClip("example.mp4")
# video file clips already have fps and duration
print("Clip duration: {}".format(myclip.duration))
print("Clip fps: {}".format(myclip.fps))
myclip = myclip.subclipped(0.5, 2)  # Cutting the clip between 0.5 and 2 secs.
print("Clip duration: {}".format(myclip.duration))  # Cuting will update duration
print("Clip fps: {}".format(myclip.fps))  # and keep fps
# the output video will be 1.5 sec long and use original fps
myclip.write_videofile("result.mp4")


Note:

These clips will have an fps (frame per second) and duration attributes, which will be transmitted if you do small modifications of the clip, and will be used by default in write_gif() <#moviepy.video.VideoClip.VideoClip.write_gif>, write_videofile() <#moviepy.video.VideoClip.VideoClip.write_videofile>, etc.


For more, see VideoFileClip <#moviepy.video.io.VideoFileClip.VideoFileClip>.

ImageSequenceClip

This ImageSequenceClip <#moviepy.video.io.ImageSequenceClip.ImageSequenceClip> is a clip made from a series of images:

from moviepy import ImageSequenceClip
# A clip with a list of images showed for 1 second each
myclip = ImageSequenceClip(

[
"example_img_dir/image_0001.jpg",
"example_img_dir/image_0002.jpg",
"example_img_dir/image_0003.jpg",
],
durations=[1, 1, 1], ) # 3 images, 1 seconds each, duration = 3 print("Clip duration: {}".format(myclip.duration)) # 3 seconds, 3 images, fps is 3/3 = 1 print("Clip fps: {}".format(myclip.fps)) # This time we will load all images in the dir, and instead of showing theme # for X seconds, we will define FPS myclip2 = ImageSequenceClip("./example_img_dir", fps=30) # fps = 30, so duration = nb images in dir / 30 print("Clip duration: {}".format(myclip2.duration)) print("Clip fps: {}".format(myclip2.fps)) # fps = 30 # the gif will be 30 fps, its duration will depend on the number of # images in dir myclip.write_gif("result.gif") # the gif will be 3 sec and 1 fps myclip2.write_gif("result2.gif")


When creating an image sequence, sequence can be either a list of image names (that will be played in the provided order), a folder name (played in alphanumerical order), or a list of frames (Numpy arrays), obtained for instance from other clips.

Warning:

All the images in the list/folder/frames must be of the same size, or an exception will be raised.


For more, see ImageSequenceClip <#moviepy.video.io.ImageSequenceClip.ImageSequenceClip>.

DataVideoClip

DataVideoClip is a video clip that takes a list of datasets, a callback function, and makes each frame by iterating over the dataset and invoking the callback function with the current data as the first argument.

You will probably never use this. But if you do, think of it like a VideoClip <#moviepy.video.VideoClip.VideoClip>, where you make frames not based on time, but based on each entry of a data list.

"""Let's make a clip where frames depend on values in a list"""
from moviepy import DataVideoClip
import numpy as np
# Dataset will just be a list of colors as RGB
dataset = [

(255, 0, 0),
(0, 255, 0),
(0, 0, 255),
(0, 255, 255),
(255, 0, 255),
(255, 255, 0), ] # The function make frame take data and create an image of 200x100 px # filled with the color given in the dataset def frame_function(data):
frame = np.full((100, 200, 3), data, dtype=np.uint8)
return frame # We create the DataVideoClip, and we set FPS at 2, making a 3s clip # (because len(dataset) = 6, so 6/2=3) myclip = DataVideoClip(data=dataset, data_to_frame=frame_function, fps=2) # Modifying fps here will change video FPS, not clip FPS myclip.write_videofile("result.mp4", fps=30)


For more, see DataVideoClip.

UpdatedVideoClip

Warning:

This is really advanced usage; you will probably never need it. If you do, please go read the code.


UpdatedVideoClip is a video whose frame_function requires some objects to be updated before we can compute it.

This is particularly practical in science where some algorithms need to make some steps before a new frame can be generated, or maybe when trying to make a video based on a live exterior context.

When you use this, you pass a world object to it. A world object is an object that respects these 3 rules:

1.
It has a clip_t property, indicating the current world time.
2.
It has an update() method, that will update the world state and is responsible for increasing clip_t when a new frame can be drawn.
3.
It has a to_frame() method, that will render a frame based on the world's current state.

On get_frame() call, your UpdatedVideoClip will try to update the world until world.clip_t is superior or equal to frame time, then it will call world.to_frame().

import random
import numpy as np
from moviepy import UpdatedVideoClip
class CoinFlipWorld:

"""A simulation of coin flipping.
Imagine we want to make a video that become more and more red as we repeat same face
on coinflip in a row because coinflip are done in real time, we need to wait
until a winning row is done to be able to make the next frame.
This is a world simulating that. Sorry, it's hard to come up with examples...
"""
def __init__(self, fps):
"""
FPS is usefull because we must increment clip_t by 1/FPS to have
UpdatedVideoClip run with a certain FPS
"""
self.clip_t = 0
self.win_strike = 0
self.reset = False
self.fps = fps
def update(self):
if self.reset:
self.win_strike = 0
self.reset = False
print("strike : {}, clip_t : {}".format(self.win_strike, self.clip_t))
print(self.win_strike)
# 0 tails, 1 heads, this is our simulation of coinflip
choice = random.randint(0, 1)
face = random.randint(0, 1)
# We win, we increment our serie and retry
if choice == face:
self.win_strike += 1
return
# Different face, we increment clip_t and set reset so we will reset on next update.
# We don't reset immediately because we will need current state to make frame
self.reset = True
self.clip_t += 1 / self.fps
def to_frame(self):
"""Return a frame of a 200x100 image with red more or less intense based
on number of victories in a row."""
red_intensity = 255 * (self.win_strike / 10)
red_intensity = min(red_intensity, 255)
# A 200x100 image with red more or less intense based on number of victories in a row
return np.full((100, 200, 3), (red_intensity, 0, 0), dtype=np.uint8) world = CoinFlipWorld(fps=5) myclip = UpdatedVideoClip(world=world, duration=10) # We will set FPS to same as world, if we was to use a different FPS, # the lowest from world.fps and our write_videofile fps param # will be the real visible fps myclip.write_videofile("result.mp4", fps=5)


Unanimated Clips

These are clips whose image will, at least before modifications, stay the same. By default, they have no duration nor FPS, meaning you will need to define them before doing operations needing such information (for example, rendering).

ImageClip

ImageClip <#moviepy.video.VideoClip.ImageClip> is the base class for all unanimated clips; it's a video clip that always displays the same image. Along with VideoFileClip <#moviepy.video.io.VideoFileClip.VideoFileClip>, it's one of the most used kinds of clips.

You can create one as follows:

"""Here's how you transform a VideoClip into an ImageClip from an image, from
arbitrary data, or by extracting a frame at a given time"""
from moviepy import ImageClip, VideoFileClip
import numpy as np
# Random RGB noise image of 200x100
noise_image = np.random.randint(low=0, high=255, size=(100, 200, 3))
myclip1 = ImageClip("example.png")  # You can create it from a path
myclip2 = ImageClip(noise_image)  # from a (height x width x 3) RGB numpy array
# Or load videoclip and extract frame at a given time
myclip3 = VideoFileClip("./example.mp4").to_ImageClip(t="00:00:01")


For more, see ImageClip <#moviepy.video.VideoClip.ImageClip>.

TextClip

A TextClip <#moviepy.video.VideoClip.TextClip> is a clip that will turn a text string into an image clip.

TextClip <#moviepy.video.VideoClip.TextClip> accepts many parameters, letting you configure the appearance of the text, such as font and font size, color, interlining, text alignment, etc.

The font you want to use must be an OpenType font <https://fr.wikipedia.org/wiki/OpenType>, and you will set it by passing the path to the font file.

Here are a few examples of using TextClip <#moviepy.video.VideoClip.TextClip>:

from moviepy import TextClip
font = "./example.ttf"
# First we use as string and let system autocalculate clip dimensions to fit the text
# we set clip duration to 2 secs, if we do not, it got an infinite duration
txt_clip1 = TextClip(

font=font,
text="Hello World !",
font_size=30,
color="#FF0000", # Red
bg_color="#FFFFFF",
duration=2, ) # This time we load text from a file, we set a fixed size for clip and let the system find best font size, # allowing for line breaking txt_clip2 = TextClip(
font=font,
filename="./example.txt",
size=(500, 200),
bg_color="#FFFFFF",
method="caption",
color=(0, 0, 255, 127), ) # Blue with 50% transparency # we set duration, because by default image clip are infinite, and we cannot render infinite txt_clip2 = txt_clip2.with_duration(2) # ImageClip have no FPS either, so we must defined it txt_clip1.write_videofile("result1.mp4", fps=24) txt_clip2.write_videofile("result2.mp4", fps=24)


Note:

The parameter method lets you define if text should be written and overflow if too long (label) or be automatically broken over multiple lines (caption).


For a more detailed explanation of all the parameters, see TextClip <#moviepy.video.VideoClip.TextClip>.

ColorClip

A ColorClip <#moviepy.video.VideoClip.ColorClip> is a clip that will return an image of only one color. It is sometimes useful when doing compositing (see Compositing Multiple Clips <#compositing>).

from moviepy import ColorClip
# Color is passed as a RGB tuple
myclip = ColorClip(size=(200, 100), color=(255, 0, 0), duration=1)
# We really don't need more than 1 fps do we ?
myclip.write_videofile("result.mp4", fps=1)


For more, see ColorClip <#moviepy.video.VideoClip.ColorClip>.

Mask Clips

Masks are a special kind of VideoClip <#moviepy.video.VideoClip.VideoClip> with the property is_mask set to True. They can be attached to any other kind of VideoClip <#moviepy.video.VideoClip.VideoClip> through method with_mask() <#moviepy.video.VideoClip.VideoClip.with_mask>.

When a clip has a mask attached to it, this mask will indicate which pixels will be visible when the clip is composed with other clips (see Compositing Multiple Clips <#compositing>). Masks are also used to define transparency when you export the clip as GIF file or as a PNG.

The fundamental difference between masks and standard clips is that standard clips output frames with 3 components (R-G-B) per pixel, comprised between 0 and 255, while a mask has just one component per pixel, between 0 and 1 (1 indicating a fully visible pixel and 0 a transparent pixel). Seen otherwise, a mask is always in greyscale.

When you create or load a clip that you will use as a mask, you need to declare it. You can then attach it to a clip with the same dimensions:

import numpy as np
from moviepy import ImageClip, VideoClip, VideoFileClip
# Random RGB noise image of 200x100
frame_function = lambda t: np.random.rand(100, 200)
# To define the VideoClip as a mask, just pass parameter is_mask as True
maskclip1 = VideoClip(frame_function, duration=4, is_mask=True)  # A random noise mask
maskclip2 = ImageClip("example_mask.jpg", is_mask=True)  # A fixed mask as jpeg
maskclip3 = VideoFileClip("example_mask.mp4", is_mask=True)  # A video as a mask
# Load our basic clip, resize to 200x100 and apply each mask
clip = VideoFileClip("example.mp4")
clip_masked1 = clip.with_mask(maskclip1)
clip_masked2 = clip.with_mask(maskclip2)
clip_masked3 = clip.with_mask(maskclip3)


Note:

In the case of video and image files, if these are not already black and white, they will be converted automatically.

Also, when you load an image with an alpha layer, like a PNG, MoviePy will use this layer as a mask unless you pass transparent=False.



Any video clip can be turned into a mask with to_mask() <#moviepy.video.VideoClip.VideoClip.to_mask>, and a mask can be turned to a standard RGB video clip with to_RGB() <#moviepy.video.VideoClip.VideoClip.to_RGB>.

Masks are treated differently by many methods (because their frames are different) but at the core, they are VideoClip <#moviepy.video.VideoClip.VideoClip>, so you can do with them everything you can do with a video clip: modify, cut, apply effects, save, etc.

Using Audio Elements with Audio Clips

In addition to VideoClip <#moviepy.video.VideoClip.VideoClip> for visuals, you can use audio elements, like an audio file, using the AudioClip <#moviepy.audio.AudioClip.AudioClip> class.

Both are quite similar, except AudioClip <#moviepy.audio.AudioClip.AudioClip> method get_frame() returns a numpy array of size Nx1 for mono, and size Nx2 for stereo.

AudioClip

AudioClip <#moviepy.audio.AudioClip.AudioClip> is the base class for all audio clips. If all you want is to edit audio files, you will never need it.

All you need is to define a function frame_function(t) which returns a Nx1 or Nx2 numpy array representing the sound at time t.

from moviepy import AudioClip
import numpy as np
def audio_frame(t):

"""Producing a sinewave of 440 Hz -> note A"""
return np.sin(440 * 2 * np.pi * t) audio_clip = AudioClip(frame_function=audio_frame, duration=3)


For more, see AudioClip <#moviepy.audio.AudioClip.AudioClip>.

AudioFileClip

AudioFileClip <#moviepy.audio.io.AudioFileClip.AudioFileClip> is used to load an audio file. This is probably the only kind of audio clip you will use.

You simply pass it the file you want to load:

from moviepy import *
# Works for audio files, but also videos file where you only want the keep the audio track
clip = AudioFileClip("example.wav")
clip.write_audiofile("./result.wav")


For more, see AudioFileClip <#moviepy.audio.io.AudioFileClip.AudioFileClip>.

AudioArrayClip

AudioArrayClip <#moviepy.audio.AudioClip.AudioArrayClip> is used to turn an array representing a sound into an audio clip. You will probably never use it unless you need to use the result of some third-party library without using a temporary file.

You need to provide a numpy array representing the sound (of size Nx1 for mono, Nx2 for stereo), and the number of fps, indicating the speed at which the sound is supposed to be played.

"""Let's create an audioclip from values in a numpy array."""
import numpy as np
from moviepy import AudioArrayClip
# We want to play these notes
notes = {"A": 440, "B": 494, "C": 523, "D": 587, "E": 659, "F": 698}
note_duration = 0.5
total_duration = len(notes) * note_duration
sample_rate = 44100  # Number of samples per second
note_size = int(note_duration * sample_rate)
n_frames = note_size * len(notes)
def frame_function(t, note_frequency):

return np.sin(note_frequency * 2 * np.pi * t) # At this point one could use this audioclip which generates the audio on the fly # clip = AudioFileClip(frame_function) # We generate all frames timepoints audio_frame_values = [
2 * [frame_function(t, freq)]
for freq in notes.values()
for t in np.arange(0, note_duration, 1.0 / sample_rate) ] # Create an AudioArrayClip from the audio samples audio_clip = AudioArrayClip(np.array(audio_frame_values), fps=sample_rate) # Write the audio clip to a WAV file audio_clip.write_audiofile("result.wav", fps=44100)


For more, see AudioArrayClip <#moviepy.audio.AudioClip.AudioArrayClip>.

Modifying clips and apply effects

Of course, once you will have loaded a Clip <#moviepy.Clip.Clip> the next step of action will be to modify it to be able to integrate it in your final video.

To modify a clip, there is three main courses of actions :
  • The built-in methods of VideoClip <#moviepy.video.VideoClip.VideoClip> or AudioClip <#moviepy.audio.AudioClip.AudioClip> modifying the properties of the object.
  • The already-implemented effects of MoviePy you can apply on clips, usually affecting the clip by applying filters on each frame of the clip at rendering time.
  • The transformation filters that you can apply using transform() <#moviepy.Clip.Clip.transform> and time_transform() <#moviepy.Clip.Clip.time_transform>.


How modifications are applied to a clip ?

Clip copy during modification

The first thing you must know is that when modifying a clip, MoviePy will never modify that clip directly. Instead it will return a modified copy of the original and let the original untouched. This is known as out-place instead of in-place behavior.

To illustrate:

# Import everything needed to edit video clips
from moviepy import VideoFileClip
# Load example.mp4
clip = VideoFileClip("example.mp4")
# This does nothing, as multiply_volume will return a copy of clip
# which you will loose immediatly as you don't store it
# If you was to render clip now, the audio would still be at full volume
clip.with_volume_scaled(0.1)
# This create a copy of clip in clip_whisper with a volume of only 10% the original,
# but does not modify the original clip
# If you was to render clip right now, the audio would still be at full volume
# If you was to render clip_whisper, the audio would be a 10% of the original volume
clip_whisper = clip.with_volume_scaled(0.1)
# This replace the original clip with a copy of it where volume is only 10% of
# the original. If you was to render clip now, the audio would be at 10%
# The original clip is now lost
clip = clip.with_volume_scaled(0.1)


This is an important point to understand, because it is one of the most recurrent source of bug for newcomers.

Memory consumption of effect and modifications

When applying an effect or modification, it does not immediately apply the effect to all the frames of the clip, but only to the first frame: all the other frames will only be modified when required (that is, when you will write the whole clip to a file or when you will preview it).

It means that creating a new clip is neither time nor memory hungry, all the computation happen during the final rendering.

Time representations in MoviePy

Many methods that we will see accept duration or timepoint as arguments. For instance clip.subclipped(t_start, t_end) which cuts the clip between two timepoints.

MoviePy usually accept duration and timepoint as either:

  • a number of seconds as a float.
  • a tuple with (minutes, seconds) or (hours, minutes, seconds).
  • a string such as '00:03:50.54'.

Also, you can usually provide negative times, indicating a time from the end of the clip. For example, clip.subclipped(-20, -10) cuts the clip between 20s before the end and 10s before the end.

Modify a clip using the with_* methods

The first way to modify a clip is by modifying internal properties of your object, thus modifying his behavior.

These methods usually start with the prefix with_ or without_, indicating that they will return a copy of the clip with the properties modified.

So, you may write something like:

from moviepy import VideoFileClip
myclip = VideoFileClip("example.mp4")
myclip = myclip.with_end(5)  # stop the clip after 5 sec
myclip = myclip.without_audio()  # remove the audio of the clip


In addition to the with_* methods, a handful of very common methods are also accessible under shorter names:

  • resized() <#moviepy.video.VideoClip.VideoClip.resized>
  • crop()
  • rotate()

For a list of all those methods, see Clip <#moviepy.Clip.Clip> and VideoClip <#moviepy.video.VideoClip.VideoClip>.

Modify a clip using effects

The second way to modify a clip is by using effects that will modify the frames of the clip (which internally are no more than numpy arrays <https://numpy.org>) by applying some sort of functions on them.

MoviePy come with many effects implemented in moviepy.video.fx <#module-moviepy.video.fx> for visual effects and moviepy.audio.fx <#module-moviepy.audio.fx> for audio effects. For practicality, these two modules are loaded in MoviePy as vfx and afx, letting you import them as from moviepy import vfx, afx.

To use these effects, you simply need to instantiate them as object and apply them on your Clip <#moviepy.Clip.Clip> using method with_effects() <#moviepy.Clip.Clip.with_effects>, with a list of Effect <#moviepy.Effect.Effect> objects you want to apply.

For convenience the effects are also dynamically added as method of VideoClip <#moviepy.video.VideoClip.VideoClip> and AudioClip classes at runtime, letting you call them as simple method of your clip.

So, you may write something like:

from moviepy import VideoFileClip
from moviepy import vfx, afx
myclip = VideoFileClip("example.mp4")
# resize clip to be 460px in width, keeping aspect ratio
myclip = myclip.with_effects([vfx.Resize(width=460)])
# fx method return a copy of the clip, so we can easily chain them
# double the speed and half the audio volume
myclip = myclip.with_effects([vfx.MultiplySpeed(2), afx.MultiplyVolume(0.5)])
# because effects are added to Clip at runtime, you can also call
# them directly from your clip as methods
myclip = myclip.with_effects([vfx.MultiplyColor(0.5)])  # darken the clip


Note:

MoviePy effects are automatically applied to both the sound and the mask of the clip if it is relevant, so that you don't have to worry about modifying these.


For a list of those effects, see moviepy.video.fx <#module-moviepy.video.fx> and moviepy.audio.fx <#module-moviepy.audio.fx>.

In addition to the effects already provided by MoviePy, you can obviously Creating Your Own Effects <#create-effects> and use them the same way.

Modify a clip appearance and timing using filters

In addition to modifying a clip's properties and using effects, you can also modify the appearance or timing of a clip by using your own custom filters with time_transform() <#moviepy.Clip.Clip.time_transform>, image_transform(), and more generally with transform() <#moviepy.Clip.Clip.transform>.

All these methods work by taking as first parameter a callback function that will receive either a clip frame, a timepoint, or both, and return a modified version of these.

Modify only the timing of a Clip

You can change the timeline of the clip with time_transform(your_filter) <#moviepy.Clip.Clip.time_transform>. Where your_filter is a callback function taking clip time as a parameter and returning a new time:

from moviepy import VideoFileClip
import math
my_clip = VideoFileClip("example.mp4")
# Let's accelerate the video by a factor of 3
modified_clip1 = my_clip.time_transform(lambda t: t * 3)
# Let's play the video back and forth with a "sine" time-warping effect
modified_clip2 = my_clip.time_transform(lambda t: 1 + math.sin(t))


Now the clip modified_clip1 plays three times faster than my_clip, while modified_clip2 will be oscillating between 00:00:00 to 00:00:02 of my_clip. Note that in the last case you have created a clip of infinite duration (which is not a problem for the moment).

Note:

By default time_transform() <#moviepy.Clip.Clip.time_transform> will only modify the clip main frame, without modifying clip audio or mask for VideoClip <#moviepy.video.VideoClip.VideoClip>.

If you wish to also modify audio and/or mask you can provide the parameter apply_to with either 'audio', 'mask', or ['audio', 'mask'].



Modifying only the appearance of a Clip

For VideoClip <#moviepy.video.VideoClip.VideoClip>, you can change the appearance of the clip with image_transform(your_filter) <#moviepy.video.VideoClip.VideoClip.image_transform>. Where your_filter is a callback function, taking clip frame (a numpy array) as a parameter and returning the transformed frame:

"""Let's invert the green and blue channels of a video."""
from moviepy import VideoFileClip
import numpy
my_clip = VideoFileClip("example.mp4")
def invert_green_blue(image: numpy.ndarray) -> numpy.ndarray:

return image[:, :, [0, 2, 1]] modified_clip1 = my_clip.image_transform(invert_green_blue)


Now the clip modified_clip1 will have his green and blue canals inverted.

Note:

You can define if transformation should be applied to audio and mask same as for time_transform() <#moviepy.Clip.Clip.time_transform>.


Note:

Sometimes need to treat clip frames and mask frames in a different way. To distinguish between the two, you can always look at their shape, clips are H*W*3, and masks H*W.


Modifying both the appearance and the timing of a Clip

Finally, you may want to process the clip by taking into account both the time and the frame picture, for example to apply visual effects variating with time. This is possible with the method transform(your_filter) <#moviepy.Clip.Clip.transform>. Where your_filter is a callback function taking two parameters, and returning a new frame picture. Where first argument is a get_frame method (i.e. a function get_frame(time) which given a time returns the clip’s frame at that time), and the second argument is the time.

"""Let's create a scolling video effect from scratch."""
from moviepy import VideoFileClip
my_clip = VideoFileClip("example.mp4")
def scroll(get_frame, t):

"""
This function returns a 'region' of the current frame.
The position of this region depends on the time.
"""
frame = get_frame(t)
frame_region = frame[int(t) : int(t) + 360, :]
return frame_region modified_clip1 = my_clip.transform(scroll)


This will scroll down the clip, with a constant height of 360 pixels.

Note:

You can define if transformation should be applied to audio and mask same as for time_transform() <#moviepy.Clip.Clip.time_transform>.


Note:

When programming a new effect, whenever it is possible, prefer using time_transform and image_transform instead of transform when implementing new effects. The reason is that, though they both internally rely on transform when these effects are applied to ImageClip objects, MoviePy will recognize they only need to be applied once instead of on each frame, resulting in faster renderings.


To keep things simple, we have only addressed the case of VideoClip <#moviepy.video.VideoClip.VideoClip>, but know that the same principle applies to AudioClip <#moviepy.audio.AudioClip.AudioClip>, except that instead of a picture frame, you will have an audio frame, which is also a numpy array.

Creating Your Own Effects

In addition to the existing effects already offered by MoviePy, we can create our own effects to modify a clip however we want.

Why Create Your Own Effects?

For simple enough tasks, we've seen that we can modify. Though it might be enough for simple tasks, filters are kind of limited:

  • They can only access the frame and/or timepoint.
  • We cannot pass arguments to them.
  • They are hard to maintain and reuse.

To allow for more complex and reusable clip modifications, we can create our own custom effects, which we will later apply with with_effects() <#moviepy.Clip.Clip.with_effects>.

For example, imagine we want to add a progress bar to a clip. To do so, we will not only need the time and image of the current frame but also the total duration of the clip. We will also probably want to be able to pass parameters to define the appearance of the progress bar, such as color or height. This is a perfect task for an effect!

Creating an Effect

In MoviePy, effects are objects of type moviepy.Effect.Effect <#moviepy.Effect.Effect>, which is the base abstract class for all effects (similar to how Clip <#moviepy.Clip.Clip> is the base for all VideoClip <#moviepy.video.VideoClip.VideoClip> and AudioClip <#moviepy.audio.AudioClip.AudioClip>).

So, to create an effect, we will need to inherit the Effect <#moviepy.Effect.Effect> class and do two things:

  • Create an __init__ method to be able to receive the parameters of our effect.
  • Implement the inherited apply() <#moviepy.Effect.Effect.apply> method, which must take as an argument the clip we want to modify and return the modified version.

In the end, your effect will probably use time_transform() <#moviepy.Clip.Clip.time_transform>, image_transform(), or transform() <#moviepy.Clip.Clip.transform> to really apply your modifications to the clip. The main difference is that because your filter will be a method or an anonymous function inside your effect class, you will be able to access all properties of your object from it!

So, let's see how we could create our progress bar effect:

"""Let's write a custom effect that will add a basic progress bar
at the bottom of our clip."""
from moviepy import VideoClip
from moviepy.decorators import requires_duration
# Here you see a decorator that will verify if our clip have a duration
# MoviePy offer a few of them that may come handy when writing your own effects
@requires_duration
def progress_bar(clip: VideoClip, color: tuple, height: int = 10):

"""
Add a progress bar at the bottom of our clip
Parameters
----------
color: Color of the bar as a RGB tuple
height: The height of the bar in pixels. Default = 10
"""
# Because we have define the filter func inside our global effect,
# it have access to global effect scope and can use clip from inside filter
def filter(get_frame, t):
progression = t / clip.duration
bar_width = int(progression * clip.w)
# Showing a progress bar is just replacing bottom pixels
# on some part of our frame
frame = get_frame(t)
frame[-height:, 0:bar_width] = color
return frame
return clip.transform(filter, apply_to="mask")


Note:

When creating an effect, you frequently have to write boilerplate code for assigning properties on object initialization. dataclasses is a nice way to limit that.


If you want to create your own effects, in addition to this documentation, we strongly encourage you to go and take a look at the existing ones (see moviepy.video.fx <#module-moviepy.video.fx> and moviepy.audio.fx <#module-moviepy.audio.fx>) to see how they work and take inspiration.

Compositing Multiple Clips

Video composition, also known as non-linear editing, is the process of mixing and playing several clips together in a new clip. This video is a good example of what compositing you can do with MoviePy:

Note:

Before starting, note that video clips generally carry an audio track and a mask, which are also clips. When you compose these clips together, the soundtrack and mask of the final clip are automatically generated by putting together the soundtracks and masks of the clips. So most of the time you don't need to worry about mixing the audio and masks.


Juxtaposing and Concatenating Clips

Two simple ways of putting clips together are to concatenate them (to play them one after the other in a single long clip) or to juxtapose them (to put them side by side in a single larger clip).

Concatenating Multiple Clips

Concatenation can be done very easily with the function concatenate_videoclips() <#moviepy.video.compositing.CompositeVideoClip.concatenate_videoclips>.

"""Let's concatenate (play one after the other) three video clips."""
from moviepy import VideoFileClip, concatenate_videoclips
# We load all the clips we want to concatenate
clip1 = VideoFileClip("example.mp4")
clip2 = VideoFileClip("example2.mp4").subclipped(0, 1)
clip3 = VideoFileClip("example3.mp4")
# We concatenate them and write the result
final_clip = concatenate_videoclips([clip1, clip2, clip3])
final_clip.write_videofile("final_clip.mp4")


The final_clip is a clip that plays the clips 1, 2, and 3 one after the other.

Note:

The clips do not need to be the same size. If they aren't, they will all appear centered in a clip large enough to contain the biggest of them, with optionally a color of your choosing to fill the background.


For more info, see concatenate_videoclips() <#moviepy.video.compositing.CompositeVideoClip.concatenate_videoclips>.

Juxtaposing Multiple Clips

Putting multiple clips side by side is done with clip_array():

"""Let's juxtapose four video clips in a 2x2 grid."""
from moviepy import VideoFileClip, clips_array, vfx
# We will use the same clip and transform it in 3 ways
clip1 = VideoFileClip("example.mp4").with_effects([vfx.Margin(10)])  # add 10px contour
clip2 = clip1.with_effects([vfx.MirrorX()])  # Flip horizontaly
clip3 = clip1.with_effects([vfx.MirrorY()])  # Flip verticaly
clip4 = clip1.resized(0.6)  # downsize to 60% of original
# The form of the final clip will depend of the shape of the array
# We want our clip to be our 4 videos, 2x2, so we make an array of 2x2
array = [

[clip1, clip2],
[clip3, clip4], ] final_clip = clips_array(array) # let's resize the final clip so it has 480px of width final_clip = final_clip.resized(width=480) final_clip.write_videofile("final_clip.mp4")


You obtain a clip which looks like this:

[image]


For more info, see clip_array().

More Complex Video Compositing

The CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip> class is the base of all video compositing. For example, internally, both concatenate_videoclips() <#moviepy.video.compositing.CompositeVideoClip.concatenate_videoclips> and clip_array() create a CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip>.

It provides a very flexible way to compose clips by layering multiple clips on top of each other, in the order they have been passed to CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip>. Here's an example:

"""Let's stack three video clips on top of each other with
CompositeVideoClip."""
from moviepy import VideoFileClip, CompositeVideoClip
# We load all the clips we want to compose
clip1 = VideoFileClip("example.mp4")
clip2 = VideoFileClip("example2.mp4").subclipped(0, 1)
clip3 = VideoFileClip("example.mp4")
# We concatenate them and write theme stacked on top of each other,
# with clip3 over clip2 over clip1
final_clip = CompositeVideoClip([clip1, clip2, clip3])
final_clip.write_videofile("final_clip.mp4")


Now final_clip plays all clips at the same time, with clip3 over clip2 over clip1. It means that, if all clips have the same size, then only clip3, which is on top, will be visible in the video...

Unless clip3 and/or clip2 have masks which hide parts of them.

Note:

Note that by default the composition has the size of its first clip (as it is generally a background). But sometimes you will want to make your clips float in a bigger composition. To do so, just pass the size of the final composition as size parameter of CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip>.


For now we have stacked multiple clips on top of each other, but this is obviously not enough for doing real video compositing. For that, we will need to change when some clips start and stop playing, as well as define the x:y position of these clips in the final video.

For more info, see CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip>.

Changing Starting and Stopping Times of Clips

In a CompositionClip, each clip starts to play at a time that is specified by its clip.start attribute, and will play until clip.end.

So, considering that you would want to play clip1 for the first 6 seconds, clip2 5 seconds after the start of the video, and finally clip3 at the end of clip2, you would do as follows:

from moviepy import VideoFileClip, CompositeVideoClip
# We load all the clips we want to compose
clip1 = VideoFileClip("example.mp4")
clip2 = VideoFileClip("example2.mp4").subclipped(0, 1)
clip3 = VideoFileClip("example3.mp4")
# We want to stop clip1 after 1s
clip1 = clip1.with_end(1)
# We want to play clip2 after 1.5s
clip2 = clip2.with_start(1.5)
# We want to play clip3 at the end of clip2, and so for 3 seconds only
# Some times its more practical to modify the duration of a clip instead
# of his end
clip3 = clip3.with_start(clip2.end).with_duration(1)
# We write the result
final_clip = CompositeVideoClip([clip1, clip2, clip3])
final_clip.write_videofile("final_clip.mp4")


Note:

When working with timing of your clips, you will frequently want to keep only parts of the original clip. To do so, you should take a look at subclipped() <#moviepy.Clip.Clip.subclipped> and with_section_cut_out() <#moviepy.Clip.Clip.with_section_cut_out>.


Positioning Clips

Frequently, you will want a smaller clip to appear on top of a larger one and decide where it will appear in the composition by setting their position.

You can do so by using the with_position() <#moviepy.video.VideoClip.VideoClip.with_position> method. The position is always defined from the top left corner, but you can define it in many ways:

"""Let's position some text and images on a video."""
from moviepy import CompositeVideoClip, ImageClip, TextClip, VideoFileClip
# We load all the clips we want to compose
background = VideoFileClip("example2.mp4").subclipped(0, 2)
title = TextClip(

"./example.ttf",
text="Big Buck Bunny",
font_size=80,
color="#fff",
text_align="center",
duration=1, ) author = TextClip(
"./example.ttf",
text="Blender Foundation",
font_size=40,
color="#fff",
text_align="center",
duration=1, ) copyright = TextClip(
"./example.ttf",
text="© CC BY 3.0",
font_size=20,
color="#fff",
text_align="center",
duration=1, ) logo = ImageClip("./example2.png", duration=1).resized(height=50) # We want our title to be at the center horizontaly and start at 25% # of the video verticaly. We can set as "center", "left", "right", # "top" and "bottom", and % relative from the clip size title = title.with_position(("center", 0.25), relative=True) # We want the author to be in the center, 30px under the title # We can set as pixels top = background.h * 0.25 + title.h + 30 left = (background.w - author.w) / 2 author = author.with_position((left, top)) # We want the copyright to be 30px before bottom copyright = copyright.with_position(("center", background.h - copyright.h - 30)) # Finally, we want the logo to be in the center, but to drop as time pass # We can do so by setting position as a function that take time as argument, # a lot like frame_function top = (background.h - logo.h) / 2 logo = logo.with_position(lambda t: ("center", top + t * 30)) # We write the result final_clip = CompositeVideoClip([background, title, author, copyright, logo]) final_clip.write_videofile("final_clip.mp4")


When indicating the position, keep in mind that the y coordinate has its zero at the top of the picture:

[image]


Adding Transition Effects

The last part of composition is adding transition effects. For example, when a clip starts while another is still playing, it would be nice to make the new one fade-in instead of showing abruptly.

To do so, we can use the transitions offered by MoviePy in transitions, like crossfadein():

"""In this example, we will concatenate two clips with a 1-second
crossfadein of the second clip."""
from moviepy import VideoFileClip, CompositeVideoClip, vfx
# We load all the clips we want to compose
clip1 = VideoFileClip("example.mp4")
clip2 = VideoFileClip("example2.mp4")
clips = [

clip1.with_end(2),
clip2.with_start(1).with_effects([vfx.CrossFadeIn(1)]), ] final_clip = CompositeVideoClip(clips) final_clip.write_videofile("final_clip.mp4")


MoviePy offers only a few transitions in transitions. But technically, transitions are mostly effects applied to the mask of a clip! That means you can actually use any of the already existing effects and use them as transitions by applying them on the mask of your clip (see moviepy.video.fx <#module-moviepy.video.fx>).

For more info, see transitions and fx <#module-moviepy.video.fx>.

Compositing Audio Clips

When you mix video clips together, MoviePy will automatically compose their respective audio tracks to form the audio track of the final clip, so you don't need to worry about compositing these tracks yourself.

If you want to make a custom audio track from several audio sources, audio clips can be mixed together like video clips, with CompositeAudioClip <#moviepy.audio.AudioClip.CompositeAudioClip> and concatenate_audioclips() <#moviepy.audio.AudioClip.concatenate_audioclips>:

"""Let's first concatenate (one after the other) then composite
(on top of each other) three audio clips."""
from moviepy import AudioFileClip, CompositeAudioClip, concatenate_audioclips
# We load all the clips we want to compose
clip1 = AudioFileClip("example.wav")
clip2 = AudioFileClip("example2.wav")
clip3 = AudioFileClip("example3.wav")
# All clip will play one after the other
concat = concatenate_audioclips([clip1, clip2, clip3])
# We will play clip1, then on top of it clip2 starting at t=5s,
# and clip3 on top of both starting t=9s
compo = CompositeAudioClip(

[
clip1.with_volume_scaled(1.2),
clip2.with_start(5), # start at t=5s
clip3.with_start(9),
] )


Previewing and Saving Video Clips

Once you are done working with your clips, the final step will be to export the result into a video/image file, or sometimes to simply preview it in order to verify that everything is working as expected.

Previewing a Clip

When you are working with a clip, you will frequently need to have a quick look at what your clip looks like, either to verify that everything is working as intended or to check how things look.

To do so, you could render your entire clip into a file, but that's a rather long task, and you only need a quick look, so a better solution exists: previewing.

Preview a Clip as a Video

Warning:

You must have ffplay installed and accessible to MoviePy to be able to use preview(). If you're not sure, take a look install#binaries


The first thing you can do is to preview your clip as a video by calling the method preview() on your clip:

from moviepy import *
myclip = VideoFileClip("./example.mp4").subclipped(0, 1)  # Keep only 0 to 1 sec
# We preview our clip as a video, inheriting FPS and audio of the original clip
myclip.preview()
# We preview our clip as video, but with a custom FPS for video and audio
# making it less consuming for our computer
myclip.preview(fps=5, audio_fps=11000)
# Now we preview without audio
myclip.preview(audio=False)


You will probably frequently want to preview only a small portion of your clip, though preview does not offer such capabilities, you can easily emulate such behavior by using subclip().

Note:

It is quite frequent for a clip preview to be out of sync or to play slower than it should. This indicates that your computer is not powerful enough to render the clip in real-time.

Don't hesitate to play with the options of preview: for instance, lower the fps of the sound (11000 Hz is still fine) and the video. Also, downsizing your video with resize() can help.



For more information, see preview().

Note:

A quite similar function is also available for AudioClip() <#moviepy.audio.AudioClip.AudioClip>, see ffplay_audiopreview() <#moviepy.audio.io.ffplay_audiopreviewer.ffplay_audiopreview>.


Preview Just One Frame of a Clip

In many situations, you don't really need to preview your entire clip; seeing just one frame is enough to see how it looks and to ensure everything is going as expected.

To do so, you can use the method show() on your clip, passing the frame time as an argument:

from moviepy import *
myclip = VideoFileClip("./example.mp4")
# We show the first frame of our clip
myclip.show()
# We show the frame at point 00:00:01.5 of our clip
myclip.show(1.5)
# We want to see our clip without applying his mask
myclip.show(1.5, with_mask=False)


Contrary to video previewing, show() does not require ffplay but uses the pillow Image.show function.

For more information, see show().

Showing a Clip in Jupyter Notebook

If you work with a Jupyter Notebook <https://jupyter.org/>, it can be very practical to display your clip within the notebook. To do so, you can use the method display_in_notebook() <#moviepy.video.io.display_in_notebook.display_in_notebook> on your clip. [image]

With display_in_notebook() <#moviepy.video.io.display_in_notebook.display_in_notebook>, you can embed videos, images, and sounds, either from a file or directly from a clip:

from moviepy import *
# ...
# ... some jupyter specifics stuff
# ...
my_video_clip = VideoFileClip("./example.mp4")
my_image_clip = ImageClip("./example.png")
my_audio_clip = AudioFileClip("./example.wav")
# We can show any type of clip
my_video_clip.display_in_notebook()  # embeds a video
my_image_clip.display_in_notebook()  # embeds an image
my_audio_clip.display_in_notebook()  # embeds a sound
# We can display only a snaphot of a video
my_video_clip.display_in_notebook(t=1)
# We can provide any valid HTML5 option as keyword argument
# For instance, if the clip is too big, we can set width
my_video_clip.display_in_notebook(width=400)
# We can also make it loop, for example to check if a GIF is
# looping as expected
my_video_clip.display_in_notebook(autoplay=1, loop=1)


Warning:

Note that display_in_notebook() <#moviepy.video.io.display_in_notebook.display_in_notebook> will only work if it is on the last line of the notebook cell.

Also, note that display_in_notebook() <#moviepy.video.io.display_in_notebook.display_in_notebook> actually embeds the clips physically in your notebook. The advantage is that you can move the notebook or put it online and the videos will work. However, the drawback is that the file size of the notebook can become very large. Depending on your browser, re-computing and displaying the video multiple times can take up space in the cache and the RAM (this will only be a problem for intensive uses). Restarting your browser solves the problem.



For more information, see display_in_notebook() <#moviepy.video.io.display_in_notebook.display_in_notebook>.

Saving Your Clip into a File

Once you are satisfied with how your clip looks, you can save it into a file, a step known in video editing as rendering. MoviePy offers various ways to save your clip.

Video Files (.mp4, .webm, .ogv, ...)

The obvious first choice will be to write your clip to a video file, which you can do with write_videofile() <#moviepy.video.VideoClip.VideoClip.write_videofile>:

from moviepy import *
# We load all the clips we want to compose
background = VideoFileClip("long_examples/example2.mp4").subclipped(0, 10)
title = TextClip(

"./example.ttf",
text="Big Buck Bunny",
font_size=80,
color="#fff",
text_align="center",
duration=3, ).with_position(("center", "center")) # We make our final clip through composition final_clip = CompositeVideoClip([background, title]) # And finally we can write the result into a file # Here we just save as MP4, inheriting FPS, etc. from final_clip final_clip.write_videofile("result.mp4") # Here we save as MP4, but we set the FPS of the clip to our own, here 24 fps, like cinema final_clip.write_videofile("result24fps.mp4", fps=24) # Now we save as WEBM instead, and we want tu use codec libvpx-vp9 (usefull when mp4 + transparency). # We also want ffmpeg compression optimisation as minimal as possible. This will not change # the video quality and it will decrease time for encoding, but increase final file size a lot. # Finally, we want ffmpeg to use 4 threads for video encoding. You should probably leave that # to default, as ffmpeg is already quite good at using the best setting on his own. final_clip.write_videofile(
"result.webm", codec="libvpx-vp9", fps=24, preset="ultrafast", threads=4 )


MoviePy can automatically find the default codec names for the most common file extensions. If you want to use exotic formats or if you are not happy with the defaults, you can provide the codec with codec='mpeg4' for instance.

There are many options when you are writing a video (bitrate, parameters of the audio writing, file size optimization, number of processors to use, etc.), and we will not go into detail about each. For more information, see write_videofile() <#moviepy.video.VideoClip.VideoClip.write_videofile>.

Note:

Although you are encouraged to experiment with the settings of write_videofile, know that lowering the optimization preset or increasing the number of threads will not necessarily improve the rendering time, as the bottleneck may be in MoviePy's computation of each frame and not in ffmpeg encoding.

Also, know that it is possible to pass additional parameters to the ffmpeg command line invoked by MoviePy by using the ffmpeg_params argument.



Sometimes it is impossible for MoviePy to guess the duration attribute of the clip (keep in mind that some clips, like ImageClips displaying a picture, have a priori an infinite duration). In such cases, the duration must be set manually with with_duration() <#moviepy.Clip.Clip.with_duration>:

from moviepy import *
# By default an ImageClip has no duration
my_clip = ImageClip("example.png")
try:

# This will fail! We cannot write a clip with no duration!
my_clip.write_videofile("result.mp4") except:
print("Cannot write a video without duration") # By calling with_duration on our clip, we fix the problem! We also need to set fps my_clip.with_duration(2).write_videofile("result.mp4", fps=1)


Note:

A quite similar function is also available for AudioClip() <#moviepy.audio.AudioClip.AudioClip>, see write_audiofile().


Export a Single Frame of the Clip

As with previewing, sometimes you will need to export only one frame of a clip, for example to create the preview image of a video. You can do so with save_frame() <#moviepy.video.VideoClip.VideoClip.save_frame>:

from moviepy import *
# We load all the clips we want to compose
myclip = VideoFileClip("example.mp4")
myclip.save_frame("result.png", t=1)  # Save frame at 1 sec


For more information, see save_frame() <#moviepy.video.VideoClip.VideoClip.save_frame>.

Animated GIFs

In addition to writing video files, MoviePy also lets you write GIF files with write_gif() <#moviepy.video.VideoClip.VideoClip.write_gif>:

from moviepy import *
myclip = VideoFileClip("example.mp4").subclipped(0, 2)
# Here we just save as GIF
myclip.write_gif("result.gif")
# Here we save as GIF, but we set the FPS of our GIF at 10
myclip.write_gif("result.gif", fps=10)


For more information, see write_gif() <#moviepy.video.VideoClip.VideoClip.write_gif>.

Export All the Clip as Images in a Directory

Lastly, you might wish to export an entire clip as an image sequence (multiple images in one directory, one image per frame). You can do so with the function write_images_sequence() <#moviepy.video.VideoClip.VideoClip.write_images_sequence>:

from moviepy import *
import os
myclip = VideoFileClip("example.mp4")
# Here we just save in dir output with filename being his index (start at 0, then +1 for each frame)
os.mkdir("./output")
myclip.write_images_sequence("./output/%d.jpg")
# We set the FPS of our GIF at 10, and we leftpad name with 0 up to 4 digits
myclip.write_images_sequence("./output/%04d.jpg")


For more information, see write_images_sequence() <#moviepy.video.VideoClip.VideoClip.write_images_sequence>.

``

`

Api Reference

This is the definitive place to find all the details on MoviePy API documentation.

For a more beginner introduction, please see Getting started with MoviePy <#getting-started>, for a more detailed explanations of the different concepts in MoviePy, see The MoviePy User Guide <#user-guide>.

moviepy <#module-moviepy> Imports everything that you need from the MoviePy submodules so that every thing can be directly imported with from moviepy import *.

moviepy

Imports everything that you need from the MoviePy submodules so that every thing can be directly imported with from moviepy import *.

Modules

Clip <#module-moviepy.Clip> Implements the central object of MoviePy, the Clip, and all the methods that are common to the two subclasses of Clip, VideoClip and AudioClip.
Effect <#module-moviepy.Effect>() Base abstract class for all effects in MoviePy.
audio <#module-moviepy.audio> Everything about audio manipulation.
config <#module-moviepy.config> Third party programs configuration for MoviePy.
decorators <#module-moviepy.decorators> Decorators used by moviepy.
tools <#module-moviepy.tools> Misc.
version <#module-moviepy.version>
video <#module-moviepy.video> Everything about video manipulation.

moviepy.Clip

Implements the central object of MoviePy, the Clip, and all the methods that are common to the two subclasses of Clip, VideoClip and AudioClip.

Classes

Clip <#moviepy.Clip.Clip>() Base class of all clips (VideoClips and AudioClips).

moviepy.Clip.Clip

class moviepy.Clip.Clip
Base class of all clips (VideoClips and AudioClips).
start
When the clip is included in a composition, time of the composition at which the clip starts playing (in seconds).
Type
float


end
When the clip is included in a composition, time of the composition at which the clip stops playing (in seconds).
Type
float


duration
Duration of the clip (in seconds). Some clips are infinite, in this case their duration will be None.
Type
float


close()
Release any resources that are in use.

copy()
Allows the usage of .copy() in clips as chained methods invocation.

get_frame(t) -> ndarray
Gets a numpy array representing the RGB picture of the clip, or (mono or stereo) value for a sound clip, at time t.
Parameters
t (float or tuple or str) -- Moment of the clip whose frame will be returned.


is_playing(t)
If t is a time, returns true if t is between the start and the end of the clip. t can be expressed in seconds (15.35), in (min, sec), in (hour, min, sec), or as a string: '01:03:05.35'. If t is a numpy array, returns False if none of the t is in the clip, else returns a vector [b_1, b_2, b_3...] where b_i is true if tti is in the clip.

iter_frames(fps=None, with_times=False, logger=None, dtype=None)
Iterates over all the frames of the clip.

Returns each frame of the clip as a HxWxN Numpy array, where N=1 for mask clips and N=3 for RGB clips.

This function is not really meant for video editing. It provides an easy way to do frame-by-frame treatment of a video, for fields like science, computer vision...

Parameters
  • fps (int, optional) -- Frames per second for clip iteration. Is optional if the clip already has a fps attribute.
  • with_times (bool, optional) -- Ff True yield tuples of (t, frame) where t is the current time for the frame, otherwise only a frame object.
  • logger (str, optional) -- Either "bar" for progress bar or None or any Proglog logger.
  • dtype (type, optional) -- Type to cast Numpy array frames. Use dtype="uint8" when using the pictures to write video, images..


Examples

# prints the maximum of red that is contained
# on the first line of each frame of the clip.
from moviepy import VideoFileClip
myclip = VideoFileClip('myvideo.mp4')
print([frame[0,:,0].max()

for frame in myclip.iter_frames()])



subclipped(start_time=0, end_time=None)
Returns a clip playing the content of the current clip between times start_time and end_time, which can be expressed in seconds (15.35), in (min, sec), in (hour, min, sec), or as a string: '01:03:05.35'.

The mask and audio of the resulting subclip will be subclips of mask and audio the original clip, if they exist.

It's equivalent to slice the clip as a sequence, like clip[t_start:t_end].

Parameters
  • start_time (float or tuple or str, optional) -- Moment that will be chosen as the beginning of the produced clip. If is negative, it is reset to clip.duration + start_time.
  • end_time (float or tuple or str, optional) --

    Moment that will be chosen as the end of the produced clip. If not provided, it is assumed to be the duration of the clip (potentially infinite). If is negative, it is reset to clip.duration + end_time. For instance:

    >>> # cut the last two seconds of the clip:
    >>> new_clip = clip.subclipped(0, -2)
        

    If end_time is provided or if the clip has a duration attribute, the duration of the returned clip is set automatically.




time_transform(time_func, apply_to=None, keep_duration=False)
Returns a Clip instance playing the content of the current clip but with a modified timeline, time t being replaced by the return of time_func(t).
Parameters
  • time_func (function) -- A function t -> new_t.
  • apply_to ({"mask", "audio", ["mask", "audio"]}, optional) -- Can be either 'mask', or 'audio', or ['mask','audio']. Specifies if the filter transform should also be applied to the audio or the mask of the clip, if any.
  • keep_duration (bool, optional) -- False (default) if the transformation modifies the duration of the clip.


Examples

# plays the clip (and its mask and sound) twice faster
new_clip = clip.time_transform(lambda t: 2*t, apply_to=['mask', 'audio'])
# plays the clip starting at t=3, and backwards:
new_clip = clip.time_transform(lambda t: 3-t)



transform(func, apply_to=None, keep_duration=True)
General processing of a clip.

Returns a new Clip whose frames are a transformation (through function func) of the frames of the current clip.

Parameters
  • func (function) -- A function with signature (gf,t -> frame) where gf will represent the current clip's get_frame method, i.e. gf is a function (t->image). Parameter t is a time in seconds, frame is a picture (=Numpy array) which will be returned by the transformed clip (see examples below).
  • apply_to ({"mask", "audio", ["mask", "audio"]}, optional) -- Can be either 'mask', or 'audio', or ['mask','audio']. Specifies if the filter should also be applied to the audio or the mask of the clip, if any.
  • keep_duration (bool, optional) -- Set to True if the transformation does not change the duration of the clip.


Examples

In the following new_clip a 100 pixels-high clip whose video content scrolls from the top to the bottom of the frames of clip at 50 pixels per second.

>>> filter = lambda get_frame,t : get_frame(t)[int(t):int(t)+50, :]
>>> new_clip = clip.transform(filter, apply_to='mask')

with_duration(duration, change_end=True)
Returns a copy of the clip, with the duration attribute set to t, which can be expressed in seconds (15.35), in (min, sec), in (hour, min, sec), or as a string: '01:03:05.35'. Also sets the duration of the mask and audio, if any, of the returned clip.

If change_end is False, the start attribute of the clip will be modified in function of the duration and the preset end of the clip.

Parameters
  • duration (float) -- New duration attribute value for the clip.
  • change_end (bool, optional) -- If True, the end attribute value of the clip will be adjusted accordingly to the new duration using clip.start + duration.



with_effects(effects: List[Effect <#moviepy.Effect.Effect>])
Return a copy of the current clip with the effects applied

>>> new_clip = clip.with_effects([vfx.Resize(0.2, method="bilinear")])
    

You can also pass multiple effect as a list

>>> clip.with_effects([afx.VolumeX(0.5), vfx.Resize(0.3), vfx.Mirrorx()])
    

with_end(t)
Returns a copy of the clip, with the end attribute set to t, which can be expressed in seconds (15.35), in (min, sec), in (hour, min, sec), or as a string: '01:03:05.35'. Also sets the duration of the mask and audio, if any, of the returned clip.
note::
The start and end attribute of a clip define when a clip will start playing when used in a composite video clip, not the start time of the clip itself.

i.e: with_start(10) mean the clip will still start at his first frame, but if used in a composite video clip it will only start to show at 10 seconds.


Parameters
t (float or tuple or str) -- New end attribute value for the clip.


with_fps(fps, change_duration=False)
Returns a copy of the clip with a new default fps for functions like write_videofile, iterframe, etc.
Parameters
  • fps (int) -- New fps attribute value for the clip.
  • change_duration (bool, optional) -- If change_duration=True, then the video speed will change to match the new fps (conserving all frames 1:1). For example, if the fps is halved in this mode, the duration will be doubled.



with_is_mask(is_mask)
Says whether the clip is a mask or not.
Parameters
is_mask (bool) -- New is_mask attribute value for the clip.


with_memoize(memoize)
Sets whether the clip should keep the last frame read in memory.
Parameters
memoize (bool) -- Indicates if the clip should keep the last frame read in memory.


with_section_cut_out(start_time, end_time)
Returns a clip playing the content of the current clip but skips the extract between start_time and end_time, which can be expressed in seconds (15.35), in (min, sec), in (hour, min, sec), or as a string: '01:03:05.35'.

If the original clip has a duration attribute set, the duration of the returned clip is automatically computed as `` duration - (end_time - start_time)``.

The resulting clip's audio and mask will also be cutout if they exist.

Parameters
  • start_time (float or tuple or str) -- Moment from which frames will be ignored in the resulting output.
  • end_time (float or tuple or str) -- Moment until which frames will be ignored in the resulting output.



with_speed_scaled(factor: float = None, final_duration: float = None)
Returns a clip playing the current clip but at a speed multiplied by factor. For info on the parameters, please see vfx.MultiplySpeed.

with_start(t, change_end=True)
Returns a copy of the clip, with the start attribute set to t, which can be expressed in seconds (15.35), in (min, sec), in (hour, min, sec), or as a string: '01:03:05.35'.

These changes are also applied to the audio and mask clips of the current clip, if they exist.

note::
The start and end attribute of a clip define when a clip will start playing when used in a composite video clip, not the start time of the clip itself.

i.e: with_start(10) mean the clip will still start at his first frame, but if used in a composite video clip it will only start to show at 10 seconds.


Parameters
  • t (float or tuple or str) -- New start attribute value for the clip.
  • change_end (bool optional) -- Indicates if the end attribute value must be changed accordingly, if possible. If change_end=True and the clip has a duration attribute, the end attribute of the clip will be updated to start + duration. If change_end=False and the clip has a end attribute, the duration attribute of the clip will be updated to end - start.



with_updated_frame_function(frame_function)
Sets a frame_function attribute for the clip. Useful for setting arbitrary/complicated videoclips.
Parameters
frame_function (function) -- New frame creator function for the clip. A frame_function is a function taking a time t as input and returning a frame (a numpy array) as a result.


with_volume_scaled(factor: float, start_time=None, end_time=None)
Returns a new clip with audio volume multiplied by the value factor. For info on the parameters, please see afx.MultiplyVolume


moviepy.Effect

Defines the base class for all effects in MoviePy.

class moviepy.Effect.Effect
Base abstract class for all effects in MoviePy. Any new effect have to extend this base class.
abstractmethod apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the current effect on a clip
Parameters
clip -- The target clip to apply the effect on. (Internally, MoviePy will always pass a copy of the original clip)


copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.audio

Everything about audio manipulation.

Modules

AudioClip <#module-moviepy.audio.AudioClip> Implements AudioClip (base class for audio clips) and its main subclasses:
fx <#module-moviepy.audio.fx> All the audio effects that can be applied to AudioClip and VideoClip.
io <#module-moviepy.audio.io> Class and methods to read, write, preview audiofiles.
tools <#module-moviepy.audio.tools> Tools to better processing and edition of audio.

moviepy.audio.AudioClip

Implements AudioClip (base class for audio clips) and its main subclasses:

  • Audio clips: AudioClip, AudioFileClip, AudioArrayClip
  • Composition: CompositeAudioClip

Classes

AudioArrayClip <#moviepy.audio.AudioClip.AudioArrayClip>(array, fps) An audio clip made from a sound array.
AudioClip <#moviepy.audio.AudioClip.AudioClip>([frame_function, duration, fps]) Base class for audio clips.
CompositeAudioClip <#moviepy.audio.AudioClip.CompositeAudioClip>(clips) Clip made by composing several AudioClips.

moviepy.audio.AudioClip.AudioArrayClip

class moviepy.audio.AudioClip.AudioArrayClip(array, fps)
An audio clip made from a sound array.
Parameters
  • array -- A Numpy array representing the sound, of size Nx1 for mono, Nx2 for stereo.
  • fps -- Frames per second : speed at which the sound is supposed to be played.



moviepy.audio.AudioClip.AudioClip

class moviepy.audio.AudioClip.AudioClip(frame_function=None, duration=None, fps=None)
Base class for audio clips.

See AudioFileClip and CompositeAudioClip for usable classes.

An AudioClip is a Clip with a frame_function attribute of the form `` t -> [ f_t ]`` for mono sound and t-> [ f1_t, f2_t ] for stereo sound (the arrays are Numpy arrays). The f_t are floats between -1 and 1. These bounds can be trespassed without problems (the program will put the sound back into the bounds at conversion time, without much impact).

Parameters
  • frame_function -- A function t-> frame at time t. The frame does not mean much for a sound, it is just a float. What 'makes' the sound are the variations of that float in the time.
  • duration -- Duration of the clip (in seconds). Some clips are infinite, in this case their duration will be None.
  • nchannels -- Number of channels (one or two for mono or stereo).


Examples

# Plays the note A in mono (a sine wave of frequency 440 Hz)
import numpy as np
frame_function = lambda t: np.sin(440 * 2 * np.pi * t)
clip = AudioClip(frame_function, duration=5, fps=44100)
clip.preview()
# Plays the note A in stereo (two sine waves of frequencies 440 and 880 Hz)
frame_function = lambda t: np.array([

np.sin(440 * 2 * np.pi * t),
np.sin(880 * 2 * np.pi * t) ]).T.copy(order="C") clip = AudioClip(frame_function, duration=3, fps=44100) clip.preview()


audiopreview(fps=None, buffersize=2000, nbytes=2, audio_flag=None, video_flag=None)
Preview an AudioClip using ffplay
Parameters
  • fps -- Frame rate of the sound. 44100 gives top quality, but may cause problems if your computer is not fast enough and your clip is complicated. If the sound jumps during the preview, lower it (11025 is still fine, 5000 is tolerable).
  • buffersize -- The sound is not generated all at once, but rather made by bunches of frames (chunks). buffersize is the size of such a chunk. Try varying it if you meet audio problems (but you shouldn't have to).
  • nbytes -- Number of bytes to encode the sound: 1 for 8bit sound, 2 for 16bit, 4 for 32bit sound. 2 bytes is fine.
  • audio_flag -- Instances of class threading events that are used to synchronize video and audio during VideoClip.preview().
  • video_flag -- Instances of class threading events that are used to synchronize video and audio during VideoClip.preview().



display_in_notebook(filetype=None, maxduration=60, t=None, fps=None, rd_kwargs=None, center=True, **html_kwargs)
Displays clip content in an Jupyter Notebook.

Remarks: If your browser doesn't support HTML5, this should warn you. If nothing is displayed, maybe your file or filename is wrong. Important: The media will be physically embedded in the notebook.

Parameters
  • clip (moviepy.Clip.Clip <#moviepy.Clip.Clip>) -- Either the name of a file, or a clip to preview. The clip will actually be written to a file and embedded as if a filename was provided.
  • filetype (str, optional) -- One of "video", "image" or "audio". If None is given, it is determined based on the extension of filename, but this can bug.
  • maxduration (float, optional) -- An error will be raised if the clip's duration is more than the indicated value (in seconds), to avoid spoiling the browser's cache and the RAM.
  • t (float, optional) -- If not None, only the frame at time t will be displayed in the notebook, instead of a video of the clip.
  • fps (int, optional) -- Enables to specify an fps, as required for clips whose fps is unknown.
  • rd_kwargs (dict, optional) -- Keyword arguments for the rendering, like dict(fps=15, bitrate="50k"). Allow you to give some options to the render process. You can, for example, disable the logger bar passing dict(logger=None).
  • center (bool, optional) -- If true (default), the content will be wrapped in a <div align=middle> HTML container, so the content will be displayed at the center.
  • kwargs -- Allow you to give some options, like width=260, etc. When editing looping gifs, a good choice is loop=1, autoplay=1.


Examples

from moviepy import *
# later ...
clip.display_in_notebook(width=360)
clip.audio.display_in_notebook()
clip.write_gif("test.gif")
display_in_notebook('test.gif')
clip.save_frame("first_frame.jpeg")
display_in_notebook("first_frame.jpeg")



iter_chunks(chunksize=None, chunk_duration=None, fps=None, quantize=False, nbytes=2, logger=None)
Iterator that returns the whole sound array of the clip by chunks

max_volume(stereo=False, chunksize=50000, logger=None)
Returns the maximum volume level of the clip.

to_soundarray(tt=None, fps=None, quantize=False, nbytes=2, buffersize=50000)
Transforms the sound into an array that can be played by pygame or written in a wav file. See AudioClip.preview.
Parameters
  • fps -- Frame rate of the sound for the conversion. 44100 for top quality.
  • nbytes -- Number of bytes to encode the sound: 1 for 8bit sound, 2 for 16bit, 4 for 32bit sound.



write_audiofile(filename, fps=None, nbytes=2, buffersize=2000, codec=None, bitrate=None, ffmpeg_params=None, write_logfile=False, logger='bar')
Writes an audio file from the AudioClip.
Parameters
  • filename -- Name of the output file, as a string or a path-like object.
  • fps -- Frames per second. If not set, it will try default to self.fps if already set, otherwise it will default to 44100.
  • nbytes -- Sample width (set to 2 for 16-bit sound, 4 for 32-bit sound)
  • buffersize -- The sound is not generated all at once, but rather made by bunches of frames (chunks). buffersize is the size of such a chunk. Try varying it if you meet audio problems (but you shouldn't have to). Default to 2000
  • codec -- Which audio codec should be used. If None provided, the codec is determined based on the extension of the filename. Choose 'pcm_s16le' for 16-bit wav and 'pcm_s32le' for 32-bit wav.
  • bitrate -- Audio bitrate, given as a string like '50k', '500k', '3000k'. Will determine the size and quality of the output file. Note that it mainly an indicative goal, the bitrate won't necessarily be the this in the output file.
  • ffmpeg_params -- Any additional parameters you would like to pass, as a list of terms, like ['-option1', 'value1', '-option2', 'value2']
  • write_logfile -- If true, produces a detailed logfile named filename + '.log' when writing the file
  • logger -- Either "bar" for progress bar or None or any Proglog logger.




moviepy.audio.AudioClip.CompositeAudioClip

class moviepy.audio.AudioClip.CompositeAudioClip(clips)
Clip made by composing several AudioClips.

An audio clip made by putting together several audio clips.

Parameters
clips -- List of audio clips, which may start playing at different times or together, depends on their start attributes. If all have their duration attribute set, the duration of the composite clip is computed automatically.

property ends
Returns ending times for all clips in the composition.

frame_function(t)
Renders a frame for the composition for the time t.

property starts
Returns starting times for all clips in the composition.


Functions

concatenate_audioclips <#moviepy.audio.AudioClip.concatenate_audioclips>(clips) Concatenates one AudioClip after another, in the order that are passed to clips parameter.

moviepy.audio.AudioClip.concatenate_audioclips

moviepy.audio.AudioClip.concatenate_audioclips(clips)
Concatenates one AudioClip after another, in the order that are passed to clips parameter.
Parameters
clips -- List of audio clips, which will be played one after other.


moviepy.audio.fx

All the audio effects that can be applied to AudioClip and VideoClip.

Modules

AudioDelay <#module-moviepy.audio.fx.AudioDelay>([offset, n_repeats, decay]) Repeats audio certain number of times at constant intervals multiplying their volume levels using a linear space in the range 1 to decay argument value.
AudioFadeIn <#module-moviepy.audio.fx.AudioFadeIn>(duration) Return an audio (or video) clip that is first mute, then the sound arrives progressively over duration seconds.
AudioFadeOut <#module-moviepy.audio.fx.AudioFadeOut>(duration) Return a sound clip where the sound fades out progressively over duration seconds at the end of the clip.
AudioLoop <#module-moviepy.audio.fx.AudioLoop>([n_loops, duration]) Loops over an audio clip.
AudioNormalize <#module-moviepy.audio.fx.AudioNormalize>() Return a clip whose volume is normalized to 0db.
MultiplyStereoVolume <#module-moviepy.audio.fx.MultiplyStereoVolume>([left, right]) For a stereo audioclip, this function enables to change the volume of the left and right channel separately (with the factors left and right).
MultiplyVolume <#module-moviepy.audio.fx.MultiplyVolume>(factor[, start_time, end_time]) Returns a clip with audio volume multiplied by the value factor.

moviepy.audio.fx.AudioDelay

class moviepy.audio.fx.AudioDelay.AudioDelay(offset: float = 0.2, n_repeats: int = 8, decay: float = 1)
Repeats audio certain number of times at constant intervals multiplying their volume levels using a linear space in the range 1 to decay argument value.
Parameters
  • offset (float, optional) -- Gap between repetitions start times, in seconds.
  • n_repeats (int, optional) -- Number of repetitions (without including the clip itself).
  • decay (float, optional) -- Multiplication factor for the volume level of the last repetition. Each repetition will have a value in the linear function between 1 and this value, increasing or decreasing constantly. Keep in mind that the last repetition will be muted if this is 0, and if is greater than 1, the volume will increase for each repetition.


Examples

from moviepy import *
videoclip = AudioFileClip('myaudio.wav').with_effects([

afx.AudioDelay(offset=.2, n_repeats=10, decayment=.2) ]) # stereo A note frame_function = lambda t: np.array(
[np.sin(440 * 2 * np.pi * t), np.sin(880 * 2 * np.pi * t)] ).T clip = AudioClip(frame_function=frame_function, duration=0.1, fps=44100) clip = clip.with_effects([afx.AudioDelay(offset=.2, n_repeats=11, decay=0)])


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.audio.fx.AudioFadeIn

class moviepy.audio.fx.AudioFadeIn.AudioFadeIn(duration: float)
Return an audio (or video) clip that is first mute, then the sound arrives progressively over duration seconds.
Parameters
duration (float) -- How long does it take for the sound to return to its normal level.

Examples

clip = VideoFileClip("media/chaplin.mp4")
clip.with_effects([afx.AudioFadeIn("00:00:06")])


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.audio.fx.AudioFadeOut

class moviepy.audio.fx.AudioFadeOut.AudioFadeOut(duration: float)
Return a sound clip where the sound fades out progressively over duration seconds at the end of the clip.
Parameters
duration (float) -- How long does it take for the sound to reach the zero level at the end of the clip.

Examples

clip = VideoFileClip("media/chaplin.mp4")
clip.with_effects([afx.AudioFadeOut("00:00:06")])


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.audio.fx.AudioLoop

class moviepy.audio.fx.AudioLoop.AudioLoop(n_loops: int = None, duration: float = None)
Loops over an audio clip.

Returns an audio clip that plays the given clip either n_loops times, or during duration seconds.

Examples

from moviepy import *
videoclip = VideoFileClip('myvideo.mp4')
music = AudioFileClip('music.ogg')
audio = music.with_effects([afx.AudioLoop(duration=videoclip.duration)])
videoclip.with_audio(audio)


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.audio.fx.AudioNormalize

class moviepy.audio.fx.AudioNormalize.AudioNormalize
Return a clip whose volume is normalized to 0db.

Return an audio (or video) clip whose audio volume is normalized so that the maximum volume is at 0db, the maximum achievable volume.

Examples

>>> from moviepy import *
>>> videoclip = VideoFileClip('myvideo.mp4').with_effects([afx.AudioNormalize()])
    
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.audio.fx.MultiplyStereoVolume

class moviepy.audio.fx.MultiplyStereoVolume.MultiplyStereoVolume(left: float = 1, right: float = 1)
For a stereo audioclip, this function enables to change the volume of the left and right channel separately (with the factors left and right). Makes a stereo audio clip in which the volume of left and right is controllable.

Examples

from moviepy import AudioFileClip
music = AudioFileClip('music.ogg')
# mutes left channel
audio_r = music.with_effects([afx.MultiplyStereoVolume(left=0, right=1)])
# halves audio volume
audio_h = music.with_effects([afx.MultiplyStereoVolume(left=0.5, right=0.5)])


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.audio.fx.MultiplyVolume

class moviepy.audio.fx.MultiplyVolume.MultiplyVolume(factor: float, start_time: float = None, end_time: float = None)
Returns a clip with audio volume multiplied by the value factor. Can be applied to both audio and video clips.
Parameters
  • factor (float) -- Volume multiplication factor.
  • start_time (float, optional) -- Time from the beginning of the clip until the volume transformation begins to take effect, in seconds. By default at the beginning.
  • end_time (float, optional) -- Time from the beginning of the clip until the volume transformation ends to take effect, in seconds. By default at the end.


Examples

from moviepy import AudioFileClip
music = AudioFileClip("music.ogg")
# doubles audio volume
doubled_audio_clip = music.with_effects([afx.MultiplyVolume(2)])
# halves audio volume
half_audio_clip = music.with_effects([afx.MultiplyVolume(0.5)])
# silences clip during one second at third
effect = afx.MultiplyVolume(0, start_time=2, end_time=3)
silenced_clip = clip.with_effects([effect])


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.audio.io

Class and methods to read, write, preview audiofiles.

Modules

AudioFileClip <#module-moviepy.audio.io.AudioFileClip> Implements AudioFileClip, a class for audio clips creation using audio files.
ffmpeg_audiowriter <#module-moviepy.audio.io.ffmpeg_audiowriter> MoviePy audio writing with ffmpeg.
ffplay_audiopreviewer <#module-moviepy.audio.io.ffplay_audiopreviewer> MoviePy audio writing with ffmpeg.
readers <#module-moviepy.audio.io.readers> MoviePy audio reading with ffmpeg.

moviepy.audio.io.AudioFileClip

Implements AudioFileClip, a class for audio clips creation using audio files.

Classes

AudioFileClip <#moviepy.audio.io.AudioFileClip.AudioFileClip>(filename[, decode_file, ...]) An audio clip read from a sound file, or an array.

moviepy.audio.io.AudioFileClip.AudioFileClip

class moviepy.audio.io.AudioFileClip.AudioFileClip(filename, decode_file=False, buffersize=200000, nbytes=2, fps=44100, audio_stream_index=0)
An audio clip read from a sound file, or an array. The whole file is not loaded in memory. Instead, only a portion is read and stored in memory. this portion includes frames before and after the last frames read, so that it is fast to read the sound backward and forward.
Parameters
  • filename -- Either a soundfile name (of any extension supported by ffmpeg) as a string or a path-like object, or an array representing a sound. If the soundfile is not a .wav, it will be converted to .wav first, using the fps and bitrate arguments.
  • buffersize -- Size to load in memory (in number of frames)


nbytes
Number of bits per frame of the original audio file.

fps
Number of frames per second in the audio file

buffersize
See Parameters.

audio_stream_index
The index of the audio stream to read from the file.

Lifetime

--------

Note that this creates subprocesses and locks files. If you construct one

of these instances, you must call close() afterwards, or the subresources

will not be cleaned up until the process ends.

Examples

snd = AudioFileClip("song.wav")
snd.close()


close()
Close the internal reader.


moviepy.audio.io.ffmpeg_audiowriter

MoviePy audio writing with ffmpeg.

Classes

FFMPEG_AudioWriter <#moviepy.audio.io.ffmpeg_audiowriter.FFMPEG_AudioWriter>(filename, fps_input[, ...]) A class to write an AudioClip into an audio file.

moviepy.audio.io.ffmpeg_audiowriter.FFMPEG_AudioWriter

class moviepy.audio.io.ffmpeg_audiowriter.FFMPEG_AudioWriter(filename, fps_input, nbytes=2, nchannels=2, codec='libfdk_aac', bitrate=None, input_video=None, logfile=None, ffmpeg_params=None)
A class to write an AudioClip into an audio file.
Parameters
  • filename -- Name of any video or audio file, like video.mp4 or sound.wav etc.
  • size -- Size (width,height) in pixels of the output video.
  • fps_input -- Frames per second of the input audio (given by the AudioClip being written down).
  • nbytes (int, optional) -- Number of bytes per sample. Default is 2 (16-bit audio).
  • nchannels (int, optional) -- Number of audio channels. Default is 2 (stereo).
  • codec (str, optional) -- The codec to use for the output. Default is libfdk_aac.
  • bitrate -- A string indicating the bitrate of the final video. Only relevant for codecs which accept a bitrate.
  • input_video (str, optional) -- Path to an input video file. If provided, the audio will be muxed with this video. If not provided, the output will be audio-only.
  • logfile (file-like object or None, optional) -- A file object where FFMPEG logs will be written. If None, logs are suppressed.
  • ffmpeg_params (list of str, optional) -- Additional FFMPEG command-line parameters to customize the output.


close()
Closes the writer, terminating the subprocess if is still alive.

write_frames(frames_array)
Send the audio frame (a chunck of AudioClip) to ffmpeg for writting


Functions

ffmpeg_audiowrite <#moviepy.audio.io.ffmpeg_audiowriter.ffmpeg_audiowrite>(clip, filename, fps, ...) A function that wraps the FFMPEG_AudioWriter to write an AudioClip to a file.

moviepy.audio.io.ffmpeg_audiowriter.ffmpeg_audiowrite

moviepy.audio.io.ffmpeg_audiowriter.ffmpeg_audiowrite(clip, filename, fps, nbytes, buffersize, codec='libvorbis', bitrate=None, write_logfile=False, ffmpeg_params=None, logger='bar')
A function that wraps the FFMPEG_AudioWriter to write an AudioClip to a file.

moviepy.audio.io.ffplay_audiopreviewer

MoviePy audio writing with ffmpeg.

Classes

FFPLAY_AudioPreviewer <#moviepy.audio.io.ffplay_audiopreviewer.FFPLAY_AudioPreviewer>(fps_input[, nbytes, ...]) A class to preview an AudioClip.

moviepy.audio.io.ffplay_audiopreviewer.FFPLAY_AudioPreviewer

class moviepy.audio.io.ffplay_audiopreviewer.FFPLAY_AudioPreviewer(fps_input, nbytes=2, nchannels=2)
A class to preview an AudioClip.
Parameters
  • fps_input -- Frames per second of the input audio (given by the AudioClip being written down).
  • nbytes -- Number of bytes to encode the sound: 1 for 8bit sound, 2 for 16bit, 4 for 32bit sound. Default is 2 bytes, it's fine.
  • nchannels -- Number of audio channels in the clip. Default to 2 channels.


close()
Closes the writer, terminating the subprocess if is still alive.

write_frames(frames_array)
Send a raw audio frame (a chunck of audio) to ffplay to be played


Functions

ffplay_audiopreview <#moviepy.audio.io.ffplay_audiopreviewer.ffplay_audiopreview>(clip[, fps, buffersize, ...]) A function that wraps the FFPLAY_AudioPreviewer to preview an AudioClip

moviepy.audio.io.ffplay_audiopreviewer.ffplay_audiopreview

moviepy.audio.io.ffplay_audiopreviewer.ffplay_audiopreview(clip, fps=None, buffersize=2000, nbytes=2, audio_flag=None, video_flag=None)
A function that wraps the FFPLAY_AudioPreviewer to preview an AudioClip
Parameters
  • fps -- Frame rate of the sound. 44100 gives top quality, but may cause problems if your computer is not fast enough and your clip is complicated. If the sound jumps during the preview, lower it (11025 is still fine, 5000 is tolerable).
  • buffersize -- The sound is not generated all at once, but rather made by bunches of frames (chunks). buffersize is the size of such a chunk. Try varying it if you meet audio problems (but you shouldn't have to).
  • nbytes -- Number of bytes to encode the sound: 1 for 8bit sound, 2 for 16bit, 4 for 32bit sound. 2 bytes is fine.
  • audio_flag -- Instances of class threading events that are used to synchronize video and audio during VideoClip.preview().
  • video_flag -- Instances of class threading events that are used to synchronize video and audio during VideoClip.preview().



moviepy.audio.io.readers

MoviePy audio reading with ffmpeg.

Classes

FFMPEG_AudioReader <#moviepy.audio.io.readers.FFMPEG_AudioReader>(filename, buffersize[, ...]) A class to read the audio in either video files or audio files using ffmpeg.

moviepy.audio.io.readers.FFMPEG_AudioReader

class moviepy.audio.io.readers.FFMPEG_AudioReader(filename, buffersize, decode_file=False, print_infos=False, fps=44100, nbytes=2, nchannels=2, audio_stream_index=0)
A class to read the audio in either video files or audio files using ffmpeg. ffmpeg will read any audio and transform them into raw data.
Parameters
  • filename -- Name of any video or audio file, like video.mp4 or sound.wav etc.
  • buffersize -- The size of the buffer to use. Should be bigger than the buffer used by write_audiofile
  • print_infos -- Print the ffmpeg infos on the file being read (for debugging)
  • fps -- Desired frames per second in the decoded signal that will be received from ffmpeg
  • nbytes -- Desired number of bytes (1,2,4) in the signal that will be received from ffmpeg
  • audio_stream_index -- The index of the audio stream to read from the file.


buffer_around(frame_number)
Fill the buffer with frames, centered on frame_number if possible.

close()
Closes the reader, terminating the subprocess if is still alive.

get_frame(tt)
Retrieve the audio frame(s) corresponding to the given timestamp(s).
Parameters
numpy.ndarray) (tt (float or) -- The timestamp(s) at which to retrieve the audio frame(s). If tt is a single float value, the frame corresponding to that timestamp is returned. If tt is a NumPy array of timestamps, an array of frames corresponding to each timestamp is returned.


initialize(start_time=0)
Opens the file, creates the pipe.

read_chunk(chunksize)
Read a chunk of audio data from the audio stream.

This method reads a chunk of audio data from the audio stream. The specified number of frames, given by chunksize, is read from the proc stdout. The audio data is returned as a NumPy array, where each row corresponds to a frame and each column corresponds to a channel. If there is not enough audio left to read, the remaining portion is padded with zeros, ensuring that the returned array has the desired length. The pos attribute is updated accordingly.

Parameters
(float) (chunksize) -- The desired number of audio frames to read.


seek(pos)
Read a frame at time t. Note for coders: getting an arbitrary frame in the video with ffmpeg can be painfully slow if some decoding has to be done. This function tries to avoid fectching arbitrary frames whenever possible, by moving between adjacent frames.

skip_chunk(chunksize)
Skip a chunk of audio data by reading and discarding the specified number of frames from the audio stream. The audio stream is read from the proc stdout. After skipping the chunk, the pos attribute is updated accordingly.
Parameters
(int) (chunksize) -- The number of audio frames to skip.



moviepy.audio.tools

Tools to better processing and edition of audio.

Modules

cuts <#module-moviepy.audio.tools.cuts> Cutting utilities working with audio.

moviepy.audio.tools.cuts

Cutting utilities working with audio.

Functions

find_audio_period <#moviepy.audio.tools.cuts.find_audio_period>(clip[, min_time, ...]) Finds the period, in seconds of an audioclip.

moviepy.audio.tools.cuts.find_audio_period

moviepy.audio.tools.cuts.find_audio_period(clip, min_time=0.1, max_time=2, time_resolution=0.01)
Finds the period, in seconds of an audioclip.
Parameters
  • min_time (float, optional) -- Minimum bound for the returned value.
  • max_time (float, optional) -- Maximum bound for the returned value.
  • time_resolution (float, optional) -- Numerical precision.



moviepy.config

Third party programs configuration for MoviePy.

Functions

check <#moviepy.config.check>() Check if moviepy has found the binaries for FFmpeg.
try_cmd <#moviepy.config.try_cmd>(cmd) Verify if the OS support command invocation as expected by moviepy

moviepy.config.check

moviepy.config.check()
Check if moviepy has found the binaries for FFmpeg.

moviepy.config.try_cmd

moviepy.config.try_cmd(cmd)
Verify if the OS support command invocation as expected by moviepy

moviepy.decorators

Decorators used by moviepy.

Functions

convert_parameter_to_seconds <#moviepy.decorators.convert_parameter_to_seconds>(varnames) Converts the specified variables to seconds.
convert_path_to_string <#moviepy.decorators.convert_path_to_string>(varnames) Converts the specified variables to a path string.
preprocess_args <#moviepy.decorators.preprocess_args>(preprocess_func, varnames) Applies preprocess_func to variables in varnames before launching the function.
use_clip_fps_by_default <#moviepy.decorators.use_clip_fps_by_default>(func) Will use clip.fps if no fps=... is provided in kwargs.

moviepy.decorators.convert_parameter_to_seconds

moviepy.decorators.convert_parameter_to_seconds(varnames)
Converts the specified variables to seconds.

moviepy.decorators.convert_path_to_string

moviepy.decorators.convert_path_to_string(varnames)
Converts the specified variables to a path string.

moviepy.decorators.preprocess_args

moviepy.decorators.preprocess_args(preprocess_func, varnames)
Applies preprocess_func to variables in varnames before launching the function.

moviepy.decorators.use_clip_fps_by_default

moviepy.decorators.use_clip_fps_by_default(func)
Will use clip.fps if no fps=... is provided in kwargs.

moviepy.tools

Misc. useful functions that can be used at many places in the program.

Functions

close_all_clips <#moviepy.tools.close_all_clips>([objects, types]) Closes all clips in a context.
compute_position <#moviepy.tools.compute_position>(clip1_size, clip2_size, pos) Return the position to put clip 1 on clip 2 based on both clip size and the position of clip 1, as return by clip1.pos() method
convert_to_seconds <#moviepy.tools.convert_to_seconds>(time) Will convert any time into seconds.
cross_platform_popen_params <#moviepy.tools.cross_platform_popen_params>(popen_params) Wrap with this function a dictionary of subprocess.Popen kwargs and will be ready to work without unexpected behaviours in any platform.
deprecated_version_of <#moviepy.tools.deprecated_version_of>(func, old_name) Indicates that a function is deprecated and has a new name.
ffmpeg_escape_filename <#moviepy.tools.ffmpeg_escape_filename>(filename) Escape a filename that we want to pass to the ffmpeg command line
find_extension <#moviepy.tools.find_extension>(codec) Returns the correspondent file extension for a codec.
no_display_available <#moviepy.tools.no_display_available>() Return True if we determine the host system has no graphical environment.
subprocess_call <#moviepy.tools.subprocess_call>(cmd[, logger]) Executes the given subprocess command.

moviepy.tools.close_all_clips

moviepy.tools.close_all_clips(objects='globals', types=('audio', 'video', 'image'))
Closes all clips in a context.

Follows different strategies retrieving the namespace from which the clips to close will be retrieved depending on the objects argument, and filtering by type of clips depending on the types argument.

Parameters
  • objects (str or dict, optional) -- .INDENT 2.0
  • If is a string an the value is "globals", will close all the clips contained by the globals() namespace.
  • If is a dictionary, the values of the dictionary could be clips to close, useful if you want to use locals().

types (Iterable, optional) -- Set of types of clips to close, being "audio", "video" or "image" the supported values.




moviepy.tools.compute_position

moviepy.tools.compute_position(clip1_size: tuple, clip2_size: tuple, pos: any, relative: bool = False) -> tuple[int, int]
Return the position to put clip 1 on clip 2 based on both clip size and the position of clip 1, as return by clip1.pos() method
Parameters
  • clip1_size (tuple) -- The width and height of clip1 (e.g., (width, height)).
  • clip2_size (tuple) -- The width and height of clip2 (e.g., (width, height)).
  • pos (Any) -- The position of clip1 as returned by the clip1.pos() method.
  • relative (bool) -- Is the position relative (% of clip size), default False.

Returns
A tuple (x, y) representing the top-left corner of clip1 relative to clip2.
Return type
tuple[int, int]

Notes

For more information on pos, see the documentation for VideoClip.with_position.


moviepy.tools.convert_to_seconds

moviepy.tools.convert_to_seconds(time)
Will convert any time into seconds.

If the type of time is not valid, it's returned as is.

Here are the accepted formats:

convert_to_seconds(15.4)   # seconds
15.4
convert_to_seconds((1, 21.5))   # (min,sec)
81.5
convert_to_seconds((1, 1, 2))   # (hr, min, sec)
3662
convert_to_seconds('01:01:33.045')
3693.045
convert_to_seconds('01:01:33,5')    # coma works too
3693.5
convert_to_seconds('1:33,5')    # only minutes and secs
99.5
convert_to_seconds('33.5')      # only secs
33.5



moviepy.tools.cross_platform_popen_params

moviepy.tools.cross_platform_popen_params(popen_params)
Wrap with this function a dictionary of subprocess.Popen kwargs and will be ready to work without unexpected behaviours in any platform. Currently, the implementation will add to them:
creationflags=0x08000000: no extra unwanted window opens on Windows when the child process is created. Only added on Windows.


moviepy.tools.deprecated_version_of

moviepy.tools.deprecated_version_of(func, old_name)
Indicates that a function is deprecated and has a new name.

func is the new function and old_name is the name of the deprecated function.

Returns
A function that does the same thing as func, but with a docstring and a printed message on call which say that the function is deprecated and that you should use func instead.
Return type
deprecated_func

Examples

# The badly named method 'to_file' is replaced by 'write_file'
class Clip:

def write_file(self, some args):
# blablabla Clip.to_file = deprecated_version_of(Clip.write_file, 'to_file')



moviepy.tools.ffmpeg_escape_filename

moviepy.tools.ffmpeg_escape_filename(filename)
Escape a filename that we want to pass to the ffmpeg command line

That will ensure the filename doesn't start with a '-' (which would raise an error)


moviepy.tools.find_extension

moviepy.tools.find_extension(codec)
Returns the correspondent file extension for a codec.
Parameters
codec (str) -- Video or audio codec name.


moviepy.tools.no_display_available

moviepy.tools.no_display_available() -> bool
Return True if we determine the host system has no graphical environment. This is usefull to remove tests requiring display, like preview
..info::
Currently this only works for Linux/BSD systems with X11 or wayland. It probably works for SunOS, AIX and CYGWIN


moviepy.tools.subprocess_call

moviepy.tools.subprocess_call(cmd, logger='bar')
Executes the given subprocess command.

Set logger to None or a custom Proglog logger to avoid printings.


moviepy.version

moviepy.video

Everything about video manipulation.

Modules

VideoClip <#module-moviepy.video.VideoClip> Implements VideoClip (base class for video clips) and its main subclasses:
compositing <#module-moviepy.video.compositing> All for compositing video clips.
fx <#module-moviepy.video.fx> All the visual effects that can be applied to VideoClip.
io <#module-moviepy.video.io> Classes and methods for reading, writing and previewing video files.
tools <#module-moviepy.video.tools>

moviepy.video.VideoClip

Implements VideoClip (base class for video clips) and its main subclasses:

  • Animated clips: VideoFileClip, ImageSequenceClip, BitmapClip
  • Static image clips: ImageClip, ColorClip, TextClip,

Classes

BitmapClip <#moviepy.video.VideoClip.BitmapClip>(bitmap_frames, *[, fps, ...]) Clip made of color bitmaps.
ColorClip <#moviepy.video.VideoClip.ColorClip>(size[, color, is_mask, duration]) An ImageClip showing just one color.
DataVideoClip <#moviepy.video.VideoClip.DataVideoClip>(data, data_to_frame, fps[, ...]) Class of video clips whose successive frames are functions of successive datasets
ImageClip <#moviepy.video.VideoClip.ImageClip>(img[, is_mask, transparent, duration]) Class for non-moving VideoClips.
TextClip <#moviepy.video.VideoClip.TextClip>([font, text, filename, font_size, ...]) Class for autogenerated text clips.
UpdatedVideoClip <#moviepy.video.VideoClip.UpdatedVideoClip>(world[, is_mask, duration]) Class of clips whose frame_function requires some objects to be updated.
VideoClip <#moviepy.video.VideoClip.VideoClip>([frame_function, is_mask, ...]) Base class for video clips.

moviepy.video.VideoClip.BitmapClip

class moviepy.video.VideoClip.BitmapClip(bitmap_frames, *, fps=None, duration=None, color_dict=None, is_mask=False)
Clip made of color bitmaps. Mainly designed for testing purposes.
to_bitmap(color_dict=None)
Returns a valid bitmap list that represents each frame of the clip. If color_dict is not specified, then it will use the same color_dict that was used to create the clip.


moviepy.video.VideoClip.ColorClip

class moviepy.video.VideoClip.ColorClip(size, color=None, is_mask=False, duration=None)
An ImageClip showing just one color.
Parameters
  • size -- Size tuple (width, height) in pixels of the clip.
  • color -- If argument is_mask is False, color indicates the color in RGB of the clip (default is black). If is_mask` is True, color must be a float between 0 and 1 (default is 1)
  • is_mask -- Set to true if the clip will be used as a mask.



moviepy.video.VideoClip.DataVideoClip

class moviepy.video.VideoClip.DataVideoClip(data, data_to_frame, fps, is_mask=False, has_constant_size=True)
Class of video clips whose successive frames are functions of successive datasets
Parameters
  • data -- A list of datasets, each dataset being used for one frame of the clip
  • data_to_frame -- A function d -> video frame, where d is one element of the list data
  • fps -- Number of frames per second in the animation



moviepy.video.VideoClip.ImageClip

class moviepy.video.VideoClip.ImageClip(img, is_mask=False, transparent=True, duration=None)
Class for non-moving VideoClips.

A video clip originating from a picture. This clip will simply display the given picture at all times.

Examples

>>> clip = ImageClip("myHouse.jpeg")
>>> clip = ImageClip( someArray ) # a Numpy array represent
    
Parameters
  • img -- Any picture file (png, tiff, jpeg, etc.) as a string or a path-like object, or any array representing an RGB image (for instance a frame from a VideoClip).
  • is_mask -- Set this parameter to True if the clip is a mask.
  • transparent -- Set this parameter to True (default) if you want the alpha layer of the picture (if it exists) to be used as a mask.
  • duration -- Duration of the clip in seconds. If not provided, the clip will have infinite duration (i.e. it will be displayed until the end of the composition in which it is included).


img
Array representing the image of the clip.

image_transform(image_func, apply_to=None)
Image-transformation filter.

Does the same as VideoClip.image_transform, but for ImageClip the transformed clip is computed once and for all at the beginning, and not for each 'frame'.


time_transform(time_func, apply_to=None, keep_duration=False)
Time-transformation filter.

Applies a transformation to the clip's timeline (see Clip.time_transform).

This method does nothing for ImageClips (but it may affect their masks or their audios). The result is still an ImageClip.


transform(func, apply_to=None, keep_duration=True)
General transformation filter.

Equivalent to VideoClip.transform. The result is no more an ImageClip, it has the class VideoClip (since it may be animated)



moviepy.video.VideoClip.TextClip

class moviepy.video.VideoClip.TextClip(font=None, text=None, filename=None, font_size=None, size=(None, None), margin=(None, None), color='black', bg_color=None, stroke_color=None, stroke_width=0, method='label', text_align='left', horizontal_align='center', vertical_align='center', interline=4, transparent=True, duration=None)
Class for autogenerated text clips.

Creates an ImageClip originating from a script-generated text image.

Parameters
  • font -- Path to the font to use. Must be an OpenType font. If set to None (default) will use Pillow default font
  • text -- A string of the text to write. Can be replaced by argument filename.
  • filename -- The name of a file in which there is the text to write, as a string or a path-like object. Can be provided instead of argument text
  • font_size -- Font size in point. Can be auto-set if method='caption', or if method='label' and size is set.
  • size -- Size of the picture in pixels. Can be auto-set if method='label' and font_size is set, but mandatory if method='caption'. the height can be None for caption if font_size is defined, it will then be auto-determined.
  • margin -- Margin to be added arround the text as a tuple of two (symmetrical) or four (asymmetrical). Either (horizontal, vertical) or (left, top, right, bottom). By default no margin (None, None). This is especially usefull for auto-compute size to give the text some extra room.
  • color -- Color of the text. Default to "black". Can be a RGB (or RGBA if transparent = True) tuple, a color name, or an hexadecimal notation.
  • bg_color -- Color of the background. Default to None for no background. Can be a RGB (or RGBA if transparent = True) tuple, a color name, or an hexadecimal notation.
  • stroke_color -- Color of the stroke (=contour line) of the text. If None, there will be no stroke.
  • stroke_width -- Width of the stroke, in pixels. Must be an int.
  • method -- .INDENT 2.0
Either :
  • 'label' (default), the picture will be autosized so as to fit the text either by auto-computing font size if width is provided or auto-computing width and height if font size is defined
  • 'caption' the text will be drawn in a picture with fixed size provided with the size argument. The text will be wrapped automagically, either by auto-computing font size if width and height are provided or adding line break when necesarry if font size is defined


  • text_align -- center | left | right. Text align similar to css. Default to left.
  • horizontal_align -- center | left | right. Define horizontal align of text bloc in image. Default to center.
  • vertical_align -- center | top | bottom. Define vertical align of text bloc in image. Default to center.
  • interline -- Interline spacing. Default to 4.
  • transparent -- True (default) if you want to take into account the transparency in the image.
  • duration -- Duration of the clip
  • note:: (..) --

    ** About final TextClip size **

    The final TextClip size will be of the absolute maximum height possible for the font and the number of line. It specifically mean that the final height might be a bit bigger than the real text height, i.e, absolute bottom pixel of text - absolute top pixel of text. This is because in a font, some letter go above standard top line (e.g letters with accents), and bellow standard baseline (e.g letters such as p, y, g).

    This notion is known under the name "ascent" and "descent" meaning the highest and lowest pixel above and below the baseline.

    If your first line doesn't have an "accent character" and your last line doesn't have a "descent character", you'll have some "fat" around.





moviepy.video.VideoClip.UpdatedVideoClip

class moviepy.video.VideoClip.UpdatedVideoClip(world, is_mask=False, duration=None)
Class of clips whose frame_function requires some objects to be updated. Particularly practical in science where some algorithm needs to make some steps before a new frame can be generated.

UpdatedVideoClips have the following frame_function:

def frame_function(t):

while self.world.clip_t < t:
world.update() # updates, and increases world.clip_t
return world.to_frame()


Parameters
  • world -- An object with the following attributes: - world.clip_t: the clip's time corresponding to the world's state. - world.update() : update the world's state, (including increasing world.clip_t of one time step). - world.to_frame() : renders a frame depending on the world's state.
  • is_mask -- True if the clip is a WxH mask with values in 0-1
  • duration -- Duration of the clip, in seconds



moviepy.video.VideoClip.VideoClip

class moviepy.video.VideoClip.VideoClip(frame_function=None, is_mask=False, duration=None, has_constant_size=True)
Base class for video clips.

See VideoFileClip, ImageClip etc. for more user-friendly classes.

Parameters
  • is_mask -- True if the clip is going to be used as a mask.
  • duration -- Duration of the clip in seconds. If None we got a clip of infinite duration
  • has_constant_size -- Define if clip size is constant or if it may vary with time. Default to True


size
The size of the clip, (width,height), in pixels.

w, h
The width and height of the clip, in pixels.

is_mask
Boolean set to True if the clip is a mask.

frame_function
A function t-> frame at time t where frame is a w*h*3 RGB array.

mask(default None)
VideoClip mask attached to this clip. If mask is None,
The video clip is fully opaque.


audio(default None)
An AudioClip instance containing the audio of the video clip.

pos
A function t->(x,y) where x,y is the position of the clip when it is composed with other clips. See VideoClip.set_pos for more details

relative_pos
See variable pos.

layer
Indicates which clip is rendered on top when two clips overlap in a CompositeVideoClip. The highest number is rendered on top. Default is 0.

property aspect_ratio
Returns the aspect ratio of the video.

compose_mask(background_mask: ndarray, t: float) -> ndarray
Returns the result of the clip's mask at time t composited on the given background_mask, the position of the clip being given by the clip's pos attribute. Meant for compositing.

(warning: only use this function to blit two masks together, never images)

Parameters
  • background_mask -- The underlying mask onto which the clip mask will be composed.
  • t -- The time position in the clip at which to extract the mask.



compose_on(background: ndarray, t, background_mask: ndarray | None = None) -> Tuple[ndarray, ndarray | None]
Returns the result of the clip's frame at time t on top on the given picture, the position of the clip being given by the clip's pos attribute. Meant for compositing.

If the clip/backgrounds have transparency the transparency will be accounted for.

The return is either a numpy array for image with no transparency or a tuple (image, mask) for image with transparency

Parameters
  • background ((np.ndarray)) -- The background image to apply current clip on top of if the background image is transparent it must be given as a RGBA image
  • t ((float)) -- The time of clip to apply on top of clip
  • background_mask ((np.ndarray|None), default None) -- The background mask to apply current clip on top of if the background image is transparent it must be given as a mask if None, the background is assumed to be fully opaque

Returns
A tuple with the new image and a mask if applicable, or None
Return type
(np.ndarray, np.ndarray|None)


copy()
Mixed copy of the clip.

Returns a shallow copy of the clip whose mask and audio will be shallow copies of the clip's mask and audio if they exist.

This method is intensively used to produce new clips every time there is an outplace transformation of the clip (clip.resize, clip.subclipped, etc.)

Acts like a deepcopy except for the fact that readers and other possible unpickleables objects are not copied.


cropped(x1: int = None, y1: int = None, x2: int = None, y2: int = None, width: int = None, height: int = None, x_center: int = None, y_center: int = None)
Returns a new clip in which just a rectangular subregion of the original clip is conserved. x1,y1 indicates the top left corner and x2,y2 is the lower right corner of the cropped region. All coordinates are in pixels. Float numbers are accepted. For info on the parameters, please see vfx.Crop

display_in_notebook(filetype=None, maxduration=60, t=None, fps=None, rd_kwargs=None, center=True, **html_kwargs)
Displays clip content in an Jupyter Notebook.

Remarks: If your browser doesn't support HTML5, this should warn you. If nothing is displayed, maybe your file or filename is wrong. Important: The media will be physically embedded in the notebook.

Parameters
  • clip (moviepy.Clip.Clip <#moviepy.Clip.Clip>) -- Either the name of a file, or a clip to preview. The clip will actually be written to a file and embedded as if a filename was provided.
  • filetype (str, optional) -- One of "video", "image" or "audio". If None is given, it is determined based on the extension of filename, but this can bug.
  • maxduration (float, optional) -- An error will be raised if the clip's duration is more than the indicated value (in seconds), to avoid spoiling the browser's cache and the RAM.
  • t (float, optional) -- If not None, only the frame at time t will be displayed in the notebook, instead of a video of the clip.
  • fps (int, optional) -- Enables to specify an fps, as required for clips whose fps is unknown.
  • rd_kwargs (dict, optional) -- Keyword arguments for the rendering, like dict(fps=15, bitrate="50k"). Allow you to give some options to the render process. You can, for example, disable the logger bar passing dict(logger=None).
  • center (bool, optional) -- If true (default), the content will be wrapped in a <div align=middle> HTML container, so the content will be displayed at the center.
  • kwargs -- Allow you to give some options, like width=260, etc. When editing looping gifs, a good choice is loop=1, autoplay=1.


Examples

from moviepy import *
# later ...
clip.display_in_notebook(width=360)
clip.audio.display_in_notebook()
clip.write_gif("test.gif")
display_in_notebook('test.gif')
clip.save_frame("first_frame.jpeg")
display_in_notebook("first_frame.jpeg")



fill_array(pre_array, shape=(0, 0))
Fills an array to match the specified shape.

If the pre_array is smaller than the desired shape, the missing rows or columns are added with ones to the bottom or right, respectively, until the shape matches. If the pre_array is larger than the desired shape, the excess rows or columns are cropped from the bottom or right, respectively, until the shape matches.

The resulting array with the filled shape is returned.

Parameters
  • (numpy.ndarray) (pre_array) -- The original array to be filled.
  • (tuple) (shape) -- The desired shape of the resulting array.



property h
Returns the height of the video.

image_transform(image_func, apply_to=None)
Modifies the images of a clip by replacing the frame get_frame(t) by another frame, image_func(get_frame(t)).

property n_frames
Returns the number of frames of the video.

preview(fps=15, audio=True, audio_fps=22050, audio_buffersize=3000, audio_nbytes=2)
Displays the clip in a window, at the given frames per second.

It will avoid that the clip be played faster than normal, but it cannot avoid the clip to be played slower than normal if the computations are complex. In this case, try reducing the fps.

Parameters
  • fps (int, optional)
  • 15. (Number of frames per seconds in the displayed video. Default to)
  • audio (bool, optional)
  • during (True (default) if you want the clip's audio be played)
  • preview. (the)
  • audio_fps (int, optional)
  • sound. (The number of bytes used generating the audio)
  • audio_buffersize (int, optional)
  • sound.
  • audio_nbytes (int, optional)
  • sound.


Examples

from moviepy import *
clip = VideoFileClip("media/chaplin.mp4")
clip.preview(fps=10, audio=False)



resized(new_size=None, height=None, width=None, apply_to_mask=True)
Returns a video clip that is a resized version of the clip. For info on the parameters, please see vfx.Resize

rotated(angle: float, unit: str = 'deg', resample: str = 'bicubic', expand: bool = False, center: tuple = None, translate: tuple = None, bg_color: tuple = None)
Rotates the specified clip by angle degrees (or radians) anticlockwise If the angle is not a multiple of 90 (degrees) or center, translate, and bg_color are not None. For info on the parameters, please see vfx.Rotate

save_frame(filename, t=0, with_mask=True)
Save a clip's frame to an image file.

Saves the frame of clip corresponding to time t in filename. t can be expressed in seconds (15.35), in (min, sec), in (hour, min, sec), or as a string: '01:03:05.35'.

Parameters
  • filename (str) -- Name of the file in which the frame will be stored.
  • t (float or tuple or str, optional) -- Moment of the frame to be saved. As default, the first frame will be saved.
  • with_mask (bool, optional) -- If is True the mask is saved in the alpha layer of the picture (only works with PNGs).



show(t=0, with_mask=True)
Splashes the frame of clip corresponding to time t.
Parameters
  • t (float or tuple or str, optional)
  • display. (Time in seconds of the frame to)
  • with_mask (bool, optional)
  • without (False if the clip has a mask but you want to see the clip)
  • mask. (the)


Examples

from moviepy import *
clip = VideoFileClip("media/chaplin.mp4")
clip.show(t=4)



to_ImageClip(t=0, with_mask=True, duration=None)
Returns an ImageClip made out of the clip's frame at time t, which can be expressed in seconds (15.35), in (min, sec), in (hour, min, sec), or as a string: '01:03:05.35'.

to_RGB()
Return a non-mask video clip made from the mask video clip.

to_mask(canal=0)
Return a mask a video clip made from the clip.

property w
Returns the width of the video.

with_audio(audioclip)
Attach an AudioClip to the VideoClip.

Returns a copy of the VideoClip instance, with the audio attribute set to audio, which must be an AudioClip instance.


with_background_color(size=None, color=(0, 0, 0), pos=None, opacity=None)
Place the clip on a colored background.

Returns a clip made of the current clip overlaid on a color clip of a possibly bigger size. Can serve to flatten transparent clips.

Parameters
  • size -- Size (width, height) in pixels of the final clip. By default it will be the size of the current clip.
  • color -- Background color of the final clip ([R,G,B]).
  • pos -- Position of the clip in the final clip. 'center' is the default
  • opacity -- Parameter in 0..1 indicating the opacity of the colored background.



with_effects_on_subclip(effects: List[Effect <#moviepy.Effect.Effect>], start_time=0, end_time=None, **kwargs)
Apply a transformation to a part of the clip.

Returns a new clip in which the function fun (clip->clip) has been applied to the subclip between times start_time and end_time (in seconds).

Examples

# The scene between times t=3s and t=6s in ``clip`` will be
# be played twice slower in ``new_clip``
new_clip = clip.with_sub_effect(MultiplySpeed(0.5), 3, 6)



with_layer_index(index)
Set the clip's layer in compositions. Clips with a greater layer attribute will be displayed on top of others.

Note: Only has effect when the clip is used in a CompositeVideoClip.


with_mask(mask: VideoClip <#moviepy.video.VideoClip.VideoClip> | str = 'auto')
Set the clip's mask.

Returns a copy of the VideoClip with the mask attribute set to mask, which must be a greyscale (values in 0-1) VideoClip.

Parameters
mask (Union["VideoClip", str], optional) -- The mask to apply to the clip. If set to "auto", a default mask will be generated: - If the clip has a constant size, a solid mask with a value of 1.0 will be created. - Otherwise, a dynamic solid mask will be created based on the frame size.


with_opacity(opacity)
Set the opacity/transparency level of the clip.

Returns a semi-transparent copy of the clip where the mask is multiplied by op (any float, normally between 0 and 1).


with_position(pos, relative=False)
Set the clip's position in compositions.

Sets the position that the clip will have when included in compositions. The argument pos can be either a couple (x,y) or a function t-> (x,y). x and y mark the location of the top left corner of the clip, and can be of several types.

Examples

clip.with_position((45,150)) # x=45, y=150
# clip horizontally centered, at the top of the picture
clip.with_position(("center","top"))
# clip is at 40% of the width, 70% of the height:
clip.with_position((0.4,0.7), relative=True)
# clip's position is horizontally centered, and moving up !
clip.with_position(lambda t: ('center', 50+t))



with_updated_frame_function(frame_function: Callable[[float], ndarray])
Change the clip's get_frame.

Returns a copy of the VideoClip instance, with the frame_function attribute set to mf.


without_audio()
Remove the clip's audio.

Return a copy of the clip with audio set to None.


without_mask()
Remove the clip's mask.

write_gif(filename, fps=None, loop=0, logger='bar')
Write the VideoClip to a GIF file.

Converts a VideoClip into an animated GIF using imageio

Parameters
  • filename -- Name of the resulting gif file, as a string or a path-like object.
  • fps -- Number of frames per second (see note below). If it isn't provided, then the function will look for the clip's fps attribute (VideoFileClip, for instance, have one).
  • loop (int, optional) -- Repeat the clip using loop iterations in the resulting GIF.
  • logger -- Either "bar" for progress bar or None or any Proglog logger.


Notes

The gif will be playing the clip in real time (you can only change the frame rate). If you want the gif to be played slower than the clip you will use

# slow down clip 50% and make it a gif
myClip.multiply_speed(0.5).to_gif('myClip.gif')



write_images_sequence(name_format, fps=None, with_mask=True, logger='bar')
Writes the videoclip to a sequence of image files.
Parameters
  • name_format -- A filename specifying the numerotation format and extension of the pictures. For instance "frame%03d.png" for filenames indexed with 3 digits and PNG format. Also possible: "some_folder/frame%04d.jpeg", etc.
  • fps -- Number of frames per second to consider when writing the clip. If not specified, the clip's fps attribute will be used if it has one.
  • with_mask -- will save the clip's mask (if any) as an alpha canal (PNGs only).
  • logger -- Either "bar" for progress bar or None or any Proglog logger.

Returns
A list of all the files generated.
Return type
names_list

Notes

The resulting image sequence can be read using e.g. the class ImageSequenceClip.


write_videofile(filename, fps=None, codec=None, bitrate=None, audio=True, audio_fps=44100, preset='medium', audio_nbytes=4, audio_codec=None, audio_bitrate=None, audio_bufsize=2000, temp_audiofile=None, temp_audiofile_path='', remove_temp=True, write_logfile=False, threads=None, ffmpeg_params=None, logger='bar', pixel_format=None)
Write the clip to a videofile.
Parameters
  • filename -- Name of the video file to write in, as a string or a path-like object. The extension must correspond to the "codec" used (see below), or simply be '.avi' (which will work with any codec).
  • fps -- Number of frames per second in the resulting video file. If None is provided, and the clip has an fps attribute, this fps will be used.
  • codec --

    Codec to use for image encoding. Can be any codec supported by ffmpeg. If the filename is has extension '.mp4', '.ogv', '.webm', the codec will be set accordingly, but you can still set it if you don't like the default. For other extensions, the output filename must be set accordingly.

    Some examples of codecs are:

  • 'libx264' (default codec for file extension .mp4) makes well-compressed videos (quality tunable using 'bitrate').
  • 'mpeg4' (other codec for extension .mp4) can be an alternative to 'libx264', and produces higher quality videos by default.
  • 'rawvideo' (use file extension .avi) will produce a video of perfect quality, of possibly very huge size.
  • png (use file extension .avi) will produce a video of perfect quality, of smaller size than with rawvideo.
  • 'libvorbis' (use file extension .ogv) is a nice video format, which is completely free/ open source. However not everyone has the codecs installed by default on their machine.
  • 'libvpx' (use file extension .webm) is tiny a video format well indicated for web videos (with HTML5). Open source.

  • audio -- Either True, False, or a file name. If True and the clip has an audio clip attached, this audio clip will be incorporated as a soundtrack in the movie. If audio is the name of an audio file, this audio file will be incorporated as a soundtrack in the movie.
  • audio_fps -- frame rate to use when generating the sound.
  • temp_audiofile -- the name of the temporary audiofile, as a string or path-like object, to be created and then used to write the complete video, if any.
  • temp_audiofile_path -- the location that the temporary audiofile is placed, as a string or path-like object. Defaults to the current working directory.
  • audio_codec -- Which audio codec should be used. Examples are 'libmp3lame' for '.mp3', 'libvorbis' for 'ogg', 'libfdk_aac':'m4a', 'pcm_s16le' for 16-bit wav and 'pcm_s32le' for 32-bit wav. Default is 'libmp3lame', unless the video extension is 'ogv' or 'webm', at which case the default is 'libvorbis'.
  • audio_bitrate -- Audio bitrate, given as a string like '50k', '500k', '3000k'. Will determine the size/quality of audio in the output file. Note that it mainly an indicative goal, the bitrate won't necessarily be the this in the final file.
  • preset -- Sets the time that FFMPEG will spend optimizing the compression. Choices are: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo. Note that this does not impact the quality of the video, only the size of the video file. So choose ultrafast when you are in a hurry and file size does not matter.
  • threads -- Number of threads to use for ffmpeg. Can speed up the writing of the video on multicore computers.
  • ffmpeg_params -- Any additional ffmpeg parameters you would like to pass, as a list of terms, like ['-option1', 'value1', '-option2', 'value2'].
  • write_logfile -- If true, will write log files for the audio and the video. These will be files ending with '.log' with the name of the output file in them.
  • logger -- Either "bar" for progress bar or None or any Proglog logger.
  • pixel_format -- Pixel format for the output video file.


Examples

from moviepy import VideoFileClip
clip = VideoFileClip("myvideo.mp4").subclipped(100,120)
clip.write_videofile("my_new_video.mp4")
clip.close()




moviepy.video.compositing

All for compositing video clips.

Modules

CompositeVideoClip <#module-moviepy.video.compositing.CompositeVideoClip> Main video composition interface of MoviePy.

moviepy.video.compositing.CompositeVideoClip

Main video composition interface of MoviePy.

Classes

CompositeVideoClip <#moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip>(clips[, size, bg_color, ...]) A VideoClip made of other videoclips displayed together.

moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip

class moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip(clips, size=None, bg_color=(0, 0, 0), use_bgclip=False, is_mask=False, memoize_mask=True)
A VideoClip made of other videoclips displayed together. This is the base class for most compositions.
Parameters
  • size -- The size (width, height) of the final clip.
  • clips --

    A list of videoclips.

    Clips with a higher layer attribute will be displayed on top of other clips in a lower layer. If two or more clips share the same layer, then the one appearing latest in clips will be displayed on top (i.e. it has the higher layer).

    For each clip:

The attribute pos determines where the clip is placed.
See VideoClip.set_pos

The mask of the clip determines which parts are visible.

Finally, if all the clips in the list have their duration attribute set, then the duration of the composite video clip is computed automatically

  • bg_color -- Color for the unmasked and unfilled regions. Set to None for these regions to be transparent (will be slower). Default is black (0, 0, 0).
  • use_bgclip -- Set to True if the first clip in the list should be used as the 'background' on which all other clips are blitted. That first clip must have the same size as the final clip. If it has no transparency, the final clip will have no mask.
  • is_mask -- Set to True if the composite clip is a mask.
  • memoize_mask -- Set to True if the mask of the composite clip should be memoized during frame generation. This is useful for performances in speed with the trafe-off beeing a larger memory usage. If set to False, the mask will be recomputed at each frame generation. Default is True.


The clip with the highest FPS will be the FPS of the composite clip.

close()
Closes the instance, releasing all the resources.

frame_function(t)
The clips playing at time t are blitted over one another.

playing_clips(t=0)
Returns a list of the clips in the composite clips that are actually playing at the given time t.


Functions

clips_array <#moviepy.video.compositing.CompositeVideoClip.clips_array>(array[, rows_widths, ...]) Given a matrix whose rows are clips, creates a CompositeVideoClip where all clips are placed side by side horizontally for each clip in each row and one row on top of the other for each row.
concatenate_videoclips <#moviepy.video.compositing.CompositeVideoClip.concatenate_videoclips>(clips[, method, ...]) Concatenates several video clips.

moviepy.video.compositing.CompositeVideoClip.clips_array

moviepy.video.compositing.CompositeVideoClip.clips_array(array, rows_widths=None, cols_heights=None, bg_color=None)
Given a matrix whose rows are clips, creates a CompositeVideoClip where all clips are placed side by side horizontally for each clip in each row and one row on top of the other for each row. So given next matrix of clips with same size:

`python clips_array([[clip1, clip2, clip3], [clip4, clip5, clip6]]) `

the result will be a CompositeVideoClip with a layout displayed like:

` ┏━━━━━━━┳━━━━━━━┳━━━━━━━┓ ┃ ┃ ┃ ┃ ┃ clip1 ┃ clip2 ┃ clip3 ┃ ┃ ┃ ┃ ┃ ┣━━━━━━━╋━━━━━━━╋━━━━━━━┫ ┃ ┃ ┃ ┃ ┃ clip4 ┃ clip5 ┃ clip6 ┃ ┃ ┃ ┃ ┃ ┗━━━━━━━┻━━━━━━━┻━━━━━━━┛ `

If some clips doesn't fulfill the space required by the rows or columns in which are placed, that space will be filled by the color defined in bg_color.

array
Matrix of clips included in the returned composited video clip.
rows_widths
Widths of the different rows in pixels. If None, is set automatically.
cols_heights
Heights of the different columns in pixels. If None, is set automatically.
bg_color
Fill color for the masked and unfilled regions. Set to None for these regions to be transparent (processing will be slower).


moviepy.video.compositing.CompositeVideoClip.concatenate_videoclips

moviepy.video.compositing.CompositeVideoClip.concatenate_videoclips(clips, method='chain', transition=None, bg_color=None, is_mask=False, padding=0)
Concatenates several video clips.

Returns a video clip made by clip by concatenating several video clips. (Concatenated means that they will be played one after another).

There are two methods:

  • method="chain": will produce a clip that simply outputs the frames of the successive clips, without any correction if they are not of the same size of anything. If none of the clips have masks the resulting clip has no mask, else the mask is a concatenation of masks (using completely opaque for clips that don't have masks, obviously). If you have clips of different size and you want to write directly the result of the concatenation to a file, use the method "compose" instead.
  • method="compose", if the clips do not have the same resolution, the final resolution will be such that no clip has to be resized. As a consequence the final clip has the height of the highest clip and the width of the widest clip of the list. All the clips with smaller dimensions will appear centered. The border will be transparent if mask=True, else it will be of the color specified by bg_color.

The clip with the highest FPS will be the FPS of the result clip.

Parameters
  • clips -- A list of video clips which must all have their duration attributes set.
  • method -- "chain" or "compose": see above.
  • transition -- A clip that will be played between each two clips of the list.
  • bg_color -- Only for method='compose'. Color of the background. Set to None for a transparent clip
  • padding -- Only for method='compose'. Duration during two consecutive clips. Note that for negative padding, a clip will partly play at the same time as the clip it follows (negative padding is cool for clips who fade in on one another). A non-null padding automatically sets the method to compose.



moviepy.video.fx

All the visual effects that can be applied to VideoClip.

Modules

AccelDecel <#module-moviepy.video.fx.AccelDecel>([new_duration, abruptness, soonness]) Accelerates and decelerates a clip, useful for GIF making.
BlackAndWhite <#module-moviepy.video.fx.BlackAndWhite>([RGB, preserve_luminosity]) Desaturates the picture, makes it black and white.
Blink <#module-moviepy.video.fx.Blink>(duration_on, duration_off) Makes the clip blink.
Crop <#module-moviepy.video.fx.Crop>([x1, y1, x2, y2, width, height, ...]) Effect to crop a clip to get a new clip in which just a rectangular subregion of the original clip is conserved.
CrossFadeIn <#module-moviepy.video.fx.CrossFadeIn>(duration) Makes the clip appear progressively, over duration seconds.
CrossFadeOut <#module-moviepy.video.fx.CrossFadeOut>(duration) Makes the clip disappear progressively, over duration seconds.
EvenSize <#module-moviepy.video.fx.EvenSize>() Crops the clip to make dimensions even.
FadeIn <#module-moviepy.video.fx.FadeIn>(duration[, initial_color]) Makes the clip progressively appear from some color (black by default), over duration seconds at the beginning of the clip.
FadeOut <#module-moviepy.video.fx.FadeOut>(duration[, final_color]) Makes the clip progressively fade to some color (black by default), over duration seconds at the end of the clip.
Freeze <#module-moviepy.video.fx.Freeze>([t, freeze_duration, total_duration, ...]) Momentarily freeze the clip at time t.
FreezeRegion <#module-moviepy.video.fx.FreezeRegion>([t, region, outside_region, mask]) Freezes one region of the clip while the rest remains animated.
GammaCorrection <#module-moviepy.video.fx.GammaCorrection>(gamma) Gamma-correction of a video clip.
HeadBlur <#module-moviepy.video.fx.HeadBlur>(fx, fy, radius[, intensity]) Returns a filter that will blur a moving part (a head ?) of the frames.
InvertColors <#module-moviepy.video.fx.InvertColors>() Returns the color-inversed clip.
Loop <#module-moviepy.video.fx.Loop>([n, duration]) Returns a clip that plays the current clip in an infinite loop.
LumContrast <#module-moviepy.video.fx.LumContrast>([lum, contrast, contrast_threshold]) Luminosity-contrast correction of a clip.
MakeLoopable <#module-moviepy.video.fx.MakeLoopable>(overlap_duration) Makes the clip fade in progressively at its own end, this way it can be looped indefinitely.
Margin <#module-moviepy.video.fx.Margin>([margin_size, left, right, top, ...]) Draws an external margin all around the frame.
MaskColor <#module-moviepy.video.fx.MaskColor>([color, threshold, stiffness]) Returns a new clip with a mask for transparency where the original clip is of the given color.
MasksAnd <#module-moviepy.video.fx.MasksAnd>(other_clip) Returns the logical 'and' (minimum pixel color values) between two masks.
MasksOr <#module-moviepy.video.fx.MasksOr>(other_clip) Returns the logical 'or' (maximum pixel color values) between two masks.
MirrorX <#module-moviepy.video.fx.MirrorX>([apply_to]) Flips the clip horizontally (and its mask too, by default).
MirrorY <#module-moviepy.video.fx.MirrorY>([apply_to]) Flips the clip vertically (and its mask too, by default).
MultiplyColor <#module-moviepy.video.fx.MultiplyColor>(factor) Multiplies the clip's colors by the given factor, can be used to decrease or increase the clip's brightness (is that the right word ?)
MultiplySpeed <#module-moviepy.video.fx.MultiplySpeed>([factor, final_duration]) Returns a clip playing the current clip but at a speed multiplied by factor.
Painting <#module-moviepy.video.fx.Painting>([saturation, black]) Transforms any photo into some kind of painting.
Resize <#module-moviepy.video.fx.Resize>([new_size, height, width, apply_to_mask]) Effect returning a video clip that is a resized version of the clip.
Rotate <#module-moviepy.video.fx.Rotate>(angle[, unit, resample, expand, ...]) Rotates the specified clip by angle degrees (or radians) anticlockwise If the angle is not a multiple of 90 (degrees) or center, translate, and bg_color are not None, there will be black borders.
Scroll <#module-moviepy.video.fx.Scroll>([w, h, x_speed, y_speed, x_start, ...]) Effect that scrolls horizontally or vertically a clip, e.g. to make end credits.
SlideIn <#module-moviepy.video.fx.SlideIn>(duration, side) Makes the clip arrive from one side of the screen.
SlideOut <#module-moviepy.video.fx.SlideOut>(duration, side) Makes the clip goes away by one side of the screen.
SuperSample <#module-moviepy.video.fx.SuperSample>(d, n_frames) Replaces each frame at time t by the mean of n_frames equally spaced frames taken in the interval [t-d, t+d].
TimeMirror <#module-moviepy.video.fx.TimeMirror>() Returns a clip that plays the current clip backwards.
TimeSymmetrize <#module-moviepy.video.fx.TimeSymmetrize>() Returns a clip that plays the current clip once forwards and then once backwards.

moviepy.video.fx.AccelDecel

class moviepy.video.fx.AccelDecel.AccelDecel(new_duration: float = None, abruptness: float = 1.0, soonness: float = 1.0)
Accelerates and decelerates a clip, useful for GIF making.
Parameters
  • new_duration (float) -- Duration for the new transformed clip. If None, will be that of the current clip.
  • abruptness (float) --

    Slope shape in the acceleration-deceleration function. It will depend on the value of the parameter:

  • -1 < abruptness < 0: speed up, down, up.
  • abruptness == 0: no effect.
  • abruptness > 0: speed down, up, down.

soonness (float) -- For positive abruptness, determines how soon the transformation occurs. Should be a positive number.

Raises
ValueError -- When sooness argument is lower than 0.

Examples

The following graphs show functions generated by different combinations of arguments, where the value of the slopes represents the speed of the videos generated, being the linear function (in red) a combination that does not produce any transformation. [image: acced_decel FX parameters combinations] [image]

apply(clip)
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.BlackAndWhite

class moviepy.video.fx.BlackAndWhite.BlackAndWhite(RGB: str = None, preserve_luminosity: bool = True)
Desaturates the picture, makes it black and white. Parameter RGB allows to set weights for the different color channels. If RBG is 'CRT_phosphor' a special set of values is used. preserve_luminosity maintains the sum of RGB to 1.
apply(clip)
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



class moviepy.video.fx.Blink.Blink(duration_on: float, duration_off: float)
Makes the clip blink. At each blink it will be displayed duration_on seconds and disappear duration_off seconds. Will only work in composite clips.
apply(clip)
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.Crop

class moviepy.video.fx.Crop.Crop(x1: int = None, y1: int = None, x2: int = None, y2: int = None, width: int = None, height: int = None, x_center: int = None, y_center: int = None)
Effect to crop a clip to get a new clip in which just a rectangular subregion of the original clip is conserved. x1,y1 indicates the top left corner and x2,y2 is the lower right corner of the cropped region. All coordinates are in pixels. Float numbers are accepted.

To crop an arbitrary rectangle:

>>> Crop(x1=50, y1=60, x2=460, y2=275)
    

Only remove the part above y=30:

>>> Crop(y1=30)
    

Crop a rectangle that starts 10 pixels left and is 200px wide

>>> Crop(x1=10, width=200)
    

Crop a rectangle centered in x,y=(300,400), width=50, height=150 :

>>> Crop(x_center=300, y_center=400, width=50, height=150)
    

Any combination of the above should work, like for this rectangle centered in x=300, with explicit y-boundaries:

>>> Crop(x_center=300, width=400, y1=100, y2=600)
    
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.CrossFadeIn

class moviepy.video.fx.CrossFadeIn.CrossFadeIn(duration: float)
Makes the clip appear progressively, over duration seconds. Only works when the clip is included in a CompositeVideoClip.
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.CrossFadeOut

class moviepy.video.fx.CrossFadeOut.CrossFadeOut(duration: float)
Makes the clip disappear progressively, over duration seconds. Only works when the clip is included in a CompositeVideoClip.
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.EvenSize

class moviepy.video.fx.EvenSize.EvenSize
Crops the clip to make dimensions even.
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.FadeIn

class moviepy.video.fx.FadeIn.FadeIn(duration: float, initial_color: list = None)
Makes the clip progressively appear from some color (black by default), over duration seconds at the beginning of the clip. Can be used for masks too, where the initial color must be a number between 0 and 1.

For cross-fading (progressive appearance or disappearance of a clip over another clip, see CrossFadeIn

apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.FadeOut

class moviepy.video.fx.FadeOut.FadeOut(duration: float, final_color: list = None)
Makes the clip progressively fade to some color (black by default), over duration seconds at the end of the clip. Can be used for masks too, where the final color must be a number between 0 and 1.

For cross-fading (progressive appearance or disappearance of a clip over another clip), see CrossFadeOut

apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.Freeze

class moviepy.video.fx.Freeze.Freeze(t: float = 0, freeze_duration: float = None, total_duration: float = None, padding_end: float = 0, update_start_end: bool = True)
Momentarily freeze the clip at time t.

Set t='end' to freeze the clip at the end (actually it will freeze on the frame at time clip.duration - padding_end seconds - 1 / clip_fps). With duration you can specify the duration of the freeze. With total_duration you can specify the total duration of the clip and the freeze (i.e. the duration of the freeze is automatically computed). One of them must be provided.

With update_start_end you can define if the effect must preserve and/or update start and end properties of the original clip

apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.FreezeRegion

class moviepy.video.fx.FreezeRegion.FreezeRegion(t: float = 0, region: tuple = None, outside_region: tuple = None, mask: Clip <#moviepy.Clip.Clip> = None)
Freezes one region of the clip while the rest remains animated.

You can choose one of three methods by providing either region, outside_region, or mask.

Parameters
  • t (float) -- Time at which to freeze the freezed region.
  • region (tuple) -- A tuple (x1, y1, x2, y2) defining the region of the screen (in pixels) which will be freezed. You can provide outside_region or mask instead.
  • outside_region (tuple) -- A tuple (x1, y1, x2, y2) defining the region of the screen (in pixels) which will be the only non-freezed region.
  • mask (moviepy.Clip.Clip <#moviepy.Clip.Clip>) -- If not None, will overlay a freezed version of the clip on the current clip, with the provided mask. In other words, the "visible" pixels in the mask indicate the freezed region in the final picture.


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.GammaCorrection

class moviepy.video.fx.GammaCorrection.GammaCorrection(gamma: float)
Gamma-correction of a video clip.
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.HeadBlur

class moviepy.video.fx.HeadBlur.HeadBlur(fx: callable, fy: callable, radius: float, intensity: float = None)
Returns a filter that will blur a moving part (a head ?) of the frames.

The position of the blur at time t is defined by (fx(t), fy(t)), the radius of the blurring by radius and the intensity of the blurring by intensity.

apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.InvertColors

class moviepy.video.fx.InvertColors.InvertColors
Returns the color-inversed clip.

The values of all pixels are replaced with (255-v) or (1-v) for masks Black becomes white, green becomes purple, etc.

apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.Loop

class moviepy.video.fx.Loop.Loop(n: int = None, duration: float = None)
Returns a clip that plays the current clip in an infinite loop. Ideal for clips coming from GIFs.
Parameters
  • n (int) -- Number of times the clip should be played. If None the the clip will loop indefinitely (i.e. with no set duration).
  • duration (float) -- Total duration of the clip. Can be specified instead of n.


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.LumContrast

class moviepy.video.fx.LumContrast.LumContrast(lum: float = 0, contrast: float = 0, contrast_threshold: float = 127)
Luminosity-contrast correction of a clip.
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.MakeLoopable

class moviepy.video.fx.MakeLoopable.MakeLoopable(overlap_duration: float)
Makes the clip fade in progressively at its own end, this way it can be looped indefinitely.
Parameters
overlap_duration (float) -- Duration of the fade-in (in seconds).

apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.Margin

class moviepy.video.fx.Margin.Margin(margin_size: int = None, left: int = 0, right: int = 0, top: int = 0, bottom: int = 0, color: tuple = (0, 0, 0), opacity: float = 1.0)
Draws an external margin all around the frame.
Parameters
  • margin_size (int, optional) -- If not None, then the new clip has a margin size of size margin_size in pixels on the left, right, top, and bottom.
  • left (int, optional) -- If margin_size=None, margin size for the new clip in left direction.
  • right (int, optional) -- If margin_size=None, margin size for the new clip in right direction.
  • top (int, optional) -- If margin_size=None, margin size for the new clip in top direction.
  • bottom (int, optional) -- If margin_size=None, margin size for the new clip in bottom direction.
  • color (tuple, optional) -- Color of the margin.
  • opacity (float, optional) -- Opacity of the margin. Setting this value to 0 yields transparent margins.


add_margin(clip: Clip <#moviepy.Clip.Clip>)
Add margins to the clip.

apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.MaskColor

class moviepy.video.fx.MaskColor.MaskColor(color: tuple = (0, 0, 0), threshold: float = 0, stiffness: float = 1)
Returns a new clip with a mask for transparency where the original clip is of the given color.

You can also have a "progressive" mask by specifying a non-null distance threshold threshold. In this case, if the distance between a pixel and the given color is d, the transparency will be

d**stiffness / (threshold**stiffness + d**stiffness)

which is 1 when d>>threshold and 0 for d<<threshold, the stiffness of the effect being parametrized by stiffness

apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.MasksAnd

class moviepy.video.fx.MasksAnd.MasksAnd(other_clip: Clip <#moviepy.Clip.Clip> | ndarray)
Returns the logical 'and' (minimum pixel color values) between two masks.

The result has the duration of the clip to which has been applied, if it has any.

Parameters
np.ndarray (other_clip ImageClip or) -- Clip used to mask the original clip.

Examples

clip = ColorClip(color=(255, 0, 0), size=(1, 1))      # red
mask = ColorClip(color=(0, 255, 0), size=(1, 1))      # green
masked_clip = clip.with_effects([vfx.MasksAnd(mask)]) # black
masked_clip.get_frame(0)
[[[0 0 0]]]


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.MasksOr

class moviepy.video.fx.MasksOr.MasksOr(other_clip: Clip <#moviepy.Clip.Clip> | ndarray)
Returns the logical 'or' (maximum pixel color values) between two masks.

The result has the duration of the clip to which has been applied, if it has any.

Parameters
np.ndarray (other_clip ImageClip or) -- Clip used to mask the original clip.

Examples

clip = ColorClip(color=(255, 0, 0), size=(1, 1))     # red
mask = ColorClip(color=(0, 255, 0), size=(1, 1))     # green
masked_clip = clip.with_effects([vfx.MasksOr(mask)]) # yellow
masked_clip.get_frame(0)
[[[255 255   0]]]


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.MirrorX

class moviepy.video.fx.MirrorX.MirrorX(apply_to: List | str = 'mask')
Flips the clip horizontally (and its mask too, by default).
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.MirrorY

class moviepy.video.fx.MirrorY.MirrorY(apply_to: List | str = 'mask')
Flips the clip vertically (and its mask too, by default).
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.MultiplyColor

class moviepy.video.fx.MultiplyColor.MultiplyColor(factor: float)
Multiplies the clip's colors by the given factor, can be used to decrease or increase the clip's brightness (is that the right word ?)
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.MultiplySpeed

class moviepy.video.fx.MultiplySpeed.MultiplySpeed(factor: float = None, final_duration: float = None)
Returns a clip playing the current clip but at a speed multiplied by factor.

Instead of factor one can indicate the desired final_duration of the clip, and the factor will be automatically computed. The same effect is applied to the clip's audio and mask if any.

apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.Painting

class moviepy.video.fx.Painting.Painting(saturation: float = 1.4, black: float = 0.006)
Transforms any photo into some kind of painting.

Transforms any photo into some kind of painting. Saturation tells at which point the colors of the result should be flashy. black gives the amount of black lines wanted.

np_image : a numpy image

apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.


to_painting(np_image, saturation=1.4, black=0.006)
Transforms any photo into some kind of painting.

Transforms any photo into some kind of painting. Saturation tells at which point the colors of the result should be flashy. black gives the amount of black lines wanted.

np_image : a numpy image



moviepy.video.fx.Resize

class moviepy.video.fx.Resize.Resize(new_size: tuple | float | callable = None, height: int = None, width: int = None, apply_to_mask: bool = True)
Effect returning a video clip that is a resized version of the clip.
Parameters
  • new_size (tuple or float or function, optional) -- Can be either - (width, height) in pixels or a float representing - A scaling factor, like 0.5. - A function of time returning one of these.
  • height (int, optional) -- Height of the new clip in pixels. The width is then computed so that the width/height ratio is conserved.
  • width (int, optional) -- Width of the new clip in pixels. The height is then computed so that the width/height ratio is conserved.


Examples

clip.with_effects([vfx.Resize((460,720))]) # New resolution: (460,720)
clip.with_effects([vfx.Resize(0.6)]) # width and height multiplied by 0.6
clip.with_effects([vfx.Resize(width=800)]) # height computed automatically.
clip.with_effects([vfx.Resize(lambda t : 1+0.02*t)]) # slow clip swelling


apply(clip)
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.


resizer(pic, new_size)
Resize the image using openCV.


moviepy.video.fx.Rotate

class moviepy.video.fx.Rotate.Rotate(angle: float, unit: str = 'deg', resample: str = 'bicubic', expand: bool = True, center: tuple = None, translate: tuple = None, bg_color: tuple = None)
Rotates the specified clip by angle degrees (or radians) anticlockwise If the angle is not a multiple of 90 (degrees) or center, translate, and bg_color are not None, there will be black borders. You can make them transparent with:

>>> new_clip = clip.with_mask().rotate(72)
    
Parameters
  • clip (VideoClip <#moviepy.video.VideoClip.VideoClip>)
  • clip. (A video)
  • angle (float)
  • rotation. (Either a value or a function angle(t) representing the angle of)
  • unit (str, optional)
  • radians). (Unit of parameter angle (either "deg" for degrees or "rad" for)
  • resample (str, optional)
  • "nearest" (An optional resampling filter. One of)
  • "bilinear"
  • "bicubic". (or)
  • expand (bool, optional)
  • true (If)
  • the (expands the output image to make it large enough to hold)
  • omitted (entire rotated image. If false or)
  • same (make the output image the)
  • image. (size as the input)
  • translate (tuple, optional)
  • 2-tuple). (An optional post-rotate translation (a)
  • center (tuple, optional)
  • corner. (Optional center of rotation (a 2-tuple). Origin is the upper left)
  • bg_color (tuple, optional)
  • if (An optional color for area outside the rotated image. Only has effect)
  • true. (expand is)


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.


rotate_frame(frame: ndarray, angle: float, resample: int, expand: bool, center: tuple | None, translate: tuple | None, bg_color: tuple | None) -> ndarray
Rotate a single image or mask using OpenCV.
Parameters
  • frame (np.ndarray) -- HxWxC RGB image (dtype uint8) or HxW mask (any dtype).
  • angle (float) -- Counter-clockwise rotation angle in degrees.
  • resample (int) -- One of cv2.INTER_NEAREST, cv2.INTER_LINEAR, or cv2.INTER_CUBIC. For masks, you’ll typically want cv2.INTER_NEAREST. Default is cv2.INTER_CUBIC.
  • expand (bool) -- If True, expand the output canvas so the full rotated frame fits. If False, output size == input size (cropping corners). Default False. Expansion does not account for translation.
  • center (tuple or None) -- (cx, cy) rotation center in pixel coords. Defaults to image center.
  • translate (tuple or None) -- (dx, dy) post-rotation translation in pixels. Default (0, 0).
  • bg_color (tuple, scalar, or None) -- Fill color for areas outside the frame. If frame is HxWx3 RGB, bg_color=(R,G,B). If HxW mask, bg_color is a scalar. Default black.

Returns
rotated -- The rotated (and possibly expanded) frame or mask.
Return type
np.ndarray



moviepy.video.fx.Scroll

class moviepy.video.fx.Scroll.Scroll(w=None, h=None, x_speed=0, y_speed=0, x_start=0, y_start=0, apply_to='mask')
Effect that scrolls horizontally or vertically a clip, e.g. to make end credits
Parameters
  • w -- The width and height of the final clip. Default to clip.w and clip.h
  • h -- The width and height of the final clip. Default to clip.w and clip.h
  • x_speed -- The speed of the scroll in the x and y directions.
  • y_speed -- The speed of the scroll in the x and y directions.
  • x_start -- The starting position of the scroll in the x and y directions.
  • y_start -- The starting position of the scroll in the x and y directions.


apply_to
Whether to apply the effect to the mask too.

apply(clip)
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.SlideIn

class moviepy.video.fx.SlideIn.SlideIn(duration: float, side: str)
Makes the clip arrive from one side of the screen.

Only works when the clip is included in a CompositeVideoClip, and if the clip has the same size as the whole composition.

Parameters
  • clip (moviepy.Clip.Clip <#moviepy.Clip.Clip>) -- A video clip.
  • duration (float) -- Time taken for the clip to be fully visible
  • side (str) -- Side of the screen where the clip comes from. One of 'top', 'bottom', 'left' or 'right'.


Examples

from moviepy import *
clips = [... make a list of clips]
slided_clips = [

CompositeVideoClip([clip.with_effects([vfx.SlideIn(1, "left")])])
for clip in clips ] final_clip = concatenate_videoclips(slided_clips, padding=-1) clip = ColorClip(
color=(255, 0, 0), duration=1, size=(300, 300) ).with_fps(60) final_clip = CompositeVideoClip([clip.with_effects([vfx.SlideIn(1, "right")])])


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.SlideOut

class moviepy.video.fx.SlideOut.SlideOut(duration: float, side: str)
Makes the clip goes away by one side of the screen.

Only works when the clip is included in a CompositeVideoClip, and if the clip has the same size as the whole composition.

Parameters
  • clip (moviepy.Clip.Clip <#moviepy.Clip.Clip>) -- A video clip.
  • duration (float) -- Time taken for the clip to be fully visible
  • side (str) -- Side of the screen where the clip goes. One of 'top', 'bottom', 'left' or 'right'.


Examples

from moviepy import *
clips = [... make a list of clips]
slided_clips = [

CompositeVideoClip([clip.with_effects([vfx.SlideOut(1, "left")])])
for clip in clips ] final_clip = concatenate_videoclips(slided_clips, padding=-1) clip = ColorClip(
color=(255, 0, 0), duration=1, size=(300, 300) ).with_fps(60) final_clip = CompositeVideoClip([clip.with_effects([vfx.SlideOut(1, "right")])])


apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.SuperSample

class moviepy.video.fx.SuperSample.SuperSample(d: float, n_frames: int)
Replaces each frame at time t by the mean of n_frames equally spaced frames taken in the interval [t-d, t+d]. This results in motion blur.
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.TimeMirror

class moviepy.video.fx.TimeMirror.TimeMirror
Returns a clip that plays the current clip backwards. The clip must have its duration attribute set. The same effect is applied to the clip's audio and mask if any.
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.fx.TimeSymmetrize

class moviepy.video.fx.TimeSymmetrize.TimeSymmetrize
Returns a clip that plays the current clip once forwards and then once backwards. This is very practival to make video that loop well, e.g. to create animated GIFs. This effect is automatically applied to the clip's mask and audio if they exist.
apply(clip: Clip <#moviepy.Clip.Clip>) -> Clip <#moviepy.Clip.Clip>
Apply the effect to the clip.

copy()
Return a shallow copy of an Effect.

You must always copy an Effect before applying, because some of them will modify their own attributes when applied. For example, setting a previously unset property by using target clip property.

If we was to use the original effect, calling the same effect multiple times could lead to different properties, and different results for equivalent clips.

By using copy, we ensure we can use the same effect object multiple times while maintaining the same behavior/result.

In a way, copy makes the effect himself being kind of idempotent.



moviepy.video.io

Classes and methods for reading, writing and previewing video files.

Modules

ImageSequenceClip <#module-moviepy.video.io.ImageSequenceClip> Implements ImageSequenceClip, a class to create a video clip from a set of image files.
VideoFileClip <#module-moviepy.video.io.VideoFileClip> Implements VideoFileClip, a class for video clips creation using video files.
display_in_notebook <#module-moviepy.video.io.display_in_notebook> Implements display_in_notebook, a function to embed images/videos/audio in the Jupyter Notebook.
errors <#module-moviepy.video.io.errors> contains the errors that can be raised by the video IO functions.
ffmpeg_reader <#module-moviepy.video.io.ffmpeg_reader> Implements all the functions to read a video or a picture using ffmpeg.
ffmpeg_tools <#module-moviepy.video.io.ffmpeg_tools> Miscellaneous bindings to ffmpeg.
ffmpeg_writer <#module-moviepy.video.io.ffmpeg_writer> On the long term this will implement several methods to make videos out of VideoClips
ffplay_previewer <#module-moviepy.video.io.ffplay_previewer> On the long term this will implement several methods to make videos out of VideoClips
gif_writers <#module-moviepy.video.io.gif_writers> MoviePy video GIFs writing.

moviepy.video.io.ImageSequenceClip

Implements ImageSequenceClip, a class to create a video clip from a set of image files.

Classes

ImageSequenceClip <#moviepy.video.io.ImageSequenceClip.ImageSequenceClip>(sequence[, fps, ...]) A VideoClip made from a series of images.

moviepy.video.io.ImageSequenceClip.ImageSequenceClip

class moviepy.video.io.ImageSequenceClip.ImageSequenceClip(sequence, fps=None, durations=None, with_mask=True, is_mask=False, load_images=False)
A VideoClip made from a series of images.
Parameters
sequence --

Can be one of these:

  • The name of a folder (containing only pictures). The pictures will be considered in alphanumerical order.
  • A list of names of image files. In this case you can choose to load the pictures in memory pictures
  • A list of Numpy arrays representing images.

  • fps -- Number of picture frames to read per second. Instead, you can provide the duration of each image with durations (see below)
  • durations -- List of the duration of each picture.
  • with_mask -- Should the alpha layer of PNG images be considered as a mask ?
  • is_mask -- Will this sequence of pictures be used as an animated mask.
  • load_images -- Specify that all images should be loaded into the RAM. This is only interesting if you have a small number of images that will be used more than once.


frame_function(t)
Retrieves the frame corresponding to the given time t.

Depending on whether the frames are loaded from files or provided as an in-memory sequence, this function either reads the frame from disk or accesses it directly from the sequence.

Parameters
(float) (t) -- is to be retrieved.
Returns
numpy.ndarray -- is True, the alpha channel of the image is returned as a float array normalized to the range [0, 1]. Otherwise, the RGB channels of the image are returned.
Return type
The image frame at the specified time. If is_mask



moviepy.video.io.VideoFileClip

Implements VideoFileClip, a class for video clips creation using video files.

Classes

VideoFileClip <#moviepy.video.io.VideoFileClip.VideoFileClip>(filename[, decode_file, ...]) A video clip originating from a movie file.

moviepy.video.io.VideoFileClip.VideoFileClip

class moviepy.video.io.VideoFileClip.VideoFileClip(filename, decode_file=False, has_mask=False, audio=True, audio_buffersize=200000, target_resolution=None, resize_algorithm='bicubic', audio_fps=44100, audio_nbytes=2, fps_source='fps', pixel_format=None, is_mask=False, audio_stream_index=0)
A video clip originating from a movie file. For instance:

clip = VideoFileClip("myHolidays.mp4")
clip.close()
with VideoFileClip("myMaskVideo.avi") as clip2:

pass # Implicit close called by context manager.


Parameters
  • filename -- The name of the video file, as a string or a path-like object. It can have any extension supported by ffmpeg: .ogv, .mp4, .mpeg, .avi, .mov etc.
  • has_mask -- Set this to 'True' if there is a mask included in the videofile. Video files rarely contain masks, but some video codecs enable that. For instance if you have a MoviePy VideoClip with a mask you can save it to a videofile with a mask. (see also VideoClip.write_videofile for more details).
  • audio -- Set to False if the clip doesn't have any audio or if you do not wish to read the audio.
  • target_resolution -- Set to (desired_width, desired_height) to have ffmpeg resize the frames before returning them. This is much faster than streaming in high-res and then resizing. If either dimension is None, the frames are resized by keeping the existing aspect ratio.
  • resize_algorithm -- The algorithm used for resizing. Default: "bicubic", other popular options include "bilinear" and "fast_bilinear". For more information, see <https://ffmpeg.org/ffmpeg-scaler.html>
  • fps_source -- The fps value to collect from the metadata. Set by default to 'fps', but can be set to 'tbr', which may be helpful if you are finding that it is reading the incorrect fps from the file.
  • pixel_format -- Optional: Pixel format for the video to read. If is not specified 'rgb24' will be used as the default format unless has_mask is set as True, then 'rgba' will be used.
  • is_mask -- True if the clip is going to be used as a mask.
  • audio_stream_index -- The index of the audio stream to read from the file.


filename
Name of the original video file.

fps
Frames per second in the original file.

Read docs for Clip() and VideoClip() for other, more generic, attributes.

Lifetime

Note that this creates subprocesses and locks files. If you construct one of these instances, you must call close() afterwards, or the subresources will not be cleaned up until the process ends.

If copies are made, and close() is called on one, it may cause methods on the other copies to fail.

close()
Close the internal reader.



moviepy.video.io.display_in_notebook

Implements display_in_notebook, a function to embed images/videos/audio in the Jupyter Notebook.

Functions

HTML2 <#moviepy.video.io.display_in_notebook.HTML2>(content)
display_in_notebook <#moviepy.video.io.display_in_notebook.display_in_notebook>(clip[, filetype, ...]) Displays clip content in an Jupyter Notebook.
html_embed <#moviepy.video.io.display_in_notebook.html_embed>(clip[, filetype, maxduration, ...]) Returns HTML5 code embedding the clip.

moviepy.video.io.display_in_notebook.HTML2

moviepy.video.io.display_in_notebook.HTML2(content)

moviepy.video.io.display_in_notebook.display_in_notebook

moviepy.video.io.display_in_notebook.display_in_notebook(clip, filetype=None, maxduration=60, t=None, fps=None, rd_kwargs=None, center=True, **html_kwargs)
Displays clip content in an Jupyter Notebook.

Remarks: If your browser doesn't support HTML5, this should warn you. If nothing is displayed, maybe your file or filename is wrong. Important: The media will be physically embedded in the notebook.

Parameters
  • clip (moviepy.Clip.Clip <#moviepy.Clip.Clip>) -- Either the name of a file, or a clip to preview. The clip will actually be written to a file and embedded as if a filename was provided.
  • filetype (str, optional) -- One of "video", "image" or "audio". If None is given, it is determined based on the extension of filename, but this can bug.
  • maxduration (float, optional) -- An error will be raised if the clip's duration is more than the indicated value (in seconds), to avoid spoiling the browser's cache and the RAM.
  • t (float, optional) -- If not None, only the frame at time t will be displayed in the notebook, instead of a video of the clip.
  • fps (int, optional) -- Enables to specify an fps, as required for clips whose fps is unknown.
  • rd_kwargs (dict, optional) -- Keyword arguments for the rendering, like dict(fps=15, bitrate="50k"). Allow you to give some options to the render process. You can, for example, disable the logger bar passing dict(logger=None).
  • center (bool, optional) -- If true (default), the content will be wrapped in a <div align=middle> HTML container, so the content will be displayed at the center.
  • kwargs -- Allow you to give some options, like width=260, etc. When editing looping gifs, a good choice is loop=1, autoplay=1.


Examples

from moviepy import *
# later ...
clip.display_in_notebook(width=360)
clip.audio.display_in_notebook()
clip.write_gif("test.gif")
display_in_notebook('test.gif')
clip.save_frame("first_frame.jpeg")
display_in_notebook("first_frame.jpeg")



moviepy.video.io.display_in_notebook.html_embed

moviepy.video.io.display_in_notebook.html_embed(clip, filetype=None, maxduration=60, rd_kwargs=None, center=True, **html_kwargs)
Returns HTML5 code embedding the clip.
Parameters
  • clip (moviepy.Clip.Clip <#moviepy.Clip.Clip>) -- Either a file name, or a clip to preview. Either an image, a sound or a video. Clips will actually be written to a file and embedded as if a filename was provided.
  • filetype (str, optional) -- One of 'video','image','audio'. If None is given, it is determined based on the extension of filename, but this can bug.
  • maxduration (float, optional) -- An error will be raised if the clip's duration is more than the indicated value (in seconds), to avoid spoiling the browser's cache and the RAM.
  • rd_kwargs (dict, optional) -- Keyword arguments for the rendering, like dict(fps=15, bitrate="50k"). Allow you to give some options to the render process. You can, for example, disable the logger bar passing dict(logger=None).
  • center (bool, optional) -- If true (default), the content will be wrapped in a <div align=middle> HTML container, so the content will be displayed at the center.
  • html_kwargs -- Allow you to give some options, like width=260, autoplay=True, loop=1 etc.


Examples

from moviepy import *
# later ...
html_embed(clip, width=360)
html_embed(clip.audio)
clip.write_gif("test.gif")
html_embed('test.gif')
clip.save_frame("first_frame.jpeg")
html_embed("first_frame.jpeg")



moviepy.video.io.errors

contains the errors that can be raised by the video IO functions.

Exceptions

VideoCorruptedError Error raised when a video file is corrupted.

moviepy.video.io.ffmpeg_reader

Implements all the functions to read a video or a picture using ffmpeg.

Classes

FFMPEG_VideoReader <#moviepy.video.io.ffmpeg_reader.FFMPEG_VideoReader>(filename[, decode_file, ...]) Class for video byte-level reading with ffmpeg.
FFmpegInfosParser <#moviepy.video.io.ffmpeg_reader.FFmpegInfosParser>(infos, filename[, ...]) An (hopefully) robuste ffmpeg -i command option file information parser.

moviepy.video.io.ffmpeg_reader.FFMPEG_VideoReader

class moviepy.video.io.ffmpeg_reader.FFMPEG_VideoReader(filename, decode_file=True, print_infos=False, bufsize=None, pixel_format='rgb24', check_duration=True, target_resolution=None, resize_algo='bicubic', fps_source='fps')
Class for video byte-level reading with ffmpeg.
close(delete_lastread=True)
Closes the reader terminating the process, if is still open.

get_frame(t)
Read a file video frame at time t.

Note for coders: getting an arbitrary frame in the video with ffmpeg can be painfully slow if some decoding has to be done. This function tries to avoid fetching arbitrary frames whenever possible, by moving between adjacent frames.


get_frame_number(t)
Helper method to return the frame number at time t

initialize(start_time=0)
Opens the file, creates the pipe.

Sets self.pos to the appropriate value (1 if start_time == 0 because it pre-reads the first frame).


property lastread
Alias of self.last_read for backwards compatibility with MoviePy 1.x.

read_frame()
Reads the next frame from the file. Note that upon (re)initialization, the first frame will already have been read and stored in self.last_read.

skip_frames(n=1)
Reads and throws away n frames


moviepy.video.io.ffmpeg_reader.FFmpegInfosParser

class moviepy.video.io.ffmpeg_reader.FFmpegInfosParser(infos, filename, fps_source='fps', check_duration=True, decode_file=False)
An (hopefully) robuste ffmpeg -i command option file information parser. Is designed to parse the output by extracting the different blocks of informations, based on the indentation, in order to create an easy to handle block tree
Parameters
  • filename -- Name of the file parsed, only used to raise accurate error messages.
  • infos -- Information returned by FFmpeg.
  • fps_source -- Indicates what source data will be preferably used to retrieve fps data.
  • check_duration -- Enable or disable the parsing of the duration of the file. Useful to skip the duration check, for example, for images.
  • decode_file -- Indicates if the whole file has been decoded. The duration parsing strategy will differ depending on this argument.


class InfoBlock(block_line, indent_level=0)
Represents a block of output from ffmpeg, which can be an input file, stream, chapter or metadata.
add_child(child)
Adds a child to the current block.


exception ParseDimensionError
Error raised when we cannot find dimensions in a video stream

exception ParseDurationError
Error raised when we cannot find duration in a video stream

parse()
Parses the information returned by FFmpeg in stderr executing their binary for a file with -i option and returns a dictionary with all data needed by MoviePy.


Functions

ffmpeg_parse_infos <#moviepy.video.io.ffmpeg_reader.ffmpeg_parse_infos>(filename[, ...]) Get the information of a file using ffmpeg.
ffmpeg_read_image <#moviepy.video.io.ffmpeg_reader.ffmpeg_read_image>(filename[, with_mask, ...]) Read an image file (PNG, BMP, JPEG...).

moviepy.video.io.ffmpeg_reader.ffmpeg_parse_infos

moviepy.video.io.ffmpeg_reader.ffmpeg_parse_infos(filename, check_duration=True, fps_source='fps', decode_file=False, print_infos=False)
Get the information of a file using ffmpeg.

Returns a dictionary with next fields:

  • "audio_bitrate"
  • "audio_found"
  • "audio_fps"
  • "bitrate"
  • "duration"
  • "inputs"
  • "metadata"
  • "start"
  • "video_bitrate"
  • "video_codec_name"
  • "video_duration"
  • "video_fps"
  • "video_found"
  • "video_n_frames"
  • "video_profile"
  • "video_rotation"
  • "video_size"

Note that "video_duration" is slightly smaller than "duration" to avoid fetching the incomplete frames at the end, which raises an error.

Parameters
  • filename -- Name of the file parsed, only used to raise accurate error messages.
  • infos -- Information returned by FFmpeg.
  • fps_source -- Indicates what source data will be preferably used to retrieve fps data.
  • check_duration -- Enable or disable the parsing of the duration of the file. Useful to skip the duration check, for example, for images.
  • decode_file -- Indicates if the whole file must be read to retrieve their duration. This is needed for some files in order to get the correct duration (see <https://github.com/Zulko/moviepy/pull/1222>).



moviepy.video.io.ffmpeg_reader.ffmpeg_read_image

moviepy.video.io.ffmpeg_reader.ffmpeg_read_image(filename, with_mask=True, pixel_format=None)
Read an image file (PNG, BMP, JPEG...).

Wraps FFMPEG_Videoreader to read just one image. Returns an ImageClip.

This function is not meant to be used directly in MoviePy. Use ImageClip instead to make clips out of image files.

Parameters
  • filename -- Name of the image file. Can be of any format supported by ffmpeg.
  • with_mask -- If the image has a transparency layer, with_mask=true will save this layer as the mask of the returned ImageClip
  • pixel_format -- Optional: Pixel format for the image to read. If is not specified 'rgb24' will be used as the default format unless with_mask is set as True, then 'rgba' will be used.



moviepy.video.io.ffmpeg_tools

Miscellaneous bindings to ffmpeg.

Functions

ffmpeg_copy <#moviepy.video.io.ffmpeg_tools.ffmpeg_copy>(input_file, output_file) Re-mix a video file using ffmpeg.
ffmpeg_extract_audio <#moviepy.video.io.ffmpeg_tools.ffmpeg_extract_audio>(inputfile, outputfile) Extract the sound from a video file and save it in outputfile.
ffmpeg_extract_subclip <#moviepy.video.io.ffmpeg_tools.ffmpeg_extract_subclip>(inputfile, ...[, ...]) Makes a new video file playing video file between two times.
ffmpeg_merge_video_audio <#moviepy.video.io.ffmpeg_tools.ffmpeg_merge_video_audio>(videofile, ...[, ...]) Merges video file and audio file into one movie file.
ffmpeg_resize <#moviepy.video.io.ffmpeg_tools.ffmpeg_resize>(inputfile, outputfile, size[, ...]) Resizes a file to new size and write the result in another.
ffmpeg_stabilize_video <#moviepy.video.io.ffmpeg_tools.ffmpeg_stabilize_video>(inputfile[, ...]) Stabilizes filename and write the result to output.
ffmpeg_version <#moviepy.video.io.ffmpeg_tools.ffmpeg_version>() Retrieve the FFmpeg version.
ffplay_version <#moviepy.video.io.ffmpeg_tools.ffplay_version>() Retrieve the FFplay version.

moviepy.video.io.ffmpeg_tools.ffmpeg_copy

moviepy.video.io.ffmpeg_tools.ffmpeg_copy(input_file, output_file)
Re-mix a video file using ffmpeg. This may fix issues with corrupted video file.
Parameters
  • input_file (str or Path file that will be re-encoded)
  • output_file (str or Path path to save the re-encoded file)

Return type
None


moviepy.video.io.ffmpeg_tools.ffmpeg_extract_audio

moviepy.video.io.ffmpeg_tools.ffmpeg_extract_audio(inputfile, outputfile, bitrate=3000, fps=44100, logger='bar')
Extract the sound from a video file and save it in outputfile.
Parameters
  • inputfile (str) -- The path to the file from which the audio will be extracted.
  • outputfile (str) -- The path to the file to which the audio will be stored.
  • bitrate (int, optional) -- Bitrate for the new audio file.
  • fps (int, optional) -- Frame rate for the new audio file.



moviepy.video.io.ffmpeg_tools.ffmpeg_extract_subclip

moviepy.video.io.ffmpeg_tools.ffmpeg_extract_subclip(inputfile, start_time, end_time, outputfile=None, logger='bar')
Makes a new video file playing video file between two times.
Parameters
  • inputfile (str) -- Path to the file from which the subclip will be extracted.
  • start_time (float) -- Moment of the input clip that marks the start of the produced subclip.
  • end_time (float) -- Moment of the input clip that marks the end of the produced subclip.
  • outputfile (str, optional) -- Path to the output file. Defaults to <inputfile_name>SUB<start_time>_<end_time><ext>.



moviepy.video.io.ffmpeg_tools.ffmpeg_merge_video_audio

moviepy.video.io.ffmpeg_tools.ffmpeg_merge_video_audio(videofile, audiofile, outputfile, video_codec='copy', audio_codec='copy', logger='bar')
Merges video file and audio file into one movie file.
Parameters
  • videofile (str) -- Path to the video file used in the merge.
  • audiofile (str) -- Path to the audio file used in the merge.
  • outputfile (str) -- Path to the output file.
  • video_codec (str, optional) -- Video codec used by FFmpeg in the merge.
  • audio_codec (str, optional) -- Audio codec used by FFmpeg in the merge.



moviepy.video.io.ffmpeg_tools.ffmpeg_resize

moviepy.video.io.ffmpeg_tools.ffmpeg_resize(inputfile, outputfile, size, logger='bar')
Resizes a file to new size and write the result in another.
Parameters
  • inputfile (str) -- Path to the file to be resized.
  • outputfile (str) -- Path to the output file.
  • size (list or tuple) -- New size in format [width, height] for the output file.



moviepy.video.io.ffmpeg_tools.ffmpeg_stabilize_video

moviepy.video.io.ffmpeg_tools.ffmpeg_stabilize_video(inputfile, outputfile=None, output_dir='', overwrite_file=True, logger='bar')
Stabilizes filename and write the result to output.
Parameters
  • inputfile (str) -- The name of the shaky video.
  • outputfile (str, optional) -- The name of new stabilized video. Defaults to appending '_stabilized' to the input file name.
  • output_dir (str, optional) -- The directory to place the output video in. Defaults to the current working directory.
  • overwrite_file (bool, optional) -- If outputfile already exists in output_dir, then overwrite outputfile Defaults to True.



moviepy.video.io.ffmpeg_tools.ffmpeg_version

moviepy.video.io.ffmpeg_tools.ffmpeg_version()
Retrieve the FFmpeg version.

This function retrieves both the full and numeric version of FFmpeg by executing the ffmpeg -version command. The full version includes additional details like build information, while the numeric version contains only the version numbers (e.g., '7.0.2').

Returns
A tuple containing: - full_version (str): The complete version string (e.g., '7.0.2-static'). - numeric_version (str): The numeric version string (e.g., '7.0.2').
Return type
tuple

Example

>>> ffmpeg_version()
('7.0.2-static', '7.0.2')
Raises
subprocess.CalledProcessError -- If the FFmpeg command fails to execute properly.


moviepy.video.io.ffmpeg_tools.ffplay_version

moviepy.video.io.ffmpeg_tools.ffplay_version()
Retrieve the FFplay version.

This function retrieves both the full and numeric version of FFplay by executing the ffplay -version command. The full version includes additional details like build information, while the numeric version contains only the version numbers (e.g., '6.0.1').

Returns
A tuple containing: - full_version (str): The complete version string (e.g., '6.0.1-static'). - numeric_version (str): The numeric version string (e.g., '6.0.1').
Return type
tuple

Example

>>> ffplay_version()
('6.0.1-static', '6.0.1')
Raises
subprocess.CalledProcessError -- If the FFplay command fails to execute properly.


moviepy.video.io.ffmpeg_writer

On the long term this will implement several methods to make videos out of VideoClips

Classes

FFMPEG_VideoWriter <#moviepy.video.io.ffmpeg_writer.FFMPEG_VideoWriter>(filename, size, fps[, ...]) A class for FFMPEG-based video writing.

moviepy.video.io.ffmpeg_writer.FFMPEG_VideoWriter

class moviepy.video.io.ffmpeg_writer.FFMPEG_VideoWriter(filename, size, fps, codec='libx264', audiofile=None, audio_codec=None, preset='medium', bitrate=None, with_mask=False, logfile=None, threads=None, ffmpeg_params=None, pixel_format=None, print_cmd=False)
A class for FFMPEG-based video writing.
Parameters
  • filename (str) -- Any filename like "video.mp4" etc. but if you want to avoid complications it is recommended to use the generic extension ".avi" for all your videos.
  • size (tuple or list) -- Size of the output video in pixels (width, height).
  • fps (int) -- Frames per second in the output video file.
  • codec (str, optional) --

    FFMPEG codec. It seems that in terms of quality the hierarchy is 'rawvideo' = 'png' > 'mpeg4' > 'libx264' 'png' manages the same lossless quality as 'rawvideo' but yields smaller files. Type ffmpeg -codecs in a terminal to get a list of accepted codecs.

    Note for default 'libx264': by default the pixel format yuv420p is used. If the video dimensions are not both even (e.g. 720x405) another pixel format is used, and this can cause problem in some video readers.

  • audiofile (str, optional) -- The name of an audio file that will be incorporated to the video.
  • audio_codec (str, optional) -- FFMPEG audio codec. If None, "copy" codec is used.
  • preset (str, optional) -- Sets the time that FFMPEG will take to compress the video. The slower, the better the compression rate. Possibilities are: "ultrafast", "superfast", "veryfast", "faster", "fast", "medium" (default), "slow", "slower", "veryslow", "placebo".
  • bitrate (str, optional) -- Only relevant for codecs which accept a bitrate. "5000k" offers nice results in general.
  • with_mask (bool, optional) -- Set to True if there is a mask in the video to be encoded.
  • pixel_format (str, optional) -- Optional: Pixel format for the output video file. If is not specified "rgb24" will be used as the default format unless with_mask is set as True, then "rgba" will be used.
  • logfile (int, optional) -- File descriptor for logging output. If not defined, subprocess.PIPE will be used. Defined using another value, the log level of the ffmpeg command will be "info", otherwise "error".
  • threads (int, optional) -- Number of threads used to write the output with ffmpeg.
  • ffmpeg_params (list, optional) -- Additional parameters passed to ffmpeg command.
  • print_cmd (bool, optional) -- If set to True, the ffmpeg command used to write the video will be printed to the console. This can be useful for debugging purposes. Default is False.


close()
Closes the writer, terminating the subprocess if is still alive.

write_frame(img_array)
Writes one frame in the file.


Functions

ffmpeg_write_image <#moviepy.video.io.ffmpeg_writer.ffmpeg_write_image>(filename, image[, ...]) Writes an image (HxWx3 or HxWx4 numpy array) to a file, using ffmpeg.
ffmpeg_write_video <#moviepy.video.io.ffmpeg_writer.ffmpeg_write_video>(clip, filename, fps[, ...]) Write the clip to a videofile.

moviepy.video.io.ffmpeg_writer.ffmpeg_write_image

moviepy.video.io.ffmpeg_writer.ffmpeg_write_image(filename, image, logfile=False, pixel_format=None)
Writes an image (HxWx3 or HxWx4 numpy array) to a file, using ffmpeg.
Parameters
  • filename (str) -- Path to the output file.
  • image (np.ndarray) -- Numpy array with the image data.
  • logfile (bool, optional) -- Writes the ffmpeg output inside a logging file (True) or not (False).
  • pixel_format (str, optional) -- Pixel format for ffmpeg. If not defined, it will be discovered checking if the image data contains an alpha channel ("rgba") or not ("rgb24").



moviepy.video.io.ffmpeg_writer.ffmpeg_write_video

moviepy.video.io.ffmpeg_writer.ffmpeg_write_video(clip, filename, fps, codec='libx264', bitrate=None, preset='medium', write_logfile=False, audiofile=None, audio_codec=None, threads=None, ffmpeg_params=None, logger='bar', pixel_format=None)
Write the clip to a videofile. See VideoClip.write_videofile for details on the parameters.

moviepy.video.io.ffplay_previewer

On the long term this will implement several methods to make videos out of VideoClips

Classes

FFPLAY_VideoPreviewer <#moviepy.video.io.ffplay_previewer.FFPLAY_VideoPreviewer>(size, fps, pixel_format) A class for FFPLAY-based video preview.

moviepy.video.io.ffplay_previewer.FFPLAY_VideoPreviewer

class moviepy.video.io.ffplay_previewer.FFPLAY_VideoPreviewer(size, fps, pixel_format)
A class for FFPLAY-based video preview.
Parameters
  • size (tuple or list) -- Size of the output video in pixels (width, height).
  • fps (int) -- Frames per second in the output video file.
  • pixel_format (str) -- Pixel format for the output video file, rgb24 for normal video, rgba if video with mask.


close()
Closes the writer, terminating the subprocess if is still alive.

show_frame(img_array)
Writes one frame in the file.


Functions

ffplay_preview_video <#moviepy.video.io.ffplay_previewer.ffplay_preview_video>(clip, fps[, ...]) Preview the clip using ffplay.

moviepy.video.io.ffplay_previewer.ffplay_preview_video

moviepy.video.io.ffplay_previewer.ffplay_preview_video(clip, fps, pixel_format='rgb24', audio_flag=None, video_flag=None)
Preview the clip using ffplay. See VideoClip.preview for details on the parameters.
Parameters
  • clip (VideoClip <#moviepy.video.VideoClip.VideoClip>) -- The clip to preview
  • fps (int) -- Number of frames per seconds in the displayed video.
  • pixel_format (str, optional) --

    Warning: This is not used anywhere in the code and should probably be removed. It is believed pixel format rgb24 does not work properly for now because it requires applying a mask on CompositeVideoClip and that is believed to not be working.

    Pixel format for the output video file, rgb24 for normal video, rgba if video with mask

  • audio_flag (Thread.Event, optional) -- A thread event that video will wait for. If not provided we ignore audio
  • video_flag (Thread.Event, optional) -- A thread event that video will set after first frame has been shown. If not provided, we simply ignore



moviepy.video.io.gif_writers

MoviePy video GIFs writing.

Functions

write_gif_with_imageio <#moviepy.video.io.gif_writers.write_gif_with_imageio>(clip, filename[, ...]) Writes the gif with the Python library ImageIO (calls FreeImage).

moviepy.video.io.gif_writers.write_gif_with_imageio

moviepy.video.io.gif_writers.write_gif_with_imageio(clip, filename, fps=None, loop=0, logger='bar')
Writes the gif with the Python library ImageIO (calls FreeImage).

moviepy.video.tools

Modules

credits <#module-moviepy.video.tools.credits> Contains different functions to make end and opening credits, even though it is difficult to fill everyone needs in this matter.
cuts <#module-moviepy.video.tools.cuts> Contains everything that can help automate the cuts in MoviePy.
drawing <#module-moviepy.video.tools.drawing> Deals with making images (np arrays).
interpolators <#module-moviepy.video.tools.interpolators> Classes for easy interpolation of trajectories and curves.
subtitles <#module-moviepy.video.tools.subtitles> Experimental module for subtitles support.

moviepy.video.tools.credits

Contains different functions to make end and opening credits, even though it is difficult to fill everyone needs in this matter.

Classes

CreditsClip <#moviepy.video.tools.credits.CreditsClip>(creditfile, width[, color, ...]) Credits clip.

moviepy.video.tools.credits.CreditsClip

class moviepy.video.tools.credits.CreditsClip(creditfile, width, color='white', stroke_color='black', stroke_width=2, font='Impact-Normal', font_size=60, bg_color=None, gap=0)
Credits clip.
Parameters
creditfile --

A string or path like object pointing to a text file whose content must be as follows:

..code:: python

# This is a comment # The next line says : leave 4 blank lines .blank 4

..Executive Story Editor MARCEL DURAND

..Associate Producers MARTIN MARCEL DIDIER MARTIN

..Music Supervisor JEAN DIDIER



  • width -- Total width of the credits text in pixels
  • gap -- Horizontal gap in pixels between the jobs and the names
  • color -- Color of the text. See TextClip.list('color') for a list of acceptable names.
  • font -- Name of the font to use. See TextClip.list('font') for the list of fonts you can use on your computer.
  • font_size -- Size of font to use
  • stroke_color -- Color of the stroke (=contour line) of the text. If None, there will be no stroke.
  • stroke_width -- Width of the stroke, in pixels. Can be a float, like 1.5.
  • bg_color -- Color of the background. If None, the background will be transparent.

Returns
An ImageClip instance that looks like this and can be scrolled to make some credits:

Executive Story Editor    MARCEL DURAND

Associate Producers MARTIN MARCEL
DIDIER MARTIN
Music Supervisor JEAN DIDIER


Return type
image


moviepy.video.tools.cuts

Contains everything that can help automate the cuts in MoviePy.

Classes

FramesMatch <#moviepy.video.tools.cuts.FramesMatch>(start_time, end_time, ...) Frames match inside a set of frames.
FramesMatches <#moviepy.video.tools.cuts.FramesMatches>(lst) Frames matches inside a set of frames.

moviepy.video.tools.cuts.FramesMatch

class moviepy.video.tools.cuts.FramesMatch(start_time, end_time, min_distance, max_distance)
Frames match inside a set of frames.
Parameters
  • start_time (float) -- Starting time.
  • end_time (float) -- End time.
  • min_distance (float) -- Lower bound on the distance between the first and last frames
  • max_distance (float) -- Upper bound on the distance between the first and last frames



moviepy.video.tools.cuts.FramesMatches

class moviepy.video.tools.cuts.FramesMatches(lst)
Frames matches inside a set of frames.

You can instantiate it passing a list of FramesMatch objects or using the class methods load and from_clip.

Parameters
lst (list) -- Iterable of FramesMatch objects.

best(n=1, percent=None)
Returns a new instance of FramesMatches object or a FramesMatch from the current class instance given different conditions.

By default returns the first FramesMatch that the current instance stores.

Parameters
  • n (int, optional) -- Number of matches to retrieve from the current FramesMatches object. Only has effect when percent=None.
  • percent (float, optional) -- Percent of the current match to retrieve.

Returns
FramesMatch or FramesMatches -- greater than 1 returns a FramesMatches object, otherwise a FramesMatch.
Return type
If the number of matches to retrieve is


filter(condition)
Return a FramesMatches object obtained by filtering out the FramesMatch which do not satistify a condition.
Parameters
condition (func) -- Function which takes a FrameMatch object as parameter and returns a bool.

Examples

# Only keep the matches corresponding to (> 1 second) sequences.
new_matches = matches.filter(lambda match: match.time_span > 1)



static from_clip(clip, distance_threshold, max_duration, fps=None, logger='bar')
Finds all the frames that look alike in a clip, for instance to make a looping GIF.
Parameters
  • clip (moviepy.video.VideoClip.VideoClip <#moviepy.video.VideoClip.VideoClip>) -- A MoviePy video clip.
  • distance_threshold (float) -- Distance above which a match is rejected.
  • max_duration (float) -- Maximal duration (in seconds) between two matching frames.
  • fps (int, optional) -- Frames per second (default will be clip.fps).
  • logger (str, optional) -- Either "bar" for progress bar or None or any Proglog logger.

Returns
All pairs of frames with end_time - start_time < max_duration and whose distance is under distance_threshold.
Return type
FramesMatches <#moviepy.video.tools.cuts.FramesMatches>

Examples

We find all matching frames in a given video and turn the best match with a duration of 1.5 seconds or more into a GIF:

from moviepy import VideoFileClip
from moviepy.video.tools.cuts import FramesMatches
clip = VideoFileClip("foo.mp4").resize(width=200)
matches = FramesMatches.from_clip(

clip, distance_threshold=10, max_duration=3, # will take time ) best = matches.filter(lambda m: m.time_span > 1.5).best() clip.subclipped(best.start_time, best.end_time).write_gif("foo.gif")



static load(filename)
Load a FramesMatches object from a file.
Parameters
filename (str) -- Path to the file to use loading a FramesMatches object.

Examples

>>> matching_frames = FramesMatches.load("somefile")

save(filename)
Save a FramesMatches object to a file.
Parameters
filename (str) -- Path to the file in which will be dumped the FramesMatches object data.


select_scenes(match_threshold, min_time_span, nomatch_threshold=None, time_distance=0)
Select the scenes at which a video clip can be reproduced as the smoothest possible way, mainly oriented for the creation of GIF images.
Parameters
  • match_threshold (float) -- Maximum distance possible between frames. The smaller, the better-looping the GIFs are.
  • min_time_span (float) -- Minimum duration for a scene. Only matches with a duration longer than the value passed to this parameters will be extracted.
  • nomatch_threshold (float, optional) -- Minimum distance possible between frames. If is None, then it is chosen equal to match_threshold.
  • time_distance (float, optional) -- Minimum time offset possible between matches.

Returns
FramesMatches
Return type
New instance of the class with the selected scenes.

Examples

from pprint import pprint
from moviepy import *
from moviepy.video.tools.cuts import FramesMatches
ch_clip = VideoFileClip("media/chaplin.mp4").subclipped(1, 4)
mirror_and_clip = [ch_clip.with_effects([vfx.TimeMirror()]), ch_clip]
clip = concatenate_videoclips(mirror_and_clip)
result = FramesMatches.from_clip(clip, 10, 3).select_scenes(

1, 2, nomatch_threshold=0, ) print(result) # [(1.0000, 4.0000, 0.0000, 0.0000), # (1.1600, 3.8400, 0.0000, 0.0000), # (1.2800, 3.7200, 0.0000, 0.0000), # (1.4000, 3.6000, 0.0000, 0.0000)]



write_gifs(clip, gifs_dir, **kwargs)
Extract the matching frames represented by the instance from a clip and write them as GIFs in a directory, one GIF for each matching frame.
Parameters
  • clip (video.VideoClip.VideoClip <#moviepy.video.VideoClip.VideoClip>) -- A video clip whose frames scenes you want to obtain as GIF images.
  • gif_dir (str) -- Directory in which the GIF images will be written.
  • kwargs -- Passed as clip.write_gif optional arguments.


Examples

import os
from pprint import pprint
from moviepy import *
from moviepy.video.tools.cuts import FramesMatches
ch_clip = VideoFileClip("media/chaplin.mp4").subclipped(1, 4)
clip = concatenate_videoclips([ch_clip.time_mirror(), ch_clip])
result = FramesMatches.from_clip(clip, 10, 3).select_scenes(

1, 2, nomatch_threshold=0, ) os.mkdir("foo") result.write_gifs(clip, "foo") # MoviePy - Building file foo/00000100_00000400.gif with imageio. # MoviePy - Building file foo/00000115_00000384.gif with imageio. # MoviePy - Building file foo/00000128_00000372.gif with imageio. # MoviePy - Building file foo/00000140_00000360.gif with imageio.




Functions

detect_scenes <#moviepy.video.tools.cuts.detect_scenes>([clip, luminosities, ...]) Detects scenes of a clip based on luminosity changes.
find_video_period <#moviepy.video.tools.cuts.find_video_period>(clip[, fps, start_time]) Find the period of a video based on frames correlation.

moviepy.video.tools.cuts.detect_scenes

moviepy.video.tools.cuts.detect_scenes(clip=None, luminosities=None, luminosity_threshold=10, logger='bar', fps=None)
Detects scenes of a clip based on luminosity changes.

Note that for large clip this may take some time.

Returns
tuple -- cuts is a series of cuts [(0,t1), (t1,t2),...(...,tf)] luminosities are the luminosities computed for each frame of the clip.
Return type
cuts, luminosities
Parameters
  • clip (video.VideoClip.VideoClip <#moviepy.video.VideoClip.VideoClip>, optional) -- A video clip. Can be None if a list of luminosities is provided instead. If provided, the luminosity of each frame of the clip will be computed. If the clip has no 'fps' attribute, you must provide it.
  • luminosities (list, optional) -- A list of luminosities, e.g. returned by detect_scenes in a previous run.
  • luminosity_threshold (float, optional) -- Determines a threshold above which the 'luminosity jumps' will be considered as scene changes. A scene change is defined as a change between 2 consecutive frames that is larger than (avg * thr) where avg is the average of the absolute changes between consecutive frames.
  • logger (str, optional) -- Either "bar" for progress bar or None or any Proglog logger.
  • fps (int, optional) -- Frames per second value. Must be provided if you provide no clip or a clip without fps attribute.



moviepy.video.tools.cuts.find_video_period

moviepy.video.tools.cuts.find_video_period(clip, fps=None, start_time=0.3)
Find the period of a video based on frames correlation.
Parameters
  • clip (moviepy.Clip.Clip <#moviepy.Clip.Clip>) -- Clip for which the video period will be computed.
  • fps (int, optional) -- Number of frames per second used computing the period. Higher values will produce more accurate periods, but the execution time will be longer.
  • start_time (float, optional) -- First timeframe used to calculate the period of the clip.


Examples

from moviepy import *
from moviepy.video.tools.cuts import find_video_period
clip = VideoFileClip("media/chaplin.mp4").subclipped(0, 1).loop(2)
round(videotools.find_video_period(clip, fps=80), 6)
1



moviepy.video.tools.drawing

Deals with making images (np arrays). It provides drawing methods that are difficult to do with the existing Python libraries.

Functions

circle <#moviepy.video.tools.drawing.circle>(screensize, center, radius[, color, ...]) Draw an image with a circle.
color_gradient <#moviepy.video.tools.drawing.color_gradient>(size, p1[, p2, vector, ...]) Draw a linear, bilinear, or radial gradient.
color_split <#moviepy.video.tools.drawing.color_split>(size[, x, y, p1, p2, vector, ...]) Make an image split in 2 colored regions.

moviepy.video.tools.drawing.circle

moviepy.video.tools.drawing.circle(screensize, center, radius, color=1.0, bg_color=0, blur=1)
Draw an image with a circle.

Draws a circle of color color, on a background of color bg_color, on a screen of size screensize at the position center=(x, y), with a radius radius but slightly blurred on the border by blur pixels.

Parameters
  • screensize (tuple or list) -- Size of the canvas.
  • center (tuple or list) -- Center of the circle.
  • radius (float) -- Radius of the circle, in pixels.
  • bg_color (tuple or float, optional) -- Color for the background of the canvas. As default, black.
  • blur (float, optional) -- Blur for the border of the circle.


Examples

from moviepy.video.tools.drawing import circle
circle(

(5, 5), # size
(2, 2), # center
2, # radius ) # array([[0. , 0. , 0. , 0. , 0. ], # [0. , 0.58578644, 1. , 0.58578644, 0. ], # [0. , 1. , 1. , 1. , 0. ], # [0. , 0.58578644, 1. , 0.58578644, 0. ], # [0. , 0. , 0. , 0. , 0. ]])



moviepy.video.tools.drawing.color_gradient

moviepy.video.tools.drawing.color_gradient(size, p1, p2=None, vector=None, radius=None, color_1=0.0, color_2=1.0, shape='linear', offset=0)
Draw a linear, bilinear, or radial gradient.

The result is a picture of size size, whose color varies gradually from color color_1 in position p1 to color color_2 in position p2.

If it is a RGB picture the result must be transformed into a 'uint8' array to be displayed normally:

Parameters
  • size (tuple or list) -- Size (width, height) in pixels of the final image array.
  • p1 (tuple or list) -- Position for the first coordinate of the gradient in pixels (x, y). The color 'before' p1 is color_1 and it gradually changes in the direction of p2 until it is color_2 when it reaches p2.
  • p2 (tuple or list, optional) -- .INDENT 2.0
Position for the second coordinate of the gradient in pixels (x, y).
Coordinates (x, y) of the limit point for color_1 and color_2.

  • vector (tuple or list, optional) -- A vector (x, y) in pixels that can be provided instead of p2. p2 is then defined as (p1 + vector).
  • color_1 (tuple or list, optional) -- Starting color for the gradient. As default, black. Either floats between 0 and 1 (for gradients used in masks) or [R, G, B] arrays (for colored gradients).
  • color_2 (tuple or list, optional) -- Color for the second point in the gradient. As default, white. Either floats between 0 and 1 (for gradients used in masks) or [R, G, B] arrays (for colored gradients).
  • shape (str, optional) -- Shape of the gradient. Can be either "linear", "bilinear" or "circular". In a linear gradient the color varies in one direction, from point p1 to point p2. In a bilinear gradient it also varies symmetrically from p1 in the other direction. In a circular gradient it goes from color_1 to color_2 in all directions.
  • radius (float, optional) -- If shape="radial", the radius of the gradient is defined with the parameter radius, in pixels.
  • offset (float, optional) -- Real number between 0 and 1 indicating the fraction of the vector at which the gradient actually starts. For instance if offset is 0.9 in a gradient going from p1 to p2, then the gradient will only occur near p2 (before that everything is of color color_1) If the offset is 0.9 in a radial gradient, the gradient will occur in the region located between 90% and 100% of the radius, this creates a blurry disc of radius d(p1, p2).

Returns
An Numpy array of dimensions (width, height, n_colors) of type float representing the image of the gradient.
Return type
image

Examples

color_gradient((10, 1), (0, 0), p2=(10, 0))  # from white to black
#[[1.  0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1]]
# from red to green
color_gradient(

(10, 1), (0, 0),
p2=(10, 0),
color_1=(255, 0, 0),
color_2=(0, 255, 0) ) # [[[ 0. 255. 0. ] # [ 25.5 229.5 0. ] # [ 51. 204. 0. ] # [ 76.5 178.5 0. ] # [102. 153. 0. ] # [127.5 127.5 0. ] # [153. 102. 0. ] # [178.5 76.5 0. ] # [204. 51. 0. ] # [229.5 25.5 0. ]]]




moviepy.video.tools.drawing.color_split

moviepy.video.tools.drawing.color_split(size, x=None, y=None, p1=None, p2=None, vector=None, color_1=0, color_2=1.0, gradient_width=0)
Make an image split in 2 colored regions.

Returns an array of size size divided in two regions called 1 and 2 in what follows, and which will have colors color_1 and color_2 respectively.

Parameters
  • x (int, optional) -- If provided, the image is split horizontally in x, the left region being region 1.
  • y (int, optional) -- If provided, the image is split vertically in y, the top region being region 1.
  • p1 (tuple or list, optional) -- Positions (x1, y1), (x2, y2) in pixels, where the numbers can be floats. Region 1 is defined as the whole region on the left when going from p1 to p2.
  • p2 (tuple or list, optional) -- Positions (x1, y1), (x2, y2) in pixels, where the numbers can be floats. Region 1 is defined as the whole region on the left when going from p1 to p2.
  • p1 -- p1 is (x1,y1) and vector (v1,v2), where the numbers can be floats. Region 1 is then the region on the left when starting in position p1 and going in the direction given by vector.
  • vector (tuple or list, optional) -- p1 is (x1,y1) and vector (v1,v2), where the numbers can be floats. Region 1 is then the region on the left when starting in position p1 and going in the direction given by vector.
  • gradient_width (float, optional) -- If not zero, the split is not sharp, but gradual over a region of width gradient_width (in pixels). This is preferable in many situations (for instance for antialiasing).


Examples

size = [200, 200]
# an image with all pixels with x<50 =0, the others =1
color_split(size, x=50, color_1=0, color_2=1)
# an image with all pixels with y<50 red, the others green
color_split(size, x=50, color_1=[255, 0, 0], color_2=[0, 255, 0])
# An image split along an arbitrary line (see below)
color_split(size, p1=[20, 50], p2=[25, 70], color_1=0, color_2=1)



moviepy.video.tools.interpolators

Classes for easy interpolation of trajectories and curves.

Classes

Interpolator <#moviepy.video.tools.interpolators.Interpolator>([tt, ss, ttss, left, right]) Poorman's linear interpolator.
Trajectory <#moviepy.video.tools.interpolators.Trajectory>(tt, xx, yy) Trajectory compound by time frames and (x, y) pixels.

moviepy.video.tools.interpolators.Interpolator

class moviepy.video.tools.interpolators.Interpolator(tt=None, ss=None, ttss=None, left=None, right=None)
Poorman's linear interpolator.
Parameters
  • tt (list, optional) -- List of time frames for the interpolator.
  • ss (list, optional) -- List of values for the interpolator.
  • ttss (list, optional) -- Lists of time frames and their correspondients values for the interpolator. This argument can be used instead of tt and ss to instantiate the interpolator using an unique argument.
  • left (float, optional) -- Value to return when t < tt[0].
  • right (float, optional) -- Value to return when t > tt[-1].


Examples

# instantiate using `tt` and `ss`
interpolator = Interpolator(tt=[0, 1, 2], ss=[3, 4, 5])
# instantiate using `ttss`
interpolator = Interpolator(ttss=[[0, 3], [1, 4], [2, 5]])  # [t, value]



moviepy.video.tools.interpolators.Trajectory

class moviepy.video.tools.interpolators.Trajectory(tt, xx, yy)
Trajectory compound by time frames and (x, y) pixels.

It's designed as an interpolator, so you can get the position at a given time t. You can instantiate it from a file using the methods from_file and load_list.

Parameters
  • tt (list or numpy.ndarray) -- Time frames.
  • xx (list or numpy.ndarray) -- X positions in the trajectory.
  • yy (list or numpy.ndarray) -- Y positions in the trajectory.


Examples

>>> trajectory = Trajectory([0, .166, .333], [554, 474, 384], [100, 90, 91])
addx(x)
Adds a value to the xx position of the trajectory.
Parameters
x (int) -- Value added to xx in the trajectory.
Returns
Trajectory
Return type
new instance with the new X position included.


addy(y)
Adds a value to the yy position of the trajectory.
Parameters
y (int) -- Value added to yy in the trajectory.
Returns
Trajectory
Return type
new instance with the new Y position included.


static from_file(filename)
Instantiates an object of Trajectory using a data text file.
Parameters
filename (str) -- Path to the location of trajectory text file to load.
Returns
Trajectory
Return type
new instance loaded from text file.


static load_list(filename)
Loads a list of trajectories from a data text file.
Parameters
filename (str) -- Path of the text file that stores the data of a set of trajectories.
Returns
list
Return type
List of trajectories loaded from the file.


static save_list(trajs, filename)
Saves a set of trajectories into a text file.
Parameters
  • trajs (list) -- List of trajectories to be saved.
  • filename (str) -- Path of the text file that will store the trajectories data.



to_file(filename)
Saves the trajectory data in a text file.
Parameters
filename (str) -- Path to the location of the new trajectory text file.


txy(tms=False)
Returns all times with the X and Y values of each position.
Parameters
tms (bool, optional) -- If is True, the time will be returned in milliseconds.


update_interpolators()
Updates the internal X and Y position interpolators for the instance.


moviepy.video.tools.subtitles

Experimental module for subtitles support.

Classes

SubtitlesClip <#moviepy.video.tools.subtitles.SubtitlesClip>(subtitles[, font, ...]) A Clip that serves as "subtitle track" in videos.

moviepy.video.tools.subtitles.SubtitlesClip

class moviepy.video.tools.subtitles.SubtitlesClip(subtitles, font=None, make_textclip=None, encoding=None)
A Clip that serves as "subtitle track" in videos.

One particularity of this class is that the images of the subtitle texts are not generated beforehand, but only if needed.

Parameters
  • subtitles -- Either the name of a file as a string or path-like object, or a list
  • font -- Path to a font file to be used. Optional if make_textclip is provided.
  • make_textclip --

    A custom function to use for text clip generation. If None, a TextClip will be generated.

    The function must take a text as argument and return a VideoClip to be used as caption

  • encoding -- Optional, specifies srt file encoding. Any standard Python encoding is allowed (listed at <https://docs.python.org/3.8/library/codecs.html#standard-encodings>)


Examples

from moviepy.video.tools.subtitles import SubtitlesClip
from moviepy.video.io.VideoFileClip import VideoFileClip
generator = lambda text: TextClip(text, font='./path/to/font.ttf',

font_size=24, color='white') sub = SubtitlesClip("subtitles.srt", make_textclip=generator, encoding='utf-8') myvideo = VideoFileClip("myvideo.avi") final = CompositeVideoClip([clip, subtitles]) final.write_videofile("final.mp4", fps=myvideo.fps)


in_subclip(start_time=None, end_time=None)
Returns a sequence of [(t1,t2), text] covering all the given subclip from start_time to end_time. The first and last times will be cropped so as to be exactly start_time and end_time if possible.

match_expr(expr)
Matches a regular expression against the subtitles of the clip.

write_srt(filename)
Writes an .srt file with the content of the clip.


Functions

file_to_subtitles <#moviepy.video.tools.subtitles.file_to_subtitles>(filename[, encoding]) Converts a srt file into subtitles.

moviepy.video.tools.subtitles.file_to_subtitles

moviepy.video.tools.subtitles.file_to_subtitles(filename, encoding=None)
Converts a srt file into subtitles.

The returned list is of the form [((start_time,end_time),'some text'),...] and can be fed to SubtitlesClip.

Only works for '.srt' format for the moment.


The MoviePy Developer's Guide

This guide covers most of the things people wanting to participate in MoviePy development need to know.

Installation for MoviePy developers

Warning:

This part is only destined to people who want to build the MoviePy documentation by themselves, or to contribute to MoviePy. Normal users don't need it.


In addition to MoviePy main libraries, MoviePy developers will also need to install additional libraries to be able to run MoviePy tests and build the MoviePy documentation.

Libraries for documentation

You can install the libraries required to build documentation with:

$ (sudo) pip install moviepy[doc]


Once libraries installed you can build the documentation with:

$ python setup.py build_docs


Libraries for testing and linting

You can install the libraries required for testing and linting with:

$ (sudo) pip install moviepy[test]
$ (sudo) pip install moviepy[lint]


Once libraries installed you can test with:

$ python -m pytest


And you can lint with:

$ python -m black .


and

$ python3 -m flake8 -v --show-source --ignore=E501 moviepy docs/conf.py examples tests


Adding Git pre-commit hooks

Running linter manually is painfull and error prone, instead you should consider adding a pre-commit hook. To do so you can simply go in your local moviepy directory, and run :

This will enable a git hooks using python pre-commit framework.

MoviePy's Contribution Guidelines

Communication on GitHub

Keep messages on GitHub issues and pull requests on-topic and to the point. Be aware that each comment triggers a notification which gets sent out to a number of people.
  • Opinions are OK.
  • For longer or more in-depth discussions, use the MoviePy Gitter <https://gitter.im/Movie-py>. If these discussions lead to a decision, like a merge/reject, please leave a message on the relevant MoviePy issue to document the outcome of the discussion/the reason for the decision.


Do not push any commit that changes the API without prior discussion.

Preparing for development

  • Fork the official MoviePy repository to your own GitHub account: Use the "Fork" button in the top right corner of the GitHub interface while viewing the official MoviePy <https://github.com/Zulko/moviepy> repository.
  • Use your fork as the basis for cloning the repository to your local machine: $ git clone URL_TO_YOUR_FORK You can get the appropriate URL (SSH- or HTTPS-based) by using the green "Code" button located at the top right of the repository view while looking at your fork. By default, Git refers to any remote you clone from – i.e. in this case your fork on GitHub – as origin.
  • Enter your local clone and add the official MoviePy repository as a second remote, with alias upstream: $ git remote add upstream git@github.com:Zulko/moviepy.git (using SSL) _or_ $ git remote add upstream https://github.com/Zulko/moviepy.git (using HTTPS).
  • Install the library inside a virtual environment <https://docs.python.org/3/tutorial/venv.html> with all dependencies included using $ pip install -e ".[optional,doc,test,lint]"
  • Configure pre-commit hooks running $ pre-commit install

Coding conventions, code quality

  • Respect PEP8 <https://www.python.org/dev/peps/pep-0008/> conventions.
  • Add just the "right" amount of comments. Try to write auto-documented code with very explicit variable names.
  • If you introduce new functionality or fix a bug, document it in the docstring or with code comments.
  • MoviePy's team adopted pre-commit <https://pre-commit.com/> to run code checks using black, flake8 and isort, so make sure that you've configured the pre-commit hooks with pre-commit install.

Standard contribution workflow

Local development

  • Keep your local master branch up-to-date with the official repo's master by periodically fetching/pulling it: $ git pull upstream master
  • Never make changes on master directly, but branch off into separate develop branches: $ git checkout --branch YOUR_DEVELOP_BRANCH Ideally, these are given names which function as keywords for what you are working on, and are prefixed with fix_ (for bug fixes), feature_ or something similarly appropriate and descriptive.
  • Base any changes you submit on the most recent master.

More detailed explanation of the last point:

It is likely that the official repo's master branch will move on (get updated, have other PRs merged into it) while you are working on your changes. Before creating a pull request, you will have to make sure your changes are not based on outdated code. For this reason, it makes sense to avoid falling "too much behind" while developing by rebasing your local master branch at intervals. Make sure your master branch is in sync with the official master branch (as per the first point), then, while checked into your develop branch, run: $ git rebase master

If you haven't rebased before, make sure to familiarise yourself with the concept.

Submitting Pull Requests

You do not have to have finished your feature or bug fix before submitting a PR; just mention that it still is a work in progress.

Before submitting PRs:

  • run the test suite over your code to expose any problems: $ pytest
  • push your local develop branch to your GitHub fork $ git push origin YOUR_DEVELOP_BRANCH

When you now look at your forked repo on your GitHub account, you will see GitHub suggest branches for sending pull requests to the official Zulko/moviepy repository.

Once you open a PR, you will be presented with a template which you are asked to fill out. You are encouraged to add any additional information which helps provide further context to your changes, and to link to any issues or PRs which your pull request references or is informed by.

On submitting your PR, an automated test suite runs over your submission, which might take a few minutes to complete. In a next step, a MoviePy maintainer will review your code and, if necessary, help you to get it merge-ready.

Publishing a New Version of MoviePy

This section is for maintainers responsible for publishing new versions of MoviePy. Follow these steps to ensure the process is smooth and consistent:

Pre-requisites

Ensure you have proper permissions to push changes and create releases in the MoviePy repository.

Steps to Publish a New Version

1.
Update the `CHANGELOG.md`
  • Add a new section for the upcoming version, respecting the format used in previous entries.
  • Summarize all changes, fixes, and new features.

2.
Update the version in `pyproject.toml`
  • Open the pyproject.toml file.
  • Update the version field to the new version, following Semantic Versioning <https://semver.org/>.

3.
Commit and Push
Stage your changes:

git add CHANGELOG.md pyproject.toml


Commit your changes:

git commit -m "Release vX.Y.Z"


Push your changes:

git push



4.
Create a New Tag
Create a tag for the new version (replace vX.Y.Z with the actual version number):

git tag -a vX.Y.Z -m "Release vX.Y.Z"


Push the tag to the remote repository:

git push origin vX.Y.Z



5.
Create a New Release
  • Go to the repository's page on GitHub (or the relevant hosting platform).
  • Navigate to the "Releases" section and create a new release.
  • Use the new tag (vX.Y.Z) and provide a description for the release. - Copy the changelog for this version into the release description.
  • Publish the release.


GitHub actions will automatically build and publish the new release on PyPi.

By following these steps, you ensure that each MoviePy release is well-documented, correctly versioned, and accessible to users.

Author

Zulko

Copyright

2025, Zulko - MIT

July 3, 2026 2.2.1