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:
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:
##################### # 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:
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:
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:
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:
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:
######################## # 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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
Note:
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:
Note:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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.
moviepy.video.fx.Blink
- 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
..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:
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 |
