Zulko / moviepy

Video editing with Python
https://zulko.github.io/moviepy/
MIT License
12.09k stars 1.51k forks source link

Multiple decorators, causing parameter parsing errors #2075

Open wangmos opened 7 months ago

wangmos commented 7 months ago

This bug occurs in VideoClip.py:

@requires_duration
@use_clip_fps_by_default
@convert_masks_to_RGB
def write_videofile(self, filename, fps=None, codec=None,

In the second decorator @use_clip_fps_by_default

names = func_code.co_varnames[1:]

This code will not get the expected parameter list, but the parameters of the @convert_masks_to_RGB decorator: *args, **kw

Solution: The final objective function under multiple wrappers must be obtained


@decorator.decorator
def use_clip_fps_by_default(f, clip, *a, **k):
    """ Will use clip.fps if no fps=... is provided in **k """

This is the newly added code

    import inspect
    def get_wrapped_function(func):
        nonlocals = inspect.getclosurevars(func).nonlocals
        if 'func' in nonlocals:
            return get_wrapped_function(nonlocals['func'])
        else:
            return func
    f = get_wrapped_function(f)
    def fun(fps):
        if fps is not None:
            return fps
        else:
            if hasattr(clip, 'fps') and clip.fps is not None:
                return clip.fps
            else:
                raise AttributeError("No 'fps' (frames per second) attribute specified"
                " for function %s and the clip has no 'fps' attribute. Either"
                " provide e.g. fps=24 in the arguments of the function, or define"
                " the clip's fps with `clip.fps=24`"%f.__name__)

    if hasattr(f, "func_code"):
        func_code = f.func_code # Python 2
    else:
        func_code = f.__code__ # Python 3

    names = func_code.co_varnames[1:]

    new_a = [fun(arg) if (name=='fps') else arg
             for (arg, name) in zip(a, names)]
    new_kw = {k: fun(v) if k=='fps' else v
             for (k,v) in k.items()}
    return f(clip, *new_a, **new_kw)
keikoro commented 4 months ago

This is the newly added code

Is this your code to fix the problem? Is this something that should go into a PR?

keikoro commented 4 months ago

@wangmos Ping. It's unclear which version of MoviePy you are using, i.e. if this issue hasn't been fixed already. I'm currently trying to find duplicates of the same fps-related issues and can't tell if yours is another candidate.