Skip to content

Commit

Permalink
improve mp4/ffmpeg support
Browse files Browse the repository at this point in the history
  • Loading branch information
kbarnhart committed Mar 21, 2024
1 parent f6df10e commit 94e2084
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 32 deletions.
10 changes: 6 additions & 4 deletions src/python/visclaw/animation_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ def make_rst(anim, file_name='anim.rst',


def make_mp4(anim, file_name='anim.mp4',
fps=None, embed_frames=True, default_mode='once'):
fps=None, embed_frames=True, default_mode='once',
dpi=None):
"""
Take an animation and covert to mp4 file using ffmpeg, which must be
installed.
Expand All @@ -259,7 +260,7 @@ def make_mp4(anim, file_name='anim.mp4',
if fps is None:
fps = 3
writer = animation.writers['ffmpeg'](fps=fps)
anim.save(file_name, writer=writer)
anim.save(file_name, writer=writer, dpi=dpi)
print("Created %s" % file_name)


Expand Down Expand Up @@ -409,8 +410,9 @@ def make_anim_outputs_from_plotdir(plotdir='_plots', fignos='all',

if 'mp4' in outputs:
file_name = file_name_prefix + 'fig%s.mp4' % figno

make_mp4(anim, file_name, fps=fps, \
embed_frames=True, default_mode='once')
embed_frames=True, default_mode='once', dpi=dpi)

if 'html' in outputs:
file_name = file_name_prefix + 'fig%s.html' % figno
Expand All @@ -423,7 +425,7 @@ def make_anim_outputs_from_plotdir(plotdir='_plots', fignos='all',
embed_frames=True, default_mode='once')


def animate_from_plotdir(plotdir='_plots', figno=None, figsize=None,
def animate_from_plotdir(plotdir='_plots', figno=None, figsize=None,
dpi=None, fps=5):
"""
Use the png files in plotdir to create an animation that is returned.
Expand Down
13 changes: 4 additions & 9 deletions src/python/visclaw/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,8 @@ def __init__(self, controller=None):

self.add_attribute('gif_movie',False) # make animated gif movie of frames

self.add_attribute('ffmpeg_movie',False) # make animated mp4 movie with ffmpeg
self.add_attribute('ffmpeg_name', "")
self.add_attribute('ffmpeg_global_options', '')
self.add_attribute('ffmpeg_input_options', '-y -r 6 -f image2')
self.add_attribute('ffmpeg_output_options', '-vcodec libx264 -vf scale=1800:-2 -crf 20 -pix_fmt yuv420p')


self.add_attribute('mp4_movie',False) # make animated mp4 movie of frames
self.add_attribute('movie_name_prefix', 'movie_')
self.add_attribute('setplot',False) # Execute setplot.py in plot routine

self.add_attribute('mapc2p',None) # function to map computational
Expand Down Expand Up @@ -696,9 +691,9 @@ def __init__(self, name, plotfigure):
self.add_attribute('title_fontsize', None)
self.add_attribute('title_kwargs', {}) # e.g. to set color
self.add_attribute('title_t_format', None) # format for t in title
self.add_attribute('xticks_fontsize', None)
self.add_attribute('xticks_fontsize', None)
self.add_attribute('xticks_kwargs', {}) # e.g. to set ticks,rotation
self.add_attribute('yticks_fontsize', None)
self.add_attribute('yticks_fontsize', None)
self.add_attribute('yticks_kwargs', {}) # e.g. to set ticks
self.add_attribute('xlabel', None) # label for x-axis
self.add_attribute('ylabel', None) # label for y-axis
Expand Down
53 changes: 34 additions & 19 deletions src/python/visclaw/plotpages.py
Original file line number Diff line number Diff line change
Expand Up @@ -2243,6 +2243,12 @@ def plotclaw2html(plotdata):
html.write('\n <td><a href="moviefig%s.gif">%s</a></td>' \
% (fignos[ifig],fignames[fignos[ifig]]))
html.write('</tr>\n')
if plotdata.mp4_movie:
html.write('<p><tr><td><b>mp4 Movies:</b></td>')
for ifig in range(len(fignos)):
html.write(f'\n <td><a href="{plotdata.movie_name_prefix}fig%s.mp4">%s</a></td>' \
% (fignos[ifig],fignames[fignos[ifig]]))
html.write('</tr>\n')
html.write('<p>\n<tr><td><b>All Frames:</b></td> ')
for ifig in range(len(fignos)):
html.write('\n <td><a href="%s">%s</a></td>' \
Expand Down Expand Up @@ -3052,7 +3058,7 @@ def plotclaw_driver(plotdata, verbose=False, format='ascii'):
if plotdata.kml:
plotpages.plotclaw2kml(plotdata)

if (plotdata.html_movie == "JSAnimation") and (len(framenos) > 0):
if ((plotdata.html_movie == "JSAnimation") or plotdata.mp4_movie) and (len(framenos) > 0):

# Create Animations

Expand All @@ -3070,16 +3076,39 @@ def plotclaw_driver(plotdata, verbose=False, format='ascii'):
png_prefix = ''
else:
png_prefix = plotdata.file_prefix

outputs = []
if plotdata.html_movie == "JSAnimation":
outputs.append('html')
if plotdata.mp4_movie:
outputs.append('mp4')

# get original dpi and fig shape, if
# this ensures that the resolution of the movie is the
# same as the frames.
figname = plotdata._figname_from_num[figno]
plotfigure = plotdata.plotfigure_dict[figname]

figkwargs = getattr(plotfigure, 'kwargs', {})
figsize = getattr(plotfigure, 'figsize', None)
if figsize is None:
figsize = figkwargs.get('figsize', None)
dpi = figkwargs.get('dpi', html_movie_dpi)

# make animations
animation_tools.make_anim_outputs_from_plotdir(plotdir=plotdir,
#file_name_prefix='movieframe_allframes',
file_name_prefix='movie_',
file_name_prefix=plotdata.movie_name_prefix,
png_prefix=png_prefix,
figsize=None,
fignos=[figno], outputs=['html'], raw_html=raw_html)
figsize=figsize,
dpi=dpi,
fignos=[figno], outputs=outputs,
raw_html=raw_html)

# Note: setting figsize=None above chooses figsize with aspect
# ratio based on .png files read in, may fit better on page

# 3/21/24 - For MP4 size and dpi are taken from plotdata for each figure.


#-----------
# gif movie:
Expand All @@ -3095,20 +3124,6 @@ def plotclaw_driver(plotdata, verbose=False, format='ascii'):
except:
print('*** Error creating moviefig%s.gif' % figno)

#-----------
# mp4 movie:
#-----------
if plotdata.ffmpeg_movie:
print('Making movies with ffmpeg. This may take some time....')
for figno in fignos_each_frame:
try:
cmd = f"ffmpeg {plotdata.ffmpeg_global_options} {plotdata.ffmpeg_input_options} -i frame%4dfig{figno}.png {plotdata.ffmpeg_output_options} {plotdata.ffmpeg_name}moviefig{figno}.mp4"
os.system(cmd)
print(' Created ffmpeg outputs for figno %s' % figno)
except:
print('*** Error creating ffmpeg outputs for figno %s' % figno)


os.chdir(rootdir)

# print out pointers to html index page:
Expand Down

0 comments on commit 94e2084

Please sign in to comment.