* Improve typing for our callbacks

* Return 0 for get_download_size

* Introduce ONNX powered face enhancer

* Introduce ONNX powered face enhancer

* Introduce ONNX powered face enhancer

* Remove tile processing from frame enhancer

* Fix video compress translation for libvpx-vp9

* Allow zero values for video compression

* Develop (#134)

* Introduce model options to the frame processors

* Finish UI to select frame processors models

* Simplify frame processors options

* Fix lint in CI

* Rename all kind of settings to options

* Add blend to enhancers

* Simplify webcam mode naming

* Bypass SSL issues under Windows

* Fix blend of frame enhancer

* Massive CLI refactoring, Register and apply ARGS via the frame processors

* Refine UI theme and introduce donate button

* Update dependencies and fix cpu only torch

* Update dependencies and fix cpu only torch

* Fix theme, Fix frame_processors in headless mode

* Remove useless astype

* Disable CoreML for the ONNX face enhancer

* Disable CoreML for the ONNX face enhancer

* Predict webcam too

* Improve resize of preview

* Change output quality defaults, Move options to the right

* Support for codeformer model

* Update the typo

* Add GPEN and GFPGAN 1.2

* Extract blend_frame methods

* Extend the installer

* Revert broken Gradio

* Rework on ui components

* Move output path selector to the output options

* Remove tons of pointless component updates

* Reset more base theme styling

* Use latest Gradio

* Fix the sliders

* More styles

* Update torch to 2.1.0

* Add RealESRNet_x4plus

* Fix that button

* Use latest onnxruntime-silicon

* Looks stable to me

* Lowercase model keys, Update preview and readme
This commit is contained in:
Henry Ruhs
2023-10-09 10:16:13 +02:00
committed by GitHub
parent 3e361e7701
commit a6809c3ccb
53 changed files with 1105 additions and 563 deletions

View File

@@ -1,12 +1,23 @@
from typing import Optional
import gradio
from facefusion import metadata
from facefusion import metadata, wording
ABOUT_HTML : Optional[gradio.HTML] = None
ABOUT_BUTTON : Optional[gradio.HTML] = None
DONATE_BUTTON : Optional[gradio.HTML] = None
def render() -> None:
global ABOUT_HTML
global ABOUT_BUTTON
global DONATE_BUTTON
ABOUT_HTML = gradio.HTML('<center><a href="' + metadata.get('url') + '">' + metadata.get('name') + ' ' + metadata.get('version') + '</a></center>')
ABOUT_BUTTON = gradio.Button(
value = metadata.get('name') + ' ' + metadata.get('version'),
variant = 'primary',
link = metadata.get('url')
)
DONATE_BUTTON = gradio.Button(
value = wording.get('donate_button_label'),
link = 'https://donate.facefusion.io',
size = 'sm'
)

View File

@@ -11,9 +11,8 @@ from facefusion.face_cache import clear_faces_cache
from facefusion.processors.frame.core import get_frame_processors_modules
from facefusion.vision import count_video_frame_total
from facefusion.core import limit_resources, conditional_process
from facefusion.uis.typing import Update
from facefusion.uis import core as ui
from facefusion.utilities import normalize_output_path, clear_temp
from facefusion.uis.core import get_ui_component
BENCHMARK_RESULTS_DATAFRAME : Optional[gradio.Dataframe] = None
BENCHMARK_START_BUTTON : Optional[gradio.Button] = None
@@ -58,16 +57,18 @@ def render() -> None:
)
BENCHMARK_START_BUTTON = gradio.Button(
value = wording.get('start_button_label'),
variant = 'primary'
variant = 'primary',
size = 'sm'
)
BENCHMARK_CLEAR_BUTTON = gradio.Button(
value = wording.get('clear_button_label')
value = wording.get('clear_button_label'),
size = 'sm'
)
def listen() -> None:
benchmark_runs_checkbox_group = ui.get_component('benchmark_runs_checkbox_group')
benchmark_cycles_slider = ui.get_component('benchmark_cycles_slider')
benchmark_runs_checkbox_group = get_ui_component('benchmark_runs_checkbox_group')
benchmark_cycles_slider = get_ui_component('benchmark_cycles_slider')
if benchmark_runs_checkbox_group and benchmark_cycles_slider:
BENCHMARK_START_BUTTON.click(start, inputs = [ benchmark_runs_checkbox_group, benchmark_cycles_slider ], outputs = BENCHMARK_RESULTS_DATAFRAME)
BENCHMARK_CLEAR_BUTTON.click(clear, outputs = BENCHMARK_RESULTS_DATAFRAME)
@@ -124,7 +125,7 @@ def benchmark(target_path : str, benchmark_cycles : int) -> List[Any]:
]
def clear() -> Update:
def clear() -> gradio.Dataframe:
if facefusion.globals.target_path:
clear_temp(facefusion.globals.target_path)
return gradio.update(value = None)
return gradio.Dataframe(value = None)

View File

@@ -1,9 +1,8 @@
from typing import Optional, List
from typing import Optional
import gradio
from facefusion import wording
from facefusion.uis.typing import Update
from facefusion.uis import core as ui
from facefusion.uis.core import register_ui_component
from facefusion.uis.components.benchmark import BENCHMARKS
BENCHMARK_RUNS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
@@ -21,18 +20,10 @@ def render() -> None:
)
BENCHMARK_CYCLES_SLIDER = gradio.Slider(
label = wording.get('benchmark_cycles_slider_label'),
minimum = 1,
step = 1,
value = 3,
step = 1,
minimum = 1,
maximum = 10
)
ui.register_component('benchmark_runs_checkbox_group', BENCHMARK_RUNS_CHECKBOX_GROUP)
ui.register_component('benchmark_cycles_slider', BENCHMARK_CYCLES_SLIDER)
def listen() -> None:
BENCHMARK_RUNS_CHECKBOX_GROUP.change(update_benchmark_runs, inputs = BENCHMARK_RUNS_CHECKBOX_GROUP, outputs = BENCHMARK_RUNS_CHECKBOX_GROUP)
def update_benchmark_runs(benchmark_runs : List[str]) -> Update:
return gradio.update(value = benchmark_runs)
register_ui_component('benchmark_runs_checkbox_group', BENCHMARK_RUNS_CHECKBOX_GROUP)
register_ui_component('benchmark_cycles_slider', BENCHMARK_CYCLES_SLIDER)

View File

@@ -0,0 +1,38 @@
from typing import Optional, List
import gradio
import facefusion.globals
from facefusion import wording
from facefusion.uis import choices
COMMON_OPTIONS_CHECKBOX_GROUP : Optional[gradio.Checkboxgroup] = None
def render() -> None:
global COMMON_OPTIONS_CHECKBOX_GROUP
value = []
if facefusion.globals.keep_fps:
value.append('keep-fps')
if facefusion.globals.keep_temp:
value.append('keep-temp')
if facefusion.globals.skip_audio:
value.append('skip-audio')
if facefusion.globals.skip_download:
value.append('skip-download')
COMMON_OPTIONS_CHECKBOX_GROUP = gradio.Checkboxgroup(
label = wording.get('common_options_checkbox_group_label'),
choices = choices.common_options,
value = value
)
def listen() -> None:
COMMON_OPTIONS_CHECKBOX_GROUP.change(update, inputs = COMMON_OPTIONS_CHECKBOX_GROUP)
def update(common_options : List[str]) -> None:
facefusion.globals.keep_fps = 'keep-fps' in common_options
facefusion.globals.keep_temp = 'keep-temp' in common_options
facefusion.globals.skip_audio = 'skip-audio' in common_options
facefusion.globals.skip_download = 'skip-download' in common_options

View File

