.. _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 sorts 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 theme, see :ref:`rendering` (we will usually save them in example, but we wont explain here).

There's a lot of 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


The best to understand all these clips more thoroughly is to read the full documentation for each in the :ref:`reference_manual`.


Releasing resources by closing a clip
---------------------------------------

When you create some types of clip instances - e.g. ``VideoFileClip`` or ``AudioFileClip`` - MoviePy creates a subprocess and locks the file. In order 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 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 type 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 the 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 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 requires 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 object ! 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 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 who take a list of datasets, a callback function, 
and make each frame by iterating over dataset and invoking the callback function with the current data as 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 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 algorithm needs 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 who respect 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 drown.
#. It has a ``to_frame()`` method, that will render a frame based on world 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 kind of clip.
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` accept 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 example of using :py:class:`~moviepy.video.VideoClip.TextClip` :

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

.. note::
    The parameter ``method`` let 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 as 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 theme 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 visual, 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` return 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 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`.