mirror of
https://github.com/s0md3v/roop.git
synced 2025-12-06 18:08:29 +00:00
Add the web UI built by Gradio
This commit is contained in:
parent
68f534c35f
commit
e4d66ecfe0
@ -20,4 +20,6 @@ tensorflow==2.12.0; sys_platform != 'darwin'
|
||||
opennsfw2==0.10.2
|
||||
protobuf==4.23.2
|
||||
tqdm==4.65.0
|
||||
gfpgan==1.3.8
|
||||
gfpgan==1.3.8
|
||||
gradio
|
||||
moviepy
|
||||
@ -20,6 +20,7 @@ import tensorflow
|
||||
import roop.globals
|
||||
import roop.metadata
|
||||
import roop.ui as ui
|
||||
from roop import gradio_ui
|
||||
from roop.predicter import predict_image, predict_video
|
||||
from roop.processors.frame.core import get_frame_processors_modules
|
||||
from roop.utilities import has_image_extension, is_image, is_video, detect_fps, create_video, extract_frames, get_temp_frame_paths, restore_audio, create_temp, move_temp, clean_temp, normalize_output_path
|
||||
@ -37,6 +38,7 @@ def parse_args() -> None:
|
||||
program.add_argument('-s', '--source', help='select an source image', dest='source_path')
|
||||
program.add_argument('-t', '--target', help='select an target image or video', dest='target_path')
|
||||
program.add_argument('-o', '--output', help='select output file or directory', dest='output_path')
|
||||
program.add_argument('--gradio-ui', help='using gradio web ui', dest='gradio_ui', action='store_true', default=False)
|
||||
program.add_argument('--frame-processor', help='frame processors (choices: face_swapper, face_enhancer, ...)', dest='frame_processor', default=['face_swapper'], nargs='+')
|
||||
program.add_argument('--keep-fps', help='keep original fps', dest='keep_fps', action='store_true', default=False)
|
||||
program.add_argument('--keep-audio', help='keep original audio', dest='keep_audio', action='store_true', default=True)
|
||||
@ -54,6 +56,7 @@ def parse_args() -> None:
|
||||
roop.globals.source_path = args.source_path
|
||||
roop.globals.target_path = args.target_path
|
||||
roop.globals.output_path = normalize_output_path(roop.globals.source_path, roop.globals.target_path, args.output_path)
|
||||
roop.globals.gradio_ui = args.gradio_ui
|
||||
roop.globals.frame_processors = args.frame_processor
|
||||
roop.globals.headless = args.source_path or args.target_path or args.output_path
|
||||
roop.globals.keep_fps = args.keep_fps
|
||||
@ -132,7 +135,7 @@ def pre_check() -> bool:
|
||||
|
||||
def update_status(message: str, scope: str = 'ROOP.CORE') -> None:
|
||||
print(f'[{scope}] {message}')
|
||||
if not roop.globals.headless:
|
||||
if not roop.globals.headless and not roop.globals.gradio_ui:
|
||||
ui.update_status(message)
|
||||
|
||||
|
||||
@ -210,6 +213,9 @@ def run() -> None:
|
||||
limit_resources()
|
||||
if roop.globals.headless:
|
||||
start()
|
||||
elif roop.globals.gradio_ui:
|
||||
demo = gradio_ui.init(start, destroy)
|
||||
demo.launch()
|
||||
else:
|
||||
window = ui.init(start, destroy)
|
||||
window.mainloop()
|
||||
|
||||
@ -3,6 +3,7 @@ from typing import List
|
||||
source_path = None
|
||||
target_path = None
|
||||
output_path = None
|
||||
gradio_ui = None
|
||||
frame_processors: List[str] = []
|
||||
keep_fps = None
|
||||
keep_audio = None
|
||||
|
||||
138
roop/gradio_ui.py
Normal file
138
roop/gradio_ui.py
Normal file
@ -0,0 +1,138 @@
|
||||
import os
|
||||
import time
|
||||
from typing import Callable
|
||||
|
||||
import gradio as gr
|
||||
from moviepy.editor import VideoFileClip
|
||||
|
||||
import roop.globals
|
||||
|
||||
OUTPUT_PATH = "output"
|
||||
os.makedirs(OUTPUT_PATH, exist_ok=True)
|
||||
|
||||
start_func = None
|
||||
|
||||
|
||||
def has_image_extension(image_path: str) -> bool:
|
||||
return image_path.lower().endswith(('png', 'jpg', 'jpeg', 'webp', 'gif'))
|
||||
|
||||
|
||||
def has_video_extension(image_path: str) -> bool:
|
||||
return image_path.lower().endswith(('mp4'))
|
||||
|
||||
|
||||
def mp42gif(video):
|
||||
gif = video[:-3] + 'gif'
|
||||
video = VideoFileClip(video)
|
||||
video.write_gif(gif)
|
||||
return gif
|
||||
|
||||
|
||||
def gif2mp4(gif):
|
||||
video = gif[:-3] + 'mp4'
|
||||
gif = VideoFileClip(gif)
|
||||
gif.write_videofile(video, fps=gif.fps)
|
||||
return video
|
||||
|
||||
|
||||
def submit_func(source, target, keep_fps, many_faces, keep_audio=False, keep_frames=False, video_quality=-1):
|
||||
if source is None:
|
||||
raise gr.Error("Please upload your source file!")
|
||||
return gr.update(), gr.update()
|
||||
|
||||
if target is None:
|
||||
raise gr.Error("Please upload your target file!")
|
||||
return gr.update(), gr.update()
|
||||
|
||||
source = source.name
|
||||
target = target.name
|
||||
|
||||
gif_flag = False
|
||||
if target.endswith('.gif'):
|
||||
gif_flag = True
|
||||
target = gif2mp4(target)
|
||||
|
||||
suffix = os.path.splitext(target)[-1]
|
||||
output_filepath = os.path.join(OUTPUT_PATH,
|
||||
'output-{timestamp}{suffix}'.format(suffix=suffix, timestamp=int(time.time())))
|
||||
|
||||
roop.globals.source_path = source
|
||||
roop.globals.target_path = target
|
||||
roop.globals.output_path = output_filepath
|
||||
|
||||
roop.globals.keep_fps = keep_fps
|
||||
roop.globals.many_faces = many_faces
|
||||
roop.globals.keep_audio = keep_audio
|
||||
roop.globals.keep_frames = keep_frames
|
||||
roop.globals.video_quality = video_quality
|
||||
|
||||
global start_func
|
||||
start_func()
|
||||
|
||||
if gif_flag:
|
||||
output_filepath = mp42gif(output_filepath)
|
||||
|
||||
if has_image_extension(output_filepath):
|
||||
return gr.update(value=output_filepath, visible=True), gr.update(visible=False)
|
||||
|
||||
if has_video_extension(output_filepath):
|
||||
return gr.update(visible=False), gr.update(value=output_filepath, visible=True)
|
||||
|
||||
|
||||
def show_source_file(file):
|
||||
if file is None:
|
||||
return gr.update()
|
||||
|
||||
return file.name
|
||||
|
||||
|
||||
def show_target_file(file):
|
||||
if file is None:
|
||||
return gr.update(), gr.update()
|
||||
|
||||
if has_image_extension(file.name):
|
||||
return gr.update(value=file.name, visible=True), gr.update(visible=False)
|
||||
|
||||
if has_video_extension(file.name):
|
||||
return gr.update(visible=False), gr.update(value=file.name, visible=True)
|
||||
|
||||
|
||||
def init(start: Callable[[], None], destroy: Callable[[], None]):
|
||||
global start_func
|
||||
start_func = start
|
||||
|
||||
with gr.Blocks() as demo:
|
||||
gr.Markdown("# Welcome to use the Face Swapper !")
|
||||
|
||||
with gr.Row():
|
||||
source_file = gr.File(file_count='single', file_types=['.png', '.jpg', '.jpeg', '.webp'],
|
||||
type='file', label='source')
|
||||
target_file = gr.File(file_count='single', file_types=['.png', '.jpg', '.jpeg', '.webp', '.gif', '.mp4'],
|
||||
type='file', label='target')
|
||||
|
||||
with gr.Row():
|
||||
source_img = gr.Image(type='filepath', label="source", interactive=False, height=300)
|
||||
target_img = gr.Image(type='filepath', label="target image", interactive=False, height=300, visible=True)
|
||||
target_video = gr.Video(label="target video", interactive=False, visible=False)
|
||||
|
||||
with gr.Row():
|
||||
keep_fps = gr.Checkbox(value=False, label="Keep fps")
|
||||
many_face = gr.Checkbox(value=False, label="Many faces")
|
||||
keep_audio = gr.Checkbox(value=True, label="Keep audio")
|
||||
keep_frames = gr.Checkbox(value=False, label="Keep frames")
|
||||
|
||||
video_quality = gr.Slider(minimum=0, maximum=51, value=18, label='Video Quality')
|
||||
|
||||
submit_btn = gr.Button("Submit")
|
||||
|
||||
output_img = gr.Image(type='filepath', label="output image", interactive=False, height=300, visible=True)
|
||||
output_video = gr.Video(label="output video", interactive=False, visible=False)
|
||||
|
||||
source_file.change(show_source_file, inputs=source_file, outputs=source_img)
|
||||
target_file.change(show_target_file, inputs=[target_file], outputs=[target_img, target_video])
|
||||
|
||||
submit_btn.click(submit_func,
|
||||
inputs=[source_file, target_file, keep_fps, many_face, keep_audio, keep_frames, video_quality],
|
||||
outputs=[output_img, output_video])
|
||||
|
||||
return demo
|
||||
Loading…
Reference in New Issue
Block a user