diff --git a/gifmake.py b/gifmake.py index b1cba2b..724dc46 100644 --- a/gifmake.py +++ b/gifmake.py @@ -11,20 +11,26 @@ from typing import Any, Dict, List def get_args() -> Dict[str, Any]: parser = argparse.ArgumentParser( - prog='GIF Make', - description='Use ffmpeg to make GIFs from videos', - epilog='— Be gay and do crime') - parser.add_argument('-i', '--input', type=str, required=True, help="Input pattern like '/users/MyName/Videos/*.mov'") - parser.add_argument('-w', '--width', type=str, default='960', help='Width of the GIF in pixels, respecting aspect ratio') - parser.add_argument('-r', '--framerate', type=str, default='12', help='Framerate of GIF') - parser.add_argument('-t', '--tag', type=str, default=get_tag(), help='Optional tag included in file name') - parser.add_argument('-f', '--force_palette', action='store_const', const=True, help='Force regeneration of GIF color palettes') - parser.add_argument('-c', '--clean_up', action='store_const', const=True, help='Delete color palettes after finishing GIFs') + prog='GIF Make', + description='Use ffmpeg to make GIFs from videos', + epilog='— Be gay and do crime') + parser.add_argument('-i', '--input', type=str, required=True, + help="Input pattern like '/users/MyName/Videos/*.mov'") + parser.add_argument('-w', '--width', type=str, default='960', + help='Width of the GIF in pixels, respecting aspect ratio') + parser.add_argument('-r', '--framerate', type=str, + default='12', help='Framerate of GIF') + parser.add_argument('-t', '--tag', type=str, default=get_tag(), + help='Optional tag included in file name') + parser.add_argument('-f', '--force_palette', action='store_const', + const=True, help='Force regeneration of GIF color palettes') + parser.add_argument('-c', '--clean_up', action='store_const', + const=True, help='Delete color palettes after finishing GIFs') return vars(parser.parse_args()) def get_tag() -> str: - return ''.join(random.choices(string.ascii_uppercase + string.digits, k = 5)) + return ''.join(random.choices(string.ascii_uppercase + string.digits, k=5)) def get_inputs(args: Dict[str, Any]) -> List[str]: @@ -38,8 +44,7 @@ def clean_up_palette_files(palette_map: Dict[str, str]) -> None: def call_ffmpeg(command: str) -> str: print("ffmpeg", *command.split(' ')) - # If we want to silence the command output: stdout=open(os.devnull, 'wb') - return str(subprocess.run(["ffmpeg", *command.split(' ')])) + return str(subprocess.run(["ffmpeg", '-hide_banner', '-loglevel', 'error', *command.split(' ')])) def generate_palette_files_and_map(inputs: List[str], args: Dict[str, Any]) -> Dict[str, str]: @@ -52,7 +57,8 @@ def generate_palette_files_and_map(inputs: List[str], args: Dict[str, Any]) -> D file_name = f"{Path(input).stem}_{tag}_palette.png" full_path = f"{Path(input).parent}/{file_name}" if force_palette or not os.path.exists(full_path): - call_ffmpeg(f"-i {input} -lavfi scale={width}:-1,palettegen -sws_flags ewa_lanczos -y {full_path}") + call_ffmpeg( + f"-i {input} -lavfi scale={width}:-1,palettegen -sws_flags ewa_lanczos -y {full_path}") else: print(f"Skipped regenerating palette file {file_name}...") palette_map[input] = full_path @@ -70,7 +76,8 @@ def generate_gif_files(palette_map: Dict[str, str], args: Dict[str, Any]) -> Dic palette = palette_map[input] file_name = f"{Path(input).stem}_{tag}.gif" full_path = f"{Path(input).parent}/{file_name}" - call_ffmpeg(f"-i {input} -i {palette} -f gif -r {framerate} -lavfi scale={width}:-1,paletteuse -sws_flags ewa_lanczos {full_path}") + call_ffmpeg(f"-i {input} -i {palette} -f gif -r {framerate} -lavfi scale={ \ + width}:-1,paletteuse -sws_flags ewa_lanczos {full_path}") output_map[input] = full_path return output_map @@ -85,7 +92,7 @@ def make_gifs(args: Dict[str, Any]) -> None: if clean_up: clean_up_palette_files(palette_map) - + for input in output_map: print(f"Created {output_map[input]} from {input}") @@ -96,4 +103,4 @@ def main() -> None: if __name__ == '__main__': - main() \ No newline at end of file + main()