MoviePy AudioFileClip.to_soundarray 报错 TypeError: arrays to stack must be passed as a “sequence“

我的python3.10.14,moviepy 1.0.3

代码为:

from moviepy.editor import VideoFileClip, AudioFileClip
import numpy as np
import os

def read_audio(
    dir_name: str,
    file_name: str = "movie.mp4"
) -> np.ndarray:
    """Read the audio from behavioral video"""
    f_dir = os.path.join(dir_name, file_name)

    # Read audio from video
    with VideoFileClip(f_dir) as video:
        audio = video.audio

    # 也可以直接 video = VideoFileClip(f_dir)
    # audio = video.audio

    # Convert to array
    audio_array = audio.to_soundarray(fps = audio.fps)
    print(type(audio_array))

    # Get time from duration and convert it to milisecond
    audio_time = np.linspace(0, audio.duration, audio_array.shape[0]) * 1000
    return np.vstack((audio_array, audio_time)).T

if __name__ == "__main__":
    dir_name = r"E:\HelloWorld"
    audio = read_audio(dir_name)

报错信息:

  File "c:\ProgramData\anaconda3\envs\replaypy\Lib\site-packages\replay\preprocess\frequency.py", line 27, in <module>
    audio = read_audio(dir_name)
  File "c:\ProgramData\anaconda3\envs\replaypy\Lib\site-packages\replay\preprocess\frequency.py", line 17, in read_audio
    audio_array = audio.to_soundarray(fps = audio.fps)
  File "<decorator-gen-44>", line 2, in to_soundarray
  File "C:\ProgramData\anaconda3\envs\replaypy\lib\site-packages\moviepy\decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "C:\ProgramData\anaconda3\envs\replaypy\lib\site-packages\moviepy\audio\AudioClip.py", line 113, in to_soundarray
    return stacker(self.iter_chunks(fps=fps, quantize=quantize,
  File "C:\ProgramData\anaconda3\envs\replaypy\lib\site-packages\numpy\core\shape_base.py", line 216, in _vhstack_dispatcher
    return _arrays_for_stack_dispatcher(tup)
  File "C:\ProgramData\anaconda3\envs\replaypy\lib\site-packages\numpy\core\shape_base.py", line 209, in _arrays_for_stack_dispatcher
    raise TypeError('arrays to stack must be passed as a "sequence" type '
TypeError: arrays to stack must be passed as a "sequence" type such as list or tuple.

观察了下问题出在to_soundarray函数内的这一部分:

class AudioClip(Clip):
    ...
    
    @requires_duration
    def to_soundarray(self, tt=None, fps=None, quantize=False, nbytes=2, buffersize=50000):
        
        ...
        
        stacker = np.vstack if self.nchannels == 2 else np.hstack
        max_duration = 1.0 * buffersize / fps
        if tt is None:
            if self.duration > max_duration:
                return stacker(self.iter_chunks(fps=fps, quantize=quantize,
                                                nbytes=2, chunksize=buffersize))
            else:
                tt = np.arange(0, self.duration, 1.0/fps)
        
        ...

其中stacker,如果声道数为2(立体声),则用numpy的vstack函数,其他的则为hstack

而新的numpy环境已经不支持iter_chunks直接作为输入参数,因此报错。


据说更改python版本至3.8可以解决这一问题,也可以将moviepy更换为2.0.0dev0版本,参考:https://github.com/Zulko/moviepy/issues/1338

我觉得最直接的方式 参考Github issue: https://github.com/Zulko/moviepy/pull/1443https://github.com/Zulko/moviepy/pull/1443/commits/49536feea593c031e584975c010337d804eec560

显式的将self.iter_chunks转化为tuple数据类型。问题解决。

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值