Skip to content

Commit

Permalink
Timelapse update (#591)
Browse files Browse the repository at this point in the history
* Removing ffmpy requirement
* Can overwrite timelapse
* Default timelapse goes into same directory as observation
  • Loading branch information
wtgee authored Sep 15, 2018
1 parent 3358d3f commit aa226be
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 29 deletions.
96 changes: 68 additions & 28 deletions pocs/utils/images/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
from matplotlib import pyplot as plt
from warnings import warn

from astropy import units as u
from astropy.wcs import WCS
from astropy.io.fits import open as open_fits
from astropy.visualization import (PercentileInterval, LogStretch, ImageNormalize)

from ffmpy import FFmpeg
from glob import glob
from copy import copy

Expand Down Expand Up @@ -201,20 +199,34 @@ def _make_pretty_from_cr2(fname, timeout=15, **kwargs): # pragma: no cover
return fname.replace('cr2', 'jpg')


def create_timelapse(directory, fn_out=None, file_type='jpg', **kwargs):
"""Create a timelapse
def make_timelapse(
directory,
fn_out=None,
file_type='jpg',
overwrite=False,
timeout=60,
verbose=False,
**kwargs):
"""Create a timelapse.
A timelapse is created from all the jpg images in a given `directory`
A timelapse is created from all the images in a given `directory`
Args:
directory (str): Directory containing jpg files
directory (str): Directory containing image files
fn_out (str, optional): Full path to output file name, if not provided,
defaults to `directory` basename.
file_type (str, optional): Type of file to search for, default 'jpg'.
overwrite (bool, optional): Overwrite timelapse if exists, default False.
timeout (int): Timeout for making movie, default 60 seconds.
verbose (bool, optional): Show output, default False.
**kwargs (dict): Valid keywords: verbose
Returns:
str: Name of output file
Raises:
error.InvalidSystemCommand: Raised if ffmpeg command is not found.
FileExistsError: Raised if fn_out already exists and overwrite=False.
"""
if fn_out is None:
head, tail = os.path.split(directory)
Expand All @@ -224,29 +236,54 @@ def create_timelapse(directory, fn_out=None, file_type='jpg', **kwargs):
field_name = head.split('/')[-2]
cam_name = head.split('/')[-1]
fname = '{}_{}_{}.mp4'.format(field_name, cam_name, tail)
fn_out = os.path.join(os.getenv('PANDIR'), 'images', 'timelapse', fname)
fn_out = os.path.normpath(os.path.join(directory, fname))

if verbose:
print("Timelapse file: {}".format(fn_out))

if os.path.exists(fn_out) and not overwrite:
raise FileExistsError("Timelapse exists. Set overwrite=True if needed")

ffmpeg = shutil.which('ffmpeg')
if ffmpeg is None:
raise error.InvalidSystemCommand("ffmpeg not found, can't make timelapse")

fn_dir = os.path.dirname(fn_out)
os.makedirs(fn_dir, exist_ok=True)
inputs_glob = os.path.join(directory, '*.{}'.format(file_type))

try:
ff = FFmpeg(
global_options='-r 3 -pattern_type glob',
inputs={inputs_glob: None},
outputs={
fn_out: '-s hd1080 -vcodec libx264'
})

if 'verbose' in kwargs:
out = None
err = None
print("Timelapse command: ", ff.cmd)
else:
out = open(os.devnull, 'w')
err = open(os.devnull, 'w')

ff.run(stdout=out, stderr=err)
ffmpeg_cmd = [
ffmpeg,
'-r', '3',
'-pattern_type', 'glob',
'-i', inputs_glob,
'-s', 'hd1080',
'-vcodec', 'libx264',
]

if overwrite:
ffmpeg_cmd.append('-y')

ffmpeg_cmd.append(fn_out)

if verbose:
print(ffmpeg_cmd)

proc = subprocess.Popen(ffmpeg_cmd, universal_newlines=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
try:
# Don't wait forever
outs, errs = proc.communicate(timeout=timeout)
except subprocess.TimeoutExpired:
proc.kill()
outs, errs = proc.communicate()
finally:
if verbose:
print(outs)
print(errs)

# Double-check for file existence
if not os.path.exists(fn_out):
fn_out = None
except Exception as e:
warn("Problem creating timelapse in {}: {!r}".format(fn_out, e))
fn_out = None
Expand Down Expand Up @@ -307,9 +344,12 @@ def _glob(s):
if len(jpg_list) > 0:

# Create timelapse
_print('Creating timelapse for {}'.format(dir_name))
video_file = create_timelapse(dir_name)
_print('Timelapse created: {}'.format(video_file))
try:
_print('Creating timelapse for {}'.format(dir_name))
video_file = make_timelapse(dir_name)
_print('Timelapse created: {}'.format(video_file))
except Exception as e:
_print("Problem creating timelapse: {}".format(e))

# Remove jpgs
_print('Removing jpgs')
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ ccdproc
codecov
coveralls
dateparser
ffmpy
gcloud
google-cloud-storage
matplotlib >= 2.0.0
Expand Down

0 comments on commit aa226be

Please sign in to comment.