Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(mostly internal) variables renaming #2259

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/_static/code/user_guide/compositing/with_position.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

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

Expand Down
6 changes: 3 additions & 3 deletions docs/_static/code/user_guide/loading/AudioArrayClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@
n_frames = note_size * len(notes)


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


# At this point one could use this audioclip which generates the audio on the fly
# clip = AudioFileClip(frame_function)
# clip = AudioFileClip(get_frame)

# We generate all frames timepoints

audio_frame_values = [
2 * [frame_function(t, freq)]
2 * [get_frame(t, freq)]
for freq in notes.values()
for t in np.arange(0, note_duration, 1.0 / sample_rate)
]
Expand Down
2 changes: 1 addition & 1 deletion docs/_static/code/user_guide/loading/AudioClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ def audio_frame(t):
return np.sin(440 * 2 * np.pi * t)


audio_clip = AudioClip(frame_function=audio_frame, duration=3)
audio_clip = AudioClip(get_frame=audio_frame, 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 @@ -16,14 +16,14 @@

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


# We create the DataVideoClip, and we set FPS at 2, making a 3s clip
# (because len(dataset) = 6, so 6/2=3)
myclip = DataVideoClip(data=dataset, data_to_frame=frame_function, fps=2)
myclip = DataVideoClip(data=dataset, data_to_frame=get_frame, 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 frame_function(t):
def get_frame(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,6 +25,6 @@ def frame_function(t):


# we define a 2s duration for the clip to be able to render it later
clip = VideoClip(frame_function, duration=2)
clip = VideoClip(get_frame, duration=2)
# we must set a framerate because VideoClip have no framerate by default
clip.write_gif("circle.gif", fps=15)
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 @@ -14,22 +14,22 @@
black = (255, 255, 255) # RGB for black


def frame_function(t):
def get_frame(t):
"""Random noise image of 200x100"""
return np.random.randint(low=0, high=255, size=(100, 200, 3))


def frame_function_audio(t):
def get_frame_audio(t):
"""A note by producing a sinewave of 440 Hz"""
return np.sin(440 * 2 * np.pi * t)


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

# VIDEO CLIPS
# for custom animations, where frame_function is a function returning an image
# for custom animations, where get_frame is a function returning an image
# as numpy array for a given time
clip = VideoClip(frame_function, duration=5)
clip = VideoClip(get_frame, duration=5)
clip = VideoFileClip("example.mp4") # for videos
# for a list or directory of images to be used as a video sequence
clip = ImageSequenceClip("example_img_dir", fps=24)
Expand All @@ -42,6 +42,6 @@ def frame_function_audio(t):
# AUDIO CLIPS
# for audio files, but also videos where you only want the keep the audio track
clip = AudioFileClip("example.wav")
# for custom audio, where frame_function is a function returning a
# for custom audio, where get_frame is a function returning a
# float (or tuple for stereo) for a given time
clip = AudioClip(frame_function_audio, duration=3)
clip = AudioClip(get_frame_audio, duration=3)
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
frame_function = lambda t: np.random.rand(100, 200)
get_frame = lambda t: np.random.rand(100, 200)

# To define the VideoClip as a mask, just pass parameter is_mask as True
maskclip1 = VideoClip(frame_function, duration=4, is_mask=True) # A random noise mask
maskclip1 = VideoClip(get_frame, 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
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 ``frame_function(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 ``get_frame(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 ``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.
Clips that are made with a ``get_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.

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 frame_function requires some objects to be updated before we can compute it.
:py:class:`~moviepy.video.io.VideoClip.UpdatedVideoClip` is a video whose get_frame 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 ``frame_function(t)`` which returns a ``Nx1`` or ``Nx2`` numpy array representing the sound at time ``t``.
All you need is to define a function ``get_frame(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
16 changes: 8 additions & 8 deletions moviepy/Clip.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ def get_frame(self, t):
if t == self.memoized_t:
return self.memoized_frame
else:
frame = self.frame_function(t)
frame = self.get_frame(t)
self.memoized_t = t
self.memoized_frame = frame
return frame
else:
return self.frame_function(t)
return self.get_frame(t)

def transform(self, func, apply_to=None, keep_duration=True):
"""General processing of a clip.
Expand Down Expand Up @@ -126,8 +126,8 @@ def transform(self, func, apply_to=None, keep_duration=True):
if apply_to is None:
apply_to = []

# mf = copy(self.frame_function)
new_clip = self.with_updated_frame_function(lambda t: func(self.get_frame, t))
# mf = copy(self.get_frame)
new_clip = self.with_updated_get_frame(lambda t: func(self.get_frame, t))

if not keep_duration:
new_clip.duration = None
Expand Down Expand Up @@ -296,17 +296,17 @@ def with_duration(self, duration, change_end=True):
self.start = self.end - duration

@outplace
def with_updated_frame_function(self, frame_function):
"""Sets a ``frame_function`` attribute for the clip. Useful for setting
def with_updated_get_frame(self, get_frame):
"""Sets a ``get_frame`` attribute for the clip. Useful for setting
arbitrary/complicated videoclips.

Parameters
----------

frame_function : function
get_frame : function
New frame creator function for the clip.
"""
self.frame_function = frame_function
self.get_frame = get_frame

def with_fps(self, fps, change_duration=False):
"""Returns a copy of the clip with a new default fps for functions like
Expand Down
24 changes: 12 additions & 12 deletions moviepy/audio/AudioClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class AudioClip(Clip):

See ``AudioFileClip`` and ``CompositeAudioClip`` for usable classes.

An AudioClip is a Clip with a ``frame_function`` attribute of
An AudioClip is a Clip with a ``get_frame`` attribute of
the form `` t -> [ f_t ]`` for mono sound and
``t-> [ f1_t, f2_t ]`` for stereo sound (the arrays are Numpy arrays).
The `f_t` are floats between -1 and 1. These bounds can be
Expand All @@ -32,7 +32,7 @@ class AudioClip(Clip):
Parameters
----------

frame_function
get_frame
A function `t-> frame at time t`. The frame does not mean much
for a sound, it is just a float. What 'makes' the sound are
the variations of that float in the time.
Expand All @@ -51,28 +51,28 @@ class AudioClip(Clip):

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

# Plays the note A in stereo (two sine waves of frequencies 440 and 880 Hz)
frame_function = lambda t: np.array([
get_frame = lambda t: np.array([
np.sin(440 * 2 * np.pi * t),
np.sin(880 * 2 * np.pi * t)
]).T.copy(order="C")
clip = AudioClip(frame_function, duration=3, fps=44100)
clip = AudioClip(get_frame, duration=3, fps=44100)
clip.preview()

"""

def __init__(self, frame_function=None, duration=None, fps=None):
def __init__(self, get_frame=None, duration=None, fps=None):
super().__init__()

if fps is not None:
self.fps = fps

if frame_function is not None:
self.frame_function = frame_function
if get_frame is not None:
self.get_frame = get_frame
frame0 = self.get_frame(0)
if hasattr(frame0, "__iter__"):
self.nchannels = len(list(frame0))
Expand Down Expand Up @@ -337,7 +337,7 @@ def __init__(self, array, fps):
self.fps = fps
self.duration = 1.0 * len(array) / fps

def frame_function(t):
def get_frame(t):
"""Complicated, but must be able to handle the case where t
is a list of the form sin(t).
"""
Expand All @@ -354,7 +354,7 @@ def frame_function(t):
else:
return self.array[i]

self.frame_function = frame_function
self.get_frame = get_frame
self.nchannels = len(list(self.get_frame(0)))


Expand Down Expand Up @@ -402,7 +402,7 @@ def ends(self):
"""Returns ending times for all clips in the composition."""
return (clip.end for clip in self.clips)

def frame_function(self, t):
def get_frame(self, t):
"""Renders a frame for the composition for the time ``t``."""
played_parts = [clip.is_playing(t) for clip in self.clips]

Expand Down
4 changes: 2 additions & 2 deletions moviepy/audio/fx/AudioDelay.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ class AudioDelay(Effect):
])

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

Expand Down
2 changes: 1 addition & 1 deletion moviepy/audio/io/AudioFileClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def __init__(
self.buffersize = self.reader.buffersize
self.filename = filename

self.frame_function = lambda t: self.reader.get_frame(t)
self.get_frame = lambda t: self.reader.get_frame(t)
self.nchannels = self.reader.nchannels

def close(self):
Expand Down
Loading
Loading