使用MoviePy的cutout方法触发索引越界错误的解决咨询
问题
我尝试用MoviePy从音频片段中移除主题曲,代码如下:
audioclip = AudioFileClip(file) audioclip.write_audiofile(audioFileName) offset = findOffset(audioFileName, themeFile, 90) print('\nFound offset: ', offset, ' - Writing audio file again...') print('Cutting audio from', offset, ' to ', str(offset + themeFileDuration)) cutout = audioclip.cutout(offset, offset + themeFileDuration) cutout.write_audiofile(cutoutAudioFileName)
代码逻辑为先创建AudioFileClip实例,写入文件后定位主题曲起始偏移量,再调用cutout方法移除对应片段并写入新文件。但执行到写入新文件步骤时,进度到3%就抛出错误:
Found offset: 49.1 - Writing audio file again... Cutting audio from 49.1 to 93.1 MoviePy - Writing audio in /Users/chud37/Desktop/Friends/output/120 - The Evil Orthodontist_cutout.wav chunk: 3%|████▋ | 755/27881 [00:00<00:06, 3914.41it/s, now=None]Traceback (most recent call last): File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/audio/io/readers.py", line 193, in get_frame result[in_time] = self.buffer[indices] IndexError: index -1842399 is out of bounds for axis 0 with size 200000 During handling of the above exception, another exception occurred: File "ttr.py", line 94, in <module> main() File "ttr.py", line 91, in main convertToAudioFiles(files, directory) File "ttr.py", line 60, in convertToAudioFiles cutout.write_audiofile(cutoutAudioFileName) File "<decorator-gen-47>", line 2, in write_audiofile File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/decorators.py", line 54, in requires_duration return f(clip, *a, **k) File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/audio/AudioClip.py", line 210, in write_audiofile logger=logger) File "<decorator-gen-11>", line 2, in ffmpeg_audiowrite File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/decorators.py", line 54, in requires_duration return f(clip, *a, **k) File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/audio/io/ffmpeg_audiowriter.py", line 169, in ffmpeg_audiowrite logger=logger): File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/audio/AudioClip.py", line 86, in iter_chunks fps=fps, buffersize=chunksize) File "<decorator-gen-46>", line 2, in to_soundarray File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/decorators.py", line 54, in requires_duration return f(clip, *a, **k) File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/audio/AudioClip.py", line 127, in to_soundarray snd_array = self.get_frame(tt) File "<decorator-gen-13>", line 2, in get_frame File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/decorators.py", line 89, in wrapper return f(*new_a, **new_kw) File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/Clip.py", line 93, in get_frame return self.make_frame(t) File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/Clip.py", line 136, in <lambda> newclip = self.set_make_frame(lambda t: fun(self.get_frame, t)) File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/Clip.py", line 187, in <lambda> return self.fl(lambda gf, t: gf(t_func(t)), apply_to, File "<decorator-gen-13>", line 2, in get_frame File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/decorators.py", line 89, in wrapper return f(*new_a, **new_kw) File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/Clip.py", line 93, in get_frame return self.make_frame(t) File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/audio/io/AudioFileClip.py", line 77, in <lambda> self.make_frame = lambda t: self.reader.get_frame(t) File "/Users/chud37/opt/anaconda3/envs/themeTuneRemover/lib/python3.6/site-packages/moviepy/audio/io/readers.py", line 205, in get_frame result[in_time] = self.buffer[indices] IndexError: index -1842399 is out of bounds for axis 0 with size 200000
我确认cutout方法的使用符合示例规范,但错误似乎源于MoviePy内部,该如何解决?
解决方案
- 避免复用原始AudioFileClip实例:原始实例写入文件后,内部缓存或读取指针可能出现异常。获取偏移量后,重新从写入的音频文件创建新实例再剪切:
audioclip = AudioFileClip(file) audioclip.write_audiofile(audioFileName) offset = findOffset(audioFileName, themeFile, 90) # 重新加载音频文件 new_audioclip = AudioFileClip(audioFileName) print('\nFound offset: ', offset, ' - Writing audio file again...') print('Cutting audio from', offset, ' to ', str(offset + themeFileDuration)) cutout = new_audioclip.cutout(offset, offset + themeFileDuration) cutout.write_audiofile(cutoutAudioFileName) # 手动关闭实例释放资源 audioclip.close() new_audioclip.close() cutout.close()
- 手动拼接音频片段替代cutout方法:绕过
cutout的内部bug,直接拆分音频为两段后拼接:
# 导入拼接工具 from moviepy.editor import concatenate_audioclips # 替换原cutout代码段 part1 = new_audioclip.subclip(0, offset) part2 = new_audioclip.subclip(offset + themeFileDuration) cutout = concatenate_audioclips([part1, part2]) cutout.write_audiofile(cutoutAudioFileName)
- 升级MoviePy及Python版本:你当前使用的Python3.6搭配旧版MoviePy,这类索引越界bug可能已在新版本修复。执行命令升级:
pip install --upgrade moviepy
若Python3.6兼容性存在问题,建议升级Python到3.8及以上版本后再更新MoviePy。
- 修复音频文件编码异常:原始音频可能存在损坏或编码问题,先用ffmpeg重新编码:
ffmpeg -i 原始音频文件 -acodec pcm_s16le 重编码后的文件.wav
使用重编码后的文件进行后续处理。
内容的提问来源于stack exchange,提问作者Chud37
相关产品推荐
相关产品推荐

