I have covered a lot of ground on stack so far trying to get ffmpeg going so I can make a timelapse video.
I am on a CentOS 7 machine, running python3.7.0a0
.
python3
>>> import numpy as np
>>> np.__version__
'1.12.0'
>>> import matplotlib as mpl
>>> mpl.__version__
'2.0.0'
>>> import mpl_toolkits.basemap as base
>>> base.__version__
'1.0.7'
I found this github gist on installing ffmpeg. I used the chromium source, and installed without a prefix
option (using the default).
I have confirmed that ffmpeg is installed, although I don't know anything about testing whether it works.
which ffmpeg
/usr/local/bin/ffmpeg
ffmpeg -version
ffmpeg version N-83533-gada281d Copyright (c) 2000-2017 the FFmpeg dev elopers
built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-11
configuration:
libavutil 55. 47.100 / 55. 47.100
libavcodec 57. 80.100 / 57. 80.100
libavformat 57. 66.102 / 57. 66.102
libavdevice 57. 2.100 / 57. 2.100
libavfilter 6. 73.100 / 6. 73.100
libswscale 4. 3.101 / 4. 3.101
libswresample 2. 4.100 / 2. 4.100
I tried to run a few sample examples I found online:
[1] http://matplotlib.org/examples/animation/basic_example_writer.html
[2] https://stackoverflow.com/a/23098090/3454650
Everything works fine up until I try to save the animation file.
[1]
anim.save('basic_animation.mp4', writer = FFwriter, fps=30, extra_args=['-vcodec', 'libx264'])
[2]
im_ani.save('im.mp4', writer=writer)
I found here that explictly setting the path to ffmpeg might be necessary so I added this to the top of the test scripts:
plt.rcParams['animation.ffmpeg_path'] = '/usr/local/bin/ffmpeg'
I tried a few more tweaks in the code but always get the same response, which I do not know how to begin deciphering:
Traceback (most recent call last):
File "testanim.py", line 27, in <module>
writer.grab_frame()
File "/usr/local/lib/python3.7/contextlib.py", line 100, in __exit__
self.gen.throw(type, value, traceback)
File "/usr/local/lib/python3.7/site-packages/matplotlib/animation.py", line 256, in saving
self.finish()
File "/usr/local/lib/python3.7/site-packages/matplotlib/animation.py", line 276, in finish
self.cleanup()
File "/usr/local/lib/python3.7/site-packages/matplotlib/animation.py", line 311, in cleanup
out, err = self._proc.communicate()
File "/usr/local/lib/python3.7/subprocess.py", line 836, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
File "/usr/local/lib/python3.7/subprocess.py", line 1474, in _communicate
selector.register(self.stdout, selectors.EVENT_READ)
File "/usr/local/lib/python3.7/selectors.py", line 351, in register
key = super().register(fileobj, events, data)
File "/usr/local/lib/python3.7/selectors.py", line 237, in register
key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data)
File "/usr/local/lib/python3.7/selectors.py", line 224, in _fileobj_lookup
return _fileobj_to_fd(fileobj)
File "/usr/local/lib/python3.7/selectors.py", line 39, in _fileobj_to_fd
"{!r}".format(fileobj)) from None
ValueError: Invalid file object: <_io.BufferedReader name=6>
Is there something with my configuration that is malformed? I searched google for this error for some time but never found anything relevant to animations / ffmpeg. Any help would be greatly appreciated.
UPDATE:
@LordNeckBeard pointed me here: https://trac.ffmpeg.org/wiki/CompilationGuide/Centos
I ran into problems with installing the x264 encoding dependency. Some files in libavcodec/*.c (in the make
output) were reporting undefined references to several functions. After a wild goose chase found this: https://mailman.videolan.org/pipermail/x264-devel/2015-February/010971.html
To fix the x264 installation, I simply added some configure
flags:
./configure --enable-static --enable-shared --extra-ldflags="-lswresample -llzma"
UPDATE:
So everything installed fine after fixing the libx264 problems. I went ahead and copied the ffmpeg binary from the ffmpeg_build
folder into /usr/local/bin/ffmpeg
.
After running the script I was getting problems where ffmpeg could not find the libx264 shared object. I think I will have to recompile everything using different prefixes. My intuition tells me there are old files laying around after I have messed with everything, using some configuration that is broken.
So I decided maybe I should just try to use NUX: http://linoxide.com/linux-how-to/install-ffmpeg-centos-7/ I installed ffmpeg using the new rpm, but to no avail. I still was not able to run ffmpeg because of a missing shared object.
Finally, instead of usiong files copied into my /usr/local/bin
folder, I ran ffmpeg directly from the build bin directory. Turns out that this does work properly!
So in essence, if I want to install ffmpeg system wide, I need to manually compile from sources again but using a nonlocal prefix.
Plotting our Animation We start by creating our figure object with three-dimensional axes. We then use FuncAnimation, which takes the figure, our animation function created earlier, an interval value, and a frames value as inputs.
To save an animation, we can use Animation. save() or Animation. to_html5_video().
I had this same issue using Anaconda. Running which ffmpeg
showed that it was using the ffmpeg
inside the Anaconda path instead of the system's binary. I fixed this by adding
plt.rcParams['animation.ffmpeg_path'] = '/usr/bin/ffmpeg'
immediately after my matplotlib
import.
I see no ffmpeg
specific info in the output you provided; however you are attempting to use libx264, but your ffmpeg configure is missing --enable-gpl --enable-libx264
which are required to enable encoding with this encoder. You can download a ffmpeg
binary for Linux, macOS, or Windows that does support libx264 then point your script to it.
Alternatively, compile ffmpeg
using the mentioned configure options.
I had a similar error and I found a solution in the comments of this matplotlib GitHub Issue:
My code was
WriterClass = animation.writers['ffmpeg']
writer = WriterClass(fps=10, metadata=dict(artist='bww'), bitrate=1800)
anim.save('../../data/media/' + name + '.mp4', writer=writer)
(Here anim
is just an animation.FuncAnimation(...)
with some settings)
I fixed it by using writer = animation.FFMpegFileWriter(...)
instead of WriterClass
(same arguments).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With