@@ -6,7 +6,6 @@ import facefusion.globals
from facefusion import wording
from facefusion.face_analyser import clear_face_analyser
from facefusion.processors.frame.core import clear_frame_processors_modules
from facefusion.uis.typing import Update
from facefusion.utilities import encode_execution_providers, decode_execution_providers
EXECUTION_PROVIDERS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
@@ -26,10 +25,10 @@ def listen() -> None:
EXECUTION_PROVIDERS_CHECKBOX_GROUP.change(update_execution_providers, inputs = EXECUTION_PROVIDERS_CHECKBOX_GROUP, outputs = EXECUTION_PROVIDERS_CHECKBOX_GROUP)
def update_execution_providers(execution_providers : List[str]) -> Update:
def update_execution_providers(execution_providers : List[str]) -> gradio.CheckboxGroup:
clear_face_analyser()
clear_frame_processors_modules()
if not execution_providers:
execution_providers = encode_execution_providers(onnxruntime.get_available_providers())
facefusion.globals.execution_providers = decode_execution_providers(execution_providers)
return gradio.update(value = execution_providers)
return gradio.CheckboxGroup(value = execution_providers)

View File

@@ -3,7 +3,6 @@ import gradio
import facefusion.globals
from facefusion import wording
from facefusion.uis.typing import Update
EXECUTION_QUEUE_COUNT_SLIDER : Optional[gradio.Slider] = None
@@ -21,9 +20,9 @@ def render() -> None:
def listen() -> None:
EXECUTION_QUEUE_COUNT_SLIDER.change(update_execution_queue_count, inputs = EXECUTION_QUEUE_COUNT_SLIDER, outputs = EXECUTION_QUEUE_COUNT_SLIDER)
EXECUTION_QUEUE_COUNT_SLIDER.change(update_execution_queue_count, inputs = EXECUTION_QUEUE_COUNT_SLIDER)
def update_execution_queue_count(execution_queue_count : int = 1) -> Update:
def update_execution_queue_count(execution_queue_count : int = 1) -> None:
facefusion.globals.execution_queue_count = execution_queue_count
return gradio.update(value = execution_queue_count)

View File

@@ -3,7 +3,6 @@ import gradio
import facefusion.globals
from facefusion import wording
from facefusion.uis.typing import Update
EXECUTION_THREAD_COUNT_SLIDER : Optional[gradio.Slider] = None
@@ -21,9 +20,9 @@ def render() -> None:
def listen() -> None:
EXECUTION_THREAD_COUNT_SLIDER.change(update_execution_thread_count, inputs = EXECUTION_THREAD_COUNT_SLIDER, outputs = EXECUTION_THREAD_COUNT_SLIDER)
EXECUTION_THREAD_COUNT_SLIDER.change(update_execution_thread_count, inputs = EXECUTION_THREAD_COUNT_SLIDER)
def update_execution_thread_count(execution_thread_count : int = 1) -> Update:
def update_execution_thread_count(execution_thread_count : int = 1) -> None:
facefusion.globals.execution_thread_count = execution_thread_count
return gradio.update(value = execution_thread_count)

View File

@@ -5,8 +5,7 @@ import gradio
import facefusion.choices
import facefusion.globals
from facefusion import wording
from facefusion.uis import core as ui
from facefusion.uis.typing import Update
from facefusion.uis.core import register_ui_component
FACE_ANALYSER_DIRECTION_DROPDOWN : Optional[gradio.Dropdown] = None
FACE_ANALYSER_AGE_DROPDOWN : Optional[gradio.Dropdown] = None
@@ -20,33 +19,32 @@ def render() -> None:
FACE_ANALYSER_DIRECTION_DROPDOWN = gradio.Dropdown(
label = wording.get('face_analyser_direction_dropdown_label'),
choices = facefusion.choices.face_analyser_direction,
choices = facefusion.choices.face_analyser_directions,
value = facefusion.globals.face_analyser_direction
)
FACE_ANALYSER_AGE_DROPDOWN = gradio.Dropdown(
label = wording.get('face_analyser_age_dropdown_label'),
choices = ['none'] + facefusion.choices.face_analyser_age,
choices = ['none'] + facefusion.choices.face_analyser_ages,
value = facefusion.globals.face_analyser_age or 'none'
)
FACE_ANALYSER_GENDER_DROPDOWN = gradio.Dropdown(
label = wording.get('face_analyser_gender_dropdown_label'),
choices = ['none'] + facefusion.choices.face_analyser_gender,
choices = ['none'] + facefusion.choices.face_analyser_genders,
value = facefusion.globals.face_analyser_gender or 'none'
)
ui.register_component('face_analyser_direction_dropdown', FACE_ANALYSER_DIRECTION_DROPDOWN)
ui.register_component('face_analyser_age_dropdown', FACE_ANALYSER_AGE_DROPDOWN)
ui.register_component('face_analyser_gender_dropdown', FACE_ANALYSER_GENDER_DROPDOWN)
register_ui_component('face_analyser_direction_dropdown', FACE_ANALYSER_DIRECTION_DROPDOWN)
register_ui_component('face_analyser_age_dropdown', FACE_ANALYSER_AGE_DROPDOWN)
register_ui_component('face_analyser_gender_dropdown', FACE_ANALYSER_GENDER_DROPDOWN)
def listen() -> None:
FACE_ANALYSER_DIRECTION_DROPDOWN.select(lambda value: update_dropdown('face_analyser_direction', value), inputs = FACE_ANALYSER_DIRECTION_DROPDOWN, outputs = FACE_ANALYSER_DIRECTION_DROPDOWN)
FACE_ANALYSER_AGE_DROPDOWN.select(lambda value: update_dropdown('face_analyser_age', value), inputs = FACE_ANALYSER_AGE_DROPDOWN, outputs = FACE_ANALYSER_AGE_DROPDOWN)
FACE_ANALYSER_GENDER_DROPDOWN.select(lambda value: update_dropdown('face_analyser_gender', value), inputs = FACE_ANALYSER_GENDER_DROPDOWN, outputs = FACE_ANALYSER_GENDER_DROPDOWN)
FACE_ANALYSER_DIRECTION_DROPDOWN.select(lambda value: update_dropdown('face_analyser_direction', value), inputs = FACE_ANALYSER_DIRECTION_DROPDOWN)
FACE_ANALYSER_AGE_DROPDOWN.select(lambda value: update_dropdown('face_analyser_age', value), inputs = FACE_ANALYSER_AGE_DROPDOWN)
FACE_ANALYSER_GENDER_DROPDOWN.select(lambda value: update_dropdown('face_analyser_gender', value), inputs = FACE_ANALYSER_GENDER_DROPDOWN)
def update_dropdown(name : str, value : str) -> Update:
def update_dropdown(name : str, value : str) -> None:
if value == 'none':
setattr(facefusion.globals, name, None)
else:
setattr(facefusion.globals, name, value)
return gradio.update(value = value)

View File

