flake8 code cleanup, minor fixes
This commit is contained in:
parent
b9eb2d234e
commit
43f08547f0
4 changed files with 606 additions and 583 deletions
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
# vim: tabstop=4 shiftwidth=4 expandtab
|
||||
|
||||
import subprocess
|
||||
import renderlib
|
||||
|
@ -8,227 +9,235 @@ import shlex
|
|||
import time
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import platform
|
||||
|
||||
from xml.sax.saxutils import escape as xmlescape
|
||||
from shutil import copyfile
|
||||
|
||||
# Parse arguments
|
||||
parser = argparse.ArgumentParser(
|
||||
description='C3VOC Intro-Outro-Generator - Variant to use with Adobe After Effects Files',
|
||||
usage="./make-adobe-after-effects.py yourproject/ https://url/to/schedule.xml",
|
||||
formatter_class=argparse.RawTextHelpFormatter)
|
||||
description='C3VOC Intro-Outro-Generator - Variant to use with Adobe After Effects Files',
|
||||
usage="./make-adobe-after-effects.py yourproject/ https://url/to/schedule.xml",
|
||||
formatter_class=argparse.RawTextHelpFormatter)
|
||||
|
||||
parser.add_argument('project', action="store", metavar='Project folder', type=str, help='''
|
||||
Path to your project folder with After Effects Files (intro.aep/scpt/jsx)
|
||||
''')
|
||||
parser.add_argument('schedule', action="store", metavar='Schedule-URL', type=str, nargs='?', help='''
|
||||
URL or Path to your schedule.xml
|
||||
''')
|
||||
Path to your project folder with After Effects Files (intro.aep/scpt/jsx)
|
||||
''')
|
||||
parser.add_argument('schedule', action="store", metavar='Schedule-URL', type=str, nargs='?', help='''
|
||||
URL or Path to your schedule.xml
|
||||
''')
|
||||
|
||||
parser.add_argument('--debug', action="store_true", default=False, help='''
|
||||
Run script in debug mode and render with placeholder texts,
|
||||
not parsing or accessing a schedule. Schedule-URL can be left blank when
|
||||
used with --debug
|
||||
This argument must not be used together with --id
|
||||
Usage: ./make-adobe-after-effects.py yourproject/ --debug
|
||||
''')
|
||||
Run script in debug mode and render with placeholder texts,
|
||||
not parsing or accessing a schedule. Schedule-URL can be left blank when
|
||||
used with --debug
|
||||
This argument must not be used together with --id
|
||||
Usage: ./make-adobe-after-effects.py yourproject/ --debug
|
||||
''')
|
||||
|
||||
parser.add_argument('--id', dest='ids', nargs='+', action="store", type=int, help='''
|
||||
Only render the given ID(s) from your projects schedule.
|
||||
This argument must not be used together with --debug
|
||||
Usage: ./make-adobe-after-effects.py yourproject/ --id 4711 0815 4223 1337
|
||||
''')
|
||||
Only render the given ID(s) from your projects schedule.
|
||||
This argument must not be used together with --debug
|
||||
Usage: ./make-adobe-after-effects.py yourproject/ --id 4711 0815 4223 1337
|
||||
''')
|
||||
|
||||
parser.add_argument('--room', dest='rooms', nargs='+', action="store", type=str, help='''
|
||||
Only render the given room(s) from your projects schedule.
|
||||
This argument must not be used together with --debug
|
||||
Usage: ./make-adobe-after-effects.py yourproject/ --room "HfG_Studio" "ZKM_Vortragssaal"
|
||||
''')
|
||||
Only render the given room(s) from your projects schedule.
|
||||
This argument must not be used together with --debug
|
||||
Usage: ./make-adobe-after-effects.py yourproject/ --room "HfG_Studio" "ZKM_Vortragssaal"
|
||||
''')
|
||||
|
||||
parser.add_argument('--pause', action="store_true", default=False, help='''
|
||||
Render a pause loop from the pause.aep file in the project folder.
|
||||
''')
|
||||
Render a pause loop from the pause.aep file in the project folder.
|
||||
''')
|
||||
|
||||
parser.add_argument('--force', action="store_true", default=False, help='''
|
||||
Force render if file exists.
|
||||
''')
|
||||
Force render if file exists.
|
||||
''')
|
||||
|
||||
parser.add_argument('--no-finalize', dest='nof', action="store_true", default=False, help='''
|
||||
Skip finalize job.
|
||||
''')
|
||||
Skip finalize job.
|
||||
''')
|
||||
|
||||
parser.add_argument('--outro', action="store_true", default=False, help='''
|
||||
Render outro from the outro.aep file in the project folder.
|
||||
''')
|
||||
Render outro from the outro.aep file in the project folder.
|
||||
''')
|
||||
|
||||
parser.add_argument('--bgloop', action="store_true", default=False, help='''
|
||||
Render background loop from the bgloop.aep file in the project folder.
|
||||
''')
|
||||
Render background loop from the bgloop.aep file in the project folder.
|
||||
''')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
def headline(str):
|
||||
print("##################################################")
|
||||
print(str)
|
||||
print("##################################################")
|
||||
print()
|
||||
print("##################################################")
|
||||
print(str)
|
||||
print("##################################################")
|
||||
print()
|
||||
|
||||
|
||||
def error(str):
|
||||
headline(str)
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
headline(str)
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if not args.project:
|
||||
error("The Path to your project with After Effect Files is a required argument")
|
||||
error("The Path to your project with After Effect Files is a required argument")
|
||||
|
||||
if not args.debug and not args.pause and not args.outro and not args.bgloop and not args.schedule:
|
||||
error("Either specify --debug, --pause, --outro or supply a schedule")
|
||||
error("Either specify --debug, --pause, --outro or supply a schedule")
|
||||
|
||||
if args.debug:
|
||||
persons = ['watz']
|
||||
events = [{
|
||||
'id': 1,
|
||||
'title': 'Eröffnungsveranstaltung',
|
||||
'subtitle': 'Easterhegg 2018',
|
||||
'persons': persons,
|
||||
'personnames': ', '.join(persons),
|
||||
'room': 'Heisenberg 1',
|
||||
}]
|
||||
persons = ['watz']
|
||||
events = [{
|
||||
'id': 1,
|
||||
'title': 'Eröffnungsveranstaltung',
|
||||
'subtitle': 'Easterhegg 2018',
|
||||
'persons': persons,
|
||||
'personnames': ', '.join(persons),
|
||||
'room': 'Heisenberg 1',
|
||||
}]
|
||||
|
||||
elif args.pause:
|
||||
events = [{
|
||||
'id': 'pause',
|
||||
'title': 'Pause Loop',
|
||||
}]
|
||||
events = [{
|
||||
'id': 'pause',
|
||||
'title': 'Pause Loop',
|
||||
}]
|
||||
|
||||
elif args.outro:
|
||||
events = [{
|
||||
'id': 'outro',
|
||||
'title': 'Outro',
|
||||
}]
|
||||
events = [{
|
||||
'id': 'outro',
|
||||
'title': 'Outro',
|
||||
}]
|
||||
|
||||
elif args.bgloop:
|
||||
events = [{
|
||||
'id': 'bgloop',
|
||||
'title': 'Background Loop',
|
||||
}]
|
||||
events = [{
|
||||
'id': 'bgloop',
|
||||
'title': 'Background Loop',
|
||||
}]
|
||||
|
||||
else:
|
||||
events = list(renderlib.events(args.schedule))
|
||||
events = list(renderlib.events(args.schedule))
|
||||
|
||||
|
||||
def describe_event(event):
|
||||
return "#{}: {}".format(event['id'], event['title'])
|
||||
return "#{}: {}".format(event['id'], event['title'])
|
||||
|
||||
|
||||
def event_print(event, message):
|
||||
print("{} – {}".format(describe_event(event), message))
|
||||
print("{} – {}".format(describe_event(event), message))
|
||||
|
||||
|
||||
tempdir = tempfile.TemporaryDirectory()
|
||||
print('working in '+tempdir.name)
|
||||
print('working in ' + tempdir.name)
|
||||
|
||||
|
||||
def fmt_command(command, **kwargs):
|
||||
args = {}
|
||||
for key, value in kwargs.items():
|
||||
args[key] = shlex.quote(value)
|
||||
args = {}
|
||||
for key, value in kwargs.items():
|
||||
args[key] = shlex.quote(value)
|
||||
|
||||
command = command.format(**args)
|
||||
return shlex.split(command)
|
||||
|
||||
command = command.format(**args)
|
||||
return shlex.split(command)
|
||||
|
||||
def run_once(command, **kwargs):
|
||||
DETACHED_PROCESS = 0x00000008
|
||||
return subprocess.Popen(
|
||||
fmt_command(command, **kwargs),
|
||||
shell=False,
|
||||
stdin=None,
|
||||
stdout=None,
|
||||
stderr=None,
|
||||
close_fds=True,
|
||||
creationflags=DETACHED_PROCESS)
|
||||
DETACHED_PROCESS = 0x00000008
|
||||
return subprocess.Popen(
|
||||
fmt_command(command, **kwargs),
|
||||
shell=False,
|
||||
stdin=None,
|
||||
stdout=None,
|
||||
stderr=None,
|
||||
close_fds=True,
|
||||
creationflags=DETACHED_PROCESS)
|
||||
|
||||
|
||||
def run(command, **kwargs):
|
||||
return subprocess.check_call(
|
||||
fmt_command(command, **kwargs),
|
||||
stderr=subprocess.STDOUT,
|
||||
stdout=subprocess.DEVNULL)
|
||||
return subprocess.check_call(
|
||||
fmt_command(command, **kwargs),
|
||||
stderr=subprocess.STDOUT,
|
||||
stdout=subprocess.DEVNULL)
|
||||
|
||||
|
||||
def enqueue_job(event):
|
||||
event_id = str(event['id'])
|
||||
if os.path.exists(os.path.join(args.project, event_id+'.ts')) or os.path.exists(os.path.join(args.project, event_id+'.mov')) and not args.force:
|
||||
event_print(event, "file exist, skipping "+str(event['id']))
|
||||
return
|
||||
work_doc = os.path.join(tempdir.name, event_id+'.aep')
|
||||
script_doc = os.path.join(tempdir.name, event_id+'.jsx')
|
||||
ascript_doc = os.path.join(tempdir.name, event_id+'.scpt')
|
||||
intermediate_clip = os.path.join(tempdir.name, event_id+'.mov')
|
||||
event_id = str(event['id'])
|
||||
if os.path.exists(os.path.join(args.project, event_id + '.ts')) or os.path.exists(os.path.join(args.project, event_id + '.mov')) and not args.force:
|
||||
event_print(event, "file exist, skipping " + str(event['id']))
|
||||
return
|
||||
work_doc = os.path.join(tempdir.name, event_id + '.aep')
|
||||
script_doc = os.path.join(tempdir.name, event_id + '.jsx')
|
||||
ascript_doc = os.path.join(tempdir.name, event_id + '.scpt')
|
||||
intermediate_clip = os.path.join(tempdir.name, event_id + '.mov')
|
||||
|
||||
if event_id == 'pause' or event_id == 'outro' or event_id == 'bgloop':
|
||||
copyfile(args.project+event_id+'.aep',work_doc)
|
||||
if platform.system() == 'Darwin':
|
||||
run('/Applications/Adobe\ After\ Effects\ CC\ 2018/aerender -project {jobpath} -comp {comp} -output {locationpath}',
|
||||
jobpath=work_doc,
|
||||
comp=event_id,
|
||||
locationpath=intermediate_clip)
|
||||
if event_id == 'pause' or event_id == 'outro' or event_id == 'bgloop':
|
||||
copyfile(args.project + event_id + '.aep', work_doc)
|
||||
if platform.system() == 'Darwin':
|
||||
run(r'/Applications/Adobe\ After\ Effects\ CC\ 2018/aerender -project {jobpath} -comp {comp} -output {locationpath}',
|
||||
jobpath=work_doc,
|
||||
comp=event_id,
|
||||
locationpath=intermediate_clip)
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
run('C:/Program\ Files/Adobe/Adobe\ After\ Effects\ CC\ 2018/Support\ Files/aerender.exe -project {jobpath} -comp {comp} -output {locationpath}',
|
||||
jobpath=work_doc,
|
||||
comp=event_id,
|
||||
locationpath=intermediate_clip)
|
||||
if platform.system() == 'Windows':
|
||||
run(r'C:/Program\ Files/Adobe/Adobe\ After\ Effects\ CC\ 2018/Support\ Files/aerender.exe -project {jobpath} -comp {comp} -output {locationpath}',
|
||||
jobpath=work_doc,
|
||||
comp=event_id,
|
||||
locationpath=intermediate_clip)
|
||||
|
||||
else:
|
||||
with open(args.project+'intro.jsx', 'r') as fp:
|
||||
scriptstr = fp.read()
|
||||
else:
|
||||
with open(args.project + 'intro.jsx', 'r') as fp:
|
||||
scriptstr = fp.read()
|
||||
|
||||
for key, value in event.items():
|
||||
value = str(value).replace('"', '\\"')
|
||||
scriptstr = scriptstr.replace("$"+str(key), value)
|
||||
for key, value in event.items():
|
||||
value = str(value).replace('"', '\\"')
|
||||
scriptstr = scriptstr.replace("$" + str(key), value)
|
||||
|
||||
with open(script_doc, 'w', encoding='utf-8') as fp:
|
||||
fp.write(scriptstr)
|
||||
with open(script_doc, 'w', encoding='utf-8') as fp:
|
||||
fp.write(scriptstr)
|
||||
|
||||
copyfile(args.project+'intro.aep',work_doc)
|
||||
copyfile(args.project + 'intro.aep', work_doc)
|
||||
|
||||
if platform.system() == 'Darwin':
|
||||
copyfile(args.project+'intro.scpt',ascript_doc)
|
||||
run('osascript {ascript_path} {jobpath} {scriptpath}',
|
||||
jobpath=work_doc,
|
||||
scriptpath=script_doc,
|
||||
ascript_path=ascript_doc)
|
||||
if platform.system() == 'Darwin':
|
||||
copyfile(args.project + 'intro.scpt', ascript_doc)
|
||||
run('osascript {ascript_path} {jobpath} {scriptpath}',
|
||||
jobpath=work_doc,
|
||||
scriptpath=script_doc,
|
||||
ascript_path=ascript_doc)
|
||||
|
||||
run('/Applications/Adobe\ After\ Effects\ CC\ 2018/aerender -project {jobpath} -comp "intro" -output {locationpath}',
|
||||
jobpath=work_doc,
|
||||
locationpath=intermediate_clip)
|
||||
run(r'/Applications/Adobe\ After\ Effects\ CC\ 2018/aerender -project {jobpath} -comp "intro" -output {locationpath}',
|
||||
jobpath=work_doc,
|
||||
locationpath=intermediate_clip)
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
run_once('C:/Program\ Files/Adobe/Adobe\ After\ Effects\ CC\ 2018/Support\ Files/AfterFX.exe -noui {jobpath}',
|
||||
jobpath=work_doc)
|
||||
time.sleep(15)
|
||||
if platform.system() == 'Windows':
|
||||
run_once(r'C:/Program\ Files/Adobe/Adobe\ After\ Effects\ CC\ 2018/Support\ Files/AfterFX.exe -noui {jobpath}',
|
||||
jobpath=work_doc)
|
||||
time.sleep(15)
|
||||
|
||||
run_once('C:/Program\ Files/Adobe/Adobe\ After\ Effects\ CC\ 2018/Support\ Files/AfterFX.exe -noui -r {scriptpath}',
|
||||
scriptpath=script_doc)
|
||||
time.sleep(5)
|
||||
run_once(r'C:/Program\ Files/Adobe/Adobe\ After\ Effects\ CC\ 2018/Support\ Files/AfterFX.exe -noui -r {scriptpath}',
|
||||
scriptpath=script_doc)
|
||||
time.sleep(5)
|
||||
|
||||
run('C:/Program\ Files/Adobe/Adobe\ After\ Effects\ CC\ 2018/Support\ Files/aerender.exe -project {jobpath} -comp "intro" -output {locationpath}',
|
||||
jobpath=work_doc,
|
||||
locationpath=intermediate_clip)
|
||||
run(r'C:/Program\ Files/Adobe/Adobe\ After\ Effects\ CC\ 2018/Support\ Files/aerender.exe -project {jobpath} -comp "intro" -output {locationpath}',
|
||||
jobpath=work_doc,
|
||||
locationpath=intermediate_clip)
|
||||
|
||||
return event_id
|
||||
|
||||
return event_id
|
||||
|
||||
def finalize_job(job_id, event):
|
||||
event_id = str(event['id'])
|
||||
intermediate_clip = os.path.join(tempdir.name, event_id+'.mov')
|
||||
final_clip = os.path.join(os.path.dirname(args.project), event_id+'.ts')
|
||||
event_id = str(event['id'])
|
||||
intermediate_clip = os.path.join(tempdir.name, event_id + '.mov')
|
||||
final_clip = os.path.join(os.path.dirname(args.project), event_id + '.ts')
|
||||
|
||||
run('ffmpeg -y -hide_banner -loglevel error -i {input} -f lavfi -i anullsrc -ar 48000 -ac 2 -map 0:v -c:v mpeg2video -q:v 0 -aspect 16:9 -map 1:a -map 1:a -map 1:a -map 1:a -shortest -f mpegts {output}',
|
||||
#run('ffmpeg -y -hide_banner -loglevel error -i "{input}" -ar 48000 -ac 1 -map 0:v -c:v mpeg2video -q:v 0 -aspect 16:9 -map 1:0 -c:a copy -map 2:0 -c:a copy -shortest -f mpegts "{output}"',
|
||||
input=intermediate_clip,
|
||||
output=final_clip)
|
||||
run('ffmpeg -y -hide_banner -loglevel error -i {input} -f lavfi -i anullsrc -ar 48000 -ac 2 -map 0:v -c:v mpeg2video -q:v 0 -aspect 16:9 -map 1:a -map 1:a -map 1:a -map 1:a -shortest -f mpegts {output}',
|
||||
# run('ffmpeg -y -hide_banner -loglevel error -i "{input}" -ar 48000 -ac 1 -map 0:v -c:v mpeg2video -q:v 0 -aspect 16:9 -map 1:0 -c:a copy -map 2:0 -c:a copy -shortest -f mpegts "{output}"',
|
||||
input=intermediate_clip,
|
||||
output=final_clip)
|
||||
|
||||
if event_id == 'pause' or event_id == 'outro' or event_id == 'bgloop':
|
||||
event_print(event, "finalized "+str(event_id)+" to "+final_clip)
|
||||
else:
|
||||
event_print(event, "finalized intro to "+final_clip)
|
||||
if event_id == 'pause' or event_id == 'outro' or event_id == 'bgloop':
|
||||
event_print(event, "finalized " + str(event_id) + " to " + final_clip)
|
||||
else:
|
||||
event_print(event, "finalized intro to " + final_clip)
|
||||
|
||||
|
||||
if args.ids:
|
||||
|
@ -243,34 +252,34 @@ else:
|
|||
print("enqueuing {} jobs into aerender".format(len(events)))
|
||||
|
||||
for event in events:
|
||||
if args.ids and event['id'] not in args.ids:
|
||||
continue
|
||||
if args.ids and event['id'] not in args.ids:
|
||||
continue
|
||||
|
||||
if args.rooms and event['room'] not in args.rooms:
|
||||
print("skipping room %s (%s)" % (event['room'], event['title']))
|
||||
continue
|
||||
if args.rooms and event['room'] not in args.rooms:
|
||||
print("skipping room %s (%s)" % (event['room'], event['title']))
|
||||
continue
|
||||
|
||||
event_print(event, "enqueued as "+str(event['id']))
|
||||
event_print(event, "enqueued as " + str(event['id']))
|
||||
|
||||
job_id = enqueue_job(event)
|
||||
if not job_id:
|
||||
event_print(event, "job was not enqueued successfully, skipping postprocessing")
|
||||
continue
|
||||
job_id = enqueue_job(event)
|
||||
if not job_id:
|
||||
event_print(event, "job was not enqueued successfully, skipping postprocessing")
|
||||
continue
|
||||
|
||||
if not args.nof:
|
||||
event_print(event, "finalizing job")
|
||||
finalize_job(job_id, event)
|
||||
if not args.nof:
|
||||
event_print(event, "finalizing job")
|
||||
finalize_job(job_id, event)
|
||||
else:
|
||||
event_id = str(event['id'])
|
||||
event_print(event, "skipping finalizing job")
|
||||
if platform.system() == 'Windows':
|
||||
intermediate_clip = os.path.join(tempdir.name, event_id + '.avi')
|
||||
final_clip = os.path.join(os.path.dirname(args.project), event_id + '.avi')
|
||||
else:
|
||||
event_id = str(event['id'])
|
||||
event_print(event, "skipping finalizing job")
|
||||
if platform.system() == 'Windows':
|
||||
intermediate_clip = os.path.join(tempdir.name, event_id+'.avi')
|
||||
final_clip = os.path.join(os.path.dirname(args.project), event_id+'.avi')
|
||||
else:
|
||||
intermediate_clip = os.path.join(tempdir.name, event_id+'.mov')
|
||||
final_clip = os.path.join(os.path.dirname(args.project), event_id+'.mov')
|
||||
copyfile(intermediate_clip, final_clip)
|
||||
event_print(event, "copied intermediate clip to "+final_clip)
|
||||
intermediate_clip = os.path.join(tempdir.name, event_id + '.mov')
|
||||
final_clip = os.path.join(os.path.dirname(args.project), event_id + '.mov')
|
||||
copyfile(intermediate_clip, final_clip)
|
||||
event_print(event, "copied intermediate clip to " + final_clip)
|
||||
|
||||
print('all done, cleaning up '+tempdir.name)
|
||||
print('all done, cleaning up ' + tempdir.name)
|
||||
tempdir.cleanup()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue