[TIDY] Apply autopep8 formatting

This commit is contained in:
Jannik Beyerstedt 2023-10-29 11:53:59 +01:00
parent 909bf79673
commit b0e83b1134
12 changed files with 405 additions and 329 deletions

2
.pep8 Normal file
View file

@ -0,0 +1,2 @@
[pycodestyle]
max_line_length = 99

287
easing.py
View file

@ -4,208 +4,233 @@
import math import math
def easeLinear(t, b, c, d): def easeLinear(t, b, c, d):
return c*t/d + b return c*t/d + b
def easeOutCubic(t, b, c, d): def easeOutCubic(t, b, c, d):
t=float(t)/d-1 t = float(t)/d-1
return c*((t)*t*t + 1) + b return c*((t)*t*t + 1) + b
def easeInCubic(t, b, c, d): def easeInCubic(t, b, c, d):
t=float(t)/d t = float(t)/d
return c*(t)*t*t + b; return c*(t)*t*t + b
def easeInQuad(t, b, c, d): def easeInQuad(t, b, c, d):
t /= d t /= d
return c*t*t + b return c*t*t + b
def easeOutQuad(t, b, c, d): def easeOutQuad(t, b, c, d):
t /= d t /= d
return -c * t*(t-2) + b return -c * t*(t-2) + b
def easeInOutQuad(t, b, c, d): def easeInOutQuad(t, b, c, d):
t /= d/2 t /= d/2
if t < 1: if t < 1:
return c/2*t*t + b return c/2*t*t + b
t-=1 t -= 1
return -c/2 * (t*(t-2) - 1) + b return -c/2 * (t*(t-2) - 1) + b
def easeInOutCubic(t, b, c, d): def easeInOutCubic(t, b, c, d):
t /= d/2 t /= d/2
if t < 1: if t < 1:
return c/2*t*t*t + b return c/2*t*t*t + b
t -= 2 t -= 2
return c/2*(t*t*t + 2) + b return c/2*(t*t*t + 2) + b
def easeInQuart(t, b, c, d): def easeInQuart(t, b, c, d):
t /= d t /= d
return c*t*t*t*t + b return c*t*t*t*t + b
def easeOutQuart(t, b, c, d): def easeOutQuart(t, b, c, d):
t /= d t /= d
t -= 1 t -= 1
return -c * (t*t*t*t - 1) + b return -c * (t*t*t*t - 1) + b
def easeInOutQuart(t, b, c, d): def easeInOutQuart(t, b, c, d):
t /= d/2 t /= d/2
if t < 1: if t < 1:
return c/2*t*t*t*t + b return c/2*t*t*t*t + b
t -= 2 t -= 2
return -c/2 * (t*t*t*t - 2) + b return -c/2 * (t*t*t*t - 2) + b
def easeInQuint(t, b, c, d): def easeInQuint(t, b, c, d):
t /= d t /= d
return c*t*t*t*t*t + b return c*t*t*t*t*t + b
def easeOutQuint(t, b, c, d): def easeOutQuint(t, b, c, d):
t /= d t /= d
t -= 1 t -= 1
return c*(t*t*t*t*t + 1) + b return c*(t*t*t*t*t + 1) + b
def easeInOutQuint(t, b, c, d): def easeInOutQuint(t, b, c, d):
t /= d/2 t /= d/2
if t < 1: if t < 1:
return c/2*t*t*t*t*t + b return c/2*t*t*t*t*t + b
t -= 2 t -= 2
return c/2*(t*t*t*t*t + 2) + b return c/2*(t*t*t*t*t + 2) + b
def easeInSine(t, b, c, d): def easeInSine(t, b, c, d):
return -c * math.cos(t/d * (math.pi/2)) + c + b return -c * math.cos(t/d * (math.pi/2)) + c + b
def easeOutSine(t, b, c, d): def easeOutSine(t, b, c, d):
return c * math.sin(t/d * (math.pi/2)) + b return c * math.sin(t/d * (math.pi/2)) + b
def easeInOutSine(t, b, c, d): def easeInOutSine(t, b, c, d):
return -c/2 * (math.cos(math.pi*t/d) - 1) + b return -c/2 * (math.cos(math.pi*t/d) - 1) + b
def easeInExpo(t, b, c, d): def easeInExpo(t, b, c, d):
return c * math.pow( 2, 10 * (t/d - 1) ) + b return c * math.pow(2, 10 * (t/d - 1)) + b
def easeOutExpo(t, b, c, d): def easeOutExpo(t, b, c, d):
return c * ( -math.pow( 2, -10 * t/d ) + 1 ) + b return c * (-math.pow(2, -10 * t/d) + 1) + b
def easeInOutExpo(t, b, c, d): def easeInOutExpo(t, b, c, d):
t /= d/2 t /= d/2
if t < 1: if t < 1:
return c/2 * math.pow( 2, 10 * (t - 1) ) + b return c/2 * math.pow(2, 10 * (t - 1)) + b
t -= 1 t -= 1
return c/2 * ( -math.pow( 2, -10 * t) + 2 ) + b return c/2 * (-math.pow(2, -10 * t) + 2) + b
def easeInCirc(t, b, c, d): def easeInCirc(t, b, c, d):
t /= d t /= d
return -c * (math.sqrt(1 - t*t) - 1) + b return -c * (math.sqrt(1 - t*t) - 1) + b
def easeOutCirc(t, b, c, d): def easeOutCirc(t, b, c, d):
t /= d; t /= d
t -= 1 t -= 1
return c * math.sqrt(1 - t*t) + b return c * math.sqrt(1 - t*t) + b
def easeInOutCirc(t, b, c, d): def easeInOutCirc(t, b, c, d):
t /= d/2 t /= d/2
if t < 1: if t < 1:
return -c/2 * (math.sqrt(1 - t*t) - 1) + b return -c/2 * (math.sqrt(1 - t*t) - 1) + b
t -= 2 t -= 2
return c/2 * (math.sqrt(1 - t*t) + 1) + b return c/2 * (math.sqrt(1 - t*t) + 1) + b
def easeInElastic(t, b, c, d, s = 1.70158): def easeInElastic(t, b, c, d, s=1.70158):
a = c a = c
if t == 0: if t == 0:
return b return b
t /= d t /= d
if t == 1: if t == 1:
return b + c return b + c
p = d * 0.3 p = d * 0.3
if a < abs(c): if a < abs(c):
a = c a = c
s = p / 4 s = p / 4
else: else:
s = p / (2 * math.pi) * math.asin(c / a) s = p / (2 * math.pi) * math.asin(c / a)
t -= 1 t -= 1
return -(a * pow(2, 10 * t) * math.sin((t * d - s) * (2 * math.pi) / p)) + b return -(a * pow(2, 10 * t) * math.sin((t * d - s) * (2 * math.pi) / p)) + b
def easeOutElastic(t, b, c, d, a = 1.70158):
if t == 0:
return b
t /= d
if t == 1:
return b + c
p = d * 0.3 def easeOutElastic(t, b, c, d, a=1.70158):
if a < abs(c): if t == 0:
a, s = c, p / 4 return b
else: t /= d
s = p / (2 * math.pi) * math.asin(c / a) if t == 1:
return b + c
return a * pow(2, -10 * t) * math.sin((t * d - s) * (2 * math.pi) / p) + c + b p = d * 0.3
if a < abs(c):
a, s = c, p / 4
else:
s = p / (2 * math.pi) * math.asin(c / a)
def easeInOutElastic(t, b, c, d, a = 1.70158): return a * pow(2, -10 * t) * math.sin((t * d - s) * (2 * math.pi) / p) + c + b
if t == 0:
return b
t /= (d / 2)
if t == 2:
return b + c
p = d * (0.3 * 1.5)
if a < abs(c):
a, s = c, p / 4
else:
s = p / (2 * math.pi) * math.asin(c / a)
if t < 1: def easeInOutElastic(t, b, c, d, a=1.70158):
t -= 1 if t == 0:
return -0.5 * (a * pow(2, 10 * t) * math.sin((t * d - s) * (2 * math.pi) / p)) + b return b
t /= (d / 2)
if t == 2:
return b + c
t -= 1 p = d * (0.3 * 1.5)
return a * pow(2, -10 * t) * math.sin((t * d - s) * (2 * math.pi) / p ) * 0.5 + c + b if a < abs(c):
a, s = c, p / 4
else:
s = p / (2 * math.pi) * math.asin(c / a)
def easeInBack(t, b, c, d, s = 1.70158): if t < 1:
t /= d t -= 1
return c * t * t * ((s + 1) * t - s) + b return -0.5 * (a * pow(2, 10 * t) * math.sin((t * d - s) * (2 * math.pi) / p)) + b
def easeOutBack(t, b, c, d, s = 1.70158): t -= 1
t = t / d - 1 return a * pow(2, -10 * t) * math.sin((t * d - s) * (2 * math.pi) / p) * 0.5 + c + b
return c * (t * t * ((s + 1) * t + s) + 1) + b
def easeInOutBack(t, b, c, d, s = 1.70158):
t /= d / 2
s *= 1.525
if t < 1:
return c / 2 * (t * t * ((s + 1) * t - s)) + b;
t -= 2 def easeInBack(t, b, c, d, s=1.70158):
return c/2 * (t * t * ((s + 1) * t + s) + 2) + b; t /= d
return c * t * t * ((s + 1) * t - s) + b
def easeOutBack(t, b, c, d, s=1.70158):
t = t / d - 1
return c * (t * t * ((s + 1) * t + s) + 1) + b
def easeInOutBack(t, b, c, d, s=1.70158):
t /= d / 2
s *= 1.525
if t < 1:
return c / 2 * (t * t * ((s + 1) * t - s)) + b
t -= 2
return c/2 * (t * t * ((s + 1) * t + s) + 2) + b
def easeInBounce(t, b, c, d): def easeInBounce(t, b, c, d):
return c - easeOutBounce(d-t, 0, c, d) + b; return c - easeOutBounce(d-t, 0, c, d) + b
def easeOutBounce(t, b, c, d): def easeOutBounce(t, b, c, d):
t /= d t /= d
if t < (1/2.75): if t < (1/2.75):
return c*(7.5625*t*t) + b; return c*(7.5625*t*t) + b
elif t < (2/2.75): elif t < (2/2.75):
t -= (1.5/2.75) t -= (1.5/2.75)
return c*(7.5625*t*t + 0.75) + b; return c*(7.5625*t*t + 0.75) + b
elif t < (2.5/2.75): elif t < (2.5/2.75):
t -= (2.25/2.75) t -= (2.25/2.75)
return c*(7.5625*t*t + 0.9375) + b; return c*(7.5625*t*t + 0.9375) + b
else:
t -= (2.625/2.75)
return c*(7.5625*t*t + 0.984375) + b
else:
t -= (2.625/2.75)
return c*(7.5625*t*t + 0.984375) + b;
def easeInOutBounce(t, b, c, d): def easeInOutBounce(t, b, c, d):
if t < d/2: if t < d/2:
return easeInBounce(t*2, 0, c, d) * .5 + b; return easeInBounce(t*2, 0, c, d) * .5 + b
return easeOutBounce(t*2-d, 0, c, d) * .5 + c*.5 + b; return easeOutBounce(t*2-d, 0, c, d) * .5 + c*.5 + b