@@ -9,9 +9,9 @@ from facefusion.vision import get_video_frame, normalize_frame_color, read_stati
from facefusion.face_analyser import get_many_faces
from facefusion.face_reference import clear_face_reference
from facefusion.typing import Frame, FaceRecognition
from facefusion.uis import core as ui
from facefusion.uis.typing import ComponentName, Update
from facefusion.utilities import is_image, is_video
from facefusion.uis.core import get_ui_component, register_ui_component
from facefusion.uis.typing import ComponentName
FACE_RECOGNITION_DROPDOWN : Optional[gradio.Dropdown] = None
REFERENCE_FACE_POSITION_GALLERY : Optional[gradio.Gallery] = None
@@ -40,20 +40,21 @@ def render() -> None:
reference_face_gallery_args['value'] = extract_gallery_frames(reference_frame)
FACE_RECOGNITION_DROPDOWN = gradio.Dropdown(
label = wording.get('face_recognition_dropdown_label'),
choices = facefusion.choices.face_recognition,
choices = facefusion.choices.face_recognitions,
value = facefusion.globals.face_recognition
)
REFERENCE_FACE_POSITION_GALLERY = gradio.Gallery(**reference_face_gallery_args)
REFERENCE_FACE_DISTANCE_SLIDER = gradio.Slider(
label = wording.get('reference_face_distance_slider_label'),
value = facefusion.globals.reference_face_distance,
maximum = 3,
step = 0.05,
minimum = 0,
maximum = 3,
visible = 'reference' in facefusion.globals.face_recognition
)
ui.register_component('face_recognition_dropdown', FACE_RECOGNITION_DROPDOWN)
ui.register_component('reference_face_position_gallery', REFERENCE_FACE_POSITION_GALLERY)
ui.register_component('reference_face_distance_slider', REFERENCE_FACE_DISTANCE_SLIDER)
register_ui_component('face_recognition_dropdown', FACE_RECOGNITION_DROPDOWN)
register_ui_component('reference_face_position_gallery', REFERENCE_FACE_POSITION_GALLERY)
register_ui_component('reference_face_distance_slider', REFERENCE_FACE_DISTANCE_SLIDER)
def listen() -> None:
@@ -67,7 +68,7 @@ def listen() -> None:
'target_video'
]
for component_name in multi_component_names:
component = ui.get_component(component_name)
component = get_ui_component(component_name)
if component:
for method in [ 'upload', 'change', 'clear' ]:
getattr(component, method)(update_face_reference_position, outputs = REFERENCE_FACE_POSITION_GALLERY)
@@ -78,29 +79,29 @@ def listen() -> None:
'face_analyser_gender_dropdown'
]
for component_name in select_component_names:
component = ui.get_component(component_name)
component = get_ui_component(component_name)
if component:
component.select(update_face_reference_position, outputs = REFERENCE_FACE_POSITION_GALLERY)
preview_frame_slider = ui.get_component('preview_frame_slider')
preview_frame_slider = get_ui_component('preview_frame_slider')
if preview_frame_slider:
preview_frame_slider.release(update_face_reference_position, outputs = REFERENCE_FACE_POSITION_GALLERY)
def update_face_recognition(face_recognition : FaceRecognition) -> Tuple[Update, Update]:
def update_face_recognition(face_recognition : FaceRecognition) -> Tuple[gradio.Gallery, gradio.Slider]:
if face_recognition == 'reference':
facefusion.globals.face_recognition = face_recognition
return gradio.update(visible = True), gradio.update(visible = True)
return gradio.Gallery(visible = True), gradio.Slider(visible = True)
if face_recognition == 'many':
facefusion.globals.face_recognition = face_recognition
return gradio.update(visible = False), gradio.update(visible = False)
return gradio.Gallery(visible = False), gradio.Slider(visible = False)
def clear_and_update_face_reference_position(event: gradio.SelectData) -> Update:
def clear_and_update_face_reference_position(event: gradio.SelectData) -> gradio.Gallery:
clear_face_reference()
return update_face_reference_position(event.index)
def update_face_reference_position(reference_face_position : int = 0) -> Update:
def update_face_reference_position(reference_face_position : int = 0) -> gradio.Gallery:
gallery_frames = []
facefusion.globals.reference_face_position = reference_face_position
if is_image(facefusion.globals.target_path):
@@ -110,13 +111,12 @@ def update_face_reference_position(reference_face_position : int = 0) -> Update:
reference_frame = get_video_frame(facefusion.globals.target_path, facefusion.globals.reference_frame_number)
gallery_frames = extract_gallery_frames(reference_frame)
if gallery_frames:
return gradio.update(value = gallery_frames)
return gradio.update(value = None)
return gradio.Gallery(value = gallery_frames)
return gradio.Gallery(value = None)
def update_reference_face_distance(reference_face_distance : float) -> Update:
def update_reference_face_distance(reference_face_distance : float) -> None:
facefusion.globals.reference_face_distance = reference_face_distance
return gradio.update(value = reference_face_distance)
def extract_gallery_frames(reference_frame : Frame) -> List[Frame]:

View File

@@ -4,9 +4,8 @@ import gradio
import facefusion.globals
from facefusion import wording
from facefusion.processors.frame.core import load_frame_processor_module, clear_frame_processors_modules
from facefusion.uis import core as ui
from facefusion.uis.typing import Update
from facefusion.utilities import list_module_names
from facefusion.uis.core import register_ui_component
FRAME_PROCESSORS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
@@ -19,23 +18,23 @@ def render() -> None:
choices = sort_frame_processors(facefusion.globals.frame_processors),
value = facefusion.globals.frame_processors
)
ui.register_component('frame_processors_checkbox_group', FRAME_PROCESSORS_CHECKBOX_GROUP)
register_ui_component('frame_processors_checkbox_group', FRAME_PROCESSORS_CHECKBOX_GROUP)
def listen() -> None:
FRAME_PROCESSORS_CHECKBOX_GROUP.change(update_frame_processors, inputs = FRAME_PROCESSORS_CHECKBOX_GROUP, outputs = FRAME_PROCESSORS_CHECKBOX_GROUP)
def update_frame_processors(frame_processors : List[str]) -> Update:
clear_frame_processors_modules()
def update_frame_processors(frame_processors : List[str]) -> gradio.CheckboxGroup:
facefusion.globals.frame_processors = frame_processors
clear_frame_processors_modules()
for frame_processor in frame_processors:
frame_processor_module = load_frame_processor_module(frame_processor)
if not frame_processor_module.pre_check():
return gradio.update()
return gradio.update(value = frame_processors, choices = sort_frame_processors(frame_processors))
return gradio.CheckboxGroup()
return gradio.CheckboxGroup(value = frame_processors, choices = sort_frame_processors(frame_processors))
def sort_frame_processors(frame_processors : List[str]) -> list[str]:
frame_processors_names = list_module_names('facefusion/processors/frame/modules')
return sorted(frame_processors_names, key = lambda frame_processor : frame_processors.index(frame_processor) if frame_processor in frame_processors else len(frame_processors))
available_frame_processors = list_module_names('facefusion/processors/frame/modules')
return sorted(available_frame_processors, key = lambda frame_processor : frame_processors.index(frame_processor) if frame_processor in frame_processors else len(frame_processors))

View File

