From 9e48ab688b3db41d637ec0b1600450deac26c9f3 Mon Sep 17 00:00:00 2001 From: Aleksey Date: Mon, 5 Feb 2024 21:43:56 +0400 Subject: [PATCH] complete rework * drop support for makefile generation * rewrite generator as pydoit task generator * rewrite as python module --- __init__.py | 0 make.py | 102 ------------------------------------------ stickergen/actions.py | 76 +++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 102 deletions(-) create mode 100644 __init__.py delete mode 100755 make.py create mode 100644 stickergen/actions.py diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/make.py b/make.py deleted file mode 100755 index 9ea2baa..0000000 --- a/make.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python3 -from yaml import safe_load -from pathlib import Path -from sys import argv -import logging -from shlex import quote - -path_stickers_root = Path(argv[1]) -path_stickers_output_dir = path_stickers_root / 'stickers' -path_stickers_source_dir = path_stickers_root / 'src' -path_makefile_gen = path_stickers_root / 'makefile.gen' -path_stickers_data_dir = path_stickers_root / 'data' -log = logging.getLogger("stickers.make") -logging.basicConfig( - filename=str(path_stickers_root / 'make.log'), - level=logging.DEBUG - ) -output_ext = 'static' -out_formats = { - 'static': { - 'extension': 'webp', - 'options': '-lossless 1 -f webp' - }, - 'video': { - 'extension': 'webm', - 'options': '-codec:v libvpx-vp9 -map v -pix_fmt yuva420p' - }, - 'png': { - 'extension': 'png', - 'options': '-preset:v icon -frames 1' - } - } - -with open(path_makefile_gen, 'w') as makefile: - targets_list = list() - # makefile: skeleton rules - makefile.write(".PHONY: all default clean stickers/\n") - makefile.write("default: all\n") - makefile.write('stickers:\n\tmkdir stickers\n') - makefile.write('clean:\n\trm -vrf stickers\n') - for sticker_description_file in path_stickers_data_dir.glob('*.yaml'): - log.debug('input description file: %s', sticker_description_file) - with open(sticker_description_file) as yaml_file: - sticker_description = safe_load(yaml_file) - log.debug("stuff %s", sticker_description) - target_filename = path_stickers_output_dir \ - / ( sticker_description['name'] \ - + '.' \ - + out_formats[output_ext]['extension'] ) - prerequisite_filename=f"{sticker_description_file} " - if sticker_description['input']['base'].get('format','') \ - not in ('lavfi', 'image2'): - prerequisite_filename += str( - path_stickers_source_dir \ - / sticker_description['input']['base']['input'] - ).replace(' ', '\\ ') - targets_list.append(f"{target_filename}") - # makefile: rule declaration - makefile.write(f"{target_filename}: {prerequisite_filename} | stickers\n") - # makefile: recipe ffmpeg base - makefile.write('\tffmpeg ') - # makefile: specify format if present - if sticker_description['input']['base'].get('format'): - makefile.write(f"-f {sticker_description['input']['base']['format']} ") - # makefile: force input framerate if present - if sticker_description['input']['base'].get('framerate'): - makefile.write(f"-framerate {sticker_description['input']['base']['framerate']} ") - #makefile: input base file - input_file = quote(str(path_stickers_source_dir \ - / sticker_description['input']['base']['input'] - ) - ) - makefile.write(f"-i {input_file} ") - # makefile: video filter: base - makefile.write('-vf ') - # makefile: video filter: change transparent color - if sticker_description['input'].get('colors',{}).get('transparent'): - makefile.write("geq=\\''") - transparent = sticker_description['input']['colors']['transparent'] - makefile.write(f"r=if(lt(alpha(X,Y),128),{transparent[0]},r(X,Y)):" - f"g=if(lt(alpha(X,Y),128),{transparent[1]},g(X,Y)):" - f"b=if(lt(alpha(X,Y),128),{transparent[2]},b(X,Y)):" - "a=alpha(X,Y)'\\'," - ) - # makefile: video filter: scale - out_width = sticker_description.get('output', {}).get('width', 512) - out_height = sticker_description.get('output', {}).get('height', 512) - makefile.write(f"scale=w={out_width}:h={out_height}:force_original_aspect_ratio=decrease") - # makefile: output file speed - if sticker_description.get('output', {}).get('speed'): - makefile.write(f",setpts={sticker_description['output']['speed']}") - # makefile: video filter: finalize - makefile.write(' ') - # makefile: output file options - makefile.write(f"{out_formats[output_ext]['options']} ") - # makefile: replace output without confirmation - makefile.write('-y ') - # makefile: output file - makefile.write(quote(str(target_filename))) - # makefile: finalize recipe - makefile.write('\n') - makefile.write(f"all: {' '.join(targets_list)} | stickers\n") diff --git a/stickergen/actions.py b/stickergen/actions.py new file mode 100644 index 0000000..06b8a3a --- /dev/null +++ b/stickergen/actions.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from yaml import safe_load +from pathlib import Path +import logging + +path_stickers_root = Path('.') +path_stickers_output_dir = path_stickers_root / 'stickers' +path_stickers_output_dir.mkdir(exist_ok=True) +path_stickers_source_dir = path_stickers_root / 'src' +path_stickers_data_dir = path_stickers_root / 'data' +logging.basicConfig( + filename=str(path_stickers_root / 'make.log'), + level=logging.DEBUG) +log = logging.getLogger('stickers.actions') +log.setLevel(logging.DEBUG) +log.debug('path_stickers_root = %s', path_stickers_root) +log.debug('path_stickers_data_dir = %s', path_stickers_data_dir) + + +def mktask(out_format, out_ext, ffmpeg_opts): + def task_stickers(): + log = logging.getLogger('stickers.actions.task_'+out_format) + log.setLevel(logging.DEBUG) + log.debug(f'{list(path_stickers_data_dir.glob("*.yaml"))}') + for sticker_description_file in path_stickers_data_dir.glob('*.yaml'): + ffmpeg_action = ['ffmpeg'] + file_dep = [ sticker_description_file ] + log.debug('input description file: %s', sticker_description_file) + with open(sticker_description_file) as yaml_file: + sticker_description = safe_load(yaml_file) + if sticker_description.get('disabled', False): + continue + log.debug('stuff %s', sticker_description) + out_filename = f'{sticker_description["name"]}.{out_ext}' + target_filename = path_stickers_output_dir / out_filename + if sticker_description['input']['base'].get('format','') not in ('lavfi', 'image2'): + file_dep.append(f'{path_stickers_source_dir/sticker_description["input"]["base"]["input"]}') + if sticker_description['input']['base'].get('format'): + ffmpeg_action.append('-f') + ffmpeg_action.append(sticker_description['input']['base']['format']) + if sticker_description['input']['base'].get('framerate'): + ffmpeg_action.append('-framerate') + ffmpeg_action.append(sticker_description['input']['base']['framerate']) + ffmpeg_action.append('-i') + ffmpeg_action.append(path_stickers_source_dir/sticker_description['input']['base']['input']) + ffmpeg_action.append('-vf') + filterspec = '' + if sticker_description['input'].get('colors',{}).get('transparent'): + transparent = sticker_description['input']['colors']['transparent'] + filterspec += 'geq=\'' + filterspec += f'r=if(lt(alpha(X,Y),128),{transparent[0]},r(X,Y)):' + filterspec += f'g=if(lt(alpha(X,Y),128),{transparent[1]},g(X,Y)):' + filterspec += f'b=if(lt(alpha(X,Y),128),{transparent[2]},b(X,Y)):' + filterspec += f'a=alpha(X,Y)\',' + + out_width = sticker_description.get('output', {}).get('width', 512) + out_height = sticker_description.get('output', {}).get('height', 512) + filterspec += f'scale=w={out_width}:h={out_height}:force_original_aspect_ratio=decrease' + if sticker_description.get('output', {}).get('speed'): + filterspec += f',setpts={sticker_description['output']['speed']}' + ffmpeg_action.append(filterspec) + ffmpeg_action.append('-y') + ffmpeg_action += ffmpeg_opts + ffmpeg_action.append(target_filename) + yield { + 'actions': [ffmpeg_action], + 'name': out_filename, + 'targets': [target_filename], + 'file_dep': file_dep + } + return task_stickers + +task_png = mktask('png', 'png', ['-preset:v', 'icon', '-frames', '1']) +task_webm = mktask('webm', 'webm', ['-codec:v', 'libvpx-vp9', '-map', 'v', '-pix_fmt', 'yuva420p']) +task_webp = mktask('webp', 'webp', ['-lossless', '1'])