#!/usr/bin/env python3 import glob import json import re import time from .base_worker import * from ..engines.aerender_engine import AERender def aerender_path(): paths = glob.glob('/Applications/*After Effects*/aerender') if len(paths) > 1: logging.warning('Multiple After Effects installations detected') elif not paths: logging.error('After Effects installation not found') else: return paths[0] class AERenderWorker(BaseRenderWorker): supported_extensions = ['.aep'] engine = AERender def __init__(self, input_path, output_path, priority=2, args=None, owner=None, client=None, name=None): super(AERenderWorker, self).__init__(input_path=input_path, output_path=output_path, args=args, client=client, priority=priority, owner=owner, name=name) self.comp = args.get('comp', None) self.render_settings = args.get('render_settings', None) self.omsettings = args.get('omsettings', None) self.progress = 0 self.progress_history = [] self.attributes = {} def generate_worker_subprocess(self): if os.path.exists('nexrender-cli-macos'): logging.info('nexrender found') # { # "template": { # "src": String, # "composition": String, # # "frameStart": Number, # "frameEnd": Number, # "frameIncrement": Number, # # "continueOnMissing": Boolean, # "settingsTemplate": String, # "outputModule": String, # "outputExt": String, # }, # "assets": [], # "actions": { # "prerender": [], # "postrender": [], # }, # "onChange": Function, # "onRenderProgress": Function # } job = {'template': { 'src': 'file://' + self.input_path, 'composition': self.comp.replace('"', ''), 'settingsTemplate': self.render_settings.replace('"', ''), 'outputModule': self.omsettings.replace('"', ''), 'outputExt': 'mov'} } x = ['./nexrender-cli-macos', "'{}'".format(json.dumps(job))] else: logging.info('nexrender not found') x = [aerender_path(), '-project', self.input_path, '-comp', self.comp, '-RStemplate', self.render_settings, '-OMtemplate', self.omsettings, '-output', self.output_path] return x def _parse_stdout(self, line): # print line if line.startswith('PROGRESS:'): # print 'progress' trimmed = line.replace('PROGRESS:', '').strip() if len(trimmed): self.progress_history.append(line) if 'Seconds' in trimmed: self._update_progress(line) elif ': ' in trimmed: tmp = trimmed.split(': ') self.attributes[tmp[0].strip()] = tmp[1].strip() elif line.startswith('WARNING:'): trimmed = line.replace('WARNING:', '').strip() self.warnings.append(trimmed) logging.warning(trimmed) elif line.startswith('aerender ERROR') or 'ERROR:' in line: self.log_error(line) def _update_progress(self, line): if not self.total_frames: duration_string = self.attributes.get('Duration', None) frame_rate = self.attributes.get('Frame Rate', '0').split(' ')[0] self.total_frames = timecode_to_frames(duration_string.split('Duration:')[-1], float(frame_rate)) match = re.match(r'PROGRESS:.*\((?P\d+)\): (?P