pitchplots
pitchplots copied to clipboard
Problem with MoviePy: maximum recursion depth
MoviePy seems to have problems with long pieces. I tried to create an animation of 25 measures (not really long for a musical piece) and it broke because of "maximum recursion depth".
This is the error message:
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
<ipython-input-54-28fac940bd82> in <module>
----> 1 tonnetz_animation(csv_path, measures=[1,25], center='G')
C:\ProgramData\Anaconda3\lib\site-packages\pitchplots\dynamic.py in tonnetz_animation(piece, pitch_type, measures, sampling_frequency, speed_ratio, pitch_class_display, adaptive_scale, duplicate, duration, log, colorbar, vocabulary, radius, hex_size, fontsize, figsize, cmap, nan_color, center, edgecolor, filename, **kwargs)
921 #audio_background = mpe.AudioFileClip('pitchplots_sound_only.wav')
922 my_clip = my_clip.set_audio(soundtrack)
--> 923 my_clip.write_videofile(filename)
924
925 # os.remove("pitchplots_midi.mid")
<C:\ProgramData\Anaconda3\lib\site-packages\decorator.py:decorator-gen-177> in write_videofile(self, filename, fps, codec, bitrate, audio, audio_fps, preset, audio_nbytes, audio_codec, audio_bitrate, audio_bufsize, temp_audiofile, rewrite_audio, remove_temp, write_logfile, verbose, threads, ffmpeg_params, logger)
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\decorators.py in requires_duration(f, clip, *a, **k)
52 raise ValueError("Attribute 'duration' not set")
53 else:
---> 54 return f(clip, *a, **k)
55
56
<C:\ProgramData\Anaconda3\lib\site-packages\decorator.py:decorator-gen-176> in write_videofile(self, filename, fps, codec, bitrate, audio, audio_fps, preset, audio_nbytes, audio_codec, audio_bitrate, audio_bufsize, temp_audiofile, rewrite_audio, remove_temp, write_logfile, verbose, threads, ffmpeg_params, logger)
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\decorators.py in use_clip_fps_by_default(f, clip, *a, **k)
135 for (k,v) in k.items()}
136
--> 137 return f(clip, *new_a, **new_kw)
<C:\ProgramData\Anaconda3\lib\site-packages\decorator.py:decorator-gen-175> in write_videofile(self, filename, fps, codec, bitrate, audio, audio_fps, preset, audio_nbytes, audio_codec, audio_bitrate, audio_bufsize, temp_audiofile, rewrite_audio, remove_temp, write_logfile, verbose, threads, ffmpeg_params, logger)
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\decorators.py in convert_masks_to_RGB(f, clip, *a, **k)
20 if clip.ismask:
21 clip = clip.to_RGB()
---> 22 return f(clip, *a, **k)
23
24 @decorator.decorator
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\video\VideoClip.py in write_videofile(self, filename, fps, codec, bitrate, audio, audio_fps, preset, audio_nbytes, audio_codec, audio_bitrate, audio_bufsize, temp_audiofile, rewrite_audio, remove_temp, write_logfile, verbose, threads, ffmpeg_params, logger)
315 write_logfile=write_logfile,
316 verbose=verbose,
--> 317 logger=logger)
318
319 ffmpeg_write_video(self, filename, fps, codec,
<C:\ProgramData\Anaconda3\lib\site-packages\decorator.py:decorator-gen-199> in write_audiofile(self, filename, fps, nbytes, buffersize, codec, bitrate, ffmpeg_params, write_logfile, verbose, logger)
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\decorators.py in requires_duration(f, clip, *a, **k)
52 raise ValueError("Attribute 'duration' not set")
53 else:
---> 54 return f(clip, *a, **k)
55
56
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\audio\AudioClip.py in write_audiofile(self, filename, fps, nbytes, buffersize, codec, bitrate, ffmpeg_params, write_logfile, verbose, logger)
207 write_logfile=write_logfile, verbose=verbose,
208 ffmpeg_params=ffmpeg_params,
--> 209 logger=logger)
210
211
<C:\ProgramData\Anaconda3\lib\site-packages\decorator.py:decorator-gen-196> in ffmpeg_audiowrite(clip, filename, fps, nbytes, buffersize, codec, bitrate, write_logfile, verbose, ffmpeg_params, logger)
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\decorators.py in requires_duration(f, clip, *a, **k)
52 raise ValueError("Attribute 'duration' not set")
53 else:
---> 54 return f(clip, *a, **k)
55
56
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\audio\io\ffmpeg_audiowriter.py in ffmpeg_audiowrite(clip, filename, fps, nbytes, buffersize, codec, bitrate, write_logfile, verbose, ffmpeg_params, logger)
167 quantize=True,
168 nbytes=nbytes, fps=fps,
--> 169 logger=logger):
170 writer.write_frames(chunk)
171
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\audio\AudioClip.py in iter_chunks(self, chunksize, chunk_duration, fps, quantize, nbytes, logger)
83 tt = (1.0/fps)*np.arange(pospos[i], pospos[i+1])
84 yield self.to_soundarray(tt, nbytes=nbytes, quantize=quantize,
---> 85 fps=fps, buffersize=chunksize)
86
87 @requires_duration
<C:\ProgramData\Anaconda3\lib\site-packages\decorator.py:decorator-gen-198> in to_soundarray(self, tt, fps, quantize, nbytes, buffersize)
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\decorators.py in requires_duration(f, clip, *a, **k)
52 raise ValueError("Attribute 'duration' not set")
53 else:
---> 54 return f(clip, *a, **k)
55
56
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\audio\AudioClip.py in to_soundarray(self, tt, fps, quantize, nbytes, buffersize)
124 #print tt.max() - tt.min(), tt.min(), tt.max()
125
--> 126 snd_array = self.get_frame(tt)
127
128 if quantize:
<C:\ProgramData\Anaconda3\lib\site-packages\decorator.py:decorator-gen-136> in get_frame(self, t)
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\decorators.py in wrapper(f, *a, **kw)
87 new_kw = {k: fun(v) if k in varnames else v
88 for (k,v) in kw.items()}
---> 89 return f(*new_a, **new_kw)
90 return decorator.decorator(wrapper)
91
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\Clip.py in get_frame(self, t)
93 return frame
94 else:
---> 95 return self.make_frame(t)
96
97 def fl(self, fun, apply_to=None, keep_duration=True):
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\audio\AudioClip.py in make_frame(t)
294
295 sounds = [c.get_frame(t - c.start)*np.array([part]).T
--> 296 for c, part in zip(self.clips, played_parts)
297 if (part is not False)]
298
C:\ProgramData\Anaconda3\lib\site-packages\moviepy\audio\AudioClip.py in <listcomp>(.0)
295 sounds = [c.get_frame(t - c.start)*np.array([part]).T
296 for c, part in zip(self.clips, played_parts)
--> 297 if (part is not False)]
298
299 if isinstance(t, np.ndarray):
... last 5 frames repeated, from the frame below ...
<C:\ProgramData\Anaconda3\lib\site-packages\decorator.py:decorator-gen-136> in get_frame(self, t)
RecursionError: maximum recursion depth exceeded
If there is no simple way to fix this, I suggest that we temporarily remove the movie facility from the library and stick with the GIFs because this seems to be a tricky case where more time should be invested.