Compare commits
	
		
			5 commits
		
	
	
		
			master
			...
			gpn21--sim
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | aa12718952 | ||
|   | 8e13126d91 | ||
|   | 7b8aa9fe6c | ||
|   | f9dfad60ed | ||
|   | 50d35cb03e | 
					 10 changed files with 153 additions and 44 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -12,3 +12,4 @@ schedule.de.xml | ||||||
| snapshot-*.png | snapshot-*.png | ||||||
| env | env | ||||||
| .DS_Store | .DS_Store | ||||||
|  | *.swp | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								glt23/TitilliumWeb-Regular-with-emoji.ttf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								glt23/TitilliumWeb-Regular-with-emoji.ttf
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								glt23/TitilliumWeb-SemiBold-with-emoji.ttf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								glt23/TitilliumWeb-SemiBold-with-emoji.ttf
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										33
									
								
								glt23/config.ini
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								glt23/config.ini
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,33 @@ | ||||||
|  | [default] | ||||||
|  | schedule = https://pretalx.linuxtage.at/glt23/schedule/export/schedule.xml | ||||||
|  | template = glt23_intro_template.ts | ||||||
|  | alpha = false | ||||||
|  | prores = false | ||||||
|  | 
 | ||||||
|  | [title] | ||||||
|  | in = 1 | ||||||
|  | out = 6.5 | ||||||
|  | font = TitilliumWeb-SemiBold-with-emoji.ttf | ||||||
|  | fontsize = 100 | ||||||
|  | fontcolor = #000000 | ||||||
|  | x = 200 | ||||||
|  | y = 200 | ||||||
|  | 
 | ||||||
|  | [speaker] | ||||||
|  | in = 2 | ||||||
|  | out = 6.5 | ||||||
|  | font = TitilliumWeb-Regular-with-emoji.ttf | ||||||
|  | fontsize = 60 | ||||||
|  | fontcolor = #000000 | ||||||
|  | x = 200 | ||||||
|  | y = 800 | ||||||
|  | 
 | ||||||
|  | [text] | ||||||
|  | in = 3 | ||||||
|  | out = 6.5 | ||||||
|  | font = TitilliumWeb-Regular-with-emoji.ttf | ||||||
|  | fontsize = 45 | ||||||
|  | fontcolor = #000000 | ||||||
|  | x = 200 | ||||||
|  | y = 1000 | ||||||
|  | text = '' | ||||||
							
								
								
									
										
											BIN
										
									
								
								gpn21/Roboto-Regular-enriched.ttf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gpn21/Roboto-Regular-enriched.ttf
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										34
									
								
								gpn21/config.toml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								gpn21/config.toml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | ||||||
|  | [default] | ||||||
|  | schedule = "https://cfp.gulas.ch/gpn21/schedule/export/schedule.xml" | ||||||
|  | template = "gpn21_intro_template_audio.mp4" | ||||||
|  | alpha = false | ||||||
|  | prores = false | ||||||
|  | 
 | ||||||
|  | [title] | ||||||
|  | in = 1.5 | ||||||
|  | out = 7 | ||||||
|  | font = "Roboto-Regular-enriched.ttf" | ||||||
|  | fontsize = 100 | ||||||
|  | fontcolor = "#000000" | ||||||
|  | x = 64 | ||||||
|  | y = 200 | ||||||
|  | 
 | ||||||
|  | [speaker] | ||||||
|  | in = 2.5 | ||||||
|  | out = 7 | ||||||
|  | font = "Roboto-Regular-enriched.ttf" | ||||||
|  | fontsize = 60 | ||||||
|  | fontcolor = "#000000" | ||||||
|  | x = 64 | ||||||
|  | y = 900 | ||||||
|  | 
 | ||||||
|  | [text] | ||||||
|  | in = 3 | ||||||
|  | out = 7 | ||||||
|  | font = "Roboto-Regular-enriched.ttf" | ||||||
|  | fontsize = 45 | ||||||
|  | fontcolor = "#000000" | ||||||
|  | x = 64 | ||||||
|  | y = 1000 | ||||||
|  | text = '' | ||||||
|  | 
 | ||||||
							
								
								
									
										
											BIN
										
									
								
								jh23-ffm/Roboto-Regular-enriched.ttf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								jh23-ffm/Roboto-Regular-enriched.ttf
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										34
									
								
								jh23-ffm/config.toml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								jh23-ffm/config.toml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | ||||||