@@ -0,0 +1,118 @@
from typing import List, Optional, Tuple
import gradio
import facefusion.globals
from facefusion import wording
from facefusion.processors.frame.core import load_frame_processor_module
from facefusion.processors.frame import globals as frame_processors_globals, choices as frame_processors_choices
from facefusion.uis.core import get_ui_component, register_ui_component
FACE_SWAPPER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
FACE_ENHANCER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
FACE_ENHANCER_BLEND_SLIDER : Optional[gradio.Slider] = None
FRAME_ENHANCER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
FRAME_ENHANCER_BLEND_SLIDER : Optional[gradio.Slider] = None
def render() -> None:
global FACE_SWAPPER_MODEL_DROPDOWN
global FACE_ENHANCER_MODEL_DROPDOWN
global FACE_ENHANCER_BLEND_SLIDER
global FRAME_ENHANCER_MODEL_DROPDOWN
global FRAME_ENHANCER_BLEND_SLIDER
FACE_SWAPPER_MODEL_DROPDOWN = gradio.Dropdown(
label = wording.get('face_swapper_model_dropdown_label'),
choices = frame_processors_choices.face_swapper_models,
value = frame_processors_globals.face_swapper_model,
visible = 'face_swapper' in facefusion.globals.frame_processors
)
FACE_ENHANCER_MODEL_DROPDOWN = gradio.Dropdown(
label = wording.get('face_enhancer_model_dropdown_label'),
choices = frame_processors_choices.face_enhancer_models,
value = frame_processors_globals.face_enhancer_model,
visible = 'face_enhancer' in facefusion.globals.frame_processors
)
FACE_ENHANCER_BLEND_SLIDER = gradio.Slider(
label = wording.get('face_enhancer_blend_slider_label'),
value = frame_processors_globals.face_enhancer_blend,
step = 1,
minimum = 0,
maximum = 100,
visible = 'face_enhancer' in facefusion.globals.frame_processors
)
FRAME_ENHANCER_MODEL_DROPDOWN = gradio.Dropdown(
label = wording.get('frame_enhancer_model_dropdown_label'),
choices = frame_processors_choices.frame_enhancer_models,
value = frame_processors_globals.frame_enhancer_model,
visible = 'frame_enhancer' in facefusion.globals.frame_processors
)
FRAME_ENHANCER_BLEND_SLIDER = gradio.Slider(
label = wording.get('frame_enhancer_blend_slider_label'),
value = frame_processors_globals.frame_enhancer_blend,
step = 1,
minimum = 0,
maximum = 100,
visible = 'face_enhancer' in facefusion.globals.frame_processors
)
register_ui_component('face_swapper_model_dropdown', FACE_SWAPPER_MODEL_DROPDOWN)
register_ui_component('face_enhancer_model_dropdown', FACE_ENHANCER_MODEL_DROPDOWN)
register_ui_component('face_enhancer_blend_slider', FACE_ENHANCER_BLEND_SLIDER)
register_ui_component('frame_enhancer_model_dropdown', FRAME_ENHANCER_MODEL_DROPDOWN)
register_ui_component('frame_enhancer_blend_slider', FRAME_ENHANCER_BLEND_SLIDER)
def listen() -> None:
FACE_SWAPPER_MODEL_DROPDOWN.change(update_face_swapper_model, inputs = FACE_SWAPPER_MODEL_DROPDOWN, outputs = FACE_SWAPPER_MODEL_DROPDOWN)
FACE_ENHANCER_MODEL_DROPDOWN.change(update_face_enhancer_model, inputs = FACE_ENHANCER_MODEL_DROPDOWN, outputs = FACE_ENHANCER_MODEL_DROPDOWN)
FACE_ENHANCER_BLEND_SLIDER.change(update_face_enhancer_blend, inputs = FACE_ENHANCER_BLEND_SLIDER)
FRAME_ENHANCER_MODEL_DROPDOWN.change(update_frame_enhancer_model, inputs = FRAME_ENHANCER_MODEL_DROPDOWN, outputs = FRAME_ENHANCER_MODEL_DROPDOWN)
FRAME_ENHANCER_BLEND_SLIDER.change(update_frame_enhancer_blend, inputs = FRAME_ENHANCER_BLEND_SLIDER)
frame_processors_checkbox_group = get_ui_component('frame_processors_checkbox_group')
if frame_processors_checkbox_group:
frame_processors_checkbox_group.change(toggle_face_swapper_model, inputs = frame_processors_checkbox_group, outputs = [ FACE_SWAPPER_MODEL_DROPDOWN, FACE_ENHANCER_MODEL_DROPDOWN, FACE_ENHANCER_BLEND_SLIDER, FRAME_ENHANCER_MODEL_DROPDOWN, FRAME_ENHANCER_BLEND_SLIDER ])
def update_face_swapper_model(face_swapper_model : str) -> gradio.Dropdown:
frame_processors_globals.face_swapper_model = face_swapper_model
face_swapper_module = load_frame_processor_module('face_swapper')
face_swapper_module.clear_frame_processor()
face_swapper_module.set_options('model', face_swapper_module.MODELS[face_swapper_model])
if not face_swapper_module.pre_check():
return gradio.Dropdown()
return gradio.Dropdown(value = face_swapper_model)
def update_face_enhancer_model(face_enhancer_model : str) -> gradio.Dropdown:
frame_processors_globals.face_enhancer_model = face_enhancer_model
face_enhancer_module = load_frame_processor_module('face_enhancer')
face_enhancer_module.clear_frame_processor()
face_enhancer_module.set_options('model', face_enhancer_module.MODELS[face_enhancer_model])
if not face_enhancer_module.pre_check():
return gradio.Dropdown()
return gradio.Dropdown(value = face_enhancer_model)
def update_face_enhancer_blend(face_enhancer_blend : int) -> None:
frame_processors_globals.face_enhancer_blend = face_enhancer_blend
def update_frame_enhancer_model(frame_enhancer_model : str) -> gradio.Dropdown:
frame_processors_globals.frame_enhancer_model = frame_enhancer_model
frame_enhancer_module = load_frame_processor_module('frame_enhancer')
frame_enhancer_module.clear_frame_processor()
frame_enhancer_module.set_options('model', frame_enhancer_module.MODELS[frame_enhancer_model])
if not frame_enhancer_module.pre_check():
return gradio.Dropdown()
return gradio.Dropdown(value = frame_enhancer_model)
def update_frame_enhancer_blend(frame_enhancer_blend : int) -> None:
frame_processors_globals.frame_enhancer_blend = frame_enhancer_blend
def toggle_face_swapper_model(frame_processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Dropdown, gradio.Slider, gradio.Dropdown, gradio.Slider]:
has_face_swapper = 'face_swapper' in frame_processors
has_face_enhancer = 'face_enhancer' in frame_processors
has_frame_enhancer = 'frame_enhancer' in frame_processors
return gradio.Dropdown(visible = has_face_swapper), gradio.Dropdown(visible = has_face_enhancer), gradio.Slider(visible = has_face_enhancer), gradio.Dropdown(visible = has_frame_enhancer), gradio.Slider(visible = has_frame_enhancer)

View File

@@ -3,7 +3,6 @@ import gradio
import facefusion.globals
from facefusion import wording
from facefusion.uis.typing import Update
MAX_MEMORY_SLIDER : Optional[gradio.Slider] = None
@@ -13,16 +12,15 @@ def render() -> None:
MAX_MEMORY_SLIDER = gradio.Slider(
label = wording.get('max_memory_slider_label'),
step = 1,
minimum = 0,
maximum = 128,
step = 1
maximum = 128
)
def listen() -> None:
MAX_MEMORY_SLIDER.change(update_max_memory, inputs = MAX_MEMORY_SLIDER, outputs = MAX_MEMORY_SLIDER)
MAX_MEMORY_SLIDER.change(update_max_memory, inputs = MAX_MEMORY_SLIDER)
def update_max_memory(max_memory : int) -> Update:
def update_max_memory(max_memory : int) -> None:
facefusion.globals.max_memory = max_memory if max_memory > 0 else None
return gradio.update(value = max_memory)

View File

