Closed
Description
Here is a basic test script:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure()
ax = plt.axes()
patch = plt.Circle((0, 0), 0)
def update(i):
patch.set_radius(np.sin(np.radians(i)))
def init():
ax.add_patch(patch)
ani = animation.FuncAnimation(fig, update, init_func=init, interval=10, frames=100)
ani.save('1.mp4', writer='mencoder_file', fps=25, bitrate=500)
It crashes as follows:
Traceback (most recent call last):
File "/home/pupssman/git/ado-ft/ado/tests/a.py", line 21, in <module>
ani.save('1.mp4', writer='mencoder_file', fps=25, bitrate=500)
File "/home/pupssman/venv/pytest/local/lib/python2.7/site-packages/matplotlib/animation.py", line 752, in save
writer.grab_frame(**savefig_kwargs)
File "/usr/lib/python2.7/contextlib.py", line 24, in __exit__
self.gen.next()
File "/home/pupssman/venv/pytest/local/lib/python2.7/site-packages/matplotlib/animation.py", line 177, in saving
self.finish()
File "/home/pupssman/venv/pytest/local/lib/python2.7/site-packages/matplotlib/animation.py", line 365, in finish
+ ' Try running with --verbose-debug')
RuntimeError: Error creating movie, return code: 1 Try running with --verbose-debug
Verbose reveals that it generates following command:
MovieWriter.run: running command: mencoder mf://_tmp*.png -frames 100 -mf type=png:fps=25 -o 1.mp4 -ovc lavc -lavcopts vcodec=mpeg4 vbitrate=500
And MEncoder fails with:
MEncoder 1.1-4.8 (C) 2000-2012 MPlayer Team
...
File not found: 'vbitrate=500'
Failed to open vbitrate=500.
Cannot open file/device.
...
And all the docs about MEncoder specify that mencoder's lavcopts should be given joined via :
, as in http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-enc-libavcodec.html:
-lavcopts vcodec=mpeg4:vbitrate=2400:v4mv:mbd=2:trell:cmp=3:subcmp=3:autoaspect:vpass=1
Looks like the problem in with this bit of code (animation.py's MencoderBase
):
args = ['-o', self.outfile, '-ovc', 'lavc', '-lavcopts',
'vcodec=%s' % self.codec]
if self.bitrate > 0:
args.append('vbitrate=%d' % self.bitrate)
Changing this to following fixes the failure:
lavcopts = {'vcodec': self.codec}
if self.bitrate > 0:
lavcopts.update(vbitrate=self.bitrate)
args = ['-o', self.outfile, '-ovc', 'lavc', '-lavcopts', ':'.join(itertools.starmap('{0}={1}'.format, lavcopts.items()))]
Could anyone of maintainers plz look into the issue and say if this is a proper fix? I would be glad to send a PR.