View file

@ -109,7 +109,7 @@ if not args.debug and not args.pause and not args.outro and not args.bgloop and
error("Either specify --debug, --pause, --outro or supply a schedule") error("Either specify --debug, --pause, --outro or supply a schedule")
if args.debug: if args.debug:
#persons = ['blubbel'] # persons = ['blubbel']
persons = ['Vitor Sakaguti', 'Sara', 'A.L. Fehlhaber'] persons = ['Vitor Sakaguti', 'Sara', 'A.L. Fehlhaber']
events = [{ events = [{
'id': 11450, 'id': 11450,
@ -177,15 +177,15 @@ def run_output(command, **kwargs):
def run_once(command, **kwargs): def run_once(command, **kwargs):
DETACHED_PROCESS = 0x00000008 DETACHED_PROCESS = 0x00000008
return subprocess.Popen( return subprocess.Popen(
fmt_command(command, **kwargs), fmt_command(command, **kwargs),
shell=False, shell=False,
stdin=None, stdin=None,
stdout=None, stdout=None,
stderr=None, stderr=None,
close_fds=True, close_fds=True,
creationflags=DETACHED_PROCESS) creationflags=DETACHED_PROCESS)
def enqueue_job(event): def enqueue_job(event):
@ -227,16 +227,16 @@ def enqueue_job(event):
with open(script_doc, 'w', encoding='utf-8') as fp: with open(script_doc, 'w', encoding='utf-8') as fp:
fp.write(scriptstr) fp.write(scriptstr)
copyfile(args.project+args.introfile,work_doc) copyfile(args.project+args.introfile, work_doc)
if platform.system() == 'Darwin': if platform.system() == 'Darwin':
copyfile(args.project+'intro.scpt',ascript_doc) copyfile(args.project+'intro.scpt', ascript_doc)
run('osascript {ascript_path} {scriptpath}', run('osascript {ascript_path} {scriptpath}',
scriptpath=script_doc, scriptpath=script_doc,
ascript_path=ascript_doc) ascript_path=ascript_doc)
#run('osascript {ascript_path} {jobpath} {scriptpath}', # run('osascript {ascript_path} {jobpath} {scriptpath}',
# jobpath=work_doc, # jobpath=work_doc,
# scriptpath=script_doc, # scriptpath=script_doc,
# ascript_path=ascript_doc) # ascript_path=ascript_doc)
@ -247,7 +247,7 @@ def enqueue_job(event):
if platform.system() == 'Windows': if platform.system() == 'Windows':
run_once(r'C:/Program\ Files/Adobe/Adobe\ After\ Effects\ 2022/Support\ Files/AfterFX.exe -noui -r {scriptpath}', run_once(r'C:/Program\ Files/Adobe/Adobe\ After\ Effects\ 2022/Support\ Files/AfterFX.exe -noui -r {scriptpath}',
scriptpath=script_doc) scriptpath=script_doc)
time.sleep(5) time.sleep(5)
@ -256,7 +256,7 @@ def enqueue_job(event):
locationpath=intermediate_clip) locationpath=intermediate_clip)
if args.debug or args.keep: if args.debug or args.keep:
path = tempdir.name path = tempdir.name
dirs = os.listdir( path ) dirs = os.listdir(path)
for file in dirs: for file in dirs:
print(file) print(file)
@ -277,7 +277,7 @@ def finalize_job(job_id, event):
if args.alpha: if args.alpha:
ffprobe = run_output('ffprobe -i {input} -show_streams -select_streams a -loglevel error', ffprobe = run_output('ffprobe -i {input} -show_streams -select_streams a -loglevel error',
input=intermediate_clip) input=intermediate_clip)
if ffprobe: if ffprobe:
run('ffmpeg -threads 0 -y -hide_banner -loglevel error -i {input} -c:v qtrle -movflags faststart -aspect 16:9 -c:a mp2 -b:a 384k -shortest -f mov {output}', run('ffmpeg -threads 0 -y -hide_banner -loglevel error -i {input} -c:v qtrle -movflags faststart -aspect 16:9 -c:a mp2 -b:a 384k -shortest -f mov {output}',
input=intermediate_clip, input=intermediate_clip,
@ -288,7 +288,7 @@ def finalize_job(job_id, event):
output=final_clip) output=final_clip)
else: else:
ffprobe = run_output('ffprobe -i {input} -show_streams -select_streams a -loglevel error', ffprobe = run_output('ffprobe -i {input} -show_streams -select_streams a -loglevel error',
input=intermediate_clip) input=intermediate_clip)
if ffprobe: if ffprobe:
event_print(event, "finalize with audio from source file") event_print(event, "finalize with audio from source file")
run('ffmpeg -threads 0 -y -hide_banner -loglevel error -i {input} -c:v mpeg2video -q:v 2 -aspect 16:9 -c:a mp2 -b:a 384k -shortest -f mpegts {output}', run('ffmpeg -threads 0 -y -hide_banner -loglevel error -i {input} -c:v mpeg2video -q:v 2 -aspect 16:9 -c:a mp2 -b:a 384k -shortest -f mpegts {output}',

View file

@ -117,6 +117,7 @@ def fmt_command(command, **kwargs):
def run(command, **kwargs): def run(command, **kwargs):
os.system(fmt_command(command, **kwargs)) os.system(fmt_command(command, **kwargs))
def run_output(command, **kwargs): def run_output(command, **kwargs):
# Apple Compressor behaves weirdly with its stdout. It will not terminate right when ran through # Apple Compressor behaves weirdly with its stdout. It will not terminate right when ran through
# os.subprocess, but work fine when run via os.system. To still get the output, we pipe it into a # os.subprocess, but work fine when run via os.system. To still get the output, we pipe it into a
@ -127,6 +128,7 @@ def run_output(command, **kwargs):
os.system(f'{cmd} >{t.name} 2>&1') os.system(f'{cmd} >{t.name} 2>&1')
return t.read().decode('utf-8') return t.read().decode('utf-8')
def enqueue_job(event): def enqueue_job(event):
event_id = str(event['id']) event_id = str(event['id'])
work_doc = os.path.join(tempdir.name, event_id + '.motn') work_doc = os.path.join(tempdir.name, event_id + '.motn')
@ -156,7 +158,8 @@ def enqueue_job(event):
def fetch_job_status(): def fetch_job_status():
compressor_status = run_output('/Applications/Compressor.app/Contents/MacOS/Compressor -monitor') compressor_status = run_output(
'/Applications/Compressor.app/Contents/MacOS/Compressor -monitor')
job_status_matches = re.finditer(r"<jobStatus (.*) \/jobStatus>", compressor_status) job_status_matches = re.finditer(r"<jobStatus (.*) \/jobStatus>", compressor_status)
status_dict = {} status_dict = {}
@ -188,7 +191,8 @@ def filter_finished_jobs(active_jobs):
elif status == 'Successful': elif status == 'Successful':
finished_jobs.append((job_id, event)) finished_jobs.append((job_id, event))
else: else:
event_print(event, "failed with staus=" + status + " removing from postprocessing queue") event_print(event, "failed with staus=" + status +
" removing from postprocessing queue")
return new_active_jobs, finished_jobs return new_active_jobs, finished_jobs
@ -209,6 +213,7 @@ def finalize_job(job_id, event):
event_print(event, "finalized intro to " + final_clip) event_print(event, "finalized intro to " + final_clip)
active_jobs = [] active_jobs = []
if args.ids: if args.ids:
@ -219,7 +224,8 @@ if args.exclude_ids:
filtered_events = events filtered_events = events
filtered_events = filter(lambda event: not args.ids or event['id'] in args.ids, filtered_events) filtered_events = filter(lambda event: not args.ids or event['id'] in args.ids, filtered_events)
filtered_events = filter(lambda event: not args.exclude_ids or event['id'] not in args.exclude_ids, filtered_events) filtered_events = filter(
lambda event: not args.exclude_ids or event['id'] not in args.exclude_ids, filtered_events)
filtered_events = list(filtered_events) filtered_events = list(filtered_events)
print("enqueuing {} jobs into compressor".format(len(filtered_events))) print("enqueuing {} jobs into compressor".format(len(filtered_events)))

View file

@ -19,14 +19,14 @@ from shutil import copyfile
titlemap = {} titlemap = {}
#titlemap = { # titlemap = {
# "205" : { # "205" : {
# "title" : "Attacking CPUs with Power Side Channels from Software" # "title" : "Attacking CPUs with Power Side Channels from Software"
# }, # },
# "20" : { # "20" : {
# "title" : "New title for Talk id 20" # "title" : "New title for Talk id 20"
# } # }
#} # }
# Parse arguments # Parse arguments
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
@ -117,7 +117,7 @@ if not args.debug and not args.pause and not args.outro and not args.bgloop and
error("Either specify --debug, --pause, --outro or supply a schedule") error("Either specify --debug, --pause, --outro or supply a schedule")
if args.debug: if args.debug:
#persons = ['blubbel'] # persons = ['blubbel']
persons = ['Vitor Sakaguti', 'Sara', 'A.L. Fehlhaber'] persons = ['Vitor Sakaguti', 'Sara', 'A.L. Fehlhaber']
events = [{ events = [{
'id': 11450, 'id': 11450,
@ -228,7 +228,8 @@ def enqueue_job(event):
if platform.system() == 'Darwin': if platform.system() == 'Darwin':
if args.debug: if args.debug:
print("running: Blender.app --background %s --python-use-system-env --python %s --use-extension 0 --threads 0 --render-output %s --render-anim" % (work_source, work_doc, intermediate_clip)) print("running: Blender.app --background %s --python-use-system-env --python %s --use-extension 0 --threads 0 --render-output %s --render-anim" %
(work_source, work_doc, intermediate_clip))
run(r'/Applications/Blender.app/Contents/MacOS/Blender --background {source} --python-use-system-env --python {jobpath} --use-extension 0 --threads 0 --render-output {locationpath} --render-anim', run(r'/Applications/Blender.app/Contents/MacOS/Blender --background {source} --python-use-system-env --python {jobpath} --use-extension 0 --threads 0 --render-output {locationpath} --render-anim',
source=work_source, source=work_source,
jobpath=work_doc, jobpath=work_doc,
@ -236,14 +237,16 @@ def enqueue_job(event):
if platform.system() == 'Windows': if platform.system() == 'Windows':
if args.debug: if args.debug:
print("running: blender.exe --background %s --python-use-system-env --python %s --use-extension 0 --threads 0 --render-output %s --render-anim" % (work_source, work_doc, intermediate_clip)) print("running: blender.exe --background %s --python-use-system-env --python %s --use-extension 0 --threads 0 --render-output %s --render-anim" %
(work_source, work_doc, intermediate_clip))
run(r'C:/Program\ Files/Blender\ Foundation/Blender\ 2.92/blender.exe --background {source} --python-use-system-env --python {jobpath} --use-extension 0 --threads 0 --render-output {locationpath} --render-anim', run(r'C:/Program\ Files/Blender\ Foundation/Blender\ 2.92/blender.exe --background {source} --python-use-system-env --python {jobpath} --use-extension 0 --threads 0 --render-output {locationpath} --render-anim',
source=work_source, source=work_source,
jobpath=work_doc, jobpath=work_doc,
locationpath=intermediate_clip) locationpath=intermediate_clip)
if platform.system() == 'Linux': if platform.system() == 'Linux':
if args.debug: if args.debug:
print("running: blender --background %s --python-use-system-env --python %s --use-extension 0 --threads 0 --render-output %s --render-anim" % (work_source, work_doc, intermediate_clip)) print("running: blender --background %s --python-use-system-env --python %s --use-extension 0 --threads 0 --render-output %s --render-anim" %
(work_source, work_doc, intermediate_clip))
run(r'blender --background {source} --python-use-system-env --python {jobpath} --use-extension 0 --threads 0 --render-output {locationpath} --render-anim', run(r'blender --background {source} --python-use-system-env --python {jobpath} --use-extension 0 --threads 0 --render-output {locationpath} --render-anim',
source=work_source, source=work_source,
jobpath=work_doc, jobpath=work_doc,
@ -261,7 +264,7 @@ def finalize_job(job_id, event):
if args.alpha: if args.alpha:
ffprobe = run_output('ffprobe -i {input} -show_streams -select_streams a -loglevel error', ffprobe = run_output('ffprobe -i {input} -show_streams -select_streams a -loglevel error',
input=intermediate_clip) input=intermediate_clip)
if ffprobe: if ffprobe:
run('ffmpeg -threads 0 -y -hide_banner -loglevel error -i {input} -c:v qtrle -movflags faststart -aspect 16:9 -c:a mp2 -b:a 384k -shortest -f mov {output}', run('ffmpeg -threads 0 -y -hide_banner -loglevel error -i {input} -c:v qtrle -movflags faststart -aspect 16:9 -c:a mp2 -b:a 384k -shortest -f mov {output}',
input=intermediate_clip, input=intermediate_clip,
@ -272,7 +275,7 @@ def finalize_job(job_id, event):
output=final_clip) output=final_clip)
else: else:
ffprobe = run_output('ffprobe -i {input} -show_streams -select_streams a -loglevel error', ffprobe = run_output('ffprobe -i {input} -show_streams -select_streams a -loglevel error',
input=intermediate_clip) input=intermediate_clip)
if ffprobe: if ffprobe:
event_print(event, "finalize with audio from source file") event_print(event, "finalize with audio from source file")
run('ffmpeg -threads 0 -y -hide_banner -loglevel error -i {input} -c:v mpeg2video -q:v 2 -aspect 16:9 -c:a mp2 -b:a 384k -shortest -f mpegts {output}', run('ffmpeg -threads 0 -y -hide_banner -loglevel error -i {input} -c:v mpeg2video -q:v 2 -aspect 16:9 -c:a mp2 -b:a 384k -shortest -f mpegts {output}',

View file

@ -52,20 +52,21 @@ parser.add_argument('--force', action="store_true", default=False, help='''
args = parser.parse_args() args = parser.parse_args()
if (args.skip is None): if (args.skip is None):
args.skip = [] args.skip = []
def headline(str): def headline(str):
print("##################################################") print("##################################################")
print(str) print(str)
print("##################################################") print("##################################################")
print() print()
def error(str): def error(str):
headline(str) headline(str)
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)
cparser = ConfigParser() cparser = ConfigParser()
cparser.read(os.path.join(os.path.dirname(args.project), 'config.ini')) cparser.read(os.path.join(os.path.dirname(args.project), 'config.ini'))
@ -145,6 +146,7 @@ if args.debug:
else: else:
events = list(schedulelib.events(schedule)) events = list(schedulelib.events(schedule))
def describe_event(event): def describe_event(event):
return "#{}: {}".format(event['id'], event['title']) return "#{}: {}".format(event['id'], event['title'])
@ -231,58 +233,62 @@ def enqueue_job(event):
outfile = os.path.join(os.path.dirname(args.project), event_id + '.ts') outfile = os.path.join(os.path.dirname(args.project), event_id + '.ts')
videofilter = "drawtext=fontfile={fontfile}:fontsize={fontsize}:fontcolor={fontcolor}:x={x}:y={y}:text='{text}':".format( videofilter = "drawtext=fontfile={fontfile}:fontsize={fontsize}:fontcolor={fontcolor}:x={x}:y={y}:text='{text}':".format(
fontfile = font_t, fontfile=font_t,
fontsize = title_fontsize, fontsize=title_fontsize,
fontcolor = title_fontcolor, fontcolor=title_fontcolor,
x = title_x, x=title_x,
y = title_y, y=title_y,
text = t) text=t)
videofilter += "alpha='if(lt(t,{fade_in_start_time}),0,if(lt(t,{fade_in_end_time}),(t-{fade_in_start_time})/{fade_duration},if(lt(t,{fade_out_start_time}),1,if(lt(t,{fade_out_end_time}),({fade_duration}-(t-{fade_out_start_time}))/{fade_duration},0))))',".format( videofilter += "alpha='if(lt(t,{fade_in_start_time}),0,if(lt(t,{fade_in_end_time}),(t-{fade_in_start_time})/{fade_duration},if(lt(t,{fade_out_start_time}),1,if(lt(t,{fade_out_end_time}),({fade_duration}-(t-{fade_out_start_time}))/{fade_duration},0))))',".format(
fade_in_start_time = title_in, fade_in_start_time=title_in,
fade_in_end_time = title_in + fade_duration, fade_in_end_time=title_in + fade_duration,
fade_out_start_time = title_in + fade_duration + title_duration, fade_out_start_time=title_in + fade_duration + title_duration,
fade_out_end_time = title_in + fade_duration + title_duration + fade_duration, fade_out_end_time=title_in + fade_duration + title_duration + fade_duration,
fade_duration = fade_duration fade_duration=fade_duration
) )
videofilter += "drawtext=fontfile={fontfile}:fontsize={fontsize}:fontcolor={fontcolor}:x={x}:y={y}:text='{text}':".format( videofilter += "drawtext=fontfile={fontfile}:fontsize={fontsize}:fontcolor={fontcolor}:x={x}:y={y}:text='{text}':".format(
fontfile = font_s, fontfile=font_s,
fontsize = speaker_fontsize, fontsize=speaker_fontsize,
fontcolor = speaker_fontcolor, fontcolor=speaker_fontcolor,
x = speaker_x, x=speaker_x,
y = speaker_y, y=speaker_y,
text = s) text=s)
videofilter += "alpha='if(lt(t,{fade_in_start_time}),0,if(lt(t,{fade_in_end_time}),(t-{fade_in_start_time})/{fade_duration},if(lt(t,{fade_out_start_time}),1,if(lt(t,{fade_out_end_time}),({fade_duration}-(t-{fade_out_start_time}))/{fade_duration},0))))',".format( videofilter += "alpha='if(lt(t,{fade_in_start_time}),0,if(lt(t,{fade_in_end_time}),(t-{fade_in_start_time})/{fade_duration},if(lt(t,{fade_out_start_time}),1,if(lt(t,{fade_out_end_time}),({fade_duration}-(t-{fade_out_start_time}))/{fade_duration},0))))',".format(
fade_in_start_time = speaker_in, fade_in_start_time=speaker_in,
fade_in_end_time = speaker_in + fade_duration, fade_in_end_time=speaker_in + fade_duration,
fade_out_start_time = speaker_in + fade_duration + speaker_duration, fade_out_start_time=speaker_in + fade_duration + speaker_duration,
fade_out_end_time = speaker_in + fade_duration + speaker_duration + fade_duration, fade_out_end_time=speaker_in + fade_duration + speaker_duration + fade_duration,
fade_duration = fade_duration fade_duration=fade_duration
) )
videofilter += "drawtext=fontfile={fontfile}:fontsize={fontsize}:fontcolor={fontcolor}:x={x}:y={y}:text={text}:".format( videofilter += "drawtext=fontfile={fontfile}:fontsize={fontsize}:fontcolor={fontcolor}:x={x}:y={y}:text={text}:".format(
fontfile = font_tt, fontfile=font_tt,
fontsize = text_fontsize, fontsize=text_fontsize,
fontcolor = text_fontcolor, fontcolor=text_fontcolor,
x = text_x, x=text_x,
y = text_y, y=text_y,
text = text_text) text=text_text)
videofilter += "alpha='if(lt(t,{fade_in_start_time}),0,if(lt(t,{fade_in_end_time}),(t-{fade_in_start_time})/{fade_duration},if(lt(t,{fade_out_start_time}),1,if(lt(t,{fade_out_end_time}),({fade_duration}-(t-{fade_out_start_time}))/{fade_duration},0))))'".format( videofilter += "alpha='if(lt(t,{fade_in_start_time}),0,if(lt(t,{fade_in_end_time}),(t-{fade_in_start_time})/{fade_duration},if(lt(t,{fade_out_start_time}),1,if(lt(t,{fade_out_end_time}),({fade_duration}-(t-{fade_out_start_time}))/{fade_duration},0))))'".format(
fade_in_start_time = text_in, fade_in_start_time=text_in,
fade_in_end_time = text_in + fade_duration, fade_in_end_time=text_in + fade_duration,
fade_out_start_time = text_in + fade_duration + text_duration, fade_out_start_time=text_in + fade_duration + text_duration,
fade_out_end_time = text_in + fade_duration + text_duration + fade_duration, fade_out_end_time=text_in + fade_duration + text_duration + fade_duration,
fade_duration = fade_duration fade_duration=fade_duration
) )
if fileformat == '.mov': if fileformat == '.mov':
if alpha == 'true': if alpha == 'true':
if prores == 'true': if prores == 'true':
cmd = 'ffmpeg -y -i "{0}" -vf "{1}" -vcodec prores_ks -pix_fmt yuva444p10le -profile:v 4444 -shortest -movflags faststart -f mov "{2}"'.format(infile, videofilter, outfile) cmd = 'ffmpeg -y -i "{0}" -vf "{1}" -vcodec prores_ks -pix_fmt yuva444p10le -profile:v 4444 -shortest -movflags faststart -f mov "{2}"'.format(
infile, videofilter, outfile)
else: else:
cmd = 'ffmpeg -y -i "{0}" -vf "{1}" -shortest -c:v qtrle -movflags faststart -f mov "{2}"'.format(infile, videofilter, outfile) cmd = 'ffmpeg -y -i "{0}" -vf "{1}" -shortest -c:v qtrle -movflags faststart -f mov "{2}"'.format(
infile, videofilter, outfile)
else: else:
cmd = 'ffmpeg -y -i "{0}" -vf "{1}" -map 0:0 -c:v mpeg2video -q:v 2 -aspect 16:9 -map 0:1 -c:a mp2 -b:a 384k -shortest -f mpegts "{2}"'.format(infile, videofilter, outfile) cmd = 'ffmpeg -y -i "{0}" -vf "{1}" -map 0:0 -c:v mpeg2video -q:v 2 -aspect 16:9 -map 0:1 -c:a mp2 -b:a 384k -shortest -f mpegts "{2}"'.format(
infile, videofilter, outfile)
else: else:
cmd = 'ffmpeg -y -i "{0}" -vf "{1}" -map 0:0 -c:v mpeg2video -pix_fmt:v yuv420p -qscale:v 2 -qmin:v 2 -qmax:v 7 -keyint_min 0 -bf 0 -g 0 -maxrate:0 90M -aspect 16:9 -map 0:1 -c:a mp2 -b:a 384k -shortest -f mpegts "{2}"'.format(infile, videofilter, outfile) cmd = 'ffmpeg -y -i "{0}" -vf "{1}" -map 0:0 -c:v mpeg2video -pix_fmt:v yuv420p -qscale:v 2 -qmin:v 2 -qmax:v 7 -keyint_min 0 -bf 0 -g 0 -maxrate:0 90M -aspect 16:9 -map 0:1 -c:a mp2 -b:a 384k -shortest -f mpegts "{2}"'.format(
infile, videofilter, outfile)
if args.debug: if args.debug:
print(cmd) print(cmd)
@ -321,5 +327,3 @@ for event in events:
print('all done') print('all done')

View file

@ -55,28 +55,29 @@ parser.add_argument('--force', action="store_true", default=False, help='''
args = parser.parse_args() args = parser.parse_args()
if (args.skip is None): if (args.skip is None):
args.skip = [] args.skip = []
def headline(str): def headline(str):
print("##################################################") print("##################################################")
print(str) print(str)
print("##################################################") print("##################################################")
print() print()
def error(str): def error(str):
headline(str) headline(str)
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)
cparser = ConfigParser() cparser = ConfigParser()
cparser.read(os.path.join(os.path.dirname(args.project), 'config.ini')) cparser.read(os.path.join(os.path.dirname(args.project), 'config.ini'))
template = cparser['default']['template'] template = cparser['default']['template']
alpha = cparser['default']['alpha'] alpha = cparser['default']['alpha']
prores = cparser['default']['prores'] prores = cparser['default']['prores']
fontfile = cparser['default']['fontfile'] # use a font file instead of a font family fontfile = cparser['default']['fontfile'] # use a font file instead of a font family
inout = cparser['default']['inout'] # in and out time format: t for seconds, n for frame number inout = cparser['default']['inout'] # in and out time format: t for seconds, n for frame number
title_in = cparser['title']['in'] title_in = cparser['title']['in']
title_out = cparser['title']['out'] title_out = cparser['title']['out']
@ -148,6 +149,7 @@ if args.debug:
else: else:
events = list(schedulelib.events(schedule)) events = list(schedulelib.events(schedule))
def describe_event(event): def describe_event(event):
return "#{}: {}".format(event['id'], event['title']) return "#{}: {}".format(event['id'], event['title'])
@ -194,7 +196,7 @@ def fit_text(string: str, frame_width):
def fit_title(string: str): def fit_title(string: str):
global translation_font global translation_font
translation_font = ImageFont.truetype( translation_font = ImageFont.truetype(
font_t, size=80, encoding="unic") font_t, size=80, encoding="unic")
title = fit_text(string, 1080) title = fit_text(string, 1080)
return title return title
@ -203,7 +205,7 @@ def fit_title(string: str):
def fit_speaker(string: str): def fit_speaker(string: str):
global translation_font global translation_font
translation_font = ImageFont.truetype( translation_font = ImageFont.truetype(
font_s, size=50, encoding="unic") font_s, size=50, encoding="unic")
speaker = fit_text(string, 1080) speaker = fit_text(string, 1080)
return speaker return speaker
@ -225,7 +227,7 @@ def enqueue_job(event):
event_personnames = event_personnames.replace('"', '\\"') event_personnames = event_personnames.replace('"', '\\"')
t = fit_title(event_title) t = fit_title(event_title)
t = t.replace(':', "\:") # the ffmpeg command needs colons to be escaped t = t.replace(':', "\:") # the ffmpeg command needs colons to be escaped
s = fit_speaker(event_personnames) s = fit_speaker(event_personnames)
if args.debug: if args.debug:
@ -240,33 +242,45 @@ def enqueue_job(event):
font_s_win = "/".join(font_s.split("\\")) font_s_win = "/".join(font_s.split("\\"))
font_tt_win = "/".join(font_tt.split("\\")) font_tt_win = "/".join(font_tt.split("\\"))
else: else:
ffmpeg_path = 'ffmpeg' ffmpeg_path = 'ffmpeg'
if fontfile == 'true': if fontfile == 'true':
if platform.system() == 'Windows': if platform.system() == 'Windows':
videofilter = "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}',".format(title_in, title_out, font_t_win, title_fontsize, title_fontcolor, title_x, title_y, t, inout) videofilter = "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}',".format(
videofilter += "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}':box=1,".format(speaker_in, speaker_out, font_s_win, speaker_fontsize, speaker_fontcolor, speaker_x, speaker_y, s, inout) title_in, title_out, font_t_win, title_fontsize, title_fontcolor, title_x, title_y, t, inout)
videofilter += "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}'".format(text_in, text_out, font_tt_win, text_fontsize, text_fontcolor, text_x, text_y, text_text, inout) videofilter += "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}':box=1,".format(
speaker_in, speaker_out, font_s_win, speaker_fontsize, speaker_fontcolor, speaker_x, speaker_y, s, inout)
videofilter += "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}'".format(
text_in, text_out, font_tt_win, text_fontsize, text_fontcolor, text_x, text_y, text_text, inout)
else: else:
videofilter = "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}',".format(title_in, title_out, font_t, title_fontsize, title_fontcolor, title_x, title_y, t, inout) videofilter = "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}',".format(
videofilter += "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}':box=1,".format(speaker_in, speaker_out, font_s, speaker_fontsize, speaker_fontcolor, speaker_x, speaker_y, s, inout) title_in, title_out, font_t, title_fontsize, title_fontcolor, title_x, title_y, t, inout)
videofilter += "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}'".format(text_in, text_out, font_tt, text_fontsize, text_fontcolor, text_x, text_y, text_text, inout) videofilter += "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}':box=1,".format(
speaker_in, speaker_out, font_s, speaker_fontsize, speaker_fontcolor, speaker_x, speaker_y, s, inout)
videofilter += "drawtext=enable='between({8},{0},{1})':fontfile='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}'".format(
text_in, text_out, font_tt, text_fontsize, text_fontcolor, text_x, text_y, text_text, inout)
else: else:
videofilter = "drawtext=enable='between({8},{0},{1})':font='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}',".format(title_in, title_out, title_fontfamily, title_fontsize, title_fontcolor, title_x, title_y, t, inout) videofilter = "drawtext=enable='between({8},{0},{1})':font='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}',".format(
videofilter += "drawtext=enable='between({8},{0},{1})':font='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}':box=1,".format(speaker_in, speaker_out, speaker_fontfamily, speaker_fontsize, speaker_fontcolor, speaker_x, speaker_y, s, inout) title_in, title_out, title_fontfamily, title_fontsize, title_fontcolor, title_x, title_y, t, inout)
videofilter += "drawtext=enable='between({8},{0},{1})':font='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}'".format(text_in, text_out, text_fontfamily, text_fontsize, text_fontcolor, text_x, text_y, text_text, inout) videofilter += "drawtext=enable='between({8},{0},{1})':font='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}':box=1,".format(
speaker_in, speaker_out, speaker_fontfamily, speaker_fontsize, speaker_fontcolor, speaker_x, speaker_y, s, inout)
videofilter += "drawtext=enable='between({8},{0},{1})':font='{2}':fontsize={3}:fontcolor={4}:x={5}:y={6}:text='{7}'".format(
text_in, text_out, text_fontfamily, text_fontsize, text_fontcolor, text_x, text_y, text_text, inout)
if fileformat == '.mov': if fileformat == '.mov':
if alpha == 'true': if alpha == 'true':
if prores == 'true': if prores == 'true':
cmd = '{3} -y -i "{0}" -vf "{1}" -vcodec prores_ks -pix_fmt yuva444p10le -profile:v 4444 -shortest -movflags faststart -f mov "{2}"'.format(infile, videofilter, outfile, ffmpeg_path) cmd = '{3} -y -i "{0}" -vf "{1}" -vcodec prores_ks -pix_fmt yuva444p10le -profile:v 4444 -shortest -movflags faststart -f mov "{2}"'.format(
infile, videofilter, outfile, ffmpeg_path)
else: else:
cmd = '{3} -y -i "{0}" -vf "{1}" -shortest -c:v qtrle -movflags faststart -f mov "{2}"'.format(infile, videofilter, outfile, ffmpeg_path) cmd = '{3} -y -i "{0}" -vf "{1}" -shortest -c:v qtrle -movflags faststart -f mov "{2}"'.format(
infile, videofilter, outfile, ffmpeg_path)
else: else:
cmd = '{3} -y -i "{0}" -vf "{1}" -map 0:0 -c:v mpeg2video -q:v 2 -aspect 16:9 -map 0:1 -c:a mp2 -b:a 384k -shortest -f mpegts "{2}"'.format(infile, videofilter, outfile, ffmpeg_path) cmd = '{3} -y -i "{0}" -vf "{1}" -map 0:0 -c:v mpeg2video -q:v 2 -aspect 16:9 -map 0:1 -c:a mp2 -b:a 384k -shortest -f mpegts "{2}"'.format(
infile, videofilter, outfile, ffmpeg_path)
else: else:
cmd = '{3} -y -i "{0}" -vf "{1}" -map 0:0 -c:v mpeg2video -q:v 2 -aspect 16:9 -map 0:1 -c:a mp2 -b:a 384k -shortest -f mpegts "{2}"'.format(infile, videofilter, outfile, ffmpeg_path) cmd = '{3} -y -i "{0}" -vf "{1}" -map 0:0 -c:v mpeg2video -q:v 2 -aspect 16:9 -map 0:1 -c:a mp2 -b:a 384k -shortest -f mpegts "{2}"'.format(
infile, videofilter, outfile, ffmpeg_path)
if args.debug: if args.debug:
print(cmd) print(cmd)
@ -305,5 +319,3 @@ for event in events:
print('all done') print('all done')

12
make.py
View file

@ -14,7 +14,8 @@ import renderlib
import argparse import argparse
# Parse arguments # Parse arguments
parser = argparse.ArgumentParser(description='C3VOC Intro-Outro-Generator', usage="see help with option -h", formatter_class=argparse.RawTextHelpFormatter) parser = argparse.ArgumentParser(description='C3VOC Intro-Outro-Generator',
usage="see help with option -h", formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('projectpath', action="store", metavar='yourproject/', type=str, help=''' parser.add_argument('projectpath', action="store", metavar='yourproject/', type=str, help='''
Path to your project is a required argument. Path to your project is a required argument.
Usage: ./make.py yourproject/ Usage: ./make.py yourproject/
@ -87,7 +88,8 @@ projectpath = args.projectpath
try: try:
project = renderlib.loadProject(projectname) project = renderlib.loadProject(projectname)
except ImportError: except ImportError:
print("you must specify a project-name as first argument, eg. './make.py sotmeu14'. The supplied value '{0}' seems not to be a valid project (there is no '{0}/__init__.py').\n".format(projectname)) print(
"you must specify a project-name as first argument, eg. './make.py sotmeu14'. The supplied value '{0}' seems not to be a valid project (there is no '{0}/__init__.py').\n".format(projectname))
raise raise
# using --debug skips the threading, the network fetching of the schedule and # using --debug skips the threading, the network fetching of the schedule and
@ -98,7 +100,8 @@ renderlib.args = args
def render(infile, outfile, sequence, parameters={}, workdir=os.path.join(projectname, 'artwork')): def render(infile, outfile, sequence, parameters={}, workdir=os.path.join(projectname, 'artwork')):
task = renderlib.Rendertask(infile=infile, outfile=outfile, sequence=sequence, parameters=parameters, workdir=workdir) task = renderlib.Rendertask(infile=infile, outfile=outfile,
sequence=sequence, parameters=parameters, workdir=workdir)
return renderlib.rendertask(task) return renderlib.rendertask(task)
@ -188,7 +191,8 @@ def worker():
renderlib.rendertask(task) renderlib.rendertask(task)
# print that we're finished # print that we're finished
tprint('finished {0}, {1} tasks left'.format(task.outfile, max(0, tasks.qsize() - num_worker_threads))) tprint('finished {0}, {1} tasks left'.format(
task.outfile, max(0, tasks.qsize() - num_worker_threads)))
# mark the task as finished # mark the task as finished
tasks.task_done() tasks.task_done()

View file

@ -17,7 +17,8 @@ fps = 25
debug = True debug = True
args = None args = None
scheduleTree=None scheduleTree = None
def loadProject(projectname): def loadProject(projectname):
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), projectname)) sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), projectname))
@ -45,7 +46,7 @@ class Rendertask:
self.parameters = parameters self.parameters = parameters
self.outfile = outfile self.outfile = outfile
self.workdir = workdir self.workdir = workdir
self.sequence = sequence # deprecated, use animated() self.sequence = sequence # deprecated, use animated()
def animated(self, sequence): def animated(self, sequence):
atask = self atask = self
@ -70,6 +71,8 @@ class Rendertask:
return None return None
# try to create all folders needed and skip, they already exist # try to create all folders needed and skip, they already exist
def ensurePathExists(path): def ensurePathExists(path):
try: try:
os.makedirs(path) os.makedirs(path)
@ -83,6 +86,7 @@ def ensureFilesRemoved(pattern):
for f in glob.glob(pattern): for f in glob.glob(pattern):
os.unlink(f) os.unlink(f)
def renderFrame(infile, task, outfile): def renderFrame(infile, task, outfile):
width = 1920 width = 1920
height = 1080 height = 1080
@ -93,61 +97,67 @@ def renderFrame(infile, task, outfile):
converted.save(filename=outfile) converted.save(filename=outfile)
elif args.resvg: elif args.resvg:
# invoke inkscape to convert the generated svg-file into a png inside the .frames-directory # invoke inkscape to convert the generated svg-file into a png inside the .frames-directory
cmd = 'resvg --background white --width={1} --height={2} "{4}" "{3}" 2>&1 >/dev/null'.format(task.workdir, width, height, outfile, infile) cmd = 'resvg --background white --width={1} --height={2} "{4}" "{3}" 2>&1 >/dev/null'.format(
errorReturn = subprocess.check_output(cmd, shell=True, universal_newlines=True, stderr=subprocess.STDOUT, cwd=task.workdir) task.workdir, width, height, outfile, infile)
errorReturn = subprocess.check_output(
cmd, shell=True, universal_newlines=True, stderr=subprocess.STDOUT, cwd=task.workdir)
if errorReturn != '': if errorReturn != '':
print("resvg exited with error\n" + errorReturn) print("resvg exited with error\n" + errorReturn)
# sys.exit(42) # sys.exit(42)
else: else:
# invoke inkscape to convert the generated svg-file into a png inside the .frames-directory # invoke inkscape to convert the generated svg-file into a png inside the .frames-directory
cmd = 'inkscape --export-background=white --export-background-opacity=0 --export-width={1} --export-height={2} --export-filename="{3}" "{4}" --pipe 2>&1 >/dev/null'.format(task.workdir, width, height, os.path.abspath(outfile), os.path.abspath(infile)) cmd = 'inkscape --export-background=white --export-background-opacity=0 --export-width={1} --export-height={2} --export-filename="{3}" "{4}" --pipe 2>&1 >/dev/null'.format(
errorReturn = subprocess.check_output(cmd, shell=True, universal_newlines=True, stderr=subprocess.STDOUT, cwd=task.workdir) task.workdir, width, height, os.path.abspath(outfile), os.path.abspath(infile))
errorReturn = subprocess.check_output(
cmd, shell=True, universal_newlines=True, stderr=subprocess.STDOUT, cwd=task.workdir)
if errorReturn != '': if errorReturn != '':
print("inkscape exited with error\n" + errorReturn) print("inkscape exited with error\n" + errorReturn)
# sys.exit(42) # sys.exit(42)
def cachedRenderFrame(frame, frameNr, task, cache): def cachedRenderFrame(frame, frameNr, task, cache):
skip_rendering = False skip_rendering = False
# skip first n frames, to speed up rerendering during debugging # skip first n frames, to speed up rerendering during debugging
if 'only_rerender_frames_after' in task.parameters: if 'only_rerender_frames_after' in task.parameters:
skip_rendering = (frameNr <= task.parameters['only_rerender_frames_after']) skip_rendering = (frameNr <= task.parameters['only_rerender_frames_after'])
if args.skip_frames: if args.skip_frames:
skip_rendering = (frameNr <= args.skip_frames) skip_rendering = (frameNr <= args.skip_frames)
if args.only_frame: if args.only_frame:
skip_rendering = (frameNr != args.only_frame) skip_rendering = (frameNr != args.only_frame)
# print a line for each and every frame generated # print a line for each and every frame generated
if debug and not skip_rendering: if debug and not skip_rendering:
print("frameNr {0:3d} => {1}".format(frameNr, frame)) print("frameNr {0:3d} => {1}".format(frameNr, frame))
frame = tuple(frame) frame = tuple(frame)
if frame in cache: if frame in cache:
if debug: if debug:
print("cache hit, reusing frame {0}".format(cache[frame])) print("cache hit, reusing frame {0}".format(cache[frame]))
framedir = task.workdir + "/.frames/" framedir = task.workdir + "/.frames/"
shutil.copyfile("{0}/{1:04d}.png".format(framedir, cache[frame]), "{0}/{1:04d}.png".format(framedir, frameNr)) shutil.copyfile("{0}/{1:04d}.png".format(framedir,
cache[frame]), "{0}/{1:04d}.png".format(framedir, frameNr))
return return
elif not skip_rendering: elif not skip_rendering:
cache[frame] = frameNr cache[frame] = frameNr
svgfile = '{0}/.frames/{1:04d}.svg'.format(task.workdir, frameNr) svgfile = '{0}/.frames/{1:04d}.svg'.format(task.workdir, frameNr)
if not skip_rendering: if not skip_rendering:
with SVGTemplate(task, svgfile) as svg: with SVGTemplate(task, svgfile) as svg:
svg.replacetext() svg.replacetext()
svg.transform(frame) svg.transform(frame)
svg.write() svg.write()
outfile = '{0}/.frames/{1:04d}.png'.format(task.workdir, frameNr) outfile = '{0}/.frames/{1:04d}.png'.format(task.workdir, frameNr)
renderFrame(svgfile, task, outfile) renderFrame(svgfile, task, outfile)
# increment frame-number # increment frame-number
frameNr += 1 frameNr += 1
def rendertask_image(task): def rendertask_image(task):
@ -157,6 +167,7 @@ def rendertask_image(task):
svg.write() svg.write()
renderFrame(svgfile, task, task.outfile) renderFrame(svgfile, task, task.outfile)
def rendertask_video(task): def rendertask_video(task):
# iterate through the animation sequence frame by frame # iterate through the animation sequence frame by frame
# frame is a ... tbd # frame is a ... tbd
@ -171,7 +182,8 @@ def rendertask_video(task):
ensureFilesRemoved(os.path.join(task.workdir, task.outfile)) ensureFilesRemoved(os.path.join(task.workdir, task.outfile))
if task.outfile.endswith('.png'): if task.outfile.endswith('.png'):
cmd = 'cd {0} && cp ".frames/{1:04d}.png" "{2}"'.format(task.workdir, args.only_frame, task.outfile) cmd = 'cd {0} && cp ".frames/{1:04d}.png" "{2}"'.format(
task.workdir, args.only_frame, task.outfile)
# invoke avconv aka ffmpeg and renerate a lossles-dv from the frames # invoke avconv aka ffmpeg and renerate a lossles-dv from the frames
# if we're not in debug-mode, suppress all output # if we're not in debug-mode, suppress all output
@ -192,11 +204,14 @@ def rendertask_video(task):
cmd += '-shortest -f mpegts "{0}"'.format(task.outfile) cmd += '-shortest -f mpegts "{0}"'.format(task.outfile)
elif task.outfile.endswith('.mov'): elif task.outfile.endswith('.mov'):
cmd = 'cd {0} && '.format(task.workdir) cmd = 'cd {0} && '.format(task.workdir)
cmd += 'ffmpeg -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -f image2 -i .frames/%04d.png -r 25 -shortest -c:v qtrle -f mov "{0}"'.format(task.outfile) cmd += 'ffmpeg -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -f image2 -i .frames/%04d.png -r 25 -shortest -c:v qtrle -f mov "{0}"'.format(
task.outfile)
elif task.outfile.endswith('.mkv'): elif task.outfile.endswith('.mkv'):
cmd = 'cd {0} && ffmpeg -ar 48000 -ac 2 -f s16le -i /dev/zero -f image2 -i .frames/%04d.png -aspect 16:9 -c copy -shortest "{1}"'.format(task.workdir, task.outfile) cmd = 'cd {0} && ffmpeg -ar 48000 -ac 2 -f s16le -i /dev/zero -f image2 -i .frames/%04d.png -aspect 16:9 -c copy -shortest "{1}"'.format(
task.workdir, task.outfile)
else: else:
cmd = 'cd {0} && ffmpeg -ar 48000 -ac 2 -f s16le -i /dev/zero -f image2 -i .frames/%04d.png -target pal-dv -aspect 16:9 -shortest "{1}"'.format(task.workdir, task.outfile) cmd = 'cd {0} && ffmpeg -ar 48000 -ac 2 -f s16le -i /dev/zero -f image2 -i .frames/%04d.png -target pal-dv -aspect 16:9 -shortest "{1}"'.format(
task.workdir, task.outfile)
if debug: if debug:
print(cmd) print(cmd)
@ -208,15 +223,16 @@ def rendertask_video(task):
if r != 0: if r != 0:
sys.exit() sys.exit()
def rendertask(task): def rendertask(task):
global args global args
# in debug mode we have no thread-worker which prints its progress # in debug mode we have no thread-worker which prints its progress
if debug: if debug:
print("generating {0} from {1}".format(task.outfile, task.infile)) print("generating {0} from {1}".format(task.outfile, task.infile))
## Hacky workaround: Fix this properly without breaking the # Hacky workaround: Fix this properly without breaking the
## support for partially rendered intros # support for partially rendered intros
if True: #args.skip_frames and 'only_rerender_frames_after' not in task.parameters: if True: # args.skip_frames and 'only_rerender_frames_after' not in task.parameters:
if os.path.isdir(os.path.join(task.workdir, '.frames')): if os.path.isdir(os.path.join(task.workdir, '.frames')):
print("Removing", os.path.join(task.workdir, '.frames')) print("Removing", os.path.join(task.workdir, '.frames'))
shutil.rmtree(os.path.join(task.workdir, '.frames')) shutil.rmtree(os.path.join(task.workdir, '.frames'))
@ -241,4 +257,3 @@ try:
except ImportError: except ImportError:
def colored(str, col): def colored(str, col):
return str return str

View file

@ -4,7 +4,7 @@ import re
from lxml import etree from lxml import etree
from urllib.request import urlopen from urllib.request import urlopen
scheduleTree=None scheduleTree = None
# Download the Events-Schedule and parse all Events out of it. Yield a tupel for each Event # Download the Events-Schedule and parse all Events out of it. Yield a tupel for each Event
@ -21,10 +21,11 @@ def downloadSchedule(scheduleUrl):
parser = etree.XMLParser(huge_tree=True) parser = etree.XMLParser(huge_tree=True)
return etree.fromstring(xml, parser) return etree.fromstring(xml, parser)
def getSchedule(scheduleUrl): def getSchedule(scheduleUrl):
global scheduleTree global scheduleTree
if not scheduleTree: if not scheduleTree:
scheduleTree=downloadSchedule(scheduleUrl) scheduleTree = downloadSchedule(scheduleUrl)
return scheduleTree return scheduleTree
@ -62,6 +63,7 @@ def persons(scheduleUrl, personmap={}, taglinemap={}, forEventId=None):
'tagline': tagline 'tagline': tagline
} }
def events(scheduleUrl, titlemap={}): def events(scheduleUrl, titlemap={}):
schedule = getSchedule(scheduleUrl) schedule = getSchedule(scheduleUrl)
# iterate all days # iterate all days
@ -108,7 +110,7 @@ def events(scheduleUrl, titlemap={}):
'personnames': ', '.join(personnames), 'personnames': ', '.join(personnames),
'room': room.attrib['name'], 'room': room.attrib['name'],
'track': event.find('track').text, 'track': event.find('track').text,
'url': url 'url': url
} }
@ -117,4 +119,3 @@ try:
except ImportError: except ImportError:
def colored(str, col): def colored(str, col):
return str return str

View file

@ -10,17 +10,17 @@ import renderlib
import c3t_rpc_client as rpc import c3t_rpc_client as rpc
try: try:
from termcolor import colored from termcolor import colored
except ImportError: except ImportError:
def colored(str, col): def colored(str, col):
return str return str
print("C3TT preroll generator") print("C3TT preroll generator")
renderlib.debug = True renderlib.debug = True
if os.environ.get('CRS_TOKEN') is None or os.environ.get('CRS_SECRET') is None: if os.environ.get('CRS_TOKEN') is None or os.environ.get('CRS_SECRET') is None:
print('CRS_TOKEN or CRS_SECRET is empty. did you source the tracker-scripts-profile?') print('CRS_TOKEN or CRS_SECRET is empty. did you source the tracker-scripts-profile?')
sys.exit(1) sys.exit(1)
ticket_type = 'recording' ticket_type = 'recording'
ticket_state = 'generating' ticket_state = 'generating'
@ -32,45 +32,48 @@ secret = os.environ['CRS_SECRET']
filter = {} filter = {}
if not os.environ.get('CRS_ROOM') is None: if not os.environ.get('CRS_ROOM') is None:
filter['Fahrplan.Room'] = os.environ['CRS_ROOM'] filter['Fahrplan.Room'] = os.environ['CRS_ROOM']
projects = {} projects = {}
def generatePreroll(ticket): def generatePreroll(ticket):
print(ticket) print(ticket)
projectname = ticket.get('Processing.Prerolls.Slug', ticket['Meta.Acronym']) projectname = ticket.get('Processing.Prerolls.Slug', ticket['Meta.Acronym'])
if not projectname in projects: if not projectname in projects:
projects[projectname] = renderlib.loadProject(projectname) projects[projectname] = renderlib.loadProject(projectname)
project = projects[projectname] project = projects[projectname]
task = project.ticket(ticket) task = project.ticket(ticket)
task.outfile = os.path.join(ticket['Processing.Path.Intros'], ticket['Fahrplan.ID'] + '.dv') task.outfile = os.path.join(ticket['Processing.Path.Intros'], ticket['Fahrplan.ID'] + '.dv')
task.workdir = os.path.join(os.getcwd(), projectname, 'artwork') task.workdir = os.path.join(os.getcwd(), projectname, 'artwork')
print(colored("rendering", 'green')) print(colored("rendering", 'green'))
renderlib.rendertask(task) renderlib.rendertask(task)
if hasattr(project, 'deploy'): if hasattr(project, 'deploy'):
print(colored("deploying", 'green')) print(colored("deploying", 'green'))
project.deploy(ticket, task) project.deploy(ticket, task)
while True: while True:
print(colored('Asking RPC for {0}-tickets which are ready for state {1}'.format(ticket_type, ticket_state), 'yellow')) print(colored(
'Asking RPC for {0}-tickets which are ready for state {1}'.format(ticket_type, ticket_state), 'yellow'))
ticket_id = rpc.assignNextUnassignedForState(ticket_type, ticket_state, url, token, host, secret, filter) ticket_id = rpc.assignNextUnassignedForState(
if ticket_id != False: ticket_type, ticket_state, url, token, host, secret, filter)
ticket = rpc.getTicketProperties(str(ticket_id), url, token, host, secret) if ticket_id != False:
try: ticket = rpc.getTicketProperties(str(ticket_id), url, token, host, secret)
generatePreroll(ticket) try:
rpc.setTicketDone(str(ticket_id), url, token, host, secret) generatePreroll(ticket)
except: rpc.setTicketDone(str(ticket_id), url, token, host, secret)
error = str(traceback.format_exc()) except:
print(colored(error, 'red')) error = str(traceback.format_exc())
rpc.setTicketFailed(str(ticket_id), error, url, token, host, secret) print(colored(error, 'red'))
rpc.setTicketFailed(str(ticket_id), error, url, token, host, secret)
else: else:
print('No ticket found') print('No ticket found')
print('Sleeping for 30 seconds')
time.sleep(30);
print('Sleeping for 30 seconds')
time.sleep(30)

View file

@ -11,6 +11,7 @@ from xml.sax.saxutils import escape as xmlescape
cssutils.ser.prefs.lineSeparator = ' ' cssutils.ser.prefs.lineSeparator = ' '
cssutils.log.setLevel(logging.FATAL) cssutils.log.setLevel(logging.FATAL)
class SVGTemplate: class SVGTemplate:
def __init__(self, task, outfile): def __init__(self, task, outfile):
self.task = task self.task = task