@@ -1,16 +1,14 @@
import tempfile
from typing import Tuple, Optional
import gradio
import facefusion.globals
from facefusion import wording
from facefusion.core import limit_resources, conditional_process
from facefusion.uis.typing import Update
from facefusion.uis.core import get_ui_component
from facefusion.utilities import is_image, is_video, normalize_output_path, clear_temp
OUTPUT_IMAGE : Optional[gradio.Image] = None
OUTPUT_VIDEO : Optional[gradio.Video] = None
OUTPUT_PATH_TEXTBOX : Optional[gradio.Textbox] = None
OUTPUT_START_BUTTON : Optional[gradio.Button] = None
OUTPUT_CLEAR_BUTTON : Optional[gradio.Button] = None
@@ -18,7 +16,6 @@ OUTPUT_CLEAR_BUTTON : Optional[gradio.Button] = None
def render() -> None:
global OUTPUT_IMAGE
global OUTPUT_VIDEO
global OUTPUT_PATH_TEXTBOX
global OUTPUT_START_BUTTON
global OUTPUT_CLEAR_BUTTON
@@ -29,43 +26,36 @@ def render() -> None:
OUTPUT_VIDEO = gradio.Video(
label = wording.get('output_image_or_video_label')
)
OUTPUT_PATH_TEXTBOX = gradio.Textbox(
label = wording.get('output_path_textbox_label'),
value = facefusion.globals.output_path or tempfile.gettempdir(),
max_lines = 1
)
OUTPUT_START_BUTTON = gradio.Button(
value = wording.get('start_button_label'),
variant = 'primary'
variant = 'primary',
size = 'sm'
)
OUTPUT_CLEAR_BUTTON = gradio.Button(
value = wording.get('clear_button_label'),
size = 'sm'
)
def listen() -> None:
OUTPUT_PATH_TEXTBOX.change(update_output_path, inputs = OUTPUT_PATH_TEXTBOX, outputs = OUTPUT_PATH_TEXTBOX)
OUTPUT_START_BUTTON.click(start, inputs = OUTPUT_PATH_TEXTBOX, outputs = [ OUTPUT_IMAGE, OUTPUT_VIDEO ])
output_path_textbox = get_ui_component('output_path_textbox')
if output_path_textbox:
OUTPUT_START_BUTTON.click(start, inputs = output_path_textbox, outputs = [ OUTPUT_IMAGE, OUTPUT_VIDEO ])
OUTPUT_CLEAR_BUTTON.click(clear, outputs = [ OUTPUT_IMAGE, OUTPUT_VIDEO ])
def start(output_path : str) -> Tuple[Update, Update]:
def start(output_path : str) -> Tuple[gradio.Image, gradio.Video]:
facefusion.globals.output_path = normalize_output_path(facefusion.globals.source_path, facefusion.globals.target_path, output_path)
limit_resources()
conditional_process()
if is_image(facefusion.globals.output_path):
return gradio.update(value = facefusion.globals.output_path, visible = True), gradio.update(value = None, visible = False)
return gradio.Image(value = facefusion.globals.output_path, visible = True), gradio.Video(value = None, visible = False)
if is_video(facefusion.globals.output_path):
return gradio.update(value = None, visible = False), gradio.update(value = facefusion.globals.output_path, visible = True)
return gradio.update(), gradio.update()
return gradio.Image(value = None, visible = False), gradio.Video(value = facefusion.globals.output_path, visible = True)
return gradio.Image(), gradio.Video()
def update_output_path(output_path : str) -> Update:
facefusion.globals.output_path = output_path
return gradio.update(value = output_path)
def clear() -> Tuple[Update, Update]:
def clear() -> Tuple[gradio.Image, gradio.Video]:
if facefusion.globals.target_path:
clear_temp(facefusion.globals.target_path)
return gradio.update(value = None), gradio.update(value = None)
return gradio.Image(value = None), gradio.Video(value = None)

View File

@@ -1,33 +1,43 @@
from typing import Optional, Tuple, List
import tempfile
import gradio
import facefusion.choices
import facefusion.globals
from facefusion import wording
from facefusion.typing import OutputVideoEncoder
from facefusion.uis import core as ui
from facefusion.uis.typing import Update, ComponentName
from facefusion.utilities import is_image, is_video
from facefusion.uis.typing import ComponentName
from facefusion.uis.core import get_ui_component, register_ui_component
OUTPUT_PATH_TEXTBOX : Optional[gradio.Textbox] = None
OUTPUT_IMAGE_QUALITY_SLIDER : Optional[gradio.Slider] = None
OUTPUT_VIDEO_ENCODER_DROPDOWN : Optional[gradio.Dropdown] = None
OUTPUT_VIDEO_QUALITY_SLIDER : Optional[gradio.Slider] = None
def render() -> None:
global OUTPUT_PATH_TEXTBOX
global OUTPUT_IMAGE_QUALITY_SLIDER
global OUTPUT_VIDEO_ENCODER_DROPDOWN
global OUTPUT_VIDEO_QUALITY_SLIDER
OUTPUT_PATH_TEXTBOX = gradio.Textbox(
label = wording.get('output_path_textbox_label'),
value = facefusion.globals.output_path or tempfile.gettempdir(),
max_lines = 1
)
OUTPUT_IMAGE_QUALITY_SLIDER = gradio.Slider(
label = wording.get('output_image_quality_slider_label'),
value = facefusion.globals.output_image_quality,
step = 1,
minimum = 0,
maximum = 100,
visible = is_image(facefusion.globals.target_path)
)
OUTPUT_VIDEO_ENCODER_DROPDOWN = gradio.Dropdown(
label = wording.get('output_video_encoder_dropdown_label'),
choices = facefusion.choices.output_video_encoder,
choices = facefusion.choices.output_video_encoders,
value = facefusion.globals.output_video_encoder,
visible = is_video(facefusion.globals.target_path)
)
@@ -35,14 +45,18 @@ def render() -> None:
label = wording.get('output_video_quality_slider_label'),
value = facefusion.globals.output_video_quality,
step = 1,
minimum = 0,
maximum = 100,
visible = is_video(facefusion.globals.target_path)
)
register_ui_component('output_path_textbox', OUTPUT_PATH_TEXTBOX)
def listen() -> None:
OUTPUT_IMAGE_QUALITY_SLIDER.change(update_output_image_quality, inputs = OUTPUT_IMAGE_QUALITY_SLIDER, outputs = OUTPUT_IMAGE_QUALITY_SLIDER)
OUTPUT_VIDEO_ENCODER_DROPDOWN.select(update_output_video_encoder, inputs = OUTPUT_VIDEO_ENCODER_DROPDOWN, outputs = OUTPUT_VIDEO_ENCODER_DROPDOWN)
OUTPUT_VIDEO_QUALITY_SLIDER.change(update_output_video_quality, inputs = OUTPUT_VIDEO_QUALITY_SLIDER, outputs = OUTPUT_VIDEO_QUALITY_SLIDER)
OUTPUT_PATH_TEXTBOX.change(update_output_path, inputs = OUTPUT_PATH_TEXTBOX)
OUTPUT_IMAGE_QUALITY_SLIDER.change(update_output_image_quality, inputs = OUTPUT_IMAGE_QUALITY_SLIDER)
OUTPUT_VIDEO_ENCODER_DROPDOWN.select(update_output_video_encoder, inputs = OUTPUT_VIDEO_ENCODER_DROPDOWN)
OUTPUT_VIDEO_QUALITY_SLIDER.change(update_output_video_quality, inputs = OUTPUT_VIDEO_QUALITY_SLIDER)
multi_component_names : List[ComponentName] =\
[
'source_image',
@@ -50,30 +64,31 @@ def listen() -> None:
'target_video'
]
for component_name in multi_component_names:
component = ui.get_component(component_name)
component = get_ui_component(component_name)
if component:
for method in [ 'upload', 'change', 'clear' ]:
getattr(component, method)(remote_update, outputs = [ OUTPUT_IMAGE_QUALITY_SLIDER, OUTPUT_VIDEO_ENCODER_DROPDOWN, OUTPUT_VIDEO_QUALITY_SLIDER ])
def remote_update() -> Tuple[Update, Update, Update]:
def remote_update() -> Tuple[gradio.Slider, gradio.Dropdown, gradio.Slider]:
if is_image(facefusion.globals.target_path):
return gradio.update(visible = True), gradio.update(visible = False), gradio.update(visible = False)
return gradio.Slider(visible = True), gradio.Dropdown(visible = False), gradio.Slider(visible = False)
if is_video(facefusion.globals.target_path):
return gradio.update(visible = False), gradio.update(visible = True), gradio.update(visible = True)
return gradio.update(visible = False), gradio.update(visible = False), gradio.update(visible = False)
return gradio.Slider(visible = False), gradio.Dropdown(visible = True), gradio.Slider(visible = True)
return gradio.Slider(visible = False), gradio.Dropdown(visible = False), gradio.Slider(visible = False)
def update_output_image_quality(output_image_quality : int) -> Update:
def update_output_path(output_path : str) -> None:
facefusion.globals.output_path = output_path
def update_output_image_quality(output_image_quality : int) -> None:
facefusion.globals.output_image_quality = output_image_quality
return gradio.update(value = output_image_quality)
def update_output_video_encoder(output_video_encoder: OutputVideoEncoder) -> Update:
def update_output_video_encoder(output_video_encoder: OutputVideoEncoder) -> None:
facefusion.globals.output_video_encoder = output_video_encoder
return gradio.update(value = output_video_encoder)
def update_output_video_quality(output_video_quality : int) -> Update:
def update_output_video_quality(output_video_quality : int) -> None:
facefusion.globals.output_video_quality = output_video_quality
return gradio.update(value = output_video_quality)