|  | [default] | ||||||
|  | schedule = "https://jh.franzi.business/schedule/jh23ffm.xml" | ||||||
|  | template = "jh23-ffm-template.ts" | ||||||
|  | alpha = false | ||||||
|  | prores = false | ||||||
|  | 
 | ||||||
|  | [title] | ||||||
|  | in = 1.5 | ||||||
|  | out = 7 | ||||||
|  | font = "Roboto-Regular-enriched.ttf" | ||||||
|  | fontsize = 80 | ||||||
|  | fontcolor = "#ffffff" | ||||||
|  | x = 400 | ||||||
|  | y = 860 | ||||||
|  | 
 | ||||||
|  | [speaker] | ||||||
|  | in = 2.5 | ||||||
|  | out = 7 | ||||||
|  | font = "Roboto-Regular-enriched.ttf" | ||||||
|  | fontsize = 60 | ||||||
|  | fontcolor = "#ffffff" | ||||||
|  | x = 400 | ||||||
|  | y = 960 | ||||||
|  | 
 | ||||||
|  | [text] | ||||||
|  | in = 3 | ||||||
|  | out = 7 | ||||||
|  | font = "Roboto-Regular-enriched.ttf" | ||||||
|  | fontsize = 45 | ||||||
|  | fontcolor = "#ffffff" | ||||||
|  | x = 64 | ||||||
|  | y = 1000 | ||||||
|  | text = '' | ||||||
|  | 
 | ||||||
|  | @ -7,10 +7,19 @@ import subprocess | ||||||
| import renderlib | import renderlib | ||||||
| import argparse | import argparse | ||||||
| import shlex | import shlex | ||||||
|  | from toml import load | ||||||
| from PIL import ImageFont | from PIL import ImageFont | ||||||
| from configparser import ConfigParser |  | ||||||
| import json | import json | ||||||
| 
 | 
 | ||||||
|  | from rich import print,inspect | ||||||
|  | import logging | ||||||
|  | from rich.logging import RichHandler | ||||||
|  | 
 | ||||||
