8000 Add method to convert Animation to HTML5 video. · matplotlib/matplotlib@8cdc00a · GitHub
[go: up one dir, main page]

Skip to content

Commit 8cdc00a

Browse files
committed
Add method to convert Animation to HTML5 video.
This paves the way for displaying animations in IPython notebooks.
1 parent 563129c commit 8cdc00a

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

lib/matplotlib/animation.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@
2323
from matplotlib.externals import six
2424
from matplotlib.externals.six.moves import xrange, zip
2525

26+
import os
2627
import platform
2728
import sys
2829
import itertools
30+
import base64
2931
import contextlib
32+
import tempfile
3033
from matplotlib.cbook import iterable, is_string_like
3134
from matplotlib.compat import subprocess
3235
from matplotlib import verbose
@@ -383,7 +386,6 @@ def cleanup(self):
383386

384387
# Delete temporary files
385388
if self.clear_temp:
386-
import os
387389
verbose.report(
388390
'MovieWriter: clearing temporary fnames=%s' %
389391
str(self._temp_names),
@@ -885,6 +887,51 @@ def _end_redraw(self, evt):
885887
self._resize_id = self._fig.canvas.mpl_connect('resize_event',
886888
self._handle_resize)
887889

890+
def to_html5_video(self):
891+
r'''Returns animation as an HTML5 video tag.
892+
893+
This saves the animation as an h264 video, encoded in base64
894+
directly into the HTML5 video tag. This respects the rc parameters
895+
for the writer as well as the bitrate. This also makes use of the
896+
``interval`` to control the speed, and uses the ``repeat``
897+
paramter to decide whether to loop.
898+
'''
899+
VIDEO_TAG = r'''<video {size} {options}>
900+
<source type="video/mp4" src="data:video/mp4;base64,{video}">
901+
Your browser does not support the video tag.
902+
</video>'''
903+
# Cache the the rendering of the video as HTML
904+
if not hasattr(self, '_base64_video'):
905+
# First write the video to a tempfile. Set delete to False
906+
# so we can re-open to read binary data.
907+
with tempfile.NamedTemporaryFile(suffix='.m4v',
908+
delete=False) as f:
909+
# We create a writer manually so that we can get the
910+
# appropriate size for the tag
911+
Writer = writers[rcParams['animation.writer']]
912+
writer = Writer(codec='h264',
913+
bitrate=rcParams['animation.bitrate'],
914+
fps=1000. / self._interval)
915+
self.save(f.name, writer=writer)
916+
917+
# Now open and base64 encode
918+
with open(f.name, 'rb') as video:
919+
vid64 = base64.encodebytes(video.read())
920+
self._base64_video = vid64.decode('ascii')
921+
self._video_size = 'width="{0}" height="{1}"'.format(
922+
*writer.frame_size)
923+
os.remove(f.name) # Now we can remove
924+
925+
# Default HTML5 options are to autoplay and to display video controls
926+
options = ['controls', 'autoplay']
927+
928+
# If we're set to repeat, make it loop
929+
if self.repeat:
930+
options.append('loop')
931+
return VIDEO_TAG.format(video=self._base64_video,
932+
size=self._video_size,
933+
options=' '.join(options))
934+
888935

889936
class TimedAnimation(Animation):
890937
'''

0 commit comments

Comments
 (0)
0