mirror of
https://github.com/blw1138/Zordon.git
synced 2025-12-17 08:48:13 +00:00
146 lines
5.0 KiB
Python
146 lines
5.0 KiB
Python
#! /usr/bin/python
|
|
import glob
|
|
import json
|
|
import re
|
|
import time
|
|
|
|
from utilities.render_worker import *
|
|
|
|
|
|
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):
|
|
|
|
@staticmethod
|
|
def version():
|
|
version = None
|
|
try:
|
|
x = subprocess.Popen([aerender_path(), '-version'], stdout=subprocess.PIPE)
|
|
x.wait()
|
|
ver_out = str(x.stdout.read().strip())
|
|
version = ver_out.split(" ")[-1].strip()
|
|
except Exception as e:
|
|
logging.error('failed getting version: {}'.format(e))
|
|
return version
|
|
|
|
renderer = 'After Effects'
|
|
render_engine = 'aerender'
|
|
supported_extensions = ['.aep']
|
|
|
|
def __init__(self, project, comp, render_settings, omsettings, output):
|
|
super(AERenderWorker, self).__init__(input=project, output=output)
|
|
|
|
self.comp = comp
|
|
self.render_settings = render_settings
|
|
self.omsettings = omsettings
|
|
|
|
self.progress = 0
|
|
self.progress_history = []
|
|
self.attributes = {}
|
|
|
|
def _generate_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, '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, '-comp', self.comp, '-RStemplate', self.render_settings,
|
|
'-OMtemplate', self.omsettings, '-output', self.output]
|
|
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.errors.append(line)
|
|
logging.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<frame>\d+)\): (?P<time>\d+)', line).groupdict()
|
|
self.last_frame = match['frame']
|
|
|
|
def average_frame_duration(self):
|
|
|
|
total_durations = 0
|
|
|
|
for line in self.progress_history:
|
|
match = re.match(r'PROGRESS:.*\((?P<frame>\d+)\): (?P<time>\d+)', line)
|
|
if match:
|
|
total_durations += int(match.group(2))
|
|
|
|
average = float(total_durations) / self.last_frame
|
|
return average
|
|
|
|
def percent_complete(self):
|
|
if self.total_frames:
|
|
return (float(self.last_frame) / float(self.total_frames)) * 100
|
|
else:
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
logging.basicConfig(format='%(asctime)s - %(message)s', datefmt='%d-%b-%y %H:%M:%S', level=logging.DEBUG)
|
|
|
|
r = AERenderWorker('/Users/brett/Desktop/Youtube_Vids/Film_Formats/Frame_Animations.aep', '"Film Pan"',
|
|
'"Draft Settings"', '"ProRes"', '/Users/brett/Desktop/test_render')
|
|
r.start()
|
|
while r.is_running():
|
|
time.sleep(0.1)
|