Accelerate or decelerate a movie clip
<p>I am trying to accelerate and/or decelerate a movie clip with the help of Python's moviepy module, but I can't seem to work it out properly. The script runs quite smoothly, and without any errors, but I do not see any effects. Might be my script is wrong and I can't detect the problem. Looking for help/tips from you. I do not need a complete solution, any hints will be of great help. I have been working on this solution for sometime and I think I should post my problem here. Any help, tips, guidance will be greatly appreciated. Thank you.  </p>

<pre><code>from moviepy.editor import *
from moviepy.video.tools.drawing import color_split
import os

dir = os.path.split(os.path.realpath(__file__))[0]
img = os.path.join('tmp', 'stock.jpg')
folder = 'tmp'


def f_accel_decel(t, old_d, new_d, abruptness=1, soonness=1.0):
    """
    abruptness
      negative abruptness (&gt;-1): speed up down up
      zero abruptness : no effect
      positive abruptness: speed down up down

    soonness
      for positive abruptness, determines how soon the
      speedup occurs (0&lt;soonness &lt; inf)
    """

    a = 1.0+abruptness
    def _f(t):
        f1 = lambda t: (0.5)**(1-a)*(t**a)
        f2 = lambda t: (1-f1(1-t))
        return (t&lt;.5)*f1(t) + (t&gt;=.5)*f2(t) 

    return old_d*_f((t/new_d)**soonness)

def accel_decel(clip, new_duration=None, abruptness=1.0, soonness=1.0):
    """
    new_duration
      If None, will be that of the current clip.
    abruptness
      negative abruptness (&gt;-1): speed up down up
      zero abruptness : no effect
      positive abruptness: speed down up down

    soonness
      for positive abruptness, determines how soon the
      speedup occurs (0&lt;soonness &lt; inf)
    """

    if new_duration is None:
        new_duration = clip.duration

    fl = lambda t : f_accel_decel(t, clip.duration, new_duration,
                                   abruptness, soonness)

    return clip.fl_time(fl).set_duration(new_duration)



duration = 30

main_clip = ImageClip(img, duration=30)
W,H = main_clip.size
print W,H



clip1 = (main_clip
             .subclip(0,duration)
             .set_pos(lambda t:(max((0), (int(W-0.5*W*t))), "center"))
             )


modifiedClip1 = accel_decel(clip1, abruptness=5, soonness=1.3)


cc = CompositeVideoClip([modifiedClip1], size=(1920,1080), bg_color=(232,54,18)).resize(0.5)
cc.preview(fps=24)
#cc.write_videofile("mask.avi", fps=25, codec="libx264", bitrate="1000K", threads=3)
</code></pre>

<p>I think the best way of accelerating and decelerating clip objects is using <strong>easing functions</strong>.</p>

<p>Some reference sites:</p>

<ul>
<li><a href="http://easings.net" rel="nofollow">http://easings.net</a></li>
<li><a href="http://www.gizma.com/easing/" rel="nofollow">http://www.gizma.com/easing/</a></li>
<li><a href="http://gsgd.co.uk/sandbox/jquery/easing/" rel="nofollow">http://gsgd.co.uk/sandbox/jquery/easing/</a></li>
</ul>

<p>Here's part of a script I made when trying to understand these functions.
Maybe you can use some of this concepts to solve your issue.</p>

<pre><code>from __future__ import division
from moviepy.editor import TextClip, CompositeVideoClip
import math


def efunc(x0, x1, dur, func='linear', **kwargs):
    # Return an easing function.
    # It will control a single dimention of the clip movement.
    # http://www.gizma.com/easing/

    def linear(t):
        return c*t/d + b

    def out_quad(t):
        t = t/d
        return -c * t*(t-2) + b

    def in_out_sine(t):
        return -c/2 * (math.cos(math.pi*t/d) - 1) + b

    def in_quint(t):
        t = t/d
        return c*t*t*t*t*t + b

    def in_out_circ(t):
        t /= d/2;
        if t &lt; 1:
            return -c/2 * (math.sqrt(1 - t*t) - 1) + b
        t -= 2;
        return c/2 * (math.sqrt(1 - t*t) + 1) + b;

    def out_bounce(t):
        # http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js
        t = t/d
        if t &lt; 1/2.75:
            return c*(7.5625*t*t) + b
        elif t &lt; 2/2.75:
            t -= 1.5/2.75
            return c*(7.5625*t*t + .75) + b
        elif t &lt; 2.5/2.75:
            t -= 2.25/2.75
            return c*(7.5625*t*t + .9375) + b
        else:
            t -= 2.625/2.75
            return c*(7.5625*t*t + .984375) + b

    # Kept the (t, b, c, d) notation found everywhere.
    b = x0
    c = x1 - x0
    d = dur
    return locals()[func]


def particle(x0, x1, y0, y1, d, func='linear', color='black', **kwargs):
    # Dummy clip for testing.

    def pos(t):
        return efunc(x0, x1, d, func=func)(t), efunc(y0, y1, d, func=func)(t)

    return (
        TextClip('*', fontsize=80, color=color)
        .set_position(pos)
        .set_duration(d)
        )

# Make a gif to visualize the behaviour of the functions:

easing_functions = [
    ('linear', 'red'),
    ('in_out_sine', 'green'),
    ('in_out_circ', 'violet'),
    ('out_quad', 'blue'),
    ('out_bounce', 'brown'),
    ('in_quint', 'black'),
    ]

d = 4
x0, x1 = 0, 370
clips = []
for i, (func, c) in enumerate(easing_functions):
    y = 40*i
    clips.append(particle(x0, x1, y, y, d=d, func=func, color=c))
    clips.append(particle(x1, x0, y, y, d=d, func=func, color=c).set_start(d))

clip = CompositeVideoClip(clips, size=(400,250), bg_color=(255,255,255))
clip.write_gif('easing.gif', fps=12)
</code></pre>

<p><br></p>

<p>The output of the script:</p>

<p><a href="https://i.stack.imgur.com/73oVB.gif" rel="nofollow"><img src="https://i.stack.imgur.com/73oVB.gif" alt="Easing functions demo"></a></p>

python numpy moviepy