# Technical Documentation: Zulko/moviepy

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/Zulko/moviepy)

### Overview (README.md)

# MoviePy


[](https://pypi.org/project/moviepy/) [](Gitter_) [](https://github.com/Zulko/moviepy/actions/workflows/test_suite.yml) [](https://coveralls.io/github/Zulko/moviepy?branch=master)

> [!NOTE]
> MoviePy recently upgraded to v2.0, introducing major breaking changes. You can consult the last v1 docs [here](https://zulko.github.io/moviepy/v1.0.3/) but beware that v1 is no longer maintained. For more info on how to update your code from v1 to v2, see [this guide](https://zulko.github.io/moviepy/getting_started/updating_to_v2.html).

MoviePy (online documentation [here](https://zulko.github.io/moviepy/)) is a Python library for video editing: cuts, concatenations, title insertions, video compositing (a.k.a. non-linear editing), video processing, and creation of custom effects.

MoviePy can read and write all the most common audio and video formats, including GIF, and runs on Windows/Mac/Linux, with Python 3.9+.

# Example

In this example we open a video file, select the subclip between 10 and
20 seconds, add a title at the center of the screen, and write the
result to a new file:

``` python
from moviepy import VideoFileClip, TextClip, CompositeVideoClip

# Load file example.mp4 and keep only the subclip from 00:00:10 to 00:00:20
# Reduce the audio volume to 80% of its original volume

clip = (
    VideoFileClip("long_examples/example2.mp4")
    .subclipped(10, 20)
    .with_volume_scaled(0.8)
)

# Generate a text clip. You can customize the font, color, etc.
txt_clip = TextClip(
    font="Arial.ttf",
    text="Hello there!",
    font_size=70,
    color='white'
).with_duration(10).with_position('center')

# Overlay the text clip on the first video clip
final_video = CompositeVideoClip([clip, txt_clip])
final_video.write_videofile("result.mp4")
```

# How MoviePy works

Under the hood, MoviePy imports media (video frames, images, sounds) and converts them into Python objects (numpy arrays) so that every pixel becomes accessible, and video or audio effects can be defined in just a few lines of code (see the [built-in effects](https://zulko.github.io/moviepy/reference/reference/moviepy.video.fx.html) for examples).

The library also provides ways to mix clips together (concatenations, playing clips side by side or on top of each other with transparency, etc.). The final clip is then encoded back into mp4/webm/gif/etc.

This makes MoviePy very flexible and approachable, albeit slower than using ffmpeg directly due to heavier data import/export operations.  


# Installation

Intall moviepy with `pip install moviepy`. For additional installation options, such as a custom FFMPEG or for previewing, see [this section](https://zulko.github.io/moviepy/getting_started/install.html). For development, clone that repo locally and install with `pip install -e .`

# Documentation

The online documentation ([here](https://zulko.github.io/moviepy/)) is automatically built at every push to the master branch. To build the documentation locally, install the extra dependencies via `pip install "moviepy[doc]"`, then go to the `docs` folder and run `make html`.

# Contribute

MoviePy is open-source software originally written by
[Zulko](https://github.com/Zulko) and released under the MIT licence.
The project is hosted on [GitHub](https://github.com/Zulko/moviepy),
where everyone is welcome to contribute and open issues or give feedback Please read our [Contributing
Guidelines](https://github.com/Zulko/moviepy/blob/master/CONTRIBUTING.md).
To ask for help or simply discuss usage and examples, use [our Reddit channel](https://www.reddit.com/r/moviepy/).

# Maintainers

## Active maintainers
-   [Zulko](https://github.com/Zulko) (owner)
-   [@osaajani](https://github.com/OsaAjani) led the development of v2 ([MR](https://github.com/Zulko/moviepy/pull/2024))
-   [@tburrows13](https://github.com/tburrows13)
-   [@keikoro](https://github.com/keikoro)

## Past maintainers and thanks
-   [@mgaitan](https://github.com/mgaitan)
-   [@earney](https://github.com/earney)
-   [@mbeacom](https://github.com/mbeacom)
-   [@overdrivr](https://github.com/overdrivr)
-   [@ryanfox](https://github.com/ryanfox)
-   [@mondeja](https://github.com/mondeja)

**Maintainers wanted!** this library has only been kept afloat by the involvement of its maintainers, and there are times where none of us have enough bandwidth. We'd love to hear about developers interested in giving a hand and solving some of the issues (especially the ones that affect you) or reviewing pull requests. Open
an issue or contact us directly if you are interested. Thanks!

---

### Index (`docs/index.rst`)

:notoc:

***********************
MoviePy documentation
***********************

.. image:: /_static/medias/logo.png
    :width: 50%
    :align: center

**Date**: |today| **Version**: |version|

**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.

.. grid:: 1 2 2 2
    :gutter: 4
    :padding: 2 2 0 0
    :class-container: sd-text-center

    .. grid-item-card:: Getting started
        :img-top: _static/medias/index_getting_started.svg
        :class-card: intro-card
        :shadow: md

        New to *MoviePy*? Check out the getting started guides. They contain instructions
        to install *MoviePy* as well as introduction concepts and tutorials.

        +++

        .. button-ref:: getting_started
            :ref-type: ref
            :click-parent:
            :color: secondary
            :expand:

            To the starting guide

    .. grid-item-card::  User guide
        :img-top: _static/medias/index_user_guide.svg
        :class-card: intro-card
        :shadow: md

        The user guide provides in-depth information on the
        key concepts of *MoviePy* with useful background information and explanation.

        +++

        .. button-ref:: user_guide
            :ref-type: ref
            :click-parent:
            :color: secondary
            :expand:

            To the user guide

    .. grid-item-card::  API reference
        :img-top: _static/medias/index_api.svg
        :class-card: intro-card
        :shadow: md

        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.

        +++

        .. button-ref:: reference_manual
            :ref-type: ref
            :click-parent:
            :color: secondary
            :expand:

            To the reference guide

    .. grid-item-card::  Developer guide
        :img-top: _static/medias/index_contribute.svg
        :class-card: intro-card
        :shadow: md

        Saw a typo in the documentation? Want to improve
        existing functionalities? The contributing guidelines will guide
        you through the process of improving *MoviePy*.

        +++

        .. button-ref:: developer_guide
            :ref-type: ref
            :click-parent:
            :color: secondary
            :expand:

            To the development guide




Contribute!
--------------

MoviePy is an open source software originally written by Zulko_ and released under the MIT licence. It works on Windows, Mac, and Linux. 

.. raw:: html

    <a href="https://twitter.com/share" class="twitter-share-button"
    data-text="MoviePy - Video editing with Python" data-size="large" data-hashtags="MoviePy">Tweet
    </a>
    <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';
    if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';
    fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');
    </script>

    <iframe type="text/html" src="https://ghbtns.com/github-btn.html?user=Zulko&repo=moviepy&type=watch&count=true&size=large"
    allowtransparency="true" frameborder="0" scrolling="0" width="152px" height="30px"></iframe>


.. toctree::
    :maxdepth: 3
    :hidden:
    :titlesonly:


    getting_started/index
    user_guide/index
    reference/index
    developer_guide/index


.. _PyPI: https://pypi.python.org/pypi/moviepy
.. _Zulko: https://github.com/Zulko/
.. _Stackoverflow: https://stackoverflow.com/
.. _Github: https://github.com/Zulko/moviepy
.. _Reddit: https://www.reddit.com/r/moviepy/

---

### Developer Guide Contribution Guidelines (`docs/developer_guide/contribution_guidelines.rst`)

.. _contribution_guidelines:

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.

---

### Developer Guide Developers Install (`docs/developer_guide/developers_install.rst`)

.. _developers_install:

Installation for MoviePy developers
======================================

.. warning::
    This part is only destined to people who want to build the MoviePy documentation by themselves, or to contribute to MoviePy. Normal users don't need it.

In addition to MoviePy main libraries, MoviePy developers will also need to install additional libraries to be able to run MoviePy tests and build the MoviePy documentation.

Libraries for documentation
-----------------------------

You can install the libraries required to build documentation with: 

.. code:: bash

    $ (sudo) pip install moviepy[doc]

Once libraries installed you can build the documentation with:

.. code:: bash

    $ python setup.py build_docs


Libraries for testing and linting
-------------------------------------

You can install the libraries required for testing and linting with:

.. code:: bash

    $ (sudo) pip install moviepy[test]
    $ (sudo) pip install moviepy[lint]

Once libraries installed you can test with:

.. code:: bash

    $ python -m pytest

And you can lint with:

.. code:: bash

    $ python -m black .

and 

.. code:: bash

    $ 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 :

.. code:: bash
    $ pre-commit install

This will enable a git hooks using python pre-commit framework.

---

### Developer Guide Index (`docs/developer_guide/index.rst`)

.. _developer_guide:

The MoviePy Developer's Guide
-----------------------------

This guide covers most of the things people wanting to participate in MoviePy development need to know.

.. toctree::
   :maxdepth: 1
   
   developers_install
   contribution_guidelines
   maintainers_publish

---

### Developer Guide Maintainers Publish (`docs/developer_guide/maintainers_publish.rst`)

.. _maintainers_publish:

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.

---

### Getting Started FAQ (`docs/getting_started/FAQ.rst`)

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_, or on the dedicated Subreddit_.


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 :ref:`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.

.. _Github: https://github.com/Zulko/moviepy
.. _Subreddit: https://www.reddit.com/r/moviepy/

---

### Getting Started Docker (`docs/getting_started/docker.rst`)

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

---

### Getting Started Index (`docs/getting_started/index.rst`)

.. _getting_started:

Getting started with MoviePy
------------------------------

This section explain everything you need to start editing with MoviePy. To go further, have a look at the :ref:`user_guide` and the :ref:`reference_manual`.


.. toctree::
   :maxdepth: 1

   install
   quick_presentation
   moviepy_10_minutes
   docker
   updating_to_v2
   FAQ

---

### Getting Started Install (`docs/getting_started/install.rst`)

.. _install:

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:

.. code:: bash

    $ (sudo) pip install moviepy

.. _install-binaries:

Installation of Additional Binaries
-----------------------------------

MoviePy depends on the software ffmpeg_ for video reading and writing and on ``ffplay`` for video previewing.

You don't need to worry about ffmpeg_, 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:

.. code-block:: python

    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

.. code-block:: ini

    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:

    .. code-block:: python

        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:

.. code:: python

    from moviepy.config import check
    check()

.. _ffmpeg: https://www.ffmpeg.org/download.html

---

### Getting Started Moviepy 10 Minutes (`docs/getting_started/moviepy_10_minutes.rst`)

.. _moviepy_10_minutes:

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

.. note::
   This tutorial aims to be a simple and short introduction for new users wishing to use MoviePy. For a more in-depth exploration of the concepts seen in this tutorial, see :ref:`user_guide`.

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

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; padding-top: 30px; margin-bottom:30px; height: 0; overflow: hidden; margin-left: 5%;">
      <video controls>
         <source src="/moviepy/_static/medias/getting_started/moviepy_10_minutes/trailer_bbb.mp4" type="video/mp4">
         <p>Your browser does not support HTML5 video in MP4 format.</p>
      </video>
   </div>

Prerequisites
-------------

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

.. code-block:: shell

   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 :download:`the project template </_static/medias/getting_started/moviepy_10_minutes/moviepy_10_minutes.zip>` 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:

.. literalinclude:: /_static/code/getting_started/moviepy_10_minutes/trailer.py
   :language: python
   :lines: 1-10

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 :py:class:`~moviepy.video.VideoClip.VideoClip` for any visual element, and an :py:class:`~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 :ref:`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:

.. literalinclude:: /_static/code/getting_started/moviepy_10_minutes/trailer.py
   :language: python
   :lines: 13-25

Here, we use the ``subclipped`` 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 :py:class:`~moviepy.audio.AudioClip.AudioClip`).

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

.. literalinclude:: /_static/code/getting_started/moviepy_10_minutes/trailer.py
   :language: python
   :lines: 28-38

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 :py:class:`~moviepy.audio.AudioClip.AudioClip` and added to your video clip.

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

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

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

.. literalinclude:: /_static/code/getting_started/moviepy_10_minutes/trailer.py
   :language: python
   :lines: 41-54

In that particular case, we have used the ``with_section_cut_out``, 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 :ref:`reference_manual`.

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

Step 5: Creating Text/Logo Clips
------------------------------------

In addition to videos, we often need to work with images and texts. MoviePy offers some specialized kinds of :py:class:`~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.

.. literalinclude:: /_static/code/getting_started/moviepy_10_minutes/trailer.py
    :language: python
    :lines: 56-82

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

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

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.

.. literalinclude:: /_static/code/getting_started/moviepy_10_minutes/trailer.py
    :language: python
    :lines: 85-111

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

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

Step 7: Seeing How All Clips Combine
------------------------------------

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

:py:class:`~moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip` takes an array of clips as input and will play them on top of each other at render time, starting and stopping each clip at its start and end points.

.. note::
   If possible, :py:class:`~moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip` will extract endpoint and size from the biggest/last ending clip. If a clip in the list has no duration, then you will have to manually set the duration of :py:class:`~moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip` before rendering.

.. literalinclude:: /_static/code/getting_started/moviepy_10_minutes/trailer.py
    :language: python
    :lines: 114-136

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 :py:class:`~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``.

.. literalinclude:: /_static/code/getting_started/moviepy_10_minutes/trailer.py
    :language: python
    :lines: 139-174

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

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

Step 9: Adding Transitions and Effects
--------------------------------------

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

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

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

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

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

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

.. literalinclude:: /_static/code/getting_started/moviepy_10_minutes/trailer.py
    :language: python
    :lines: 177-239

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 :py:mod:`moviepy.video.fx`, :py:mod:`moviepy.audio.fx`, and :ref:`create_effects`.

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

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

   For more info, see :ref:`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 :py:meth:`~moviepy.video.VideoClip.VideoClip.image_transform` method.

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

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

.. warning::
   This is a bit of an advanced usage, and the example involves matrix multiplication. If this is too much for you, you can simply ignore it until you really need to make custom filters, then go look for a more detailed explanation on how to do filtering (:ref:`modifying#filters`) and create custom effects (:ref:`create_effects`) in the user guide.

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

.. literalinclude:: /_static/code/getting_started/moviepy_10_minutes/trailer.py
    :language: python
    :lines: 242-283

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 :py:meth:`~moviepy.video.VideoClip.VideoClip.write_videofile` for more info.

.. literalinclude:: /_static/code/getting_started/moviepy_10_minutes/trailer.py
    :language: python
    :lines: 286-307

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 :ref:`user_guide`, as well as looking directly at the :ref:`reference_manual`.

---

### Getting Started Quick Presentation (`docs/getting_started/quick_presentation.rst`)

.. _quick_presentation:

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_, OpenCV_ 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: 

.. literalinclude:: /_static/code/getting_started/quick_presentation/basic_example.py
    :language: python


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:: /_static/medias/getting_started/explanations.jpeg
    :width: 570px
    :align: center


The central concept, the clips
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The central object of MoviePy is the the :py:class:`Clip <moviepy.Clip.Clip>`, with either :py:class:`~moviepy.audio.AudioClip.AudioClip` for any audio element, or :py:class:`~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:   

#. Load different resources as clips (see :ref:`loading`)
#. Modify them (see :ref:`modifying`)
#. Mixing them into one final clip (see :ref:`compositing`)
#. Render them into a file (see :ref:`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 :ref:`create_effects`)!


.. _imageio: https://imageio.github.io/
.. _OpenCV: http://opencv.org/

---

### Getting Started Updating To V2 (`docs/getting_started/updating_to_v2.rst`)

.. _updating_to_v2:

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:

.. code-block:: python

    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 :py:class:`~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 :ref:`create_effects`.

Moving from ``clip.fx`` to :py:meth:`~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 :py:meth:`~moviepy.Clip.Clip.with_effects`.

For more information on how to use effects with v2.0, see :ref:`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 :py:meth:`~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>`_.

---

### Reference Index (`docs/reference/index.rst`)

.. _reference_manual:


Api Reference
================

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

For a more beginner introduction, please see :ref:`getting_started`, for a more detailed explanations of the different concepts in MoviePy,
see :ref:`user_guide`.

.. autosummary::
   :toctree: reference
   :recursive:
   :template: custom_autosummary/module.rst

   moviepy

---

### User Guide Compositing (`docs/user_guide/compositing.rst`)

.. _compositing:

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:

.. raw:: html

    <div style="position: relative; padding-bottom: 56.25%; padding-top: 30px; margin-bottom:30px; height: 0; overflow: hidden; margin-left:15%;">
        <iframe type="text/html" src="https://youtube.com/embed/rIehsqqYFEM?rel=0" frameborder="0"
        style="position: absolute; top: 0; bottom: 10; width: 70%; height: 100%; "></iframe>
    </div>

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

Juxtaposing and Concatenating Clips
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

Concatenating Multiple Clips
"""""""""""""""""""""""""""""""""

Concatenation can be done very easily with the function :py:func:`~moviepy.video.compositing.CompositeVideoClip.concatenate_videoclips`.

.. literalinclude:: /_static/code/user_guide/compositing/concatenate.py
    :language: python

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

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

For more info, see :py:func:`~moviepy.video.compositing.CompositeVideoClip.concatenate_videoclips`.

Juxtaposing Multiple Clips
""""""""""""""""""""""""""""""

Putting multiple clips side by side is done with :py:func:`~moviepy.video.compositing.CompositeVideoClip.clip_array`:

.. literalinclude:: /_static/code/user_guide/compositing/juxtaposing.py
    :language: python

You obtain a clip which looks like this:

.. figure:: /_static/medias/user_guide/stacked.jpeg
   :align: center

For more info, see :py:func:`~moviepy.video.compositing.CompositeVideoClip.clip_array`.

More Complex Video Compositing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The :py:class:`~moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip` class is the base of all video compositing.
For example, internally, both :py:func:`~moviepy.video.compositing.CompositeVideoClip.concatenate_videoclips` and :py:func:`~moviepy.video.compositing.CompositeVideoClip.clip_array` create a :py:class:`~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 :py:class:`~moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip`. Here's an example:

.. literalinclude:: /_static/code/user_guide/compositing/CompositeVideoClip.py
    :language: python

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

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

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

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

For more info, see :py:class:`~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:

.. literalinclude:: /_static/code/user_guide/compositing/with_start.py
    :language: python

.. note::
    When working with timing of your clips, you will frequently want to keep only parts of the original clip.
    To do so, you should take a look at :py:meth:`~moviepy.Clip.Clip.subclipped` and :py:meth:`~moviepy.Clip.Clip.with_section_cut_out`.

Positioning Clips
""""""""""""""""""

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

You can do so by using the :py:meth:`~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:

.. literalinclude:: /_static/code/user_guide/compositing/with_position.py
    :language: python

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

.. figure:: /_static/medias/user_guide/videoWH.jpeg

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 :py:mod:`~moviepy.video.compositing.transitions`, like :py:func:`~moviepy.video.compositing.transitions.crossfadein`:

.. literalinclude:: /_static/code/user_guide/compositing/crossfadein.py
    :language: python

MoviePy offers only a few transitions in :py:mod:`~moviepy.video.compositing.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 :py:mod:`moviepy.video.fx`).

For more info, see :py:mod:`~moviepy.video.compositing.transitions` and :py:mod:`~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 :py:class:`~moviepy.audio.AudioClip.CompositeAudioClip` and :py:func:`~moviepy.audio.AudioClip.concatenate_audioclips`:

.. literalinclude:: /_static/code/user_guide/compositing/CompositeAudioClip.py
    :language: python

---

### User Guide Create Effects (`docs/user_guide/create_effects.rst`)

.. _create_effects:

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 :ref:`modify <filters>`. 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 :py:func:`~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 :py:class:`moviepy.Effect.Effect`, which is the base abstract class for all effects (similar to how :py:class:`~moviepy.Clip.Clip` is the base for all :py:class:`~moviepy.video.VideoClip.VideoClip` and :py:class:`~moviepy.audio.AudioClip.AudioClip`).

So, to create an effect, we will need to inherit the :py:class:`~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 :py:meth:`~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 :py:func:`~moviepy.Clip.Clip.time_transform`, :py:func:`~moviepy.Clip.Clip.image_transform`, or :py:func:`~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:

.. literalinclude:: /_static/code/user_guide/effects/custom_effect.py
    :language: python

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

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

---

### User Guide Index (`docs/user_guide/index.rst`)

.. _user_guide:

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 :ref:`getting_started` section, and more specifically the :ref:`moviepy_10_minutes` tutorial.

For a full overview of MoviePy, see the :ref:`reference_manual`.

.. toctree::
   :maxdepth: 1
   
   loading
   modifying
   create_effects
   compositing
   rendering

---

### User Guide Loading (`docs/user_guide/loading.rst`)

.. _loading:

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 :ref:`modifying`. For how to put clips together, see :ref:`compositing`. And for how to see/save them, see :ref:`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 :py:class:`~moviepy.Clip.Clip`, and more precisely of :py:class:`~moviepy.audio.AudioClip.AudioClip` for any audio element, or :py:class:`~moviepy.video.VideoClip.VideoClip` for any visual element.

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

.. literalinclude:: /_static/code/user_guide/loading/loading.py
    :language: python

To understand all these clips more thoroughly, read the full documentation for each in the :ref:`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 :py:class:`~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.

.. literalinclude:: /_static/code/user_guide/loading/closing.py
    :language: python

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 :py:class:`~moviepy.video.VideoClip.VideoFileClip`, :py:class:`~moviepy.video.VideoClip.VideoClip`, and :py:class:`~moviepy.video.io.ImageSequenceClip.ImageSequenceClip`), which will always have duration.
* Unanimated clips (made with :py:class:`~moviepy.video.VideoClip.ImageClip`, :py:class:`~moviepy.video.VideoClip.TextClip`, and :py:class:`~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 (:py:class:`~moviepy.audio.AudioClip.AudioClip`) in :py:attr:`~moviepy.video.VideoClip.VideoClip.audio` which is its *soundtrack*, and a mask clip in :py:attr:`~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
"""""""""

:py:class:`~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/>`_.

.. literalinclude:: /_static/code/user_guide/loading/VideoClip.py
    :language: python

Resulting in this:

.. image:: /_static/medias/user_guide/circle.gif
   :width: 128 px
   :align: center
   :alt: A pulsating red circle on black background.

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

For more, see :py:class:`~moviepy.video.VideoClip.VideoClip`.

VideoFileClip
"""""""""""""""

A :py:class:`~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:

.. literalinclude:: /_static/code/user_guide/loading/VideoFileClip.py
    :language: python

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

For more, see :py:class:`~moviepy.video.io.VideoFileClip.VideoFileClip`.

ImageSequenceClip
""""""""""""""""""

This :py:class:`~moviepy.video.io.ImageSequenceClip.ImageSequenceClip` is a clip made from a series of images:

.. literalinclude:: /_static/code/user_guide/loading/ImageSequenceClip.py
    :language: python

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

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

For more, see :py:class:`~moviepy.video.io.ImageSequenceClip.ImageSequenceClip`.

DataVideoClip
"""""""""""""""

:py:class:`~moviepy.video.io.VideoClip.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 :py:class:`~moviepy.video.VideoClip.VideoClip`, where you make frames not based on time, but based on each entry of a data list.

.. literalinclude:: /_static/code/user_guide/loading/DataVideoClip.py
    :language: python

For more, see :py:class:`~moviepy.video.io.VideoClip.DataVideoClip`.

UpdatedVideoClip
""""""""""""""""""

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

:py:class:`~moviepy.video.io.VideoClip.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:

#. It has a ``clip_t`` property, indicating the current world time.
#. 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.
#. It has a ``to_frame()`` method, that will render a frame based on the world's current state.

On :py:meth:`~moviepy.video.io.VideoClip.UpdatedVideoClip.get_frame` call, your :py:class:`~moviepy.video.io.VideoClip.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()``.

.. literalinclude:: /_static/code/user_guide/loading/UpdatedVideoClip.py
    :language: python

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
"""""""""

:py:class:`~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 :py:class:`~moviepy.video.io.VideoFileClip.VideoFileClip`, it's one of the most used kinds of clips.

You can create one as follows:

.. literalinclude:: /_static/code/user_guide/loading/ImageClip.py
    :language: python

For more, see :py:class:`~moviepy.video.VideoClip.ImageClip`.

TextClip
"""""""""

A :py:class:`~moviepy.video.VideoClip.TextClip` is a clip that will turn a text string into an image clip.

:py:class:`~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 :py:class:`~moviepy.video.VideoClip.TextClip`:

.. literalinclude:: /_static/code/user_guide/loading/TextClip.py
    :language: python

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

For a more detailed explanation of all the parameters, see :py:class:`~moviepy.video.VideoClip.TextClip`.

ColorClip
"""""""""

A :py:class:`~moviepy.video.VideoClip.ColorClip` is a clip that will return an image of only one color. It is sometimes useful when doing compositing (see :ref:`compositing`).

.. literalinclude:: /_static/code/user_guide/loading/ColorClip.py
    :language: python

For more, see :py:class:`~moviepy.video.VideoClip.ColorClip`.

.. _loading#masks:

Mask Clips
~~~~~~~~~~~~~~

Masks are a special kind of :py:class:`~moviepy.video.VideoClip.VideoClip` with the property ``is_mask`` set to ``True``. They can be attached to any other kind of :py:class:`~moviepy.video.VideoClip.VideoClip` through method :py:meth:`~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 :ref:`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:

.. literalinclude:: /_static/code/user_guide/loading/masks.py
    :language: python

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

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

Any video clip can be turned into a mask with :py:meth:`~moviepy.video.VideoClip.VideoClip.to_mask`, and a mask can be turned to a standard RGB video clip with :py:meth:`~moviepy.video.VideoClip.VideoClip.to_RGB()`.

Masks are treated differently by many methods (because their frames are different) but at the core, they are :py:class:`~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 :py:class:`~moviepy.video.VideoClip.VideoClip` for visuals, you can use audio elements, like an audio file, using the :py:class:`~moviepy.audio.AudioClip.AudioClip` class.

Both are quite similar, except :py:class:`~moviepy.audio.AudioClip.AudioClip` method :py:meth:`~moviepy.audio.AudioClip.AudioClip.get_frame` returns a numpy array of size ``Nx1`` for mono, and size ``Nx2`` for stereo.

AudioClip
~~~~~~~~~~

:py:class:`~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``.

.. literalinclude:: /_static/code/user_guide/loading/AudioClip.py
    :language: python

For more, see :py:class:`~moviepy.audio.AudioClip.AudioClip`.

AudioFileClip
"""""""""""""""""

:py:class:`~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:

.. literalinclude:: /_static/code/user_guide/loading/AudioFileClip.py
    :language: python

For more, see :py:class:`~moviepy.audio.io.AudioFileClip.AudioFileClip`.

AudioArrayClip
"""""""""""""""""

:py:class:`~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.

.. literalinclude:: /_static/code/user_guide/loading/AudioArrayClip.py
    :language: python

For more, see :py:class:`~moviepy.audio.AudioClip.AudioArrayClip`.

---

### User Guide Modifying (`docs/user_guide/modifying.rst`)

.. _modifying:

Modifying clips and apply effects
===================================

Of course, once you will have loaded a :py:class:`~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 :py:class:`~moviepy.video.VideoClip.VideoClip` or :py:class:`~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 :py:func:`~moviepy.Clip.Clip.transform` and :py:func:`~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:

.. literalinclude:: /_static/code/user_guide/effects/modify_copy_example.py
    :language: python

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 :py:meth:`clip.subclipped(t_start, t_end) <moviepy.Clip.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:

.. literalinclude:: /_static/code/user_guide/effects/using_with_methods.py
    :language: python

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

- :py:meth:`~moviepy.video.VideoClip.VideoClip.resized`
- :py:meth:`~moviepy.video.VideoClip.VideoClip.crop`
- :py:meth:`~moviepy.video.VideoClip.VideoClip.rotate`

For a list of all those methods, see :py:class:`~moviepy.Clip.Clip` and :py:class:`~moviepy.video.VideoClip.VideoClip`.


.. _modifying#effects:

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 :py:mod:`moviepy.video.fx` for visual effects and :py:mod:`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 :py:class:`~moviepy.Clip.Clip` using method :py:meth:`~moviepy.Clip.Clip.with_effects`, with a list of :py:class:`~moviepy.Effect.Effect` objects you want to apply. 

For convenience the effects are also dynamically added as method of :py:class:`~moviepy.video.VideoClip.VideoClip` and :py:class:`~moviepy.video.AudioClip.AudioClip`  classes at runtime, letting you call them as simple method of your clip.

So, you may write something like:

.. literalinclude:: /_static/code/user_guide/effects/using_effects.py
    :language: python

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

For a list of those effects, see :py:mod:`moviepy.video.fx` and :py:mod:`moviepy.audio.fx`.

In addition to the effects already provided by MoviePy, you can obviously :ref:`create_effects` and use them the same way.

.. _modifying#filters:

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 :py:func:`~moviepy.Clip.Clip.time_transform`, :py:func:`~moviepy.Clip.Clip.image_transform`, and more generally with :py:func:`~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 :py:meth:`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:

.. literalinclude:: /_static/code/user_guide/effects/time_transform.py
    :language: python

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

.. note::
    By default :py:func:`~moviepy.Clip.Clip.time_transform` will only modify the clip main frame, without modifying clip audio or mask for :py:class:`~moviepy.video.VideoClip.VideoClip`. 
    
    If you wish to also modify audio and/or mask you can provide the parameter ``apply_to`` with either ``'audio'``, ``'mask'``, or ``['audio', 'mask']``. 


Modifying only the appearance of a Clip
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For :py:class:`~moviepy.video.VideoClip.VideoClip`, you can change the appearance of the clip with :py:meth:`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:

.. literalinclude:: /_static/code/user_guide/effects/image_transform.py
    :language: python

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

.. note::
    You can define if transformation should be applied to audio and mask same as for :py:func:`~moviepy.Clip.Clip.time_transform`.

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


Modifying both the appearance and the timing of a Clip
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Finally, you may want to process the clip by taking into account both the time and the frame picture, for example to apply visual effects variating with time. 
This is possible with the method :py:meth:`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.

.. literalinclude:: /_static/code/user_guide/effects/transform.py
    :language: python

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

.. note::
    You can define if transformation should be applied to audio and mask same as for :py:func:`~moviepy.Clip.Clip.time_transform`. 

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

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

---

### User Guide Rendering (`docs/user_guide/rendering.rst`)

.. _rendering:

Previewing and Saving Video Clips
=================================

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

Previewing a Clip
-----------------

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

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

Preview a Clip as a Video
~~~~~~~~~~~~~~~~~~~~~~~~~

.. warning::
    You must have ``ffplay`` installed and accessible to MoviePy to be able to use :py:func:`~moviepy.video.io.preview.preview`.
    If you're not sure, take a look :ref:`install#binaries`

The first thing you can do is to preview your clip as a video by calling the method :py:func:`~moviepy.video.io.preview.preview` on your clip:

.. literalinclude:: /_static/code/user_guide/rendering/preview.py
    :language: python

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 :py:meth:`~moviepy.Clip.Clip.subclip`.

.. note::
    It is quite frequent for a clip preview to be out of sync or to play slower than it should. This indicates that your computer is not powerful enough to render the clip in real-time.
    
    Don't hesitate to play with the options of preview: for instance, lower the fps of the sound (11000 Hz is still fine) and the video. Also, downsizing your video with :py:meth:`~moviepy.video.VideoClip.VideoClip.resize` can help.

For more information, see :py:func:`~moviepy.video.io.preview.preview`.

.. note::
    A quite similar function is also available for :py:func:`~moviepy.audio.AudioClip.AudioClip`, see :py:func:`~moviepy.audio.io.ffplay_audiopreviewer.ffplay_audiopreview`.

Preview Just One Frame of a Clip
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

To do so, you can use the method :py:func:`~moviepy.video.io.preview.show` on your clip, passing the frame time as an argument:

.. literalinclude:: /_static/code/user_guide/rendering/show.py
    :language: python

Contrary to video previewing, :py:func:`~moviepy.video.io.preview.show` does not require ``ffplay`` but uses the ``pillow`` ``Image.show`` function.

For more information, see :py:func:`~moviepy.video.io.preview.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 :py:func:`~moviepy.video.io.display_in_notebook.display_in_notebook` on your clip.

.. image:: /_static/medias/user_guide/demo_preview.jpeg
    :width: 500px
    :align: center

With :py:func:`~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:

.. literalinclude:: /_static/code/user_guide/rendering/display_in_notebook.py
    :language: python

.. warning::
    Note that :py:func:`~moviepy.video.io.display_in_notebook.display_in_notebook` will only work if it is on the last line of the notebook cell. 

    Also, note that :py:func:`~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 :py:func:`~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 :py:meth:`~moviepy.video.VideoClip.VideoClip.write_videofile`:

.. literalinclude:: /_static/code/user_guide/rendering/write_videofile.py
    :language: python

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 :py:meth:`~moviepy.video.VideoClip.VideoClip.write_videofile`.

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

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

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

.. literalinclude:: /_static/code/user_guide/rendering/write_videofile_duration.py
    :language: python

.. note::
    A quite similar function is also available for :py:func:`~moviepy.audio.AudioClip.AudioClip`, see :py:func:`~moviepy.audio.io.AudioClip.write_audiofile`.

Export a Single Frame of the Clip
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

As with previewing, sometimes you will need to export only one frame of a clip, for example to create the preview image of a video. You can do so with :py:meth:`~moviepy.video.VideoClip.VideoClip.save_frame`:

.. literalinclude:: /_static/code/user_guide/rendering/save_frame.py
    :language: python

For more information, see :py:func:`~moviepy.video.VideoClip.VideoClip.save_frame`.

Animated GIFs
~~~~~~~~~~~~~

In addition to writing video files, MoviePy also lets you write GIF files with :py:meth:`~moviepy.video.VideoClip.VideoClip.write_gif`:

.. literalinclude:: /_static/code/user_guide/rendering/write_gif.py
    :language: python

For more information, see :py:func:`~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 :py:meth:`~moviepy.video.VideoClip.VideoClip.write_images_sequence`:

.. literalinclude:: /_static/code/user_guide/rendering/write_images_sequence.py
    :language: python

For more information, see :py:func:`~moviepy.video.VideoClip.VideoClip.write_images_sequence`.
```

---

###  Templates Custom Autosummary Class (`docs/_templates/custom_autosummary/class.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

{{ fullname | escape | underline}}

.. currentmodule:: {{ module }}

.. autoclass:: {{ objname }}
   :members:

---

###  Templates Custom Autosummary Module (`docs/_templates/custom_autosummary/module.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
{{ fullname | escape | underline}}

{% if fullname in ['moviepy.Effect'] or '.fx.' in fullname %} {# Fix for autosummary to document abstract class #}
.. automodule:: {{ fullname }}
   :inherited-members:
{% else %}
.. automodule:: {{ fullname }}
{% endif %}
   

   {% block classes %}
   {% if classes %}
   .. rubric:: {{ _('Classes') }}

   .. autosummary::
      :toctree:
      :template: custom_autosummary/class.rst
   {% for item in classes %}
      {{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}


   {% block functions %}
   {% if functions %}
   .. rubric:: {{ _('Functions') }}

   .. autosummary::
      :toctree:
   {% for item in functions %}
      {{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}


   {% block exceptions %}
   {% if exceptions %}
   .. rubric:: {{ _('Exceptions') }}

   .. autosummary::
   {% for item in exceptions %}
      {{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

{% block modules %}
{% if modules %}
.. rubric:: Modules

.. autosummary::
   :toctree:
   :template: custom_autosummary/module.rst
   :recursive:
{% for item in modules %}
{% if not item in ['moviepy.version'] %}
   {{ item }}
{% endif %}
{%- endfor %}
{% endif %}
{% endblock %}

---

### Reference Reference Moviepy.Clip.Clip (`docs/reference/reference/moviepy.Clip.Clip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.Clip.Clip
=================

.. currentmodule:: moviepy.Clip

.. autoclass:: Clip
   :members:

---

### Reference Reference Moviepy.Clip (`docs/reference/reference/moviepy.Clip.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.Clip
============


.. automodule:: moviepy.Clip

   

   
   
   .. rubric:: Classes

   .. autosummary::
      :toctree:
      :template: custom_autosummary/class.rst
   
      Clip

---

### Reference Reference Moviepy.Effect (`docs/reference/reference/moviepy.Effect.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.Effect
==============

 
.. automodule:: moviepy.Effect
   :inherited-members:

---

### Reference Reference Moviepy.Audio.AudioClip.AudioArrayClip (`docs/reference/reference/moviepy.audio.AudioClip.AudioArrayClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.audio.AudioClip.AudioArrayClip
======================================

.. currentmodule:: moviepy.audio.AudioClip

.. autoclass:: AudioArrayClip
   :members:

---

### Reference Reference Moviepy.Audio.AudioClip.AudioClip (`docs/reference/reference/moviepy.audio.AudioClip.AudioClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.audio.AudioClip.AudioClip
=================================

.. currentmodule:: moviepy.audio.AudioClip

.. autoclass:: AudioClip
   :members:

---

### Reference Reference Moviepy.Audio.AudioClip.CompositeAudioClip (`docs/reference/reference/moviepy.audio.AudioClip.CompositeAudioClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.audio.AudioClip.CompositeAudioClip
==========================================

.. currentmodule:: moviepy.audio.AudioClip

.. autoclass:: CompositeAudioClip
   :members:

---

### Reference Reference Moviepy.Audio.AudioClip.Concatenate Audioclips (`docs/reference/reference/moviepy.audio.AudioClip.concatenate_audioclips.rst`)

moviepy.audio.AudioClip.concatenate\_audioclips
===============================================

.. currentmodule:: moviepy.audio.AudioClip

.. autofunction:: concatenate_audioclips

---

### Reference Reference Moviepy.Audio.AudioClip (`docs/reference/reference/moviepy.audio.AudioClip.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.AudioClip
=======================


.. automodule:: moviepy.audio.AudioClip

   

   
   
   .. rubric:: Classes

   .. autosummary::
      :toctree:
      :template: custom_autosummary/class.rst
   
      AudioArrayClip
      AudioClip
      CompositeAudioClip
   
   


   
   
   .. rubric:: Functions

   .. autosummary::
      :toctree:
   
      concatenate_audioclips

---

### Reference Reference Moviepy.Audio.Fx.AudioDelay (`docs/reference/reference/moviepy.audio.fx.AudioDelay.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.fx.AudioDelay
===========================

 
.. automodule:: moviepy.audio.fx.AudioDelay
   :inherited-members:

---

### Reference Reference Moviepy.Audio.Fx.AudioFadeIn (`docs/reference/reference/moviepy.audio.fx.AudioFadeIn.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.fx.AudioFadeIn
============================

 
.. automodule:: moviepy.audio.fx.AudioFadeIn
   :inherited-members:

---

### Reference Reference Moviepy.Audio.Fx.AudioFadeOut (`docs/reference/reference/moviepy.audio.fx.AudioFadeOut.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.fx.AudioFadeOut
=============================

 
.. automodule:: moviepy.audio.fx.AudioFadeOut
   :inherited-members:

---

### Reference Reference Moviepy.Audio.Fx.AudioLoop (`docs/reference/reference/moviepy.audio.fx.AudioLoop.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.fx.AudioLoop
==========================

 
.. automodule:: moviepy.audio.fx.AudioLoop
   :inherited-members:

---

### Reference Reference Moviepy.Audio.Fx.AudioNormalize (`docs/reference/reference/moviepy.audio.fx.AudioNormalize.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.fx.AudioNormalize
===============================

 
.. automodule:: moviepy.audio.fx.AudioNormalize
   :inherited-members:

---

### Reference Reference Moviepy.Audio.Fx.MultiplyStereoVolume (`docs/reference/reference/moviepy.audio.fx.MultiplyStereoVolume.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.fx.MultiplyStereoVolume
=====================================

 
.. automodule:: moviepy.audio.fx.MultiplyStereoVolume
   :inherited-members:

---

### Reference Reference Moviepy.Audio.Fx.MultiplyVolume (`docs/reference/reference/moviepy.audio.fx.MultiplyVolume.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.fx.MultiplyVolume
===============================

 
.. automodule:: moviepy.audio.fx.MultiplyVolume
   :inherited-members:

---

### Reference Reference Moviepy.Audio.Fx (`docs/reference/reference/moviepy.audio.fx.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.fx
================


.. automodule:: moviepy.audio.fx

   

   
   
   


   
   
   


   
   
   



.. rubric:: Modules

.. autosummary::
   :toctree:
   :template: custom_autosummary/module.rst
   :recursive:


   moviepy.audio.fx.AudioDelay


   moviepy.audio.fx.AudioFadeIn


   moviepy.audio.fx.AudioFadeOut


   moviepy.audio.fx.AudioLoop


   moviepy.audio.fx.AudioNormalize


   moviepy.audio.fx.MultiplyStereoVolume


   moviepy.audio.fx.MultiplyVolume

---

### Reference Reference Moviepy.Audio.Io.AudioFileClip.AudioFileClip (`docs/reference/reference/moviepy.audio.io.AudioFileClip.AudioFileClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.audio.io.AudioFileClip.AudioFileClip
============================================

.. currentmodule:: moviepy.audio.io.AudioFileClip

.. autoclass:: AudioFileClip
   :members:

---

### Reference Reference Moviepy.Audio.Io.AudioFileClip (`docs/reference/reference/moviepy.audio.io.AudioFileClip.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.io.AudioFileClip
==============================


.. automodule:: moviepy.audio.io.AudioFileClip

   

   
   
   .. rubric:: Classes

   .. autosummary::
      :toctree:
      :template: custom_autosummary/class.rst
   
      AudioFileClip

---

### Reference Reference Moviepy.Audio.Io.Ffmpeg Audiowriter.FFMPEG AudioWriter (`docs/reference/reference/moviepy.audio.io.ffmpeg_audiowriter.FFMPEG_AudioWriter.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.audio.io.ffmpeg\_audiowriter.FFMPEG\_AudioWriter
========================================================

.. currentmodule:: moviepy.audio.io.ffmpeg_audiowriter

.. autoclass:: FFMPEG_AudioWriter
   :members:

---

### Reference Reference Moviepy.Audio.Io.Ffmpeg Audiowriter.Ffmpeg Audiowrite (`docs/reference/reference/moviepy.audio.io.ffmpeg_audiowriter.ffmpeg_audiowrite.rst`)

moviepy.audio.io.ffmpeg\_audiowriter.ffmpeg\_audiowrite
=======================================================

.. currentmodule:: moviepy.audio.io.ffmpeg_audiowriter

.. autofunction:: ffmpeg_audiowrite

---

### Reference Reference Moviepy.Audio.Io.Ffmpeg Audiowriter (`docs/reference/reference/moviepy.audio.io.ffmpeg_audiowriter.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.io.ffmpeg\_audiowriter
====================================


.. automodule:: moviepy.audio.io.ffmpeg_audiowriter

   

   
   
   .. rubric:: Classes

   .. autosummary::
      :toctree:
      :template: custom_autosummary/class.rst
   
      FFMPEG_AudioWriter
   
   


   
   
   .. rubric:: Functions

   .. autosummary::
      :toctree:
   
      ffmpeg_audiowrite

---

### Reference Reference Moviepy.Audio.Io.Ffplay Audiopreviewer.FFPLAY AudioPreviewer (`docs/reference/reference/moviepy.audio.io.ffplay_audiopreviewer.FFPLAY_AudioPreviewer.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.audio.io.ffplay\_audiopreviewer.FFPLAY\_AudioPreviewer
==============================================================

.. currentmodule:: moviepy.audio.io.ffplay_audiopreviewer

.. autoclass:: FFPLAY_AudioPreviewer
   :members:

---

### Reference Reference Moviepy.Audio.Io.Ffplay Audiopreviewer.Ffplay Audiopreview (`docs/reference/reference/moviepy.audio.io.ffplay_audiopreviewer.ffplay_audiopreview.rst`)

moviepy.audio.io.ffplay\_audiopreviewer.ffplay\_audiopreview
============================================================

.. currentmodule:: moviepy.audio.io.ffplay_audiopreviewer

.. autofunction:: ffplay_audiopreview

---

### Reference Reference Moviepy.Audio.Io.Ffplay Audiopreviewer (`docs/reference/reference/moviepy.audio.io.ffplay_audiopreviewer.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.io.ffplay\_audiopreviewer
=======================================


.. automodule:: moviepy.audio.io.ffplay_audiopreviewer

   

   
   
   .. rubric:: Classes

   .. autosummary::
      :toctree:
      :template: custom_autosummary/class.rst
   
      FFPLAY_AudioPreviewer
   
   


   
   
   .. rubric:: Functions

   .. autosummary::
      :toctree:
   
      ffplay_audiopreview

---

### Reference Reference Moviepy.Audio.Io.Readers.FFMPEG AudioReader (`docs/reference/reference/moviepy.audio.io.readers.FFMPEG_AudioReader.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.audio.io.readers.FFMPEG\_AudioReader
============================================

.. currentmodule:: moviepy.audio.io.readers

.. autoclass:: FFMPEG_AudioReader
   :members:

---

### Reference Reference Moviepy.Audio.Io.Readers (`docs/reference/reference/moviepy.audio.io.readers.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.io.readers
========================


.. automodule:: moviepy.audio.io.readers

   

   
   
   .. rubric:: Classes

   .. autosummary::
      :toctree:
      :template: custom_autosummary/class.rst
   
      FFMPEG_AudioReader

---

### Reference Reference Moviepy.Audio.Io (`docs/reference/reference/moviepy.audio.io.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.io
================


.. automodule:: moviepy.audio.io

   

   
   
   


   
   
   


   
   
   



.. rubric:: Modules

.. autosummary::
   :toctree:
   :template: custom_autosummary/module.rst
   :recursive:


   moviepy.audio.io.AudioFileClip


   moviepy.audio.io.ffmpeg_audiowriter


   moviepy.audio.io.ffplay_audiopreviewer


   moviepy.audio.io.readers

---

### Reference Reference Moviepy.Audio (`docs/reference/reference/moviepy.audio.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio
=============


.. automodule:: moviepy.audio

   

   
   
   


   
   
   


   
   
   



.. rubric:: Modules

.. autosummary::
   :toctree:
   :template: custom_autosummary/module.rst
   :recursive:


   moviepy.audio.AudioClip


   moviepy.audio.fx


   moviepy.audio.io


   moviepy.audio.tools

---

### Reference Reference Moviepy.Audio.Tools.Cuts.Find Audio Period (`docs/reference/reference/moviepy.audio.tools.cuts.find_audio_period.rst`)

moviepy.audio.tools.cuts.find\_audio\_period
============================================

.. currentmodule:: moviepy.audio.tools.cuts

.. autofunction:: find_audio_period

---

### Reference Reference Moviepy.Audio.Tools.Cuts (`docs/reference/reference/moviepy.audio.tools.cuts.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.tools.cuts
========================


.. automodule:: moviepy.audio.tools.cuts

   

   
   
   


   
   
   .. rubric:: Functions

   .. autosummary::
      :toctree:
   
      find_audio_period

---

### Reference Reference Moviepy.Audio.Tools (`docs/reference/reference/moviepy.audio.tools.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.audio.tools
===================


.. automodule:: moviepy.audio.tools

   

   
   
   


   
   
   


   
   
   



.. rubric:: Modules

.. autosummary::
   :toctree:
   :template: custom_autosummary/module.rst
   :recursive:


   moviepy.audio.tools.cuts

---

### Reference Reference Moviepy.Config.Check (`docs/reference/reference/moviepy.config.check.rst`)

moviepy.config.check
====================

.. currentmodule:: moviepy.config

.. autofunction:: check

---

### Reference Reference Moviepy.Config (`docs/reference/reference/moviepy.config.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.config
==============


.. automodule:: moviepy.config

   

   
   
   


   
   
   .. rubric:: Functions

   .. autosummary::
      :toctree:
   
      check
      try_cmd

---

### Reference Reference Moviepy.Config.Try Cmd (`docs/reference/reference/moviepy.config.try_cmd.rst`)

moviepy.config.try\_cmd
=======================

.. currentmodule:: moviepy.config

.. autofunction:: try_cmd

---

### Reference Reference Moviepy.Decorators.Add Mask If None (`docs/reference/reference/moviepy.decorators.add_mask_if_none.rst`)

moviepy.decorators.add\_mask\_if\_none
======================================

.. currentmodule:: moviepy.decorators

.. autofunction:: add_mask_if_none

---

### Reference Reference Moviepy.Decorators.Apply To Audio (`docs/reference/reference/moviepy.decorators.apply_to_audio.rst`)

moviepy.decorators.apply\_to\_audio
===================================

.. currentmodule:: moviepy.decorators

.. autofunction:: apply_to_audio

---

### Reference Reference Moviepy.Decorators.Apply To Mask (`docs/reference/reference/moviepy.decorators.apply_to_mask.rst`)

moviepy.decorators.apply\_to\_mask
==================================

.. currentmodule:: moviepy.decorators

.. autofunction:: apply_to_mask

---

### Reference Reference Moviepy.Decorators.Audio Video Effect (`docs/reference/reference/moviepy.decorators.audio_video_effect.rst`)

moviepy.decorators.audio\_video\_effect
=======================================

.. currentmodule:: moviepy.decorators

.. autofunction:: audio_video_effect

---

### Reference Reference Moviepy.Decorators.Convert Masks To RGB (`docs/reference/reference/moviepy.decorators.convert_masks_to_RGB.rst`)

moviepy.decorators.convert\_masks\_to\_RGB
==========================================

.. currentmodule:: moviepy.decorators

.. autofunction:: convert_masks_to_RGB

---

### Reference Reference Moviepy.Decorators.Convert Parameter To Seconds (`docs/reference/reference/moviepy.decorators.convert_parameter_to_seconds.rst`)

moviepy.decorators.convert\_parameter\_to\_seconds
==================================================

.. currentmodule:: moviepy.decorators

.. autofunction:: convert_parameter_to_seconds

---

### Reference Reference Moviepy.Decorators.Convert Path To String (`docs/reference/reference/moviepy.decorators.convert_path_to_string.rst`)

moviepy.decorators.convert\_path\_to\_string
============================================

.. currentmodule:: moviepy.decorators

.. autofunction:: convert_path_to_string

---

### Reference Reference Moviepy.Decorators.Outplace (`docs/reference/reference/moviepy.decorators.outplace.rst`)

moviepy.decorators.outplace
===========================

.. currentmodule:: moviepy.decorators

.. autofunction:: outplace

---

### Reference Reference Moviepy.Decorators.Preprocess Args (`docs/reference/reference/moviepy.decorators.preprocess_args.rst`)

moviepy.decorators.preprocess\_args
===================================

.. currentmodule:: moviepy.decorators

.. autofunction:: preprocess_args

---

### Reference Reference Moviepy.Decorators.Requires Duration (`docs/reference/reference/moviepy.decorators.requires_duration.rst`)

moviepy.decorators.requires\_duration
=====================================

.. currentmodule:: moviepy.decorators

.. autofunction:: requires_duration

---

### Reference Reference Moviepy.Decorators.Requires Fps (`docs/reference/reference/moviepy.decorators.requires_fps.rst`)

moviepy.decorators.requires\_fps
================================

.. currentmodule:: moviepy.decorators

.. autofunction:: requires_fps

---

### Reference Reference Moviepy.Decorators (`docs/reference/reference/moviepy.decorators.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.decorators
==================


.. automodule:: moviepy.decorators

   

   
   
   


   
   
   .. rubric:: Functions

   .. autosummary::
      :toctree:
   
      add_mask_if_none
      apply_to_audio
      apply_to_mask
      audio_video_effect
      convert_masks_to_RGB
      convert_parameter_to_seconds
      convert_path_to_string
      outplace
      preprocess_args
      requires_duration
      requires_fps
      use_clip_fps_by_default

---

### Reference Reference Moviepy.Decorators.Use Clip Fps By Default (`docs/reference/reference/moviepy.decorators.use_clip_fps_by_default.rst`)

moviepy.decorators.use\_clip\_fps\_by\_default
==============================================

.. currentmodule:: moviepy.decorators

.. autofunction:: use_clip_fps_by_default

---

### Reference Reference Moviepy (`docs/reference/reference/moviepy.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy
=======


.. automodule:: moviepy

   

   
   
   


   
   
   


   
   
   



.. rubric:: Modules

.. autosummary::
   :toctree:
   :template: custom_autosummary/module.rst
   :recursive:


   moviepy.Clip


   moviepy.Effect


   moviepy.audio


   moviepy.config


   moviepy.decorators


   moviepy.tools



   moviepy.video

---

### Reference Reference Moviepy.Tools.Close All Clips (`docs/reference/reference/moviepy.tools.close_all_clips.rst`)

moviepy.tools.close\_all\_clips
===============================

.. currentmodule:: moviepy.tools

.. autofunction:: close_all_clips

---

### Reference Reference Moviepy.Tools.Convert To Seconds (`docs/reference/reference/moviepy.tools.convert_to_seconds.rst`)

moviepy.tools.convert\_to\_seconds
==================================

.. currentmodule:: moviepy.tools

.. autofunction:: convert_to_seconds

---

### Reference Reference Moviepy.Tools.Cross Platform Popen Params (`docs/reference/reference/moviepy.tools.cross_platform_popen_params.rst`)

moviepy.tools.cross\_platform\_popen\_params
============================================

.. currentmodule:: moviepy.tools

.. autofunction:: cross_platform_popen_params

---

### Reference Reference Moviepy.Tools.Deprecated Version Of (`docs/reference/reference/moviepy.tools.deprecated_version_of.rst`)

moviepy.tools.deprecated\_version\_of
=====================================

.. currentmodule:: moviepy.tools

.. autofunction:: deprecated_version_of

---

### Reference Reference Moviepy.Tools.Find Extension (`docs/reference/reference/moviepy.tools.find_extension.rst`)

moviepy.tools.find\_extension
=============================

.. currentmodule:: moviepy.tools

.. autofunction:: find_extension

---

### Reference Reference Moviepy.Tools.No Display Available (`docs/reference/reference/moviepy.tools.no_display_available.rst`)

moviepy.tools.no\_display\_available
====================================

.. currentmodule:: moviepy.tools

.. autofunction:: no_display_available

---

### Reference Reference Moviepy.Tools (`docs/reference/reference/moviepy.tools.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.tools
=============


.. automodule:: moviepy.tools

   

   
   
   


   
   
   .. rubric:: Functions

   .. autosummary::
      :toctree:
   
      close_all_clips
      convert_to_seconds
      cross_platform_popen_params
      deprecated_version_of
      find_extension
      no_display_available
      subprocess_call

---

### Reference Reference Moviepy.Tools.Subprocess Call (`docs/reference/reference/moviepy.tools.subprocess_call.rst`)

moviepy.tools.subprocess\_call
==============================

.. currentmodule:: moviepy.tools

.. autofunction:: subprocess_call

---

### Reference Reference Moviepy.Video.VideoClip.BitmapClip (`docs/reference/reference/moviepy.video.VideoClip.BitmapClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.video.VideoClip.BitmapClip
==================================

.. currentmodule:: moviepy.video.VideoClip

.. autoclass:: BitmapClip
   :members:

---

### Reference Reference Moviepy.Video.VideoClip.ColorClip (`docs/reference/reference/moviepy.video.VideoClip.ColorClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.video.VideoClip.ColorClip
=================================

.. currentmodule:: moviepy.video.VideoClip

.. autoclass:: ColorClip
   :members:

---

### Reference Reference Moviepy.Video.VideoClip.DataVideoClip (`docs/reference/reference/moviepy.video.VideoClip.DataVideoClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.video.VideoClip.DataVideoClip
=====================================

.. currentmodule:: moviepy.video.VideoClip

.. autoclass:: DataVideoClip
   :members:

---

### Reference Reference Moviepy.Video.VideoClip.ImageClip (`docs/reference/reference/moviepy.video.VideoClip.ImageClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.video.VideoClip.ImageClip
=================================

.. currentmodule:: moviepy.video.VideoClip

.. autoclass:: ImageClip
   :members:

---

### Reference Reference Moviepy.Video.VideoClip.TextClip (`docs/reference/reference/moviepy.video.VideoClip.TextClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.video.VideoClip.TextClip
================================

.. currentmodule:: moviepy.video.VideoClip

.. autoclass:: TextClip
   :members:

---

### Reference Reference Moviepy.Video.VideoClip.UpdatedVideoClip (`docs/reference/reference/moviepy.video.VideoClip.UpdatedVideoClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.video.VideoClip.UpdatedVideoClip
========================================

.. currentmodule:: moviepy.video.VideoClip

.. autoclass:: UpdatedVideoClip
   :members:

---

### Reference Reference Moviepy.Video.VideoClip.VideoClip (`docs/reference/reference/moviepy.video.VideoClip.VideoClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.video.VideoClip.VideoClip
=================================

.. currentmodule:: moviepy.video.VideoClip

.. autoclass:: VideoClip
   :members:

---

### Reference Reference Moviepy.Video.VideoClip (`docs/reference/reference/moviepy.video.VideoClip.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.VideoClip
=======================


.. automodule:: moviepy.video.VideoClip

   

   
   
   .. rubric:: Classes

   .. autosummary::
      :toctree:
      :template: custom_autosummary/class.rst
   
      BitmapClip
      ColorClip
      DataVideoClip
      ImageClip
      TextClip
      UpdatedVideoClip
      VideoClip

---

### Reference Reference Moviepy.Video.Compositing.CompositeVideoClip.CompositeVideoClip (`docs/reference/reference/moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip.rst`)

.. custom class to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202

moviepy.video.compositing.CompositeVideoClip.CompositeVideoClip
===============================================================

.. currentmodule:: moviepy.video.compositing.CompositeVideoClip

.. autoclass:: CompositeVideoClip
   :members:

---

### Reference Reference Moviepy.Video.Compositing.CompositeVideoClip.Clips Array (`docs/reference/reference/moviepy.video.compositing.CompositeVideoClip.clips_array.rst`)

moviepy.video.compositing.CompositeVideoClip.clips\_array
=========================================================

.. currentmodule:: moviepy.video.compositing.CompositeVideoClip

.. autofunction:: clips_array

---

### Reference Reference Moviepy.Video.Compositing.CompositeVideoClip.Concatenate Videoclips (`docs/reference/reference/moviepy.video.compositing.CompositeVideoClip.concatenate_videoclips.rst`)

moviepy.video.compositing.CompositeVideoClip.concatenate\_videoclips
====================================================================

.. currentmodule:: moviepy.video.compositing.CompositeVideoClip

.. autofunction:: concatenate_videoclips

---

### Reference Reference Moviepy.Video.Compositing.CompositeVideoClip (`docs/reference/reference/moviepy.video.compositing.CompositeVideoClip.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.compositing.CompositeVideoClip
============================================


.. automodule:: moviepy.video.compositing.CompositeVideoClip

   

   
   
   .. rubric:: Classes

   .. autosummary::
      :toctree:
      :template: custom_autosummary/class.rst
   
      CompositeVideoClip
   
   


   
   
   .. rubric:: Functions

   .. autosummary::
      :toctree:
   
      clips_array
      concatenate_videoclips

---

### Reference Reference Moviepy.Video.Compositing (`docs/reference/reference/moviepy.video.compositing.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.compositing
=========================


.. automodule:: moviepy.video.compositing

   

   
   
   


   
   
   


   
   
   



.. rubric:: Modules

.. autosummary::
   :toctree:
   :template: custom_autosummary/module.rst
   :recursive:


   moviepy.video.compositing.CompositeVideoClip

---

### Reference Reference Moviepy.Video.Fx.AccelDecel (`docs/reference/reference/moviepy.video.fx.AccelDecel.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.fx.AccelDecel
===========================

 
.. automodule:: moviepy.video.fx.AccelDecel
   :inherited-members:

---

### Reference Reference Moviepy.Video.Fx.BlackAndWhite (`docs/reference/reference/moviepy.video.fx.BlackAndWhite.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.fx.BlackAndWhite
==============================

 
.. automodule:: moviepy.video.fx.BlackAndWhite
   :inherited-members:

---

### Reference Reference Moviepy.Video.Fx.Blink (`docs/reference/reference/moviepy.video.fx.Blink.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.fx.Blink
======================

 
.. automodule:: moviepy.video.fx.Blink
   :inherited-members:

---

### Reference Reference Moviepy.Video.Fx.Crop (`docs/reference/reference/moviepy.video.fx.Crop.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.fx.Crop
=====================

 
.. automodule:: moviepy.video.fx.Crop
   :inherited-members:

---

### Reference Reference Moviepy.Video.Fx.CrossFadeIn (`docs/reference/reference/moviepy.video.fx.CrossFadeIn.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.fx.CrossFadeIn
============================

 
.. automodule:: moviepy.video.fx.CrossFadeIn
   :inherited-members:

---

### Reference Reference Moviepy.Video.Fx.CrossFadeOut (`docs/reference/reference/moviepy.video.fx.CrossFadeOut.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.fx.CrossFadeOut
=============================

 
.. automodule:: moviepy.video.fx.CrossFadeOut
   :inherited-members:

---

### Reference Reference Moviepy.Video.Fx.EvenSize (`docs/reference/reference/moviepy.video.fx.EvenSize.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.fx.EvenSize
=========================

 
.. automodule:: moviepy.video.fx.EvenSize
   :inherited-members:

---

### Reference Reference Moviepy.Video.Fx.FadeIn (`docs/reference/reference/moviepy.video.fx.FadeIn.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.fx.FadeIn
=======================

 
.. automodule:: moviepy.video.fx.FadeIn
   :inherited-members:

---

### Reference Reference Moviepy.Video.Fx.FadeOut (`docs/reference/reference/moviepy.video.fx.FadeOut.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.fx.FadeOut
========================

 
.. automodule:: moviepy.video.fx.FadeOut
   :inherited-members:

---

### Reference Reference Moviepy.Video.Fx.Freeze (`docs/reference/reference/moviepy.video.fx.Freeze.rst`)

.. custom module to enable complete documentation of every function
   see https://stackoverflow.com/a/62613202
   
moviepy.video.fx.Freeze
=======================

 
.. automodule:: moviepy.video.fx.Freeze
   :inherited-members:

---

--- METRICS ---
- Files Extracted: 101
- Estimated Token Budget: ~32162 tokens
- Canonical Reference: https://codewiki.google/github.com/Zulko/moviepy
