def _f_accel_decel(t, old_duration, new_duration, abruptness=1.0, soonness=1.0):
a = 1.0 + abruptness
def _f(t):
def f1(t):
return (0.5) ** (1 - a) * (t**a)
def f2(t):
return 1 - f1(1 - t)
return (t < 0.5) * f1(t) + (t >= 0.5) * f2(t)
return old_duration * _f((t / new_duration) ** soonness)
[docs]def accel_decel(clip, new_duration=None, abruptness=1.0, soonness=1.0):
"""Accelerates and decelerates a clip, useful for GIF making.
Parameters
----------
new_duration : float
Duration for the new transformed clip. If None, will be that of the
current clip.
abruptness : float
Slope shape in the acceleration-deceleration function. It will depend
on the value of the parameter:
* ``-1 < abruptness < 0``: speed up, down, up.
* ``abruptness == 0``: no effect.
* ``abruptness > 0``: speed down, up, down.
soonness : float
For positive abruptness, determines how soon the transformation occurs.
Should be a positive number.
Raises
------
ValueError
When ``sooness`` argument is lower than 0.
Examples
--------
The following graphs show functions generated by different combinations
of arguments, where the value of the slopes represents the speed of the
videos generated, being the linear function (in red) a combination that
does not produce any transformation.
.. image:: /_static/accel_decel-fx-params.png
:alt: acced_decel FX parameters combinations
"""
if new_duration is None:
new_duration = clip.duration
if soonness < 0:
raise ValueError("'sooness' should be a positive number")
return clip.time_transform(
lambda t: _f_accel_decel(t, clip.duration, new_duration, abruptness, soonness)
).with_duration(new_duration)