View File

@@ -4,15 +4,15 @@ import gradio
import facefusion.globals
from facefusion import wording
from facefusion.typing import Frame, Face
from facefusion.vision import get_video_frame, count_video_frame_total, normalize_frame_color, resize_frame_dimension, read_static_image
from facefusion.face_analyser import get_one_face
from facefusion.face_reference import get_face_reference, set_face_reference
from facefusion.predictor import predict_frame
from facefusion.processors.frame.core import load_frame_processor_module
from facefusion.typing import Frame, Face
from facefusion.uis import core as ui
from facefusion.uis.typing import ComponentName, Update
from facefusion.utilities import is_video, is_image
from facefusion.uis.typing import ComponentName
from facefusion.uis.core import get_ui_component, register_ui_component
PREVIEW_IMAGE : Optional[gradio.Image] = None
PREVIEW_FRAME_SLIDER : Optional[gradio.Slider] = None
@@ -24,12 +24,15 @@ def render() -> None:
preview_image_args: Dict[str, Any] =\
{
'label': wording.get('preview_image_label')
'label': wording.get('preview_image_label'),
'interactive': False
}
preview_frame_slider_args: Dict[str, Any] =\
{
'label': wording.get('preview_frame_slider_label'),
'step': 1,
'minimum': 0,
'maximum': 100,
'visible': False
}
conditional_set_face_reference()
@@ -49,7 +52,7 @@ def render() -> None:
preview_frame_slider_args['visible'] = True
PREVIEW_IMAGE = gradio.Image(**preview_image_args)
PREVIEW_FRAME_SLIDER = gradio.Slider(**preview_frame_slider_args)
ui.register_component('preview_frame_slider', PREVIEW_FRAME_SLIDER)
register_ui_component('preview_frame_slider', PREVIEW_FRAME_SLIDER)
def listen() -> None:
@@ -61,7 +64,7 @@ def listen() -> None:
'target_video'
]
for component_name in multi_component_names:
component = ui.get_component(component_name)
component = get_ui_component(component_name)
if component:
for method in [ 'upload', 'change', 'clear' ]:
getattr(component, method)(update_preview_image, inputs = PREVIEW_FRAME_SLIDER, outputs = PREVIEW_IMAGE)
@@ -69,10 +72,13 @@ def listen() -> None:
update_component_names : List[ComponentName] =\
[
'face_recognition_dropdown',
'frame_processors_checkbox_group'
'frame_processors_checkbox_group',
'face_swapper_model_dropdown',
'face_enhancer_model_dropdown',
'frame_enhancer_model_dropdown'
]
for component_name in update_component_names:
component = ui.get_component(component_name)
component = get_ui_component(component_name)
if component:
component.change(update_preview_image, inputs = PREVIEW_FRAME_SLIDER, outputs = PREVIEW_IMAGE)
select_component_names : List[ComponentName] =\
@@ -83,15 +89,22 @@ def listen() -> None:
'face_analyser_gender_dropdown'
]
for component_name in select_component_names:
component = ui.get_component(component_name)
component = get_ui_component(component_name)
if component:
component.select(update_preview_image, inputs = PREVIEW_FRAME_SLIDER, outputs = PREVIEW_IMAGE)
reference_face_distance_slider = ui.get_component('reference_face_distance_slider')
if reference_face_distance_slider:
reference_face_distance_slider.change(update_preview_image, inputs = PREVIEW_FRAME_SLIDER, outputs = PREVIEW_IMAGE)
change_component_names : List[ComponentName] =\
[
'reference_face_distance_slider',
'face_enhancer_blend_slider',
'frame_enhancer_blend_slider'
]
for component_name in change_component_names:
component = get_ui_component(component_name)
if component:
component.change(update_preview_image, inputs = PREVIEW_FRAME_SLIDER, outputs = PREVIEW_IMAGE)
def update_preview_image(frame_number : int = 0) -> Update:
def update_preview_image(frame_number : int = 0) -> gradio.Image:
conditional_set_face_reference()
source_face = get_one_face(read_static_image(facefusion.globals.source_path))
reference_face = get_face_reference() if 'reference' in facefusion.globals.face_recognition else None
@@ -99,30 +112,30 @@ def update_preview_image(frame_number : int = 0) -> Update:
target_frame = read_static_image(facefusion.globals.target_path)
preview_frame = process_preview_frame(source_face, reference_face, target_frame)
preview_frame = normalize_frame_color(preview_frame)
return gradio.update(value = preview_frame)
return gradio.Image(value = preview_frame)
if is_video(facefusion.globals.target_path):
facefusion.globals.reference_frame_number = frame_number
temp_frame = get_video_frame(facefusion.globals.target_path, facefusion.globals.reference_frame_number)
preview_frame = process_preview_frame(source_face, reference_face, temp_frame)
preview_frame = normalize_frame_color(preview_frame)
return gradio.update(value = preview_frame)
return gradio.update(value = None)
return gradio.Image(value = preview_frame)
return gradio.Image(value = None)
def update_preview_frame_slider(frame_number : int = 0) -> Update:
def update_preview_frame_slider(frame_number : int = 0) -> gradio.Slider:
if is_image(facefusion.globals.target_path):
return gradio.update(value = None, maximum = None, visible = False)
return gradio.Slider(value = None, maximum = None, visible = False)
if is_video(facefusion.globals.target_path):
facefusion.globals.reference_frame_number = frame_number
video_frame_total = count_video_frame_total(facefusion.globals.target_path)
return gradio.update(maximum = video_frame_total, visible = True)
return gradio.update(value = None, maximum = None, visible = False)
return gradio.Slider(maximum = video_frame_total, visible = True)
return gradio.Slider()
def process_preview_frame(source_face : Face, reference_face : Face, temp_frame : Frame) -> Frame:
temp_frame = resize_frame_dimension(temp_frame, 640, 640)
if predict_frame(temp_frame):
return cv2.GaussianBlur(temp_frame, (99, 99), 0)
temp_frame = resize_frame_dimension(temp_frame, 480)
for frame_processor in facefusion.globals.frame_processors:
frame_processor_module = load_frame_processor_module(frame_processor)
if frame_processor_module.pre_process('preview'):

View File

@@ -1,40 +0,0 @@
from typing import Optional, List
import gradio
import facefusion.globals
from facefusion import wording
from facefusion.uis import choices
from facefusion.uis.typing import Update
SETTINGS_CHECKBOX_GROUP : Optional[gradio.Checkboxgroup] = None
def render() -> None:
global SETTINGS_CHECKBOX_GROUP
value = []
if facefusion.globals.keep_fps:
value.append('keep-fps')
if facefusion.globals.keep_temp:
value.append('keep-temp')
if facefusion.globals.skip_audio:
value.append('skip-audio')
if facefusion.globals.skip_download:
value.append('skip-download')
SETTINGS_CHECKBOX_GROUP = gradio.Checkboxgroup(
label = wording.get('settings_checkbox_group_label'),
choices = choices.settings,
value = value
)
def listen() -> None:
SETTINGS_CHECKBOX_GROUP.change(update, inputs = SETTINGS_CHECKBOX_GROUP, outputs = SETTINGS_CHECKBOX_GROUP)
def update(settings : List[str]) -> Update:
facefusion.globals.keep_fps = 'keep-fps' in settings
facefusion.globals.keep_temp = 'keep-temp' in settings
facefusion.globals.skip_audio = 'skip-audio' in settings
facefusion.globals.skip_download = 'skip-download' in settings
return gradio.update(value = settings)

View File

