Skip to content

Commit

Permalink
More api changes (#2255)
Browse files Browse the repository at this point in the history
More api changes
  • Loading branch information
Zulko authored Nov 24, 2024
1 parent c88852f commit b22e702
Show file tree
Hide file tree
Showing 54 changed files with 222 additions and 230 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/formatting_linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
- name: Show Flake8 version
run: flake8 --version
- name: Run Flake8
run: flake8 -v --show-source moviepy docs/conf.py examples tests
run: flake8 -v --show-source --max-line-length=92 moviepy docs/conf.py examples tests

isort:
name: isort import sorter
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ result to a new file:
from moviepy import *

# Load file example.mp4 and keep only the subclip from 00:00:10 to 00:00:20
clip = VideoFileClip("long_examples/example2.mp4").with_subclip(10, 20)
clip = VideoFileClip("long_examples/example2.mp4").subclipped(10, 20)

# Reduce the audio volume to 80% of its original volume
clip = clip.with_multiply_volume(0.8)
clip = clip.with_volume_scaled(0.8)

# Generate a text clip. You can customize the font, color, etc.
txt_clip = TextClip(font="example.ttf", text="Big Buck Bunny", font_size=70, color='white')
Expand Down
18 changes: 9 additions & 9 deletions docs/_static/code/getting_started/moviepy_10_minutes/trailer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
# We extract the scenes we want to use

# First the characters
intro_clip = video.with_subclip(1, 11)
bird_clip = video.with_subclip(16, 20)
bunny_clip = video.with_subclip(37, 55)
rodents_clip = video.with_subclip(
intro_clip = video.subclipped(1, 11)
bird_clip = video.subclipped(16, 20)
bunny_clip = video.subclipped(37, 55)
rodents_clip = video.subclipped(
"00:03:34.75", "00:03:56"
) # we can also use string notation with format HH:MM:SS.uS
rambo_clip = video.with_subclip("04:41.5", "04:44.70")
rambo_clip = video.subclipped("04:41.5", "04:44.70")


#####################
Expand All @@ -43,8 +43,8 @@
##############################
# Well, looking at the rodent scene it is a bit long isn't?
# Let's see how we modify the clip with one of the many clip manipulation method starting by with_*
# in that case by removing of the clip the part between 00:06:00 to 00:10:00 of the clip, using with_cutout
rodents_clip = rodents_clip.with_cutout(start_time=4, end_time=10)
# in that case by removing of the clip the part between 00:06:00 to 00:10:00 of the clip, using with_section_cut_out
rodents_clip = rodents_clip.with_section_cut_out(start_time=4, end_time=10)

# Note: You may have noticed that we have reassign rodents_clip, this is because all with_* methods return a modified *copy* of the
# original clip instead of modifying it directly. In MoviePy any function starting by with_* is out-place instead of in-place
Expand Down Expand Up @@ -210,8 +210,8 @@

# Effects are not only for transition, they can also change a clip timing or apparence
# To show that, lets also modify the Rambo-like part of our clip to be in slow motion
# PS : We do it for effect, but this is one of the few effects that have a direct shortcut, with_multiply_speed
# the others are with_multiply_volume, resized, croped and rotated
# PS : We do it for effect, but this is one of the few effects that have a direct shortcut, with_speed_scaled
# the others are with_volume_scaled, resized, croped and rotated
rambo_clip = rambo_clip.with_effects([vfx.MultiplySpeed(0.5)])

# Because we modified timing of rambo_clip with our MultiplySpeed effect, we must re-assign the following clips timing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
from moviepy import *

# Load file example.mp4 and extract only the subclip from 00:00:10 to 00:00:20
clip = VideoFileClip("long_examples/example2.mp4").with_subclip(10, 20)
clip = VideoFileClip("long_examples/example2.mp4").subclipped(10, 20)

# Reduce the audio volume to 80% of his original volume
clip = clip.with_multiply_volume(0.8)
clip = clip.with_volume_scaled(0.8)

# Generate a text clip. You can customize the font, color, etc.
txt_clip = TextClip(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# We will play aclip1, then ontop of it aclip2 after 5s, and the aclip3 on top of both after 9s
compo = CompositeAudioClip(
[
aclip1.with_multiply_volume(1.2),
aclip1.with_volume_scaled(1.2),
aclip2.with_start(5), # start at t=5s
aclip3.with_start(9),
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# We load all the clips we want to compose
clip1 = VideoFileClip("example.mp4")
clip2 = VideoFileClip("example2.mp4").with_subclip(0, 1)
clip2 = VideoFileClip("example2.mp4").subclipped(0, 1)
clip3 = VideoFileClip("example3.mp4")

# We concatenate them and write theme stacked on top of each other, with clip3 over clip2 over clip1
Expand Down
2 changes: 1 addition & 1 deletion docs/_static/code/user_guide/compositing/concatenate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# We load all the clips we want to concatenate
clip1 = VideoFileClip("example.mp4")
clip2 = VideoFileClip("example2.mp4").with_subclip(0, 1)
clip2 = VideoFileClip("example2.mp4").subclipped(0, 1)
clip3 = VideoFileClip("example3.mp4")

# We concatenate them and write the result
Expand Down
2 changes: 1 addition & 1 deletion docs/_static/code/user_guide/compositing/crossfadein.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# We load all the clips we want to compose
clip1 = VideoFileClip("example.mp4")
clip2 = VideoFileClip("example2.mp4").with_subclip(0, 1)
clip2 = VideoFileClip("example2.mp4").subclipped(0, 1)

# Clip2 will be on top of clip1 for 1s
clip1 = clip1.with_end(2)
Expand Down
4 changes: 2 additions & 2 deletions docs/_static/code/user_guide/compositing/with_position.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from moviepy import *

# We load all the clips we want to compose
background = VideoFileClip("example2.mp4").with_subclip(0, 2)
background = VideoFileClip("example2.mp4").subclipped(0, 2)
title = TextClip(
"./example.ttf",
text="Big Buck Bunny",
Expand Down Expand Up @@ -42,7 +42,7 @@
copyright = copyright.with_position(("center", background.h - copyright.h - 30))

# Finally, we want the logo to be in the center, but to drop as time pass
# We can do so by setting position as a function that take time as argument, a lot like make_frame
# We can do so by setting position as a function that take time as argument, a lot like frame_function
top = (background.h - logo.h) / 2
logo = logo.with_position(lambda t: ("center", top + t * 30))

Expand Down
2 changes: 1 addition & 1 deletion docs/_static/code/user_guide/compositing/with_start.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# We load all the clips we want to compose
clip1 = VideoFileClip("example.mp4")
clip2 = VideoFileClip("example2.mp4").with_subclip(0, 1)
clip2 = VideoFileClip("example2.mp4").subclipped(0, 1)
clip3 = VideoFileClip("example3.mp4")

# We want to stop clip1 after 1s
Expand Down
6 changes: 3 additions & 3 deletions docs/_static/code/user_guide/effects/modify_copy_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@

# This does nothing, as multiply_volume will return a copy of clip which you will loose immediatly as you dont store it
# If you was to render clip now, the audio would still be at full volume
clip.with_multiply_volume(0.1)
clip.with_volume_scaled(0.1)

# This create a copy of clip in clip_whisper with a volume of only 10% the original, but does not modify the original clip
# If you was to render clip right now, the audio would still be at full volume
# If you was to render clip_whisper, the audio would be a 10% of the original volume
clip_whisper = clip.with_multiply_volume(0.1)
clip_whisper = clip.with_volume_scaled(0.1)

# This replace the original clip with a copy of it where volume is only 10% of the original
# If you was to render clip now, the audio would be at 10%
# The original clip is now lost
clip = clip.with_multiply_volume(0.1)
clip = clip.with_volume_scaled(0.1)
4 changes: 2 additions & 2 deletions docs/_static/code/user_guide/loading/AudioArrayClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
total_size = note_size * len(notes)


def make_frame(t, note_frequency):
def frame_function(t, note_frequency):
return np.sin(note_frequency * 2 * np.pi * t)


Expand All @@ -24,7 +24,7 @@ def make_frame(t, note_frequency):
i = 0
for note, frequency in notes.items():
for _ in range(note_size):
audio_array[i][0] = make_frame(times[i], frequency)
audio_array[i][0] = frame_function(times[i], frequency)
i += 1

# Create an AudioArrayClip from the audio samples
Expand Down
4 changes: 2 additions & 2 deletions docs/_static/code/user_guide/loading/AudioClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import numpy as np

# Producing a sinewave of 440 Hz -> note A
make_frame_audio = lambda t: np.sin(440 * 2 * np.pi * t)
frame_function_audio = lambda t: np.sin(440 * 2 * np.pi * t)

# AUDIO CLIPS
clip = AudioClip(make_frame_audio, duration=3)
clip = AudioClip(frame_function_audio, duration=3)
4 changes: 2 additions & 2 deletions docs/_static/code/user_guide/loading/DataVideoClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@


# The function make frame take data and create an image of 200x100 px fill with the color
def make_frame(data):
def frame_function(data):
frame = np.full((100, 200, 3), data, dtype=np.uint8)
return frame


# We create the DataVideoClip, and we set FPS at 2, making a 3s clip (because len(dataset) = 6, so 6/2=3)
myclip = DataVideoClip(data=dataset, data_to_frame=make_frame, fps=2)
myclip = DataVideoClip(data=dataset, data_to_frame=frame_function, fps=2)

# Modifying fps here will change video FPS, not clip FPS
myclip.write_videofile("result.mp4", fps=30)
4 changes: 2 additions & 2 deletions docs/_static/code/user_guide/loading/VideoClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
RED = (255, 0, 0)


def make_frame(t):
def frame_function(t):
frequency = 1 # One pulse per second
coef = 0.5 * (1 + math.sin(2 * math.pi * frequency * t)) # radius varies over time
radius = WIDTH * coef
Expand All @@ -25,7 +25,7 @@ def make_frame(t):


clip = VideoClip(
make_frame, duration=2
frame_function, duration=2
) # we define a 2s duration for the clip to be able to render it later
clip.write_gif(
"circle.gif", fps=15
Expand Down
2 changes: 1 addition & 1 deletion docs/_static/code/user_guide/loading/VideoFileClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
print("Clip duration: {}".format(myclip.duration))
print("Clip fps: {}".format(myclip.fps))

myclip = myclip.with_subclip(0.5, 2) # Cutting the clip between 0.5 and 2 secs.
myclip = myclip.subclipped(0.5, 2) # Cutting the clip between 0.5 and 2 secs.
print("Clip duration: {}".format(myclip.duration)) # Cuting will update duration
print("Clip fps: {}".format(myclip.fps)) # and keep fps

Expand Down
12 changes: 6 additions & 6 deletions docs/_static/code/user_guide/loading/loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
# Define some constants for later use
black = (255, 255, 255) # RGB for black
# Random noise image of 200x100
make_frame = lambda t: np.random.randint(low=0, high=255, size=(100, 200, 3))
frame_function = lambda t: np.random.randint(low=0, high=255, size=(100, 200, 3))
# A note by producing a sinewave of 440 Hz
make_frame_audio = lambda t: np.sin(440 * 2 * np.pi * t)
frame_function_audio = lambda t: np.sin(440 * 2 * np.pi * t)

# Now lets see how to load different type of resources !

# VIDEO CLIPS`
clip = VideoClip(
make_frame, duration=5
) # for custom animations, where make_frame is a function returning an image as numpy array for a given time
frame_function, duration=5
) # for custom animations, where frame_function is a function returning an image as numpy array for a given time
clip = VideoFileClip("example.mp4") # for videos
clip = ImageSequenceClip(
"example_img_dir", fps=24
Expand All @@ -31,5 +31,5 @@
"example.wav"
) # for audio files, but also videos where you only want the keep the audio track
clip = AudioClip(
make_frame_audio, duration=3
) # for custom audio, where make_frame is a function returning a float (or tuple for stereo) for a given time
frame_function_audio, duration=3
) # for custom audio, where frame_function is a function returning a float (or tuple for stereo) for a given time
4 changes: 2 additions & 2 deletions docs/_static/code/user_guide/loading/masks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import numpy as np

# Random RGB noise image of 200x100
makeframe = lambda t: np.random.rand(100, 200)
frame_function = lambda t: np.random.rand(100, 200)

# To define the VideoClip as a mask, just pass parameter is_mask as True
maskclip1 = VideoClip(makeframe, duration=4, is_mask=True) # A random noise mask
maskclip1 = VideoClip(frame_function, duration=4, is_mask=True) # A random noise mask
maskclip2 = ImageClip("example_mask.jpg", is_mask=True) # A fixed mask as jpeg
maskclip3 = VideoFileClip("example_mask.mp4", is_mask=True) # A video as a mask

Expand Down
2 changes: 1 addition & 1 deletion docs/_static/code/user_guide/rendering/preview.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from moviepy import *

myclip = VideoFileClip("./example.mp4").with_subclip(0, 1) # Keep only 0 to 1 sec
myclip = VideoFileClip("./example.mp4").subclipped(0, 1) # Keep only 0 to 1 sec

# We preview our clip as a video, inheriting FPS and audio of the original clip
myclip.preview()
Expand Down
2 changes: 1 addition & 1 deletion docs/_static/code/user_guide/rendering/write_gif.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from moviepy import *

myclip = VideoFileClip("example.mp4").with_subclip(0, 2)
myclip = VideoFileClip("example.mp4").subclipped(0, 2)

# Here we just save as GIF
myclip.write_gif("result.gif")
Expand Down
2 changes: 1 addition & 1 deletion docs/_static/code/user_guide/rendering/write_videofile.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from moviepy import *

# We load all the clips we want to compose
background = VideoFileClip("long_examples/example2.mp4").with_subclip(0, 10)
background = VideoFileClip("long_examples/example2.mp4").subclipped(0, 10)
title = TextClip(
"./example.ttf",
text="Big Buck Bunny",
Expand Down
6 changes: 3 additions & 3 deletions docs/getting_started/moviepy_10_minutes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ This is a very classic task, so let's turn our main clip into multiple subclips:
:lines: 13-25


Here, we use the ``with_subclip`` method to extract specific scenes from the main video. We provide the start and end times (in seconds or as text with the format ``HH:MM:SS.µS``) for each scene.
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
Expand Down Expand Up @@ -93,13 +93,13 @@ 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_cutout`` method to remove a portion of the clip between ``00:06:00`` to ``00:10:00``.
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_cutout``, but this is only one of the many clip manipulation methods starting with ``with_*``. We will see a few others
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::
Expand Down
2 changes: 1 addition & 1 deletion docs/user_guide/compositing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ So, considering that you would want to play ``clip1`` for the first 6 seconds, `

.. note::
When working with timing of your clip, 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.with_subclip` and :py:meth:`~moviepy.Clip.Clip.with_cutout`.
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
Expand Down
8 changes: 4 additions & 4 deletions docs/user_guide/loading.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ 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 ``make_frame(t)`` which returns a `HxWx3` numpy array (of 8-bits integers) representing the frame at time ``t``.
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/>`_.

Expand All @@ -81,7 +81,7 @@ Resulting in this.


.. note::
Clips that are made with a ``make_frame`` 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.
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`.

Expand Down Expand Up @@ -137,7 +137,7 @@ 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 make_frame requires some objects to be updated before we can compute it.
: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.

Expand Down Expand Up @@ -244,7 +244,7 @@ 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 ``make_frame(t)`` which returns a ``Nx1`` or ``Nx2`` numpy array representing the sound at time ``t``.
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
Expand Down
4 changes: 2 additions & 2 deletions docs/user_guide/modifying.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ It means that creating a new clip is neither time nor memory hungry, all the com

Time representations in MoviePy
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Many methods that we will see accept duration or timepoint as arguments. For instance :py:meth:`clip.with_subclip(t_start, t_end) <moviepy.Clip.Clip.with_subclip(t_start, t_end)>` which cuts the clip between two timepoints.
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.with_subclip(-20, -10)`` cuts the clip between 20s before the end and 10s before the end.
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
Expand Down
2 changes: 1 addition & 1 deletion docs/user_guide/rendering.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The first thing you can do is to preview your clip as a video, by calling method
.. 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`` do not offer such capabilities, you can easily emulate such behavior by using :py:meth:`~moviepy.Clip.Clip.with_subclip`.
You will probably frequently want to preview only a small portion of your clip, though ``preview`` do not offer such capabilities, you can easily emulate such behavior by using :py:meth:`~moviepy.Clip.Clip.subclipped`.

.. note::
It is quite frequent for a clip preview to be out of sync, or to play slower than it should. It means that your computer is not powerful enough to render the clip in real time.
Expand Down
Loading

0 comments on commit b22e702

Please sign in to comment.