Skip to content

Loop once then wait #85

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

Closed
stephanedebove opened this issue May 3, 2025 · 3 comments
Closed

Loop once then wait #85

stephanedebove opened this issue May 3, 2025 · 3 comments

Comments

@stephanedebove
Copy link

stephanedebove commented May 3, 2025

Description

Hi there,

is it possible to pass a parameter so that the animation loops only once and then waits on the last frame a certain amount of time?

at the moment --time controls both the video duration and loop duration if I’m not mistaken, is there a way to dissociate the two? With a parameter --loop_time and another --loop_number for instance.

Thanks.

Edit: I’ve also tried to generate a video with one loop and then extend it to the required duration freezing the last frame (with ffmpeg). But two problems with this:

  • a second loop always start before the animation ends, I can’t get one loop exactly
  • there is no deceleration at the end of the loop so freezing the last frame gives a "hard stop"
@Tremeschin
Copy link
Member

Hey! bit of a lengthy answer after writing it 😅

Not sure if I followed exactly what you're trying to achieve given your edit, as repeating the last frame will indeed have a hard stop effect (but you want it on the first statement?). I think some animations had a bad last frame on v0.8 also, so freezing the last frame likely didn't work because your animation doesn't seamless connects to its start? (like horizontal --linear)

Anyhow, it doesn't fit much having a loop time and number on the other project depthflow derives from, but we can extend its class, add new commands and override the temporal functions no problem, for example:

import sys
from typing import Annotated

from attrs import define
from typer import Argument

from DepthFlow.Scene import DepthScene

@define
class CustomScene(DepthScene):
    _loop_time: float = 5.0

    def loop_time(self, value: Annotated[float, Argument()]):
        self._loop_time = value

    @property
    def tau(self) -> float:
        return min(self.time / self._loop_time, 1)

    def commands(self):
        DepthScene.commands(self)
        self.cli.command(self.loop_time)

def manual():
    scene = CustomScene()
    scene.cli(sys.argv[1:])

def managed():
    scene = CustomScene(backend="headless")
    scene.loop_time(8.0)
    scene.input(image="image.png")
    scene.main(output="./video.mp4", fps=30, time=5)
    scene.window.destroy()

if __name__ == "__main__":
    # managed()
    manual()

Save to a custom.py and run with python custom.py loop-time 4 main -t 8 -o video.mp4 (red curve below), preferably install the latest pre release v0.9.0.dev1 from pypi. Alternatively, you can easily run it by using uv:

We can use some maths to make self.tau ease-out at the end, so it doesn't hard stops:

Image

import math

@define
class CustomScene(DepthScene):

    @property
    def tau(self) -> float:

        # Red curve
        return min(self.time / self._loop_time, 1)

        # Green curve
        return 1 - math.e**(-1.386*(self.time / self._loop_time))

        # Blue curve
        x = min(self.time / self._loop_time, 1)
        return x*x*(3 - 2*x)
Red curve video (click to expand)

Hard stops at the end, repeats last frame

red.mp4
Green curve video (click to expand)

Faster and explosive start, progressively slower as time goes

green.mp4
Blue curve video (click to expand)

Best all-around (called smoothstep), also kind of hard stops

blue.mp4

To loop multiple times simply multiply any of the functions above by an integer, for example, with 2*(1 - math.e**(...)):

Green curve (2x) video (click to expand)
multiple.mp4

It's kind of an advanced usage and the best way is through custom scripts..

Let me know if any of these solves what you need! 🙂

@stephanedebove
Copy link
Author

I don’t understand the whole code you produced but it works! Thanks a lot!
(I use custom scripts so no problems)

@Tremeschin
Copy link
Member

Awesome, happy to help!

Might add such scripts to a example of custom animation shaping functions too 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants