diff --git a/ui.py b/ui.py new file mode 100644 index 0000000..85de1b4 --- /dev/null +++ b/ui.py @@ -0,0 +1,171 @@ + +import gradio as gr + +from ebsynth_utility import ebsynth_utility_process +from modules import script_callbacks +from modules.call_queue import wrap_gradio_gpu_call + +def on_ui_tabs(): + + with gr.Blocks(analytics_enabled=False) as ebs_interface: + with gr.Row().style(equal_height=False): + with gr.Column(variant='panel'): + + with gr.Row(): + with gr.Tabs(elem_id="ebs_settings"): + with gr.TabItem('project setting', elem_id='ebs_project_setting'): + project_dir = gr.Textbox(label='Project directory', lines=1) + original_movie_path = gr.Textbox(label='Original Movie Path', lines=1) + + org_video = gr.Video(interactive=True, mirror_webcam=False) + def fn_upload_org_video(video): + return video + org_video.upload(fn_upload_org_video, org_video, original_movie_path) + gr.HTML(value="

\ + If you have trouble entering the video path manually, you can also use drag and drop. \ +

") + + with gr.TabItem('configuration', elem_id='ebs_configuration'): + with gr.Tabs(elem_id="ebs_configuration_tab"): + with gr.TabItem(label="stage 1",elem_id='ebs_configuration_tab1'): + with gr.Row(): + frame_width = gr.Number(value=-1, label="Frame Width", precision=0, interactive=True) + frame_height = gr.Number(value=-1, label="Frame Height", precision=0, interactive=True) + gr.HTML(value="

\ + -1 means that it is calculated automatically. If both are -1, the size will be the same as the source size. \ +

") + + st1_masking_method_index = gr.Radio(label='Masking Method', choices=["transparent-background","clipseg","transparent-background AND clipseg"], value="transparent-background", type="index") + + with gr.Accordion(label="transparent-background options"): + st1_mask_threshold = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Mask Threshold', value=0.0) + + # https://pypi.org/project/transparent-background/ + gr.HTML(value="

\ + configuration for \ + [transparent-background]\ +

") + tb_use_fast_mode = gr.Checkbox(label="Use Fast Mode(It will be faster, but the quality of the mask will be lower.)", value=False) + tb_use_jit = gr.Checkbox(label="Use Jit", value=False) + + with gr.Accordion(label="clipseg options"): + clipseg_mask_prompt = gr.Textbox(label='Mask Target (e.g., girl, cats)', lines=1) + clipseg_exclude_prompt = gr.Textbox(label='Exclude Target (e.g., finger, book)', lines=1) + clipseg_mask_threshold = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Mask Threshold', value=0.4) + clipseg_mask_blur_size = gr.Slider(minimum=0, maximum=150, step=1, label='Mask Blur Kernel Size(MedianBlur)', value=11) + clipseg_mask_blur_size2 = gr.Slider(minimum=0, maximum=150, step=1, label='Mask Blur Kernel Size(GaussianBlur)', value=11) + + with gr.TabItem(label="stage 2", elem_id='ebs_configuration_tab2'): + key_min_gap = gr.Slider(minimum=0, maximum=500, step=1, label='Minimum keyframe gap', value=10) + key_max_gap = gr.Slider(minimum=0, maximum=1000, step=1, label='Maximum keyframe gap', value=300) + key_th = gr.Slider(minimum=0.0, maximum=100.0, step=0.1, label='Threshold of delta frame edge', value=8.5) + key_add_last_frame = gr.Checkbox(label="Add last frame to keyframes", value=True) + + with gr.TabItem(label="stage 7", elem_id='ebs_configuration_tab7'): + blend_rate = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Crossfade blend rate', value=1.0) + export_type = gr.Dropdown(choices=["mp4","webm","gif","rawvideo"], value="mp4" ,label="Export type") + + with gr.TabItem(label="stage 8", elem_id='ebs_configuration_tab8'): + bg_src = gr.Textbox(label='Background source(mp4 or directory containing images)', lines=1) + bg_type = gr.Dropdown(choices=["Fit video length","Loop"], value="Fit video length" ,label="Background type") + mask_blur_size = gr.Slider(minimum=0, maximum=150, step=1, label='Mask Blur Kernel Size', value=5) + mask_threshold = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Mask Threshold', value=0.0) + #is_transparent = gr.Checkbox(label="Is Transparent", value=True, visible = False) + fg_transparency = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Foreground Transparency', value=0.0) + + with gr.TabItem(label="etc", elem_id='ebs_configuration_tab_etc'): + mask_mode = gr.Dropdown(choices=["Normal","Invert","None"], value="Normal" ,label="Mask Mode") + with gr.TabItem('info', elem_id='ebs_info'): + gr.HTML(value="

\ + The process of creating a video can be divided into the following stages.
\ + (Stage 3, 4, and 6 only show a guide and do nothing actual processing.)

\ + stage 1
\ + Extract frames from the original video.
\ + Generate a mask image.

\ + stage 2
\ + Select keyframes to be given to ebsynth.

\ + stage 3
\ + img2img keyframes.

\ + stage 4
\ + and upscale to the size of the original video.

\ + stage 5
\ + Rename keyframes.
\ + Generate .ebs file.(ebsynth project file)

\ + stage 6
\ + Running ebsynth.(on your self)
\ + Open the generated .ebs under project directory and press [Run All] button.
\ + If ""out-*"" directory already exists in the Project directory, delete it manually before executing.
\ + If multiple .ebs files are generated, run them all.

\ + stage 7
\ + Concatenate each frame while crossfading.
\ + Composite audio files extracted from the original video onto the concatenated video.

\ + stage 8
\ + This is an extra stage.
\ + You can put any image or images or video you like in the background.
\ + You can specify in this field -> [Ebsynth Utility]->[configuration]->[stage 8]->[Background source]
\ + If you have already created a background video in Invert Mask Mode([Ebsynth Utility]->[configuration]->[etc]->[Mask Mode]),
\ + You can specify \"path_to_project_dir/inv/crossfade_tmp\".
\ +

") + + with gr.Column(variant='panel'): + with gr.Column(scale=1): + with gr.Row(): + stage_index = gr.Radio(label='Process Stage', choices=["stage 1","stage 2","stage 3","stage 4","stage 5","stage 6","stage 7","stage 8"], value="stage 1", type="index", elem_id='ebs_stages') + + with gr.Row(): + generate_btn = gr.Button('Generate', elem_id="ebs_generate_btn", variant='primary') + + with gr.Group(): + debug_info = gr.HTML(elem_id="ebs_info_area", value=".") + + with gr.Column(scale=2): + html_info = gr.HTML() + + ebs_args = dict( + fn=wrap_gradio_gpu_call(ebsynth_utility_process), + inputs=[ + stage_index, + + project_dir, + original_movie_path, + + frame_width, + frame_height, + st1_masking_method_index, + st1_mask_threshold, + tb_use_fast_mode, + tb_use_jit, + clipseg_mask_prompt, + clipseg_exclude_prompt, + clipseg_mask_threshold, + clipseg_mask_blur_size, + clipseg_mask_blur_size2, + + key_min_gap, + key_max_gap, + key_th, + key_add_last_frame, + + blend_rate, + export_type, + + bg_src, + bg_type, + mask_blur_size, + mask_threshold, + fg_transparency, + + mask_mode, + + ], + outputs=[ + debug_info, + html_info, + ], + show_progress=False, + ) + generate_btn.click(**ebs_args) + + return (ebs_interface, "Ebsynth Utility Lite", "ebs_interface"), + +script_callbacks.on_ui_tabs(on_ui_tabs)