Zulko / moviepy

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

"Arrays to stack must be passed as a sequence" in clip.to_soundarray for audio clips #2025

Open vincenzoml opened 11 months ago

vincenzoml commented 11 months ago

I have a function to load audio to an array that looks more or less like this:

def load_audio(filename, mono=False):
    clip = mpy.AudioFileClip(filename)
    vector = clip.to_soundarray(fps=clip.fps)
    ...

Expected Behavior

The audio is converted to an array

Actual Behavior

I get the following error on "clip.to_soundarray"

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/workspaces/animachines-ai/home/vincenzo/projects/kitchen/kitchen.py in line 4
      [33](file:///workspaces/animachines-ai/home/vincenzo/projects/kitchen/kitchen.py?line=32) breakpoint()
      [34](file:///workspaces/animachines-ai/home/vincenzo/projects/kitchen/kitchen.py?line=33) # %% audio
----> [36](file:///workspaces/animachines-ai/home/vincenzo/projects/kitchen/kitchen.py?line=35) master_track = sonica.load_audio("music/kitchen 2023-08-06 2312.mp3")

File /workspaces/animachines-ai/home/vincenzo/anima/sonica.py:110, in load_audio(filename, mono)
    [108](file:///workspaces/animachines-ai/home/vincenzo/anima/sonica.py?line=107) clip = mpy.AudioFileClip(filename)
    [109](file:///workspaces/animachines-ai/home/vincenzo/anima/sonica.py?line=108) fn = clip.get_frame
--> [110](file:///workspaces/animachines-ai/home/vincenzo/anima/sonica.py?line=109) vector = clip.to_soundarray(fps=clip.fps)
    [111](file:///workspaces/animachines-ai/home/vincenzo/anima/sonica.py?line=110) if mono:
    [112](file:///workspaces/animachines-ai/home/vincenzo/anima/sonica.py?line=111)     def fn(t): return np.average(clip.get_frame(t))

File :2, in to_soundarray(self, tt, fps, quantize, nbytes, buffersize)

File /usr/local/lib/python3.10/dist-packages/moviepy/decorators.py:54, in requires_duration(f, clip, *a, **k)
     [52](file:///usr/local/lib/python3.10/dist-packages/moviepy/decorators.py?line=51)     raise ValueError("Attribute 'duration' not set")
     [53](file:///usr/local/lib/python3.10/dist-packages/moviepy/decorators.py?line=52) else:
---> [54](file:///usr/local/lib/python3.10/dist-packages/moviepy/decorators.py?line=53)     return f(clip, *a, **k)

File /usr/local/lib/python3.10/dist-packages/moviepy/audio/AudioClip.py:113, in AudioClip.to_soundarray(self, tt, fps, quantize, nbytes, buffersize)
    [111](file:///usr/local/lib/python3.10/dist-packages/moviepy/audio/AudioClip.py?line=110) if tt is None:
    [112](file:///usr/local/lib/python3.10/dist-packages/moviepy/audio/AudioClip.py?line=111)     if self.duration > max_duration:
--> [113](file:///usr/local/lib/python3.10/dist-packages/moviepy/audio/AudioClip.py?line=112)         return stacker(self.iter_chunks(fps=fps, quantize=quantize,
    [114](file:///usr/local/lib/python3.10/dist-packages/moviepy/audio/AudioClip.py?line=113)                                         nbytes=2, chunksize=buffersize))
    [115](file:///usr/local/lib/python3.10/dist-packages/moviepy/audio/AudioClip.py?line=114)     else:
    [116](file:///usr/local/lib/python3.10/dist-packages/moviepy/audio/AudioClip.py?line=115)         tt = np.arange(0, self.duration, 1.0/fps)

File [~/.local/lib/python3.10/site-packages/numpy/core/shape_base.py:216](https://vscode-remote+dev-002dcontainer-002b7b22686f737450617468223a222f686f6d652f76696e63656e7a6f2f646174612f6c6f63616c2f7265706f732f616e696d616368696e65732d6169222c226c6f63616c446f636b6572223a66616c73652c2273657474696e6773223a7b22686f7374223a227373683a2f2f70632d6369616e6369612e697374692e636e722e6974227d2c22636f6e66696746696c65223a7b22246d6964223a312c2270617468223a222f686f6d652f76696e63656e7a6f2f646174612f6c6f63616c2f7265706f732f616e696d616368696e65732d61692f2e646576636f6e7461696e65722f646576636f6e7461696e65722e6a736f6e222c22736368656d65223a227673636f64652d66696c65486f7374227d7d.vscode-resource.vscode-cdn.net/workspaces/animachines-ai/home/vincenzo/projects/kitchen/~/.local/lib/python3.10/site-packages/numpy/core/shape_base.py:216), in _vhstack_dispatcher(tup, dtype, casting)
    [215](file:///home/animachines/.local/lib/python3.10/site-packages/numpy/core/shape_base.py?line=214) def _vhstack_dispatcher(tup, *, dtype=None, casting=None):
--> [216](file:///home/animachines/.local/lib/python3.10/site-packages/numpy/core/shape_base.py?line=215)     return _arrays_for_stack_dispatcher(tup)

File [~/.local/lib/python3.10/site-packages/numpy/core/shape_base.py:209](https://vscode-remote+dev-002dcontainer-002b7b22686f737450617468223a222f686f6d652f76696e63656e7a6f2f646174612f6c6f63616c2f7265706f732f616e696d616368696e65732d6169222c226c6f63616c446f636b6572223a66616c73652c2273657474696e6773223a7b22686f7374223a227373683a2f2f70632d6369616e6369612e697374692e636e722e6974227d2c22636f6e66696746696c65223a7b22246d6964223a312c2270617468223a222f686f6d652f76696e63656e7a6f2f646174612f6c6f63616c2f7265706f732f616e696d616368696e65732d61692f2e646576636f6e7461696e65722f646576636f6e7461696e65722e6a736f6e222c22736368656d65223a227673636f64652d66696c65486f7374227d7d.vscode-resource.vscode-cdn.net/workspaces/animachines-ai/home/vincenzo/projects/kitchen/~/.local/lib/python3.10/site-packages/numpy/core/shape_base.py:209), in _arrays_for_stack_dispatcher(arrays)
    [207](file:///home/animachines/.local/lib/python3.10/site-packages/numpy/core/shape_base.py?line=206) def _arrays_for_stack_dispatcher(arrays):
    [208](file:///home/animachines/.local/lib/python3.10/site-packages/numpy/core/shape_base.py?line=207)     if not hasattr(arrays, "__getitem__"):
--> [209](file:///home/animachines/.local/lib/python3.10/site-packages/numpy/core/shape_base.py?line=208)         raise TypeError('arrays to stack must be passed as a "sequence" type '
    [210](file:///home/animachines/.local/lib/python3.10/site-packages/numpy/core/shape_base.py?line=209)                         'such as list or tuple.')
    [212](file:///home/animachines/.local/lib/python3.10/site-packages/numpy/core/shape_base.py?line=211)     return tuple(arrays)

TypeError: arrays to stack must be passed as a "sequence" type such as list or tuple.

Specifications

vincenzoml commented 11 months ago

I found out the issue comes from recent numpy (> 1.25.1) which probably enforces deprecation of some behaviour. Using numpy 1.24.4 is a way to overcome the issue temporarily, but I guess moviepy should be updated.

bianchiidentity commented 9 months ago

I encountered the same bug. Is there a resolution for this issue?

Details:

NumPy Version: 1.24.3 (No error) NumPy Version: 1.26.0

TypeError
arrays to stack must be passed as a "sequence" type such as list or tuple.
  File "/app/exec.py", line 54, in <module>
    audio = video_clip.audio.to_soundarray()
TypeError: arrays to stack must be passed as a "sequence" type such as list or tuple.
Geometrein commented 8 months ago

Encountered the same issue. For those who are stuck a workaround to using to_soundarray() can be something like this:

# Load the clip
audio_clip = mpy.AudioFileClip(filename)

# Extract the audio as a list of samples
audio_samples = list(audio_clip.iter_frames())

# Convert the list of samples to a NumPy array
sound_array = np.array(audio_samples)

It seems that this issue was raised and fixed before but then the fix was deleted from the codebase for some reason...

keikoro commented 4 months ago

It seems that this issue was raised and fixed before but then the fix was deleted from the codebase for some reason...

@Geometrein what do you mean by "but then the fix was deleted from the codebase"? The fix you refer to is in master, isn't it?

cjaverliat commented 1 week ago

As pointed out by @keikoro, the fix is present in master, but not in the commit db19920 used for the latest release on PyPi (1.0.3 as of today): https://github.com/Zulko/moviepy/blob/db19920764b5cb1d8aa6863019544fd8ae0d3cce/moviepy/audio/AudioClip.py#L113-L114

It looks like the 1.0.3 version is already 4 years old!

In the meantime, you can install the package directly from the git repo like so:

pip install git+https://github.com/Zulko/moviepy.git