@@ -3,9 +3,8 @@ import gradio
import facefusion.globals
from facefusion import wording
from facefusion.uis import core as ui
from facefusion.uis.typing import Update
from facefusion.utilities import is_image
from facefusion.uis.core import register_ui_component
SOURCE_FILE : Optional[gradio.File] = None
SOURCE_IMAGE : Optional[gradio.Image] = None
@@ -32,16 +31,16 @@ def render() -> None:
visible = is_source_image,
show_label = False
)
ui.register_component('source_image', SOURCE_IMAGE)
register_ui_component('source_image', SOURCE_IMAGE)
def listen() -> None:
SOURCE_FILE.change(update, inputs = SOURCE_FILE, outputs = SOURCE_IMAGE)
def update(file: IO[Any]) -> Update:
def update(file: IO[Any]) -> gradio.Image:
if file and is_image(file.name):
facefusion.globals.source_path = file.name
return gradio.update(value = file.name, visible = True)
return gradio.Image(value = file.name, visible = True)
facefusion.globals.source_path = None
return gradio.update(value = None, visible = False)
return gradio.Image(value = None, visible = False)

View File

@@ -4,9 +4,8 @@ import gradio
import facefusion.globals
from facefusion import wording
from facefusion.face_reference import clear_face_reference
from facefusion.uis import core as ui
from facefusion.uis.typing import Update
from facefusion.utilities import is_image, is_video
from facefusion.uis.core import register_ui_component
TARGET_FILE : Optional[gradio.File] = None
TARGET_IMAGE : Optional[gradio.Image] = None
@@ -42,21 +41,21 @@ def render() -> None:
visible = is_target_video,
show_label = False
)
ui.register_component('target_image', TARGET_IMAGE)
ui.register_component('target_video', TARGET_VIDEO)
register_ui_component('target_image', TARGET_IMAGE)
register_ui_component('target_video', TARGET_VIDEO)
def listen() -> None:
TARGET_FILE.change(update, inputs = TARGET_FILE, outputs = [ TARGET_IMAGE, TARGET_VIDEO ])
def update(file : IO[Any]) -> Tuple[Update, Update]:
def update(file : IO[Any]) -> Tuple[gradio.Image, gradio.Video]:
clear_face_reference()
if file and is_image(file.name):
facefusion.globals.target_path = file.name
return gradio.update(value = file.name, visible = True), gradio.update(value = None, visible = False)
return gradio.Image(value = file.name, visible = True), gradio.Video(value = None, visible = False)
if file and is_video(file.name):
facefusion.globals.target_path = file.name
return gradio.update(value = None, visible = False), gradio.update(value = file.name, visible = True)
return gradio.Image(value = None, visible = False), gradio.Video(value = file.name, visible = True)
facefusion.globals.target_path = None
return gradio.update(value = None, visible = False), gradio.update(value = None, visible = False)
return gradio.Image(value = None, visible = False), gradio.Video(value = None, visible = False)

View File

@@ -5,9 +5,8 @@ import facefusion.choices
import facefusion.globals
from facefusion import wording
from facefusion.typing import TempFrameFormat
from facefusion.uis import core as ui
from facefusion.uis.typing import Update
from facefusion.utilities import is_video
from facefusion.uis.core import get_ui_component
TEMP_FRAME_FORMAT_DROPDOWN : Optional[gradio.Dropdown] = None
TEMP_FRAME_QUALITY_SLIDER : Optional[gradio.Slider] = None
@@ -19,7 +18,7 @@ def render() -> None:
TEMP_FRAME_FORMAT_DROPDOWN = gradio.Dropdown(
label = wording.get('temp_frame_format_dropdown_label'),
choices = facefusion.choices.temp_frame_format,
choices = facefusion.choices.temp_frame_formats,
value = facefusion.globals.temp_frame_format,
visible = is_video(facefusion.globals.target_path)
)
@@ -27,30 +26,30 @@ def render() -> None:
label = wording.get('temp_frame_quality_slider_label'),
value = facefusion.globals.temp_frame_quality,
step = 1,
minimum = 0,
maximum = 100,
visible = is_video(facefusion.globals.target_path)
)
def listen() -> None:
TEMP_FRAME_FORMAT_DROPDOWN.select(update_temp_frame_format, inputs = TEMP_FRAME_FORMAT_DROPDOWN, outputs = TEMP_FRAME_FORMAT_DROPDOWN)
TEMP_FRAME_QUALITY_SLIDER.change(update_temp_frame_quality, inputs = TEMP_FRAME_QUALITY_SLIDER, outputs = TEMP_FRAME_QUALITY_SLIDER)
target_video = ui.get_component('target_video')
TEMP_FRAME_FORMAT_DROPDOWN.select(update_temp_frame_format, inputs = TEMP_FRAME_FORMAT_DROPDOWN)
TEMP_FRAME_QUALITY_SLIDER.change(update_temp_frame_quality, inputs = TEMP_FRAME_QUALITY_SLIDER)
target_video = get_ui_component('target_video')
if target_video:
for method in [ 'upload', 'change', 'clear' ]:
getattr(target_video, method)(remote_update, outputs = [ TEMP_FRAME_FORMAT_DROPDOWN, TEMP_FRAME_QUALITY_SLIDER ])
def remote_update() -> Tuple[Update, Update]:
def remote_update() -> Tuple[gradio.Dropdown, gradio.Slider]:
if is_video(facefusion.globals.target_path):
return gradio.update(visible = True), gradio.update(visible = True)
return gradio.update(visible = False), gradio.update(visible = False)
return gradio.Dropdown(visible = True), gradio.Slider(visible = True)
return gradio.Dropdown(visible = False), gradio.Slider(visible = False)
def update_temp_frame_format(temp_frame_format : TempFrameFormat) -> Update:
def update_temp_frame_format(temp_frame_format : TempFrameFormat) -> None:
facefusion.globals.temp_frame_format = temp_frame_format
return gradio.update(value = temp_frame_format)
def update_temp_frame_quality(temp_frame_quality : int) -> Update:
def update_temp_frame_quality(temp_frame_quality : int) -> None:
facefusion.globals.temp_frame_quality = temp_frame_quality
return gradio.update(value = temp_frame_quality)

View File

@@ -4,9 +4,8 @@ import gradio
import facefusion.globals
from facefusion import wording
from facefusion.vision import count_video_frame_total
from facefusion.uis import core as ui
from facefusion.uis.typing import Update
from facefusion.utilities import is_video
from facefusion.uis.core import get_ui_component
TRIM_FRAME_START_SLIDER : Optional[gradio.Slider] = None
TRIM_FRAME_END_SLIDER : Optional[gradio.Slider] = None
@@ -20,12 +19,16 @@ def render() -> None:
{
'label': wording.get('trim_frame_start_slider_label'),
'step': 1,
'minimum': 0,
'maximum': 100,
'visible': False
}
trim_frame_end_slider_args : Dict[str, Any] =\
{
'label': wording.get('trim_frame_end_slider_label'),
'step': 1,
'minimum': 0,
'maximum': 100,
'visible': False
}
if is_video(facefusion.globals.target_path):
@@ -41,29 +44,27 @@ def render() -> None:
def listen() -> None:
TRIM_FRAME_START_SLIDER.change(update_trim_frame_start, inputs = TRIM_FRAME_START_SLIDER, outputs = TRIM_FRAME_START_SLIDER)
TRIM_FRAME_END_SLIDER.change(update_trim_frame_end, inputs = TRIM_FRAME_END_SLIDER, outputs = TRIM_FRAME_END_SLIDER)
target_video = ui.get_component('target_video')
TRIM_FRAME_START_SLIDER.change(update_trim_frame_start, inputs = TRIM_FRAME_START_SLIDER)
TRIM_FRAME_END_SLIDER.change(update_trim_frame_end, inputs = TRIM_FRAME_END_SLIDER)
target_video = get_ui_component('target_video')
if target_video:
for method in [ 'upload', 'change', 'clear' ]:
getattr(target_video, method)(remote_update, outputs = [ TRIM_FRAME_START_SLIDER, TRIM_FRAME_END_SLIDER ])
def remote_update() -> Tuple[Update, Update]:
def remote_update() -> Tuple[gradio.Slider, gradio.Slider]:
if is_video(facefusion.globals.target_path):
video_frame_total = count_video_frame_total(facefusion.globals.target_path)
facefusion.globals.trim_frame_start = None
facefusion.globals.trim_frame_end = None
return gradio.update(value = 0, maximum = video_frame_total, visible = True), gradio.update(value = video_frame_total, maximum = video_frame_total, visible = True)
return gradio.update(value = None, maximum = None, visible = False), gradio.update(value = None, maximum = None, visible = False)
return gradio.Slider(value = 0, maximum = video_frame_total, visible = True), gradio.Slider(value = video_frame_total, maximum = video_frame_total, visible = True)
return gradio.Slider(value = None, maximum = None, visible = False), gradio.Slider(value = None, maximum = None, visible = False)
def update_trim_frame_start(trim_frame_start : int) -> Update:
def update_trim_frame_start(trim_frame_start : int) -> None:
facefusion.globals.trim_frame_start = trim_frame_start if trim_frame_start > 0 else None
return gradio.update(value = trim_frame_start)
def update_trim_frame_end(trim_frame_end : int) -> Update:
def update_trim_frame_end(trim_frame_end : int) -> None:
video_frame_total = count_video_frame_total(facefusion.globals.target_path)
facefusion.globals.trim_frame_end = trim_frame_end if trim_frame_end < video_frame_total else None
return gradio.update(value = trim_frame_end)