|  | FORMAT = "%(message)s" | ||||||
|  | logging.basicConfig( | ||||||
|  |     level="INFO", format=FORMAT, datefmt="[%X]", handlers=[RichHandler()] | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| # Parse arguments | # Parse arguments | ||||||
| parser = argparse.ArgumentParser( | parser = argparse.ArgumentParser( | ||||||
|     description='C3VOC Intro-Outro-Generator - Variant which renders only using video filters in ffmpeg', |     description='C3VOC Intro-Outro-Generator - Variant which renders only using video filters in ffmpeg', | ||||||
|  | @ -51,24 +60,20 @@ parser.add_argument('--force', action="store_true", default=False, help=''' | ||||||
| 
 | 
 | ||||||
| args = parser.parse_args() | args = parser.parse_args() | ||||||
| 
 | 
 | ||||||
|  | if args.debug: | ||||||
|  |     logging.getLogger().setLevel(logging.DEBUG) | ||||||
|  | 
 | ||||||
| if (args.skip is None): | if (args.skip is None): | ||||||
| 	args.skip = [] | 	args.skip = [] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def headline(str): | if not (os.path.exists(os.path.join(args.project, 'config.toml'))): | ||||||
| 	print("##################################################") |     logging.error("config.toml file in Project Path is missing") | ||||||
| 	print(str) |  | ||||||
| 	print("##################################################") |  | ||||||
| 	print() |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def error(str): |  | ||||||
| 	headline(str) |  | ||||||
| 	parser.print_help() |  | ||||||
|     sys.exit(1) |     sys.exit(1) | ||||||
| 
 | 
 | ||||||
| cparser = ConfigParser() | with open(os.path.join(args.project, 'config.toml'), 'r') as f: | ||||||
| cparser.read(os.path.join(os.path.dirname(args.project), 'config.ini')) |     cparser = load(f) | ||||||
|  | logging.debug(cparser) | ||||||
| template = cparser['default']['template'] | template = cparser['default']['template'] | ||||||
| alpha = cparser['default']['alpha'] | alpha = cparser['default']['alpha'] | ||||||
| prores = cparser['default']['prores'] | prores = cparser['default']['prores'] | ||||||
|  | @ -103,33 +108,31 @@ text_x = int(cparser['text']['x']) | ||||||
| text_y = int(cparser['text']['y']) | text_y = int(cparser['text']['y']) | ||||||
| text_text = cparser['text']['text'] | text_text = cparser['text']['text'] | ||||||
| 
 | 
 | ||||||
| font_t = os.path.join(os.path.dirname(args.project), title_font) | font_t = os.path.join(args.project, title_font) | ||||||
| font_s = os.path.join(os.path.dirname(args.project), speaker_font) | font_s = os.path.join(args.project, speaker_font) | ||||||
| font_tt = os.path.join(os.path.dirname(args.project), text_font) | font_tt = os.path.join(args.project, text_font) | ||||||
| 
 | 
 | ||||||
| fileformat = os.path.splitext(template)[1] | fileformat = os.path.splitext(template)[1] | ||||||
| infile = os.path.join(os.path.dirname(args.project), template) | infile = os.path.join(args.project, template) | ||||||
| 
 | 
 | ||||||
| schedule = cparser['default']['schedule'] | schedule = cparser['default']['schedule'] | ||||||
| 
 | 
 | ||||||
| if not (os.path.exists(os.path.join(args.project, template))): | if not (os.path.exists(os.path.join(args.project, template))): | ||||||
|     error("Template file {} in Project Path is missing".format(template)) |     logging.error("Template file {} in Project Path is missing".format(template)) | ||||||
| 
 | 
 | ||||||
| for ffile in (title_font, speaker_font, text_font): | for ffile in (title_font, speaker_font, text_font): | ||||||
|     if not (os.path.exists(os.path.join(args.project, ffile))): |     if not (os.path.exists(os.path.join(args.project, ffile))): | ||||||
|         error("Font file {} in Project Path is missing".format(ffile)) |         logging.error("Font file {} in Project Path is missing".format(ffile)) | ||||||
| 
 | 
 | ||||||
| if not (os.path.exists(os.path.join(args.project, 'config.ini'))): |  | ||||||
|     error("config.ini file in Project Path is missing") |  | ||||||
| 
 | 
 | ||||||
| if alpha == 'true' and not fileformat == '.mov': | if alpha == 'true' and not fileformat == '.mov': | ||||||
|     error("Alpha can only be rendered with .mov source files") |     logging.error("Alpha can only be rendered with .mov source files") | ||||||
| 
 | 
 | ||||||
| if not args.project: | if not args.project: | ||||||
|     error("The Project Path is a required argument") |     logging.error("The Project Path is a required argument") | ||||||
| 
 | 
 | ||||||
| if not args.debug and not schedule: | if not args.debug and not schedule: | ||||||
|     error("Either specify --debug or supply a schedule in config.ini") |     logging.error("Either specify --debug or supply a schedule in config.ini") | ||||||
| 
 | 
 | ||||||
| if args.debug: | if args.debug: | ||||||
|     persons = ['Thomas Roth', 'Dmitry Nedospasov', 'Josh Datko'] |     persons = ['Thomas Roth', 'Dmitry Nedospasov', 'Josh Datko'] | ||||||
|  | @ -150,7 +153,7 @@ def describe_event(event): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def event_print(event, message): | def event_print(event, message): | ||||||
|     print("{} – {}".format(describe_event(event), message)) |     logging.info("{} – {}".format(describe_event(event), message)) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def fmt_command(command, **kwargs): | def fmt_command(command, **kwargs): | ||||||
|  | @ -176,10 +179,10 @@ def fit_text(string: str, frame_width): | ||||||
|     line_num = 0 |     line_num = 0 | ||||||
|     line = "" |     line = "" | ||||||
|     for word in split_line: |     for word in split_line: | ||||||
|         w, _ = translation_font.getsize(" ".join([line, word])) |         w = translation_font.getlength(" ".join([line, word])) | ||||||
|         print("{}, {}".format(w, line)) |         logging.debug("{}, {}".format(w, line)) | ||||||
|         if w > (frame_width): |         if w > (frame_width): | ||||||
|             print("too wide, breaking") |             logging.debug("too wide, breaking") | ||||||
|             lines += line.strip() + "\n" |             lines += line.strip() + "\n" | ||||||
|             line = "" |             line = "" | ||||||
| 
 | 
 | ||||||
|  | @ -222,17 +225,18 @@ def enqueue_job(event): | ||||||
| 
 | 
 | ||||||
|     t = fit_title(event_title) |     t = fit_title(event_title) | ||||||
|     s = fit_speaker(event_personnames) |     s = fit_speaker(event_personnames) | ||||||
|     print(s) |     logging.info(s) | ||||||
| 
 | 
 | ||||||
|     if args.debug: |     if args.debug: | ||||||
|         print('Title: ', t) |         logging.info(f'Title: {t}') | ||||||
|         print('Speaker: ', s) |         logging.info(f'Speaker: {s}') | ||||||
| 
 | 
 | ||||||
|     outfile = os.path.join(os.path.dirname(args.project), event_id + '.ts') |     outfile = os.path.join(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}:line_spacing={linespacing}:fontcolor={fontcolor}:x={x}:y={y}:text='{text}':".format( | ||||||
|             fontfile = font_t,  |             fontfile = font_t,  | ||||||
|             fontsize = title_fontsize,  |             fontsize = title_fontsize,  | ||||||
|  |             linespacing = int(0.05*title_fontsize), | ||||||
|             fontcolor = title_fontcolor,  |             fontcolor = title_fontcolor,  | ||||||
|             x = title_x,  |             x = title_x,  | ||||||
|             y = title_y,  |             y = title_y,  | ||||||
|  | @ -244,9 +248,10 @@ def enqueue_job(event): | ||||||
|             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}:line_spacing={linespacing}:fontcolor={fontcolor}:x={x}:y={y}:text='{text}':".format( | ||||||
|             fontfile = font_s,  |             fontfile = font_s,  | ||||||
|             fontsize = speaker_fontsize,  |             fontsize = speaker_fontsize,  | ||||||
|  |             linespacing = int(0.05*speaker_fontsize), | ||||||
|             fontcolor = speaker_fontcolor,  |             fontcolor = speaker_fontcolor,  | ||||||
|             x = speaker_x,  |             x = speaker_x,  | ||||||
|             y = speaker_y,  |             y = speaker_y,  | ||||||
|  | @ -258,9 +263,10 @@ def enqueue_job(event): | ||||||
|             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}:line_spacing={linespacing}:fontcolor={fontcolor}:x={x}:y={y}:text={text}:".format( | ||||||
|             fontfile = font_tt,  |             fontfile = font_tt,  | ||||||
|             fontsize = text_fontsize,  |             fontsize = text_fontsize,  | ||||||
|  |             linespacing = int(0.05*text_fontsize), | ||||||
|             fontcolor = text_fontcolor,  |             fontcolor = text_fontcolor,  | ||||||
|             x = text_x,  |             x = text_x,  | ||||||
|             y = text_y,  |             y = text_y,  | ||||||
|  | @ -284,8 +290,7 @@ def enqueue_job(event): | ||||||
|     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 -intra: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 -intra: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: |     logging.debug(cmd) | ||||||
|         print(cmd) |  | ||||||
| 
 | 
 | ||||||
|     run(cmd) |     run(cmd) | ||||||
| 
 | 
 | ||||||
|  | @ -294,14 +299,14 @@ def enqueue_job(event): | ||||||
| 
 | 
 | ||||||
| if args.ids: | if args.ids: | ||||||
|     if len(args.ids) == 1: |     if len(args.ids) == 1: | ||||||
|         print("enqueuing {} job".format(len(args.ids))) |         logging.info("enqueuing {} job".format(len(args.ids))) | ||||||
|     else: |     else: | ||||||
|         print("enqueuing {} jobs".format(len(args.ids))) |         logging.info("enqueuing {} jobs".format(len(args.ids))) | ||||||
| else: | else: | ||||||
|     if len(events) == 1: |     if len(events) == 1: | ||||||
|         print("enqueuing {} job".format(len(events))) |         logging.info("enqueuing {} job".format(len(events))) | ||||||
|     else: |     else: | ||||||
|         print("enqueuing {} jobs".format(len(events))) |         logging.info("enqueuing {} jobs".format(len(events))) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| for event in events: | for event in events: | ||||||
|  | @ -309,7 +314,7 @@ for event in events: | ||||||
|         continue |         continue | ||||||
| 
 | 
 | ||||||
|     if args.rooms and event['room'] not in args.rooms: |     if args.rooms and event['room'] not in args.rooms: | ||||||
|         print("skipping room %s (%s)" % (event['room'], event['title'])) |         logging.info("skipping room %s (%s)" % (event['room'], event['title'])) | ||||||
|         continue |         continue | ||||||
| 
 | 
 | ||||||
|     event_print(event, "enqueued as " + str(event['id'])) |     event_print(event, "enqueued as " + str(event['id'])) | ||||||
|  | @ -320,6 +325,6 @@ for event in events: | ||||||
|         continue |         continue | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| print('all done') | logging.info('all done') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,3 +3,5 @@ cssutils==1.0.2 | ||||||
| lxml==4.6.3 | lxml==4.6.3 | ||||||
| svg.path==4.0.2 | svg.path==4.0.2 | ||||||
| Wand==0.6.5 | Wand==0.6.5 | ||||||
|  | toml | ||||||
|  | rich | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue