From 7bf970cf1be36d447dd94cfd1d405b8b5813c81d Mon Sep 17 00:00:00 2001 From: Artemy Date: Sun, 16 Apr 2023 09:55:33 +0300 Subject: [PATCH] feat: images to video --- app.py | 2 +- processing/bulk.py | 23 ++++++++++++++++++----- processing/stacking.py | 8 +------- processing/utils.py | 16 ++++++++++++++++ tabs/Images to video/app.py | 29 +++++++++++++++++++++-------- 5 files changed, 57 insertions(+), 21 deletions(-) create mode 100644 processing/utils.py diff --git a/app.py b/app.py index 7f065f8..464424a 100644 --- a/app.py +++ b/app.py @@ -23,7 +23,7 @@ for tab_name in tabs: all_tabs.append((tab_name, tab.app)) except Exception as e: - print(f"Error loading tab: {e}") + print(f"Error loading tab ({tab_name}): {e}") with gr.Blocks() as app: for tab_name, tab in all_tabs: diff --git a/processing/bulk.py b/processing/bulk.py index 5bff6b4..fe7c230 100644 --- a/processing/bulk.py +++ b/processing/bulk.py @@ -1,11 +1,24 @@ from PIL import Image, ImageFilter import ffmpeg import os +from processing.utils import generate_name, get_date_text -def images_to_video(directory, fps): - glob_path = os.path.join(directory, "*.png") - video_path = os.path.join(directory, "video.mp4") +def images_to_video(directory, fps, img_ext, img_name_format, video_name, video_ext, video_dir): + images_pattern = os.path.join(directory, f"{img_name_format}.{img_ext}") - ffmpeg.input(glob_path, pattern_type="glob", - framerate=fps).output(video_path).run() + if video_dir: + video_path = os.path.join(video_dir, f"{video_name}.{video_ext}") + else: + video_path = generate_name( + extension=video_ext, name=video_name, subfolder="videos") + + ffmpeg.input(images_pattern, + framerate=fps).output(video_path, pix_fmt='yuv420p').global_args("-y").run() + + +def video_to_images(video_path, img_ext): + images_pattern = generate_name( + extension=img_ext, name=video_path, subfolder=os.path.join("images", get_date_text())) + + ffmpeg.input(video_path).output(images_pattern).run() diff --git a/processing/stacking.py b/processing/stacking.py index 8e38797..ccf46ca 100644 --- a/processing/stacking.py +++ b/processing/stacking.py @@ -1,12 +1,6 @@ from methods.stack_methods import denoise, startracks, noise_extractor, untrack import os -import datetime - - -def generate_name(): - os.makedirs("./output/stacked", exist_ok=True) - - return f"./output/stacked/{datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.png" +from processing.utils import generate_name def stacking(dir, method): diff --git a/processing/utils.py b/processing/utils.py new file mode 100644 index 0000000..f201d26 --- /dev/null +++ b/processing/utils.py @@ -0,0 +1,16 @@ +import os +import datetime + + +def generate_name(name=False, subfolder="stacked", extension="png", format='%Y-%m-%d_%H-%M-%S'): + + os.makedirs(os.path.join("./output", subfolder), exist_ok=True) + + if name is False or name == "": + name = get_date_text(format) + + return os.path.join("./output", subfolder, f"{name}.{extension}") + + +def get_date_text(format='%Y-%m-%d_%H-%M-%S'): + return datetime.datetime.now().strftime(format) diff --git a/tabs/Images to video/app.py b/tabs/Images to video/app.py index 3166125..6f03c9e 100644 --- a/tabs/Images to video/app.py +++ b/tabs/Images to video/app.py @@ -2,16 +2,29 @@ import gradio as gr from processing.bulk import images_to_video with gr.Blocks() as app: - gr.Markdown("Convert images to video. # **WIP, not working**") - with gr.Row(): - with gr.Column(): - directory = gr.Text( - placeholder="A directory with many images of the same size", lines=1, label="Directory") + gr.Markdown("Convert images to video.") + directory = gr.Text( + placeholder="A directory with many images of the same size", label="Directory") - fps = gr.Number(label="FPS") - submit = gr.Button("Submit") + fps = gr.Number(label="FPS", value=30, min=0) + + with gr.Accordion("Advanced settings", open=False) as acc: + video_name = gr.Text( + label="Video name", placeholder="Video name e.g. video. If not specified will be generated by time") + video_ext = gr.Dropdown(label="Video extension", choices=[ + "mp4"], value="mp4") + video_dir = gr.Text( + label="Video directory", placeholder="The directory where the video will be saved. If not specified `./output/videos`") + + img_ext = gr.Dropdown(label="Image extension", choices=[ + "png", "jpg"], value="png") + img_name_format = gr.Text( + label="Image name format", placeholder="ffmpeg pattern e.g. %04d is (0000.png)", value="%d") + + submit = gr.Button("Submit") submit.click( fn=images_to_video, - inputs=[directory, fps], + inputs=[directory, fps, img_ext, img_name_format, + video_name, video_ext, video_dir], )