View File

@@ -10,13 +10,14 @@ from tqdm import tqdm
import facefusion.globals
from facefusion import wording
from facefusion.predictor import predict_stream
from facefusion.typing import Frame, Face
from facefusion.face_analyser import get_one_face
from facefusion.processors.frame.core import load_frame_processor_module
from facefusion.uis import core as ui
from facefusion.uis.typing import StreamMode, WebcamMode, Update
from facefusion.processors.frame.core import get_frame_processors_modules
from facefusion.utilities import open_ffmpeg
from facefusion.vision import normalize_frame_color, read_static_image
from facefusion.uis.typing import StreamMode, WebcamMode
from facefusion.uis.core import get_ui_component
WEBCAM_IMAGE : Optional[gradio.Image] = None
WEBCAM_START_BUTTON : Optional[gradio.Button] = None
@@ -33,25 +34,27 @@ def render() -> None:
)
WEBCAM_START_BUTTON = gradio.Button(
value = wording.get('start_button_label'),
variant = 'primary'
variant = 'primary',
size = 'sm'
)
WEBCAM_STOP_BUTTON = gradio.Button(
value = wording.get('stop_button_label')
value = wording.get('stop_button_label'),
size = 'sm'
)
def listen() -> None:
start_event = None
webcam_mode_radio = ui.get_component('webcam_mode_radio')
webcam_resolution_dropdown = ui.get_component('webcam_resolution_dropdown')
webcam_fps_slider = ui.get_component('webcam_fps_slider')
webcam_mode_radio = get_ui_component('webcam_mode_radio')
webcam_resolution_dropdown = get_ui_component('webcam_resolution_dropdown')
webcam_fps_slider = get_ui_component('webcam_fps_slider')
if webcam_mode_radio and webcam_resolution_dropdown and webcam_fps_slider:
start_event = WEBCAM_START_BUTTON.click(start, inputs = [ webcam_mode_radio, webcam_resolution_dropdown, webcam_fps_slider ], outputs = WEBCAM_IMAGE)
webcam_mode_radio.change(stop, outputs = WEBCAM_IMAGE, cancels = start_event)
webcam_resolution_dropdown.change(stop, outputs = WEBCAM_IMAGE, cancels = start_event)
webcam_fps_slider.change(stop, outputs = WEBCAM_IMAGE, cancels = start_event)
WEBCAM_STOP_BUTTON.click(stop, cancels = start_event)
source_image = ui.get_component('source_image')
source_image = get_ui_component('source_image')
if source_image:
for method in [ 'upload', 'change', 'clear' ]:
getattr(source_image, method)(stop, cancels = start_event)
@@ -61,10 +64,8 @@ def start(mode: WebcamMode, resolution: str, fps: float) -> Generator[Frame, Non
facefusion.globals.face_recognition = 'many'
source_face = get_one_face(read_static_image(facefusion.globals.source_path))
stream = None
if mode == 'stream_udp':
stream = open_stream('udp', resolution, fps)
if mode == 'stream_v4l2':
stream = open_stream('v4l2', resolution, fps)
if mode in [ 'udp', 'v4l2' ]:
stream = open_stream(mode, resolution, fps) # type: ignore[arg-type]
capture = capture_webcam(resolution, fps)
if capture.isOpened():
for capture_frame in multi_process_capture(source_face, capture):
@@ -80,6 +81,8 @@ def multi_process_capture(source_face: Face, capture : cv2.VideoCapture) -> Gene
deque_capture_frames : Deque[Frame] = deque()
while True:
_, capture_frame = capture.read()
if predict_stream(capture_frame):
return
future = executor.submit(process_stream_frame, source_face, capture_frame)
futures.append(future)
for future_done in [ future for future in futures if future.done() ]:
@@ -91,8 +94,8 @@ def multi_process_capture(source_face: Face, capture : cv2.VideoCapture) -> Gene
progress.update()
def stop() -> Update:
return gradio.update(value = None)
def stop() -> gradio.Image:
return gradio.Image(value = None)
def capture_webcam(resolution : str, fps : float) -> cv2.VideoCapture:
@@ -109,8 +112,7 @@ def capture_webcam(resolution : str, fps : float) -> cv2.VideoCapture:
def process_stream_frame(source_face : Face, temp_frame : Frame) -> Frame:
for frame_processor in facefusion.globals.frame_processors:
frame_processor_module = load_frame_processor_module(frame_processor)
for frame_processor_module in get_frame_processors_modules(facefusion.globals.frame_processors):
if frame_processor_module.pre_process('stream'):
temp_frame = frame_processor_module.process_frame(
source_face,

View File

@@ -3,8 +3,7 @@ import gradio
from facefusion import wording
from facefusion.uis import choices
from facefusion.uis import core as ui
from facefusion.uis.typing import Update
from facefusion.uis.core import register_ui_component
WEBCAM_MODE_RADIO : Optional[gradio.Radio] = None
WEBCAM_RESOLUTION_DROPDOWN : Optional[gradio.Dropdown] = None
@@ -18,25 +17,21 @@ def render() -> None:
WEBCAM_MODE_RADIO = gradio.Radio(
label = wording.get('webcam_mode_radio_label'),
choices = choices.webcam_mode,
choices = choices.webcam_modes,
value = 'inline'
)
WEBCAM_RESOLUTION_DROPDOWN = gradio.Dropdown(
label = wording.get('webcam_resolution_dropdown'),
choices = choices.webcam_resolution,
value = choices.webcam_resolution[0]
choices = choices.webcam_resolutions,
value = choices.webcam_resolutions[0]
)
WEBCAM_FPS_SLIDER = gradio.Slider(
label = wording.get('webcam_fps_slider'),
minimum = 1,
maximum = 60,
value = 25,
step = 1,
value = 25
minimum = 1,
maximum = 60
)
ui.register_component('webcam_mode_radio', WEBCAM_MODE_RADIO)
ui.register_component('webcam_resolution_dropdown', WEBCAM_RESOLUTION_DROPDOWN)
ui.register_component('webcam_fps_slider', WEBCAM_FPS_SLIDER)
def update() -> Update:
return gradio.update(value = None)
register_ui_component('webcam_mode_radio', WEBCAM_MODE_RADIO)
register_ui_component('webcam_resolution_dropdown', WEBCAM_RESOLUTION_DROPDOWN)
register_ui_component('webcam_fps_slider', WEBCAM_FPS_SLIDER)